Merge changes I7d9444d5,I7b104c8e into integration

* changes:
  feat(mt8192): update memory protect region
  feat(mt8195): update memory protect region
diff --git a/.ctags b/.ctags
new file mode 100644
index 0000000..5e608e4
--- /dev/null
+++ b/.ctags
@@ -0,0 +1,4 @@
+--regex-Asm=/^func[ \t]+([a-zA-Z_0-9]+)$/\1/l,function/
+--regex-Asm=/^.*\.macro[ \t]+([a-zA-Z_0-9]+)$/\1/m,macro/
+--regex-Asm=/^vector_entry[ \t]+([a-zA-Z_0-9]+)$/\1/l,function/
+--regex-Asm=/^.equ[ \t]+([a-zA-Z_0-9]+),/\1/l,name/
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 bbde1a7..ea4966d 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,7 @@
 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
 
 ################################################################################
@@ -31,28 +32,22 @@
 ################################################################################
 
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
+include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
+
+# To be able to set platform specific defaults
+ifneq ($(PLAT_DEFAULTS_MAKEFILE_FULL),)
+include ${PLAT_DEFAULTS_MAKEFILE_FULL}
+endif
 
 ################################################################################
 # 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
 ENABLE_ASSERTIONS		:= ${DEBUG}
 ENABLE_PMF			:= ${ENABLE_RUNTIME_INSTRUMENTATION}
-PLAT				:= ${DEFAULT_PLAT}
 
 ################################################################################
 # Checkpatch script options
@@ -417,7 +412,6 @@
 ################################################################################
 # Generic definitions
 ################################################################################
-include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
 
 ifeq (${BUILD_BASE},)
      BUILD_BASE		:=	./build
@@ -453,6 +447,9 @@
 			ifeq ($(SPMC_AT_EL3),1)
                                 $(error SPM cannot be enabled in both S-EL2 and EL3.)
 			endif
+			ifeq ($(CTX_INCLUDE_SVE_REGS),1)
+                                $(error SVE context management not needed with Hafnium SPMC.)
+			endif
 		endif
 
 		ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
@@ -690,8 +687,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
@@ -973,27 +968,54 @@
 	endif
 endif #(ENABLE_SME_FOR_SWD)
 
+# Enabling SVE for SWD requires enabling SVE for NWD due to ENABLE_FEAT
+# mechanism.
 ifeq (${ENABLE_SVE_FOR_SWD},1)
-	ifeq (${ENABLE_SVE_FOR_NS},0)
-                $(error "ENABLE_SVE_FOR_SWD requires ENABLE_SVE_FOR_NS")
-	endif
-endif #(ENABLE_SVE_FOR_SWD)
+    ifeq (${ENABLE_SVE_FOR_NS},0)
+        $(error "ENABLE_SVE_FOR_SWD requires ENABLE_SVE_FOR_NS")
+    endif
+endif
 
-# SVE and SME cannot be used with CTX_INCLUDE_FPREGS since secure manager does
-# its own context management including FPU registers.
-ifeq (${CTX_INCLUDE_FPREGS},1)
-	ifneq (${ENABLE_SME_FOR_NS},0)
-                $(error "ENABLE_SME_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
-	endif
+# Enabling SVE for both the worlds typically requires the context
+# management of SVE registers. The only exception being SPMC at S-EL2.
+ifeq (${ENABLE_SVE_FOR_SWD}, 1)
+    ifneq (${ENABLE_SVE_FOR_NS}, 0)
+        ifeq (${CTX_INCLUDE_SVE_REGS}-$(SPMD_SPM_AT_SEL2),0-0)
+            $(warning "ENABLE_SVE_FOR_SWD and ENABLE_SVE_FOR_NS together require CTX_INCLUDE_SVE_REGS")
+        endif
+    endif
+endif
 
-	ifeq (${ENABLE_SVE_FOR_NS},1)
-		# Warning instead of error due to CI dependency on this
-                $(warning "ENABLE_SVE_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
-                $(warning "Forced ENABLE_SVE_FOR_NS=0")
-		override ENABLE_SVE_FOR_NS	:= 0
-	endif
+# Enabling SVE in either world while enabling CTX_INCLUDE_FPREGS requires
+# CTX_INCLUDE_SVE_REGS to be enabled due to architectural dependency between FP
+# and SVE registers.
+ifeq (${CTX_INCLUDE_FPREGS}, 1)
+    ifneq (${ENABLE_SVE_FOR_NS},0)
+        ifeq (${CTX_INCLUDE_SVE_REGS},0)
+	    # Warning instead of error due to CI dependency on this
+            $(warning "CTX_INCLUDE_FPREGS and ENABLE_SVE_FOR_NS together require CTX_INCLUDE_SVE_REGS")
+            $(warning "Forced ENABLE_SVE_FOR_NS=0")
+	    override ENABLE_SVE_FOR_NS	:= 0
+        endif
+    endif
 endif #(CTX_INCLUDE_FPREGS)
 
+# SVE context management is only required if secure world has access to SVE/FP
+# functionality.
+ifeq (${CTX_INCLUDE_SVE_REGS},1)
+    ifeq (${ENABLE_SVE_FOR_SWD},0)
+        $(error "CTX_INCLUDE_SVE_REGS requires ENABLE_SVE_FOR_SWD to also be enabled")
+    endif
+endif
+
+# SME cannot be used with CTX_INCLUDE_FPREGS since SPM does its own context
+# management including FPU registers.
+ifeq (${CTX_INCLUDE_FPREGS},1)
+    ifneq (${ENABLE_SME_FOR_NS},0)
+        $(error "ENABLE_SME_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
+    endif
+endif #(CTX_INCLUDE_FPREGS)
+
 ifeq ($(DRTM_SUPPORT),1)
         $(info DRTM_SUPPORT is an experimental feature)
 endif
@@ -1128,6 +1150,7 @@
 	CREATE_KEYS \
 	CTX_INCLUDE_AARCH32_REGS \
 	CTX_INCLUDE_FPREGS \
+	CTX_INCLUDE_SVE_REGS \
 	CTX_INCLUDE_EL2_REGS \
 	CTX_INCLUDE_MPAM_REGS \
 	DEBUG \
@@ -1154,6 +1177,7 @@
 	HW_ASSISTED_COHERENCY \
 	MEASURED_BOOT \
 	DICE_PROTECTION_ENVIRONMENT \
+	RMMD_ENABLE_EL3_TOKEN_SIGN \
 	DRTM_SUPPORT \
 	NS_TIMER_SWITCH \
 	OVERRIDE_LIBC \
@@ -1166,6 +1190,7 @@
 	SEPARATE_CODE_AND_RODATA \
 	SEPARATE_BL2_NOLOAD_REGION \
 	SEPARATE_NOBITS_REGION \
+	SEPARATE_SIMD_SECTION \
 	SPIN_ON_BL1_EXIT \
 	SPM_MM \
 	SPMC_AT_EL3 \
@@ -1227,9 +1252,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 \
@@ -1237,11 +1264,13 @@
 	ENABLE_FEAT_RNG_TRAP \
 	ENABLE_FEAT_SEL2 \
 	ENABLE_FEAT_TCR2 \
+	ENABLE_FEAT_THE \
 	ENABLE_FEAT_SB \
 	ENABLE_FEAT_S2PIE \
 	ENABLE_FEAT_S1PIE \
 	ENABLE_FEAT_S2POE \
 	ENABLE_FEAT_S1POE \
+	ENABLE_FEAT_SCTLR2 \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_VHE \
 	ENABLE_FEAT_MPAM \
@@ -1284,6 +1313,7 @@
 	COLD_BOOT_SINGLE_CPU \
 	CTX_INCLUDE_AARCH32_REGS \
 	CTX_INCLUDE_FPREGS \
+	CTX_INCLUDE_SVE_REGS \
 	CTX_INCLUDE_PAUTH_REGS \
 	CTX_INCLUDE_MPAM_REGS \
 	EL3_EXCEPTION_HANDLING \
@@ -1297,12 +1327,14 @@
 	AMU_RESTRICT_COUNTERS \
 	ENABLE_ASSERTIONS \
 	ENABLE_BTI \
+	ENABLE_FEAT_DEBUGV8P9 \
 	ENABLE_FEAT_MPAM \
 	ENABLE_PAUTH \
 	ENABLE_PIE \
 	ENABLE_PMF \
 	ENABLE_PSCI_STAT \
 	ENABLE_RME \
+	RMMD_ENABLE_EL3_TOKEN_SIGN \
 	ENABLE_RUNTIME_INSTRUMENTATION \
 	ENABLE_SME_FOR_NS \
 	ENABLE_SME2_FOR_NS \
@@ -1335,6 +1367,7 @@
 	SEPARATE_CODE_AND_RODATA \
 	SEPARATE_BL2_NOLOAD_REGION \
 	SEPARATE_NOBITS_REGION \
+	SEPARATE_SIMD_SECTION \
 	RECLAIM_INIT_CODE \
 	SPD_${SPD} \
 	SPIN_ON_BL1_EXIT \
@@ -1381,6 +1414,7 @@
 	ENABLE_MPMM \
 	ENABLE_MPMM_FCONF \
 	ENABLE_FEAT_FGT \
+	ENABLE_FEAT_FGT2 \
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_SEL2 \
@@ -1389,10 +1423,12 @@
 	ENABLE_FEAT_CSV2_3 \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_TCR2 \
+	ENABLE_FEAT_THE \
 	ENABLE_FEAT_S2PIE \
 	ENABLE_FEAT_S1PIE \
 	ENABLE_FEAT_S2POE \
 	ENABLE_FEAT_S1POE \
+	ENABLE_FEAT_SCTLR2 \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_MTE2 \
 	FEATURE_DETECTION \
@@ -1459,7 +1495,7 @@
 # Build targets
 ################################################################################
 
-.PHONY:	all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip sp fwu_fip certtool dtbs memmap doc enctool
+.PHONY:	all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip sp tl fwu_fip certtool dtbs memmap doc enctool
 .SUFFIXES:
 
 all: msg_start
@@ -1476,7 +1512,6 @@
 endif
 endif #(!ERROR_DEPRECATED)
 
-$(eval $(call MAKE_LIB_DIRS))
 $(eval $(call MAKE_LIB,c))
 
 # Expand build macros for the different images
@@ -1560,7 +1595,7 @@
 
 # Add Secure Partition packages
 ifeq (${NEED_SP_PKG},yes)
-$(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
+$(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)
 	$(s)echo
@@ -1632,11 +1667,10 @@
 	for commit in `git rev-list --no-merges $$COMMON_COMMIT..HEAD`;	\
 	do								\
 		printf "\n[*] Checking style of '$$commit'\n\n";	\
-		git log --format=email "$$commit~..$$commit"		\
-			-- ${CHECK_PATHS} |				\
-			${CHECKPATCH} ${CHECKPATCH_OPTS} - || true;	\
-		git diff --format=email "$$commit~..$$commit"		\
-			-- ${CHECK_PATHS} |				\
+		( git log --format=email "$$commit~..$$commit"		\
+			-- ${CHECK_PATHS} ;				\
+		  git diff --format=email "$$commit~..$$commit"		\
+			-- ${CHECK_PATHS}; ) |				\
 			${CHECKPATCH}  ${CHECKPATCH_OPTS} - || true;	\
 	done
 
@@ -1688,7 +1722,7 @@
 
 ${FIPTOOL}: FORCE
 ifdef UNIX_MK
-	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} --no-print-directory -C ${FIPTOOLPATH} all
+	$(q)${MAKE} PLAT=${PLAT} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} --no-print-directory -C ${FIPTOOLPATH} all
 else
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
@@ -1707,6 +1741,11 @@
 		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
 endif
 
+tl: ${BUILD_PLAT}/tl.bin
+${BUILD_PLAT}/tl.bin: ${HW_CONFIG}
+	$(if $(host-poetry),$(q)poetry -q install)
+	$(q)$(if $(host-poetry),poetry run )tlc create --fdt $< -s ${FW_HANDOFF_SIZE} $@
+
 doc:
 	$(s)echo "  BUILD DOCUMENTATION"
 	$(q)${MAKE} --no-print-directory -C ${DOCS_PATH} html
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index db0eafc..a8a0061 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -19,7 +19,8 @@
 
 ifeq (${ARCH},aarch64)
 BL1_SOURCES		+=	lib/cpus/aarch64/dsu_helpers.S		\
-				lib/el3_runtime/aarch64/context.S
+				lib/el3_runtime/aarch64/context.S	\
+				lib/cpus/errata_common.c
 endif
 
 ifeq (${TRUSTED_BOARD_BOOT},1)
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 40add91..336ad2b 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -42,10 +42,12 @@
 				bl31/bl31_context_mgmt.c			\
 				bl31/bl31_traps.c				\
 				common/runtime_svc.c				\
+				lib/cpus/errata_common.c			\
 				lib/cpus/aarch64/dsu_helpers.S			\
 				plat/common/aarch64/platform_mp_stack.S		\
 				services/arm_arch_svc/arm_arch_svc_setup.c	\
 				services/std_svc/std_svc_setup.c		\
+				lib/el3_runtime/simd_ctx.c			\
 				${PSCI_LIB_SOURCES}				\
 				${SPMD_SOURCES}					\
 				${SPM_MM_SOURCES}				\
@@ -105,6 +107,14 @@
 BL31_SOURCES		+=	${AMU_SOURCES}
 endif
 
+ifneq (${ENABLE_FEAT_FGT2},0)
+BL31_SOURCES		+=	lib/extensions/fgt/fgt2.c
+endif
+
+ifneq (${ENABLE_FEAT_TCR2},0)
+BL31_SOURCES		+=	lib/extensions/tcr/tcr2.c
+endif
+
 ifeq (${ENABLE_MPMM},1)
 BL31_SOURCES		+=	${MPMM_SOURCES}
 endif
@@ -120,6 +130,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 6a235cd..3591f02 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
 
@@ -241,8 +247,8 @@
               - title: RD-N2
                 scope: rdn2
 
-              - title: RD-Fremont
-                scope: rdfremont
+              - title: RD-V3
+                scope: rdv3
 
                 deprecated:
                   - board/rdn2
@@ -266,6 +272,13 @@
           - title: Corstone-1000
             scope: corstone-1000
 
+          - title: Automotive RD
+            scope: automotive_rd
+
+            subsections:
+              - title: RD-1 AE
+                scope: rd1ae
+
       - title: Aspeed
         scope: aspeed
 
@@ -799,6 +812,9 @@
           - title: RAS
             scope: ras
 
+          - title: SIMD
+            scope: simd
+
       - title: FCONF
         scope: fconf
 
@@ -884,6 +900,9 @@
       - title: Console
         scope: console
 
+      - title: Delay Timer
+        scope: delay-timer
+
       - title: Generic Clock
         scope: clk
 
@@ -1396,6 +1415,7 @@
           - git-hooks
 
   - title: Tools
+    scope: tools
 
     subsections:
       - title: STM32 Image
@@ -1428,6 +1448,22 @@
       - 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: Chain of Trust device tree to C source file
+        scope: cot-dt2c
+
   - title: Dependencies
     scope: deps
 
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index 1bad74f..59b7543 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -197,6 +197,7 @@
 			    uintptr_t base, size_t size)
 {
 	int offs = fdt_path_offset(dtb, "/reserved-memory");
+	int node;
 	uint32_t addresses[4];
 	int ac, sc;
 	unsigned int idx = 0;
@@ -213,6 +214,24 @@
 		fdt_setprop(dtb, offs, "ranges", NULL, 0);
 	}
 
+	/* Check for existing regions */
+	fdt_for_each_subnode(node, dtb, offs) {
+		uintptr_t c_base;
+		size_t c_size;
+		int ret;
+
+		ret = fdt_get_reg_props_by_index(dtb, node, 0, &c_base, &c_size);
+		/* Ignore illegal subnodes */
+		if (ret != 0) {
+			continue;
+		}
+
+		/* existing region entirely contains the new region */
+		if (base >= c_base && (base + size) <= (c_base + c_size)) {
+			return 0;
+		}
+	}
+
 	if (ac > 1) {
 		addresses[idx] = cpu_to_fdt32(HIGH_BITS(base));
 		idx++;
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 783b660..b213ffa 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -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
  */
@@ -88,6 +88,19 @@
 	return 0;
 }
 
+uint64_t fdt_read_uint64_default(const void *dtb, int node,
+				 const char *prop_name, uint64_t dflt_value)
+{
+	uint64_t ret = dflt_value;
+	int err = fdt_read_uint64(dtb, node, prop_name, &ret);
+
+	if (err < 0) {
+		return dflt_value;
+	}
+
+	return ret;
+}
+
 /*
  * Read bytes from a given property of the given node. Any number of
  * bytes of the property can be read. The fdt pointer is updated.
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 8e3e3dd..e63eec4 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,
@@ -251,6 +257,18 @@
 
 }
 
+static unsigned int read_feat_the_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_THE_SHIFT,
+			     ID_AA64PFR1_EL1_THE_MASK);
+}
+
+static unsigned int read_feat_sctlr2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_SCTLR2_SHIFT,
+			     ID_AA64MMFR3_EL1_SCTLR2_MASK);
+}
+
 /***********************************************************************************
  * TF-A supports many Arm architectural features starting from arch version
  * (8.0 till 8.7+). These features are mostly enabled through build flags. This
@@ -328,7 +346,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 +375,12 @@
 		      "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);
+	check_feature(ENABLE_FEAT_THE, read_feat_the_id_field(),
+			"THE", 1, 1);
+	check_feature(ENABLE_FEAT_SCTLR2, read_feat_sctlr2_id_field(),
+			"SCTLR2", 1, 1);
 
 	/* v9.0 features */
 	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index cbed72f..4d08a7f 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -565,8 +565,8 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
 :|G|: `abdellatif-elkhlifi`_
-:|M|: Xueliang Zhong <xueliang.zhong@arm.com>
-:|G|: `xueliang-zhong-arm`_
+:|M|: Hugues Kamba Mpiana <hugues.kambampiana@arm.com>
+:|G|: `hugues-kambampiana-arm`_
 :|F|: plat/arm/board/corstone700
 :|F|: plat/arm/board/a5ds
 :|F|: plat/arm/board/corstone1000
@@ -594,6 +594,16 @@
 :|G|: `rupsin01`_
 :|F|: plat/arm/board/tc
 
+Arm Automotive RD platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Diego Sueiro <diego.sueiro@arm.com>
+:|G|: `diego-sueiro`_
+:|M|: Peter Hoyes <peter.hoyes@arm.com>
+:|G|: `hoyes`_
+:|M|: Divin Raj <divin.raj@arm.com>
+:|G|: `divin-raj`_
+:|F|: plat/arm/board/automotive_rd
+
 Aspeed platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Chia-Wei Wang <chiawei_wang@aspeedtech.com>
@@ -858,8 +868,6 @@
 :|G|: `rockchip-linux`_
 :|M|: Heiko Stuebner <heiko@sntech.de>
 :|G|: `mmind`_
-:|M|: Julius Werner <jwerner@chromium.org>
-:|G|: `jwerner-chromium`_
 :|F|: plat/rockchip/
 
 STMicroelectronics platform ports
@@ -1043,13 +1051,17 @@
 .. _CJKay: https://github.com/cjkay
 .. _danh-arm: https://github.com/danh-arm
 .. _davidvincze: https://github.com/davidvincze
+.. _diego-sueiro: https://github.com/diego-sueiro
+.. _divin-raj: https://github.com/divin-raj
 .. _etienne-lms: https://github.com/etienne-lms
 .. _glneo: https://github.com/glneo
 .. _gprocopciucnxp: https://github.com/gprocopciucnxp
 .. _grandpaul: https://github.com/grandpaul
 .. _harrisonmutai-arm: https://github.com/harrisonmutai-arm
 .. _hilamirandakuzi1: https://github.com/hilamirandakuzi1
+.. _hoyes: https://github.com/hoyes
 .. _hzhuang1: https://github.com/hzhuang1
+.. _hugues-kambampiana-arm: https://github.com/hugueskamba
 .. _JackyBai: https://github.com/JackyBai
 .. _J-Alves: https://github.com/J-Alves
 .. _jason-ch-chen: https://github.com/jason-ch-chen
@@ -1112,7 +1124,6 @@
 .. _vijayenthiran-arm: https://github.com/vijayenthiran-arm
 .. _vishnu-banavath: https://github.com/vishnu-banavath
 .. _vwadekar: https://github.com/vwadekar
-.. _xueliang-zhong-arm: https://github.com/xueliang-zhong-arm
 .. _Yann-lms: https://github.com/Yann-lms
 
 --------------
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 7fafe03..253b18d 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -70,6 +70,10 @@
 +-----------------+---------------------------+------------------------------+
 | v2.11           | 4th week of May '24       | 2nd week of May '24          |
 +-----------------+---------------------------+------------------------------+
+| v2.12           | 4th week of Nov '24       | 2nd week of Nov '24          |
++-----------------+---------------------------+------------------------------+
+| v2.13           | 4th week of May '25       | 2nd week of May '25          |
++-----------------+---------------------------+------------------------------+
 
 Removal of Deprecated Interfaces
 --------------------------------
diff --git a/docs/components/context-management-library.rst b/docs/components/context-management-library.rst
index 56ba2ec..266b82a 100644
--- a/docs/components/context-management-library.rst
+++ b/docs/components/context-management-library.rst
@@ -98,14 +98,15 @@
 
 4. **Dynamic discovery of Feature enablement by EL3**
 
-TF-A supports three states for feature enablement at EL3, to make them available
+TF-A supports four states for feature enablement at EL3, to make them available
 for lower exception levels.
 
 .. code:: c
 
-	#define FEAT_STATE_DISABLED	0
-	#define FEAT_STATE_ENABLED	1
-	#define FEAT_STATE_CHECK	2
+	#define FEAT_STATE_DISABLED     	0
+	#define FEAT_STATE_ENABLED      	1
+	#define FEAT_STATE_CHECK        	2
+	#define FEAT_STATE_CHECK_ASYMMETRIC	3
 
 A pattern is established for feature enablement behavior.
 Each feature must support the 3 possible values with rigid semantics.
@@ -119,7 +120,26 @@
 - **FEAT_STATE_CHECK** - same as ``FEAT_STATE_ALWAYS`` except that the feature's
   existence will be checked at runtime. Default on dynamic platforms (example: FVP).
 
-.. note::
+- **FEAT_STATE_CHECK_ASYMMETRIC** - same as ``FEAT_STATE_CHECK`` except that the feature's
+  existence is asymmetric across cores, which requires the feature existence is checked
+  during warmboot path also. Note that only limited number of features can be asymmetric.
+
+ .. note::
+   Only limited number of features can be ``FEAT_STATE_CHECK_ASYMMETRIC`` this is due to
+   the fact that Operating systems are designed for SMP systems.
+   There are no clear guidelines what kind of mismatch is allowed but following pointers
+   can help making a decision
+
+    - All mandatory features must be symmetric.
+    - Any feature that impacts the generation of page tables must be symmetric.
+    - Any feature access which does not trap to EL3 should be symmetric.
+    - Features related with profiling, debug and trace could be asymmetric
+    - Migration of vCPU/tasks between CPUs should not cause an error
+
+    Whenever there is asymmetric feature support is added for a feature TF-A need to add
+    feature specific code in context management code.
+
+ .. note::
    ``FEAT_RAS`` is an exception here, as it impacts the execution of EL3 and
    it is essential to know its presence at compile time. Refer to ``ENABLE_FEAT``
    macro under :ref:`Build Options` section for more details.
@@ -498,4 +518,4 @@
 .. |Context Init WarmBoot| image:: ../resources/diagrams/context_init_warmboot.png
 .. _Trustzone for AArch64: https://developer.arm.com/documentation/102418/0101/TrustZone-in-the-processor/Switching-between-Security-states
 .. _Security States with RME: https://developer.arm.com/documentation/den0126/0100/Security-states
-.. _lib/el3_runtime/(aarch32/aarch64): https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/lib/el3_runtime
\ No newline at end of file
+.. _lib/el3_runtime/(aarch32/aarch64): https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/lib/el3_runtime
diff --git a/docs/components/cot-binding.rst b/docs/components/cot-binding.rst
index 702bb56..5d9acdf 100644
--- a/docs/components/cot-binding.rst
+++ b/docs/components/cot-binding.rst
@@ -108,7 +108,7 @@
                      Usage:
 
                      This property provides the Object ID of public key
-                     provided in the certificate which the help of which
+                     provided in the certificate with the help of which
                      public key information can be extracted.
 
                      Value type: <string>
@@ -122,7 +122,7 @@
                      Usage:
 
                      This property provides the Object ID of hash provided in
-                     the certificate which the help of which hash information
+                     the certificate with the help of which hash information
                      can be extracted.
 
                      Value type: <string>
@@ -138,7 +138,7 @@
          trusted-key-cert: trusted-key-cert {
             root-certificate;
             image-id = <TRUSTED_KEY_CERT_ID>;
-            antirollback-counter = <&trusted_nv_counter>;
+            antirollback-counter = <&trusted_nv_ctr>;
 
             trusted-world-pk: trusted-world-pk {
                oid = TRUSTED_WORLD_PK_OID;
@@ -152,7 +152,7 @@
             image-id = <SCP_FW_KEY_CERT_ID>;
             parent = <&trusted-key-cert>;
             signing-key = <&trusted_world_pk>;
-            antirollback-counter = <&trusted_nv_counter>;
+            antirollback-counter = <&trusted_nv_ctr>;
 
             scp_fw_content_pk: scp_fw_content_pk {
                oid = SCP_FW_CONTENT_CERT_PK_OID;
@@ -312,13 +312,13 @@
         #address-cells = <1>;
         #size-cells = <0>;
 
-        trusted-nv-counter: trusted_nv_counter {
+        trusted_nv_ctr: trusted_nv_ctr {
            id  = <TRUSTED_NV_CTR_ID>;
            reg = <TFW_NVCTR_BASE>;
            oid = TRUSTED_FW_NVCOUNTER_OID;
         };
 
-        non_trusted_nv_counter: non_trusted_nv_counter {
+        non_trusted_nv_ctr: non_trusted_nv_ctr {
            id  = <NON_TRUSTED_NV_CTR_ID>;
            reg = <NTFW_CTR_BASE>;
            oid = NON_TRUSTED_FW_NVCOUNTER_OID;
diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst
index ee322ac..2b6382b 100644
--- a/docs/components/ffa-manifest-binding.rst
+++ b/docs/components/ffa-manifest-binding.rst
@@ -1,5 +1,5 @@
 FF-A manifest binding to device tree
-========================================
+====================================
 
 This document defines the nodes and properties used to define a partition,
 according to the FF-A specification.
@@ -82,7 +82,7 @@
      the partition. Absence of this field indicates that the entry point is at
      offset 0x0 from the base of the partition's binary.
 
-- xlat-granule [mandatory]
+- xlat-granule
    - value type: <u32>
    - Translation granule used with the partition:
 
@@ -91,10 +91,10 @@
       - 0x2: 64k
 
 - boot-order
-   - value type: <u16>
+   - value type: <u32>
    - A unique number amongst all partitions that specifies if this partition
      must be booted before others. The partition with the smaller number will be
-     booted first.
+     booted first. Highest vlue allowed for this field is 0xFFFF.
 
 - rx-tx-buffer
    - value type: "memory-regions" node
@@ -103,13 +103,15 @@
      The "compatible" must be the string "arm,ffa-manifest-rx_tx-buffer".
 
 - messaging-method [mandatory]
-   - value type: <u8>
+   - value type: <u32>
    - Specifies which messaging methods are supported by the partition, set bit
      means the feature is supported, clear bit - not supported:
 
-      - Bit[0]: partition can receive direct requests if set
-      - Bit[1]: partition can send direct requests if set
+      - Bit[0]: partition can receive direct requests via FFA_MSG_SEND_DIRECT_REQ ABI if set
+      - Bit[1]: partition can send direct requests via FFA_MSG_SEND_DIRECT_REQ ABI if set
       - Bit[2]: partition can send and receive indirect messages
+      - Bit[9]: partition can receive direct requests via FFA_MSG_SEND_DIRECT_REQ2 ABI if set
+      - Bit[10]: partition can send direct requests via FFA_MSG_SEND_DIRECT_REQ2 ABI if set
 
 - managed-exit
    - value type: <empty>
@@ -117,6 +119,11 @@
    - This field is deprecated in favor of ns-interrupts-action field in the FF-A
      v1.1 EAC0 spec.
 
+- managed-exit-virq
+   - value type: <empty>
+   - Indicates if the partition needs managed exit, if supported, to be signaled
+     through vIRQ signal.
+
 - ns-interrupts-action [mandatory]
    - value type: <u32>
    - Specifies the action that the SPMC must take in response to a Non-secure
@@ -157,11 +164,6 @@
      the FF-A boot information blob to be passed in the specified general purpose
      register.
 
-- stream-endpoint-ids
-   - value type: <prop-encoded-array>
-   - List of <u32> tuples, identifying the IDs this partition is acting as
-     proxy for.
-
 - power-management-messages
    - value type: <u32>
    - Specifies which power management messages a partition subscribes to.
@@ -172,6 +174,17 @@
       - Bit[1]: CPU_SUSPEND
       - Bit[2]: CPU_SUSPEND_RESUME
 
+- vm-availability-messages
+   - value type: <u32>
+   - Specifies which VM availability messages a partition subscribes to. A set
+     bit means the partition should be informed of the event, clear bit - should
+     not be informed of event:
+
+      - Bit[0]: VM created
+      - Bit[1]: VM destroyed
+
+.. _memory_region_node:
+
 Memory Regions
 --------------
 
@@ -209,6 +222,33 @@
      then communicate the region properties (including the base address chosen
      by the partition manager) to the partition.
 
+- load-address-relative-offset
+   - value type: <u64>
+   - Offset relative to the load address of the partition.
+     When this is provided in the partition manifest, it should be added to the
+     load address to get the base address of the region. The secure partition
+     manifest can have either "base-address" or "load-address-relative-offset".
+     It cannot have both.
+
+- stream-ids
+   - value type: <prop-encoded-array>
+   - List of IDs belonging to a DMA capable peripheral device that has access to
+     the memory region represented by current node.
+   - Each ID must have been declared in exactly one device region node.
+
+- smmu-id
+   - value type: <u32>
+   - Identifies the SMMU IP that enforces the access control for the DMA device
+     that owns the above stream-ids.
+
+- stream-ids-access-permissions
+   - value type: <prop-encoded-array>
+   - List of attributes representing the instruction and data access permissions
+     used by the DMA device streams to access the memory region represented by
+     current node.
+
+.. _device_region_node:
+
 Device Regions
 --------------
 
@@ -251,11 +291,10 @@
 
 - stream-ids
    - value type: <prop-encoded-array>
-   - A list of (id, mem-manage) pair, where:
+   - List of IDs where an ID is a unique <u32> value amongst all devices assigned
+     to the partition.
 
-      - id: A unique <u32> value amongst all devices assigned to the partition.
-
-- interrupts [mandatory]
+- interrupts
    - value type: <prop-encoded-array>
    - A list of (id, attributes) pair describing the device interrupts, where:
 
@@ -306,4 +345,4 @@
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 5fbd7fd..03703bc 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -52,7 +52,7 @@
   - ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
     consistency with the versioning schemes used in other parts of RMM.
 
-This document specifies the 0.2 version of Boot Interface ABI and RMM-EL3
+This document specifies the 0.3 version of Boot Interface ABI and RMM-EL3
 services specification and the 0.3 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
@@ -238,6 +238,7 @@
    ``E_RMM_BAD_PAS``,Incorrect PAS,-3
    ``E_RMM_NOMEM``,Not enough memory to perform an operation,-4
    ``E_RMM_INVAL``,The value of an argument was invalid,-5
+   ``E_RMM_AGAIN``,The resource is busy. Try again.,-6
 
 If multiple failure conditions are detected in an RMM to EL3 command, then EL3
 is allowed to return an error code corresponding to any of the failure
@@ -442,7 +443,21 @@
 RMM_ATTEST_GET_PLAT_TOKEN command
 =================================
 
-Retrieve the Platform Token from EL3.
+Retrieve the Platform Token from EL3. If the entire token does not fit in the
+buffer, EL3 returns a hunk of the token (via ``tokenHunkSize`` parameter) and
+indicates the remaining bytes that are pending retrieval (via ``remainingSize``
+parameter). The challenge object for the platform token must be populated in
+the buffer for the first call of this command and the size of the object is
+indicated by ``c_size`` parameter. Subsequent calls to retrieve remaining hunks of
+the token must be made with ``c_size`` as 0.
+
+If ``c_size`` is not 0, this command could cause regeneration of platform token
+and will return token hunk corresponding to beginning of the token.
+
+It is valid for the calls of this command to return ``E_RMM_AGAIN`` error,
+which is an indication to the caller to retry this command again. Depending on the
+platform, this mechanism can be used to implement queuing to HES, if HES is
+involved in platform token generation.
 
 FID
 ---
@@ -457,9 +472,9 @@
    :widths: 1 1 1 1 5
 
    fid,x0,[63:0],UInt64,Command FID
-   buf_pa,x1,[63:0],Address,PA of the platform attestation token. The challenge object is passed in this buffer. The PA must belong to the shared buffer
+   buf_pa,x1,[63:0],Address,"PA of the platform attestation token. The challenge object must be passed in this buffer for the first call of this command. Any subsequent calls, if required to retrieve the full token, should not have this object. The PA must belong to the shared buffer."
    buf_size,x2,[63:0],Size,Size in bytes of the platform attestation token buffer. ``bufPa + bufSize`` must lie within the shared buffer
-   c_size,x3,[63:0],Size,Size in bytes of the challenge object. It corresponds to the size of one of the defined SHA algorithms
+   c_size,x3,[63:0],Size,"Size in bytes of the challenge object. It corresponds to the size of one of the defined SHA algorithms. Any subsequent calls, if required to retrieve the full token, should set this size to 0."
 
 Output values
 -------------
@@ -469,7 +484,8 @@
    :widths: 1 1 1 1 5
 
    Result,x0,[63:0],Error Code,Command return status
-   tokenSize,x1,[63:0],Size,Size of the platform token
+   tokenHunkSize,x1,[63:0],Size,Size of the platform token hunk retrieved
+   remainingSize,x2,[63:0],Size,Remaining bytes of the token that are pending retrieval
 
 Failure conditions
 ------------------
@@ -481,9 +497,11 @@
    :header: "ID", "Condition"
    :widths: 1 5
 
+   ``E_RMM_AGAIN``,Resource for Platform token retrieval is busy. Try again.
    ``E_RMM_BAD_ADDR``,``PA`` is outside the shared buffer
    ``E_RMM_INVAL``,``PA + BSize`` is outside the shared buffer
-   ``E_RMM_INVAL``,``CSize`` does not represent the size of a supported SHA algorithm
+   ``E_RMM_INVAL``,``CSize`` does not represent the size of a supported SHA algorithm for the first call to this command
+   ``E_RMM_INVAL``,``CSize`` is not 0 for subsequent calls to retrieve remaining hunks of the token
    ``E_RMM_UNK``,An unknown error occurred whilst processing the command
    ``E_RMM_OK``,No errors detected
 
diff --git a/docs/components/romlib-design.rst b/docs/components/romlib-design.rst
index 62c173a..c0f3ed3 100644
--- a/docs/components/romlib-design.rst
+++ b/docs/components/romlib-design.rst
@@ -71,6 +71,15 @@
 The "library at ROM" contains a necessary init function that initialises the
 global variables defined by the functions inside "library at ROM".
 
+Wrapper functions are specified at the link stage of compilation and cannot
+interpose uppon functions within the same translation unit. For example, if
+function ``fn_a`` calls ``fn_b`` within translation unit ``functions.c`` and
+the romlib jump table includes an entry for ``fn_b``, ``fn_a`` will include
+a reference to ``fn_b``'s original program text instead of the wrapper. Thus
+the jumptable author must take care to include public entry points into
+translation units to avoid paying the program text cost twice, once in the
+original executable and once in romlib.
+
 Script
 ~~~~~~
 
@@ -86,7 +95,7 @@
 
 3. ``romlib_generator.py genwrappers [args]`` - Generates a wrapper function for
    each entry in the index file except for the ones that contain the keyword
-   ``patch``. The generated wrapper file is called ``<fn_name>.s``.
+   ``patch``. The generated wrapper file is called ``wrappers.s``.
 
 4. ``romlib_generator.py pre [args]`` - Preprocesses the index file which means
    it resolves all the include commands in the file recursively. It can also
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index b6f4219..220c3ce 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -10,42 +10,12 @@
 ========
 
 +--------+--------------------------------------+
-| CoT    | Chain of Trust                       |
-+--------+--------------------------------------+
-| DMA    | Direct Memory Access                 |
-+--------+--------------------------------------+
-| DTB    | Device Tree Blob                     |
-+--------+--------------------------------------+
 | DTS    | Device Tree Source                   |
 +--------+--------------------------------------+
-| EC     | Execution Context                    |
-+--------+--------------------------------------+
-| FIP    | Firmware Image Package               |
-+--------+--------------------------------------+
 | FF-A   | Firmware Framework for Arm A-profile |
 +--------+--------------------------------------+
-| IPA    | Intermediate Physical Address        |
-+--------+--------------------------------------+
-| JOP    | Jump-Oriented Programming            |
-+--------+--------------------------------------+
 | NWd    | Normal World                         |
 +--------+--------------------------------------+
-| ODM    | Original Design Manufacturer         |
-+--------+--------------------------------------+
-| OEM    | Original Equipment Manufacturer      |
-+--------+--------------------------------------+
-| PA     | Physical Address                     |
-+--------+--------------------------------------+
-| PE     | Processing Element                   |
-+--------+--------------------------------------+
-| PM     | Power Management                     |
-+--------+--------------------------------------+
-| PVM    | Primary VM                           |
-+--------+--------------------------------------+
-| ROP    | Return-Oriented Programming          |
-+--------+--------------------------------------+
-| SMMU   | System Memory Management Unit        |
-+--------+--------------------------------------+
 | SP     | Secure Partition                     |
 +--------+--------------------------------------+
 | SPD    | Secure Payload Dispatcher            |
@@ -56,16 +26,8 @@
 +--------+--------------------------------------+
 | SPMD   | SPM Dispatcher                       |
 +--------+--------------------------------------+
-| SiP    | Silicon Provider                     |
-+--------+--------------------------------------+
 | SWd    | Secure World                         |
 +--------+--------------------------------------+
-| TLV    | Tag-Length-Value                     |
-+--------+--------------------------------------+
-| TOS    | Trusted Operating System             |
-+--------+--------------------------------------+
-| VM     | Virtual Machine                      |
-+--------+--------------------------------------+
 
 Foreword
 ========
@@ -74,34 +36,14 @@
 codebase:
 
 #. S-EL2 SPMC based on the FF-A specification `[1]`_, enabling virtualization in
-   the secure world, managing multiple S-EL1 or S-EL0 partitions.
+   the secure world, managing multiple S-EL1 or S-EL0 partitions `[5]`_.
 #. EL3 SPMC based on the FF-A specification, managing a single S-EL1 partition
-   without virtualization in the secure world.
+   without virtualization in the secure world `[6]`_.
 #. EL3 SPM based on the MM specification, legacy implementation managing a
    single S-EL0 partition `[2]`_.
 
 These implementations differ in their respective SW architecture and only one
-can be selected at build time. This document:
-
-- describes the implementation from bullet 1. when the SPMC resides at S-EL2.
-- is not an architecture specification and it might provide assumptions
-  on sections mandated as implementation-defined in the specification.
-- covers the implications to TF-A used as a bootloader, and Hafnium used as a
-  reference code base for an S-EL2/SPMC secure firmware on platforms
-  implementing the FEAT_SEL2 architecture extension.
-
-Terminology
------------
-
-- The term Hypervisor refers to the NS-EL2 component managing Virtual Machines
-  (or partitions) in the normal world.
-- The term SPMC refers to the S-EL2 component managing secure partitions in
-  the secure world when the FEAT_SEL2 architecture extension is implemented.
-- Alternatively, SPMC can refer to an S-EL1 component, itself being a secure
-  partition and implementing the FF-A ABI on platforms not implementing the
-  FEAT_SEL2 architecture extension.
-- The term VM refers to a normal world Virtual Machine managed by an Hypervisor.
-- The term SP refers to a secure world "Virtual Machine" managed by an SPMC.
+can be selected at build time.
 
 Support for legacy platforms
 ----------------------------
@@ -123,16 +65,6 @@
 - S-EL2 SPMC for platforms implementing the FEAT_SEL2 architecture
   extension. The SPMD relays the FF-A protocol from EL3 to S-EL2.
 
-Sample reference stack
-======================
-
-The following diagram illustrates a possible configuration when the
-FEAT_SEL2 architecture extension is implemented, showing the SPMD
-and SPMC, one or multiple secure partitions, with an optional
-Hypervisor:
-
-.. image:: ../resources/diagrams/ff-a-spm-sel2.png
-
 TF-A build options
 ==================
 
@@ -147,16 +79,15 @@
   level to being at S-EL2. It defaults to enabled (value 1) when
   SPD=spmd is chosen.
 - **SPMC_AT_EL3**: this option adjusts the SPMC exception level to being
-  at EL3.
-- If neither ``SPMD_SPM_AT_SEL2`` or ``SPMC_AT_EL3`` are enabled the SPMC
-  exception level is set to S-EL1.
+  at EL3. If neither ``SPMD_SPM_AT_SEL2`` or ``SPMC_AT_EL3`` are enabled the
+  SPMC exception level is set to S-EL1.
   ``SPMD_SPM_AT_SEL2`` is enabled. The context save/restore routine
   and exhaustive list of registers is visible at `[4]`_.
 - **SPMC_AT_EL3_SEL0_SP**: this option enables the support to load SEL0 SP
   when SPMC at EL3 support is enabled.
 - **SP_LAYOUT_FILE**: this option specifies a text description file
   providing paths to SP binary images and manifests in DTS format
-  (see `Describing secure partitions`_). It
+  (see `[3]`_). It
   is required when ``SPMD_SPM_AT_SEL2`` is enabled hence when multiple
   secure partitions are to be loaded by BL2 on behalf of the SPMC.
 
@@ -275,1358 +206,28 @@
     PLAT=fvp \
     all fip
 
-FVP model invocation
-====================
-
-The FVP command line needs the following options to exercise the S-EL2 SPMC:
-
-+---------------------------------------------------+------------------------------------+
-| - cluster0.has_arm_v8-5=1                         | Implements FEAT_SEL2, FEAT_PAuth,  |
-| - cluster1.has_arm_v8-5=1                         | and FEAT_BTI.                      |
-+---------------------------------------------------+------------------------------------+
-| - pci.pci_smmuv3.mmu.SMMU_AIDR=2                  | Parameters required for the        |
-| - pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B         | SMMUv3.2 modeling.                 |
-| - pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002         |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714             |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0472         |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002       |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_S_IDR2=0                |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_S_IDR3=0                |                                    |
-+---------------------------------------------------+------------------------------------+
-| - cluster0.has_branch_target_exception=1          | Implements FEAT_BTI.               |
-| - cluster1.has_branch_target_exception=1          |                                    |
-+---------------------------------------------------+------------------------------------+
-| - cluster0.has_pointer_authentication=2           | Implements FEAT_PAuth              |
-| - cluster1.has_pointer_authentication=2           |                                    |
-+---------------------------------------------------+------------------------------------+
-| - cluster0.memory_tagging_support_level=2         | Implements FEAT_MTE2               |
-| - cluster1.memory_tagging_support_level=2         |                                    |
-| - bp.dram_metadata.is_enabled=1                   |                                    |
-+---------------------------------------------------+------------------------------------+
-
-Sample FVP command line invocation:
-
-.. code:: shell
-
-    <path-to-fvp-model>/FVP_Base_RevC-2xAEMvA -C pctl.startup=0.0.0.0 \
-    -C cluster0.NUM_CORES=4 -C cluster1.NUM_CORES=4 -C bp.secure_memory=1 \
-    -C bp.secureflashloader.fname=trusted-firmware-a/build/fvp/debug/bl1.bin \
-    -C bp.flashloader0.fname=trusted-firmware-a/build/fvp/debug/fip.bin \
-    -C bp.pl011_uart0.out_file=fvp-uart0.log -C bp.pl011_uart1.out_file=fvp-uart1.log \
-    -C bp.pl011_uart2.out_file=fvp-uart2.log \
-    -C cluster0.has_arm_v8-5=1 -C cluster1.has_arm_v8-5=1 \
-    -C cluster0.has_pointer_authentication=2 -C cluster1.has_pointer_authentication=2 \
-    -C cluster0.has_branch_target_exception=1 -C cluster1.has_branch_target_exception=1 \
-    -C cluster0.memory_tagging_support_level=2 -C cluster1.memory_tagging_support_level=2 \
-    -C bp.dram_metadata.is_enabled=1 \
-    -C pci.pci_smmuv3.mmu.SMMU_AIDR=2 -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B \
-    -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002 -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714 \
-    -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0472 -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002 \
-    -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0 -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0
-
 Boot process
 ============
 
-Loading Hafnium and secure partitions in the secure world
----------------------------------------------------------
-
-TF-A BL2 is the bootlader for the SPMC and SPs in the secure world.
-
-SPs may be signed by different parties (SiP, OEM/ODM, TOS vendor, etc.).
-Thus they are supplied as distinct signed entities within the FIP flash
-image. The FIP image itself is not signed hence this provides the ability
-to upgrade SPs in the field.
-
-Booting through TF-A
---------------------
-
-SP manifests
-~~~~~~~~~~~~
-
-An SP manifest describes SP attributes as defined in `[1]`_
-(partition manifest at virtual FF-A instance) in DTS format. It is
-represented as a single file associated with the SP. A sample is
-provided by `[5]`_. A binding document is provided by `[6]`_.
-
-Secure Partition packages
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Secure partitions are bundled as independent package files consisting
-of:
-
-- a header
-- a DTB
-- an image payload
-
-The header starts with a magic value and offset values to SP DTB and
-image payload. Each SP package is loaded independently by BL2 loader
-and verified for authenticity and integrity.
-
-The SP package identified by its UUID (matching FF-A uuid property) is
-inserted as a single entry into the FIP at end of the TF-A build flow
-as shown:
-
-.. code:: shell
-
-    Trusted Boot Firmware BL2: offset=0x1F0, size=0x8AE1, cmdline="--tb-fw"
-    EL3 Runtime Firmware BL31: offset=0x8CD1, size=0x13000, cmdline="--soc-fw"
-    Secure Payload BL32 (Trusted OS): offset=0x1BCD1, size=0x15270, cmdline="--tos-fw"
-    Non-Trusted Firmware BL33: offset=0x30F41, size=0x92E0, cmdline="--nt-fw"
-    HW_CONFIG: offset=0x3A221, size=0x2348, cmdline="--hw-config"
-    TB_FW_CONFIG: offset=0x3C569, size=0x37A, cmdline="--tb-fw-config"
-    SOC_FW_CONFIG: offset=0x3C8E3, size=0x48, cmdline="--soc-fw-config"
-    TOS_FW_CONFIG: offset=0x3C92B, size=0x427, cmdline="--tos-fw-config"
-    NT_FW_CONFIG: offset=0x3CD52, size=0x48, cmdline="--nt-fw-config"
-    B4B5671E-4A90-4FE1-B81F-FB13DAE1DACB: offset=0x3CD9A, size=0xC168, cmdline="--blob"
-    D1582309-F023-47B9-827C-4464F5578FC8: offset=0x48F02, size=0xC168, cmdline="--blob"
-
-.. uml:: ../resources/diagrams/plantuml/fip-secure-partitions.puml
-
-Describing secure partitions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A json-formatted description file is passed to the build flow specifying paths
-to the SP binary image and associated DTS partition manifest file. The latter
-is processed by the dtc compiler to generate a DTB fed into the SP package.
-Optionally, the partition's json description can contain offsets for both
-the image and partition manifest within the SP package. Both offsets need to be
-4KB aligned, because it is the translation granule supported by Hafnium SPMC.
-These fields can be leveraged to support SPs with S1 translation granules that
-differ from 4KB, and to configure the regions allocated within the SP package,
-as well as to comply with the requirements for the implementation of the boot
-information protocol (see `Passing boot data to the SP`_ for more details). In
-case the offsets are absent in their json node, they default to 0x1000 and
-0x4000 for the manifest offset and image offset respectively.
-This file also specifies the SP owner (as an optional field) identifying the
-signing domain in case of dual root CoT.
-The SP owner can either be the silicon or the platform provider. The
-corresponding "owner" field value can either take the value of "SiP" or "Plat".
-In absence of "owner" field, it defaults to "SiP" owner.
-The UUID of the partition can be specified as a field in the description file or
-if it does not exist there the UUID is extracted from the DTS partition
-manifest.
-
-.. code:: shell
-
-    {
-        "tee1" : {
-            "image": "tee1.bin",
-             "pm": "tee1.dts",
-             "owner": "SiP",
-             "uuid": "1b1820fe-48f7-4175-8999-d51da00b7c9f"
-        },
-
-        "tee2" : {
-            "image": "tee2.bin",
-            "pm": "tee2.dts",
-            "owner": "Plat"
-        },
-
-        "tee3" : {
-            "image": {
-                "file": "tee3.bin",
-                "offset":"0x2000"
-             },
-            "pm": {
-                "file": "tee3.dts",
-                "offset":"0x6000"
-             },
-            "owner": "Plat"
-        },
-    }
-
-SPMC manifest
-~~~~~~~~~~~~~
-
-This manifest contains the SPMC *attribute* node consumed by the SPMD at boot
-time. It implements `[1]`_ (SP manifest at physical FF-A instance) and serves
-two different cases:
-
-- The SPMC resides at S-EL1: the SPMC manifest is used by the SPMD to setup a
-  SP that co-resides with the SPMC and executes at S-EL1 or Secure Supervisor
-  mode.
-- The SPMC resides at S-EL2: the SPMC manifest is used by the SPMD to setup
-  the environment required by the SPMC to run at S-EL2. SPs run at S-EL1 or
-  S-EL0.
-
-.. code:: shell
-
-    attribute {
-        spmc_id = <0x8000>;
-        maj_ver = <0x1>;
-        min_ver = <0x1>;
-        exec_state = <0x0>;
-        load_address = <0x0 0x6000000>;
-        entrypoint = <0x0 0x6000000>;
-        binary_size = <0x60000>;
-    };
-
-- *spmc_id* defines the endpoint ID value that SPMC can query through
-  ``FFA_ID_GET``.
-- *maj_ver/min_ver*. SPMD checks provided version versus its internal
-  version and aborts if not matching.
-- *exec_state* defines the SPMC execution state (AArch64 or AArch32).
-  Notice Hafnium used as a SPMC only supports AArch64.
-- *load_address* and *binary_size* are mostly used to verify secondary
-  entry points fit into the loaded binary image.
-- *entrypoint* defines the cold boot primary core entry point used by
-  SPMD (currently matches ``BL32_BASE``) to enter the SPMC.
-
-Other nodes in the manifest are consumed by Hafnium in the secure world.
-A sample can be found at `[7]`_:
-
-- The *hypervisor* node describes SPs. *is_ffa_partition* boolean attribute
-  indicates a FF-A compliant SP. The *load_address* field specifies the load
-  address at which BL2 loaded the SP package.
-- *cpus* node provide the platform topology and allows MPIDR to VMPIDR mapping.
-  Note the primary core is declared first, then secondary cores are declared
-  in reverse order.
-- The *memory* nodes provide platform information on the ranges of memory
-  available for use by SPs at runtime. These ranges relate to either
-  secure or non-secure memory, depending on the *device_type* field.
-  If the field specifies "memory" the range is secure, else if it specifies
-  "ns-memory" the memory is non-secure. The system integrator must exclude
-  the memory used by other components that are not SPs, such as the monitor,
-  or the SPMC itself, the OS Kernel/Hypervisor, or other NWd VMs. The SPMC
-  limits the SP's address space such that they do not access memory outside
-  of those ranges.
+The boot process involving SPMC is highly dependent on the SPMC implementation.
+It is recommended to refer to corresponding SPMC documentation for further
+details. Some aspects of boot process are described here in the greater interest
+of the project.
 
 SPMC boot
-~~~~~~~~~
+---------
 
-The SPMC is loaded by BL2 as the BL32 image.
+When SPMC resides at a lower EL i.e., S-EL1 or S-EL2, it is loaded by BL2 as the
+BL32 image. The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image `[7]`_.
 
-The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image `[9]`_.
-
-BL2 passes the SPMC manifest address to BL31 through a register.
-
-At boot time, the SPMD in BL31 runs from the primary core, initializes the core
-contexts and launches the SPMC (BL32) passing the following information through
-registers:
+BL2 passes the SPMC manifest address to BL31 through a register. At boot time,
+the SPMD in BL31 runs from the primary core, initializes the core contexts and
+launches the SPMC (BL32) passing the following information through registers:
 
 - X0 holds the ``TOS_FW_CONFIG`` physical address (or SPMC manifest blob).
 - X1 holds the ``HW_CONFIG`` physical address.
 - X4 holds the currently running core linear id.
 
-Loading of SPs
-~~~~~~~~~~~~~~
-
-At boot time, BL2 loads SPs sequentially in addition to the SPMC as depicted
-below:
-
-.. uml:: ../resources/diagrams/plantuml/bl2-loading-sp.puml
-
-Note this boot flow is an implementation sample on Arm's FVP platform.
-Platforms not using TF-A's *Firmware CONFiguration* framework would adjust to a
-different boot flow. The flow restricts to a maximum of 8 secure partitions.
-
-Secure boot
-~~~~~~~~~~~
-
-The SP content certificate is inserted as a separate FIP item so that BL2 loads SPMC,
-SPMC manifest, secure partitions and verifies them for authenticity and integrity.
-Refer to TBBR specification `[3]`_.
-
-The multiple-signing domain feature (in current state dual signing domain `[8]`_) allows
-the use of two root keys namely S-ROTPK and NS-ROTPK:
-
-- SPMC (BL32) and SPMC manifest are signed by the SiP using the S-ROTPK.
-- BL33 may be signed by the OEM using NS-ROTPK.
-- An SP may be signed either by SiP (using S-ROTPK) or by OEM (using NS-ROTPK).
-- A maximum of 4 partitions can be signed with the S-ROTPK key and 4 partitions
-  signed with the NS-ROTPK key.
-
-Also refer to `Describing secure partitions`_ and `TF-A build options`_ sections.
-
-Hafnium in the secure world
-===========================
-
-General considerations
-----------------------
-
-Build platform for the secure world
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In the Hafnium reference implementation specific code parts are only relevant to
-the secure world. Such portions are isolated in architecture specific files
-and/or enclosed by a ``SECURE_WORLD`` macro.
-
-Secure partitions scheduling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The FF-A specification `[1]`_ provides two ways to relinquinsh CPU time to
-secure partitions. For this a VM (Hypervisor or OS kernel), or SP invokes one of:
-
-- the FFA_MSG_SEND_DIRECT_REQ interface.
-- the FFA_RUN interface.
-
-Additionally a secure interrupt can pre-empt the normal world execution and give
-CPU cycles by transitioning to EL3 and S-EL2.
-
-Platform topology
-~~~~~~~~~~~~~~~~~
-
-The *execution-ctx-count* SP manifest field can take the value of one or the
-total number of PEs. The FF-A specification `[1]`_  recommends the
-following SP types:
-
-- Pinned MP SPs: an execution context matches a physical PE. MP SPs must
-  implement the same number of ECs as the number of PEs in the platform.
-- Migratable UP SPs: a single execution context can run and be migrated on any
-  physical PE. Such SP declares a single EC in its SP manifest. An UP SP can
-  receive a direct message request originating from any physical core targeting
-  the single execution context.
-
-Parsing SP partition manifests
-------------------------------
-
-Hafnium consumes SP manifests as defined in `[1]`_ and `SP manifests`_.
-Note the current implementation may not implement all optional fields.
-
-The SP manifest may contain memory and device regions nodes. In case of
-an S-EL2 SPMC:
-
-- Memory regions are mapped in the SP EL1&0 Stage-2 translation regime at
-  load time (or EL1&0 Stage-1 for an S-EL1 SPMC). A memory region node can
-  specify RX/TX buffer regions in which case it is not necessary for an SP
-  to explicitly invoke the ``FFA_RXTX_MAP`` interface. The memory referred
-  shall be contained within the memory ranges defined in SPMC manifest. The
-  NS bit in the attributes field should be consistent with the security
-  state of the range that it relates to. I.e. non-secure memory shall be
-  part of a non-secure memory range, and secure memory shall be contained
-  in a secure memory range of a given platform.
-- Device regions are mapped in the SP EL1&0 Stage-2 translation regime (or
-  EL1&0 Stage-1 for an S-EL1 SPMC) as peripherals and possibly allocate
-  additional resources (e.g. interrupts).
-
-For the S-EL2 SPMC, base addresses for memory and device region nodes are IPAs
-provided the SPMC identity maps IPAs to PAs within SP EL1&0 Stage-2 translation
-regime.
-
-Note: in the current implementation both VTTBR_EL2 and VSTTBR_EL2 point to the
-same set of page tables. It is still open whether two sets of page tables shall
-be provided per SP. The memory region node as defined in the specification
-provides a memory security attribute hinting to map either to the secure or
-non-secure EL1&0 Stage-2 table if it exists.
-
-Passing boot data to the SP
----------------------------
-
-In `[1]`_ , the section  "Boot information protocol" defines a method for passing
-data to the SPs at boot time. It specifies the format for the boot information
-descriptor and boot information header structures, which describe the data to be
-exchanged between SPMC and SP.
-The specification also defines the types of data that can be passed.
-The aggregate of both the boot info structures and the data itself is designated
-the boot information blob, and is passed to a Partition as a contiguous memory
-region.
-
-Currently, the SPM implementation supports the FDT type which is used to pass the
-partition's DTB manifest.
-
-The region for the boot information blob is allocated through the SP package.
-
-.. image:: ../resources/diagrams/partition-package.png
-
-To adjust the space allocated for the boot information blob, the json description
-of the SP (see section `Describing secure partitions`_) shall be updated to contain
-the manifest offset. If no offset is provided the manifest offset defaults to 0x1000,
-which is the page size in the Hafnium SPMC.
-
-The configuration of the boot protocol is done in the SPs manifest. As defined by
-the specification, the manifest field 'gp-register-num' configures the GP register
-which shall be used to pass the address to the partitions boot information blob when
-booting the partition.
-In addition, the Hafnium SPMC implementation requires the boot information arguments
-to be listed in a designated DT node:
-
-.. code:: shell
-
-  boot-info {
-      compatible = "arm,ffa-manifest-boot-info";
-      ffa_manifest;
-  };
-
-The whole secure partition package image (see `Secure Partition packages`_) is
-mapped to the SP secure EL1&0 Stage-2 translation regime. As such, the SP can
-retrieve the address for the boot information blob in the designated GP register,
-process the boot information header and descriptors, access its own manifest
-DTB blob and extract its partition manifest properties.
-
-SP Boot order
--------------
-
-SP manifests provide an optional boot order attribute meant to resolve
-dependencies such as an SP providing a service required to properly boot
-another SP. SPMC boots the SPs in accordance to the boot order attribute,
-lowest to the highest value. If the boot order attribute is absent from the FF-A
-manifest, the SP is treated as if it had the highest boot order value
-(i.e. lowest booting priority).
-
-It is possible for an SP to call into another SP through a direct request
-provided the latter SP has already been booted.
-
-Boot phases
------------
-
-Primary core boot-up
-~~~~~~~~~~~~~~~~~~~~
-
-Upon boot-up, BL31 hands over to the SPMC (BL32) on the primary boot physical
-core. The SPMC performs its platform initializations and registers the SPMC
-secondary physical core entry point physical address by the use of the
-`FFA_SECONDARY_EP_REGISTER`_ interface (SMC invocation from the SPMC to the SPMD
-at secure physical FF-A instance).
-
-The SPMC then creates secure partitions based on SP packages and manifests. Each
-secure partition is launched in sequence (`SP Boot order`_) on their "primary"
-execution context. If the primary boot physical core linear id is N, an MP SP is
-started using EC[N] on PE[N] (see `Platform topology`_). If the partition is a
-UP SP, it is started using its unique EC0 on PE[N].
-
-The SP primary EC (or the EC used when the partition is booted as described
-above):
-
-- Performs the overall SP boot time initialization, and in case of a MP SP,
-  prepares the SP environment for other execution contexts.
-- In the case of a MP SP, it invokes the FFA_SECONDARY_EP_REGISTER at secure
-  virtual FF-A instance (SMC invocation from SP to SPMC) to provide the IPA
-  entry point for other execution contexts.
-- Exits through ``FFA_MSG_WAIT`` to indicate successful initialization or
-  ``FFA_ERROR`` in case of failure.
-
-Secondary cores boot-up
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Once the system is started and NWd brought up, a secondary physical core is
-woken up by the ``PSCI_CPU_ON`` service invocation. The TF-A SPD hook mechanism
-calls into the SPMD on the newly woken up physical core. Then the SPMC is
-entered at the secondary physical core entry point.
-
-In the current implementation, the first SP is resumed on the coresponding EC
-(the virtual CPU which matches the physical core). The implication is that the
-first SP must be a MP SP.
-
-In a linux based system, once secure and normal worlds are booted but prior to
-a NWd FF-A driver has been loaded:
-
-- The first SP has initialized all its ECs in response to primary core boot up
-  (at system initialization) and secondary core boot up (as a result of linux
-  invoking PSCI_CPU_ON for all secondary cores).
-- Other SPs have their first execution context initialized as a result of secure
-  world initialization on the primary boot core. Other ECs for those SPs have to
-  be run first through ffa_run to complete their initialization (which results
-  in the EC completing with FFA_MSG_WAIT).
-
-Refer to `Power management`_ for further details.
-
-Notifications
--------------
-
-The FF-A v1.1 specification `[1]`_ defines notifications as an asynchronous
-communication mechanism with non-blocking semantics. It allows for one FF-A
-endpoint to signal another for service provision, without hindering its current
-progress.
-
-Hafnium currently supports 64 notifications. The IDs of each notification define
-a position in a 64-bit bitmap.
-
-The signaling of notifications can interchangeably happen between NWd and SWd
-FF-A endpoints.
-
-The SPMC is in charge of managing notifications from SPs to SPs, from SPs to
-VMs, and from VMs to SPs. An hypervisor component would only manage
-notifications from VMs to VMs. Given the SPMC has no visibility of the endpoints
-deployed in NWd, the Hypervisor or OS kernel must invoke the interface
-FFA_NOTIFICATION_BITMAP_CREATE to allocate the notifications bitmap per FF-A
-endpoint in the NWd that supports it.
-
-A sender can signal notifications once the receiver has provided it with
-permissions. Permissions are provided by invoking the interface
-FFA_NOTIFICATION_BIND.
-
-Notifications are signaled by invoking FFA_NOTIFICATION_SET. Henceforth
-they are considered to be in a pending sate. The receiver can retrieve its
-pending notifications invoking FFA_NOTIFICATION_GET, which, from that moment,
-are considered to be handled.
-
-Per the FF-A v1.1 spec, each FF-A endpoint must be associated with a scheduler
-that is in charge of donating CPU cycles for notifications handling. The
-FF-A driver calls FFA_NOTIFICATION_INFO_GET to retrieve the information about
-which FF-A endpoints have pending notifications. The receiver scheduler is
-called and informed by the FF-A driver, and it should allocate CPU cycles to the
-receiver.
-
-There are two types of notifications supported:
-
-- Global, which are targeted to a FF-A endpoint and can be handled within any of
-  its execution contexts, as determined by the scheduler of the system.
-- Per-vCPU, which are targeted to a FF-A endpoint and to be handled within a
-  a specific execution context, as determined by the sender.
-
-The type of a notification is set when invoking FFA_NOTIFICATION_BIND to give
-permissions to the sender.
-
-Notification signaling resorts to two interrupts:
-
-- Schedule Receiver Interrupt: non-secure physical interrupt to be handled by
-  the FF-A driver within the receiver scheduler. At initialization the SPMC
-  donates a SGI ID chosen from the secure SGI IDs range and configures it as
-  non-secure. The SPMC triggers this SGI on the currently running core when
-  there are pending notifications, and the respective receivers need CPU cycles
-  to handle them.
-- Notifications Pending Interrupt: virtual interrupt to be handled by the
-  receiver of the notification. Set when there are pending notifications for the
-  given secure partition. The NPI is pended when the NWd relinquishes CPU cycles
-  to an SP.
-
-The notifications receipt support is enabled in the partition FF-A manifest.
-
-Mandatory interfaces
---------------------
-
-The following interfaces are exposed to SPs:
-
--  ``FFA_VERSION``
--  ``FFA_FEATURES``
--  ``FFA_RX_RELEASE``
--  ``FFA_RXTX_MAP``
--  ``FFA_RXTX_UNMAP``
--  ``FFA_PARTITION_INFO_GET``
--  ``FFA_ID_GET``
--  ``FFA_MSG_WAIT``
--  ``FFA_MSG_SEND_DIRECT_REQ``
--  ``FFA_MSG_SEND_DIRECT_RESP``
--  ``FFA_MEM_DONATE``
--  ``FFA_MEM_LEND``
--  ``FFA_MEM_SHARE``
--  ``FFA_MEM_RETRIEVE_REQ``
--  ``FFA_MEM_RETRIEVE_RESP``
--  ``FFA_MEM_RELINQUISH``
--  ``FFA_MEM_FRAG_RX``
--  ``FFA_MEM_FRAG_TX``
--  ``FFA_MEM_RECLAIM``
--  ``FFA_RUN``
-
-As part of the FF-A v1.1 support, the following interfaces were added:
-
- - ``FFA_NOTIFICATION_BITMAP_CREATE``
- - ``FFA_NOTIFICATION_BITMAP_DESTROY``
- - ``FFA_NOTIFICATION_BIND``
- - ``FFA_NOTIFICATION_UNBIND``
- - ``FFA_NOTIFICATION_SET``
- - ``FFA_NOTIFICATION_GET``
- - ``FFA_NOTIFICATION_INFO_GET``
- - ``FFA_SPM_ID_GET``
- - ``FFA_SECONDARY_EP_REGISTER``
- - ``FFA_MEM_PERM_GET``
- - ``FFA_MEM_PERM_SET``
- - ``FFA_MSG_SEND2``
- - ``FFA_RX_ACQUIRE``
-
-FFA_VERSION
-~~~~~~~~~~~
-
-``FFA_VERSION`` requires a *requested_version* parameter from the caller.
-The returned value depends on the caller:
-
-- Hypervisor or OS kernel in NS-EL1/EL2: the SPMD returns the SPMC version
-  specified in the SPMC manifest.
-- SP: the SPMC returns its own implemented version.
-- SPMC at S-EL1/S-EL2: the SPMD returns its own implemented version.
-
-FFA_FEATURES
-~~~~~~~~~~~~
-
-FF-A features supported by the SPMC may be discovered by secure partitions at
-boot (that is prior to NWd is booted) or run-time.
-
-The SPMC calling FFA_FEATURES at secure physical FF-A instance always get
-FFA_SUCCESS from the SPMD.
-
-The request made by an Hypervisor or OS kernel is forwarded to the SPMC and
-the response relayed back to the NWd.
-
-FFA_RXTX_MAP/FFA_RXTX_UNMAP
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When invoked from a secure partition FFA_RXTX_MAP maps the provided send and
-receive buffers described by their IPAs to the SP EL1&0 Stage-2 translation
-regime as secure buffers in the MMU descriptors.
-
-When invoked from the Hypervisor or OS kernel, the buffers are mapped into the
-SPMC EL2 Stage-1 translation regime and marked as NS buffers in the MMU
-descriptors. The provided addresses may be owned by a VM in the normal world,
-which is expected to receive messages from the secure world. The SPMC will in
-this case allocate internal state structures to facilitate RX buffer access
-synchronization (through FFA_RX_ACQUIRE interface), and to permit SPs to send
-messages.
-
-The FFA_RXTX_UNMAP unmaps the RX/TX pair from the translation regime of the
-caller, either it being the Hypervisor or OS kernel, as well as a secure
-partition.
-
-FFA_PARTITION_INFO_GET
-~~~~~~~~~~~~~~~~~~~~~~
-
-Partition info get call can originate:
-
-- from SP to SPMC
-- from Hypervisor or OS kernel to SPMC. The request is relayed by the SPMD.
-
-FFA_ID_GET
-~~~~~~~~~~
-
-The FF-A id space is split into a non-secure space and secure space:
-
-- FF-A ID with bit 15 clear relates to VMs.
-- FF-A ID with bit 15 set related to SPs.
-- FF-A IDs 0, 0xffff, 0x8000 are assigned respectively to the Hypervisor, SPMD
-  and SPMC.
-
-The SPMD returns:
-
-- The default zero value on invocation from the Hypervisor.
-- The ``spmc_id`` value specified in the SPMC manifest on invocation from
-  the SPMC (see `SPMC manifest`_)
-
-This convention helps the SPMC to determine the origin and destination worlds in
-an FF-A ABI invocation. In particular the SPMC shall filter unauthorized
-transactions in its world switch routine. It must not be permitted for a VM to
-use a secure FF-A ID as origin world by spoofing:
-
-- A VM-to-SP direct request/response shall set the origin world to be non-secure
-  (FF-A ID bit 15 clear) and destination world to be secure (FF-A ID bit 15
-  set).
-- Similarly, an SP-to-SP direct request/response shall set the FF-A ID bit 15
-  for both origin and destination IDs.
-
-An incoming direct message request arriving at SPMD from NWd is forwarded to
-SPMC without a specific check. The SPMC is resumed through eret and "knows" the
-message is coming from normal world in this specific code path. Thus the origin
-endpoint ID must be checked by SPMC for being a normal world ID.
-
-An SP sending a direct message request must have bit 15 set in its origin
-endpoint ID and this can be checked by the SPMC when the SP invokes the ABI.
-
-The SPMC shall reject the direct message if the claimed world in origin endpoint
-ID is not consistent:
-
--  It is either forwarded by SPMD and thus origin endpoint ID must be a "normal
-   world ID",
--  or initiated by an SP and thus origin endpoint ID must be a "secure world ID".
-
-
-FFA_MSG_SEND_DIRECT_REQ/FFA_MSG_SEND_DIRECT_RESP
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is a mandatory interface for secure partitions consisting in direct request
-and responses with the following rules:
-
-- An SP can send a direct request to another SP.
-- An SP can receive a direct request from another SP.
-- An SP can send a direct response to another SP.
-- An SP cannot send a direct request to an Hypervisor or OS kernel.
-- An Hypervisor or OS kernel can send a direct request to an SP.
-- An SP can send a direct response to an Hypervisor or OS kernel.
-
-FFA_NOTIFICATION_BITMAP_CREATE/FFA_NOTIFICATION_BITMAP_DESTROY
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The secure partitions notifications bitmap are statically allocated by the SPMC.
-Hence, this interface is not to be issued by secure partitions.
-
-At initialization, the SPMC is not aware of VMs/partitions deployed in the
-normal world. Hence, the Hypervisor or OS kernel must use both ABIs for SPMC
-to be prepared to handle notifications for the provided VM ID.
-
-FFA_NOTIFICATION_BIND/FFA_NOTIFICATION_UNBIND
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Pair of interfaces to manage permissions to signal notifications. Prior to
-handling notifications, an FF-A endpoint must allow a given sender to signal a
-bitmap of notifications.
-
-If the receiver doesn't have notification support enabled in its FF-A manifest,
-it won't be able to bind notifications, hence forbidding it to receive any
-notifications.
-
-FFA_NOTIFICATION_SET/FFA_NOTIFICATION_GET
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-FFA_NOTIFICATION_GET retrieves all pending global notifications and
-per-vCPU notifications targeted to the current vCPU.
-
-Hafnium maintains a global count of pending notifications which gets incremented
-and decremented when handling FFA_NOTIFICATION_SET and FFA_NOTIFICATION_GET
-respectively. A delayed SRI is triggered if the counter is non-zero when the
-SPMC returns to normal world.
-
-FFA_NOTIFICATION_INFO_GET
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Hafnium maintains a global count of pending notifications whose information
-has been retrieved by this interface. The count is incremented and decremented
-when handling FFA_NOTIFICATION_INFO_GET and FFA_NOTIFICATION_GET respectively.
-It also tracks notifications whose information has been retrieved individually,
-such that it avoids duplicating returned information for subsequent calls to
-FFA_NOTIFICATION_INFO_GET. For each notification, this state information is
-reset when receiver called FFA_NOTIFICATION_GET to retrieve them.
-
-FFA_SPM_ID_GET
-~~~~~~~~~~~~~~
-
-Returns the FF-A ID allocated to an SPM component which can be one of SPMD
-or SPMC.
-
-At initialization, the SPMC queries the SPMD for the SPMC ID, using the
-FFA_ID_GET interface, and records it. The SPMC can also query the SPMD ID using
-the FFA_SPM_ID_GET interface at the secure physical FF-A instance.
-
-Secure partitions call this interface at the virtual FF-A instance, to which
-the SPMC returns the priorly retrieved SPMC ID.
-
-The Hypervisor or OS kernel can issue the FFA_SPM_ID_GET call handled by the
-SPMD, which returns the SPMC ID.
-
-FFA_SECONDARY_EP_REGISTER
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When the SPMC boots, all secure partitions are initialized on their primary
-Execution Context.
-
-The FFA_SECONDARY_EP_REGISTER interface is to be used by a secure partition
-from its first execution context, to provide the entry point address for
-secondary execution contexts.
-
-A secondary EC is first resumed either upon invocation of PSCI_CPU_ON from
-the NWd or by invocation of FFA_RUN.
-
-FFA_RX_ACQUIRE/FFA_RX_RELEASE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The RX buffers can be used to pass information to an FF-A endpoint in the
-following scenarios:
-
- - When it was targetted by a FFA_MSG_SEND2 invokation from another endpoint.
- - Return the result of calling ``FFA_PARTITION_INFO_GET``.
- - In a memory share operation, as part of the ``FFA_MEM_RETRIEVE_RESP``,
-   with the memory descriptor of the shared memory.
-
-If a normal world VM is expected to exchange messages with secure world,
-its RX/TX buffer addresses are forwarded to the SPMC via FFA_RXTX_MAP ABI,
-and are from this moment owned by the SPMC.
-The hypervisor must call the FFA_RX_ACQUIRE interface before attempting
-to use the RX buffer, in any of the aforementioned scenarios. A successful
-call to FFA_RX_ACQUIRE transfers ownership of RX buffer to hypervisor, such
-that it can be safely used.
-
-The FFA_RX_RELEASE interface is used after the FF-A endpoint is done with
-processing the data received in its RX buffer. If the RX buffer has been
-acquired by the hypervisor, the FFA_RX_RELEASE call must be forwarded to
-the SPMC to reestablish SPMC's RX ownership.
-
-An attempt from an SP to send a message to a normal world VM whose RX buffer
-was acquired by the hypervisor fails with error code FFA_BUSY, to preserve
-the RX buffer integrity.
-The operation could then be conducted after FFA_RX_RELEASE.
-
-FFA_MSG_SEND2
-~~~~~~~~~~~~~
-
-Hafnium copies a message from the sender TX buffer into receiver's RX buffer.
-For messages from SPs to VMs, operation is only possible if the SPMC owns
-the receiver's RX buffer.
-
-Both receiver and sender need to enable support for indirect messaging,
-in their respective partition manifest. The discovery of support
-of such feature can be done via FFA_PARTITION_INFO_GET.
-
-On a successful message send, Hafnium pends an RX buffer full framework
-notification for the receiver, to inform it about a message in the RX buffer.
-
-The handling of framework notifications is similar to that of
-global notifications. Binding of these is not necessary, as these are
-reserved to be used by the hypervisor or SPMC.
-
-SPMC-SPMD direct requests/responses
------------------------------------
-
-Implementation-defined FF-A IDs are allocated to the SPMC and SPMD.
-Using those IDs in source/destination fields of a direct request/response
-permits SPMD to SPMC communication and either way.
-
-- SPMC to SPMD direct request/response uses SMC conduit.
-- SPMD to SPMC direct request/response uses ERET conduit.
-
-This is used in particular to convey power management messages.
-
-Memory Sharing
---------------
-
-Hafnium implements the following memory sharing interfaces:
-
- - ``FFA_MEM_SHARE`` - for shared access between lender and borrower.
- - ``FFA_MEM_LEND`` - borrower to obtain exclusive access, though lender
-   retains ownership of the memory.
- - ``FFA_MEM_DONATE`` - lender permanently relinquishes ownership of memory
-   to the borrower.
-
-The ``FFA_MEM_RETRIEVE_REQ`` interface is for the borrower to request the
-memory to be mapped into its address space: for S-EL1 partitions the SPM updates
-their stage 2 translation regime; for S-EL0 partitions the SPM updates their
-stage 1 translation regime. On a successful call, the SPMC responds back with
-``FFA_MEM_RETRIEVE_RESP``.
-
-The ``FFA_MEM_RELINQUISH`` interface is for when the borrower is done with using
-a memory region.
-
-The ``FFA_MEM_RECLAIM`` interface is for the owner of the memory to reestablish
-its ownership and exclusive access to the memory shared.
-
-The memory transaction descriptors are transmitted via RX/TX buffers. In
-situations where the size of the memory transaction descriptor exceeds the
-size of the RX/TX buffers, Hafnium provides support for fragmented transmission
-of the full transaction descriptor. The ``FFA_MEM_FRAG_RX`` and ``FFA_MEM_FRAG_TX``
-interfaces are for receiving and transmitting the next fragment, respectively.
-
-If lender and borrower(s) are SPs, all memory sharing operations are supported.
-
-Hafnium also supports memory sharing operations between the normal world and the
-secure world. If there is an SP involved, the SPMC allocates data to track the
-state of the operation.
-
-The SPMC is also the designated allocator for the memory handle. The hypervisor
-or OS kernel has the possibility to rely on the SPMC to maintain the state
-of the operation, thus saving memory.
-A lender SP can only donate NS memory to a borrower from the normal world.
-
-The SPMC supports the hypervisor retrieve request, as defined by the FF-A
-v1.1 EAC0 specification, in section 16.4.3. The intent is to aid with operations
-that the hypervisor must do for a VM retriever. For example, when handling
-an FFA_MEM_RECLAIM, if the hypervisor relies on SPMC to keep the state
-of the operation, the hypervisor retrieve request can be used to obtain
-that state information, do the necessary validations, and update stage 2
-memory translation.
-
-Hafnium also supports memory lend and share targetting multiple borrowers.
-This is the case for a lender SP to multiple SPs, and for a lender VM to
-multiple endpoints (from both secure world and normal world). If there is
-at least one borrower VM, the hypervisor is in charge of managing its
-stage 2 translation on a successful memory retrieve.
-The semantics of ``FFA_MEM_DONATE`` implies ownership transmission,
-which should target only one partition.
-
-The memory share interfaces are backwards compatible with memory transaction
-descriptors from FF-A v1.0. These get translated to FF-A v1.1 descriptors for
-Hafnium's internal processing of the operation. If the FF-A version of a
-borrower is v1.0, Hafnium provides FF-A v1.0 compliant memory transaction
-descriptors on memory retrieve response.
-
-PE MMU configuration
---------------------
-
-With secure virtualization enabled (``HCR_EL2.VM = 1``) and for S-EL1
-partitions, two IPA spaces (secure and non-secure) are output from the
-secure EL1&0 Stage-1 translation.
-The EL1&0 Stage-2 translation hardware is fed by:
-
-- A secure IPA when the SP EL1&0 Stage-1 MMU is disabled.
-- One of secure or non-secure IPA when the secure EL1&0 Stage-1 MMU is enabled.
-
-``VTCR_EL2`` and ``VSTCR_EL2`` provide configuration bits for controlling the
-NS/S IPA translations. The following controls are set up:
-``VSTCR_EL2.SW = 0`` , ``VSTCR_EL2.SA = 0``, ``VTCR_EL2.NSW = 0``,
-``VTCR_EL2.NSA = 1``:
-
-- Stage-2 translations for the NS IPA space access the NS PA space.
-- Stage-2 translation table walks for the NS IPA space are to the secure PA space.
-
-Secure and non-secure IPA regions (rooted to by ``VTTBR_EL2`` and ``VSTTBR_EL2``)
-use the same set of Stage-2 page tables within a SP.
-
-The ``VTCR_EL2/VSTCR_EL2/VTTBR_EL2/VSTTBR_EL2`` virtual address space
-configuration is made part of a vCPU context.
-
-For S-EL0 partitions with VHE enabled, a single secure EL2&0 Stage-1 translation
-regime is used for both Hafnium and the partition.
-
-Schedule modes and SP Call chains
----------------------------------
-
-An SP execution context is said to be in SPMC scheduled mode if CPU cycles are
-allocated to it by SPMC. Correspondingly, an SP execution context is said to be
-in Normal world scheduled mode if CPU cycles are allocated by the normal world.
-
-A call chain represents all SPs in a sequence of invocations of a direct message
-request. When execution on a PE is in the secure state, only a single call chain
-that runs in the Normal World scheduled mode can exist. FF-A v1.1 spec allows
-any number of call chains to run in the SPMC scheduled mode but the Hafnium
-SPMC restricts the number of call chains in SPMC scheduled mode to only one for
-keeping the implementation simple.
-
-Partition runtime models
-------------------------
-
-The runtime model of an endpoint describes the transitions permitted for an
-execution context between various states. These are the four partition runtime
-models supported (refer to `[1]`_ section 7):
-
-  - RTM_FFA_RUN: runtime model presented to an execution context that is
-    allocated CPU cycles through FFA_RUN interface.
-  - RTM_FFA_DIR_REQ: runtime model presented to an execution context that is
-    allocated CPU cycles through FFA_MSG_SEND_DIRECT_REQ interface.
-  - RTM_SEC_INTERRUPT: runtime model presented to an execution context that is
-    allocated CPU cycles by SPMC to handle a secure interrupt.
-  - RTM_SP_INIT: runtime model presented to an execution context that is
-    allocated CPU cycles by SPMC to initialize its state.
-
-If an endpoint execution context attempts to make an invalid transition or a
-valid transition that could lead to a loop in the call chain, SPMC denies the
-transition with the help of above runtime models.
-
-Interrupt management
---------------------
-
-GIC ownership
-~~~~~~~~~~~~~
-
-The SPMC owns the GIC configuration. Secure and non-secure interrupts are
-trapped at S-EL2. The SPMC manages interrupt resources and allocates interrupt
-IDs based on SP manifests. The SPMC acknowledges physical interrupts and injects
-virtual interrupts by setting the use of vIRQ/vFIQ bits before resuming a SP.
-
-Abbreviations:
-
-  - NS-Int: A non-secure physical interrupt. It requires a switch to the normal
-    world to be handled if it triggers while execution is in secure world.
-  - Other S-Int: A secure physical interrupt targeted to an SP different from
-    the one that is currently running.
-  - Self S-Int: A secure physical interrupt targeted to the SP that is currently
-    running.
-
-Non-secure interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This section documents the actions supported in SPMC in response to a non-secure
-interrupt as per the guidance provided by FF-A v1.1 EAC0 specification.
-An SP specifies one of the following actions in its partition manifest:
-
-  - Non-secure interrupt is signaled.
-  - Non-secure interrupt is signaled after a managed exit.
-  - Non-secure interrupt is queued.
-
-An SP execution context in a call chain could specify a less permissive action
-than subsequent SP execution contexts in the same call chain. The less
-permissive action takes precedence over the more permissive actions specified
-by the subsequent execution contexts. Please refer to FF-A v1.1 EAC0 section
-8.3.1 for further explanation.
-
-Secure interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This section documents the support implemented for secure interrupt handling in
-SPMC as per the guidance provided by FF-A v1.1 EAC0 specification.
-The following assumptions are made about the system configuration:
-
-  - In the current implementation, S-EL1 SPs are expected to use the para
-    virtualized ABIs for interrupt management rather than accessing the virtual
-    GIC interface.
-  - Unless explicitly stated otherwise, this support is applicable only for
-    S-EL1 SPs managed by SPMC.
-  - Secure interrupts are configured as G1S or G0 interrupts.
-  - All physical interrupts are routed to SPMC when running a secure partition
-    execution context.
-  - All endpoints with multiple execution contexts have their contexts pinned
-    to corresponding CPUs. Hence, a secure virtual interrupt cannot be signaled
-    to a target vCPU that is currently running or blocked on a different
-    physical CPU.
-
-A physical secure interrupt could trigger while CPU is executing in normal world
-or secure world.
-The action of SPMC for a secure interrupt depends on: the state of the target
-execution context of the SP that is responsible for handling the interrupt;
-whether the interrupt triggered while execution was in normal world or secure
-world.
-
-Secure interrupt signaling mechanisms
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Signaling refers to the mechanisms used by SPMC to indicate to the SP execution
-context that it has a pending virtual interrupt and to further run the SP
-execution context, such that it can handle the virtual interrupt. SPMC uses
-either the FFA_INTERRUPT interface with ERET conduit or vIRQ signal for signaling
-to S-EL1 SPs. When normal world execution is preempted by a secure interrupt,
-the SPMD uses the FFA_INTERRUPT ABI with ERET conduit to signal interrupt to SPMC
-running in S-EL2.
-
-+-----------+---------+---------------+---------------------------------------+
-| SP State  | Conduit | Interface and | Description                           |
-|           |         | parameters    |                                       |
-+-----------+---------+---------------+---------------------------------------+
-| WAITING   | ERET,   | FFA_INTERRUPT,| SPMC signals to SP the ID of pending  |
-|           | vIRQ    | Interrupt ID  | interrupt. It pends vIRQ signal and   |
-|           |         |               | resumes execution context of SP       |
-|           |         |               | through ERET.                         |
-+-----------+---------+---------------+---------------------------------------+
-| BLOCKED   | ERET,   | FFA_INTERRUPT | SPMC signals to SP that an interrupt  |
-|           | vIRQ    |               | is pending. It pends vIRQ signal and  |
-|           |         |               | resumes execution context of SP       |
-|           |         |               | through ERET.                         |
-+-----------+---------+---------------+---------------------------------------+
-| PREEMPTED | vIRQ    | NA            | SPMC pends the vIRQ signal but does   |
-|           |         |               | not resume execution context of SP.   |
-+-----------+---------+---------------+---------------------------------------+
-| RUNNING   | ERET,   | NA            | SPMC pends the vIRQ signal and resumes|
-|           | vIRQ    |               | execution context of SP through ERET. |
-+-----------+---------+---------------+---------------------------------------+
-
-Secure interrupt completion mechanisms
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A SP signals secure interrupt handling completion to the SPMC through the
-following mechanisms:
-
-  - ``FFA_MSG_WAIT`` ABI if it was in WAITING state.
-  - ``FFA_RUN`` ABI if its was in BLOCKED state.
-
-This is a remnant of SPMC implementation based on the FF-A v1.0 specification.
-In the current implementation, S-EL1 SPs use the para-virtualized HVC interface
-implemented by SPMC to perform priority drop and interrupt deactivation (SPMC
-configures EOImode = 0, i.e. priority drop and deactivation are done together).
-The SPMC performs checks to deny the state transition upon invocation of
-either FFA_MSG_WAIT or FFA_RUN interface if the SP didn't perform the
-deactivation of the secure virtual interrupt.
-
-If the current SP execution context was preempted by a secure interrupt to be
-handled by execution context of target SP, SPMC resumes current SP after signal
-completion by target SP execution context.
-
-Actions for a secure interrupt triggered while execution is in normal world
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------------------+----------+-----------------------------------------------+
-| State of target   | Action   | Description                                   |
-| execution context |          |                                               |
-+-------------------+----------+-----------------------------------------------+
-| WAITING           | Signaled | This starts a new call chain in SPMC scheduled|
-|                   |          | mode.                                         |
-+-------------------+----------+-----------------------------------------------+
-| PREEMPTED         | Queued   | The target execution must have been preempted |
-|                   |          | by a non-secure interrupt. SPMC queues the    |
-|                   |          | secure virtual interrupt now. It is signaled  |
-|                   |          | when the target execution context next enters |
-|                   |          | the RUNNING state.                            |
-+-------------------+----------+-----------------------------------------------+
-| BLOCKED, RUNNING  | NA       | The target execution context is blocked or    |
-|                   |          | running on a different CPU. This is not       |
-|                   |          | supported by current SPMC implementation and  |
-|                   |          | execution hits panic.                         |
-+-------------------+----------+-----------------------------------------------+
-
-If normal world execution was preempted by a secure interrupt, SPMC uses
-FFA_NORMAL_WORLD_RESUME ABI to indicate completion of secure interrupt handling
-and further returns execution to normal world.
-
-The following figure describes interrupt handling flow when a secure interrupt
-triggers while execution is in normal world:
-
-.. image:: ../resources/diagrams/ffa-secure-interrupt-handling-nwd.png
-
-A brief description of the events:
-
-  - 1) Secure interrupt triggers while normal world is running.
-  - 2) FIQ gets trapped to EL3.
-  - 3) SPMD signals secure interrupt to SPMC at S-EL2 using FFA_INTERRUPT ABI.
-  - 4) SPMC identifies target vCPU of SP and injects virtual interrupt (pends
-       vIRQ).
-  - 5) Assuming SP1 vCPU is in WAITING state, SPMC signals virtual interrupt
-       using FFA_INTERRUPT with interrupt id as an argument and resumes the SP1
-       vCPU using ERET in SPMC scheduled mode.
-  - 6) Execution traps to vIRQ handler in SP1 provided that the virtual
-       interrupt is not masked i.e., PSTATE.I = 0
-  - 7) SP1 queries for the pending virtual interrupt id using a paravirtualized
-       HVC call. SPMC clears the pending virtual interrupt state management
-       and returns the pending virtual interrupt id.
-  - 8) SP1 services the virtual interrupt and invokes the paravirtualized
-       de-activation HVC call. SPMC de-activates the physical interrupt,
-       clears the fields tracking the secure interrupt and resumes SP1 vCPU.
-  - 9) SP1 performs secure interrupt completion through FFA_MSG_WAIT ABI.
-  - 10) SPMC returns control to EL3 using FFA_NORMAL_WORLD_RESUME.
-  - 11) EL3 resumes normal world execution.
-
-Actions for a secure interrupt triggered while execution is in secure world
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------------------+----------+------------------------------------------------+
-| State of target   | Action   | Description                                    |
-| execution context |          |                                                |
-+-------------------+----------+------------------------------------------------+
-| WAITING           | Signaled | This starts a new call chain in SPMC scheduled |
-|                   |          | mode.                                          |
-+-------------------+----------+------------------------------------------------+
-| PREEMPTED by Self | Signaled | The target execution context reenters the      |
-| S-Int             |          | RUNNING state to handle the secure virtual     |
-|                   |          | interrupt.                                     |
-+-------------------+----------+------------------------------------------------+
-| PREEMPTED by      | Queued   | SPMC queues the secure virtual interrupt now.  |
-| NS-Int            |          | It is signaled when the target execution       |
-|                   |          | context next enters the RUNNING state.         |
-+-------------------+----------+------------------------------------------------+
-| BLOCKED           | Signaled | Both preempted and target execution contexts   |
-|                   |          | must have been part of the Normal world        |
-|                   |          | scheduled call chain. Refer scenario 1 of      |
-|                   |          | Table 8.4 in the FF-A v1.1 EAC0 spec.          |
-+-------------------+----------+------------------------------------------------+
-| RUNNING           | NA       | The target execution context is running on a   |
-|                   |          | different CPU. This scenario is not supported  |
-|                   |          | by current SPMC implementation and execution   |
-|                   |          | hits panic.                                    |
-+-------------------+----------+------------------------------------------------+
-
-The following figure describes interrupt handling flow when a secure interrupt
-triggers while execution is in secure world. We assume OS kernel sends a direct
-request message to SP1. Further, SP1 sends a direct request message to SP2. SP1
-enters BLOCKED state and SPMC resumes SP2.
-
-.. image:: ../resources/diagrams/ffa-secure-interrupt-handling-swd.png
-
-A brief description of the events:
-
-  - 1) Secure interrupt triggers while SP2 is running.
-  - 2) SP2 gets preempted and execution traps to SPMC as IRQ.
-  - 3) SPMC finds the target vCPU of secure partition responsible for handling
-       this secure interrupt. In this scenario, it is SP1.
-  - 4) SPMC pends vIRQ for SP1 and signals through FFA_INTERRUPT interface.
-       SPMC further resumes SP1 through ERET conduit. Note that SP1 remains in
-       Normal world schedule mode.
-  - 6) Execution traps to vIRQ handler in SP1 provided that the virtual
-       interrupt is not masked i.e., PSTATE.I = 0
-  - 7) SP1 queries for the pending virtual interrupt id using a paravirtualized
-       HVC call. SPMC clears the pending virtual interrupt state management
-       and returns the pending virtual interrupt id.
-  - 8) SP1 services the virtual interrupt and invokes the paravirtualized
-       de-activation HVC call. SPMC de-activates the physical interrupt and
-       clears the fields tracking the secure interrupt and resumes SP1 vCPU.
-  - 9) Since SP1 direct request completed with FFA_INTERRUPT, it resumes the
-       direct request to SP2 by invoking FFA_RUN.
-  - 9) SPMC resumes the pre-empted vCPU of SP2.
-
-EL3 interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~
-
-In GICv3 based systems, EL3 interrupts are configured as Group0 secure
-interrupts. Execution traps to SPMC when a Group0 interrupt triggers while an
-SP is running. Further, SPMC running at S-EL2 uses FFA_EL3_INTR_HANDLE ABI to
-request EL3 platform firmware to handle a pending Group0 interrupt.
-Similarly, SPMD registers a handler with interrupt management framework to
-delegate handling of Group0 interrupt to the platform if the interrupt triggers
-in normal world.
-
- - Platform hook
-
-   - plat_spmd_handle_group0_interrupt
-
-     SPMD provides platform hook to handle Group0 secure interrupts. In the
-     current design, SPMD expects the platform not to delegate handling to the
-     NWd (such as through SDEI) while processing Group0 interrupts.
-
-Power management
-----------------
-
-In platforms with or without secure virtualization:
-
-- The NWd owns the platform PM policy.
-- The Hypervisor or OS kernel is the component initiating PSCI service calls.
-- The EL3 PSCI library is in charge of the PM coordination and control
-  (eventually writing to platform registers).
-- While coordinating PM events, the PSCI library calls backs into the Secure
-  Payload Dispatcher for events the latter has statically registered to.
-
-When using the SPMD as a Secure Payload Dispatcher:
-
-- A power management event is relayed through the SPD hook to the SPMC.
-- In the current implementation only cpu on (svc_on_finish) and cpu off
-  (svc_off) hooks are registered.
-- The behavior for the cpu on event is described in `Secondary cores boot-up`_.
-  The SPMC is entered through its secondary physical core entry point.
-- The cpu off event occurs when the NWd calls PSCI_CPU_OFF. The PM event is
-  signaled to the SPMC through a power management framework message.
-  It consists in a SPMD-to-SPMC direct request/response (`SPMC-SPMD direct
-  requests/responses`_) conveying the event details and SPMC response.
-  The SPMD performs a synchronous entry into the SPMC. The SPMC is entered and
-  updates its internal state to reflect the physical core is being turned off.
-  In the current implementation no SP is resumed as a consequence. This behavior
-  ensures a minimal support for CPU hotplug e.g. when initiated by the NWd linux
-  userspace.
-
-Arm architecture extensions for security hardening
-==================================================
-
-Hafnium supports the following architecture extensions for security hardening:
-
-- Pointer authentication (FEAT_PAuth): the extension permits detection of forged
-  pointers used by ROP type of attacks through the signing of the pointer
-  value. Hafnium is built with the compiler branch protection option to permit
-  generation of a pointer authentication code for return addresses (pointer
-  authentication for instructions). The APIA key is used while Hafnium runs.
-  A random key is generated at boot time and restored upon entry into Hafnium
-  at run-time. APIA and other keys (APIB, APDA, APDB, APGA) are saved/restored
-  in vCPU contexts permitting to enable pointer authentication in VMs/SPs.
-- Branch Target Identification (FEAT_BTI): the extension permits detection of
-  unexpected indirect branches used by JOP type of attacks. Hafnium is built
-  with the compiler branch protection option, inserting land pads at function
-  prologues that are reached by indirect branch instructions (BR/BLR).
-  Hafnium code pages are marked as guarded in the EL2 Stage-1 MMU descriptors
-  such that an indirect branch must always target a landpad. A fault is
-  triggered otherwise. VMs/SPs can (independently) mark their code pages as
-  guarded in the EL1&0 Stage-1 translation regime.
-- Memory Tagging Extension (FEAT_MTE): the option permits detection of out of
-  bound memory array accesses or re-use of an already freed memory region.
-  Hafnium enables the compiler option permitting to leverage MTE stack tagging
-  applied to core stacks. Core stacks are marked as normal tagged memory in the
-  EL2 Stage-1 translation regime. A synchronous data abort is generated upon tag
-  check failure on load/stores. A random seed is generated at boot time and
-  restored upon entry into Hafnium. MTE system registers are saved/restored in
-  vCPU contexts permitting MTE usage from VMs/SPs.
-
-SMMUv3 support in Hafnium
-=========================
-
-An SMMU is analogous to an MMU in a CPU. It performs address translations for
-Direct Memory Access (DMA) requests from system I/O devices.
-The responsibilities of an SMMU include:
-
--  Translation: Incoming DMA requests are translated from bus address space to
-   system physical address space using translation tables compliant to
-   Armv8/Armv7 VMSA descriptor format.
--  Protection: An I/O device can be prohibited from read, write access to a
-   memory region or allowed.
--  Isolation: Traffic from each individial device can be independently managed.
-   The devices are differentiated from each other using unique translation
-   tables.
-
-The following diagram illustrates a typical SMMU IP integrated in a SoC with
-several I/O devices along with Interconnect and Memory system.
-
-.. image:: ../resources/diagrams/MMU-600.png
-
-SMMU has several versions including SMMUv1, SMMUv2 and SMMUv3. Hafnium provides
-support for SMMUv3 driver in both normal and secure world. A brief introduction
-of SMMUv3 functionality and the corresponding software support in Hafnium is
-provided here.
-
-SMMUv3 features
----------------
-
--  SMMUv3 provides Stage1, Stage2 translation as well as nested (Stage1 + Stage2)
-   translation support. It can either bypass or abort incoming translations as
-   well.
--  Traffic (memory transactions) from each upstream I/O peripheral device,
-   referred to as Stream, can be independently managed using a combination of
-   several memory based configuration structures. This allows the SMMUv3 to
-   support a large number of streams with each stream assigned to a unique
-   translation context.
--  Support for Armv8.1 VMSA where the SMMU shares the translation tables with
-   a Processing Element. AArch32(LPAE) and AArch64 translation table format
-   are supported by SMMUv3.
--  SMMUv3 offers non-secure stream support with secure stream support being
-   optional. Logically, SMMUv3 behaves as if there is an indepdendent SMMU
-   instance for secure and non-secure stream support.
--  It also supports sub-streams to differentiate traffic from a virtualized
-   peripheral associated with a VM/SP.
--  Additionally, SMMUv3.2 provides support for PEs implementing Armv8.4-A
-   extensions. Consequently, SPM depends on Secure EL2 support in SMMUv3.2
-   for providing Secure Stage2 translation support to upstream peripheral
-   devices.
-
-SMMUv3 Programming Interfaces
------------------------------
-
-SMMUv3 has three software interfaces that are used by the Hafnium driver to
-configure the behaviour of SMMUv3 and manage the streams.
-
--  Memory based data strutures that provide unique translation context for
-   each stream.
--  Memory based circular buffers for command queue and event queue.
--  A large number of SMMU configuration registers that are memory mapped during
-   boot time by Hafnium driver. Except a few registers, all configuration
-   registers have independent secure and non-secure versions to configure the
-   behaviour of SMMUv3 for translation of secure and non-secure streams
-   respectively.
-
-Peripheral device manifest
---------------------------
-
-Currently, SMMUv3 driver in Hafnium only supports dependent peripheral devices.
-These devices are dependent on PE endpoint to initiate and receive memory
-management transactions on their behalf. The acccess to the MMIO regions of
-any such device is assigned to the endpoint during boot. Moreover, SMMUv3 driver
-uses the same stage 2 translations for the device as those used by partition
-manager on behalf of the PE endpoint. This ensures that the peripheral device
-has the same visibility of the physical address space as the endpoint. The
-device node of the corresponding partition manifest (refer to `[1]`_ section 3.2
-) must specify these additional properties for each peripheral device in the
-system :
-
--  smmu-id: This field helps to identify the SMMU instance that this device is
-   upstream of.
--  stream-ids: List of stream IDs assigned to this device.
-
-.. code:: shell
-
-    smmuv3-testengine {
-        base-address = <0x00000000 0x2bfe0000>;
-        pages-count = <32>;
-        attributes = <0x3>;
-        smmu-id = <0>;
-        stream-ids = <0x0 0x1>;
-        interrupts = <0x2 0x3>, <0x4 0x5>;
-        exclusive-access;
-    };
-
-SMMUv3 driver limitations
--------------------------
-
-The primary design goal for the Hafnium SMMU driver is to support secure
-streams.
-
--  Currently, the driver only supports Stage2 translations. No support for
-   Stage1 or nested translations.
--  Supports only AArch64 translation format.
--  No support for features such as PCI Express (PASIDs, ATS, PRI), MSI, RAS,
-   Fault handling, Performance Monitor Extensions, Event Handling, MPAM.
--  No support for independent peripheral devices.
-
-S-EL0 Partition support
-=======================
-The SPMC (Hafnium) has limited capability to run S-EL0 FF-A partitions using
-FEAT_VHE (mandatory with ARMv8.1 in non-secure state, and in secure world
-with ARMv8.4 and FEAT_SEL2).
-
-S-EL0 partitions are useful for simple partitions that don't require full
-Trusted OS functionality. It is also useful to reduce jitter and cycle
-stealing from normal world since they are more lightweight than VMs.
-
-S-EL0 partitions are presented, loaded and initialized the same as S-EL1 VMs by
-the SPMC. They are differentiated primarily by the 'exception-level' property
-and the 'execution-ctx-count' property in the SP manifest. They are host apps
-under the single EL2&0 Stage-1 translation regime controlled by the SPMC and
-call into the SPMC through SVCs as opposed to HVCs and SMCs. These partitions
-can use FF-A defined services (FFA_MEM_PERM_*) to update or change permissions
-for memory regions.
-
-S-EL0 partitions are required by the FF-A specification to be UP endpoints,
-capable of migrating, and the SPMC enforces this requirement. The SPMC allows
-a S-EL0 partition to accept a direct message from secure world and normal world,
-and generate direct responses to them.
-All S-EL0 partitions must use AArch64. AArch32 S-EL0 partitions are not supported.
-
-Memory sharing, indirect messaging, and notifications functionality with S-EL0
-partitions is supported.
-
-Interrupt handling is not supported with S-EL0 partitions and is work in
-progress.
 
 References
 ==========
@@ -1641,8 +242,7 @@
 
 .. _[3]:
 
-[3] `Trusted Boot Board Requirements
-Client <https://developer.arm.com/documentation/den0006/d/>`__
+[3] https://hafnium.readthedocs.io/en/latest/secure-partition-manager/secure-partition-manager.html#secure-partitions-layout-file
 
 .. _[4]:
 
@@ -1650,23 +250,15 @@
 
 .. _[5]:
 
-[5] https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/spm/cactus/plat/arm/fvp/fdts/cactus.dts
+[5] https://hafnium.readthedocs.io/en/latest/secure-partition-manager/index.html
 
 .. _[6]:
 
-[6] https://trustedfirmware-a.readthedocs.io/en/latest/components/ffa-manifest-binding.html
+[6] :ref:`EL3 Secure Partition Manager<EL3 Secure Partition Manager>`
 
 .. _[7]:
 
-[7] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
-
-.. _[8]:
-
-[8] https://lists.trustedfirmware.org/archives/list/tf-a@lists.trustedfirmware.org/thread/CFQFGU6H2D5GZYMUYGTGUSXIU3OYZP6U/
-
-.. _[9]:
-
-[9] https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#dynamic-configuration-during-cold-boot
+[7] https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#dynamic-configuration-during-cold-boot
 
 --------------
 
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 6147c1f..fda43dc 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -826,6 +826,10 @@
   feature is enabled and can assist the Kernel in the process of
   mitigation of the erratum.
 
+- ``ERRATA_X4_2726228``: This applies erratum 2726228 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in
+  r0p2.
+
 -  ``ERRATA_X4_2740089``: This applies errata 2740089 workaround to Cortex-X4
    CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed
    in r0p2.
@@ -833,6 +837,15 @@
 - ``ERRATA_X4_2763018``: This applies errata 2763018 workaround to Cortex-X4
   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
 
+- ``ERRATA_X4_2816013``: This applies errata 2816013 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
+- ``ERRATA_X4_2897503``: This applies errata 2897503 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
+- ``ERRATA_X4_3076789``: This applies errata 3076789 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
@@ -896,6 +909,10 @@
    Cortex-A520 CPU. This needs to be enabled for revisions r0p0 and r0p1.
    It is still open.
 
+-  ``ERRATA_A520_2938996``: This applies errata 2938996 workaround to
+   Cortex-A520 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
+
 For Cortex-A715, the following errata build flags are defined :
 
 -  ``ERRATA_A715_2331818``: This applies errata 2331818 workaround to
@@ -929,6 +946,14 @@
 
 For Cortex-A720, the following errata build flags are defined :
 
+-  ``ERRATA_A720_2792132``: This applies errata 2792132 workaround to
+   Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
+
+-  ``ERRATA_A720_2844092``: This applies errata 2844092 workaround to
+   Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
+
 -  ``ERRATA_A720_2926083``: This applies errata 2926083 workaround to
    Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
    It is fixed in r0p2.
diff --git a/docs/design_documents/rse.rst b/docs/design_documents/rse.rst
index e0e0fb3..57467f3 100644
--- a/docs/design_documents/rse.rst
+++ b/docs/design_documents/rse.rst
@@ -482,101 +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 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:            d2 84 44 a1 01 38 22 a0 59 05 81 a9 19 01 09 78
+    INFO:            23 74 61 67 3a 61 72 6d 2e 63 6f 6d 2c 32 30 32
+    INFO:            33 3a 63 63 61 5f 70 6c 61 74 66 6f 72 6d 23 31
+    INFO:            2e 30 2e 30 0a 58 20 0d 22 e0 8a 98 46 90 58 48
+    INFO:            63 18 28 34 89 bd b3 6f 09 db ef eb 18 64 df 43
+    INFO:            3f a6 e5 4e a2 d7 11 19 09 5c 58 20 7f 45 4c 46
+    INFO:            02 01 01 00 00 00 00 00 00 00 00 00 03 00 3e 00
+    INFO:            01 00 00 00 50 58 00 00 00 00 00 00 19 01 00 58
+    INFO:            21 01 07 06 05 04 03 02 01 00 0f 0e 0d 0c 0b 0a
+    INFO:            09 08 17 16 15 14 13 12 11 10 1f 1e 1d 1c 1b 1a
+    INFO:            19 18 19 09 61 44 cf cf cf cf 19 09 5b 19 30 03
+    INFO:            19 09 62 67 73 68 61 2d 32 35 36 19 09 60 78 3a
+    INFO:            68 74 74 70 73 3a 2f 2f 76 65 72 61 69 73 6f 6e
+    INFO:            2e 65 78 61 6d 70 6c 65 2f 2e 77 65 6c 6c 2d 6b
+    INFO:            6e 6f 77 6e 2f 76 65 72 61 69 73 6f 6e 2f 76 65
+    INFO:            72 69 66 69 63 61 74 69 6f 6e 19 09 5f 8d a4 01
+    INFO:            69 52 53 45 5f 42 4c 31 5f 32 05 58 20 53 78 79
+    INFO:            63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c
+    INFO:            3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20
+    INFO:            9a 27 1f 2a 91 6b 0b 6e e6 ce cb 24 26 f0 b3 20
+    INFO:            6e f0 74 57 8b e5 5d 9b c9 4f 6f 3f e3 ab 86 aa
+    INFO:            06 67 73 68 61 2d 32 35 36 a4 01 67 52 53 45 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:            c0 fa 97 3f 7a a3 02 58 20 53 c2 34 e5 e8 47 2b
+    INFO:            6a c5 1c 1a e1 ca b3 fe 06 fa d0 53 be b8 eb fd
+    INFO:            89 77 b0 10 65 5b fd d3 c3 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 65 52 53 45 5f 53 05 58 20 53 78 79
+    INFO:            63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c
+    INFO:            3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20
+    INFO:            11 21 cf cc d5 91 3f 0a 63 fe c4 0a 6f fd 44 ea
+    INFO:            64 f9 dc 13 5c 66 63 4b a0 01 d1 0b cf 43 02 a2
+    INFO:            06 67 73 68 61 2d 32 35 36 a4 01 66 41 50 5f 42
+    INFO:            4c 31 05 58 20 53 78 79 63 07 53 5d f3 ec 8d 8b
+    INFO:            15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38 c0
+    INFO:            fa 97 3f 7a a3 02 58 20 15 71 b5 ec 78 bd 68 51
+    INFO:            2b f7 83 0b b6 a2 a4 4b 20 47 c7 df 57 bc e7 9e
+    INFO:            b8 a1 c0 e5 be a0 a5 01 06 67 73 68 61 2d 32 35
+    INFO:            36 a4 01 66 41 50 5f 42 4c 32 05 58 20 53 78 79
+    INFO:            63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c
+    INFO:            3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20
+    INFO:            10 15 9b af 26 2b 43 a9 2d 95 db 59 da e1 f7 2c
+    INFO:            64 51 27 30 16 61 e0 a3 ce 4e 38 b2 95 a9 7c 58
+    INFO:            06 67 73 68 61 2d 32 35 36 a4 01 67 53 43 50 5f
+    INFO:            42 4c 31 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:            c0 fa 97 3f 7a a3 02 58 20 10 12 2e 85 6b 3f cd
+    INFO:            49 f0 63 63 63 17 47 61 49 cb 73 0a 1a a1 cf aa
+    INFO:            d8 18 55 2b 72 f5 6d 6f 68 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 67 53 43 50 5f 42 4c 32 05 58 20 f1
+    INFO:            4b 49 87 90 4b cb 58 14 e4 45 9a 05 7e d4 d2 0f
+    INFO:            58 a6 33 15 22 88 a7 61 21 4d cd 28 78 0b 56 02
+    INFO:            58 20 aa 67 a1 69 b0 bb a2 17 aa 0a a8 8a 65 34
+    INFO:            69 20 c8 4c 42 44 7c 36 ba 5f 7e a6 5f 42 2c 1f
+    INFO:            e5 d8 06 67 73 68 61 2d 32 35 36 a4 01 67 41 50
+    INFO:            5f 42 4c 33 31 05 58 20 53 78 79 63 07 53 5d f3
+    INFO:            ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3
+    INFO:            22 38 c0 fa 97 3f 7a a3 02 58 20 2e 6d 31 a5 98
+    INFO:            3a 91 25 1b fa e5 ae fa 1c 0a 19 d8 ba 3c f6 01
+    INFO:            d0 e8 a7 06 b4 cf a9 66 1a 6b 8a 06 67 73 68 61
+    INFO:            2d 32 35 36 a4 01 63 52 4d 4d 05 58 20 53 78 79
+    INFO:            63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c
+    INFO:            3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20
+    INFO:            a1 fb 50 e6 c8 6f ae 16 79 ef 33 51 29 6f d6 71
+    INFO:            34 11 a0 8c f8 dd 17 90 a4 fd 05 fa e8 68 81 64
+    INFO:            06 67 73 68 61 2d 32 35 36 a4 01 69 48 57 5f 43
+    INFO:            4f 4e 46 49 47 05 58 20 53 78 79 63 07 53 5d f3
+    INFO:            ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3
+    INFO:            22 38 c0 fa 97 3f 7a a3 02 58 20 1a 25 24 02 97
+    INFO:            2f 60 57 fa 53 cc 17 2b 52 b9 ff ca 69 8e 18 31
+    INFO:            1f ac d0 f3 b0 6e ca ae f7 9e 17 06 67 73 68 61
+    INFO:            2d 32 35 36 a4 01 69 46 57 5f 43 4f 4e 46 49 47
+    INFO:            05 58 20 53 78 79 63 07 53 5d f3 ec 8d 8b 15 a2
+    INFO:            e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38 c0 fa 97
+    INFO:            3f 7a a3 02 58 20 9a 92 ad bc 0c ee 38 ef 65 8c
+    INFO:            71 ce 1b 1b f8 c6 56 68 f1 66 bf b2 13 64 4c 89
+    INFO:            5c cb 1a d0 7a 25 06 67 73 68 61 2d 32 35 36 a4
+    INFO:            01 6c 54 42 5f 46 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:            a3 02 58 20 23 89 03 18 0c c1 04 ec 2c 5d 8b 3f
+    INFO:            20 c5 bc 61 b3 89 ec 0a 96 7d f8 cc 20 8c dc 7c
+    INFO:            d4 54 17 4f 06 67 73 68 61 2d 32 35 36 a4 01 6d
+    INFO:            53 4f 43 5f 46 57 5f 43 4f 4e 46 49 47 05 58 20
+    INFO:            53 78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56
+    INFO:            41 41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3
+    INFO:            02 58 20 e6 c2 1e 8d 26 0f e7 18 82 de bd b3 39
+    INFO:            d2 40 2a 2c a7 64 85 29 bc 23 03 f4 86 49 bc e0
+    INFO:            38 00 17 06 67 73 68 61 2d 32 35 36 58 60 31 d0
+    INFO:            4d 52 cc de 95 2c 1e 32 cb a1 81 88 5a 40 b8 cc
+    INFO:            38 e0 52 8c 1e 89 58 98 07 64 2a a5 e3 f2 bc 37
+    INFO:            f9 53 74 50 6b ff 4d 2e 4b e7 06 3c 4d 72 41 92
+    INFO:            70 c7 22 e8 d4 d9 3e e8 b6 c9 fa ce 3b 43 c9 76
+    INFO:            1a 49 94 1a b6 f3 8f fd ff 49 6a d4 63 b4 cb fa
+    INFO:            11 d8 3e 23 e3 1f 7f 62 32 9d e3 0c 1c c8
     INFO:    DELEGATED ATTEST TEST END
 
 JSON format:
@@ -584,8 +584,8 @@
 .. code-block:: JSON
 
     {
-        "CCA_ATTESTATION_PROFILE": "http://arm.com/CCA-SSD/1.0.0",
-        "CCA_PLATFORM_CHALLENGE": "b'B5973CB68BAA9FC55558786B7EC67F69E40DF5BA5AA921CD0C27F40587A011EA'",
+        "CCA_ATTESTATION_PROFILE": "tag:arm.com,2023:cca_platform#1.0.0",
+        "CCA_PLATFORM_CHALLENGE": "b'0D22E08A98469058486318283489BDB36F09DBEFEB1864DF433FA6E54EA2D711'",
         "CCA_PLATFORM_IMPLEMENTATION_ID": "b'7F454C4602010100000000000000000003003E00010000005058000000000000'",
         "CCA_PLATFORM_INSTANCE_ID": "b'0107060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
         "CCA_PLATFORM_CONFIG": "b'CFCFCFCF'",
@@ -738,5 +738,5 @@
 
 --------------
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, 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 52a9317..7776f5b 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
@@ -98,6 +99,10 @@
    file that contains the BL32 private key in PEM format or a PKCS11 URI. If
    ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key.
 
+-  ``RMM``: This is an optional build option used when ``ENABLE_RME`` is set.
+   It specifies the path to RMM binary for the ``fip`` target. If the RMM option
+   is not specified, TF-A builds the TRP to load and run at R-EL2.
+
 -  ``BL33``: Path to BL33 image in the host file system. This is mandatory for
    ``fip`` target in case TF-A BL2 is used.
 
@@ -199,6 +204,13 @@
    Note that Pointer Authentication is enabled for Non-secure world irrespective
    of the value of this flag if the CPU supports it.
 
+-  ``CTX_INCLUDE_SVE_REGS``: Boolean option that, when set to 1, will cause the
+   SVE registers to be included when saving and restoring the CPU context. Note
+   that this build option requires ``ENABLE_SVE_FOR_SWD`` to be enabled. In
+   general, it is recommended to perform SVE context management in lower ELs
+   and skip in EL3 due to the additional cost of maintaining large data
+   structures to track the SVE state. Hence, the default value is 0.
+
 -  ``DEBUG``: Chooses between a debug and release build. It can take either 0
    (release) or 1 (debug) as values. 0 is the default.
 
@@ -320,6 +332,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 +358,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
@@ -430,6 +455,22 @@
    the values 0 to 2, to align  with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``.
 
+-  ``ENABLE_FEAT_THE``: Numeric value to enable support for FEAT_THE
+   (Translation Hardening Extension) at EL2 and below, setting the bit
+   SCR_EL3.RCWMASKEn in EL3 to allow access to RCWMASK_EL1 and RCWSMASK_EL1
+   registers and context switch them.
+   Its an optional architectural feature and is available from v8.8 and upwards.
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_SCTLR2``: Numeric value to enable support for FEAT_SCTLR2
+   (Extension to SCTLR_ELx) at EL2 and below, setting the bit
+   SCR_EL3.SCTLR2En in EL3 to allow access to SCTLR2_ELx registers and
+   context switch them. This feature is OPTIONAL from Armv8.0 implementations
+   and mandatory in Armv8.9 implementations.
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
    support in GCC for TF-A. This option is currently only supported for
    AArch64. Default is 0.
@@ -487,21 +528,26 @@
 
 -  ``ENABLE_SVE_FOR_NS``: Numeric value to enable Scalable Vector Extension
    (SVE) for the Non-secure world only. SVE is an optional architectural feature
-   for AArch64. Note that when SVE is enabled for the Non-secure world, access
-   to SIMD and floating-point functionality from the Secure world is disabled by
-   default and controlled with ENABLE_SVE_FOR_SWD.
-   This is to avoid corruption of the Non-secure world data in the Z-registers
-   which are aliased by the SIMD and FP registers. The build option is not
-   compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
-   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS``
-   enabled.  This flag can take the values 0 to 2, to align with the
-   ``ENABLE_FEAT`` mechanism. At this time, this build option cannot be
-   used on systems that have SPM_MM enabled. The default is 1.
+   for AArch64. This flag can take the values 0 to 2, to align with the
+   ``ENABLE_FEAT`` mechanism. At this time, this build option cannot be used on
+   systems that have SPM_MM enabled. The default value is 2.
+
+   Note that when SVE is enabled for the Non-secure world, access
+   to SVE, SIMD and floating-point functionality from the Secure world is
+   independently controlled by build option ``ENABLE_SVE_FOR_SWD``. When enabling
+   ``CTX_INCLUDE_FPREGS`` and ``ENABLE_SVE_FOR_NS`` together, it is mandatory to
+   enable ``CTX_INCLUDE_SVE_REGS``. This is to avoid corruption of the Non-secure
+   world data in the Z-registers which are aliased by the SIMD and FP registers.
 
--  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world.
-   SVE is an optional architectural feature for AArch64. Note that this option
-   requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it is
-   automatically disabled when the target architecture is AArch32.
+-  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE and FPU/SIMD functionality
+   for the Secure world. SVE is an optional architectural feature for AArch64.
+   The default is 0 and it is automatically disabled when the target architecture
+   is AArch32.
+
+   .. note::
+      This build flag requires ``ENABLE_SVE_FOR_NS`` to be enabled. When enabling
+      ``ENABLE_SVE_FOR_SWD``, a developer must carefully consider whether
+      ``CTX_INCLUDE_SVE_REGS`` is also needed.
 
 -  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
    checks in GCC. Allowed values are "all", "strong", "default" and "none". The
@@ -818,7 +864,7 @@
 -  ``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.
+   descriptors. Default value is 512.
 
 -  ``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
@@ -867,6 +913,11 @@
    flag is disabled by default and NOLOAD sections are placed in RAM immediately
    following the loaded firmware image.
 
+-  ``SEPARATE_SIMD_SECTION``: Setting this option to ``1`` allows the SIMD context
+    data structures to be put in a dedicated memory region as decided by platform
+    integrator. Default value is ``0`` which means the SIMD context is put in BSS
+    section of EL3 firmware.
+
 -  ``SMC_PCI_SUPPORT``: This option allows platforms to handle PCI configuration
    access requests via a standard SMCCC defined in `DEN0115`_. When combined with
    UEFI+ACPI this can provide a certain amount of OS forward compatibility
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 6a0241f..de2da2f 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -27,11 +27,11 @@
         Program          Min supported version
 ======================== =====================
 Arm Compiler             6.18
-Arm GNU Compiler         13.2
+Arm GNU Compiler         13.3
 Clang/LLVM               11.0.0
 Device Tree Compiler     1.4.7
 GNU make                 3.81
-mbed TLS\ [#f1]_         3.6.0
+mbed TLS\ [#f1]_         3.6.1
 Node.js [#f2]_           16
 OpenSSL                  1.0.0
 Poetry [#f2]_            1.3.2
@@ -51,7 +51,7 @@
 AArch64 builds, the respective targets required are ``arm-none-eabi`` and
 ``aarch64-none-elf``.
 
-Testing has been performed with version 13.2.Rel1 (gcc 13.2) of the Arm
+Testing has been performed with version 13.3.Rel1 (gcc 13.3) of the Arm
 GNU compiler, which can be installed from the `Arm Developer website`_.
 
 In addition, a native compiler is required to build supporting tools.
diff --git a/docs/license.rst b/docs/license.rst
index 8996105..9e0298b 100644
--- a/docs/license.rst
+++ b/docs/license.rst
@@ -93,9 +93,27 @@
 
    -  ``include/lib/dice/dice.h``
 
+-  Some source files originating from the `pydevicetree`_ project.
+   These files are licensed under the Apache License, Version 2.0, which is a
+   permissive license compatible with BSD-3-Clause. Any contributions to this
+   code must also be made under the terms of `Apache License 2.0`_.
+   These files are:
+
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/__init__.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/directive.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/helpers.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/node.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/property.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/reference.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/source/__init__.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/source/grammar.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/source/parser.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/__init__.py``
+
+
 .. _FreeBSD: http://www.freebsd.org
 .. _Linux MIT license: https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/MIT
 .. _SCC: http://www.simple-cc.org/
 .. _Open Profile for DICE: https://pigweed.googlesource.com/open-dice/
 .. _Apache License 2.0: https://www.apache.org/licenses/LICENSE-2.0.txt
-
+.. _pydevicetree: https://pypi.org/project/pydevicetree/
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index e1b3ef0..afbb157 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -16,6 +16,12 @@
    should match the frame used by the Non-Secure image (normally the Linux
    kernel). Default is true (access to the frame is allowed).
 
+-  ``ARM_FW_CONFIG_LOAD_ENABLE``: Boolean option to enable the loading of
+   FW_CONFIG device trees from the Firmware Image Package (FIP). When enabled,
+   BL2 calls the platform specific function `arm_bl2_el3_plat_config_load`.
+   This function is responsible for loading, parsing, and validating the
+   FW_CONFIG device trees from the FIP. The option depends on RESET_TO_BL2.
+
 -  ``ARM_DISABLE_TRUSTED_WDOG``: boolean option to disable the Trusted Watchdog.
    By default, Arm platforms use a watchdog to trigger a system reset in case
    an error is encountered during the boot process (for example, when an image
diff --git a/docs/plat/arm/automotive_rd/index.rst b/docs/plat/arm/automotive_rd/index.rst
new file mode 100644
index 0000000..d0db6ac
--- /dev/null
+++ b/docs/plat/arm/automotive_rd/index.rst
@@ -0,0 +1,50 @@
+RD-1 AE (Kronos) Platform
+=========================
+
+Some of the features of the RD-1 AE platform referenced in TF-A include:
+
+- Neoverse-V3AE, Arm9.2-A application processor (64-bit mode)
+- A GICv4-compatible GIC-720AE
+
+Further information on RD1-AE is available at `rd1ae`_
+
+Boot Sequence
+-------------
+
+BL2 –> BL31 –> BL33
+
+The boot process starts from RSE (Runtime Security Engine) that loads the BL2 image
+and signals the System Control Processor (SCP) to power up the Application Processor (AP).
+The AP then runs BL2, which loads the rest of the images, including the runtime firmware
+BL31, and proceeds to execute it. Finally, it passes control to the non-secure world
+BL33 (u-boot).
+
+BL2 performs the actions described in the `Trusted Board Boot (TBB)`_ document.
+
+Build Procedure (TF-A only)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+-  Obtain `Arm toolchain`_ and set the CROSS_COMPILE environment variable to
+   point to the toolchain folder.
+
+-  Build TF-A:
+
+   .. code:: shell
+
+      make \
+      PLAT=rd1ae \
+      MBEDTLS_DIR=<mbedtls_dir> \
+      ARCH=aarch64 \
+      CREATE_KEYS=1 \
+      GENERATE_COT=1 \
+      TRUSTED_BOARD_BOOT=1 \
+      COT=tbbr \
+      ARM_ROTPK_LOCATION=devel_rsa \
+      ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
+      BL33=<path to u-boot binary> \
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
+
+.. _Arm Toolchain: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
+.. _rd1ae: https://developer.arm.com/Tools%20and%20Software/Arm%20Reference%20Design-1%20AE
+.. _Trusted Board Boot (TBB): https://trustedfirmware-a.readthedocs.io/en/latest/design/trusted-board-boot.html
diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst
index 2f68522..35c0c59 100644
--- a/docs/plat/arm/index.rst
+++ b/docs/plat/arm/index.rst
@@ -14,6 +14,7 @@
    arm-build-options
    morello/index
    corstone1000/index
+   automotive_rd/index
 
 This chapter holds documentation related to Arm's development platforms,
 including both software models (FVPs) and hardware development boards
@@ -21,4 +22,4 @@
 
 --------------
 
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 85c97e5..a8e0c8d 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -72,8 +72,8 @@
 +----------------+----------------+--------------------+--------------------+
 |    Platform    |     Vendor     | Deprecated version |  Deleted version   |
 +================+================+====================+====================+
-| None at this   |                |                    |                    |
-| time.          |                |                    |                    |
+|      TC2       |      Arm       |        2.12        |         TBD        |
+|                |                |                    |                    |
 +----------------+----------------+--------------------+--------------------+
 
 --------------
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 53f63b5..384cd73 100644
--- a/docs/plat/rockchip.rst
+++ b/docs/plat/rockchip.rst
@@ -11,6 +11,7 @@
 -  rk3368: Octa-Core Cortex-A53
 -  rk3399: Hexa-Core Cortex-A53/A72
 -  rk3566/rk3568: Quad-Core Cortex-A55
+-  rk3588: Octa-Core Cortex-A55/A76
 
 
 Boot Sequence
diff --git a/docs/plat/s32g274a.rst b/docs/plat/s32g274a.rst
index 3aa858e..d3f31ca 100644
--- a/docs/plat/s32g274a.rst
+++ b/docs/plat/s32g274a.rst
@@ -95,5 +95,17 @@
                 -d "${BOOT_IMAGE}" \
                 fip.s32
 
+SoC Errata Workarounds
+----------------------
+
+The S32G274A port of the TF-A includes compilation flags that can be used to
+control the workaround for the SoC. These flags are used similarly to how the
+:ref:`arm_cpu_macros_errata_workarounds` are used. The list of workarounds
+includes the following switches:
+
+-  ``ERRATA_S32_051700``: This applies erratum ERR051700 workaround to
+   SoCs part of the S32 Common Chassis family, and therefore it needs to
+   be enabled for the S32G and S32R devices.
+
 .. _s32g2: https://www.nxp.com/products/processors-and-microcontrollers/s32-automotive-platform/s32g-vehicle-network-processors/s32g2-processors-for-vehicle-networking:S32G2
 .. _s32g274ardb2: https://www.nxp.com/design/design-center/designs/s32g2-vehicle-networking-reference-design:S32G-VNP-RDB2
diff --git a/docs/plat/st/stm32mp2.rst b/docs/plat/st/stm32mp2.rst
index 5d4ab4e..87bb6a5 100644
--- a/docs/plat/st/stm32mp2.rst
+++ b/docs/plat/st/stm32mp2.rst
@@ -85,7 +85,8 @@
 
 Boot with FIP
 ~~~~~~~~~~~~~
-You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) before building FIP binary.
+You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) and retrieve
+DDR PHY firmware before building FIP binary.
 
 U-Boot
 ______
@@ -106,9 +107,24 @@
         ARCH=arm PLATFORM=stm32mp2 \
         CFG_EMBED_DTB_SOURCE_FILE=stm32mp257f-ev1.dts
 
-TF-A BL2 & BL31
-_______________
-To build TF-A BL2 with its STM32 header and BL31 for SD-card boot:
+DDR PHY firmware
+________________
+DDR PHY firmware files may not be delivered inside TF-A repository, especially
+if you build directly from trustedfirmware.org repository. It then needs to be
+retrieved from `STMicroelectronics DDR PHY github`_.
+
+You can either clone the repository to the default directory:
+
+.. code:: bash
+
+    git clone https://github.com/STMicroelectronics/stm32-ddr-phy-binary.git drivers/st/ddr/phy/firmware/bin
+
+Or clone it somewhere else, and add ``STM32MP_DDR_FW_PATH=`` in your make command
+line when building FIP.
+
+TF-A BL2
+________
+To build TF-A BL2 with its STM32 header for SD-card boot:
 
 .. code:: bash
 
@@ -136,5 +152,6 @@
 
 .. _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
+.. _STMicroelectronics DDR PHY github: https://github.com/STMicroelectronics/stm32-ddr-phy-binary
 
 *Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index e9dd772..d22a46d 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -75,7 +75,7 @@
 | 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
 +---------------------------+-----------------------------------------------------------+
 
-PM SMC call ranges
+PM SMC call ranges for SiP SVC version 0.1
 --------------------------------------------------------
 
 +---------------------------+---------------------------------------------------------------------------+
@@ -84,6 +84,19 @@
 | 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
 +---------------------------+---------------------------------------------------------------------------+
 
+PM SMC call ranges for SiP SVC version 0.2
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000FFF                | Fast SMC64 SiP Service call used for pass-through of AMD-Xilinx Platform  |
+|                           | Management APIs to firmware                                               |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000A00-0xc2000AFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
+|                           | specific TF-A APIs                                                        |
++---------------------------+---------------------------------------------------------------------------+
+
 SMC function IDs for SiP Service queries
 ----------------------------------------------
 
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index 072329a..7185d91 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -14,11 +14,6 @@
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31
 ```
 
-To build ATF for different platform (supported are "silicon"(default) and "versal_virt")
-```bash
-make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal VERSAL_PLATFORM=versal_virt bl31
-```
-
 To build bl32 TSP you have to rebuild bl31 too
 ```bash
 make CROSS_COMPILE=aarch64-none-elf- PLAT=versal SPD=tspd RESET_TO_BL31=1 bl31 bl32
@@ -51,11 +46,6 @@
     -   `pl011`, `pl011_0`: ARM pl011 UART 0
     -   `pl011_1`         : ARM pl011 UART 1
 
-*   `VERSAL_PLATFORM`: Select the platform. Options:
-    -   `versal_virt`	: Versal Virtual platform
-    -   `spp_itr6`	: SPP ITR6
-    -   `emu_itr6`	: EMU ITR6
-
 *   `CPU_PWRDWN_SGI`: Select the SGI for triggering CPU power down request to
                       secondary cores on receiving power down callback from
                       firmware. Options:
@@ -98,8 +88,8 @@
 | 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
 +---------------------------+-----------------------------------------------------------+
 
-PM SMC call ranges
-------------------
+PM SMC call ranges for SiP SVC version 0.1
+--------------------------------------------------------
 
 +---------------------------+---------------------------------------------------------------------------+
 |   SMC Function Identifier |  Service type                                                             |
@@ -107,6 +97,19 @@
 | 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
 +---------------------------+---------------------------------------------------------------------------+
 
+PM SMC call ranges for SiP SVC version 0.2
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000FFF                | Fast SMC64 SiP Service call used for pass-through of AMD-Xilinx Platform  |
+|                           | Management APIs to firmware                                               |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000A00-0xc2000AFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
+|                           | specific TF-A APIs                                                        |
++---------------------------+---------------------------------------------------------------------------+
+
 SMC function IDs for SiP Service queries
 ----------------------------------------
 
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 5643ea1..e672ad7 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2248,26 +2248,35 @@
 
 ::
 
-    Argument : uintptr_t, size_t *, uintptr_t, size_t
+    Argument : uintptr_t, size_t *, uintptr_t, size_t, size_t *
     Return   : int
 
-This function returns the Platform attestation token.
+This function returns the Platform attestation token. If the full token does
+not fit in the buffer, the function will return a hunk of the token and
+indicate how many bytes were copied and how many are pending. Multiple calls
+to this function may be needed to retrieve the entire token.
 
 The parameters of the function are:
 
     arg0 - A pointer to the buffer where the Platform token should be copied by
-           this function. The buffer must be big enough to hold the Platform
-           token.
+           this function. If the platform token does not completely fit in the
+           buffer, the function may return a piece of the token only.
 
-    arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
-           function returns the platform token length in this parameter.
+    arg1 - Contains the size (in bytes) of the buffer passed in arg0. In
+           addition, this parameter is used by the function to return the size
+           of the platform token length hunk copied to the buffer.
 
     arg2 - A pointer to the buffer where the challenge object is stored.
 
     arg3 - The length of the challenge object in bytes. Possible values are 32,
-           48 and 64.
+           48 and 64. This argument must be zero for subsequent calls to
+           retrieve the remaining hunks of the token.
+
+    arg4 - Returns the remaining length of the token (in bytes) that is yet to
+           be returned in further calls.
 
-The function returns 0 on success, -EINVAL on failure.
+The function returns 0 on success, -EINVAL on failure and -EAGAIN if the
+resource associated with the platform token retrieval is busy.
 
 Function : plat_rmmd_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/tools/cot-dt2c.rst b/docs/tools/cot-dt2c.rst
new file mode 100644
index 0000000..e8bb1ac
--- /dev/null
+++ b/docs/tools/cot-dt2c.rst
@@ -0,0 +1,119 @@
+TF-A CoT dt2c Tool
+==================
+
+This tool is used to automatically generate the corresponding c file for a
+CoT DT file. Since currently TF-A support two type of CoT file: static c file
+and CoT DT binding. This is error prone and hard to maintain, therefore this
+tool can generate the c file for the platform that does not support CoT DT
+binding, given the CoT DT file so the c file can be deprecated.
+
+Prerequisites
+~~~~~~~~~~~~~
+
+#. Python (3.8 or later)
+#. `Poetry`_ Python package manager
+
+Getting Started
+~~~~~~~~~~~~~~~
+
+``cot-dt2c`` is installed by default with TF-A's poetry environment. All of it's
+dependencies are listed in `tools/cot_dt2c/pyproject.toml`_.
+
+``cot-dt2c`` requires a standard DTS file without #ifdef, macros, or other
+preprocessor directives. Therefore, you need to provide a preprocessed device
+tree source(DTS) as input to the tool.
+
+#. Usage of the tool
+
+    .. code::
+
+        cot-dt2c
+
+    This command will output the following as usage for this command
+
+    .. code-block:: text
+
+        Usage: cot-dt2c [OPTIONS] COMMAND [ARGS]...
+
+        Options:
+        --version  Show the version and exit.
+        --help     Show this message and exit.
+
+        Commands:
+        convert-to-c
+        validate-cot
+        visualize-cot
+        validate-dt
+
+Convert CoT descriptors to C file
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To convert the CoT descriptors
+
+This command is for the platform that does not use CoT DT parser,
+which can generate the C file given the CoT descriptors. Before
+the conversion to C file, the tool will do an implicit checks on
+the validity of the CoT DT file.
+
+.. code::
+
+    cot-dt2c convert-to-c [INPUT DTS PATH] [OUTPUT C PATH]
+    cot-dt2c convert-to-c fdts/tbbr_cot_descriptors.dtsi test.c
+
+
+Validate CoT descriptors
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To validate the certificate
+
+The tests folder in the tool folder provides some bad-example of the
+DT file, and the tool will print out "not a valid CoT DT file" on console.
+
+The command will check the format of the CoT file
+
+#. The open bracket
+#. The open ifdef macro
+#. The missing mandatory attribute
+#. Malformed DT file (cert missing parent, missing root certs. etc.)
+
+Currently the validation is specifically for checking the CoT DT file
+
+.. code::
+
+    cot-dt2c validate-cot [INPUT DTS PATH]
+    cot-dt2c validate-cot fdts/tbbr_cot_descriptors.dtsi
+
+
+Visualize CoT descriptors
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This command create a HTML to visualize the relationship between
+the certificates and the image of a CoT DT file.
+
+.. code::
+
+    cot-dt2c visualize-cot [INPUT DTS PATH]
+    cot-dt2c visualize-cot fdts/tbbr_cot_descriptors.dtsi
+
+
+Validate Other DT files
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The command will transform the dtsi/dts file into a more standard
+dtsi/dts file inside /tmp folder that can be used as input to dt-schema
+for further validation. Currently the tool will perform some basic validation
+for the file (syntax) and dt-schema can be used for advance checks. dt-schema
+is not installed along with the tool.
+
+.. code::
+
+    cot-dt2c validate-dt [INPUT DTS PATH or INPUT DTS folder]
+    cot-dt2c validate-dt fdts/
+    cot-dt2c validate-dt fdts/fvp-bsae-gicv3.dtsi
+
+--------------
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
+
+.. _tools/cot_dt2c/pyproject.toml: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/integration/tools/cot_dt2c/pyproject.toml
+.. _Poetry: https://python-poetry.org/docs/
diff --git a/docs/tools/index.rst b/docs/tools/index.rst
index 2dee2c0..c0e214a 100644
--- a/docs/tools/index.rst
+++ b/docs/tools/index.rst
@@ -6,7 +6,9 @@
    :caption: Contents
 
    memory-layout-tool
+   transfer-list-compiler
+   cot-dt2c
 
 --------------
 
-*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/dcc/dcc_console.c b/drivers/arm/dcc/dcc_console.c
index 19c3450..841c1fd 100644
--- a/drivers/arm/dcc/dcc_console.c
+++ b/drivers/arm/dcc/dcc_console.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2015-2021, Xilinx Inc.
+ * Copyright (c) 2015-2022, Xilinx Inc.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  * Written by Michal Simek.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -45,7 +46,7 @@
 #define TIMEOUT_COUNT_US	U(0x10624)
 
 struct dcc_console {
-	struct console console;
+	console_t console;
 };
 
 static inline uint32_t __dcc_getstatus(void)
@@ -147,13 +148,14 @@
 	},
 };
 
-int console_dcc_register(void)
+int console_dcc_register(console_t *console)
 {
-	return console_register(&dcc_console.console);
+	memcpy(console, &dcc_console.console, sizeof(console_t));
+	return console_register(console);
 }
 
-void console_dcc_unregister(void)
+void console_dcc_unregister(console_t *console)
 {
-	dcc_console_flush(&dcc_console.console);
-	(void)console_unregister(&dcc_console.console);
+	dcc_console_flush(console);
+	(void)console_unregister(console);
 }
diff --git a/drivers/arm/gic/v3/arm_gicv3_common.c b/drivers/arm/gic/v3/arm_gicv3_common.c
index 4489892..cc82ddb 100644
--- a/drivers/arm/gic/v3/arm_gicv3_common.c
+++ b/drivers/arm/gic/v3/arm_gicv3_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,10 +28,13 @@
 void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num)
 {
 	uintptr_t gicr_base = 0;
+	unsigned int typer_reg;
 
 	assert(gicv3_driver_data);
 	assert(gicv3_driver_data->rdistif_base_addrs);
+	assert(gicv3_driver_data->gicd_base != 0U);
 
+	typer_reg = gicd_read_typer(gicv3_driver_data->gicd_base);
 	/*
 	 * The GICR_WAKER.Sleep bit should be set only when both
 	 * GICR_WAKER.ChildrenAsleep and GICR_WAKER.ProcessorSleep are set on
@@ -60,9 +63,14 @@
 	 */
 	gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_SL_BIT);
 
-	/* Wait until the GICR_WAKER.Quiescent bit is set */
-	while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT))
-		;
+	/*
+	 * If LPIs are supported, wait until the GICR_WAKER.Quiescent bit is
+	 * set.
+	 */
+	if ((typer_reg & TYPER_LPIS) != 0U) {
+		while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT))
+			;
+	}
 }
 
 /*
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 8ea164c..2be19db 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -686,6 +686,8 @@
 	gicr_write_ctlr(gicr_base,
 			rdist_ctx->gicr_ctlr & ~(GICR_CTLR_EN_LPIS_BIT));
 
+	gicr_wait_for_pending_write(gicr_base);
+
 	/* Restore registers' content */
 	gicr_write_propbaser(gicr_base, rdist_ctx->gicr_propbaser);
 	gicr_write_pendbaser(gicr_base, rdist_ctx->gicr_pendbaser);
diff --git a/drivers/auth/cca/bl1_cot.c b/drivers/auth/cca/bl1_cot.c
new file mode 100644
index 0000000..43cb18a
--- /dev/null
+++ b/drivers/auth/cca/bl1_cot.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <mbedtls/version.h>
+
+#include <common/tbbr/cot_def.h>
+#include <drivers/auth/auth_mod.h>
+#include <platform_def.h>
+#include <tools_share/cca_oid.h>
+
+/*
+ * Allocate static buffers to store the authentication parameters extracted from
+ * the certificates.
+ */
+static unsigned char fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
+
+/*
+ * Parameter type descriptors.
+ */
+static auth_param_type_desc_t cca_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, CCA_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, 0);
+static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG, 0);
+static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG_ALG, 0);
+static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_RAW_DATA, 0);
+
+static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
+static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
+
+/* CCA Content Certificate */
+static const auth_img_desc_t cca_content_cert = {
+	.img_id = CCA_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &cca_nv_ctr,
+				.plat_nv_ctr = &cca_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tb_fw_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tb_fw_config_hash,
+			.data = {
+				.ptr = (void *)tb_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &fw_config_hash,
+			.data = {
+				.ptr = (void *)fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t bl2_image = {
+	.img_id = BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t tb_fw_config = {
+	.img_id = TB_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_config_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t fw_config = {
+	.img_id = FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &fw_config_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t * const cot_desc[] = {
+	[CCA_CONTENT_CERT_ID]			=	&cca_content_cert,
+	[BL2_IMAGE_ID]				=	&bl2_image,
+	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
+	[FW_CONFIG_ID]				=	&fw_config,
+};
+
+REGISTER_COT(cot_desc);
diff --git a/drivers/auth/cca/cot.c b/drivers/auth/cca/cot.c
deleted file mode 100644
index 2a03604..0000000
--- a/drivers/auth/cca/cot.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-
-#include <mbedtls/version.h>
-
-#include <common/tbbr/cot_def.h>
-#include <drivers/auth/auth_mod.h>
-#include <tools_share/cca_oid.h>
-
-#include <platform_def.h>
-
-/*
- * Allocate static buffers to store the authentication parameters extracted from
- * the certificates.
- */
-static unsigned char fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char hw_config_hash_buf[HASH_DER_LEN];
-static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
-static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char rmm_hash_buf[HASH_DER_LEN];
-
-#ifdef IMAGE_BL2
-static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
-#if defined(SPD_spmd)
-static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
-#endif /* SPD_spmd */
-
-static unsigned char core_swd_pk_buf[PK_DER_LEN];
-static unsigned char plat_pk_buf[PK_DER_LEN];
-#endif /* IMAGE_BL2 */
-
-/*
- * Parameter type descriptors.
- */
-static auth_param_type_desc_t cca_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, CCA_FW_NVCOUNTER_OID);
-static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, 0);
-static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG, 0);
-static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG_ALG, 0);
-static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_RAW_DATA, 0);
-
-static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
-static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
-static 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 soc_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
-static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t rmm_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, RMM_HASH_OID);
-
-#ifdef IMAGE_BL2
-static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
-static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
-
-static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, PROT_PK_OID);
-static auth_param_type_desc_t swd_rot_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, SWD_ROT_PK_OID);
-static auth_param_type_desc_t core_swd_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, CORE_SWD_PK_OID);
-static auth_param_type_desc_t plat_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, PLAT_PK_OID);
-
-static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
-static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
-static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
-#if defined(SPD_spmd)
-static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
-static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
-static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
-static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
-static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
-static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
-static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
-static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
-#endif /* SPD_spmd */
-#endif /* IMAGE_BL2 */
-
-/* CCA Content Certificate */
-static const auth_img_desc_t cca_content_cert = {
-	.img_id = CCA_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &cca_nv_ctr,
-				.plat_nv_ctr = &cca_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tb_fw_hash,
-			.data = {
-				.ptr = (void *)tb_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &tb_fw_config_hash,
-			.data = {
-				.ptr = (void *)tb_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &fw_config_hash,
-			.data = {
-				.ptr = (void *)fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &hw_config_hash,
-			.data = {
-				.ptr = (void *)hw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[4] = {
-			.type_desc = &soc_fw_hash,
-			.data = {
-				.ptr = (void *)soc_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[5] = {
-			.type_desc = &soc_fw_config_hash,
-			.data = {
-				.ptr = (void *)soc_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[6] = {
-			.type_desc = &rmm_hash,
-			.data = {
-				.ptr = (void *)rmm_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-#ifdef IMAGE_BL1
-static const auth_img_desc_t bl2_image = {
-	.img_id = BL2_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tb_fw_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t tb_fw_config = {
-	.img_id = TB_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tb_fw_config_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t fw_config = {
-	.img_id = FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &fw_config_hash
-			}
-		}
-	}
-};
-#endif /* IMAGE_BL1 */
-
-#ifdef IMAGE_BL2
-/* HW Config */
-static const auth_img_desc_t hw_config = {
-	.img_id = HW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_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
-			}
-		}
-	}
-};
-
-/* BL31 */
-static const auth_img_desc_t bl31_image = {
-	.img_id = BL31_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &soc_fw_hash
-			}
-		}
-	}
-};
-
-/* BL31 Config */
-static const auth_img_desc_t soc_fw_config = {
-	.img_id = SOC_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &soc_fw_config_hash
-			}
-		}
-	}
-};
-
-/* RMM */
-static const auth_img_desc_t rmm_image = {
-	.img_id = RMM_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &rmm_hash
-			}
-		}
-	}
-};
-
-/* Core SWD Key Certificate */
-static const auth_img_desc_t core_swd_key_cert = {
-	.img_id = CORE_SWD_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL, /* SWD ROOT CERT */
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &swd_rot_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &core_swd_pk,
-			.data = {
-				.ptr = (void *)core_swd_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-/* SPMC Content Certificate */
-static const auth_img_desc_t trusted_os_fw_content_cert = {
-	.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &core_swd_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &core_swd_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tos_fw_hash,
-			.data = {
-				.ptr = (void *)tos_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &tos_fw_config_hash,
-			.data = {
-				.ptr = (void *)tos_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-/* SPMC */
-static const auth_img_desc_t bl32_image = {
-	.img_id = BL32_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_hash
-			}
-		}
-	}
-};
-
-/* SPM Config */
-static const auth_img_desc_t tos_fw_config = {
-	.img_id = TOS_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_config_hash
-			}
-		}
-	}
-};
-
-/* Platform Key Certificate */
-static const auth_img_desc_t plat_key_cert = {
-	.img_id = PLAT_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL, /* PLATFORM ROOT CERT */
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &prot_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &plat_pk,
-			.data = {
-				.ptr = (void *)plat_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-/* Non-Trusted Firmware */
-static const auth_img_desc_t non_trusted_fw_content_cert = {
-	.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &plat_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &plat_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &nt_world_bl_hash,
-			.data = {
-				.ptr = (void *)nt_world_bl_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &nt_fw_config_hash,
-			.data = {
-				.ptr = (void *)nt_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl33_image = {
-	.img_id = BL33_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &non_trusted_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &nt_world_bl_hash
-			}
-		}
-	}
-};
-
-/* NT FW Config */
-static const auth_img_desc_t nt_fw_config = {
-	.img_id = NT_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &non_trusted_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &nt_fw_config_hash
-			}
-		}
-	}
-};
-
-/*
- * Secure Partitions
- */
-#if defined(SPD_spmd)
-static const auth_img_desc_t sip_sp_content_cert = {
-	.img_id = SIP_SP_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &core_swd_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &core_swd_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &sp_pkg1_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[0],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &sp_pkg2_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[1],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &sp_pkg3_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[2],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &sp_pkg4_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[3],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-DEFINE_SIP_SP_PKG(1);
-DEFINE_SIP_SP_PKG(2);
-DEFINE_SIP_SP_PKG(3);
-DEFINE_SIP_SP_PKG(4);
-
-static const auth_img_desc_t plat_sp_content_cert = {
-	.img_id = PLAT_SP_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &plat_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &plat_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &sp_pkg5_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[4],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &sp_pkg6_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[5],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &sp_pkg7_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[6],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &sp_pkg8_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[7],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-DEFINE_PLAT_SP_PKG(5);
-DEFINE_PLAT_SP_PKG(6);
-DEFINE_PLAT_SP_PKG(7);
-DEFINE_PLAT_SP_PKG(8);
-#endif /* SPD_spmd */
-#endif /* IMAGE_BL2 */
-/*
- * Chain of trust definition
- */
-#ifdef IMAGE_BL1
-static const auth_img_desc_t * const cot_desc[] = {
-	[CCA_CONTENT_CERT_ID]			=	&cca_content_cert,
-	[BL2_IMAGE_ID]				=	&bl2_image,
-	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
-	[FW_CONFIG_ID]				=	&fw_config,
-};
-#else /* IMAGE_BL2 */
-static const auth_img_desc_t * const cot_desc[] = {
-	[CCA_CONTENT_CERT_ID]			=	&cca_content_cert,
-	[HW_CONFIG_ID]				=	&hw_config,
-	[BL31_IMAGE_ID]				=	&bl31_image,
-	[SOC_FW_CONFIG_ID]			=	&soc_fw_config,
-	[RMM_IMAGE_ID]				=	&rmm_image,
-	[CORE_SWD_KEY_CERT_ID]			=	&core_swd_key_cert,
-	[TRUSTED_OS_FW_CONTENT_CERT_ID]		=	&trusted_os_fw_content_cert,
-	[BL32_IMAGE_ID]				=	&bl32_image,
-	[TOS_FW_CONFIG_ID]			=	&tos_fw_config,
-	[PLAT_KEY_CERT_ID]			=	&plat_key_cert,
-	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
-	[BL33_IMAGE_ID]				=	&bl33_image,
-	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
-#if defined(SPD_spmd)
-	[SIP_SP_CONTENT_CERT_ID]		=	&sip_sp_content_cert,
-	[PLAT_SP_CONTENT_CERT_ID]		=	&plat_sp_content_cert,
-	[SP_PKG1_ID]				=	&sp_pkg1,
-	[SP_PKG2_ID]				=	&sp_pkg2,
-	[SP_PKG3_ID]				=	&sp_pkg3,
-	[SP_PKG4_ID]				=	&sp_pkg4,
-	[SP_PKG5_ID]				=	&sp_pkg5,
-	[SP_PKG6_ID]				=	&sp_pkg6,
-	[SP_PKG7_ID]				=	&sp_pkg7,
-	[SP_PKG8_ID]				=       &sp_pkg8,
-#endif
-};
-#endif /* IMAGE_BL1 */
-
-/* Register the CoT in the authentication module */
-REGISTER_COT(cot_desc);
diff --git a/drivers/auth/dualroot/bl1_cot.c b/drivers/auth/dualroot/bl1_cot.c
new file mode 100644
index 0000000..a548170
--- /dev/null
+++ b/drivers/auth/dualroot/bl1_cot.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <mbedtls/version.h>
+
+#include <common/tbbr/cot_def.h>
+#include <drivers/auth/auth_mod.h>
+#include <platform_def.h>
+#include <tools_share/dualroot_oid.h>
+
+/*
+ * Allocate static buffers to store the authentication parameters extracted from
+ * the certificates.
+ */
+static unsigned char fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char scp_fw_hash_buf[HASH_DER_LEN];
+static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
+
+/*
+ * Parameter type descriptors.
+ */
+static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, 0);
+static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG, 0);
+static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG_ALG, 0);
+static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_RAW_DATA, 0);
+
+static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
+static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
+static 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 scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, FWU_HASH_OID);
+
+static const auth_img_desc_t trusted_boot_fw_cert = {
+	.img_id = TRUSTED_BOOT_FW_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tb_fw_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tb_fw_config_hash,
+			.data = {
+				.ptr = (void *)tb_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &fw_config_hash,
+			.data = {
+				.ptr = (void *)fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t bl2_image = {
+	.img_id = BL2_IMAGE_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 = &tb_fw_hash
+			}
+		}
+	}
+};
+
+/* TB FW Config */
+static const auth_img_desc_t tb_fw_config = {
+	.img_id = TB_FW_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 = &tb_fw_config_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t fw_config = {
+	.img_id = FW_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 = &fw_config_hash
+			}
+		}
+	}
+};
+
+/* FWU auth descriptor */
+static const auth_img_desc_t fwu_cert = {
+	.img_id = FWU_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_bl2u_hash,
+			.data = {
+				.ptr = (void *)scp_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &bl2u_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &ns_bl2u_hash,
+			.data = {
+				.ptr = (void *)nt_world_bl_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+/* SCP_BL2U */
+static const auth_img_desc_t scp_bl2u_image = {
+	.img_id = SCP_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &scp_bl2u_hash
+			}
+		}
+	}
+};
+
+/* BL2U */
+static const auth_img_desc_t bl2u_image = {
+	.img_id = BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &bl2u_hash
+			}
+		}
+	}
+};
+
+/* NS_BL2U */
+static const auth_img_desc_t ns_bl2u_image = {
+	.img_id = NS_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &ns_bl2u_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t * const cot_desc[] = {
+	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
+	[BL2_IMAGE_ID]				=	&bl2_image,
+	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
+	[FW_CONFIG_ID]				=	&fw_config,
+	[FWU_CERT_ID]				=	&fwu_cert,
+	[SCP_BL2U_IMAGE_ID]			=	&scp_bl2u_image,
+	[BL2U_IMAGE_ID]				=	&bl2u_image,
+	[NS_BL2U_IMAGE_ID]			=	&ns_bl2u_image
+};
+
+REGISTER_COT(cot_desc);
diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c
deleted file mode 100644
index c89930c..0000000
--- a/drivers/auth/dualroot/cot.c
+++ /dev/null
@@ -1,962 +0,0 @@
-/*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-
-#include <mbedtls/version.h>
-
-#include <common/tbbr/cot_def.h>
-#include <drivers/auth/auth_mod.h>
-
-#include <tools_share/dualroot_oid.h>
-
-#include <platform_def.h>
-
-/*
- * Allocate static buffers to store the authentication parameters extracted from
- * the certificates.
- */
-static unsigned char fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char hw_config_hash_buf[HASH_DER_LEN];
-static unsigned char scp_fw_hash_buf[HASH_DER_LEN];
-static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
-
-#ifdef IMAGE_BL2
-static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN];
-static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
-#if defined(SPD_spmd)
-static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
-#endif /* SPD_spmd */
-
-static unsigned char trusted_world_pk_buf[PK_DER_LEN];
-static unsigned char content_pk_buf[PK_DER_LEN];
-#endif
-
-/*
- * Parameter type descriptors.
- */
-static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
-static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, 0);
-static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG, 0);
-static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG_ALG, 0);
-static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_RAW_DATA, 0);
-
-static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
-static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
-static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
-#ifdef IMAGE_BL1
-static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, FWU_HASH_OID);
-#endif /* IMAGE_BL1 */
-
-#ifdef IMAGE_BL2
-static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
-
-static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
-static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID);
-static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID);
-static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID);
-static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, PROT_PK_OID);
-
-static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SCP_FW_HASH_OID);
-static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
-static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
-static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID);
-static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_OID);
-static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
-static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
-#if defined(SPD_spmd)
-static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
-static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
-static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
-static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
-static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
-static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
-static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
-static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
-#endif /* SPD_spmd */
-#endif /* IMAGE_BL2 */
-
-
-/* BL2 */
-static const auth_img_desc_t trusted_boot_fw_cert = {
-	.img_id = TRUSTED_BOOT_FW_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tb_fw_hash,
-			.data = {
-				.ptr = (void *)tb_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &tb_fw_config_hash,
-			.data = {
-				.ptr = (void *)tb_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &hw_config_hash,
-			.data = {
-				.ptr = (void *)hw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &fw_config_hash,
-			.data = {
-				.ptr = (void *)fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-#ifdef IMAGE_BL1
-static const auth_img_desc_t bl2_image = {
-	.img_id = BL2_IMAGE_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 = &tb_fw_hash
-			}
-		}
-	}
-};
-#endif /* IMAGE_BL1 */
-
-/* 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
-			}
-		}
-	}
-};
-
-/* TB FW Config */
-#ifdef IMAGE_BL1
-static const auth_img_desc_t tb_fw_config = {
-	.img_id = TB_FW_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 = &tb_fw_config_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t fw_config = {
-	.img_id = FW_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 = &fw_config_hash
-			}
-		}
-	}
-};
-
-#endif /* IMAGE_BL1 */
-
-#ifdef IMAGE_BL2
-/* Trusted key certificate */
-static const auth_img_desc_t trusted_key_cert = {
-	.img_id = TRUSTED_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &trusted_world_pk,
-			.data = {
-				.ptr = (void *)trusted_world_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		},
-	}
-};
-
-/* SCP Firmware */
-static const auth_img_desc_t scp_fw_key_cert = {
-	.img_id = SCP_FW_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &trusted_world_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &scp_fw_content_pk,
-			.data = {
-				.ptr = (void *)content_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t scp_fw_content_cert = {
-	.img_id = SCP_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &scp_fw_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &scp_fw_content_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &scp_fw_hash,
-			.data = {
-				.ptr = (void *)scp_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t scp_bl2_image = {
-	.img_id = SCP_BL2_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &scp_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &scp_fw_hash
-			}
-		}
-	}
-};
-
-/* SoC Firmware */
-static const auth_img_desc_t soc_fw_key_cert = {
-	.img_id = SOC_FW_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &trusted_world_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &soc_fw_content_pk,
-			.data = {
-				.ptr = (void *)content_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t soc_fw_content_cert = {
-	.img_id = SOC_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &soc_fw_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &soc_fw_content_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &soc_fw_hash,
-			.data = {
-				.ptr = (void *)soc_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &soc_fw_config_hash,
-			.data = {
-				.ptr = (void *)soc_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl31_image = {
-	.img_id = BL31_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &soc_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &soc_fw_hash
-			}
-		}
-	}
-};
-
-/* SOC FW Config */
-static const auth_img_desc_t soc_fw_config = {
-	.img_id = SOC_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &soc_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &soc_fw_config_hash
-			}
-		}
-	}
-};
-
-/* Trusted OS Firmware */
-static const auth_img_desc_t trusted_os_fw_key_cert = {
-	.img_id = TRUSTED_OS_FW_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &trusted_world_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tos_fw_content_pk,
-			.data = {
-				.ptr = (void *)content_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t trusted_os_fw_content_cert = {
-	.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_os_fw_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &tos_fw_content_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tos_fw_hash,
-			.data = {
-				.ptr = (void *)tos_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &tos_fw_extra1_hash,
-			.data = {
-				.ptr = (void *)tos_fw_extra1_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &tos_fw_extra2_hash,
-			.data = {
-				.ptr = (void *)tos_fw_extra2_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &tos_fw_config_hash,
-			.data = {
-				.ptr = (void *)tos_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl32_image = {
-	.img_id = BL32_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl32_extra1_image = {
-	.img_id = BL32_EXTRA1_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_extra1_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl32_extra2_image = {
-	.img_id = BL32_EXTRA2_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_extra2_hash
-			}
-		}
-	}
-};
-
-/* TOS FW Config */
-static const auth_img_desc_t tos_fw_config = {
-	.img_id = TOS_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_config_hash
-			}
-		}
-	}
-};
-
-/* Non-Trusted Firmware */
-static const auth_img_desc_t non_trusted_fw_content_cert = {
-	.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL, /* Root certificate.  */
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &prot_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &nt_world_bl_hash,
-			.data = {
-				.ptr = (void *)nt_world_bl_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &nt_fw_config_hash,
-			.data = {
-				.ptr = (void *)nt_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl33_image = {
-	.img_id = BL33_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &non_trusted_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &nt_world_bl_hash
-			}
-		}
-	}
-};
-
-/* NT FW Config */
-static const auth_img_desc_t nt_fw_config = {
-	.img_id = NT_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &non_trusted_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &nt_fw_config_hash
-			}
-		}
-	}
-};
-
-/*
- * Secure Partitions
- */
-#if defined(SPD_spmd)
-static const auth_img_desc_t sip_sp_content_cert = {
-	.img_id = SIP_SP_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &trusted_world_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &sp_pkg1_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[0],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &sp_pkg2_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[1],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &sp_pkg3_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[2],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &sp_pkg4_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[3],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-DEFINE_SIP_SP_PKG(1);
-DEFINE_SIP_SP_PKG(2);
-DEFINE_SIP_SP_PKG(3);
-DEFINE_SIP_SP_PKG(4);
-
-static const auth_img_desc_t plat_sp_content_cert = {
-	.img_id = PLAT_SP_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &prot_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &sp_pkg5_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[4],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &sp_pkg6_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[5],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &sp_pkg7_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[6],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &sp_pkg8_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[7],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-DEFINE_PLAT_SP_PKG(5);
-DEFINE_PLAT_SP_PKG(6);
-DEFINE_PLAT_SP_PKG(7);
-DEFINE_PLAT_SP_PKG(8);
-#endif /* SPD_spmd */
-
-#else  /* IMAGE_BL2 */
-
-/* FWU auth descriptor */
-static const auth_img_desc_t fwu_cert = {
-	.img_id = FWU_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &scp_bl2u_hash,
-			.data = {
-				.ptr = (void *)scp_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &bl2u_hash,
-			.data = {
-				.ptr = (void *)tb_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &ns_bl2u_hash,
-			.data = {
-				.ptr = (void *)nt_world_bl_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-/* SCP_BL2U */
-static const auth_img_desc_t scp_bl2u_image = {
-	.img_id = SCP_BL2U_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &fwu_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &scp_bl2u_hash
-			}
-		}
-	}
-};
-
-/* BL2U */
-static const auth_img_desc_t bl2u_image = {
-	.img_id = BL2U_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &fwu_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &bl2u_hash
-			}
-		}
-	}
-};
-
-/* NS_BL2U */
-static const auth_img_desc_t ns_bl2u_image = {
-	.img_id = NS_BL2U_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &fwu_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &ns_bl2u_hash
-			}
-		}
-	}
-};
-#endif /* IMAGE_BL2 */
-
-/*
- * Chain of trust definition
- */
-#ifdef IMAGE_BL1
-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,
-	[SCP_BL2U_IMAGE_ID]			=	&scp_bl2u_image,
-	[BL2U_IMAGE_ID]				=	&bl2u_image,
-	[NS_BL2U_IMAGE_ID]			=	&ns_bl2u_image
-};
-#else /* IMAGE_BL2 */
-static const auth_img_desc_t * const cot_desc[] = {
-	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
-	[HW_CONFIG_ID]				=	&hw_config,
-	[TRUSTED_KEY_CERT_ID]			=	&trusted_key_cert,
-	[SCP_FW_KEY_CERT_ID]			=	&scp_fw_key_cert,
-	[SCP_FW_CONTENT_CERT_ID]		=	&scp_fw_content_cert,
-	[SCP_BL2_IMAGE_ID]			=	&scp_bl2_image,
-	[SOC_FW_KEY_CERT_ID]			=	&soc_fw_key_cert,
-	[SOC_FW_CONTENT_CERT_ID]		=	&soc_fw_content_cert,
-	[BL31_IMAGE_ID]				=	&bl31_image,
-	[SOC_FW_CONFIG_ID]			=	&soc_fw_config,
-	[TRUSTED_OS_FW_KEY_CERT_ID]		=	&trusted_os_fw_key_cert,
-	[TRUSTED_OS_FW_CONTENT_CERT_ID]		=	&trusted_os_fw_content_cert,
-	[BL32_IMAGE_ID]				=	&bl32_image,
-	[BL32_EXTRA1_IMAGE_ID]			=	&bl32_extra1_image,
-	[BL32_EXTRA2_IMAGE_ID]			=	&bl32_extra2_image,
-	[TOS_FW_CONFIG_ID]			=	&tos_fw_config,
-	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
-	[BL33_IMAGE_ID]				=	&bl33_image,
-	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
-#if defined(SPD_spmd)
-	[SIP_SP_CONTENT_CERT_ID]		=	&sip_sp_content_cert,
-	[PLAT_SP_CONTENT_CERT_ID]		=	&plat_sp_content_cert,
-	[SP_PKG1_ID]				=	&sp_pkg1,
-	[SP_PKG2_ID]				=	&sp_pkg2,
-	[SP_PKG3_ID]				=	&sp_pkg3,
-	[SP_PKG4_ID]				=	&sp_pkg4,
-	[SP_PKG5_ID]				=	&sp_pkg5,
-	[SP_PKG6_ID]				=	&sp_pkg6,
-	[SP_PKG7_ID]				=	&sp_pkg7,
-	[SP_PKG8_ID]				=       &sp_pkg8,
-#endif
-};
-#endif
-
-/* Register the CoT in the authentication module */
-REGISTER_COT(cot_desc);
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 55ab935..765491e 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -66,7 +66,6 @@
 					)
 
 ifeq (${PSA_CRYPTO},1)
-LIBMBEDTLS_CFLAGS 	+= -Wno-error=unused-but-set-variable
 LIBMBEDTLS_SRCS         += $(addprefix ${MBEDTLS_DIR}/library/,    	\
 					psa_crypto.c                   	\
 					psa_crypto_client.c            	\
@@ -74,6 +73,8 @@
 					psa_crypto_rsa.c               	\
 					psa_crypto_ecp.c               	\
 					psa_crypto_slot_management.c   	\
+					psa_crypto_aead.c               \
+					psa_crypto_cipher.c             \
 					psa_util.c			\
 					)
 endif
@@ -118,6 +119,14 @@
     TF_MBEDTLS_HASH_ALG_ID	:=	TF_MBEDTLS_SHA256
 endif
 
+ifeq (${MBOOT_EL_HASH_ALG}, sha256)
+    $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA256))
+else ifeq (${MBOOT_EL_HASH_ALG}, sha384)
+    $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA384))
+else ifeq (${MBOOT_EL_HASH_ALG}, sha512)
+    $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+endif
+
 ifeq (${TF_MBEDTLS_KEY_ALG},ecdsa)
     TF_MBEDTLS_KEY_ALG_ID	:=	TF_MBEDTLS_ECDSA
 else ifeq (${TF_MBEDTLS_KEY_ALG},rsa)
diff --git a/drivers/auth/mbedtls/mbedtls_psa_crypto.c b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
index 2da97dc..f2ccf15 100644
--- a/drivers/auth/mbedtls/mbedtls_psa_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
@@ -9,13 +9,11 @@
 #include <string.h>
 
 /* mbed TLS headers */
-#include <mbedtls/gcm.h>
 #include <mbedtls/md.h>
 #include <mbedtls/memory_buffer_alloc.h>
 #include <mbedtls/oid.h>
 #include <mbedtls/platform.h>
 #include <mbedtls/psa_util.h>
-#include <mbedtls/version.h>
 #include <mbedtls/x509.h>
 #include <psa/crypto.h>
 #include <psa/crypto_platform.h>
@@ -104,242 +102,84 @@
 #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;
-}
+ * 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
+ * update to 3.5.2, where this function is exposed.
+ */
+int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
+			     const mbedtls_x509_buf *sig_params,
+			     mbedtls_md_type_t *md_alg,
+			     mbedtls_pk_type_t *pk_alg,
+			     void **sig_opts);
 
 /*
- * 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)
+ * 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)
 {
-	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;
+	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;
 
-	pk_end = pk_ptr + *pk_len;
-	rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len,
-				  MBEDTLS_ASN1_CONSTRUCTED |
-				  MBEDTLS_ASN1_SEQUENCE);
+	rc = mbedtls_asn1_get_alg(&p, end, &sig_alg_oid, &params);
 	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end;
 	}
 
-	pk_end = pk_ptr + len;
-	rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params);
+	rc = mbedtls_x509_get_sig_alg(&sig_alg_oid, &params, &md_alg, pk_alg, &sig_opts);
 	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end;
 	}
 
-	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;
-	}
+	psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
 
-	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;
+	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;
 	}
 
-	*pk_start = pk_ptr;
-	*pk_len = len;
-
+end:
+	mbedtls_free(sig_opts);
 	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)
+ * Helper functions for mbedtls PK contexts.
+ */
+static void initialize_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
 {
-	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;
+	mbedtls_pk_init(pk);
+	*pk_initialized = true;
 }
-#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)
+static void cleanup_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
 {
-	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;
+	if (*pk_initialized) {
+		mbedtls_pk_free(pk);
+		*pk_initialized = false;
 	}
-
-	*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
- * update to 3.5.2, where this function is exposed.
- */
-int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
-			     const mbedtls_x509_buf *sig_params,
-			     mbedtls_md_type_t *md_alg,
-			     mbedtls_pk_type_t *pk_alg,
-			     void **sig_opts);
-/*
  * Verify a signature.
  *
  * Parameters are passed using the DER encoding format following the ASN.1
@@ -350,141 +190,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;
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end2;
 	}
 
-	/* Get the actual signature algorithm (MD + PK) */
-	rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts);
+	rc = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_MESSAGE, &psa_key_attr);
 	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end2;
 	}
 
-	/* 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 = 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);
 
-		local_sig_ptr = reformatted_sig;
-
-		rc = get_ecdsa_pkinfo_from_asn1((unsigned char **)&pk_ptr,
-						&pk_len,
-						&psa_ecc_family);
+		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) {
-			goto end2;
+			rc = CRYPTO_ERR_SIGNATURE;
+			goto end1;
 		}
+		local_sig_ptr = reformatted_sig;
 	}
 #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);
-		if (rc != 0) {
-			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;
 }
 
@@ -633,78 +431,61 @@
 			   unsigned int iv_len, const void *tag,
 			   unsigned int tag_len)
 {
-	mbedtls_gcm_context ctx;
-	mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
+	mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+	psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 	unsigned char buf[DEC_OP_BUF_SIZE];
-	unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE];
 	unsigned char *pt = data_ptr;
 	size_t dec_len;
-	int diff, i, rc;
-	size_t output_length __unused;
+	size_t output_length;
 
-	mbedtls_gcm_init(&ctx);
+	/* Load the key into the PSA key store. */
+	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
+	psa_set_key_algorithm(&attributes, PSA_ALG_GCM);
+	psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
 
-	rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8);
-	if (rc != 0) {
-		rc = CRYPTO_ERR_DECRYPTION;
-		goto exit_gcm;
+	psa_status = psa_import_key(&attributes, key, key_len, &key_id);
+	if (psa_status != PSA_SUCCESS) {
+		return CRYPTO_ERR_DECRYPTION;
 	}
 
-#if (MBEDTLS_VERSION_MAJOR < 3)
-	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0);
-#else
-	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len);
-#endif
-	if (rc != 0) {
-		rc = CRYPTO_ERR_DECRYPTION;
-		goto exit_gcm;
+	/* Perform the decryption. */
+	psa_status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_GCM);
+	if (psa_status != PSA_SUCCESS) {
+		goto err;
 	}
 
+	psa_status = psa_aead_set_nonce(&operation, iv, iv_len);
+	if (psa_status != PSA_SUCCESS) {
+		goto err;
+	}
+
 	while (len > 0) {
 		dec_len = MIN(sizeof(buf), len);
 
-#if (MBEDTLS_VERSION_MAJOR < 3)
-		rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf);
-#else
-		rc = mbedtls_gcm_update(&ctx, pt, dec_len, buf, sizeof(buf), &output_length);
-#endif
-
-		if (rc != 0) {
-			rc = CRYPTO_ERR_DECRYPTION;
-			goto exit_gcm;
+		psa_status = psa_aead_update(&operation, pt, dec_len, buf,
+					     sizeof(buf), &output_length);
+		if (psa_status != PSA_SUCCESS) {
+			goto err;
 		}
 
-		memcpy(pt, buf, dec_len);
-		pt += dec_len;
+		memcpy(pt, buf, output_length);
+		pt += output_length;
 		len -= dec_len;
 	}
 
-#if (MBEDTLS_VERSION_MAJOR < 3)
-	rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf));
-#else
-	rc = mbedtls_gcm_finish(&ctx, NULL, 0, &output_length, tag_buf, sizeof(tag_buf));
-#endif
-
-	if (rc != 0) {
-		rc = CRYPTO_ERR_DECRYPTION;
-		goto exit_gcm;
+	/* Verify the tag. */
+	psa_status = psa_aead_verify(&operation, NULL, 0, &output_length, tag, tag_len);
+	if (psa_status == PSA_SUCCESS) {
+		psa_destroy_key(key_id);
+		return CRYPTO_SUCCESS;
 	}
 
-	/* Check tag in "constant-time" */
-	for (diff = 0, i = 0; i < tag_len; i++)
-		diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i];
-
-	if (diff != 0) {
-		rc = CRYPTO_ERR_DECRYPTION;
-		goto exit_gcm;
-	}
-
-	/* GCM decryption success */
-	rc = CRYPTO_SUCCESS;
-
-exit_gcm:
-	mbedtls_gcm_free(&ctx);
-	return rc;
+err:
+	psa_aead_abort(&operation);
+	psa_destroy_key(key_id);
+	return CRYPTO_ERR_DECRYPTION;
 }
 
 /*
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c
index a3fd7bf..bdbbbf6 100644
--- a/drivers/delay_timer/delay_timer.c
+++ b/drivers/delay_timer/delay_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,3 +80,25 @@
 
 	timer_ops = ops_ptr;
 }
+
+/***********************************************************
+ * Initialize the timer in us
+ ***********************************************************/
+uint64_t timeout_init_us(uint32_t usec)
+{
+	assert(timer_ops != NULL);
+	assert(timer_ops->timeout_init_us != NULL);
+
+	return timer_ops->timeout_init_us(usec);
+}
+
+/***********************************************************
+ * check the given timeout elapsed or not.
+ ***********************************************************/
+bool timeout_elapsed(uint64_t cnt)
+{
+	assert(timer_ops != NULL);
+	assert(timer_ops->timeout_elapsed != NULL);
+
+	return timer_ops->timeout_elapsed(cnt);
+}
diff --git a/drivers/delay_timer/generic_delay_timer.c b/drivers/delay_timer/generic_delay_timer.c
index ca522e0..0407e38 100644
--- a/drivers/delay_timer/generic_delay_timer.c
+++ b/drivers/delay_timer/generic_delay_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -18,7 +18,26 @@
 
 static timer_ops_t ops;
 
-static uint32_t get_timer_value(void)
+static uint64_t timeout_cnt_us2cnt(uint32_t us)
+{
+	return ((uint64_t)us * (uint64_t)read_cntfrq_el0()) / 1000000ULL;
+}
+
+static uint64_t generic_delay_timeout_init_us(uint32_t us)
+{
+	uint64_t cnt = timeout_cnt_us2cnt(us);
+
+	cnt += read_cntpct_el0();
+
+	return cnt;
+}
+
+static bool generic_delay_timeout_elapsed(uint64_t expire_cnt)
+{
+	return read_cntpct_el0() > expire_cnt;
+}
+
+static uint32_t generic_delay_get_timer_value(void)
 {
 	/*
 	 * Generic delay timer implementation expects the timer to be a down
@@ -31,9 +50,11 @@
 
 void generic_delay_timer_init_args(uint32_t mult, uint32_t div)
 {
-	ops.get_timer_value	= get_timer_value;
+	ops.get_timer_value	= generic_delay_get_timer_value;
 	ops.clk_mult		= mult;
 	ops.clk_div		= div;
+	ops.timeout_init_us	= generic_delay_timeout_init_us;
+	ops.timeout_elapsed	= generic_delay_timeout_elapsed;
 
 	timer_init(&ops);
 
@@ -59,4 +80,3 @@
 
 	generic_delay_timer_init_args(mult, div);
 }
-
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
new file mode 100644
index 0000000..e54d581
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
@@ -0,0 +1,115 @@
+// 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)
+#define ARMPLL_BASE_ADDR		(0x40038000UL)
+#define PERIPHPLL_BASE_ADDR		(0x4003C000UL)
+#define ARM_DFS_BASE_ADDR		(0x40054000UL)
+#define CGM0_BASE_ADDR			(0x40030000UL)
+#define CGM1_BASE_ADDR			(0x40034000UL)
+#define DDRPLL_BASE_ADDR		(0x40044000UL)
+#define MC_ME_BASE_ADDR			(0x40088000UL)
+#define MC_RGM_BASE_ADDR		(0x40078000UL)
+#define RDC_BASE_ADDR			(0x40080000UL)
+#define MC_CGM5_BASE_ADDR		(0x40068000UL)
+
+/* 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)
+
+/* PLL */
+#define PLLDIG_PLLCR(PLL)		((PLL) + 0x0UL)
+#define PLLDIG_PLLCR_PLLPD		BIT_32(31U)
+
+#define PLLDIG_PLLSR(PLL)		((PLL) + 0x4UL)
+#define PLLDIG_PLLSR_LOCK		BIT_32(2U)
+
+#define PLLDIG_PLLDV(PLL)		((PLL) + 0x8UL)
+#define PLLDIG_PLLDV_RDIV_OFFSET	12U
+#define PLLDIG_PLLDV_RDIV_MASK		GENMASK_32(14U, PLLDIG_PLLDV_RDIV_OFFSET)
+#define PLLDIG_PLLDV_RDIV_SET(VAL)	(PLLDIG_PLLDV_RDIV_MASK & \
+					((VAL) << PLLDIG_PLLDV_RDIV_OFFSET))
+#define PLLDIG_PLLDV_MFI_MASK		GENMASK_32(7U, 0U)
+#define PLLDIG_PLLDV_MFI(DIV)		(PLLDIG_PLLDV_MFI_MASK & (DIV))
+
+#define PLLDIG_PLLFD(PLL)		((PLL) + 0x10UL)
+#define PLLDIG_PLLFD_SMDEN		BIT_32(30U)
+#define PLLDIG_PLLFD_MFN_MASK		GENMASK_32(14U, 0U)
+#define PLLDIG_PLLFD_MFN_SET(VAL)	(PLLDIG_PLLFD_MFN_MASK & (VAL))
+
+#define PLLDIG_PLLCLKMUX(PLL)		((PLL) + 0x20UL)
+
+#define PLLDIG_PLLODIV(PLL, N)		((PLL) + 0x80UL + ((N) * 0x4UL))
+#define PLLDIG_PLLODIV_DE		BIT_32(31U)
+#define PLLDIG_PLLODIV_DIV_OFFSET	16U
+#define PLLDIG_PLLODIV_DIV_MASK		GENMASK_32(23U, PLLDIG_PLLODIV_DIV_OFFSET)
+#define PLLDIG_PLLODIV_DIV(VAL)		(((VAL) & PLLDIG_PLLODIV_DIV_MASK) >> \
+					 PLLDIG_PLLODIV_DIV_OFFSET)
+#define PLLDIG_PLLODIV_DIV_SET(VAL)	(PLLDIG_PLLODIV_DIV_MASK & ((VAL) << \
+					 PLLDIG_PLLODIV_DIV_OFFSET))
+
+/* MMC_CGM */
+#define CGM_MUXn_CSC(CGM_ADDR, MUX)	((CGM_ADDR) + 0x300UL + ((MUX) * 0x40UL))
+#define MC_CGM_MUXn_CSC_SELCTL_OFFSET	24U
+#define MC_CGM_MUXn_CSC_SELCTL_MASK	GENMASK_32(29U, MC_CGM_MUXn_CSC_SELCTL_OFFSET)
+#define MC_CGM_MUXn_CSC_SELCTL(val)	(MC_CGM_MUXn_CSC_SELCTL_MASK & ((val) \
+					 << MC_CGM_MUXn_CSC_SELCTL_OFFSET))
+#define MC_CGM_MUXn_CSC_CLK_SW		BIT_32(2U)
+#define MC_CGM_MUXn_CSC_SAFE_SW		BIT_32(3U)
+
+#define CGM_MUXn_CSS(CGM_ADDR, MUX)	((CGM_ADDR) + 0x304UL + ((MUX) * 0x40UL))
+#define MC_CGM_MUXn_CSS_SELSTAT_OFFSET	24U
+#define MC_CGM_MUXn_CSS_SELSTAT_MASK	GENMASK_32(29U, MC_CGM_MUXn_CSS_SELSTAT_OFFSET)
+#define MC_CGM_MUXn_CSS_SELSTAT(css)	((MC_CGM_MUXn_CSS_SELSTAT_MASK & (css))\
+					 >> MC_CGM_MUXn_CSS_SELSTAT_OFFSET)
+#define MC_CGM_MUXn_CSS_SWTRG(css)	((MC_CGM_MUXn_CSS_SWTRG_MASK & (css)) \
+					 >> MC_CGM_MUXn_CSS_SWTRG_OFFSET)
+#define MC_CGM_MUXn_CSS_SWTRG_OFFSET	17U
+#define MC_CGM_MUXn_CSS_SWTRG_MASK	GENMASK_32(19U, MC_CGM_MUXn_CSS_SWTRG_OFFSET)
+#define MC_CGM_MUXn_CSS_SWTRG_SUCCESS	0x1U
+#define MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK	0x4U
+#define MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK_INACTIVE	0x5U
+#define MC_CGM_MUXn_CSS_SWIP		BIT_32(16U)
+#define MC_CGM_MUXn_CSS_SAFE_SW		BIT_32(3U)
+
+/* DFS */
+#define DFS_PORTSR(DFS_ADDR)		((DFS_ADDR) + 0xCUL)
+#define DFS_PORTOLSR(DFS_ADDR)		((DFS_ADDR) + 0x10UL)
+#define DFS_PORTOLSR_LOL(N)		(BIT_32(N) & GENMASK_32(5U, 0U))
+#define DFS_PORTRESET(DFS_ADDR)		((DFS_ADDR) + 0x14UL)
+#define DFS_PORTRESET_MASK		GENMASK_32(5U, 0U)
+#define DFS_PORTRESET_SET(VAL)		(((VAL) & DFS_PORTRESET_MASK))
+
+#define DFS_CTL(DFS_ADDR)		((DFS_ADDR) + 0x18UL)
+#define DFS_CTL_RESET			BIT_32(1U)
+
+#define DFS_DVPORTn(DFS_ADDR, PORT)	((DFS_ADDR) + 0x1CUL + ((PORT) * 0x4UL))
+#define DFS_DVPORTn_MFI_MASK		GENMASK_32(15U, 8U)
+#define DFS_DVPORTn_MFI_SHIFT		8U
+#define DFS_DVPORTn_MFN_MASK		GENMASK_32(7U, 0U)
+#define DFS_DVPORTn_MFN_SHIFT		0U
+#define DFS_DVPORTn_MFI(MFI)		(((MFI) & DFS_DVPORTn_MFI_MASK) >> DFS_DVPORTn_MFI_SHIFT)
+#define DFS_DVPORTn_MFN(MFN)		(((MFN) & DFS_DVPORTn_MFN_MASK) >> DFS_DVPORTn_MFN_SHIFT)
+#define DFS_DVPORTn_MFI_SET(VAL)	(((VAL) << DFS_DVPORTn_MFI_SHIFT) & DFS_DVPORTn_MFI_MASK)
+#define DFS_DVPORTn_MFN_SET(VAL)	(((VAL) << DFS_DVPORTn_MFN_SHIFT) & DFS_DVPORTn_MFN_MASK)
+
+#endif /* S32CC_CLK_REGS_H */
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-mc-me.h b/drivers/nxp/clk/s32cc/include/s32cc-mc-me.h
new file mode 100644
index 0000000..8249fc5
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/include/s32cc-mc-me.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2020-2021, 2023-2024 NXP
+ */
+#ifndef S32CC_MC_ME_H
+#define S32CC_MC_ME_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+int mc_me_enable_partition(uintptr_t mc_me, uintptr_t mc_rgm, uintptr_t rdc,
+			   uint32_t part);
+void mc_me_enable_part_cofb(uintptr_t mc_me, uint32_t partition_n, uint32_t block,
+			    bool check_status);
+
+#endif /* S32CC_MC_ME_H */
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h b/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
new file mode 100644
index 0000000..d6234da
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2020-2021, 2023-2024 NXP
+ */
+#ifndef S32CC_MC_RGM_H
+#define S32CC_MC_RGM_H
+
+#include <stdint.h>
+
+void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value);
+void mc_rgm_release_part(uintptr_t rgm, uint32_t part);
+void mc_rgm_wait_part_deassert(uintptr_t rgm, uint32_t part);
+
+#endif /* MC_RGM_H */
diff --git a/drivers/nxp/clk/s32cc/mc_me.c b/drivers/nxp/clk/s32cc/mc_me.c
new file mode 100644
index 0000000..04d0425
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/mc_me.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <s32cc-mc-me.h>
+#include <s32cc-mc-rgm.h>
+
+#define MC_ME_MAX_PARTITIONS		(4U)
+
+#define MC_ME_CTL_KEY(MC_ME)		((MC_ME) + 0x0UL)
+#define MC_ME_CTL_KEY_KEY		(0x5AF0U)
+#define MC_ME_CTL_KEY_INVERTEDKEY	(0xA50FU)
+
+#define MC_ME_PRTN_N(MC_ME, PART)	((MC_ME) + 0x100UL + ((PART) * 0x200UL))
+#define MC_ME_PRTN_N_PCONF(MC_ME, PART)	(MC_ME_PRTN_N(MC_ME, PART))
+#define MC_ME_PRTN_N_PCE		BIT_32(0)
+#define MC_ME_PRTN_N_OSSE		BIT_32(2)
+#define MC_ME_PRTN_N_PUPD(MC_ME, PART)	(MC_ME_PRTN_N(MC_ME, PART) + 0x4UL)
+#define MC_ME_PRTN_N_PCUD		BIT_32(0)
+#define MC_ME_PRTN_N_OSSUD		BIT_32(2)
+#define MC_ME_PRTN_N_STAT(MC_ME, PART)	(MC_ME_PRTN_N(MC_ME, PART) + 0x8UL)
+#define MC_ME_PRTN_N_PCS		BIT_32(0)
+#define MC_ME_PRTN_N_COFB0_STAT(MC_ME, PART) \
+					(MC_ME_PRTN_N(MC_ME, PART) + 0x10UL)
+#define MC_ME_PRTN_N_COFB0_CLKEN(MC_ME, PART) \
+					(MC_ME_PRTN_N(MC_ME, PART) + 0x30UL)
+#define MC_ME_PRTN_N_REQ(PART)		BIT_32(PART)
+
+#define RDC_RD_CTRL(RDC, PART)		((RDC) + ((PART) * 0x4UL))
+#define RDC_CTRL_UNLOCK			BIT_32(31)
+#define RDC_RD_INTERCONNECT_DISABLE	BIT_32(3)
+
+#define RDC_RD_N_STATUS(RDC, PART)	((RDC) + ((PART) * 0x4UL) + 0x80UL)
+#define RDC_RD_INTERCONNECT_DISABLE_STAT \
+					BIT_32(4)
+
+static bool is_interconnect_disabled(uintptr_t rdc, uint32_t part)
+{
+	return ((mmio_read_32(RDC_RD_N_STATUS(rdc, part)) &
+		  RDC_RD_INTERCONNECT_DISABLE_STAT) != 0U);
+}
+
+static void enable_interconnect(uintptr_t rdc, uint32_t part)
+{
+	/* Unlock RDC register write */
+	mmio_setbits_32(RDC_RD_CTRL(rdc, part), RDC_CTRL_UNLOCK);
+
+	/* Clear corresponding RDC_RD_INTERCONNECT bit */
+	mmio_clrbits_32(RDC_RD_CTRL(rdc, part), RDC_RD_INTERCONNECT_DISABLE);
+
+	/* Wait until the interface gets enabled */
+	while (is_interconnect_disabled(rdc, part)) {
+	}
+
+	/* Lock RDC register write */
+	mmio_clrbits_32(RDC_RD_CTRL(rdc, part), RDC_CTRL_UNLOCK);
+}
+
+static int mc_me_check_partition_nb_valid(uint32_t part)
+{
+	if (part >= MC_ME_MAX_PARTITIONS) {
+		ERROR("Invalid partition %" PRIu32 "\n", part);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void part_pconf_write_pce(uintptr_t mc_me, uint32_t pce_bit,
+				 uint32_t part)
+{
+	mmio_clrsetbits_32(MC_ME_PRTN_N_PCONF(mc_me, part), MC_ME_PRTN_N_PCE,
+			   pce_bit & MC_ME_PRTN_N_PCE);
+}
+
+static void mc_me_apply_hw_changes(uintptr_t mc_me)
+{
+	mmio_write_32(MC_ME_CTL_KEY(mc_me), MC_ME_CTL_KEY_KEY);
+	mmio_write_32(MC_ME_CTL_KEY(mc_me), MC_ME_CTL_KEY_INVERTEDKEY);
+}
+
+static void part_pupd_update_and_wait(uintptr_t mc_me, uint32_t part,
+				      uint32_t mask)
+{
+	uint32_t pconf, stat;
+
+	mmio_setbits_32(MC_ME_PRTN_N_PUPD(mc_me, part), mask);
+
+	mc_me_apply_hw_changes(mc_me);
+
+	/* wait for the updates to apply */
+	pconf = mmio_read_32(MC_ME_PRTN_N_PCONF(mc_me, part));
+	do {
+		stat = mmio_read_32(MC_ME_PRTN_N_STAT(mc_me, part));
+	} while ((stat & mask) != (pconf & mask));
+}
+
+static void part_pconf_write_osse(uintptr_t mc_me, uint32_t osse_bit,
+				  uint32_t part)
+{
+	mmio_clrsetbits_32(MC_ME_PRTN_N_PCONF(mc_me, part), MC_ME_PRTN_N_OSSE,
+			   (osse_bit & MC_ME_PRTN_N_OSSE));
+}
+
+int mc_me_enable_partition(uintptr_t mc_me, uintptr_t mc_rgm, uintptr_t rdc,
+			   uint32_t part)
+{
+	uint32_t part_stat;
+	int ret;
+
+	/* Partition 0 is already enabled by BootROM */
+	if (part == 0U) {
+		return 0;
+	}
+
+	ret = mc_me_check_partition_nb_valid(part);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Enable a partition only if it's disabled */
+	part_stat = mmio_read_32(MC_ME_PRTN_N_STAT(mc_me, part));
+	if ((MC_ME_PRTN_N_PCS & part_stat) != 0U) {
+		return 0;
+	}
+
+	part_pconf_write_pce(mc_me, MC_ME_PRTN_N_PCE, part);
+	part_pupd_update_and_wait(mc_me, part, MC_ME_PRTN_N_PCUD);
+
+	enable_interconnect(rdc, part);
+
+	/* Release partition reset */
+	mc_rgm_release_part(mc_rgm, part);
+
+	/* Clear OSSE bit */
+	part_pconf_write_osse(mc_me, 0, part);
+
+	part_pupd_update_and_wait(mc_me, part, MC_ME_PRTN_N_OSSUD);
+
+	mc_rgm_wait_part_deassert(mc_rgm, part);
+
+	return 0;
+}
+
+void mc_me_enable_part_cofb(uintptr_t mc_me, uint32_t partition_n, uint32_t block,
+			    bool check_status)
+{
+	uint32_t block_mask = MC_ME_PRTN_N_REQ(block);
+	uintptr_t cofb_stat_addr;
+
+	mmio_setbits_32(MC_ME_PRTN_N_COFB0_CLKEN(mc_me, partition_n),
+			block_mask);
+
+	mmio_setbits_32(MC_ME_PRTN_N_PCONF(mc_me, partition_n),
+			MC_ME_PRTN_N_PCE);
+
+	part_pupd_update_and_wait(mc_me, partition_n, MC_ME_PRTN_N_PCUD);
+
+	cofb_stat_addr = MC_ME_PRTN_N_COFB0_STAT(mc_me, partition_n);
+	if (check_status) {
+		while ((mmio_read_32(cofb_stat_addr) & block_mask) == 0U) {
+		}
+	}
+}
diff --git a/drivers/nxp/clk/s32cc/mc_rgm.c b/drivers/nxp/clk/s32cc/mc_rgm.c
new file mode 100644
index 0000000..c66b013
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/mc_rgm.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2023-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <s32cc-mc-rgm.h>
+
+#define MC_RGM_PRST(RGM, PER)		((RGM) + 0x40UL + ((PER) * 0x8UL))
+#define MC_RGM_PRST_PERIPH_N_RST(PER)	BIT_32(PER)
+#define MC_RGM_PSTAT(RGM, PER)		((RGM) + 0x140UL + ((PER) * 0x8UL))
+#define MC_RGM_PSTAT_PERIPH(PER)	BIT_32(PER)
+
+/*  ERR051700
+ *  Releasing more than one Software Resettable Domain (SRD)
+ *  from reset simultaneously, by clearing the corresponding
+ *  peripheral MC_RGM_PRSTn[PERIPH_x_RST] reset control may
+ *  cause a false setting of the Fault Collection and
+ *  Control Unit (FCCU) Non-Critical Fault (NCF) flag
+ *  corresponding to a Memory-Test-Repair (MTR) Error
+ */
+#if (ERRATA_S32_051700 == 1)
+void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
+{
+	uint32_t current_bit_checked, i;
+	uint32_t current_regs, mask;
+	int bit_index;
+
+	current_regs = mmio_read_32(MC_RGM_PRST(rgm, part));
+	/* Create a mask with all changed bits */
+	mask = current_regs ^ value;
+
+	while (mask != 0U) {
+		bit_index = __builtin_ffs(mask);
+		if (bit_index < 1) {
+			break;
+		}
+
+		i = (uint32_t)bit_index - 1U;
+		current_bit_checked = BIT_32(i);
+
+		/* Check if we assert or de-assert.
+		 * Also wait for completion.
+		 */
+		if ((value & current_bit_checked) != 0U) {
+			mmio_setbits_32(MC_RGM_PRST(rgm, part),
+					current_bit_checked);
+			while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
+				 current_bit_checked) == 0U)
+				;
+		} else {
+			mmio_clrbits_32(MC_RGM_PRST(rgm, part),
+					current_bit_checked);
+			while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
+					    current_bit_checked) != 0U)
+				;
+		}
+
+		mask &= ~current_bit_checked;
+	}
+}
+#else /* ERRATA_S32_051700 */
+void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
+{
+	mmio_write_32(MC_RGM_PRST(rgm, part), value);
+}
+#endif /* ERRATA_S32_051700 */
+
+void mc_rgm_release_part(uintptr_t rgm, uint32_t part)
+{
+	uint32_t reg;
+
+	reg = mmio_read_32(MC_RGM_PRST(rgm, part));
+	reg &= ~MC_RGM_PRST_PERIPH_N_RST(0);
+	mc_rgm_periph_reset(rgm, part, reg);
+}
+
+void mc_rgm_wait_part_deassert(uintptr_t rgm, uint32_t part)
+{
+	while ((mmio_read_32(MC_RGM_PSTAT(rgm, part)) &
+		MC_RGM_PSTAT_PERIPH(0)) != 0U) {
+	}
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk.mk b/drivers/nxp/clk/s32cc/s32cc_clk.mk
index f5279d3..602179e 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk.mk
+++ b/drivers/nxp/clk/s32cc/s32cc_clk.mk
@@ -6,8 +6,11 @@
 
 PLAT_INCLUDES		+= \
 	-I${PLAT_DRIVERS_INCLUDE_PATH}/clk/s32cc \
+	-I${PLAT_DRIVERS_PATH}/clk/s32cc/include \
 
 CLK_SOURCES		:= \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/mc_rgm.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/mc_me.c \
 	${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 \
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
index e6653bd..9b57607 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -4,27 +4,1049 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <errno.h>
+#include <common/debug.h>
+#include <drivers/clk.h>
+#include <lib/mmio.h>
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-modules.h>
+#include <s32cc-clk-regs.h>
+#include <s32cc-clk-utils.h>
+#include <s32cc-mc-me.h>
+
+#define MAX_STACK_DEPTH		(40U)
+
+/* This is used for floating-point precision calculations. */
+#define FP_PRECISION		(100000000UL)
+
+struct s32cc_clk_drv {
+	uintptr_t fxosc_base;
+	uintptr_t armpll_base;
+	uintptr_t periphpll_base;
+	uintptr_t armdfs_base;
+	uintptr_t cgm0_base;
+	uintptr_t cgm1_base;
+	uintptr_t cgm5_base;
+	uintptr_t ddrpll_base;
+	uintptr_t mc_me;
+	uintptr_t mc_rgm;
+	uintptr_t rdc;
+};
+
+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,
+		.armpll_base = ARMPLL_BASE_ADDR,
+		.periphpll_base = PERIPHPLL_BASE_ADDR,
+		.armdfs_base = ARM_DFS_BASE_ADDR,
+		.cgm0_base = CGM0_BASE_ADDR,
+		.cgm1_base = CGM1_BASE_ADDR,
+		.cgm5_base = MC_CGM5_BASE_ADDR,
+		.ddrpll_base = DDRPLL_BASE_ADDR,
+		.mc_me = MC_ME_BASE_ADDR,
+		.mc_rgm = MC_RGM_BASE_ADDR,
+		.rdc = RDC_BASE_ADDR,
+	};
+
+	return &driver;
+}
+
+static int enable_module(struct s32cc_clk_obj *module,
+			 const struct s32cc_clk_drv *drv,
+			 unsigned int depth);
+
+static struct s32cc_clk_obj *get_clk_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_clk *clk = s32cc_obj2clk(module);
+
+	if (clk->module != NULL) {
+		return clk->module;
+	}
+
+	if (clk->pclock != NULL) {
+		return &clk->pclock->desc;
+	}
+
+	return NULL;
+}
+
+static int get_base_addr(enum s32cc_clk_source id, const struct s32cc_clk_drv *drv,
+			 uintptr_t *base)
+{
+	int ret = 0;
+
+	switch (id) {
+	case S32CC_FXOSC:
+		*base = drv->fxosc_base;
+		break;
+	case S32CC_ARM_PLL:
+		*base = drv->armpll_base;
+		break;
+	case S32CC_PERIPH_PLL:
+		*base = drv->periphpll_base;
+		break;
+	case S32CC_DDR_PLL:
+		*base = drv->ddrpll_base;
+		break;
+	case S32CC_ARM_DFS:
+		*base = drv->armdfs_base;
+		break;
+	case S32CC_CGM0:
+		*base = drv->cgm0_base;
+		break;
+	case S32CC_CGM1:
+		*base = drv->cgm1_base;
+		break;
+	case S32CC_CGM5:
+		*base = drv->cgm5_base;
+		break;
+	case S32CC_FIRC:
+		break;
+	case S32CC_SIRC:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ret != 0) {
+		ERROR("Unknown clock source id: %u\n", id);
+	}
+
+	return ret;
+}
+
+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(struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int depth)
+{
+	const struct s32cc_osc *osc = s32cc_obj2osc(module);
+	unsigned int ldepth = depth;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	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 struct s32cc_clk_obj *get_pll_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_pll *pll = s32cc_obj2pll(module);
+
+	if (pll->source == NULL) {
+		ERROR("Failed to identify PLL's parent\n");
+	}
+
+	return pll->source;
+}
+
+static int get_pll_mfi_mfn(unsigned long pll_vco, unsigned long ref_freq,
+			   uint32_t *mfi, uint32_t *mfn)
+
+{
+	unsigned long vco;
+	unsigned long mfn64;
+
+	/* FRAC-N mode */
+	*mfi = (uint32_t)(pll_vco / ref_freq);
+
+	/* MFN formula : (double)(pll_vco % ref_freq) / ref_freq * 18432.0 */
+	mfn64 = pll_vco % ref_freq;
+	mfn64 *= FP_PRECISION;
+	mfn64 /= ref_freq;
+	mfn64 *= 18432UL;
+	mfn64 /= FP_PRECISION;
+
+	if (mfn64 > UINT32_MAX) {
+		return -EINVAL;
+	}
+
+	*mfn = (uint32_t)mfn64;
+
+	vco = ((unsigned long)*mfn * FP_PRECISION) / 18432UL;
+	vco += (unsigned long)*mfi * FP_PRECISION;
+	vco *= ref_freq;
+	vco /= FP_PRECISION;
+
+	if (vco != pll_vco) {
+		ERROR("Failed to find MFI and MFN settings for PLL freq %lu. Nearest freq = %lu\n",
+		      pll_vco, vco);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct s32cc_clkmux *get_pll_mux(const struct s32cc_pll *pll)
+{
+	const struct s32cc_clk_obj *source = pll->source;
+	const struct s32cc_clk *clk;
+
+	if (source == NULL) {
+		ERROR("Failed to identify PLL's parent\n");
+		return NULL;
+	}
+
+	if (source->type != s32cc_clk_t) {
+		ERROR("The parent of the PLL isn't a clock\n");
+		return NULL;
+	}
+
+	clk = s32cc_obj2clk(source);
+
+	if (clk->module == NULL) {
+		ERROR("The clock isn't connected to a module\n");
+		return NULL;
+	}
+
+	source = clk->module;
+
+	if ((source->type != s32cc_clkmux_t) &&
+	    (source->type != s32cc_shared_clkmux_t)) {
+		ERROR("The parent of the PLL isn't a MUX\n");
+		return NULL;
+	}
+
+	return s32cc_obj2clkmux(source);
+}
+
+static void disable_odiv(uintptr_t pll_addr, uint32_t div_index)
+{
+	mmio_clrbits_32(PLLDIG_PLLODIV(pll_addr, div_index), PLLDIG_PLLODIV_DE);
+}
+
+static void enable_odiv(uintptr_t pll_addr, uint32_t div_index)
+{
+	mmio_setbits_32(PLLDIG_PLLODIV(pll_addr, div_index), PLLDIG_PLLODIV_DE);
+}
+
+static void disable_odivs(uintptr_t pll_addr, uint32_t ndivs)
+{
+	uint32_t i;
+
+	for (i = 0; i < ndivs; i++) {
+		disable_odiv(pll_addr, i);
+	}
+}
+
+static void enable_pll_hw(uintptr_t pll_addr)
+{
+	/* Enable the PLL. */
+	mmio_write_32(PLLDIG_PLLCR(pll_addr), 0x0);
+
+	/* Poll until PLL acquires lock. */
+	while ((mmio_read_32(PLLDIG_PLLSR(pll_addr)) & PLLDIG_PLLSR_LOCK) == 0U) {
+	}
+}
+
+static void disable_pll_hw(uintptr_t pll_addr)
+{
+	mmio_write_32(PLLDIG_PLLCR(pll_addr), PLLDIG_PLLCR_PLLPD);
+}
+
+static int program_pll(const struct s32cc_pll *pll, uintptr_t pll_addr,
+		       const struct s32cc_clk_drv *drv, uint32_t sclk_id,
+		       unsigned long sclk_freq)
+{
+	uint32_t rdiv = 1, mfi, mfn;
+	int ret;
+
+	ret = get_pll_mfi_mfn(pll->vco_freq, sclk_freq, &mfi, &mfn);
+	if (ret != 0) {
+		return -EINVAL;
+	}
+
+	/* Disable ODIVs*/
+	disable_odivs(pll_addr, pll->ndividers);
+
+	/* Disable PLL */
+	disable_pll_hw(pll_addr);
+
+	/* Program PLLCLKMUX */
+	mmio_write_32(PLLDIG_PLLCLKMUX(pll_addr), sclk_id);
+
+	/* Program VCO */
+	mmio_clrsetbits_32(PLLDIG_PLLDV(pll_addr),
+			   PLLDIG_PLLDV_RDIV_MASK | PLLDIG_PLLDV_MFI_MASK,
+			   PLLDIG_PLLDV_RDIV_SET(rdiv) | PLLDIG_PLLDV_MFI(mfi));
+
+	mmio_write_32(PLLDIG_PLLFD(pll_addr),
+		      PLLDIG_PLLFD_MFN_SET(mfn) | PLLDIG_PLLFD_SMDEN);
+
+	enable_pll_hw(pll_addr);
+
+	return ret;
+}
+
+static int enable_pll(struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int depth)
+{
+	const struct s32cc_pll *pll = s32cc_obj2pll(module);
+	const struct s32cc_clkmux *mux;
+	uintptr_t pll_addr = UL(0x0);
+	unsigned int ldepth = depth;
+	unsigned long sclk_freq;
+	uint32_t sclk_id;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	mux = get_pll_mux(pll);
+	if (mux == NULL) {
+		return -EINVAL;
+	}
+
+	if (pll->instance != mux->module) {
+		ERROR("MUX type is not in sync with PLL ID\n");
+		return -EINVAL;
+	}
+
+	ret = get_base_addr(pll->instance, drv, &pll_addr);
+	if (ret != 0) {
+		ERROR("Failed to detect PLL instance\n");
+		return ret;
+	}
+
+	switch (mux->source_id) {
+	case S32CC_CLK_FIRC:
+		sclk_freq = 48U * MHZ;
+		sclk_id = 0;
+		break;
+	case S32CC_CLK_FXOSC:
+		sclk_freq = 40U * MHZ;
+		sclk_id = 1;
+		break;
+	default:
+		ERROR("Invalid source selection for PLL 0x%lx\n",
+		      pll_addr);
+		return -EINVAL;
+	};
+
+	return program_pll(pll, pll_addr, drv, sclk_id, sclk_freq);
+}
+
+static inline struct s32cc_pll *get_div_pll(const struct s32cc_pll_out_div *pdiv)
+{
+	const struct s32cc_clk_obj *parent;
+
+	parent = pdiv->parent;
+	if (parent == NULL) {
+		ERROR("Failed to identify PLL divider's parent\n");
+		return NULL;
+	}
+
+	if (parent->type != s32cc_pll_t) {
+		ERROR("The parent of the divider is not a PLL instance\n");
+		return NULL;
+	}
+
+	return s32cc_obj2pll(parent);
+}
+
+static void config_pll_out_div(uintptr_t pll_addr, uint32_t div_index, uint32_t dc)
+{
+	uint32_t pllodiv;
+	uint32_t pdiv;
+
+	pllodiv = mmio_read_32(PLLDIG_PLLODIV(pll_addr, div_index));
+	pdiv = PLLDIG_PLLODIV_DIV(pllodiv);
+
+	if (((pdiv + 1U) == dc) && ((pllodiv & PLLDIG_PLLODIV_DE) != 0U)) {
+		return;
+	}
+
+	if ((pllodiv & PLLDIG_PLLODIV_DE) != 0U) {
+		disable_odiv(pll_addr, div_index);
+	}
+
+	pllodiv = PLLDIG_PLLODIV_DIV_SET(dc - 1U);
+	mmio_write_32(PLLDIG_PLLODIV(pll_addr, div_index), pllodiv);
+
+	enable_odiv(pll_addr, div_index);
+}
+
+static struct s32cc_clk_obj *get_pll_div_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module);
+
+	if (pdiv->parent == NULL) {
+		ERROR("Failed to identify PLL DIV's parent\n");
+	}
+
+	return pdiv->parent;
+}
+
+static int enable_pll_div(struct s32cc_clk_obj *module,
+			  const struct s32cc_clk_drv *drv,
+			  unsigned int depth)
+{
+	const struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module);
+	uintptr_t pll_addr = 0x0ULL;
+	unsigned int ldepth = depth;
+	const struct s32cc_pll *pll;
+	uint32_t dc;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	pll = get_div_pll(pdiv);
+	if (pll == NULL) {
+		ERROR("The parent of the PLL DIV is invalid\n");
+		return 0;
+	}
+
+	ret = get_base_addr(pll->instance, drv, &pll_addr);
+	if (ret != 0) {
+		ERROR("Failed to detect PLL instance\n");
+		return -EINVAL;
+	}
+
+	dc = (uint32_t)(pll->vco_freq / pdiv->freq);
+
+	config_pll_out_div(pll_addr, pdiv->index, dc);
+
+	return 0;
+}
+
+static int cgm_mux_clk_config(uintptr_t cgm_addr, uint32_t mux, uint32_t source,
+			      bool safe_clk)
+{
+	uint32_t css, csc;
+
+	css = mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux));
+
+	/* Already configured */
+	if ((MC_CGM_MUXn_CSS_SELSTAT(css) == source) &&
+	    (MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SUCCESS) &&
+	    ((css & MC_CGM_MUXn_CSS_SWIP) == 0U) && !safe_clk) {
+		return 0;
+	}
+
+	/* Ongoing clock switch? */
+	while ((mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux)) &
+		MC_CGM_MUXn_CSS_SWIP) != 0U) {
+	}
+
+	csc = mmio_read_32(CGM_MUXn_CSC(cgm_addr, mux));
+
+	/* Clear previous source. */
+	csc &= ~(MC_CGM_MUXn_CSC_SELCTL_MASK);
+
+	if (!safe_clk) {
+		/* Select the clock source and trigger the clock switch. */
+		csc |= MC_CGM_MUXn_CSC_SELCTL(source) | MC_CGM_MUXn_CSC_CLK_SW;
+	} else {
+		/* Switch to safe clock */
+		csc |= MC_CGM_MUXn_CSC_SAFE_SW;
+	}
+
+	mmio_write_32(CGM_MUXn_CSC(cgm_addr, mux), csc);
+
+	/* Wait for configuration bit to auto-clear. */
+	while ((mmio_read_32(CGM_MUXn_CSC(cgm_addr, mux)) &
+		MC_CGM_MUXn_CSC_CLK_SW) != 0U) {
+	}
+
+	/* Is the clock switch completed? */
+	while ((mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux)) &
+		MC_CGM_MUXn_CSS_SWIP) != 0U) {
+	}
+
+	/*
+	 * Check if the switch succeeded.
+	 * Check switch trigger cause and the source.
+	 */
+	css = mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux));
+	if (!safe_clk) {
+		if ((MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SUCCESS) &&
+		    (MC_CGM_MUXn_CSS_SELSTAT(css) == source)) {
+			return 0;
+		}
+
+		ERROR("Failed to change the source of mux %" PRIu32 " to %" PRIu32 " (CGM=%lu)\n",
+		      mux, source, cgm_addr);
+	} else {
+		if (((MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK) ||
+		     (MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK_INACTIVE)) &&
+		     ((MC_CGM_MUXn_CSS_SAFE_SW & css) != 0U)) {
+			return 0;
+		}
+
+		ERROR("The switch of mux %" PRIu32 " (CGM=%lu) to safe clock failed\n",
+		      mux, cgm_addr);
+	}
+
+	return -EINVAL;
+}
+
+static int enable_cgm_mux(const struct s32cc_clkmux *mux,
+			  const struct s32cc_clk_drv *drv)
+{
+	uintptr_t cgm_addr = UL(0x0);
+	uint32_t mux_hw_clk;
+	int ret;
+
+	ret = get_base_addr(mux->module, drv, &cgm_addr);
+	if (ret != 0) {
+		return ret;
+	}
+
+	mux_hw_clk = (uint32_t)S32CC_CLK_ID(mux->source_id);
+
+	return cgm_mux_clk_config(cgm_addr, mux->index,
+				  mux_hw_clk, false);
+}
+
+static struct s32cc_clk_obj *get_mux_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_clkmux *mux = s32cc_obj2clkmux(module);
+	struct s32cc_clk *clk;
+
+	if (mux == NULL) {
+		return NULL;
+	}
+
+	clk = s32cc_get_arch_clk(mux->source_id);
+	if (clk == NULL) {
+		ERROR("Invalid parent (%lu) for mux %" PRIu8 "\n",
+		      mux->source_id, mux->index);
+		return NULL;
+	}
+
+	return &clk->desc;
+}
+
+static int enable_mux(struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int depth)
+{
+	const struct s32cc_clkmux *mux = s32cc_obj2clkmux(module);
+	unsigned int ldepth = depth;
+	const struct s32cc_clk *clk;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (mux == NULL) {
+		return -EINVAL;
+	}
+
+	clk = s32cc_get_arch_clk(mux->source_id);
+	if (clk == NULL) {
+		ERROR("Invalid parent (%lu) for mux %" PRIu8 "\n",
+		      mux->source_id, mux->index);
+		return -EINVAL;
+	}
+
+	switch (mux->module) {
+	/* PLL mux will be enabled by PLL setup */
+	case S32CC_ARM_PLL:
+	case S32CC_PERIPH_PLL:
+	case S32CC_DDR_PLL:
+		break;
+	case S32CC_CGM1:
+		ret = enable_cgm_mux(mux, drv);
+		break;
+	case S32CC_CGM0:
+		ret = enable_cgm_mux(mux, drv);
+		break;
+	case S32CC_CGM5:
+		ret = enable_cgm_mux(mux, drv);
+		break;
+	default:
+		ERROR("Unknown mux parent type: %d\n", mux->module);
+		ret = -EINVAL;
+		break;
+	};
+
+	return ret;
+}
+
+static struct s32cc_clk_obj *get_dfs_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_dfs *dfs = s32cc_obj2dfs(module);
+
+	if (dfs->parent == NULL) {
+		ERROR("Failed to identify DFS's parent\n");
+	}
+
+	return dfs->parent;
+}
+
+static int enable_dfs(struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int depth)
+{
+	unsigned int ldepth = depth;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct s32cc_dfs *get_div_dfs(const struct s32cc_dfs_div *dfs_div)
+{
+	const struct s32cc_clk_obj *parent = dfs_div->parent;
+
+	if (parent->type != s32cc_dfs_t) {
+		ERROR("DFS DIV doesn't have a DFS as parent\n");
+		return NULL;
+	}
+
+	return s32cc_obj2dfs(parent);
+}
+
+static struct s32cc_pll *dfsdiv2pll(const struct s32cc_dfs_div *dfs_div)
+{
+	const struct s32cc_clk_obj *parent;
+	const struct s32cc_dfs *dfs;
+
+	dfs = get_div_dfs(dfs_div);
+	if (dfs == NULL) {
+		return NULL;
+	}
+
+	parent = dfs->parent;
+	if (parent->type != s32cc_pll_t) {
+		return NULL;
+	}
+
+	return s32cc_obj2pll(parent);
+}
+
+static int get_dfs_mfi_mfn(unsigned long dfs_freq, const struct s32cc_dfs_div *dfs_div,
+			   uint32_t *mfi, uint32_t *mfn)
+{
+	uint64_t factor64, tmp64, ofreq;
+	uint32_t factor32;
+
+	unsigned long in = dfs_freq;
+	unsigned long out = dfs_div->freq;
+
+	/**
+	 * factor = (IN / OUT) / 2
+	 * MFI = integer(factor)
+	 * MFN = (factor - MFI) * 36
+	 */
+	factor64 = ((((uint64_t)in) * FP_PRECISION) / ((uint64_t)out)) / 2ULL;
+	tmp64 = factor64 / FP_PRECISION;
+	if (tmp64 > UINT32_MAX) {
+		return -EINVAL;
+	}
+
+	factor32 = (uint32_t)tmp64;
+	*mfi = factor32;
+
+	tmp64 = ((factor64 - ((uint64_t)*mfi * FP_PRECISION)) * 36UL) / FP_PRECISION;
+	if (tmp64 > UINT32_MAX) {
+		return -EINVAL;
+	}
+
+	*mfn = (uint32_t)tmp64;
+
+	/* div_freq = in / (2 * (*mfi + *mfn / 36.0)) */
+	factor64 = (((uint64_t)*mfn) * FP_PRECISION) / 36ULL;
+	factor64 += ((uint64_t)*mfi) * FP_PRECISION;
+	factor64 *= 2ULL;
+	ofreq = (((uint64_t)in) * FP_PRECISION) / factor64;
+
+	if (ofreq != dfs_div->freq) {
+		ERROR("Failed to find MFI and MFN settings for DFS DIV freq %lu\n",
+		      dfs_div->freq);
+		ERROR("Nearest freq = %" PRIx64 "\n", ofreq);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int init_dfs_port(uintptr_t dfs_addr, uint32_t port,
+			 uint32_t mfi, uint32_t mfn)
+{
+	uint32_t portsr, portolsr;
+	uint32_t mask, old_mfi, old_mfn;
+	uint32_t dvport;
+	bool init_dfs;
+
+	dvport = mmio_read_32(DFS_DVPORTn(dfs_addr, port));
+
+	old_mfi = DFS_DVPORTn_MFI(dvport);
+	old_mfn = DFS_DVPORTn_MFN(dvport);
+
+	portsr = mmio_read_32(DFS_PORTSR(dfs_addr));
+	portolsr = mmio_read_32(DFS_PORTOLSR(dfs_addr));
+
+	/* Skip configuration if it's not needed */
+	if (((portsr & BIT_32(port)) != 0U) &&
+	    ((portolsr & BIT_32(port)) == 0U) &&
+	    (mfi == old_mfi) && (mfn == old_mfn)) {
+		return 0;
+	}
+
+	init_dfs = (portsr == 0U);
+
+	if (init_dfs) {
+		mask = DFS_PORTRESET_MASK;
+	} else {
+		mask = DFS_PORTRESET_SET(BIT_32(port));
+	}
+
+	mmio_write_32(DFS_PORTOLSR(dfs_addr), mask);
+	mmio_write_32(DFS_PORTRESET(dfs_addr), mask);
+
+	while ((mmio_read_32(DFS_PORTSR(dfs_addr)) & mask) != 0U) {
+	}
+
+	if (init_dfs) {
+		mmio_write_32(DFS_CTL(dfs_addr), DFS_CTL_RESET);
+	}
+
+	mmio_write_32(DFS_DVPORTn(dfs_addr, port),
+		      DFS_DVPORTn_MFI_SET(mfi) | DFS_DVPORTn_MFN_SET(mfn));
+
+	if (init_dfs) {
+		/* DFS clk enable programming */
+		mmio_clrbits_32(DFS_CTL(dfs_addr), DFS_CTL_RESET);
+	}
+
+	mmio_clrbits_32(DFS_PORTRESET(dfs_addr), BIT_32(port));
+
+	while ((mmio_read_32(DFS_PORTSR(dfs_addr)) & BIT_32(port)) != BIT_32(port)) {
+	}
+
+	portolsr = mmio_read_32(DFS_PORTOLSR(dfs_addr));
+	if ((portolsr & DFS_PORTOLSR_LOL(port)) != 0U) {
+		ERROR("Failed to lock DFS divider\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct s32cc_clk_obj *
+get_dfs_div_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module);
+
+	if (dfs_div->parent == NULL) {
+		ERROR("Failed to identify DFS divider's parent\n");
+	}
+
+	return dfs_div->parent;
+}
+
+static int enable_dfs_div(struct s32cc_clk_obj *module,
+			  const struct s32cc_clk_drv *drv,
+			  unsigned int depth)
+{
+	const struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module);
+	unsigned int ldepth = depth;
+	const struct s32cc_pll *pll;
+	const struct s32cc_dfs *dfs;
+	uintptr_t dfs_addr = 0UL;
+	uint32_t mfi, mfn;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	dfs = get_div_dfs(dfs_div);
+	if (dfs == NULL) {
+		return -EINVAL;
+	}
+
+	pll = dfsdiv2pll(dfs_div);
+	if (pll == NULL) {
+		ERROR("Failed to identify DFS divider's parent\n");
+		return -EINVAL;
+	}
+
+	ret = get_base_addr(dfs->instance, drv, &dfs_addr);
+	if ((ret != 0) || (dfs_addr == 0UL)) {
+		return -EINVAL;
+	}
+
+	ret = get_dfs_mfi_mfn(pll->vco_freq, dfs_div, &mfi, &mfn);
+	if (ret != 0) {
+		return -EINVAL;
+	}
+
+	return init_dfs_port(dfs_addr, dfs_div->index, mfi, mfn);
+}
+
+typedef int (*enable_clk_t)(struct s32cc_clk_obj *module,
+			    const struct s32cc_clk_drv *drv,
+			    unsigned int depth);
+
+static int enable_part(struct s32cc_clk_obj *module,
+		       const struct s32cc_clk_drv *drv,
+		       unsigned int depth)
+{
+	const struct s32cc_part *part = s32cc_obj2part(module);
+	uint32_t part_no = part->partition_id;
+
+	if ((drv->mc_me == 0UL) || (drv->mc_rgm == 0UL) || (drv->rdc == 0UL)) {
+		return -EINVAL;
+	}
 
-#include <common/debug.h>
-#include <drivers/clk.h>
-#include <s32cc-clk-modules.h>
-#include <s32cc-clk-utils.h>
+	return mc_me_enable_partition(drv->mc_me, drv->mc_rgm, drv->rdc, part_no);
+}
+
+static int enable_part_block(struct s32cc_clk_obj *module,
+			     const struct s32cc_clk_drv *drv,
+			     unsigned int depth)
+{
+	const struct s32cc_part_block *block = s32cc_obj2partblock(module);
+	const struct s32cc_part *part = block->part;
+	uint32_t part_no = part->partition_id;
+	unsigned int ldepth = depth;
+	uint32_t cofb;
+	int ret;
 
-#define MAX_STACK_DEPTH		(15U)
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
 
-static int update_stack_depth(unsigned int *depth)
+	if ((block->block >= s32cc_part_block0) &&
+	    (block->block <= s32cc_part_block15)) {
+		cofb = (uint32_t)block->block - (uint32_t)s32cc_part_block0;
+		mc_me_enable_part_cofb(drv->mc_me, part_no, cofb, block->status);
+	} else {
+		ERROR("Unknown partition block type: %d\n", block->block);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct s32cc_clk_obj *
+get_part_block_parent(const struct s32cc_clk_obj *module)
 {
-	if (*depth == 0U) {
-		return -ENOMEM;
+	const struct s32cc_part_block *block = s32cc_obj2partblock(module);
+
+	return &block->part->desc;
+}
+
+static int enable_module_with_refcount(struct s32cc_clk_obj *module,
+				       const struct s32cc_clk_drv *drv,
+				       unsigned int depth);
+
+static int enable_part_block_link(struct s32cc_clk_obj *module,
+				  const struct s32cc_clk_drv *drv,
+				  unsigned int depth)
+{
+	const struct s32cc_part_block_link *link = s32cc_obj2partblocklink(module);
+	struct s32cc_part_block *block = link->block;
+	unsigned int ldepth = depth;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
 	}
 
-	(*depth)--;
+	/* Move the enablement algorithm to partition tree */
+	return enable_module_with_refcount(&block->desc, drv, ldepth);
+}
+
+static struct s32cc_clk_obj *
+get_part_block_link_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_part_block_link *link = s32cc_obj2partblocklink(module);
+
+	return link->parent;
+}
+
+static int no_enable(struct s32cc_clk_obj *module,
+		     const struct s32cc_clk_drv *drv,
+		     unsigned int depth)
+{
 	return 0;
 }
 
+static int exec_cb_with_refcount(enable_clk_t en_cb, struct s32cc_clk_obj *mod,
+				 const struct s32cc_clk_drv *drv, bool leaf_node,
+				 unsigned int depth)
+{
+	unsigned int ldepth = depth;
+	int ret = 0;
+
+	if (mod == NULL) {
+		return 0;
+	}
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Refcount will be updated as part of the recursivity */
+	if (leaf_node) {
+		return en_cb(mod, drv, ldepth);
+	}
+
+	if (mod->refcount == 0U) {
+		ret = en_cb(mod, drv, ldepth);
+	}
+
+	if (ret == 0) {
+		mod->refcount++;
+	}
+
+	return ret;
+}
+
+static struct s32cc_clk_obj *get_module_parent(const struct s32cc_clk_obj *module);
+
+static int enable_module(struct s32cc_clk_obj *module,
+			 const struct s32cc_clk_drv *drv,
+			 unsigned int depth)
+{
+	struct s32cc_clk_obj *parent = get_module_parent(module);
+	static const enable_clk_t enable_clbs[12] = {
+		[s32cc_clk_t] = no_enable,
+		[s32cc_osc_t] = enable_osc,
+		[s32cc_pll_t] = enable_pll,
+		[s32cc_pll_out_div_t] = enable_pll_div,
+		[s32cc_clkmux_t] = enable_mux,
+		[s32cc_shared_clkmux_t] = enable_mux,
+		[s32cc_dfs_t] = enable_dfs,
+		[s32cc_dfs_div_t] = enable_dfs_div,
+		[s32cc_part_t] = enable_part,
+		[s32cc_part_block_t] = enable_part_block,
+		[s32cc_part_block_link_t] = enable_part_block_link,
+	};
+	unsigned int ldepth = depth;
+	uint32_t index;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (drv == NULL) {
+		return -EINVAL;
+	}
+
+	index = (uint32_t)module->type;
+
+	if (index >= ARRAY_SIZE(enable_clbs)) {
+		ERROR("Undefined module type: %d\n", module->type);
+		return -EINVAL;
+	}
+
+	if (enable_clbs[index] == NULL) {
+		ERROR("Undefined callback for the clock type: %d\n",
+		      module->type);
+		return -EINVAL;
+	}
+
+	parent = get_module_parent(module);
+
+	ret = exec_cb_with_refcount(enable_module, parent, drv,
+				    false, ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = exec_cb_with_refcount(enable_clbs[index], module, drv,
+				    true, ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_module_with_refcount(struct s32cc_clk_obj *module,
+				       const struct s32cc_clk_drv *drv,
+				       unsigned int depth)
+{
+	return exec_cb_with_refcount(enable_module, module, drv, false, depth);
+}
+
 static int s32cc_clk_enable(unsigned long id)
 {
-	return -ENOTSUP;
+	const struct s32cc_clk_drv *drv = get_drv();
+	unsigned int depth = MAX_STACK_DEPTH;
+	struct s32cc_clk *clk;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	return enable_module_with_refcount(&clk->desc, drv, depth);
 }
 
 static void s32cc_clk_disable(unsigned long id)
@@ -97,6 +1119,157 @@
 	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_mux_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	const struct s32cc_clkmux *mux = s32cc_obj2clkmux(module);
+	const struct s32cc_clk *clk = s32cc_get_arch_clk(mux->source_id);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (clk == NULL) {
+		ERROR("Mux (id:%" PRIu8 ") without a valid source (%lu)\n",
+		      mux->index, mux->source_id);
+		return -EINVAL;
+	}
+
+	return set_module_rate(&clk->desc, rate, orate, depth);
+}
+
+static int set_dfs_div_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			    unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module);
+	const struct s32cc_dfs *dfs;
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (dfs_div->parent == NULL) {
+		ERROR("Failed to identify DFS divider's parent\n");
+		return -EINVAL;
+	}
+
+	/* Sanity check */
+	dfs = s32cc_obj2dfs(dfs_div->parent);
+	if (dfs->parent == NULL) {
+		ERROR("Failed to identify DFS's parent\n");
+		return -EINVAL;
+	}
+
+	if ((dfs_div->freq != 0U) && (dfs_div->freq != rate)) {
+		ERROR("DFS DIV frequency was already set to %lu\n",
+		      dfs_div->freq);
+		return -EINVAL;
+	}
+
+	dfs_div->freq = rate;
+	*orate = rate;
+
+	return ret;
+}
+
 static int set_module_rate(const struct s32cc_clk_obj *module,
 			   unsigned long rate, unsigned long *orate,
 			   unsigned int *depth)
@@ -108,6 +1281,8 @@
 		return ret;
 	}
 
+	ret = -EINVAL;
+
 	switch (module->type) {
 	case s32cc_clk_t:
 		ret = set_clk_freq(module, rate, orate, depth);
@@ -115,8 +1290,28 @@
 	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:
+		ret = set_mux_freq(module, rate, orate, depth);
+		break;
+	case s32cc_shared_clkmux_t:
+		ret = set_mux_freq(module, rate, orate, depth);
+		break;
+	case s32cc_dfs_t:
+		ERROR("Setting the frequency of a DFS is not allowed!");
+		break;
+	case s32cc_dfs_div_t:
+		ret = set_dfs_div_freq(module, rate, orate, depth);
+		break;
 	default:
-		ret = -EINVAL;
 		break;
 	}
 
@@ -144,14 +1339,129 @@
 	return ret;
 }
 
+static struct s32cc_clk_obj *get_no_parent(const struct s32cc_clk_obj *module)
+{
+	return NULL;
+}
+
+typedef struct s32cc_clk_obj *(*get_parent_clb_t)(const struct s32cc_clk_obj *clk_obj);
+
+static struct s32cc_clk_obj *get_module_parent(const struct s32cc_clk_obj *module)
+{
+	static const get_parent_clb_t parents_clbs[12] = {
+		[s32cc_clk_t] = get_clk_parent,
+		[s32cc_osc_t] = get_no_parent,
+		[s32cc_pll_t] = get_pll_parent,
+		[s32cc_pll_out_div_t] = get_pll_div_parent,
+		[s32cc_clkmux_t] = get_mux_parent,
+		[s32cc_shared_clkmux_t] = get_mux_parent,
+		[s32cc_dfs_t] = get_dfs_parent,
+		[s32cc_dfs_div_t] = get_dfs_div_parent,
+		[s32cc_part_t] = get_no_parent,
+		[s32cc_part_block_t] = get_part_block_parent,
+		[s32cc_part_block_link_t] = get_part_block_link_parent,
+	};
+	uint32_t index;
+
+	if (module == NULL) {
+		return NULL;
+	}
+
+	index = (uint32_t)module->type;
+
+	if (index >= ARRAY_SIZE(parents_clbs)) {
+		ERROR("Undefined module type: %d\n", module->type);
+		return NULL;
+	}
+
+	if (parents_clbs[index] == NULL) {
+		ERROR("Undefined parent getter for type: %d\n", module->type);
+		return NULL;
+	}
+
+	return parents_clbs[index](module);
+}
+
 static int s32cc_clk_get_parent(unsigned long id)
 {
-	return -ENOTSUP;
+	struct s32cc_clk *parent_clk;
+	const struct s32cc_clk_obj *parent;
+	const struct s32cc_clk *clk;
+	unsigned long parent_id;
+	int ret;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	parent = get_module_parent(clk->module);
+	if (parent == NULL) {
+		return -EINVAL;
+	}
+
+	parent_clk = s32cc_obj2clk(parent);
+	if (parent_clk == NULL) {
+		return -EINVAL;
+	}
+
+	ret = s32cc_get_clk_id(parent_clk, &parent_id);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (parent_id > (unsigned long)INT_MAX) {
+		return -E2BIG;
+	}
+
+	return (int)parent_id;
 }
 
 static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id)
 {
-	return -ENOTSUP;
+	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)
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
index f8fc52f..71055ab 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
@@ -7,6 +7,12 @@
 #include <s32cc-clk-modules.h>
 #include <s32cc-clk-utils.h>
 
+#define S32CC_A53_MIN_FREQ	(48UL * MHZ)
+#define S32CC_A53_MAX_FREQ	(1000UL * MHZ)
+
+/* Partitions */
+static struct s32cc_part part0 = S32CC_PART(0);
+
 /* Oscillators */
 static struct s32cc_osc fxosc =
 	S32CC_OSC_INIT(S32CC_FXOSC);
@@ -23,11 +29,165 @@
 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);
+
+/* ARM DFS */
+static struct s32cc_dfs armdfs =
+	S32CC_DFS_INIT(armpll, S32CC_ARM_DFS);
+static struct s32cc_dfs_div arm_dfs1_div =
+	S32CC_DFS_DIV_INIT(armdfs, 0);
+static struct s32cc_clk arm_dfs1_clk =
+	S32CC_FREQ_MODULE_CLK(arm_dfs1_div, 0, 800 * MHZ);
+
+/* MC_CGM0 */
+static struct s32cc_clkmux cgm0_mux0 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM0, 0, 2,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_ARM_PLL_DFS1, 0, 0, 0);
+static struct s32cc_clk cgm0_mux0_clk = S32CC_MODULE_CLK(cgm0_mux0);
+
+static struct s32cc_clkmux cgm0_mux8 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM0, 8, 3,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_PERIPH_PLL_PHI3,
+				 S32CC_CLK_FXOSC, 0, 0);
+static struct s32cc_clk cgm0_mux8_clk = S32CC_MODULE_CLK(cgm0_mux8);
+
+/* XBAR */
+static struct s32cc_clk xbar_2x_clk =
+	S32CC_CHILD_CLK(cgm0_mux0_clk, 48 * MHZ, 800 * MHZ);
+static struct s32cc_fixed_div xbar_div2 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 2);
+static struct s32cc_clk xbar_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div2, 24 * MHZ, 400 * MHZ);
+static struct s32cc_fixed_div xbar_div4 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 4);
+static struct s32cc_clk xbar_div2_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div4, 12 * MHZ, 200 * MHZ);
+static struct s32cc_fixed_div xbar_div6 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 6);
+static struct s32cc_clk xbar_div3_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div6, 8 * MHZ, 133333333);
+static struct s32cc_fixed_div xbar_div8 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 8);
+static struct s32cc_clk xbar_div4_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div8, 6 * MHZ, 100 * MHZ);
+static struct s32cc_fixed_div xbar_div12 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 12);
+static struct s32cc_clk xbar_div6_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div12, 4 * MHZ, 66666666);
+
+/* Linflex */
+static struct s32cc_clk linflex_baud_clk =
+	S32CC_CHILD_CLK(cgm0_mux8_clk, 19200, 133333333);
+static struct s32cc_fixed_div linflex_div =
+	S32CC_FIXED_DIV_INIT(linflex_baud_clk, 2);
+static struct s32cc_clk linflex_clk =
+	S32CC_FREQ_MODULE_CLK(linflex_div, 9600, 66666666);
+
+/* 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);
+
+/* PERIPH PLL */
+static struct s32cc_clkmux periph_pll_mux =
+	S32CC_CLKMUX_INIT(S32CC_PERIPH_PLL, 0, 2,
+			  S32CC_CLK_FIRC,
+			  S32CC_CLK_FXOSC, 0, 0, 0);
+static struct s32cc_clk periph_pll_mux_clk =
+	S32CC_MODULE_CLK(periph_pll_mux);
+static struct s32cc_pll periphpll =
+	S32CC_PLL_INIT(periph_pll_mux_clk, S32CC_PERIPH_PLL, 2);
+static struct s32cc_clk periph_pll_vco_clk =
+	S32CC_FREQ_MODULE_CLK(periphpll, 1300 * MHZ, 2 * GHZ);
+
-static struct s32cc_clk *s32cc_hw_clk_list[3] = {
+static struct s32cc_pll_out_div periph_pll_phi3_div =
+	S32CC_PLL_OUT_DIV_INIT(periphpll, 3);
+static struct s32cc_clk periph_pll_phi3_clk =
+	S32CC_FREQ_MODULE_CLK(periph_pll_phi3_div, 0, 133333333);
+
+/* DDR PLL */
+static struct s32cc_clkmux ddr_pll_mux =
+	S32CC_CLKMUX_INIT(S32CC_DDR_PLL, 0, 2,
+			  S32CC_CLK_FIRC,
+			  S32CC_CLK_FXOSC, 0, 0, 0);
+static struct s32cc_clk ddr_pll_mux_clk =
+	S32CC_MODULE_CLK(ddr_pll_mux);
+static struct s32cc_pll ddrpll =
+	S32CC_PLL_INIT(ddr_pll_mux_clk, S32CC_DDR_PLL, 1);
+static struct s32cc_clk ddr_pll_vco_clk =
+	S32CC_FREQ_MODULE_CLK(ddrpll, 1300 * MHZ, 1600 * MHZ);
+
+static struct s32cc_pll_out_div ddr_pll_phi0_div =
+	S32CC_PLL_OUT_DIV_INIT(ddrpll, 0);
+static struct s32cc_clk ddr_pll_phi0_clk =
+	S32CC_FREQ_MODULE_CLK(ddr_pll_phi0_div, 0, 800 * MHZ);
+
+/* MC_CGM5 */
+static struct s32cc_clkmux cgm5_mux0 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM5, 0, 2,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_DDR_PLL_PHI0,
+				 0, 0, 0);
+static struct s32cc_clk cgm5_mux0_clk = S32CC_MODULE_CLK(cgm5_mux0);
+
+/* DDR clock */
+static struct s32cc_part_block part0_block1 =
+	S32CC_PART_BLOCK(&part0, s32cc_part_block1);
+static struct s32cc_part_block_link ddr_block_link =
+	S32CC_PART_BLOCK_LINK(cgm5_mux0_clk, &part0_block1);
+static struct s32cc_clk ddr_clk =
+	S32CC_FREQ_MODULE_CLK(ddr_block_link, 0, 800 * MHZ);
+
+static struct s32cc_clk *s32cc_hw_clk_list[37] = {
 	/* 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,
+	/* ARM DFS */
+	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_DFS1)] = &arm_dfs1_clk,
+	/* PERIPH PLL */
+	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_PHI3)] = &periph_pll_phi3_clk,
+	/* DDR PLL */
+	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_PHI0)] = &ddr_pll_phi0_clk,
 };
 
 static struct s32cc_clk_array s32cc_hw_clocks = {
@@ -36,11 +196,62 @@
 	.n_clks = ARRAY_SIZE(s32cc_hw_clk_list),
 };
 
+static struct s32cc_clk *s32cc_arch_clk_list[22] = {
+	/* 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,
+	/* PERIPH PLL */
+	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_MUX)] = &periph_pll_mux_clk,
+	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_VCO)] = &periph_pll_vco_clk,
+	/* MC_CGM0 */
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX0)] = &cgm0_mux0_clk,
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX8)] = &cgm0_mux8_clk,
+	/* XBAR */
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_2X)] = &xbar_2x_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR)] = &xbar_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV2)] = &xbar_div2_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV3)] = &xbar_div3_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV4)] = &xbar_div4_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV6)] = &xbar_div6_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,
+	/* Linflex */
+	[S32CC_CLK_ID(S32CC_CLK_LINFLEX)] = &linflex_clk,
+	[S32CC_CLK_ID(S32CC_CLK_LINFLEX_BAUD)] = &linflex_baud_clk,
+	/* DDR PLL */
+	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_MUX)] = &ddr_pll_mux_clk,
+	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_VCO)] = &ddr_pll_vco_clk,
+	/* MC_CGM5 */
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM5_MUX0)] = &cgm5_mux0_clk,
+	/* DDR */
+	[S32CC_CLK_ID(S32CC_CLK_DDR)] = &ddr_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),
+};
+
+static const struct s32cc_clk_array *s32cc_clk_table[2] = {
+	&s32cc_hw_clocks,
+	&s32cc_arch_clocks,
+};
+
 struct s32cc_clk *s32cc_get_arch_clk(unsigned long id)
 {
-	static const struct s32cc_clk_array *clk_table[1] = {
-		&s32cc_hw_clocks,
-	};
+	return s32cc_get_clk_from_table(s32cc_clk_table,
+					ARRAY_SIZE(s32cc_clk_table),
+					id);
+}
 
-	return s32cc_get_clk_from_table(clk_table, ARRAY_SIZE(clk_table), id);
+int s32cc_get_clk_id(const struct s32cc_clk *clk, unsigned long *id)
+{
+	return s32cc_get_id_from_table(s32cc_clk_table,
+				       ARRAY_SIZE(s32cc_clk_table),
+				       clk, id);
 }
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_utils.c b/drivers/nxp/clk/s32cc/s32cc_clk_utils.c
index 14ab674..0e75054 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_utils.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_utils.c
@@ -3,6 +3,7 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include <errno.h>
 #include <s32cc-clk-ids.h>
 #include <s32cc-clk-utils.h>
 
@@ -42,3 +43,23 @@
 
 	return NULL;
 }
+
+int s32cc_get_id_from_table(const struct s32cc_clk_array *const *clk_arr,
+			    size_t size, const struct s32cc_clk *clk,
+			    unsigned long *clk_index)
+{
+	size_t i, j;
+
+	for (i = 0; i < size; i++) {
+		for (j = 0; j < clk_arr[i]->n_clks; j++) {
+			if (clk_arr[i]->clks[j] != clk) {
+				continue;
+			}
+
+			*clk_index = S32CC_CLK(clk_arr[i]->type_mask, j);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
index fc1dc02..02b9df9 100644
--- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -4,11 +4,181 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <drivers/clk.h>
+#include <platform_def.h>
 #include <s32cc-clk-drv.h>
 #include <s32cc-clk-ids.h>
 #include <s32cc-clk-utils.h>
 
-#define S32CC_FXOSC_FREQ	(40U * MHZ)
+#define S32CC_FXOSC_FREQ		(40U * MHZ)
+#define S32CC_ARM_PLL_VCO_FREQ		(2U * GHZ)
+#define S32CC_ARM_PLL_PHI0_FREQ		(1U * GHZ)
+#define S32CC_A53_FREQ			(1U * GHZ)
+#define S32CC_XBAR_2X_FREQ		(800U * MHZ)
+#define S32CC_PERIPH_PLL_VCO_FREQ	(2U * GHZ)
+#define S32CC_PERIPH_PLL_PHI3_FREQ	UART_CLOCK_HZ
+#define S32CC_DDR_PLL_VCO_FREQ		(1600U * MHZ)
+#define S32CC_DDR_PLL_PHI0_FREQ		(800U * MHZ)
+
+static int setup_fxosc(void)
+{
+	int ret;
+
+	ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int setup_arm_pll(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC);
+	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;
+	}
+
+	return ret;
+}
+
+static int setup_periph_pll(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_a53_clk(void)
+{
+	int 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_A53_CORE, S32CC_A53_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_A53_CORE);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_xbar_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_XBAR_2X);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_uart_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX8, S32CC_CLK_PERIPH_PLL_PHI3);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_LINFLEX_BAUD);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int setup_ddr_pll(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_ddr_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_DDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
 
 int s32cc_init_early_clks(void)
 {
@@ -16,7 +186,42 @@
 
 	s32cc_clk_register_drv();
 
-	ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
+	ret = setup_fxosc();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = setup_arm_pll();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_a53_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_xbar_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = setup_periph_pll();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_uart_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = setup_ddr_pll();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_ddr_clk();
 	if (ret != 0) {
 		return ret;
 	}
diff --git a/drivers/nxp/console/linflex_console.S b/drivers/nxp/console/linflex_console.S
index abcbb59..d8c10ef 100644
--- a/drivers/nxp/console/linflex_console.S
+++ b/drivers/nxp/console/linflex_console.S
@@ -18,6 +18,7 @@
 
 #define LINFLEX_LINSR		(0x8)
 #define LINSR_LINS_INITMODE	(0x00001000)
+#define LINSR_LINS_RX_TX_MODE	(0x00008000)
 #define LINSR_LINS_MASK		(0x0000F000)
 
 #define LINFLEX_UARTCR		(0x10)
@@ -48,9 +49,11 @@
  */
 .globl console_linflex_core_init
 .globl console_linflex_core_putc
+.globl console_linflex_core_flush
 
 .globl console_linflex_register
 .globl console_linflex_putc
+.globl console_linflex_flush
 
 /**
  * uint32_t get_ldiv_mult(uintptr_t baseaddr, uint32_t clock,
@@ -175,10 +178,29 @@
 	str	x0, [x3, #CONSOLE_T_BASE]
 
 	mov	x0, x3
-	finish_console_register linflex, putc=1, getc=0, flush=0
+	finish_console_register linflex, putc=1, getc=0, flush=1
 endfunc console_linflex_register
 
 /**
+ * int console_linflex_core_flush(uintptr_t baseaddr);
+ *
+ * Loop while the TX fifo is not empty, depending on the selected UART mode.
+ *
+ * In:  x0 - Linflex base address
+ * Clobber list : x0 - x1
+ */
+func console_linflex_core_flush
+wait_rx_tx:
+	ldr	w1, [x0, LINFLEX_LINSR]
+	and	w1, w1, #LINSR_LINS_MASK
+	cmp	w1, #LINSR_LINS_RX_TX_MODE
+	b.eq	wait_rx_tx
+
+	mov	x0, #0
+	ret
+endfunc console_linflex_core_flush
+
+/**
  * int console_linflex_core_putc(int c, uintptr_t baseaddr);
 
  * Out: w0 - printed character on success, < 0 on error.
@@ -257,3 +279,21 @@
 	mov	x0, #-EINVAL
 	ret
 endfunc console_linflex_putc
+
+/**
+ * int console_linflex_flush(console_t *console);
+ *
+ * Function to wait for the TX FIFO to be cleared.
+ * In : x0 - pointer to console_t struct
+ * Out: x0 - return -1 on error else return 0.
+ * Clobber list : x0 - x1
+ */
+func console_linflex_flush
+	cbz	x0, flush_error
+	ldr	x0, [x0, #CONSOLE_T_BASE]
+
+	b	console_linflex_core_flush
+flush_error:
+	mov	x0, #-EINVAL
+	ret
+endfunc console_linflex_flush
diff --git a/drivers/nxp/gpio/nxp_gpio.c b/drivers/nxp/gpio/nxp_gpio.c
index 28c9db9..b477b79 100644
--- a/drivers/nxp/gpio/nxp_gpio.c
+++ b/drivers/nxp/gpio/nxp_gpio.c
@@ -28,8 +28,8 @@
 		ERROR("GPIO is not initialized.\n");
 		return GPIO_FAILURE;
 	}
-
-	gpdir = gpio_base_addr + GPDIR_REG_OFFSET;
+	/* Divide by 4 since we're operating on 32-bit pointer addresses. */
+	gpdir = gpio_base_addr + (GPDIR_REG_OFFSET >> 2);
 	gpdat = gpio_base_addr + (GPDAT_REG_OFFSET >> 2);
 
 	/*
@@ -67,8 +67,9 @@
 		return GPIO_FAILURE;
 	}
 
-	gpdir = gpio_base_addr + GPDIR_REG_OFFSET;
-	gpdat = gpio_base_addr + GPDAT_REG_OFFSET;
+	/* Divide by 4 since we're operating on 32-bit pointer addresses. */
+	gpdir = gpio_base_addr + (GPDIR_REG_OFFSET >> 2);
+	gpdat = gpio_base_addr + (GPDAT_REG_OFFSET >> 2);
 
 	/*
 	 * Reset the corresponding bit in direction and data register
diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c
index 55a8832..460afe1 100644
--- a/drivers/rpi3/gpio/rpi3_gpio.c
+++ b/drivers/rpi3/gpio/rpi3_gpio.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019, Linaro Limited
  * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -120,7 +121,7 @@
 	int regN = gpio / 32;
 	int shift = gpio % 32;
 	uintptr_t reg_set = reg_base + RPI3_GPIO_GPSET(regN);
-	uintptr_t reg_clr = reg_base + RPI3_GPIO_GPSET(regN);
+	uintptr_t reg_clr = reg_base + RPI3_GPIO_GPCLR(regN);
 
 	switch (value) {
 	case GPIO_LEVEL_LOW:
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/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c
index e92f980..bd49324 100644
--- a/drivers/st/crypto/stm32_hash.c
+++ b/drivers/st/crypto/stm32_hash.c
@@ -10,6 +10,7 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <common/sha_common_macros.h>
 #include <drivers/clk.h>
 #include <drivers/delay_timer.h>
 #include <drivers/st/stm32_hash.h>
@@ -62,15 +63,6 @@
 #define HASH_STR_NBLW_MASK		GENMASK(4, 0)
 #define HASH_STR_DCAL			BIT(8)
 
-#define MD5_DIGEST_SIZE			16U
-#define SHA1_DIGEST_SIZE		20U
-#define SHA224_DIGEST_SIZE		28U
-#define SHA256_DIGEST_SIZE		32U
-#define SHA384_DIGEST_SIZE		48U
-#define SHA512_224_DIGEST_SIZE		28U
-#define SHA512_256_DIGEST_SIZE		32U
-#define SHA512_DIGEST_SIZE		64U
-
 #define RESET_TIMEOUT_US_1MS		1000U
 #define HASH_TIMEOUT_US			10000U
 
diff --git a/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr3.h b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr3.h
new file mode 100644
index 0000000..936b73c
--- /dev/null
+++ b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr3.h
@@ -0,0 +1,935 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MNPMUSRAMMSGBLOCK_DDR3_H
+#define MNPMUSRAMMSGBLOCK_DDR3_H
+
+/*
+ * DDR3U_1D training firmware message block structure
+ *
+ * Please refer to the Training Firmware App Note for futher information about
+ * the usage for Message Block.
+ */
+struct pmu_smb_ddr_1d {
+	uint8_t reserved00;		/*
+					 * Byte offset 0x00, CSR Addr 0x54000, Direction=In
+					 * reserved00[0:4] RFU, must be zero
+					 *
+					 * reserved00[5] = Train vrefDAC0 During Read Deskew
+					 *   0x1 = Read Deskew will begin by enabling and roughly
+					 *   training the phy's per-lane reference voltages.
+					 *   Training the vrefDACs CSRs will increase the maximum 1D
+					 *   training time by around half a millisecond, but will
+					 *   improve 1D training accuracy on systems with
+					 *   significant voltage-offsets between lane read eyes.
+					 *   0x0 = Read Deskew will assume the messageblock's
+					 *   phyVref setting will work for all lanes.
+					 *
+					 * reserved00[6] = Enable High Effort WrDQ1D
+					 *   0x1 = WrDQ1D will conditionally retry training at
+					 *   several extra RxClkDly Timings. This will increase the
+					 *   maximum 1D training time by up to 4 extra iterations of
+					 *   WrDQ1D. This is only required in systems that suffer
+					 *   from very large, asymmetric eye-collapse when receiving
+					 *   PRBS patterns.
+					 *   0x0 = WrDQ1D assume rxClkDly values found by SI
+					 *   Friendly RdDqs1D will work for receiving PRBS patterns
+					 *
+					 * reserved00[7] = Optimize for the special hard macros in
+					 * TSMC28.
+					 *   0x1 = set if the phy being trained was manufactured in
+					 *   any TSMC28 process node.
+					 *   0x0 = otherwise, when not training a TSMC28 phy, leave
+					 *   this field as 0.
+					 */
+	uint8_t msgmisc;		/*
+					 * Byte offset 0x01, CSR Addr 0x54000, Direction=In
+					 * Contains various global options for training.
+					 *
+					 * Bit fields:
+					 *
+					 * msgmisc[0] = MTESTEnable
+					 *   0x1 = Pulse primary digital test output bump at the end
+					 *   of each major training stage. This enables observation
+					 *   of training stage completion by observing the digital
+					 *   test output.
+					 *   0x0 = Do not pulse primary digital test output bump
+					 *
+					 * msgmisc[1] = SimulationOnlyReset
+					 *   0x1 = Verilog only simulation option to shorten
+					 *   duration of DRAM reset pulse length to 1ns.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use reset pulse length specified by JEDEC
+					 *   standard.
+					 *
+					 * msgmisc[2] = SimulationOnlyTraining
+					 *   0x1 = Verilog only simulation option to shorten the
+					 *   duration of the training steps by performing fewer
+					 *   iterations.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use standard training duration.
+					 *
+					 * msgmisc[3] = RFU, must be zero
+					 *
+					 * msgmisc[4] = Suppress streaming messages, including
+					 * assertions, regardless of hdtctrl setting.
+					 * Stage Completion messages, as well as training completion
+					 * and error messages are still sent depending on hdtctrl
+					 * setting.
+					 *
+					 * msgmisc[5] = PerByteMaxRdLat
+					 *   0x1 = Each DBYTE will return dfi_rddata_valid at the
+					 *   lowest possible latency. This may result in unaligned
+					 *   data between bytes to be returned to the DFI.
+					 *   0x0 = Every DBYTE will return dfi_rddata_valid
+					 *   simultaneously. This will ensure that data bytes will
+					 *   return aligned accesses to the DFI.
+					 *
+					 * msgmisc[6] = PartialRank (DDR3 UDIMM and DDR4 UDIMM only,
+					 * otherwise RFU, must be zero)
+					 *   0x1 = Support rank populated with a subset of byte, but
+					 *   where even-odd pair of rank support all the byte
+					 *   0x0 = All rank populated with all the byte (tyical
+					 *   configuration)
+					 *
+					 * msgmisc[7] RFU, must be zero
+					 *
+					 * Notes:
+					 *
+					 * - SimulationOnlyReset and SimulationOnlyTraining can be
+					 *   used to speed up simulation run times, and must never
+					 *   be used in real silicon. Some VIPs may have checks on
+					 *   DRAM reset parameters that may need to be disabled when
+					 *   using SimulationOnlyReset.
+					 */
+	uint16_t pmurevision;		/*
+					 * Byte offset 0x02, CSR Addr 0x54001, Direction=Out
+					 * PMU firmware revision ID
+					 * After training is run, this address will contain the
+					 * revision ID of the firmware.
+					 * Please reference this revision ID when filing support
+					 * cases.
+					 */
+	uint8_t pstate;			/*
+					 * Byte offset 0x04, CSR Addr 0x54002, Direction=In
+					 * Must be set to the target pstate to be trained
+					 *   0x0 = pstate 0
+					 *   0x1 = pstate 1
+					 *   0x2 = pstate 2
+					 *   0x3 = pstate 3
+					 *   All other encodings are reserved
+					 */
+	uint8_t pllbypassen;		/*
+					 * Byte offset 0x05, CSR Addr 0x54002, Direction=In
+					 * Set according to whether target pstate uses PHY PLL
+					 * bypass
+					 *   0x0 = PHY PLL is enabled for target pstate
+					 *   0x1 = PHY PLL is bypassed for target pstate
+					 */
+	uint16_t dramfreq;		/*
+					 * Byte offset 0x06, CSR Addr 0x54003, Direction=In
+					 * DDR data rate for the target pstate in units of MT/s.
+					 * For example enter 0x0640 for DDR1600.
+					 */
+	uint8_t dfifreqratio;		/*
+					 * Byte offset 0x08, CSR Addr 0x54004, Direction=In
+					 * Frequency ratio betwen DfiCtlClk and SDRAM memclk.
+					 *   0x1 = 1:1
+					 *   0x2 = 1:2
+					 *   0x4 = 1:4
+					 */
+	uint8_t bpznresval;		/*
+					 * Byte offset 0x09, CSR Addr 0x54004, Direction=In
+					 * Overwrite the value of precision resistor connected to
+					 * Phy BP_ZN
+					 *   0x00 = Do not program. Use current CSR value.
+					 *   0xf0 = 240 Ohm
+					 *   0x78 = 120 Ohm
+					 *   0x28 = 40 Ohm
+					 *   All other values are reserved.
+					 * It is recommended to set this to 0x00.
+					 */
+	uint8_t phyodtimpedance;	/*
+					 * Byte offset 0x0a, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the termination impedance in ohms
+					 * used by PHY during reads.
+					 *
+					 *   0x0 = Firmware skips programming (must be manually
+					 *   programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal termination impedance values.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must determine the correct value
+					 * through SI simulation or other methods.
+					 */
+	uint8_t phydrvimpedance;	/*
+					 * Byte offset 0x0b, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the driver impedance in ohms used
+					 * by PHY during writes for all DBYTE drivers
+					 * (DQ/DM/DBI/DQS).
+					 *
+					 *   0x0 = Firmware skips programming (must be manually
+					 *   programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal R_on driver impedance values.
+					 *
+					 * For digital simulation, any value can be used that is not
+					 * Hi-Z. For silicon, the users must determine the correct
+					 * value through SI simulation or other methods.
+					 */
+	uint8_t phyvref;		/*
+					 * Byte offset 0x0c, CSR Addr 0x54006, Direction=In
+					 * Must be programmed with the Vref level to be used by the
+					 * PHY during reads
+					 *
+					 * The units of this field are a percentage of VDDQ
+					 * according to the following equation:
+					 *
+					 * Receiver Vref = VDDQ*phyvref[6:0]/128
+					 *
+					 * For example to set Vref at 0.75*VDDQ, set this field to
+					 * 0x60.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must calculate the analytical Vref by
+					 * using the impedances, terminations, and series resistance
+					 * present in the system.
+					 */
+	uint8_t dramtype;		/*
+					 * Byte offset 0x0d, CSR Addr 0x54006, Direction=In
+					 * Module Type:
+					 *   0x01 = DDR3 unbuffered
+					 *   0x02 = Reserved
+					 *   0x03 = Reserved
+					 *   0x04 = Reserved
+					 *   0x05 = Reserved
+					 */
+	uint8_t disableddbyte;		/*
+					 * Byte offset 0x0e, CSR Addr 0x54007, Direction=In
+					 * Bitmap to indicate which Dbyte are not connected (for
+					 * DByte 0 to 7):
+					 * Set disableddbyte[i] to 1 only to specify that DByte is
+					 * not need to be trained (DByte 8 can be disabled via
+					 * enableddqs setting)
+					 */
+	uint8_t enableddqs;		/*
+					 * Byte offset 0x0f, CSR Addr 0x54007, Direction=In
+					 * Total number of DQ bits enabled in PHY
+					 */
+	uint8_t cspresent;		/*
+					 * Byte offset 0x10, CSR Addr 0x54008, Direction=In
+					 * Indicates presence of DRAM at each chip select for PHY.
+					 * Each bit corresponds to a logical CS.
+					 *
+					 * If the bit is set to 1, the CS is connected to DRAM.
+					 * If the bit is set to 0, the CS is not connected to DRAM.
+					 *
+					 * cspresent[0] = CS0 is populated with DRAM
+					 * cspresent[1] = CS1 is populated with DRAM
+					 * cspresent[2] = CS2 is populated with DRAM
+					 * cspresent[3] = CS3 is populated with DRAM
+					 * cspresent[7:4] = Reserved (must be programmed to 0)
+					 */
+	uint8_t cspresentd0;		/*
+					 * Byte offset 0x11, CSR Addr 0x54008, Direction=In
+					 * The CS signals from field cspresent that are routed to
+					 * DIMM connector 0
+					 */
+	uint8_t cspresentd1;		/*
+					 * Byte offset 0x12, CSR Addr 0x54009, Direction=In
+					 * The CS signals from field cspresent that are routed to
+					 * DIMM connector 1
+					 */
+	uint8_t addrmirror;		/*
+					 * Byte offset 0x13, CSR Addr 0x54009, Direction=In
+					 * Corresponds to CS[3:0]
+					 *   1 = Address Mirror.
+					 *   0 = No Address Mirror.
+					 */
+	uint8_t cstestfail;		/*
+					 * Byte offset 0x14, CSR Addr 0x5400a, Direction=Out
+					 * This field will be set if training fails on any rank.
+					 *   0x0 = No failures
+					 *   non-zero = one or more ranks failed training
+					 */
+	uint8_t phycfg;			/*
+					 * Byte offset 0x15, CSR Addr 0x5400a, Direction=In
+					 * Additional mode bits.
+					 *
+					 * Bit fields:
+					 * [0] SlowAccessMode:
+					 *   1 = 2T Address Timing.
+					 *   0 = 1T Address Timing.
+					 * [7-1] RFU, must be zero
+					 *
+					 * WARNING: In case of DDR4 Geardown Mode (mr3[A3] == 1),
+					 * phycfg[0] must be 0.
+					 */
+	uint16_t sequencectrl;		/*
+					 * Byte offset 0x16, CSR Addr 0x5400b, Direction=In
+					 * Controls the training steps to be run. Each bit
+					 * corresponds to a training step.
+					 *
+					 * If the bit is set to 1, the training step will run.
+					 * If the bit is set to 0, the training step will be
+					 * skipped.
+					 *
+					 * Training step to bit mapping:
+					 * sequencectrl[0] = Run DevInit - Device/phy
+					 *		     initialization. Should always be set.
+					 * sequencectrl[1] = Run WrLvl - Write leveling
+					 * sequencectrl[2] = Run RxEn - Read gate training
+					 * sequencectrl[3] = Run RdDQS1D - 1d read dqs training
+					 * sequencectrl[4] = Run WrDQ1D - 1d write dq training
+					 * sequencectrl[5] = RFU, must be zero
+					 * sequencectrl[6] = RFU, must be zero
+					 * sequencectrl[7] = RFU, must be zero
+					 * sequencectrl[8] = Run RdDeskew - Per lane read dq deskew
+					 *		     training
+					 * sequencectrl[9] = Run MxRdLat - Max read latency training
+					 * sequencectrl[10] = RFU, must be zero
+					 * sequencectrl[11] = RFU, must be zero
+					 * sequencectrl[12] = RFU, must be zero
+					 * sequencectrl[13] = RFU, must be zero
+					 * sequencectrl[15-14] = RFU, must be zero
+					 */
+	uint8_t hdtctrl;		/*
+					 * Byte offset 0x18, CSR Addr 0x5400c, Direction=In
+					 * To control the total number of debug messages, a
+					 * verbosity subfield (hdtctrl, Hardware Debug Trace
+					 * Control) exists in the message block. Every message has a
+					 * verbosity level associated with it, and as the hdtctrl
+					 * value is increased, less important s messages stop being
+					 * sent through the mailboxes. The meanings of several major
+					 * hdtctrl thresholds are explained below:
+					 *
+					 *   0x04 = Maximal debug messages (e.g., Eye contours)
+					 *   0x05 = Detailed debug messages (e.g. Eye delays)
+					 *   0x0A = Coarse debug messages (e.g. rank information)
+					 *   0xC8 = Stage completion
+					 *   0xC9 = Assertion messages
+					 *   0xFF = Firmware completion messages only
+					 */
+	uint8_t reserved19;		/* Byte offset 0x19, CSR Addr 0x5400c, Direction=N/A */
+	uint8_t reserved1a;		/* Byte offset 0x1a, CSR Addr 0x5400d, Direction=N/A */
+	uint8_t share2dvrefresult;	/*
+					 * Byte offset 0x1b, CSR Addr 0x5400d, Direction=In
+					 * Bitmap that designates the phy's vref source for every
+					 * pstate
+					 * If share2dvrefresult[x] = 0, then after 2D training,
+					 * pstate x will continue using the phyVref provided in
+					 * pstate x's 1D messageblock.
+					 * If share2dvrefresult[x] = 1, then after 2D training,
+					 * pstate x will use the per-lane VrefDAC0/1 CSRs trained by
+					 * 2d training.
+					 */
+	uint8_t reserved1c;		/* Byte offset 0x1c, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1d;		/* Byte offset 0x1d, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1e;		/*
+					 * Byte offset 0x1e, CSR Addr 0x5400f, Direction=In
+					 * Input for constraining the range of vref(DQ) values
+					 * training will collect data for, usually reducing training
+					 * time. However, too large of a voltage range may cause
+					 * longer 2D training times while too small of a voltage
+					 * range may truncate passing regions. When in doubt, leave
+					 * this field set to 0.
+					 * Used by 2D training in: Rd2D, Wr2D
+					 *
+					 * reserved1E[0-3]: Rd2D Voltage Range
+					 *   0 = Training will search all phy vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from phyVref
+					 *   2 = limit to +/-4 %VDDQ from phyVref
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from phyVref
+					 *
+					 * reserved1E[4-7]: Wr2D Voltage Range
+					 *   0 = Training will search all dram vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from mr6
+					 *   2 = limit to +/-4 %VDDQ from mr6
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from mr6
+					 */
+	uint8_t reserved1f;		/*
+					 * Byte offset 0x1f, CSR Addr 0x5400f, Direction=In
+					 * Extended training option:
+					 *
+					 * reserved1F[1:0]: Configured RxClkDly offset try during
+					 * WrDq1D high-effort (i.e., when reserved00[6] is set)
+					 *   0: -8, +8, -16, +16
+					 *   1: -4, +4, -8, +8, -12, +12, -16, +16
+					 *   2: -2, +2, -4, +4, -6, +6, -8, +8
+					 *   3: -2, +2, -4, +4, -6, +6, -8, +8, -10, +10, -12, +12,
+					 *      -14, +14, -16, +16
+					 *
+					 * reserved1F[2]: When set, execute again WrDq1D after
+					 * RdDqs1D PRBS
+					 *
+					 * reserved1F[3]: When set redo RdDeskew with PRBS after
+					 * (first) WrDqs1D
+					 *
+					 * reserved1F[7:4]: This field is reserved and must be
+					 * programmed to 0x00.
+					 */
+	uint8_t reserved20;		/*
+					 * Byte offset 0x20, CSR Addr 0x54010, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for Reserved:
+					 * Reserved MREP assume raising edge is found when
+					 * reserved20[3:0]+3 consecutive 1 are received during MREP
+					 * fine delay swept; reserved20[6:0] thus permits to
+					 * increase tolerance for noisy system. And if reserved20[7]
+					 * is set, MREP training is failing if no raising edge is
+					 * found (otherwise the raising edge is assume close to
+					 * delay 0).
+					 */
+	uint8_t reserved21;		/*
+					 * Byte offset 0x21, CSR Addr 0x54010, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for Reserved:
+					 * Reserved DWL assume raising edge is found when
+					 * reserved21[3:0]+3 consecutive 1 are received during DWL
+					 * fine delay swept; reserved21[6:0] thus permits to
+					 * increase tolerance for noisy system. And if reserved21[7]
+					 * is set, DWL training is failing if no raising edge is
+					 * found (otherwise the raising edge is assume close to
+					 * delay 0).
+					 */
+	uint16_t phyconfigoverride;	/*
+					 * Byte offset 0x22, CSR Addr 0x54011, Direction=In
+					 * Override PhyConfig csr.
+					 *   0x0: Use hardware csr value for PhyConfing
+					 *   (recommended)
+					 *   Other values: Use value for PhyConfig instead of
+					 *   Hardware value.
+					 */
+	uint8_t dfimrlmargin;		/*
+					 * Byte offset 0x24, CSR Addr 0x54012, Direction=In
+					 * Margin added to smallest passing trained DFI Max Read
+					 * Latency value, in units of DFI clocks. Recommended to be
+					 * >= 1.
+					 */
+	int8_t cdd_rr_3_2;		/*
+					 * Byte offset 0x25, CSR Addr 0x54012, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 2.
+					 */
+	int8_t cdd_rr_3_1;		/*
+					 * Byte offset 0x26, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 1.
+					 */
+	int8_t cdd_rr_3_0;		/*
+					 * Byte offset 0x27, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 0.
+					 */
+	int8_t cdd_rr_2_3;		/*
+					 * Byte offset 0x28, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 3.
+					 */
+	int8_t cdd_rr_2_1;		/*
+					 * Byte offset 0x29, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 1.
+					 */
+	int8_t cdd_rr_2_0;		/*
+					 * Byte offset 0x2a, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 0.
+					 */
+	int8_t cdd_rr_1_3;		/*
+					 * Byte offset 0x2b, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 3.
+					 */
+	int8_t cdd_rr_1_2;		/*
+					 * Byte offset 0x2c, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 2.
+					 */
+	int8_t cdd_rr_1_0;		/*
+					 * Byte offset 0x2d, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 0.
+					 */
+	int8_t cdd_rr_0_3;		/*
+					 * Byte offset 0x2e, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 3.
+					 */
+	int8_t cdd_rr_0_2;		/*
+					 * Byte offset 0x2f, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 2.
+					 */
+	int8_t cdd_rr_0_1;		/*
+					 * Byte offset 0x30, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 1.
+					 */
+	int8_t cdd_ww_3_2;		/*
+					 * Byte offset 0x31, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_3_1;		/*
+					 * Byte offset 0x32, CSR Addr 0x54019, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 1.
+					 */
+	int8_t cdd_ww_3_0;		/*
+					 * Byte offset 0x33, CSR Addr 0x54019, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_2_3;		/*
+					 * Byte offset 0x34, CSR Addr 0x5401a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_2_1;		/*
+					 * Byte offset 0x35, CSR Addr 0x5401a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 1.
+					 */
+	int8_t cdd_ww_2_0;		/*
+					 * Byte offset 0x36, CSR Addr 0x5401b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_1_3;		/*
+					 * Byte offset 0x37, CSR Addr 0x5401b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_1_2;		/*
+					 * Byte offset 0x38, CSR Addr 0x5401c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_1_0;		/*
+					 * Byte offset 0x39, CSR Addr 0x5401c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_0_3;		/*
+					 * Byte offset 0x3a, CSR Addr 0x5401d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_0_2;		/*
+					 * Byte offset 0x3b, CSR Addr 0x5401d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_0_1;		/*
+					 * Byte offset 0x3c, CSR Addr 0x5401e, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 1.
+					 */
+	int8_t cdd_rw_3_3;		/*
+					 * Byte offset 0x3d, CSR Addr 0x5401e, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_3_2;		/*
+					 * Byte offset 0x3e, CSR Addr 0x5401f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_3_1;		/*
+					 * Byte offset 0x3f, CSR Addr 0x5401f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_3_0;		/*
+					 * Byte offset 0x40, CSR Addr 0x54020, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_2_3;		/*
+					 * Byte offset 0x41, CSR Addr 0x54020, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_2_2;		/*
+					 * Byte offset 0x42, CSR Addr 0x54021, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_2_1;		/*
+					 * Byte offset 0x43, CSR Addr 0x54021, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_2_0;		/*
+					 * Byte offset 0x44, CSR Addr 0x54022, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_1_3;		/*
+					 * Byte offset 0x45, CSR Addr 0x54022, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_1_2;		/*
+					 * Byte offset 0x46, CSR Addr 0x54023, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_1_1;		/*
+					 * Byte offset 0x47, CSR Addr 0x54023, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_1_0;		/*
+					 * Byte offset 0x48, CSR Addr 0x54024, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_0_3;		/*
+					 * Byte offset 0x49, CSR Addr 0x54024, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_0_2;		/*
+					 * Byte offset 0x4a, CSR Addr 0x54025, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_0_1;		/*
+					 * Byte offset 0x4b, CSR Addr 0x54025, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_0_0;		/*
+					 * Byte offset 0x4c, CSR Addr 0x54026, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_3_3;		/*
+					 * Byte offset 0x4d, CSR Addr 0x54026, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_3_2;		/*
+					 * Byte offset 0x4e, CSR Addr 0x54027, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_3_1;		/*
+					 * Byte offset 0x4f, CSR Addr 0x54027, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_3_0;		/*
+					 * Byte offset 0x50, CSR Addr 0x54028, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_2_3;		/*
+					 * Byte offset 0x51, CSR Addr 0x54028, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_2_2;		/*
+					 * Byte offset 0x52, CSR Addr 0x54029, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_2_1;		/*
+					 * Byte offset 0x53, CSR Addr 0x54029, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_2_0;		/*
+					 * Byte offset 0x54, CSR Addr 0x5402a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_1_3;		/*
+					 * Byte offset 0x55, CSR Addr 0x5402a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_1_2;		/*
+					 * Byte offset 0x56, CSR Addr 0x5402b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_1_1;		/*
+					 * Byte offset 0x57, CSR Addr 0x5402b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_1_0;		/*
+					 * Byte offset 0x58, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_0_3;		/*
+					 * Byte offset 0x59, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_0_2;		/*
+					 * Byte offset 0x5a, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_0_1;		/*
+					 * Byte offset 0x5b, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_0_0;		/*
+					 * Byte offset 0x5c, CSR Addr 0x5402e, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 0.
+					 */
+	uint8_t reserved5d;		/*
+					 * Byte offset 0x5d, CSR Addr 0x5402e, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for DDR4:
+					 * By default, if this parameter is 0, the offset applied at
+					 * the end of DDR4 RxEn training resulting in the trained
+					 * RxEnDly is 3/8 of the RX preamble width; if reserved5D is
+					 * non zero, this offset is used instead (in fine step).
+					 */
+	uint16_t mr0;			/*
+					 * Byte offset 0x5e, CSR Addr 0x5402f, Direction=In
+					 * Value of DDR mode register mr0 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr1;			/*
+					 * Byte offset 0x60, CSR Addr 0x54030, Direction=In
+					 * Value of DDR mode register mr1 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr2;			/*
+					 * Byte offset 0x62, CSR Addr 0x54031, Direction=In
+					 * Value of DDR mode register mr2 for all ranks for current
+					 * pstate.
+					 */
+	uint8_t reserved64;		/*
+					 * Byte offset 0x64, CSR Addr 0x54032, Direction=In
+					 * Reserved64[0] = protect memory reset
+					 *   0x0 = dfi_reset_n cannot control CP_MEMRESET_L to
+					 *	   devices after training. (Default value)
+					 *   0x1 = dfi_reset_n can control CP_MEMRESET_L to
+					 *	   devices after training.
+					 *
+					 * Reserved64[7:1] RFU, must be zero
+					 */
+	uint8_t reserved65;		/*
+					 * Byte offset 0x65, CSR Addr 0x54032, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved66;		/*
+					 * Byte offset 0x66, CSR Addr 0x54033, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved67;		/*
+					 * Byte offset 0x67, CSR Addr 0x54033, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved68;		/*
+					 * Byte offset 0x68, CSR Addr 0x54034, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved69;		/*
+					 * Byte offset 0x69, CSR Addr 0x54034, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6a;		/*
+					 * Byte offset 0x6a, CSR Addr 0x54035, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6b;		/*
+					 * Byte offset 0x6b, CSR Addr 0x54035, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6c;		/*
+					 * Byte offset 0x6c, CSR Addr 0x54036, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6d;		/*
+					 * Byte offset 0x6d, CSR Addr 0x54036, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6e;		/*
+					 * Byte offset 0x6e, CSR Addr 0x54037, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6f;		/*
+					 * Byte offset 0x6f, CSR Addr 0x54037, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved70;		/*
+					 * Byte offset 0x70, CSR Addr 0x54038, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved71;		/*
+					 * Byte offset 0x71, CSR Addr 0x54038, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved72;		/*
+					 * Byte offset 0x72, CSR Addr 0x54039, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved73;		/*
+					 * Byte offset 0x73, CSR Addr 0x54039, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t acsmodtctrl0;		/*
+					 * Byte offset 0x74, CSR Addr 0x5403a, Direction=In
+					 * Odt pattern for accesses targeting rank 0. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl1;		/*
+					 * Byte offset 0x75, CSR Addr 0x5403a, Direction=In
+					 * Odt pattern for accesses targeting rank 1. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl2;		/*
+					 * Byte offset 0x76, CSR Addr 0x5403b, Direction=In
+					 * Odt pattern for accesses targeting rank 2. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl3;		/*
+					 * Byte offset 0x77, CSR Addr 0x5403b, Direction=In
+					 * Odt pattern for accesses targeting rank 3. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl4;		/*
+					 * Byte offset 0x78, CSR Addr 0x5403c, Direction=In
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t acsmodtctrl5;		/*
+					 * Byte offset 0x79, CSR Addr 0x5403c, Direction=In
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t acsmodtctrl6;		/*
+					 * Byte offset 0x7a, CSR Addr 0x5403d, Direction=In
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t acsmodtctrl7;		/*
+					 * Byte offset 0x7b, CSR Addr 0x5403d, Direction=In
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved7c;		/*
+					 * Byte offset 0x7c, CSR Addr 0x5403e, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved7d;		/*
+					 * Byte offset 0x7d, CSR Addr 0x5403e, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved7e;		/*
+					 * Byte offset 0x7e, CSR Addr 0x5403f, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved7f;		/*
+					 * Byte offset 0x7f, CSR Addr 0x5403f, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved80;		/*
+					 * Byte offset 0x80, CSR Addr 0x54040, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved81;		/*
+					 * Byte offset 0x81, CSR Addr 0x54040, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved82;		/*
+					 * Byte offset 0x82, CSR Addr 0x54041, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved83;		/*
+					 * Byte offset 0x83, CSR Addr 0x54041, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved84;		/* Byte offset 0x84, CSR Addr 0x54042, Direction=N/A */
+	uint8_t reserved85;		/* Byte offset 0x85, CSR Addr 0x54042, Direction=N/A */
+	uint8_t reserved86;		/* Byte offset 0x86, CSR Addr 0x54043, Direction=N/A */
+	uint8_t reserved87;		/* Byte offset 0x87, CSR Addr 0x54043, Direction=N/A */
+	uint8_t reserved88;		/* Byte offset 0x88, CSR Addr 0x54044, Direction=N/A */
+	uint8_t reserved89;		/* Byte offset 0x89, CSR Addr 0x54044, Direction=N/A */
+	uint8_t reserved8a;		/* Byte offset 0x8a, CSR Addr 0x54045, Direction=N/A */
+	uint8_t reserved8b;		/* Byte offset 0x8b, CSR Addr 0x54045, Direction=N/A */
+	uint8_t reserved8c;		/* Byte offset 0x8c, CSR Addr 0x54046, Direction=N/A */
+	uint8_t reserved8d;		/* Byte offset 0x8d, CSR Addr 0x54046, Direction=N/A */
+	uint8_t reserved8e;		/* Byte offset 0x8e, CSR Addr 0x54047, Direction=N/A */
+	uint8_t reserved8f;		/* Byte offset 0x8f, CSR Addr 0x54047, Direction=N/A */
+	uint8_t reserved90;		/* Byte offset 0x90, CSR Addr 0x54048, Direction=N/A */
+	uint8_t reserved91;		/* Byte offset 0x91, CSR Addr 0x54048, Direction=N/A */
+	uint8_t reserved92;		/* Byte offset 0x92, CSR Addr 0x54049, Direction=N/A */
+	uint8_t reserved93;		/* Byte offset 0x93, CSR Addr 0x54049, Direction=N/A */
+	uint8_t reserved94;		/* Byte offset 0x94, CSR Addr 0x5404a, Direction=N/A */
+	uint8_t reserved95;		/* Byte offset 0x95, CSR Addr 0x5404a, Direction=N/A */
+	uint8_t reserved96;		/* Byte offset 0x96, CSR Addr 0x5404b, Direction=N/A */
+	uint8_t reserved97;		/* Byte offset 0x97, CSR Addr 0x5404b, Direction=N/A */
+	uint8_t reserved98;		/* Byte offset 0x98, CSR Addr 0x5404c, Direction=N/A */
+	uint8_t reserved99;		/* Byte offset 0x99, CSR Addr 0x5404c, Direction=N/A */
+	uint8_t reserved9a;		/* Byte offset 0x9a, CSR Addr 0x5404d, Direction=N/A */
+	uint8_t reserved9b;		/* Byte offset 0x9b, CSR Addr 0x5404d, Direction=N/A */
+	uint8_t reserved9c;		/* Byte offset 0x9c, CSR Addr 0x5404e, Direction=N/A */
+	uint8_t reserved9d;		/* Byte offset 0x9d, CSR Addr 0x5404e, Direction=N/A */
+	uint8_t reserved9e;		/* Byte offset 0x9e, CSR Addr 0x5404f, Direction=N/A */
+	uint8_t reserved9f;		/* Byte offset 0x9f, CSR Addr 0x5404f, Direction=N/A */
+	uint8_t reserveda0;		/* Byte offset 0xa0, CSR Addr 0x54050, Direction=N/A */
+	uint8_t reserveda1;		/* Byte offset 0xa1, CSR Addr 0x54050, Direction=N/A */
+	uint8_t reserveda2;		/* Byte offset 0xa2, CSR Addr 0x54051, Direction=N/A */
+	uint8_t reserveda3;		/* Byte offset 0xa3, CSR Addr 0x54051, Direction=N/A */
+} __packed __aligned(2);
+
+#endif /* MNPMUSRAMMSGBLOCK_DDR3_H */
diff --git a/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr4.h b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr4.h
new file mode 100644
index 0000000..384650e
--- /dev/null
+++ b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr4.h
@@ -0,0 +1,2203 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MNPMUSRAMMSGBLOCK_DDR4_H
+#define MNPMUSRAMMSGBLOCK_DDR4_H
+
+/* DDR4U_1D training firmware message block structure
+ *
+ * Please refer to the Training Firmware App Note for futher information about
+ * the usage for Message Block.
+ */
+struct pmu_smb_ddr_1d {
+	uint8_t reserved00;		/*
+					 * Byte offset 0x00, CSR Addr 0x54000, Direction=In
+					 * reserved00[0:4] RFU, must be zero
+					 *
+					 * reserved00[5] = Train vrefDAC0 During Read Deskew
+					 *   0x1 = Read Deskew will begin by enabling and roughly
+					 *   training the phy's per-lane reference voltages.
+					 *   Training the vrefDACs CSRs will increase the maximum 1D
+					 *   training time by around half a millisecond, but will
+					 *   improve 1D training accuracy on systems with
+					 *   significant voltage-offsets between lane read eyes.
+					 *   0x0 = Read Deskew will assume the messageblock's
+					 *   phyVref setting will work for all lanes.
+					 *
+					 * reserved00[6] = Enable High Effort WrDQ1D
+					 *   0x1 = WrDQ1D will conditionally retry training at
+					 *   several extra RxClkDly Timings. This will increase the
+					 *   maximum 1D training time by up to 4 extra iterations of
+					 *   WrDQ1D. This is only required in systems that suffer
+					 *   from very large, asymmetric eye-collapse when receiving
+					 *   PRBS patterns.
+					 *   0x0 = WrDQ1D assume rxClkDly values found by SI
+					 *   Friendly RdDqs1D will work for receiving PRBS patterns
+					 *
+					 * reserved00[7] = Optimize for the special hard macros in
+					 * TSMC28.
+					 *   0x1 = set if the phy being trained was manufactured in
+					 *   any TSMC28 process node.
+					 *   0x0 = otherwise, when not training a TSMC28 phy, leave
+					 *   this field as 0.
+					 */
+	uint8_t msgmisc;		/*
+					 * Byte offset 0x01, CSR Addr 0x54000, Direction=In
+					 * Contains various global options for training.
+					 *
+					 * Bit fields:
+					 *
+					 * msgmisc[0] = MTESTEnable
+					 *   0x1 = Pulse primary digital test output bump at the end
+					 *   of each major training stage. This enables observation
+					 *   of training stage completion by observing the digital
+					 *   test output.
+					 *   0x0 = Do not pulse primary digital test output bump
+					 *
+					 * msgmisc[1] = SimulationOnlyReset
+					 *   0x1 = Verilog only simulation option to shorten
+					 *   duration of DRAM reset pulse length to 1ns.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use reset pulse length specified by JEDEC
+					 *   standard.
+					 *
+					 * msgmisc[2] = SimulationOnlyTraining
+					 *   0x1 = Verilog only simulation option to shorten the
+					 *   duration of the training steps by performing fewer
+					 *   iterations.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use standard training duration.
+					 *
+					 * msgmisc[3] = RFU, must be zero
+					 *   0x1 = Program user characterized Vref DQ values per
+					 *   DDR4 DRAM device. The message block vrefdqr*nib* fields
+					 *   must be populated with the desired per device Vref DQs
+					 *   when using this option. Note: this option is not
+					 *   applicable in 2D training because these values are
+					 *   explicitly trained in 2D.
+					 *   0x0 = Program Vref DQ for all DDR4 devices with the
+					 *   single value provided in mr6 message block field
+					 *
+					 * msgmisc[4] = Suppress streaming messages, including
+					 * assertions, regardless of hdtctrl setting.
+					 * Stage Completion messages, as well as training completion
+					 * and error messages are still sent depending on hdtctrl
+					 * setting.
+					 *
+					 * msgmisc[5] = PerByteMaxRdLat
+					 *   0x1 = Each DBYTE will return dfi_rddata_valid at the
+					 *   lowest possible latency. This may result in unaligned
+					 *   data between bytes to be returned to the DFI.
+					 *   0x0 = Every DBYTE will return dfi_rddata_valid
+					 *   simultaneously. This will ensure that data bytes will
+					 *   return aligned accesses to the DFI.
+					 *
+					 * msgmisc[6] = PartialRank (DDR3 UDIMM and DDR4 UDIMM only,
+					 * otherwise RFU, must be zero)
+					 *   0x1 = Support rank populated with a subset of byte, but
+					 *   where even-odd pair of rank support all the byte
+					 *   0x0 = All rank populated with all the byte (tyical
+					 *   configuration)
+					 *
+					 * msgmisc[7] RFU, must be zero
+					 *
+					 * Notes:
+					 *
+					 * - SimulationOnlyReset and SimulationOnlyTraining can be
+					 *   used to speed up simulation run times, and must never
+					 *   be used in real silicon. Some VIPs may have checks on
+					 *   DRAM reset parameters that may need to be disabled when
+					 *   using SimulationOnlyReset.
+					 */
+	uint16_t pmurevision;		/*
+					 * Byte offset 0x02, CSR Addr 0x54001, Direction=Out
+					 * PMU firmware revision ID
+					 * After training is run, this address will contain the
+					 * revision ID of the firmware.
+					 * Please reference this revision ID when filing support
+					 * cases.
+					 */
+	uint8_t pstate;			/*
+					 * Byte offset 0x04, CSR Addr 0x54002, Direction=In
+					 * Must be set to the target pstate to be trained
+					 *   0x0 = pstate 0
+					 *   0x1 = pstate 1
+					 *   0x2 = pstate 2
+					 *   0x3 = pstate 3
+					 *   All other encodings are reserved
+					 */
+	uint8_t pllbypassen;		/*
+					 * Byte offset 0x05, CSR Addr 0x54002, Direction=In
+					 * Set according to whether target pstate uses PHY PLL
+					 * bypass
+					 *   0x0 = PHY PLL is enabled for target pstate
+					 *   0x1 = PHY PLL is bypassed for target pstate
+					 */
+	uint16_t dramfreq;		/*
+					 * Byte offset 0x06, CSR Addr 0x54003, Direction=In
+					 * DDR data rate for the target pstate in units of MT/s.
+					 * For example enter 0x0640 for DDR1600.
+					 */
+	uint8_t dfifreqratio;		/*
+					 * Byte offset 0x08, CSR Addr 0x54004, Direction=In
+					 * Frequency ratio betwen DfiCtlClk and SDRAM memclk.
+					 *   0x1 = 1:1
+					 *   0x2 = 1:2
+					 *   0x4 = 1:4
+					 */
+	uint8_t bpznresval;		/*
+					 * Byte offset 0x09, CSR Addr 0x54004, Direction=In
+					 * Overwrite the value of precision resistor connected to
+					 * Phy BP_ZN
+					 *   0x00 = Do not program. Use current CSR value.
+					 *   0xf0 = 240 Ohm
+					 *   0x78 = 120 Ohm
+					 *   0x28 = 40 Ohm
+					 *   All other values are reserved.
+					 * It is recommended to set this to 0x00.
+					 */
+	uint8_t phyodtimpedance;	/*
+					 * Byte offset 0x0a, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the termination impedance in ohms
+					 * used by PHY during reads.
+					 *
+					 * 0x0 = Firmware skips programming (must be manually
+					 * programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal termination impedance values.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must determine the correct value
+					 * through SI simulation or other methods.
+					 */
+	uint8_t phydrvimpedance;	/*
+					 * Byte offset 0x0b, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the driver impedance in ohms used
+					 * by PHY during writes for all DBYTE drivers
+					 * (DQ/DM/DBI/DQS).
+					 *
+					 *   0x0 = Firmware skips programming (must be manually
+					 *   programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal R_on driver impedance values.
+					 *
+					 * For digital simulation, any value can be used that is not
+					 * Hi-Z. For silicon, the users must determine the correct
+					 * value through SI simulation or other methods.
+					 */
+	uint8_t phyvref;		/*
+					 * Byte offset 0x0c, CSR Addr 0x54006, Direction=In
+					 * Must be programmed with the Vref level to be used by the
+					 * PHY during reads
+					 *
+					 * The units of this field are a percentage of VDDQ
+					 * according to the following equation:
+					 *
+					 * Receiver Vref = VDDQ*phyvref[6:0]/128
+					 *
+					 * For example to set Vref at 0.75*VDDQ, set this field to
+					 * 0x60.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must calculate the analytical Vref by
+					 * using the impedances, terminations, and series resistance
+					 * present in the system.
+					 */
+	uint8_t dramtype;		/*
+					 * Byte offset 0x0d, CSR Addr 0x54006, Direction=In
+					 * Module Type:
+					 *   0x01 = Reserved
+					 *   0x02 = DDR4 unbuffered
+					 *   0x03 = Reserved
+					 *   0x04 = Reserved
+					 *   0x05 = Reserved
+					 */
+	uint8_t disableddbyte;		/*
+					 * Byte offset 0x0e, CSR Addr 0x54007, Direction=In
+					 * Bitmap to indicate which Dbyte are not connected (for
+					 * DByte 0 to 7):
+					 * Set disableddbyte[i] to 1 only to specify that DByte is
+					 * not need to be trained (DByte 8 can be disabled via
+					 * enableddqs setting)
+					 */
+	uint8_t enableddqs;		/*
+					 * Byte offset 0x0f, CSR Addr 0x54007, Direction=In
+					 * Total number of DQ bits enabled in PHY
+					 */
+	uint8_t cspresent;		/*
+					 * Byte offset 0x10, CSR Addr 0x54008, Direction=In
+					 * Indicates presence of DRAM at each chip select for PHY.
+					 * Each bit corresponds to a logical CS.
+					 *
+					 * If the bit is set to 1, the CS is connected to DRAM.
+					 * If the bit is set to 0, the CS is not connected to DRAM.
+					 *
+					 * cspresent[0] = CS0 is populated with DRAM
+					 * cspresent[1] = CS1 is populated with DRAM
+					 * cspresent[2] = CS2 is populated with DRAM
+					 * cspresent[3] = CS3 is populated with DRAM
+					 * cspresent[7:4] = Reserved (must be programmed to 0)
+					 */
+	uint8_t cspresentd0;		/*
+					 * Byte offset 0x11, CSR Addr 0x54008, Direction=In
+					 * The CS signals from field cspresent that are routed to
+					 * DIMM connector 0
+					 */
+	uint8_t cspresentd1;		/*
+					 * Byte offset 0x12, CSR Addr 0x54009, Direction=In
+					 * The CS signals from field cspresent that are routed to
+					 * DIMM connector 1
+					 */
+	uint8_t addrmirror;		/*
+					 * Byte offset 0x13, CSR Addr 0x54009, Direction=In
+					 * Corresponds to CS[3:0]
+					 *   1 = Address Mirror.
+					 *   0 = No Address Mirror.
+					 */
+	uint8_t cstestfail;		/*
+					 * Byte offset 0x14, CSR Addr 0x5400a, Direction=Out
+					 * This field will be set if training fails on any rank.
+					 *   0x0 = No failures
+					 *   non-zero = one or more ranks failed training
+					 */
+	uint8_t phycfg;			/*
+					 * Byte offset 0x15, CSR Addr 0x5400a, Direction=In
+					 * Additional mode bits.
+					 *
+					 * Bit fields:
+					 * [0] SlowAccessMode:
+					 *   1 = 2T Address Timing.
+					 *   0 = 1T Address Timing.
+					 * [7-1] RFU, must be zero
+					 *
+					 * WARNING: In case of DDR4 Geardown Mode (mr3[A3] == 1),
+					 * phycfg[0] must be 0.
+					 */
+	uint16_t sequencectrl;		/*
+					 * Byte offset 0x16, CSR Addr 0x5400b, Direction=In
+					 * Controls the training steps to be run. Each bit
+					 * corresponds to a training step.
+					 *
+					 * If the bit is set to 1, the training step will run.
+					 * If the bit is set to 0, the training step will be
+					 * skipped.
+					 *
+					 * Training step to bit mapping:
+					 * sequencectrl[0] = Run DevInit - Device/phy
+					 *		     initialization. Should always be set.
+					 * sequencectrl[1] = Run WrLvl - Write leveling
+					 * sequencectrl[2] = Run RxEn - Read gate training
+					 * sequencectrl[3] = Run RdDQS1D - 1d read dqs training
+					 * sequencectrl[4] = Run WrDQ1D - 1d write dq training
+					 * sequencectrl[5] = RFU, must be zero
+					 * sequencectrl[6] = RFU, must be zero
+					 * sequencectrl[7] = RFU, must be zero
+					 * sequencectrl[8] = Run RdDeskew - Per lane read dq deskew
+					 *		     training
+					 * sequencectrl[9] = Run MxRdLat - Max read latency training
+					 * sequencectrl[10] = Run Reserved
+					 * sequencectrl[11] = Run Reserved
+					 * sequencectrl[12] = Run Reserved
+					 * sequencectrl[13] = Run Reserved
+					 * sequencectrl[15-14] = RFU, must be zero
+					 */
+	uint8_t hdtctrl;		/*
+					 * Byte offset 0x18, CSR Addr 0x5400c, Direction=In
+					 * To control the total number of debug messages, a
+					 * verbosity subfield (hdtctrl, Hardware Debug Trace
+					 * Control) exists in the message block. Every message has a
+					 * verbosity level associated with it, and as the hdtctrl
+					 * value is increased, less important s messages stop being
+					 * sent through the mailboxes. The meanings of several major
+					 * hdtctrl thresholds are explained below:
+					 *
+					 *   0x04 = Maximal debug messages (e.g., Eye contours)
+					 *   0x05 = Detailed debug messages (e.g. Eye delays)
+					 *   0x0A = Coarse debug messages (e.g. rank information)
+					 *   0xC8 = Stage completion
+					 *   0xC9 = Assertion messages
+					 *   0xFF = Firmware completion messages only
+					 */
+	uint8_t reserved19;		/* Byte offset 0x19, CSR Addr 0x5400c, Direction=N/A */
+	uint8_t reserved1a;		/* Byte offset 0x1a, CSR Addr 0x5400d, Direction=N/A */
+	uint8_t share2dvrefresult;	/*
+					 * Byte offset 0x1b, CSR Addr 0x5400d, Direction=In
+					 * Bitmap that designates the phy's vref source for every
+					 * pstate
+					 * If share2dvrefresult[x] = 0, then after 2D training,
+					 * pstate x will continue using the phyVref provided in
+					 * pstate x's 1D messageblock.
+					 * If share2dvrefresult[x] = 1, then after 2D training,
+					 * pstate x will use the per-lane VrefDAC0/1 CSRs trained by
+					 * 2d training.
+					 */
+	uint8_t reserved1c;		/* Byte offset 0x1c, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1d;		/* Byte offset 0x1d, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1e;		/*
+					 * Byte offset 0x1e, CSR Addr 0x5400f, Direction=In
+					 * Input for constraining the range of vref(DQ) values
+					 * training will collect data for, usually reducing training
+					 * time. However, too large of a voltage range may cause
+					 * longer 2D training times while too small of a voltage
+					 * range may truncate passing regions. When in doubt, leave
+					 * this field set to 0.
+					 * Used by 2D training in: Rd2D, Wr2D
+					 *
+					 * reserved1E[0-3]: Rd2D Voltage Range
+					 *   0 = Training will search all phy vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from phyVref
+					 *   2 = limit to +/-4 %VDDQ from phyVref
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from phyVref
+					 *
+					 * reserved1E[4-7]: Wr2D Voltage Range
+					 *   0 = Training will search all dram vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from mr6
+					 *   2 = limit to +/-4 %VDDQ from mr6
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from mr6
+					 */
+	uint8_t reserved1f;		/*
+					 * Byte offset 0x1f, CSR Addr 0x5400f, Direction=In
+					 * Extended training option:
+					 *
+					 * reserved1F[1:0]: Configured RxClkDly offset try during
+					 * WrDq1D high-effort (i.e., when reserved00[6] is set)
+					 *   0: -8, +8, -16, +16
+					 *   1: -4, +4, -8, +8, -12, +12, -16, +16
+					 *   2: -2, +2, -4, +4, -6, +6, -8, +8
+					 *   3: -2, +2, -4, +4, -6, +6, -8, +8, -10, +10, -12, +12,
+					 *      -14, +14, -16, +16
+					 *
+					 * reserved1F[2]: When set, execute again WrDq1D after
+					 * RdDqs1D PRBS
+					 * reserved1F[3]: When set redo RdDeskew with PRBS after
+					 * (first) WrDqs1D
+					 * reserved1F[7:4]: This field is reserved and must be
+					 * programmed to 0x00.
+					 */
+	uint8_t reserved20;		/*
+					 * Byte offset 0x20, CSR Addr 0x54010, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for Reserved:
+					 * Reserved MREP assume raising edge is found when
+					 * reserved20[3:0]+3 consecutive 1 are received during MREP
+					 * fine delay swept; reserved20[6:0] thus permits to
+					 * increase tolerance for noisy system. And if reserved20[7]
+					 * is set, MREP training is failing if no raising edge is
+					 * found (otherwise the raising edge is assume close to
+					 * delay 0).
+					 */
+	uint8_t reserved21;		/*
+					 * Byte offset 0x21, CSR Addr 0x54010, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for Reserved:
+					 * Reserved DWL assume raising edge is found when
+					 * reserved21[3:0]+3 consecutive 1 are received during DWL
+					 * fine delay swept; reserved21[6:0] thus permits to
+					 * increase tolerance for noisy system. And if reserved21[7]
+					 * is set, DWL training is failing if no raising edge is
+					 * found (otherwise the raising edge is assume close to
+					 * delay 0).
+					 */
+	uint16_t phyconfigoverride;	/*
+					 * Byte offset 0x22, CSR Addr 0x54011, Direction=In
+					 * Override PhyConfig csr.
+					 *   0x0: Use hardware csr value for PhyConfing
+					 *   (recommended)
+					 *   Other values: Use value for PhyConfig instead of
+					 *   Hardware value.
+					 */
+	uint8_t dfimrlmargin;		/*
+					 * Byte offset 0x24, CSR Addr 0x54012, Direction=In
+					 * Margin added to smallest passing trained DFI Max Read
+					 * Latency value, in units of DFI clocks. Recommended to be
+					 * >= 1.
+					 */
+	int8_t cdd_rr_3_2;		/*
+					 * Byte offset 0x25, CSR Addr 0x54012, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 2.
+					 */
+	int8_t cdd_rr_3_1;		/*
+					 * Byte offset 0x26, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 1.
+					 */
+	int8_t cdd_rr_3_0;		/*
+					 * Byte offset 0x27, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 0.
+					 */
+	int8_t cdd_rr_2_3;		/*
+					 * Byte offset 0x28, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 3.
+					 */
+	int8_t cdd_rr_2_1;		/*
+					 * Byte offset 0x29, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 1.
+					 */
+	int8_t cdd_rr_2_0;		/*
+					 * Byte offset 0x2a, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 0.
+					 */
+	int8_t cdd_rr_1_3;		/*
+					 * Byte offset 0x2b, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 3.
+					 */
+	int8_t cdd_rr_1_2;		/*
+					 * Byte offset 0x2c, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 2.
+					 */
+	int8_t cdd_rr_1_0;		/*
+					 * Byte offset 0x2d, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 0.
+					 */
+	int8_t cdd_rr_0_3;		/*
+					 * Byte offset 0x2e, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 3.
+					 */
+	int8_t cdd_rr_0_2;		/*
+					 * Byte offset 0x2f, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 2.
+					 */
+	int8_t cdd_rr_0_1;		/*
+					 * Byte offset 0x30, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 1.
+					 */
+	int8_t cdd_ww_3_2;		/*
+					 * Byte offset 0x31, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_3_1;		/*
+					 * Byte offset 0x32, CSR Addr 0x54019, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 1.
+					 */
+	int8_t cdd_ww_3_0;		/*
+					 * Byte offset 0x33, CSR Addr 0x54019, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_2_3;		/*
+					 * Byte offset 0x34, CSR Addr 0x5401a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_2_1;		/*
+					 * Byte offset 0x35, CSR Addr 0x5401a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 1.
+					 */
+	int8_t cdd_ww_2_0;		/*
+					 * Byte offset 0x36, CSR Addr 0x5401b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_1_3;		/*
+					 * Byte offset 0x37, CSR Addr 0x5401b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_1_2;		/*
+					 * Byte offset 0x38, CSR Addr 0x5401c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_1_0;		/*
+					 * Byte offset 0x39, CSR Addr 0x5401c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_0_3;		/*
+					 * Byte offset 0x3a, CSR Addr 0x5401d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_0_2;		/*
+					 * Byte offset 0x3b, CSR Addr 0x5401d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_0_1;		/*
+					 * Byte offset 0x3c, CSR Addr 0x5401e, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 1.
+					 */
+	int8_t cdd_rw_3_3;		/*
+					 * Byte offset 0x3d, CSR Addr 0x5401e, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_3_2;		/*
+					 * Byte offset 0x3e, CSR Addr 0x5401f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_3_1;		/*
+					 * Byte offset 0x3f, CSR Addr 0x5401f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_3_0;		/*
+					 * Byte offset 0x40, CSR Addr 0x54020, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_2_3;		/*
+					 * Byte offset 0x41, CSR Addr 0x54020, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_2_2;		/*
+					 * Byte offset 0x42, CSR Addr 0x54021, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_2_1;		/*
+					 * Byte offset 0x43, CSR Addr 0x54021, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_2_0;		/*
+					 * Byte offset 0x44, CSR Addr 0x54022, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_1_3;		/*
+					 * Byte offset 0x45, CSR Addr 0x54022, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_1_2;		/*
+					 * Byte offset 0x46, CSR Addr 0x54023, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_1_1;		/*
+					 * Byte offset 0x47, CSR Addr 0x54023, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_1_0;		/*
+					 * Byte offset 0x48, CSR Addr 0x54024, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_0_3;		/*
+					 * Byte offset 0x49, CSR Addr 0x54024, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_0_2;		/*
+					 * Byte offset 0x4a, CSR Addr 0x54025, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_0_1;		/*
+					 * Byte offset 0x4b, CSR Addr 0x54025, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_0_0;		/*
+					 * Byte offset 0x4c, CSR Addr 0x54026, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_3_3;		/*
+					 * Byte offset 0x4d, CSR Addr 0x54026, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_3_2;		/*
+					 * Byte offset 0x4e, CSR Addr 0x54027, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_3_1;		/*
+					 * Byte offset 0x4f, CSR Addr 0x54027, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_3_0;		/*
+					 * Byte offset 0x50, CSR Addr 0x54028, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_2_3;		/*
+					 * Byte offset 0x51, CSR Addr 0x54028, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_2_2;		/*
+					 * Byte offset 0x52, CSR Addr 0x54029, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_2_1;		/*
+					 * Byte offset 0x53, CSR Addr 0x54029, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_2_0;		/*
+					 * Byte offset 0x54, CSR Addr 0x5402a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_1_3;		/*
+					 * Byte offset 0x55, CSR Addr 0x5402a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_1_2;		/*
+					 * Byte offset 0x56, CSR Addr 0x5402b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_1_1;		/*
+					 * Byte offset 0x57, CSR Addr 0x5402b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_1_0;		/*
+					 * Byte offset 0x58, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_0_3;		/*
+					 * Byte offset 0x59, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_0_2;		/*
+					 * Byte offset 0x5a, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_0_1;		/*
+					 * Byte offset 0x5b, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_0_0;		/*
+					 * Byte offset 0x5c, CSR Addr 0x5402e, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 0.
+					 */
+	uint8_t reserved5d;		/*
+					 * Byte offset 0x5d, CSR Addr 0x5402e, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for DDR4:
+					 * By default, if this parameter is 0, the offset applied at
+					 * the end of DDR4 RxEn training resulting in the trained
+					 * RxEnDly is 3/8 of the RX preamble width; if reserved5D is
+					 * non zero, this offset is used instead (in fine step).
+					 */
+	uint16_t mr0;			/*
+					 * Byte offset 0x5e, CSR Addr 0x5402f, Direction=In
+					 * Value of DDR mode register mr0 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr1;			/*
+					 * Byte offset 0x60, CSR Addr 0x54030, Direction=In
+					 * Value of DDR mode register mr1 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr2;			/*
+					 * Byte offset 0x62, CSR Addr 0x54031, Direction=In
+					 * Value of DDR mode register mr2 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr3;			/*
+					 * Byte offset 0x64, CSR Addr 0x54032, Direction=In
+					 * Value of DDR mode register mr3 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr4;			/*
+					 * Byte offset 0x66, CSR Addr 0x54033, Direction=In
+					 * Value of DDR mode register mr4 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr5;			/*
+					 * Byte offset 0x68, CSR Addr 0x54034, Direction=In
+					 * Value of DDR mode register mr5 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr6;			/*
+					 * Byte offset 0x6a, CSR Addr 0x54035, Direction=In
+					 * Value of DDR mode register mr6 for all ranks for current
+					 * pstate. Note: The initial VrefDq value and range must be
+					 * set in A6:A0.
+					 */
+	uint8_t x16present;		/*
+					 * Byte offset 0x6c, CSR Addr 0x54036, Direction=In
+					 * X16 device map. Corresponds to CS[3:0].
+					 * x16present[0] = CS0 is populated with X16 devices
+					 * x16present[1] = CS1 is populated with X16 devices
+					 * x16present[2] = CS2 is populated with X16 devices
+					 * x16present[3] = CS3 is populated with X16 devices
+					 * x16present[7:4] = Reserved (must be programmed to 0)
+					 *
+					 * Ranks may not contain mixed device types.
+					 */
+	uint8_t cssetupgddec;		/*
+					 * Byte offset 0x6d, CSR Addr 0x54036, Direction=In
+					 * controls timing of chip select signals when DDR4
+					 * gear-down mode is active
+					 *   0 - Leave delay of chip select timing group signal
+					 *   the same both before and after gear-down sync occurs
+					 *   1 - Add 1UI of delay to chip select timing group
+					 *   signals when geardown-mode is active. This allows CS
+					 *   signals to have equal setup and hold time in gear-down
+					 *   mode
+					 */
+	uint16_t rtt_nom_wr_park0;	/*
+					 * Byte offset 0x6e, CSR Addr 0x54037, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 0
+					 * DRAM:
+					 * rtt_nom_wr_park0[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park0[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 0
+					 * rtt_nom_wr_park0[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 0
+					 * rtt_nom_wr_park0[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 0
+					 */
+	uint16_t rtt_nom_wr_park1;	/*
+					 * Byte offset 0x70, CSR Addr 0x54038, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 1
+					 * DRAM:
+					 * rtt_nom_wr_park1[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park1[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 1
+					 * rtt_nom_wr_park1[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 1
+					 * rtt_nom_wr_park1[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 1
+					 */
+	uint16_t rtt_nom_wr_park2;	/*
+					 * Byte offset 0x72, CSR Addr 0x54039, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 2
+					 * DRAM:
+					 * rtt_nom_wr_park2[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park2[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 2
+					 * rtt_nom_wr_park2[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 2
+					 * rtt_nom_wr_park2[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 2
+					 */
+	uint16_t rtt_nom_wr_park3;	/*
+					 * Byte offset 0x74, CSR Addr 0x5403a, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 3
+					 * DRAM:
+					 * rtt_nom_wr_park3[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park3[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 3
+					 * rtt_nom_wr_park3[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 3
+					 * rtt_nom_wr_park3[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 3
+					 */
+	uint16_t rtt_nom_wr_park4;	/*
+					 * Byte offset 0x76, CSR Addr 0x5403b, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 4
+					 * DRAM:
+					 * rtt_nom_wr_park4[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park4[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 4
+					 * rtt_nom_wr_park4[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 4
+					 * rtt_nom_wr_park4[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 4
+					 */
+	uint16_t rtt_nom_wr_park5;	/*
+					 * Byte offset 0x78, CSR Addr 0x5403c, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 5
+					 * DRAM:
+					 * rtt_nom_wr_park5[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park5[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 5
+					 * rtt_nom_wr_park5[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 5
+					 * rtt_nom_wr_park5[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 5
+					 */
+	uint16_t rtt_nom_wr_park6;	/*
+					 * Byte offset 0x7a, CSR Addr 0x5403d, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 6
+					 * DRAM:
+					 * rtt_nom_wr_park6[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park6[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 6
+					 * rtt_nom_wr_park6[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 6
+					 * rtt_nom_wr_park6[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 6
+					 */
+	uint16_t rtt_nom_wr_park7;	/*
+					 * Byte offset 0x7c, CSR Addr 0x5403e, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 7
+					 * DRAM:
+					 * rtt_nom_wr_park7[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park7[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 7
+					 * rtt_nom_wr_park7[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 7
+					 * rtt_nom_wr_park7[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 7
+					 */
+	uint8_t acsmodtctrl0;		/*
+					 * Byte offset 0x7e, CSR Addr 0x5403f, Direction=In
+					 * Odt pattern for accesses targeting rank 0. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl1;		/*
+					 * Byte offset 0x7f, CSR Addr 0x5403f, Direction=In
+					 * Odt pattern for accesses targeting rank 1. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl2;		/*
+					 * Byte offset 0x80, CSR Addr 0x54040, Direction=In
+					 * Odt pattern for accesses targeting rank 2. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl3;		/*
+					 * Byte offset 0x81, CSR Addr 0x54040, Direction=In
+					 * Odt pattern for accesses targeting rank 3. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl4;		/*
+					 * Byte offset 0x82, CSR Addr 0x54041, Direction=In
+					 * Odt pattern for accesses targeting rank 4. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl5;		/*
+					 * Byte offset 0x83, CSR Addr 0x54041, Direction=In
+					 * Odt pattern for accesses targeting rank 5. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl6;		/*
+					 * Byte offset 0x84, CSR Addr 0x54042, Direction=In
+					 * Odt pattern for accesses targeting rank 6. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl7;		/*
+					 * Byte offset 0x85, CSR Addr 0x54042, Direction=In
+					 * Odt pattern for accesses targeting rank 7. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t vrefdqr0nib0;		/*
+					 * Byte offset 0x86, CSR Addr 0x54043, Direction=InOut
+					 * VrefDq for rank 0 nibble 0. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib1;		/*
+					 * Byte offset 0x87, CSR Addr 0x54043, Direction=InOut
+					 * VrefDq for rank 0 nibble 1. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib0 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib2;		/*
+					 * Byte offset 0x88, CSR Addr 0x54044, Direction=InOut
+					 * VrefDq for rank 0 nibble 2. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib0 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib3;		/*
+					 * Byte offset 0x89, CSR Addr 0x54044, Direction=InOut
+					 * VrefDq for rank 0 nibble 3. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib0 for x16 devices, or
+					 * vrefdqr0nib2 for x8 devices.
+					 */
+	uint8_t vrefdqr0nib4;		/*
+					 * Byte offset 0x8a, CSR Addr 0x54045, Direction=InOut
+					 * VrefDq for rank 0 nibble 4. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib5;		/*
+					 * Byte offset 0x8b, CSR Addr 0x54045, Direction=InOut
+					 * VrefDq for rank 0 nibble 5. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib4 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib6;		/*
+					 * Byte offset 0x8c, CSR Addr 0x54046, Direction=InOut
+					 * VrefDq for rank 0 nibble 6. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib4 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib7;		/*
+					 * Byte offset 0x8d, CSR Addr 0x54046, Direction=InOut
+					 * VrefDq for rank 0 nibble 7. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib4 for x16 devices,
+					 * or vrefdqr0nib6 for x8 devices.
+					 */
+	uint8_t vrefdqr0nib8;		/*
+					 * Byte offset 0x8e, CSR Addr 0x54047, Direction=InOut
+					 * VrefDq for rank 0 nibble 8. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib9;		/*
+					 * Byte offset 0x8f, CSR Addr 0x54047, Direction=InOut
+					 * VrefDq for rank 0 nibble 9. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib8 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib10;		/*
+					 * Byte offset 0x90, CSR Addr 0x54048, Direction=InOut
+					 * VrefDq for rank 0 nibble 10. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib8 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib11;		/*
+					 * Byte offset 0x91, CSR Addr 0x54048, Direction=InOut
+					 * VrefDq for rank 0 nibble 11. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib8 for x16 devices,
+					 * or vrefdqr0nib10 for x8 devices.
+					 */
+	uint8_t vrefdqr0nib12;		/*
+					 * Byte offset 0x92, CSR Addr 0x54049, Direction=InOut
+					 * VrefDq for rank 0 nibble 12. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib13;		/*
+					 * Byte offset 0x93, CSR Addr 0x54049, Direction=InOut
+					 * VrefDq for rank 0 nibble 13. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib12 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib14;		/*
+					 * Byte offset 0x94, CSR Addr 0x5404a, Direction=InOut
+					 * VrefDq for rank 0 nibble 14. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib12 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib15;		/*
+					 * Byte offset 0x95, CSR Addr 0x5404a, Direction=InOut
+					 * VrefDq for rank 0 nibble 15. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib12 for x16 devices,
+					 * or vrefdqr0nib14 for x8 devices.
+					 */
+	uint8_t vrefdqr0nib16;		/*
+					 * Byte offset 0x96, CSR Addr 0x5404b, Direction=InOut
+					 * VrefDq for rank 0 nibble 16. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib17;		/*
+					 * Byte offset 0x97, CSR Addr 0x5404b, Direction=InOut
+					 * VrefDq for rank 0 nibble 17. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib16 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib18;		/*
+					 * Byte offset 0x98, CSR Addr 0x5404c, Direction=InOut
+					 * VrefDq for rank 0 nibble 18. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib16 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib19;		/*
+					 * Byte offset 0x99, CSR Addr 0x5404c, Direction=InOut
+					 * VrefDq for rank 0 nibble 19. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib16 for x16 devices,
+					 * or vrefdqr0nib18 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib0;		/*
+					 * Byte offset 0x9a, CSR Addr 0x5404d, Direction=InOut
+					 * VrefDq for rank 1 nibble 0. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib1;		/*
+					 * Byte offset 0x9b, CSR Addr 0x5404d, Direction=InOut
+					 * VrefDq for rank 1 nibble 1. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib0 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib2;		/*
+					 * Byte offset 0x9c, CSR Addr 0x5404e, Direction=InOut
+					 * VrefDq for rank 1 nibble 2. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib0 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib3;		/*
+					 * Byte offset 0x9d, CSR Addr 0x5404e, Direction=InOut
+					 * VrefDq for rank 1 nibble 3. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib0 for x16 devices,
+					 * or vrefdqr1nib2 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib4;		/*
+					 * Byte offset 0x9e, CSR Addr 0x5404f, Direction=InOut
+					 * VrefDq for rank 1 nibble 4. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib5;		/*
+					 * Byte offset 0x9f, CSR Addr 0x5404f, Direction=InOut
+					 * VrefDq for rank 1 nibble 5. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib4 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib6;		/*
+					 * Byte offset 0xa0, CSR Addr 0x54050, Direction=InOut
+					 * VrefDq for rank 1 nibble 6. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib4 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib7;		/*
+					 * Byte offset 0xa1, CSR Addr 0x54050, Direction=InOut
+					 * VrefDq for rank 1 nibble 7. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib4 for x16 devices,
+					 * or vrefdqr1nib6 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib8;		/*
+					 * Byte offset 0xa2, CSR Addr 0x54051, Direction=InOut
+					 * VrefDq for rank 1 nibble 8. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib9;		/*
+					 * Byte offset 0xa3, CSR Addr 0x54051, Direction=InOut
+					 * VrefDq for rank 1 nibble 9. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib8 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib10;		/*
+					 * Byte offset 0xa4, CSR Addr 0x54052, Direction=InOut
+					 * VrefDq for rank 1 nibble 10. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib8 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib11;		/*
+					 * Byte offset 0xa5, CSR Addr 0x54052, Direction=InOut
+					 * VrefDq for rank 1 nibble 11. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib8 for x16 devices,
+					 * or vrefdqr1nib10 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib12;		/*
+					 * Byte offset 0xa6, CSR Addr 0x54053, Direction=InOut
+					 * VrefDq for rank 1 nibble 12. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib13;		/*
+					 * Byte offset 0xa7, CSR Addr 0x54053, Direction=InOut
+					 * VrefDq for rank 1 nibble 13. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib12 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib14;		/*
+					 * Byte offset 0xa8, CSR Addr 0x54054, Direction=InOut
+					 * VrefDq for rank 1 nibble 14. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib12 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib15;		/*
+					 * Byte offset 0xa9, CSR Addr 0x54054, Direction=InOut
+					 * VrefDq for rank 1 nibble 15. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib12 for x16 devices,
+					 * or vrefdqr1nib14 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib16;		/*
+					 * Byte offset 0xaa, CSR Addr 0x54055, Direction=InOut
+					 * VrefDq for rank 1 nibble 16. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib17;		/*
+					 * Byte offset 0xab, CSR Addr 0x54055, Direction=InOut
+					 * VrefDq for rank 1 nibble 17. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib16 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib18;		/*
+					 * Byte offset 0xac, CSR Addr 0x54056, Direction=InOut
+					 * VrefDq for rank 1 nibble 18. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib16 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib19;		/*
+					 * Byte offset 0xad, CSR Addr 0x54056, Direction=InOut
+					 * VrefDq for rank 1 nibble 19. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib16 for x16 devices,
+					 * or vrefdqr1nib18 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib0;		/*
+					 * Byte offset 0xae, CSR Addr 0x54057, Direction=InOut
+					 * VrefDq for rank 2 nibble 0. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib1;		/*
+					 * Byte offset 0xaf, CSR Addr 0x54057, Direction=InOut
+					 * VrefDq for rank 2 nibble 1. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib0 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib2;		/*
+					 * Byte offset 0xb0, CSR Addr 0x54058, Direction=InOut
+					 * VrefDq for rank 2 nibble 2. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib0 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib3;		/*
+					 * Byte offset 0xb1, CSR Addr 0x54058, Direction=InOut
+					 * VrefDq for rank 2 nibble 3. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib0 for x16 devices,
+					 * or vrefdqr2nib2 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib4;		/*
+					 * Byte offset 0xb2, CSR Addr 0x54059, Direction=InOut
+					 * VrefDq for rank 2 nibble 4. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib5;		/*
+					 * Byte offset 0xb3, CSR Addr 0x54059, Direction=InOut
+					 * VrefDq for rank 2 nibble 5. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib4 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib6;		/*
+					 * Byte offset 0xb4, CSR Addr 0x5405a, Direction=InOut
+					 * VrefDq for rank 2 nibble 6. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib4 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib7;		/*
+					 * Byte offset 0xb5, CSR Addr 0x5405a, Direction=InOut
+					 * VrefDq for rank 2 nibble 7. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib4 for x16 devices,
+					 * or vrefdqr2nib6 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib8;		/*
+					 * Byte offset 0xb6, CSR Addr 0x5405b, Direction=InOut
+					 * VrefDq for rank 2 nibble 8. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib9;		/*
+					 * Byte offset 0xb7, CSR Addr 0x5405b, Direction=InOut
+					 * VrefDq for rank 2 nibble 9. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib8 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib10;		/*
+					 * Byte offset 0xb8, CSR Addr 0x5405c, Direction=InOut
+					 * VrefDq for rank 2 nibble 10. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib8 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib11;		/*
+					 * Byte offset 0xb9, CSR Addr 0x5405c, Direction=InOut
+					 * VrefDq for rank 2 nibble 11. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib8 for x16 devices,
+					 * or vrefdqr2nib10 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib12;		/*
+					 * Byte offset 0xba, CSR Addr 0x5405d, Direction=InOut
+					 * VrefDq for rank 2 nibble 12. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib13;		/*
+					 * Byte offset 0xbb, CSR Addr 0x5405d, Direction=InOut
+					 * VrefDq for rank 2 nibble 13. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib12 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib14;		/*
+					 * Byte offset 0xbc, CSR Addr 0x5405e, Direction=InOut
+					 * VrefDq for rank 2 nibble 14. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib12 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib15;		/*
+					 * Byte offset 0xbd, CSR Addr 0x5405e, Direction=InOut
+					 * VrefDq for rank 2 nibble 15. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib12 for x16 devices,
+					 * or vrefdqr2nib14 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib16;		/*
+					 * Byte offset 0xbe, CSR Addr 0x5405f, Direction=InOut
+					 * VrefDq for rank 2 nibble 16. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib17;		/*
+					 * Byte offset 0xbf, CSR Addr 0x5405f, Direction=InOut
+					 * VrefDq for rank 2 nibble 17. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib16 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib18;		/*
+					 * Byte offset 0xc0, CSR Addr 0x54060, Direction=InOut
+					 * VrefDq for rank 2 nibble 18. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib16 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib19;		/*
+					 * Byte offset 0xc1, CSR Addr 0x54060, Direction=InOut
+					 * VrefDq for rank 2 nibble 19. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib16 for x16 devices,
+					 * or vrefdqr2nib18 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib0;		/*
+					 * Byte offset 0xc2, CSR Addr 0x54061, Direction=InOut
+					 * VrefDq for rank 3 nibble 0. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib1;		/*
+					 * Byte offset 0xc3, CSR Addr 0x54061, Direction=InOut
+					 * VrefDq for rank 3 nibble 1. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib0 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib2;		/*
+					 * Byte offset 0xc4, CSR Addr 0x54062, Direction=InOut
+					 * VrefDq for rank 3 nibble 2. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib0 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib3;		/*
+					 * Byte offset 0xc5, CSR Addr 0x54062, Direction=InOut
+					 * VrefDq for rank 3 nibble 3. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib0 for x16 devices,
+					 * or vrefdqr3nib2 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib4;		/*
+					 * Byte offset 0xc6, CSR Addr 0x54063, Direction=InOut
+					 * VrefDq for rank 3 nibble 4. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib5;		/*
+					 * Byte offset 0xc7, CSR Addr 0x54063, Direction=InOut
+					 * VrefDq for rank 3 nibble 5. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib4 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib6;		/*
+					 * Byte offset 0xc8, CSR Addr 0x54064, Direction=InOut
+					 * VrefDq for rank 3 nibble 6. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib4 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib7;		/*
+					 * Byte offset 0xc9, CSR Addr 0x54064, Direction=InOut
+					 * VrefDq for rank 3 nibble 7. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib4 for x16 devices,
+					 * or vrefdqr3nib6 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib8;		/*
+					 * Byte offset 0xca, CSR Addr 0x54065, Direction=InOut
+					 * VrefDq for rank 3 nibble 8. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib9;		/*
+					 * Byte offset 0xcb, CSR Addr 0x54065, Direction=InOut
+					 * VrefDq for rank 3 nibble 9. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib8 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib10;		/*
+					 * Byte offset 0xcc, CSR Addr 0x54066, Direction=InOut
+					 * VrefDq for rank 3 nibble 10. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib8 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib11;		/*
+					 * Byte offset 0xcd, CSR Addr 0x54066, Direction=InOut
+					 * VrefDq for rank 3 nibble 11. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib8 for x16 devices,
+					 * or vrefdqr3nib10 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib12;		/*
+					 * Byte offset 0xce, CSR Addr 0x54067, Direction=InOut
+					 * VrefDq for rank 3 nibble 12. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib13;		/*
+					 * Byte offset 0xcf, CSR Addr 0x54067, Direction=InOut
+					 * VrefDq for rank 3 nibble 13. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib12 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib14;		/*
+					 * Byte offset 0xd0, CSR Addr 0x54068, Direction=InOut
+					 * VrefDq for rank 3 nibble 14. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib12 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib15;		/*
+					 * Byte offset 0xd1, CSR Addr 0x54068, Direction=InOut
+					 * VrefDq for rank 3 nibble 15. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib12 for x16 devices,
+					 * or vrefdqr3nib14 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib16;		/*
+					 * Byte offset 0xd2, CSR Addr 0x54069, Direction=InOut
+					 * VrefDq for rank 3 nibble 16. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib17;		/*
+					 * Byte offset 0xd3, CSR Addr 0x54069, Direction=InOut
+					 * VrefDq for rank 3 nibble 17. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib16 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib18;		/*
+					 * Byte offset 0xd4, CSR Addr 0x5406a, Direction=InOut
+					 * VrefDq for rank 3 nibble 18. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib16 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib19;		/*
+					 * Byte offset 0xd5, CSR Addr 0x5406a, Direction=InOut
+					 * VrefDq for rank 3 nibble 19. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib16 for x16 devices,
+					 * or vrefdqr3nib18 for x8 devices.
+					 */
+	uint8_t reservedd6;		/* Byte offset 0xd6, CSR Addr 0x5406b, Direction=N/A */
+	uint8_t reservedd7;		/* Byte offset 0xd7, CSR Addr 0x5406b, Direction=N/A */
+	uint8_t reservedd8;		/* Byte offset 0xd8, CSR Addr 0x5406c, Direction=N/A */
+	uint8_t reservedd9;		/* Byte offset 0xd9, CSR Addr 0x5406c, Direction=N/A */
+	uint8_t reservedda;		/* Byte offset 0xda, CSR Addr 0x5406d, Direction=N/A */
+	uint8_t reserveddb;		/* Byte offset 0xdb, CSR Addr 0x5406d, Direction=N/A */
+	uint8_t reserveddc;		/* Byte offset 0xdc, CSR Addr 0x5406e, Direction=N/A */
+	uint8_t reserveddd;		/* Byte offset 0xdd, CSR Addr 0x5406e, Direction=N/A */
+	uint8_t reservedde;		/* Byte offset 0xde, CSR Addr 0x5406f, Direction=N/A */
+	uint8_t reserveddf;		/* Byte offset 0xdf, CSR Addr 0x5406f, Direction=N/A */
+	uint8_t reservede0;		/* Byte offset 0xe0, CSR Addr 0x54070, Direction=N/A */
+	uint8_t reservede1;		/* Byte offset 0xe1, CSR Addr 0x54070, Direction=N/A */
+	uint8_t reservede2;		/* Byte offset 0xe2, CSR Addr 0x54071, Direction=N/A */
+	uint8_t reservede3;		/* Byte offset 0xe3, CSR Addr 0x54071, Direction=N/A */
+	uint8_t reservede4;		/* Byte offset 0xe4, CSR Addr 0x54072, Direction=N/A */
+	uint8_t reservede5;		/* Byte offset 0xe5, CSR Addr 0x54072, Direction=N/A */
+	uint8_t reservede6;		/* Byte offset 0xe6, CSR Addr 0x54073, Direction=N/A */
+	uint8_t reservede7;		/* Byte offset 0xe7, CSR Addr 0x54073, Direction=N/A */
+	uint8_t reservede8;		/* Byte offset 0xe8, CSR Addr 0x54074, Direction=N/A */
+	uint8_t reservede9;		/* Byte offset 0xe9, CSR Addr 0x54074, Direction=N/A */
+	uint8_t reservedea;		/* Byte offset 0xea, CSR Addr 0x54075, Direction=N/A */
+	uint8_t reservedeb;		/* Byte offset 0xeb, CSR Addr 0x54075, Direction=N/A */
+	uint8_t reservedec;		/* Byte offset 0xec, CSR Addr 0x54076, Direction=N/A */
+	uint8_t reserveded;		/* Byte offset 0xed, CSR Addr 0x54076, Direction=N/A */
+	uint8_t reservedee;		/* Byte offset 0xee, CSR Addr 0x54077, Direction=N/A */
+	uint8_t reservedef;		/* Byte offset 0xef, CSR Addr 0x54077, Direction=N/A */
+	uint8_t reservedf0;		/* Byte offset 0xf0, CSR Addr 0x54078, Direction=N/A */
+	uint8_t reservedf1;		/* Byte offset 0xf1, CSR Addr 0x54078, Direction=N/A */
+	uint8_t reservedf2;		/* Byte offset 0xf2, CSR Addr 0x54079, Direction=N/A */
+	uint8_t reservedf3;		/* Byte offset 0xf3, CSR Addr 0x54079, Direction=N/A */
+	uint8_t reservedf4;		/* Byte offset 0xf4, CSR Addr 0x5407a, Direction=N/A */
+	uint8_t reservedf5;		/* Byte offset 0xf5, CSR Addr 0x5407a, Direction=N/A */
+	uint8_t reservedf6;		/* Byte offset 0xf6, CSR Addr 0x5407b, Direction=N/A */
+	uint8_t reservedf7;		/* Byte offset 0xf7, CSR Addr 0x5407b, Direction=N/A */
+	uint8_t reservedf8;		/* Byte offset 0xf8, CSR Addr 0x5407c, Direction=N/A */
+	uint8_t reservedf9;		/* Byte offset 0xf9, CSR Addr 0x5407c, Direction=N/A */
+	uint8_t reservedfa;		/* Byte offset 0xfa, CSR Addr 0x5407d, Direction=N/A */
+	uint8_t reservedfb;		/* Byte offset 0xfb, CSR Addr 0x5407d, Direction=N/A */
+	uint8_t reservedfc;		/* Byte offset 0xfc, CSR Addr 0x5407e, Direction=N/A */
+	uint8_t reservedfd;		/* Byte offset 0xfd, CSR Addr 0x5407e, Direction=N/A */
+	uint8_t reservedfe;		/* Byte offset 0xfe, CSR Addr 0x5407f, Direction=N/A */
+	uint8_t reservedff;		/* Byte offset 0xff, CSR Addr 0x5407f, Direction=N/A */
+	uint8_t reserved100;		/* Byte offset 0x100, CSR Addr 0x54080, Direction=N/A */
+	uint8_t reserved101;		/* Byte offset 0x101, CSR Addr 0x54080, Direction=N/A */
+	uint8_t reserved102;		/* Byte offset 0x102, CSR Addr 0x54081, Direction=N/A */
+	uint8_t reserved103;		/* Byte offset 0x103, CSR Addr 0x54081, Direction=N/A */
+	uint8_t reserved104;		/* Byte offset 0x104, CSR Addr 0x54082, Direction=N/A */
+	uint8_t reserved105;		/* Byte offset 0x105, CSR Addr 0x54082, Direction=N/A */
+	uint8_t reserved106;		/* Byte offset 0x106, CSR Addr 0x54083, Direction=N/A */
+	uint8_t reserved107;		/* Byte offset 0x107, CSR Addr 0x54083, Direction=N/A */
+	uint8_t reserved108;		/* Byte offset 0x108, CSR Addr 0x54084, Direction=N/A */
+	uint8_t reserved109;		/* Byte offset 0x109, CSR Addr 0x54084, Direction=N/A */
+	uint8_t reserved10a;		/* Byte offset 0x10a, CSR Addr 0x54085, Direction=N/A */
+	uint8_t reserved10b;		/* Byte offset 0x10b, CSR Addr 0x54085, Direction=N/A */
+	uint8_t reserved10c;		/* Byte offset 0x10c, CSR Addr 0x54086, Direction=N/A */
+	uint8_t reserved10d;		/* Byte offset 0x10d, CSR Addr 0x54086, Direction=N/A */
+	uint8_t reserved10e;		/* Byte offset 0x10e, CSR Addr 0x54087, Direction=N/A */
+	uint8_t reserved10f;		/* Byte offset 0x10f, CSR Addr 0x54087, Direction=N/A */
+	uint8_t reserved110;		/* Byte offset 0x110, CSR Addr 0x54088, Direction=N/A */
+	uint8_t reserved111;		/* Byte offset 0x111, CSR Addr 0x54088, Direction=N/A */
+	uint8_t reserved112;		/* Byte offset 0x112, CSR Addr 0x54089, Direction=N/A */
+	uint8_t reserved113;		/* Byte offset 0x113, CSR Addr 0x54089, Direction=N/A */
+	uint8_t reserved114;		/* Byte offset 0x114, CSR Addr 0x5408a, Direction=N/A */
+	uint8_t reserved115;		/* Byte offset 0x115, CSR Addr 0x5408a, Direction=N/A */
+	uint8_t reserved116;		/* Byte offset 0x116, CSR Addr 0x5408b, Direction=N/A */
+	uint8_t reserved117;		/* Byte offset 0x117, CSR Addr 0x5408b, Direction=N/A */
+	uint8_t reserved118;		/* Byte offset 0x118, CSR Addr 0x5408c, Direction=N/A */
+	uint8_t reserved119;		/* Byte offset 0x119, CSR Addr 0x5408c, Direction=N/A */
+	uint8_t reserved11a;		/* Byte offset 0x11a, CSR Addr 0x5408d, Direction=N/A */
+	uint8_t reserved11b;		/* Byte offset 0x11b, CSR Addr 0x5408d, Direction=N/A */
+	uint8_t reserved11c;		/* Byte offset 0x11c, CSR Addr 0x5408e, Direction=N/A */
+	uint8_t reserved11d;		/* Byte offset 0x11d, CSR Addr 0x5408e, Direction=N/A */
+	uint8_t reserved11e;		/* Byte offset 0x11e, CSR Addr 0x5408f, Direction=N/A */
+	uint8_t reserved11f;		/* Byte offset 0x11f, CSR Addr 0x5408f, Direction=N/A */
+	uint8_t reserved120;		/* Byte offset 0x120, CSR Addr 0x54090, Direction=N/A */
+	uint8_t reserved121;		/* Byte offset 0x121, CSR Addr 0x54090, Direction=N/A */
+	uint8_t reserved122;		/* Byte offset 0x122, CSR Addr 0x54091, Direction=N/A */
+	uint8_t reserved123;		/* Byte offset 0x123, CSR Addr 0x54091, Direction=N/A */
+	uint8_t reserved124;		/* Byte offset 0x124, CSR Addr 0x54092, Direction=N/A */
+	uint8_t reserved125;		/* Byte offset 0x125, CSR Addr 0x54092, Direction=N/A */
+	uint8_t reserved126;		/* Byte offset 0x126, CSR Addr 0x54093, Direction=N/A */
+	uint8_t reserved127;		/* Byte offset 0x127, CSR Addr 0x54093, Direction=N/A */
+	uint8_t reserved128;		/* Byte offset 0x128, CSR Addr 0x54094, Direction=N/A */
+	uint8_t reserved129;		/* Byte offset 0x129, CSR Addr 0x54094, Direction=N/A */
+	uint8_t reserved12a;		/* Byte offset 0x12a, CSR Addr 0x54095, Direction=N/A */
+	uint8_t reserved12b;		/* Byte offset 0x12b, CSR Addr 0x54095, Direction=N/A */
+	uint8_t reserved12c;		/* Byte offset 0x12c, CSR Addr 0x54096, Direction=N/A */
+	uint8_t reserved12d;		/* Byte offset 0x12d, CSR Addr 0x54096, Direction=N/A */
+	uint8_t reserved12e;		/* Byte offset 0x12e, CSR Addr 0x54097, Direction=N/A */
+	uint8_t reserved12f;		/* Byte offset 0x12f, CSR Addr 0x54097, Direction=N/A */
+	uint8_t reserved130;		/* Byte offset 0x130, CSR Addr 0x54098, Direction=N/A */
+	uint8_t reserved131;		/* Byte offset 0x131, CSR Addr 0x54098, Direction=N/A */
+	uint8_t reserved132;		/* Byte offset 0x132, CSR Addr 0x54099, Direction=N/A */
+	uint8_t reserved133;		/* Byte offset 0x133, CSR Addr 0x54099, Direction=N/A */
+	uint8_t reserved134;		/* Byte offset 0x134, CSR Addr 0x5409a, Direction=N/A */
+	uint8_t reserved135;		/* Byte offset 0x135, CSR Addr 0x5409a, Direction=N/A */
+	uint8_t reserved136;		/* Byte offset 0x136, CSR Addr 0x5409b, Direction=N/A */
+	uint8_t reserved137;		/* Byte offset 0x137, CSR Addr 0x5409b, Direction=N/A */
+	uint8_t reserved138;		/* Byte offset 0x138, CSR Addr 0x5409c, Direction=N/A */
+	uint8_t reserved139;		/* Byte offset 0x139, CSR Addr 0x5409c, Direction=N/A */
+	uint8_t reserved13a;		/* Byte offset 0x13a, CSR Addr 0x5409d, Direction=N/A */
+	uint8_t reserved13b;		/* Byte offset 0x13b, CSR Addr 0x5409d, Direction=N/A */
+	uint8_t reserved13c;		/* Byte offset 0x13c, CSR Addr 0x5409e, Direction=N/A */
+	uint8_t reserved13d;		/* Byte offset 0x13d, CSR Addr 0x5409e, Direction=N/A */
+	uint8_t reserved13e;		/* Byte offset 0x13e, CSR Addr 0x5409f, Direction=N/A */
+	uint8_t reserved13f;		/* Byte offset 0x13f, CSR Addr 0x5409f, Direction=N/A */
+	uint8_t reserved140;		/* Byte offset 0x140, CSR Addr 0x540a0, Direction=N/A */
+	uint8_t reserved141;		/* Byte offset 0x141, CSR Addr 0x540a0, Direction=N/A */
+	uint8_t reserved142;		/* Byte offset 0x142, CSR Addr 0x540a1, Direction=N/A */
+	uint8_t reserved143;		/* Byte offset 0x143, CSR Addr 0x540a1, Direction=N/A */
+	uint8_t reserved144;		/* Byte offset 0x144, CSR Addr 0x540a2, Direction=N/A */
+	uint8_t reserved145;		/* Byte offset 0x145, CSR Addr 0x540a2, Direction=N/A */
+	uint8_t reserved146;		/* Byte offset 0x146, CSR Addr 0x540a3, Direction=N/A */
+	uint8_t reserved147;		/* Byte offset 0x147, CSR Addr 0x540a3, Direction=N/A */
+	uint8_t reserved148;		/* Byte offset 0x148, CSR Addr 0x540a4, Direction=N/A */
+	uint8_t reserved149;		/* Byte offset 0x149, CSR Addr 0x540a4, Direction=N/A */
+	uint8_t reserved14a;		/* Byte offset 0x14a, CSR Addr 0x540a5, Direction=N/A */
+	uint8_t reserved14b;		/* Byte offset 0x14b, CSR Addr 0x540a5, Direction=N/A */
+	uint8_t reserved14c;		/* Byte offset 0x14c, CSR Addr 0x540a6, Direction=N/A */
+	uint8_t reserved14d;		/* Byte offset 0x14d, CSR Addr 0x540a6, Direction=N/A */
+	uint8_t reserved14e;		/* Byte offset 0x14e, CSR Addr 0x540a7, Direction=N/A */
+	uint8_t reserved14f;		/* Byte offset 0x14f, CSR Addr 0x540a7, Direction=N/A */
+	uint8_t reserved150;		/* Byte offset 0x150, CSR Addr 0x540a8, Direction=N/A */
+	uint8_t reserved151;		/* Byte offset 0x151, CSR Addr 0x540a8, Direction=N/A */
+	uint8_t reserved152;		/* Byte offset 0x152, CSR Addr 0x540a9, Direction=N/A */
+	uint8_t reserved153;		/* Byte offset 0x153, CSR Addr 0x540a9, Direction=N/A */
+	uint8_t reserved154;		/* Byte offset 0x154, CSR Addr 0x540aa, Direction=N/A */
+	uint8_t reserved155;		/* Byte offset 0x155, CSR Addr 0x540aa, Direction=N/A */
+	uint8_t reserved156;		/* Byte offset 0x156, CSR Addr 0x540ab, Direction=N/A */
+	uint8_t reserved157;		/* Byte offset 0x157, CSR Addr 0x540ab, Direction=N/A */
+	uint8_t reserved158;		/* Byte offset 0x158, CSR Addr 0x540ac, Direction=N/A */
+	uint8_t reserved159;		/* Byte offset 0x159, CSR Addr 0x540ac, Direction=N/A */
+	uint8_t reserved15a;		/* Byte offset 0x15a, CSR Addr 0x540ad, Direction=N/A */
+	uint8_t reserved15b;		/* Byte offset 0x15b, CSR Addr 0x540ad, Direction=N/A */
+	uint8_t reserved15c;		/* Byte offset 0x15c, CSR Addr 0x540ae, Direction=N/A */
+	uint8_t reserved15d;		/* Byte offset 0x15d, CSR Addr 0x540ae, Direction=N/A */
+	uint8_t reserved15e;		/* Byte offset 0x15e, CSR Addr 0x540af, Direction=N/A */
+	uint8_t reserved15f;		/* Byte offset 0x15f, CSR Addr 0x540af, Direction=N/A */
+	uint8_t reserved160;		/* Byte offset 0x160, CSR Addr 0x540b0, Direction=N/A */
+	uint8_t reserved161;		/* Byte offset 0x161, CSR Addr 0x540b0, Direction=N/A */
+	uint8_t reserved162;		/* Byte offset 0x162, CSR Addr 0x540b1, Direction=N/A */
+	uint8_t reserved163;		/* Byte offset 0x163, CSR Addr 0x540b1, Direction=N/A */
+	uint8_t reserved164;		/* Byte offset 0x164, CSR Addr 0x540b2, Direction=N/A */
+	uint8_t reserved165;		/* Byte offset 0x165, CSR Addr 0x540b2, Direction=N/A */
+	uint8_t reserved166;		/* Byte offset 0x166, CSR Addr 0x540b3, Direction=N/A */
+	uint8_t reserved167;		/* Byte offset 0x167, CSR Addr 0x540b3, Direction=N/A */
+	uint8_t reserved168;		/* Byte offset 0x168, CSR Addr 0x540b4, Direction=N/A */
+	uint8_t reserved169;		/* Byte offset 0x169, CSR Addr 0x540b4, Direction=N/A */
+	uint8_t reserved16a;		/* Byte offset 0x16a, CSR Addr 0x540b5, Direction=N/A */
+	uint8_t reserved16b;		/* Byte offset 0x16b, CSR Addr 0x540b5, Direction=N/A */
+	uint8_t reserved16c;		/* Byte offset 0x16c, CSR Addr 0x540b6, Direction=N/A */
+	uint8_t reserved16d;		/* Byte offset 0x16d, CSR Addr 0x540b6, Direction=N/A */
+	uint8_t reserved16e;		/* Byte offset 0x16e, CSR Addr 0x540b7, Direction=N/A */
+	uint8_t reserved16f;		/* Byte offset 0x16f, CSR Addr 0x540b7, Direction=N/A */
+	uint8_t reserved170;		/* Byte offset 0x170, CSR Addr 0x540b8, Direction=N/A */
+	uint8_t reserved171;		/* Byte offset 0x171, CSR Addr 0x540b8, Direction=N/A */
+	uint8_t reserved172;		/* Byte offset 0x172, CSR Addr 0x540b9, Direction=N/A */
+	uint8_t reserved173;		/* Byte offset 0x173, CSR Addr 0x540b9, Direction=N/A */
+	uint8_t reserved174;		/* Byte offset 0x174, CSR Addr 0x540ba, Direction=N/A */
+	uint8_t reserved175;		/* Byte offset 0x175, CSR Addr 0x540ba, Direction=N/A */
+	uint8_t reserved176;		/* Byte offset 0x176, CSR Addr 0x540bb, Direction=N/A */
+	uint8_t reserved177;		/* Byte offset 0x177, CSR Addr 0x540bb, Direction=N/A */
+	uint8_t reserved178;		/* Byte offset 0x178, CSR Addr 0x540bc, Direction=N/A */
+	uint8_t reserved179;		/* Byte offset 0x179, CSR Addr 0x540bc, Direction=N/A */
+	uint8_t reserved17a;		/* Byte offset 0x17a, CSR Addr 0x540bd, Direction=N/A */
+	uint8_t reserved17b;		/* Byte offset 0x17b, CSR Addr 0x540bd, Direction=N/A */
+	uint8_t reserved17c;		/* Byte offset 0x17c, CSR Addr 0x540be, Direction=N/A */
+	uint8_t reserved17d;		/* Byte offset 0x17d, CSR Addr 0x540be, Direction=N/A */
+	uint8_t reserved17e;		/* Byte offset 0x17e, CSR Addr 0x540bf, Direction=N/A */
+	uint8_t reserved17f;		/* Byte offset 0x17f, CSR Addr 0x540bf, Direction=N/A */
+	uint8_t reserved180;		/* Byte offset 0x180, CSR Addr 0x540c0, Direction=N/A */
+	uint8_t reserved181;		/* Byte offset 0x181, CSR Addr 0x540c0, Direction=N/A */
+	uint8_t reserved182;		/* Byte offset 0x182, CSR Addr 0x540c1, Direction=N/A */
+	uint8_t reserved183;		/* Byte offset 0x183, CSR Addr 0x540c1, Direction=N/A */
+	uint8_t reserved184;		/* Byte offset 0x184, CSR Addr 0x540c2, Direction=N/A */
+	uint8_t reserved185;		/* Byte offset 0x185, CSR Addr 0x540c2, Direction=N/A */
+	uint8_t reserved186;		/* Byte offset 0x186, CSR Addr 0x540c3, Direction=N/A */
+	uint8_t reserved187;		/* Byte offset 0x187, CSR Addr 0x540c3, Direction=N/A */
+	uint8_t reserved188;		/* Byte offset 0x188, CSR Addr 0x540c4, Direction=N/A */
+	uint8_t reserved189;		/* Byte offset 0x189, CSR Addr 0x540c4, Direction=N/A */
+	uint8_t reserved18a;		/* Byte offset 0x18a, CSR Addr 0x540c5, Direction=N/A */
+	uint8_t reserved18b;		/* Byte offset 0x18b, CSR Addr 0x540c5, Direction=N/A */
+	uint8_t reserved18c;		/* Byte offset 0x18c, CSR Addr 0x540c6, Direction=N/A */
+	uint8_t reserved18d;		/* Byte offset 0x18d, CSR Addr 0x540c6, Direction=N/A */
+	uint8_t reserved18e;		/* Byte offset 0x18e, CSR Addr 0x540c7, Direction=N/A */
+	uint8_t reserved18f;		/* Byte offset 0x18f, CSR Addr 0x540c7, Direction=N/A */
+	uint8_t reserved190;		/* Byte offset 0x190, CSR Addr 0x540c8, Direction=N/A */
+	uint8_t reserved191;		/* Byte offset 0x191, CSR Addr 0x540c8, Direction=N/A */
+	uint8_t reserved192;		/* Byte offset 0x192, CSR Addr 0x540c9, Direction=N/A */
+	uint8_t reserved193;		/* Byte offset 0x193, CSR Addr 0x540c9, Direction=N/A */
+	uint8_t reserved194;		/* Byte offset 0x194, CSR Addr 0x540ca, Direction=N/A */
+	uint8_t reserved195;		/* Byte offset 0x195, CSR Addr 0x540ca, Direction=N/A */
+	uint8_t reserved196;		/* Byte offset 0x196, CSR Addr 0x540cb, Direction=N/A */
+	uint8_t reserved197;		/* Byte offset 0x197, CSR Addr 0x540cb, Direction=N/A */
+	uint8_t reserved198;		/* Byte offset 0x198, CSR Addr 0x540cc, Direction=N/A */
+	uint8_t reserved199;		/* Byte offset 0x199, CSR Addr 0x540cc, Direction=N/A */
+	uint8_t reserved19a;		/* Byte offset 0x19a, CSR Addr 0x540cd, Direction=N/A */
+	uint8_t reserved19b;		/* Byte offset 0x19b, CSR Addr 0x540cd, Direction=N/A */
+	uint8_t reserved19c;		/* Byte offset 0x19c, CSR Addr 0x540ce, Direction=N/A */
+	uint8_t reserved19d;		/* Byte offset 0x19d, CSR Addr 0x540ce, Direction=N/A */
+	uint8_t reserved19e;		/* Byte offset 0x19e, CSR Addr 0x540cf, Direction=N/A */
+	uint8_t reserved19f;		/* Byte offset 0x19f, CSR Addr 0x540cf, Direction=N/A */
+	uint8_t reserved1a0;		/* Byte offset 0x1a0, CSR Addr 0x540d0, Direction=N/A */
+	uint8_t reserved1a1;		/* Byte offset 0x1a1, CSR Addr 0x540d0, Direction=N/A */
+	uint8_t reserved1a2;		/* Byte offset 0x1a2, CSR Addr 0x540d1, Direction=N/A */
+	uint8_t reserved1a3;		/* Byte offset 0x1a3, CSR Addr 0x540d1, Direction=N/A */
+	uint8_t reserved1a4;		/* Byte offset 0x1a4, CSR Addr 0x540d2, Direction=N/A */
+	uint8_t reserved1a5;		/* Byte offset 0x1a5, CSR Addr 0x540d2, Direction=N/A */
+	uint8_t reserved1a6;		/* Byte offset 0x1a6, CSR Addr 0x540d3, Direction=N/A */
+	uint8_t reserved1a7;		/* Byte offset 0x1a7, CSR Addr 0x540d3, Direction=N/A */
+	uint8_t reserved1a8;		/* Byte offset 0x1a8, CSR Addr 0x540d4, Direction=N/A */
+	uint8_t reserved1a9;		/* Byte offset 0x1a9, CSR Addr 0x540d4, Direction=N/A */
+	uint8_t reserved1aa;		/* Byte offset 0x1aa, CSR Addr 0x540d5, Direction=N/A */
+	uint8_t reserved1ab;		/* Byte offset 0x1ab, CSR Addr 0x540d5, Direction=N/A */
+	uint8_t reserved1ac;		/* Byte offset 0x1ac, CSR Addr 0x540d6, Direction=N/A */
+	uint8_t reserved1ad;		/* Byte offset 0x1ad, CSR Addr 0x540d6, Direction=N/A */
+	uint8_t reserved1ae;		/* Byte offset 0x1ae, CSR Addr 0x540d7, Direction=N/A */
+	uint8_t reserved1af;		/* Byte offset 0x1af, CSR Addr 0x540d7, Direction=N/A */
+	uint8_t reserved1b0;		/* Byte offset 0x1b0, CSR Addr 0x540d8, Direction=N/A */
+	uint8_t reserved1b1;		/* Byte offset 0x1b1, CSR Addr 0x540d8, Direction=N/A */
+	uint8_t reserved1b2;		/* Byte offset 0x1b2, CSR Addr 0x540d9, Direction=N/A */
+	uint8_t reserved1b3;		/* Byte offset 0x1b3, CSR Addr 0x540d9, Direction=N/A */
+	uint8_t reserved1b4;		/* Byte offset 0x1b4, CSR Addr 0x540da, Direction=N/A */
+	uint8_t reserved1b5;		/* Byte offset 0x1b5, CSR Addr 0x540da, Direction=N/A */
+	uint8_t reserved1b6;		/* Byte offset 0x1b6, CSR Addr 0x540db, Direction=N/A */
+	uint8_t reserved1b7;		/* Byte offset 0x1b7, CSR Addr 0x540db, Direction=N/A */
+	uint8_t reserved1b8;		/* Byte offset 0x1b8, CSR Addr 0x540dc, Direction=N/A */
+	uint8_t reserved1b9;		/* Byte offset 0x1b9, CSR Addr 0x540dc, Direction=N/A */
+	uint8_t reserved1ba;		/* Byte offset 0x1ba, CSR Addr 0x540dd, Direction=N/A */
+	uint8_t reserved1bb;		/* Byte offset 0x1bb, CSR Addr 0x540dd, Direction=N/A */
+	uint8_t reserved1bc;		/* Byte offset 0x1bc, CSR Addr 0x540de, Direction=N/A */
+	uint8_t reserved1bd;		/* Byte offset 0x1bd, CSR Addr 0x540de, Direction=N/A */
+	uint8_t reserved1be;		/* Byte offset 0x1be, CSR Addr 0x540df, Direction=N/A */
+	uint8_t reserved1bf;		/* Byte offset 0x1bf, CSR Addr 0x540df, Direction=N/A */
+	uint8_t reserved1c0;		/* Byte offset 0x1c0, CSR Addr 0x540e0, Direction=N/A */
+	uint8_t reserved1c1;		/* Byte offset 0x1c1, CSR Addr 0x540e0, Direction=N/A */
+	uint8_t reserved1c2;		/* Byte offset 0x1c2, CSR Addr 0x540e1, Direction=N/A */
+	uint8_t reserved1c3;		/* Byte offset 0x1c3, CSR Addr 0x540e1, Direction=N/A */
+	uint8_t reserved1c4;		/* Byte offset 0x1c4, CSR Addr 0x540e2, Direction=N/A */
+	uint8_t reserved1c5;		/* Byte offset 0x1c5, CSR Addr 0x540e2, Direction=N/A */
+	uint8_t reserved1c6;		/* Byte offset 0x1c6, CSR Addr 0x540e3, Direction=N/A */
+	uint8_t reserved1c7;		/* Byte offset 0x1c7, CSR Addr 0x540e3, Direction=N/A */
+	uint8_t reserved1c8;		/* Byte offset 0x1c8, CSR Addr 0x540e4, Direction=N/A */
+	uint8_t reserved1c9;		/* Byte offset 0x1c9, CSR Addr 0x540e4, Direction=N/A */
+	uint8_t reserved1ca;		/* Byte offset 0x1ca, CSR Addr 0x540e5, Direction=N/A */
+	uint8_t reserved1cb;		/* Byte offset 0x1cb, CSR Addr 0x540e5, Direction=N/A */
+	uint8_t reserved1cc;		/* Byte offset 0x1cc, CSR Addr 0x540e6, Direction=N/A */
+	uint8_t reserved1cd;		/* Byte offset 0x1cd, CSR Addr 0x540e6, Direction=N/A */
+	uint8_t reserved1ce;		/* Byte offset 0x1ce, CSR Addr 0x540e7, Direction=N/A */
+	uint8_t reserved1cf;		/* Byte offset 0x1cf, CSR Addr 0x540e7, Direction=N/A */
+	uint8_t reserved1d0;		/* Byte offset 0x1d0, CSR Addr 0x540e8, Direction=N/A */
+	uint8_t reserved1d1;		/* Byte offset 0x1d1, CSR Addr 0x540e8, Direction=N/A */
+	uint8_t reserved1d2;		/* Byte offset 0x1d2, CSR Addr 0x540e9, Direction=N/A */
+	uint8_t reserved1d3;		/* Byte offset 0x1d3, CSR Addr 0x540e9, Direction=N/A */
+	uint8_t reserved1d4;		/* Byte offset 0x1d4, CSR Addr 0x540ea, Direction=N/A */
+	uint8_t reserved1d5;		/* Byte offset 0x1d5, CSR Addr 0x540ea, Direction=N/A */
+	uint8_t reserved1d6;		/* Byte offset 0x1d6, CSR Addr 0x540eb, Direction=N/A */
+	uint8_t reserved1d7;		/* Byte offset 0x1d7, CSR Addr 0x540eb, Direction=N/A */
+	uint8_t reserved1d8;		/* Byte offset 0x1d8, CSR Addr 0x540ec, Direction=N/A */
+	uint8_t reserved1d9;		/* Byte offset 0x1d9, CSR Addr 0x540ec, Direction=N/A */
+	uint8_t reserved1da;		/* Byte offset 0x1da, CSR Addr 0x540ed, Direction=N/A */
+	uint8_t reserved1db;		/* Byte offset 0x1db, CSR Addr 0x540ed, Direction=N/A */
+	uint8_t reserved1dc;		/* Byte offset 0x1dc, CSR Addr 0x540ee, Direction=N/A */
+	uint8_t reserved1dd;		/* Byte offset 0x1dd, CSR Addr 0x540ee, Direction=N/A */
+	uint8_t reserved1de;		/* Byte offset 0x1de, CSR Addr 0x540ef, Direction=N/A */
+	uint8_t reserved1df;		/* Byte offset 0x1df, CSR Addr 0x540ef, Direction=N/A */
+	uint8_t reserved1e0;		/* Byte offset 0x1e0, CSR Addr 0x540f0, Direction=N/A */
+	uint8_t reserved1e1;		/* Byte offset 0x1e1, CSR Addr 0x540f0, Direction=N/A */
+	uint8_t reserved1e2;		/* Byte offset 0x1e2, CSR Addr 0x540f1, Direction=N/A */
+	uint8_t reserved1e3;		/* Byte offset 0x1e3, CSR Addr 0x540f1, Direction=N/A */
+	uint8_t reserved1e4;		/* Byte offset 0x1e4, CSR Addr 0x540f2, Direction=N/A */
+	uint8_t reserved1e5;		/* Byte offset 0x1e5, CSR Addr 0x540f2, Direction=N/A */
+	uint8_t reserved1e6;		/* Byte offset 0x1e6, CSR Addr 0x540f3, Direction=N/A */
+	uint8_t reserved1e7;		/* Byte offset 0x1e7, CSR Addr 0x540f3, Direction=N/A */
+	uint8_t reserved1e8;		/* Byte offset 0x1e8, CSR Addr 0x540f4, Direction=N/A */
+	uint8_t reserved1e9;		/* Byte offset 0x1e9, CSR Addr 0x540f4, Direction=N/A */
+	uint8_t reserved1ea;		/* Byte offset 0x1ea, CSR Addr 0x540f5, Direction=N/A */
+	uint8_t reserved1eb;		/* Byte offset 0x1eb, CSR Addr 0x540f5, Direction=N/A */
+	uint8_t reserved1ec;		/* Byte offset 0x1ec, CSR Addr 0x540f6, Direction=N/A */
+	uint8_t reserved1ed;		/* Byte offset 0x1ed, CSR Addr 0x540f6, Direction=N/A */
+	uint8_t reserved1ee;		/* Byte offset 0x1ee, CSR Addr 0x540f7, Direction=N/A */
+	uint8_t reserved1ef;		/* Byte offset 0x1ef, CSR Addr 0x540f7, Direction=N/A */
+	uint8_t reserved1f0;		/* Byte offset 0x1f0, CSR Addr 0x540f8, Direction=N/A */
+	uint8_t reserved1f1;		/* Byte offset 0x1f1, CSR Addr 0x540f8, Direction=N/A */
+	uint8_t reserved1f2;		/* Byte offset 0x1f2, CSR Addr 0x540f9, Direction=N/A */
+	uint8_t reserved1f3;		/* Byte offset 0x1f3, CSR Addr 0x540f9, Direction=N/A */
+	uint8_t reserved1f4;		/* Byte offset 0x1f4, CSR Addr 0x540fa, Direction=N/A */
+	uint8_t reserved1f5;		/* Byte offset 0x1f5, CSR Addr 0x540fa, Direction=N/A */
+	uint8_t reserved1f6;		/* Byte offset 0x1f6, CSR Addr 0x540fb, Direction=N/A */
+	uint8_t reserved1f7;		/* Byte offset 0x1f7, CSR Addr 0x540fb, Direction=N/A */
+	uint8_t reserved1f8;		/* Byte offset 0x1f8, CSR Addr 0x540fc, Direction=N/A */
+	uint8_t reserved1f9;		/* Byte offset 0x1f9, CSR Addr 0x540fc, Direction=N/A */
+	uint8_t reserved1fa;		/* Byte offset 0x1fa, CSR Addr 0x540fd, Direction=N/A */
+	uint8_t reserved1fb;		/* Byte offset 0x1fb, CSR Addr 0x540fd, Direction=N/A */
+	uint8_t reserved1fc;		/* Byte offset 0x1fc, CSR Addr 0x540fe, Direction=N/A */
+	uint8_t reserved1fd;		/* Byte offset 0x1fd, CSR Addr 0x540fe, Direction=N/A */
+	uint8_t reserved1fe;		/* Byte offset 0x1fe, CSR Addr 0x540ff, Direction=N/A */
+	uint8_t reserved1ff;		/* Byte offset 0x1ff, CSR Addr 0x540ff, Direction=N/A */
+	uint8_t reserved200;		/* Byte offset 0x200, CSR Addr 0x54100, Direction=N/A */
+	uint8_t reserved201;		/* Byte offset 0x201, CSR Addr 0x54100, Direction=N/A */
+	uint8_t reserved202;		/* Byte offset 0x202, CSR Addr 0x54101, Direction=N/A */
+	uint8_t reserved203;		/* Byte offset 0x203, CSR Addr 0x54101, Direction=N/A */
+	uint8_t reserved204;		/* Byte offset 0x204, CSR Addr 0x54102, Direction=N/A */
+	uint8_t reserved205;		/* Byte offset 0x205, CSR Addr 0x54102, Direction=N/A */
+	uint8_t reserved206;		/* Byte offset 0x206, CSR Addr 0x54103, Direction=N/A */
+	uint8_t reserved207;		/* Byte offset 0x207, CSR Addr 0x54103, Direction=N/A */
+	uint8_t reserved208;		/* Byte offset 0x208, CSR Addr 0x54104, Direction=N/A */
+	uint8_t reserved209;		/* Byte offset 0x209, CSR Addr 0x54104, Direction=N/A */
+	uint8_t reserved20a;		/* Byte offset 0x20a, CSR Addr 0x54105, Direction=N/A */
+	uint8_t reserved20b;		/* Byte offset 0x20b, CSR Addr 0x54105, Direction=N/A */
+	uint8_t reserved20c;		/* Byte offset 0x20c, CSR Addr 0x54106, Direction=N/A */
+	uint8_t reserved20d;		/* Byte offset 0x20d, CSR Addr 0x54106, Direction=N/A */
+	uint8_t reserved20e;		/* Byte offset 0x20e, CSR Addr 0x54107, Direction=N/A */
+	uint8_t reserved20f;		/* Byte offset 0x20f, CSR Addr 0x54107, Direction=N/A */
+	uint8_t reserved210;		/* Byte offset 0x210, CSR Addr 0x54108, Direction=N/A */
+	uint8_t reserved211;		/* Byte offset 0x211, CSR Addr 0x54108, Direction=N/A */
+	uint8_t reserved212;		/* Byte offset 0x212, CSR Addr 0x54109, Direction=N/A */
+	uint8_t reserved213;		/* Byte offset 0x213, CSR Addr 0x54109, Direction=N/A */
+	uint8_t reserved214;		/* Byte offset 0x214, CSR Addr 0x5410a, Direction=N/A */
+	uint8_t reserved215;		/* Byte offset 0x215, CSR Addr 0x5410a, Direction=N/A */
+	uint8_t reserved216;		/* Byte offset 0x216, CSR Addr 0x5410b, Direction=N/A */
+	uint8_t reserved217;		/* Byte offset 0x217, CSR Addr 0x5410b, Direction=N/A */
+	uint8_t reserved218;		/* Byte offset 0x218, CSR Addr 0x5410c, Direction=N/A */
+	uint8_t reserved219;		/* Byte offset 0x219, CSR Addr 0x5410c, Direction=N/A */
+	uint8_t reserved21a;		/* Byte offset 0x21a, CSR Addr 0x5410d, Direction=N/A */
+	uint8_t reserved21b;		/* Byte offset 0x21b, CSR Addr 0x5410d, Direction=N/A */
+	uint8_t reserved21c;		/* Byte offset 0x21c, CSR Addr 0x5410e, Direction=N/A */
+	uint8_t reserved21d;		/* Byte offset 0x21d, CSR Addr 0x5410e, Direction=N/A */
+	uint8_t reserved21e;		/* Byte offset 0x21e, CSR Addr 0x5410f, Direction=N/A */
+	uint8_t reserved21f;		/* Byte offset 0x21f, CSR Addr 0x5410f, Direction=N/A */
+	uint8_t reserved220;		/* Byte offset 0x220, CSR Addr 0x54110, Direction=N/A */
+	uint8_t reserved221;		/* Byte offset 0x221, CSR Addr 0x54110, Direction=N/A */
+	uint8_t reserved222;		/* Byte offset 0x222, CSR Addr 0x54111, Direction=N/A */
+	uint8_t reserved223;		/* Byte offset 0x223, CSR Addr 0x54111, Direction=N/A */
+	uint8_t reserved224;		/* Byte offset 0x224, CSR Addr 0x54112, Direction=N/A */
+	uint8_t reserved225;		/* Byte offset 0x225, CSR Addr 0x54112, Direction=N/A */
+	uint8_t reserved226;		/* Byte offset 0x226, CSR Addr 0x54113, Direction=N/A */
+	uint8_t reserved227;		/* Byte offset 0x227, CSR Addr 0x54113, Direction=N/A */
+	uint8_t reserved228;		/* Byte offset 0x228, CSR Addr 0x54114, Direction=N/A */
+	uint8_t reserved229;		/* Byte offset 0x229, CSR Addr 0x54114, Direction=N/A */
+	uint8_t reserved22a;		/* Byte offset 0x22a, CSR Addr 0x54115, Direction=N/A */
+	uint8_t reserved22b;		/* Byte offset 0x22b, CSR Addr 0x54115, Direction=N/A */
+	uint8_t reserved22c;		/* Byte offset 0x22c, CSR Addr 0x54116, Direction=N/A */
+	uint8_t reserved22d;		/* Byte offset 0x22d, CSR Addr 0x54116, Direction=N/A */
+	uint8_t reserved22e;		/* Byte offset 0x22e, CSR Addr 0x54117, Direction=N/A */
+	uint8_t reserved22f;		/* Byte offset 0x22f, CSR Addr 0x54117, Direction=N/A */
+	uint8_t reserved230;		/* Byte offset 0x230, CSR Addr 0x54118, Direction=N/A */
+	uint8_t reserved231;		/* Byte offset 0x231, CSR Addr 0x54118, Direction=N/A */
+	uint8_t reserved232;		/* Byte offset 0x232, CSR Addr 0x54119, Direction=N/A */
+	uint8_t reserved233;		/* Byte offset 0x233, CSR Addr 0x54119, Direction=N/A */
+	uint8_t reserved234;		/* Byte offset 0x234, CSR Addr 0x5411a, Direction=N/A */
+	uint8_t reserved235;		/* Byte offset 0x235, CSR Addr 0x5411a, Direction=N/A */
+	uint8_t reserved236;		/* Byte offset 0x236, CSR Addr 0x5411b, Direction=N/A */
+	uint8_t reserved237;		/* Byte offset 0x237, CSR Addr 0x5411b, Direction=N/A */
+	uint8_t reserved238;		/* Byte offset 0x238, CSR Addr 0x5411c, Direction=N/A */
+	uint8_t reserved239;		/* Byte offset 0x239, CSR Addr 0x5411c, Direction=N/A */
+	uint8_t reserved23a;		/* Byte offset 0x23a, CSR Addr 0x5411d, Direction=N/A */
+	uint8_t reserved23b;		/* Byte offset 0x23b, CSR Addr 0x5411d, Direction=N/A */
+	uint8_t reserved23c;		/* Byte offset 0x23c, CSR Addr 0x5411e, Direction=N/A */
+	uint8_t reserved23d;		/* Byte offset 0x23d, CSR Addr 0x5411e, Direction=N/A */
+	uint8_t reserved23e;		/* Byte offset 0x23e, CSR Addr 0x5411f, Direction=N/A */
+	uint8_t reserved23f;		/* Byte offset 0x23f, CSR Addr 0x5411f, Direction=N/A */
+	uint8_t reserved240;		/* Byte offset 0x240, CSR Addr 0x54120, Direction=N/A */
+	uint8_t reserved241;		/* Byte offset 0x241, CSR Addr 0x54120, Direction=N/A */
+	uint8_t reserved242;		/* Byte offset 0x242, CSR Addr 0x54121, Direction=N/A */
+	uint8_t reserved243;		/* Byte offset 0x243, CSR Addr 0x54121, Direction=N/A */
+	uint8_t reserved244;		/* Byte offset 0x244, CSR Addr 0x54122, Direction=N/A */
+	uint8_t reserved245;		/* Byte offset 0x245, CSR Addr 0x54122, Direction=N/A */
+	uint8_t reserved246;		/* Byte offset 0x246, CSR Addr 0x54123, Direction=N/A */
+	uint8_t reserved247;		/* Byte offset 0x247, CSR Addr 0x54123, Direction=N/A */
+	uint8_t reserved248;		/* Byte offset 0x248, CSR Addr 0x54124, Direction=N/A */
+	uint8_t reserved249;		/* Byte offset 0x249, CSR Addr 0x54124, Direction=N/A */
+	uint8_t reserved24a;		/* Byte offset 0x24a, CSR Addr 0x54125, Direction=N/A */
+	uint8_t reserved24b;		/* Byte offset 0x24b, CSR Addr 0x54125, Direction=N/A */
+	uint8_t reserved24c;		/* Byte offset 0x24c, CSR Addr 0x54126, Direction=N/A */
+	uint8_t reserved24d;		/* Byte offset 0x24d, CSR Addr 0x54126, Direction=N/A */
+	uint8_t reserved24e;		/* Byte offset 0x24e, CSR Addr 0x54127, Direction=N/A */
+	uint8_t reserved24f;		/* Byte offset 0x24f, CSR Addr 0x54127, Direction=N/A */
+	uint8_t reserved250;		/* Byte offset 0x250, CSR Addr 0x54128, Direction=N/A */
+	uint8_t reserved251;		/* Byte offset 0x251, CSR Addr 0x54128, Direction=N/A */
+	uint8_t reserved252;		/* Byte offset 0x252, CSR Addr 0x54129, Direction=N/A */
+	uint8_t reserved253;		/* Byte offset 0x253, CSR Addr 0x54129, Direction=N/A */
+	uint8_t reserved254;		/* Byte offset 0x254, CSR Addr 0x5412a, Direction=N/A */
+	uint8_t reserved255;		/* Byte offset 0x255, CSR Addr 0x5412a, Direction=N/A */
+	uint8_t reserved256;		/* Byte offset 0x256, CSR Addr 0x5412b, Direction=N/A */
+	uint8_t reserved257;		/* Byte offset 0x257, CSR Addr 0x5412b, Direction=N/A */
+	uint8_t reserved258;		/* Byte offset 0x258, CSR Addr 0x5412c, Direction=N/A */
+	uint8_t reserved259;		/* Byte offset 0x259, CSR Addr 0x5412c, Direction=N/A */
+	uint8_t reserved25a;		/* Byte offset 0x25a, CSR Addr 0x5412d, Direction=N/A */
+	uint8_t reserved25b;		/* Byte offset 0x25b, CSR Addr 0x5412d, Direction=N/A */
+	uint8_t reserved25c;		/* Byte offset 0x25c, CSR Addr 0x5412e, Direction=N/A */
+	uint8_t reserved25d;		/* Byte offset 0x25d, CSR Addr 0x5412e, Direction=N/A */
+	uint8_t reserved25e;		/* Byte offset 0x25e, CSR Addr 0x5412f, Direction=N/A */
+	uint8_t reserved25f;		/* Byte offset 0x25f, CSR Addr 0x5412f, Direction=N/A */
+	uint8_t reserved260;		/* Byte offset 0x260, CSR Addr 0x54130, Direction=N/A */
+	uint8_t reserved261;		/* Byte offset 0x261, CSR Addr 0x54130, Direction=N/A */
+	uint8_t reserved262;		/* Byte offset 0x262, CSR Addr 0x54131, Direction=N/A */
+	uint8_t reserved263;		/* Byte offset 0x263, CSR Addr 0x54131, Direction=N/A */
+	uint8_t reserved264;		/* Byte offset 0x264, CSR Addr 0x54132, Direction=N/A */
+	uint8_t reserved265;		/* Byte offset 0x265, CSR Addr 0x54132, Direction=N/A */
+	uint8_t reserved266;		/* Byte offset 0x266, CSR Addr 0x54133, Direction=N/A */
+	uint8_t reserved267;		/* Byte offset 0x267, CSR Addr 0x54133, Direction=N/A */
+	uint8_t reserved268;		/* Byte offset 0x268, CSR Addr 0x54134, Direction=N/A */
+	uint8_t reserved269;		/* Byte offset 0x269, CSR Addr 0x54134, Direction=N/A */
+	uint8_t reserved26a;		/* Byte offset 0x26a, CSR Addr 0x54135, Direction=N/A */
+	uint8_t reserved26b;		/* Byte offset 0x26b, CSR Addr 0x54135, Direction=N/A */
+	uint8_t reserved26c;		/* Byte offset 0x26c, CSR Addr 0x54136, Direction=N/A */
+	uint8_t reserved26d;		/* Byte offset 0x26d, CSR Addr 0x54136, Direction=N/A */
+	uint8_t reserved26e;		/* Byte offset 0x26e, CSR Addr 0x54137, Direction=N/A */
+	uint8_t reserved26f;		/* Byte offset 0x26f, CSR Addr 0x54137, Direction=N/A */
+	uint8_t reserved270;		/* Byte offset 0x270, CSR Addr 0x54138, Direction=N/A */
+	uint8_t reserved271;		/* Byte offset 0x271, CSR Addr 0x54138, Direction=N/A */
+	uint8_t reserved272;		/* Byte offset 0x272, CSR Addr 0x54139, Direction=N/A */
+	uint8_t reserved273;		/* Byte offset 0x273, CSR Addr 0x54139, Direction=N/A */
+	uint8_t reserved274;		/* Byte offset 0x274, CSR Addr 0x5413a, Direction=N/A */
+	uint8_t reserved275;		/* Byte offset 0x275, CSR Addr 0x5413a, Direction=N/A */
+	uint8_t reserved276;		/* Byte offset 0x276, CSR Addr 0x5413b, Direction=N/A */
+	uint8_t reserved277;		/* Byte offset 0x277, CSR Addr 0x5413b, Direction=N/A */
+	uint8_t reserved278;		/* Byte offset 0x278, CSR Addr 0x5413c, Direction=N/A */
+	uint8_t reserved279;		/* Byte offset 0x279, CSR Addr 0x5413c, Direction=N/A */
+	uint8_t reserved27a;		/* Byte offset 0x27a, CSR Addr 0x5413d, Direction=N/A */
+	uint8_t reserved27b;		/* Byte offset 0x27b, CSR Addr 0x5413d, Direction=N/A */
+	uint8_t reserved27c;		/* Byte offset 0x27c, CSR Addr 0x5413e, Direction=N/A */
+	uint8_t reserved27d;		/* Byte offset 0x27d, CSR Addr 0x5413e, Direction=N/A */
+	uint8_t reserved27e;		/* Byte offset 0x27e, CSR Addr 0x5413f, Direction=N/A */
+	uint8_t reserved27f;		/* Byte offset 0x27f, CSR Addr 0x5413f, Direction=N/A */
+	uint8_t reserved280;		/* Byte offset 0x280, CSR Addr 0x54140, Direction=N/A */
+	uint8_t reserved281;		/* Byte offset 0x281, CSR Addr 0x54140, Direction=N/A */
+	uint8_t reserved282;		/* Byte offset 0x282, CSR Addr 0x54141, Direction=N/A */
+	uint8_t reserved283;		/* Byte offset 0x283, CSR Addr 0x54141, Direction=N/A */
+	uint8_t reserved284;		/* Byte offset 0x284, CSR Addr 0x54142, Direction=N/A */
+	uint8_t reserved285;		/* Byte offset 0x285, CSR Addr 0x54142, Direction=N/A */
+	uint8_t reserved286;		/* Byte offset 0x286, CSR Addr 0x54143, Direction=N/A */
+	uint8_t reserved287;		/* Byte offset 0x287, CSR Addr 0x54143, Direction=N/A */
+	uint8_t reserved288;		/* Byte offset 0x288, CSR Addr 0x54144, Direction=N/A */
+	uint8_t reserved289;		/* Byte offset 0x289, CSR Addr 0x54144, Direction=N/A */
+	uint8_t reserved28a;		/* Byte offset 0x28a, CSR Addr 0x54145, Direction=N/A */
+	uint8_t reserved28b;		/* Byte offset 0x28b, CSR Addr 0x54145, Direction=N/A */
+	uint8_t reserved28c;		/* Byte offset 0x28c, CSR Addr 0x54146, Direction=N/A */
+	uint8_t reserved28d;		/* Byte offset 0x28d, CSR Addr 0x54146, Direction=N/A */
+	uint8_t reserved28e;		/* Byte offset 0x28e, CSR Addr 0x54147, Direction=N/A */
+	uint8_t reserved28f;		/* Byte offset 0x28f, CSR Addr 0x54147, Direction=N/A */
+	uint8_t reserved290;		/* Byte offset 0x290, CSR Addr 0x54148, Direction=N/A */
+	uint8_t reserved291;		/* Byte offset 0x291, CSR Addr 0x54148, Direction=N/A */
+	uint8_t reserved292;		/* Byte offset 0x292, CSR Addr 0x54149, Direction=N/A */
+	uint8_t reserved293;		/* Byte offset 0x293, CSR Addr 0x54149, Direction=N/A */
+	uint8_t reserved294;		/* Byte offset 0x294, CSR Addr 0x5414a, Direction=N/A */
+	uint8_t reserved295;		/* Byte offset 0x295, CSR Addr 0x5414a, Direction=N/A */
+	uint8_t reserved296;		/* Byte offset 0x296, CSR Addr 0x5414b, Direction=N/A */
+	uint8_t reserved297;		/* Byte offset 0x297, CSR Addr 0x5414b, Direction=N/A */
+	uint8_t reserved298;		/* Byte offset 0x298, CSR Addr 0x5414c, Direction=N/A */
+	uint8_t reserved299;		/* Byte offset 0x299, CSR Addr 0x5414c, Direction=N/A */
+	uint8_t reserved29a;		/* Byte offset 0x29a, CSR Addr 0x5414d, Direction=N/A */
+	uint8_t reserved29b;		/* Byte offset 0x29b, CSR Addr 0x5414d, Direction=N/A */
+	uint8_t reserved29c;		/* Byte offset 0x29c, CSR Addr 0x5414e, Direction=N/A */
+	uint8_t reserved29d;		/* Byte offset 0x29d, CSR Addr 0x5414e, Direction=N/A */
+	uint8_t reserved29e;		/* Byte offset 0x29e, CSR Addr 0x5414f, Direction=N/A */
+	uint8_t reserved29f;		/* Byte offset 0x29f, CSR Addr 0x5414f, Direction=N/A */
+	uint8_t reserved2a0;		/* Byte offset 0x2a0, CSR Addr 0x54150, Direction=N/A */
+	uint8_t reserved2a1;		/* Byte offset 0x2a1, CSR Addr 0x54150, Direction=N/A */
+	uint8_t reserved2a2;		/* Byte offset 0x2a2, CSR Addr 0x54151, Direction=N/A */
+	uint8_t reserved2a3;		/* Byte offset 0x2a3, CSR Addr 0x54151, Direction=N/A */
+	uint8_t reserved2a4;		/* Byte offset 0x2a4, CSR Addr 0x54152, Direction=N/A */
+	uint8_t reserved2a5;		/* Byte offset 0x2a5, CSR Addr 0x54152, Direction=N/A */
+	uint8_t reserved2a6;		/* Byte offset 0x2a6, CSR Addr 0x54153, Direction=N/A */
+	uint8_t reserved2a7;		/* Byte offset 0x2a7, CSR Addr 0x54153, Direction=N/A */
+	uint8_t reserved2a8;		/* Byte offset 0x2a8, CSR Addr 0x54154, Direction=N/A */
+	uint8_t reserved2a9;		/* Byte offset 0x2a9, CSR Addr 0x54154, Direction=N/A */
+	uint8_t reserved2aa;		/* Byte offset 0x2aa, CSR Addr 0x54155, Direction=N/A */
+	uint8_t reserved2ab;		/* Byte offset 0x2ab, CSR Addr 0x54155, Direction=N/A */
+	uint8_t reserved2ac;		/* Byte offset 0x2ac, CSR Addr 0x54156, Direction=N/A */
+	uint8_t reserved2ad;		/* Byte offset 0x2ad, CSR Addr 0x54156, Direction=N/A */
+	uint8_t reserved2ae;		/* Byte offset 0x2ae, CSR Addr 0x54157, Direction=N/A */
+	uint8_t reserved2af;		/* Byte offset 0x2af, CSR Addr 0x54157, Direction=N/A */
+	uint8_t reserved2b0;		/* Byte offset 0x2b0, CSR Addr 0x54158, Direction=N/A */
+	uint8_t reserved2b1;		/* Byte offset 0x2b1, CSR Addr 0x54158, Direction=N/A */
+	uint8_t reserved2b2;		/* Byte offset 0x2b2, CSR Addr 0x54159, Direction=N/A */
+	uint8_t reserved2b3;		/* Byte offset 0x2b3, CSR Addr 0x54159, Direction=N/A */
+	uint8_t reserved2b4;		/* Byte offset 0x2b4, CSR Addr 0x5415a, Direction=N/A */
+	uint8_t reserved2b5;		/* Byte offset 0x2b5, CSR Addr 0x5415a, Direction=N/A */
+	uint8_t reserved2b6;		/* Byte offset 0x2b6, CSR Addr 0x5415b, Direction=N/A */
+	uint8_t reserved2b7;		/* Byte offset 0x2b7, CSR Addr 0x5415b, Direction=N/A */
+	uint8_t reserved2b8;		/* Byte offset 0x2b8, CSR Addr 0x5415c, Direction=N/A */
+	uint8_t reserved2b9;		/* Byte offset 0x2b9, CSR Addr 0x5415c, Direction=N/A */
+	uint8_t reserved2ba;		/* Byte offset 0x2ba, CSR Addr 0x5415d, Direction=N/A */
+	uint8_t reserved2bb;		/* Byte offset 0x2bb, CSR Addr 0x5415d, Direction=N/A */
+	uint8_t reserved2bc;		/* Byte offset 0x2bc, CSR Addr 0x5415e, Direction=N/A */
+	uint8_t reserved2bd;		/* Byte offset 0x2bd, CSR Addr 0x5415e, Direction=N/A */
+	uint8_t reserved2be;		/* Byte offset 0x2be, CSR Addr 0x5415f, Direction=N/A */
+	uint8_t reserved2bf;		/* Byte offset 0x2bf, CSR Addr 0x5415f, Direction=N/A */
+	uint8_t reserved2c0;		/* Byte offset 0x2c0, CSR Addr 0x54160, Direction=N/A */
+	uint8_t reserved2c1;		/* Byte offset 0x2c1, CSR Addr 0x54160, Direction=N/A */
+	uint8_t reserved2c2;		/* Byte offset 0x2c2, CSR Addr 0x54161, Direction=N/A */
+	uint8_t reserved2c3;		/* Byte offset 0x2c3, CSR Addr 0x54161, Direction=N/A */
+	uint8_t reserved2c4;		/* Byte offset 0x2c4, CSR Addr 0x54162, Direction=N/A */
+	uint8_t reserved2c5;		/* Byte offset 0x2c5, CSR Addr 0x54162, Direction=N/A */
+	uint8_t reserved2c6;		/* Byte offset 0x2c6, CSR Addr 0x54163, Direction=N/A */
+	uint8_t reserved2c7;		/* Byte offset 0x2c7, CSR Addr 0x54163, Direction=N/A */
+	uint8_t reserved2c8;		/* Byte offset 0x2c8, CSR Addr 0x54164, Direction=N/A */
+	uint8_t reserved2c9;		/* Byte offset 0x2c9, CSR Addr 0x54164, Direction=N/A */
+	uint8_t reserved2ca;		/* Byte offset 0x2ca, CSR Addr 0x54165, Direction=N/A */
+	uint8_t reserved2cb;		/* Byte offset 0x2cb, CSR Addr 0x54165, Direction=N/A */
+	uint8_t reserved2cc;		/* Byte offset 0x2cc, CSR Addr 0x54166, Direction=N/A */
+	uint8_t reserved2cd;		/* Byte offset 0x2cd, CSR Addr 0x54166, Direction=N/A */
+	uint8_t reserved2ce;		/* Byte offset 0x2ce, CSR Addr 0x54167, Direction=N/A */
+	uint8_t reserved2cf;		/* Byte offset 0x2cf, CSR Addr 0x54167, Direction=N/A */
+	uint8_t reserved2d0;		/* Byte offset 0x2d0, CSR Addr 0x54168, Direction=N/A */
+	uint8_t reserved2d1;		/* Byte offset 0x2d1, CSR Addr 0x54168, Direction=N/A */
+	uint8_t reserved2d2;		/* Byte offset 0x2d2, CSR Addr 0x54169, Direction=N/A */
+	uint8_t reserved2d3;		/* Byte offset 0x2d3, CSR Addr 0x54169, Direction=N/A */
+	uint8_t reserved2d4;		/* Byte offset 0x2d4, CSR Addr 0x5416a, Direction=N/A */
+	uint8_t reserved2d5;		/* Byte offset 0x2d5, CSR Addr 0x5416a, Direction=N/A */
+	uint8_t reserved2d6;		/* Byte offset 0x2d6, CSR Addr 0x5416b, Direction=N/A */
+	uint8_t reserved2d7;		/* Byte offset 0x2d7, CSR Addr 0x5416b, Direction=N/A */
+	uint8_t reserved2d8;		/* Byte offset 0x2d8, CSR Addr 0x5416c, Direction=N/A */
+	uint8_t reserved2d9;		/* Byte offset 0x2d9, CSR Addr 0x5416c, Direction=N/A */
+	uint8_t reserved2da;		/* Byte offset 0x2da, CSR Addr 0x5416d, Direction=N/A */
+	uint8_t reserved2db;		/* Byte offset 0x2db, CSR Addr 0x5416d, Direction=N/A */
+	uint8_t reserved2dc;		/* Byte offset 0x2dc, CSR Addr 0x5416e, Direction=N/A */
+	uint8_t reserved2dd;		/* Byte offset 0x2dd, CSR Addr 0x5416e, Direction=N/A */
+	uint8_t reserved2de;		/* Byte offset 0x2de, CSR Addr 0x5416f, Direction=N/A */
+	uint8_t reserved2df;		/* Byte offset 0x2df, CSR Addr 0x5416f, Direction=N/A */
+	uint8_t reserved2e0;		/* Byte offset 0x2e0, CSR Addr 0x54170, Direction=N/A */
+	uint8_t reserved2e1;		/* Byte offset 0x2e1, CSR Addr 0x54170, Direction=N/A */
+	uint8_t reserved2e2;		/* Byte offset 0x2e2, CSR Addr 0x54171, Direction=N/A */
+	uint8_t reserved2e3;		/* Byte offset 0x2e3, CSR Addr 0x54171, Direction=N/A */
+	uint8_t reserved2e4;		/* Byte offset 0x2e4, CSR Addr 0x54172, Direction=N/A */
+	uint8_t reserved2e5;		/* Byte offset 0x2e5, CSR Addr 0x54172, Direction=N/A */
+	uint8_t reserved2e6;		/* Byte offset 0x2e6, CSR Addr 0x54173, Direction=N/A */
+	uint8_t reserved2e7;		/* Byte offset 0x2e7, CSR Addr 0x54173, Direction=N/A */
+	uint8_t reserved2e8;		/* Byte offset 0x2e8, CSR Addr 0x54174, Direction=N/A */
+	uint8_t reserved2e9;		/* Byte offset 0x2e9, CSR Addr 0x54174, Direction=N/A */
+	uint8_t reserved2ea;		/* Byte offset 0x2ea, CSR Addr 0x54175, Direction=N/A */
+	uint8_t reserved2eb;		/* Byte offset 0x2eb, CSR Addr 0x54175, Direction=N/A */
+	uint8_t reserved2ec;		/* Byte offset 0x2ec, CSR Addr 0x54176, Direction=N/A */
+	uint8_t reserved2ed;		/* Byte offset 0x2ed, CSR Addr 0x54176, Direction=N/A */
+	uint8_t reserved2ee;		/* Byte offset 0x2ee, CSR Addr 0x54177, Direction=N/A */
+	uint8_t reserved2ef;		/* Byte offset 0x2ef, CSR Addr 0x54177, Direction=N/A */
+	uint8_t reserved2f0;		/* Byte offset 0x2f0, CSR Addr 0x54178, Direction=N/A */
+	uint8_t reserved2f1;		/* Byte offset 0x2f1, CSR Addr 0x54178, Direction=N/A */
+	uint8_t reserved2f2;		/* Byte offset 0x2f2, CSR Addr 0x54179, Direction=N/A */
+	uint8_t reserved2f3;		/* Byte offset 0x2f3, CSR Addr 0x54179, Direction=N/A */
+	uint8_t reserved2f4;		/* Byte offset 0x2f4, CSR Addr 0x5417a, Direction=N/A */
+	uint8_t reserved2f5;		/* Byte offset 0x2f5, CSR Addr 0x5417a, Direction=N/A */
+	uint8_t reserved2f6;		/* Byte offset 0x2f6, CSR Addr 0x5417b, Direction=N/A */
+	uint8_t reserved2f7;		/* Byte offset 0x2f7, CSR Addr 0x5417b, Direction=N/A */
+	uint8_t reserved2f8;		/* Byte offset 0x2f8, CSR Addr 0x5417c, Direction=N/A */
+	uint8_t reserved2f9;		/* Byte offset 0x2f9, CSR Addr 0x5417c, Direction=N/A */
+	uint8_t reserved2fa;		/* Byte offset 0x2fa, CSR Addr 0x5417d, Direction=N/A */
+	uint8_t reserved2fb;		/* Byte offset 0x2fb, CSR Addr 0x5417d, Direction=N/A */
+	uint8_t reserved2fc;		/* Byte offset 0x2fc, CSR Addr 0x5417e, Direction=N/A */
+	uint8_t reserved2fd;		/* Byte offset 0x2fd, CSR Addr 0x5417e, Direction=N/A */
+	uint8_t reserved2fe;		/* Byte offset 0x2fe, CSR Addr 0x5417f, Direction=N/A */
+	uint8_t reserved2ff;		/* Byte offset 0x2ff, CSR Addr 0x5417f, Direction=N/A */
+	uint8_t reserved300;		/* Byte offset 0x300, CSR Addr 0x54180, Direction=N/A */
+	uint8_t reserved301;		/* Byte offset 0x301, CSR Addr 0x54180, Direction=N/A */
+	uint8_t reserved302;		/* Byte offset 0x302, CSR Addr 0x54181, Direction=N/A */
+	uint8_t reserved303;		/* Byte offset 0x303, CSR Addr 0x54181, Direction=N/A */
+	uint8_t reserved304;		/* Byte offset 0x304, CSR Addr 0x54182, Direction=N/A */
+	uint8_t reserved305;		/* Byte offset 0x305, CSR Addr 0x54182, Direction=N/A */
+	uint8_t reserved306;		/* Byte offset 0x306, CSR Addr 0x54183, Direction=N/A */
+	uint8_t reserved307;		/* Byte offset 0x307, CSR Addr 0x54183, Direction=N/A */
+	uint8_t reserved308;		/* Byte offset 0x308, CSR Addr 0x54184, Direction=N/A */
+	uint8_t reserved309;		/* Byte offset 0x309, CSR Addr 0x54184, Direction=N/A */
+	uint8_t reserved30a;		/* Byte offset 0x30a, CSR Addr 0x54185, Direction=N/A */
+	uint8_t reserved30b;		/* Byte offset 0x30b, CSR Addr 0x54185, Direction=N/A */
+	uint8_t reserved30c;		/* Byte offset 0x30c, CSR Addr 0x54186, Direction=N/A */
+	uint8_t reserved30d;		/* Byte offset 0x30d, CSR Addr 0x54186, Direction=N/A */
+	uint8_t reserved30e;		/* Byte offset 0x30e, CSR Addr 0x54187, Direction=N/A */
+	uint8_t reserved30f;		/* Byte offset 0x30f, CSR Addr 0x54187, Direction=N/A */
+	uint8_t reserved310;		/* Byte offset 0x310, CSR Addr 0x54188, Direction=N/A */
+	uint8_t reserved311;		/* Byte offset 0x311, CSR Addr 0x54188, Direction=N/A */
+	uint8_t reserved312;		/* Byte offset 0x312, CSR Addr 0x54189, Direction=N/A */
+	uint8_t reserved313;		/* Byte offset 0x313, CSR Addr 0x54189, Direction=N/A */
+	uint8_t reserved314;		/* Byte offset 0x314, CSR Addr 0x5418a, Direction=N/A */
+	uint8_t reserved315;		/* Byte offset 0x315, CSR Addr 0x5418a, Direction=N/A */
+	uint8_t reserved316;		/* Byte offset 0x316, CSR Addr 0x5418b, Direction=N/A */
+	uint8_t reserved317;		/* Byte offset 0x317, CSR Addr 0x5418b, Direction=N/A */
+	uint8_t reserved318;		/* Byte offset 0x318, CSR Addr 0x5418c, Direction=N/A */
+	uint8_t reserved319;		/* Byte offset 0x319, CSR Addr 0x5418c, Direction=N/A */
+	uint8_t reserved31a;		/* Byte offset 0x31a, CSR Addr 0x5418d, Direction=N/A */
+	uint8_t reserved31b;		/* Byte offset 0x31b, CSR Addr 0x5418d, Direction=N/A */
+	uint8_t reserved31c;		/* Byte offset 0x31c, CSR Addr 0x5418e, Direction=N/A */
+	uint8_t reserved31d;		/* Byte offset 0x31d, CSR Addr 0x5418e, Direction=N/A */
+	uint8_t reserved31e;		/* Byte offset 0x31e, CSR Addr 0x5418f, Direction=N/A */
+	uint8_t reserved31f;		/* Byte offset 0x31f, CSR Addr 0x5418f, Direction=N/A */
+	uint8_t reserved320;		/* Byte offset 0x320, CSR Addr 0x54190, Direction=N/A */
+	uint8_t reserved321;		/* Byte offset 0x321, CSR Addr 0x54190, Direction=N/A */
+	uint8_t reserved322;		/* Byte offset 0x322, CSR Addr 0x54191, Direction=N/A */
+	uint8_t reserved323;		/* Byte offset 0x323, CSR Addr 0x54191, Direction=N/A */
+	uint8_t reserved324;		/* Byte offset 0x324, CSR Addr 0x54192, Direction=N/A */
+	uint8_t reserved325;		/* Byte offset 0x325, CSR Addr 0x54192, Direction=N/A */
+	uint8_t reserved326;		/* Byte offset 0x326, CSR Addr 0x54193, Direction=N/A */
+	uint8_t reserved327;		/* Byte offset 0x327, CSR Addr 0x54193, Direction=N/A */
+	uint8_t reserved328;		/* Byte offset 0x328, CSR Addr 0x54194, Direction=N/A */
+	uint8_t reserved329;		/* Byte offset 0x329, CSR Addr 0x54194, Direction=N/A */
+	uint8_t reserved32a;		/* Byte offset 0x32a, CSR Addr 0x54195, Direction=N/A */
+	uint8_t reserved32b;		/* Byte offset 0x32b, CSR Addr 0x54195, Direction=N/A */
+	uint8_t reserved32c;		/* Byte offset 0x32c, CSR Addr 0x54196, Direction=N/A */
+	uint8_t reserved32d;		/* Byte offset 0x32d, CSR Addr 0x54196, Direction=N/A */
+	uint8_t reserved32e;		/* Byte offset 0x32e, CSR Addr 0x54197, Direction=N/A */
+	uint8_t reserved32f;		/* Byte offset 0x32f, CSR Addr 0x54197, Direction=N/A */
+	uint8_t reserved330;		/* Byte offset 0x330, CSR Addr 0x54198, Direction=N/A */
+	uint8_t reserved331;		/* Byte offset 0x331, CSR Addr 0x54198, Direction=N/A */
+	uint8_t reserved332;		/* Byte offset 0x332, CSR Addr 0x54199, Direction=N/A */
+	uint8_t reserved333;		/* Byte offset 0x333, CSR Addr 0x54199, Direction=N/A */
+	uint8_t reserved334;		/* Byte offset 0x334, CSR Addr 0x5419a, Direction=N/A */
+	uint8_t reserved335;		/* Byte offset 0x335, CSR Addr 0x5419a, Direction=N/A */
+	uint8_t reserved336;		/* Byte offset 0x336, CSR Addr 0x5419b, Direction=N/A */
+	uint8_t reserved337;		/* Byte offset 0x337, CSR Addr 0x5419b, Direction=N/A */
+	uint8_t reserved338;		/* Byte offset 0x338, CSR Addr 0x5419c, Direction=N/A */
+	uint8_t reserved339;		/* Byte offset 0x339, CSR Addr 0x5419c, Direction=N/A */
+	uint8_t reserved33a;		/* Byte offset 0x33a, CSR Addr 0x5419d, Direction=N/A */
+	uint8_t reserved33b;		/* Byte offset 0x33b, CSR Addr 0x5419d, Direction=N/A */
+	uint8_t reserved33c;		/* Byte offset 0x33c, CSR Addr 0x5419e, Direction=N/A */
+	uint8_t reserved33d;		/* Byte offset 0x33d, CSR Addr 0x5419e, Direction=N/A */
+	uint8_t reserved33e;		/* Byte offset 0x33e, CSR Addr 0x5419f, Direction=N/A */
+	uint8_t reserved33f;		/* Byte offset 0x33f, CSR Addr 0x5419f, Direction=N/A */
+	uint8_t reserved340;		/* Byte offset 0x340, CSR Addr 0x541a0, Direction=N/A */
+	uint8_t reserved341;		/* Byte offset 0x341, CSR Addr 0x541a0, Direction=N/A */
+	uint8_t reserved342;		/* Byte offset 0x342, CSR Addr 0x541a1, Direction=N/A */
+	uint8_t reserved343;		/* Byte offset 0x343, CSR Addr 0x541a1, Direction=N/A */
+	uint8_t reserved344;		/* Byte offset 0x344, CSR Addr 0x541a2, Direction=N/A */
+	uint8_t reserved345;		/* Byte offset 0x345, CSR Addr 0x541a2, Direction=N/A */
+	uint8_t reserved346;		/* Byte offset 0x346, CSR Addr 0x541a3, Direction=N/A */
+	uint8_t reserved347;		/* Byte offset 0x347, CSR Addr 0x541a3, Direction=N/A */
+	uint8_t reserved348;		/* Byte offset 0x348, CSR Addr 0x541a4, Direction=N/A */
+	uint8_t reserved349;		/* Byte offset 0x349, CSR Addr 0x541a4, Direction=N/A */
+	uint8_t reserved34a;		/* Byte offset 0x34a, CSR Addr 0x541a5, Direction=N/A */
+	uint8_t reserved34b;		/* Byte offset 0x34b, CSR Addr 0x541a5, Direction=N/A */
+	uint8_t reserved34c;		/* Byte offset 0x34c, CSR Addr 0x541a6, Direction=N/A */
+	uint8_t reserved34d;		/* Byte offset 0x34d, CSR Addr 0x541a6, Direction=N/A */
+	uint8_t reserved34e;		/* Byte offset 0x34e, CSR Addr 0x541a7, Direction=N/A */
+	uint8_t reserved34f;		/* Byte offset 0x34f, CSR Addr 0x541a7, Direction=N/A */
+	uint8_t reserved350;		/* Byte offset 0x350, CSR Addr 0x541a8, Direction=N/A */
+	uint8_t reserved351;		/* Byte offset 0x351, CSR Addr 0x541a8, Direction=N/A */
+	uint8_t reserved352;		/* Byte offset 0x352, CSR Addr 0x541a9, Direction=N/A */
+	uint8_t reserved353;		/* Byte offset 0x353, CSR Addr 0x541a9, Direction=N/A */
+	uint8_t reserved354;		/* Byte offset 0x354, CSR Addr 0x541aa, Direction=N/A */
+	uint8_t reserved355;		/* Byte offset 0x355, CSR Addr 0x541aa, Direction=N/A */
+	uint8_t reserved356;		/* Byte offset 0x356, CSR Addr 0x541ab, Direction=N/A */
+	uint8_t reserved357;		/* Byte offset 0x357, CSR Addr 0x541ab, Direction=N/A */
+	uint8_t reserved358;		/* Byte offset 0x358, CSR Addr 0x541ac, Direction=N/A */
+	uint8_t reserved359;		/* Byte offset 0x359, CSR Addr 0x541ac, Direction=N/A */
+	uint8_t reserved35a;		/* Byte offset 0x35a, CSR Addr 0x541ad, Direction=N/A */
+	uint8_t reserved35b;		/* Byte offset 0x35b, CSR Addr 0x541ad, Direction=N/A */
+	uint8_t reserved35c;		/* Byte offset 0x35c, CSR Addr 0x541ae, Direction=N/A */
+	uint8_t reserved35d;		/* Byte offset 0x35d, CSR Addr 0x541ae, Direction=N/A */
+	uint8_t reserved35e;		/* Byte offset 0x35e, CSR Addr 0x541af, Direction=N/A */
+	uint8_t reserved35f;		/* Byte offset 0x35f, CSR Addr 0x541af, Direction=N/A */
+	uint8_t reserved360;		/* Byte offset 0x360, CSR Addr 0x541b0, Direction=N/A */
+	uint8_t reserved361;		/* Byte offset 0x361, CSR Addr 0x541b0, Direction=N/A */
+	uint8_t reserved362;		/* Byte offset 0x362, CSR Addr 0x541b1, Direction=N/A */
+	uint8_t reserved363;		/* Byte offset 0x363, CSR Addr 0x541b1, Direction=N/A */
+	uint8_t reserved364;		/* Byte offset 0x364, CSR Addr 0x541b2, Direction=N/A */
+	uint8_t reserved365;		/* Byte offset 0x365, CSR Addr 0x541b2, Direction=N/A */
+	uint8_t reserved366;		/* Byte offset 0x366, CSR Addr 0x541b3, Direction=N/A */
+	uint8_t reserved367;		/* Byte offset 0x367, CSR Addr 0x541b3, Direction=N/A */
+	uint8_t reserved368;		/* Byte offset 0x368, CSR Addr 0x541b4, Direction=N/A */
+	uint8_t reserved369;		/* Byte offset 0x369, CSR Addr 0x541b4, Direction=N/A */
+	uint8_t reserved36a;		/* Byte offset 0x36a, CSR Addr 0x541b5, Direction=N/A */
+	uint8_t reserved36b;		/* Byte offset 0x36b, CSR Addr 0x541b5, Direction=N/A */
+	uint8_t reserved36c;		/* Byte offset 0x36c, CSR Addr 0x541b6, Direction=N/A */
+	uint8_t reserved36d;		/* Byte offset 0x36d, CSR Addr 0x541b6, Direction=N/A */
+	uint8_t reserved36e;		/* Byte offset 0x36e, CSR Addr 0x541b7, Direction=N/A */
+	uint8_t reserved36f;		/* Byte offset 0x36f, CSR Addr 0x541b7, Direction=N/A */
+	uint8_t reserved370;		/* Byte offset 0x370, CSR Addr 0x541b8, Direction=N/A */
+	uint8_t reserved371;		/* Byte offset 0x371, CSR Addr 0x541b8, Direction=N/A */
+	uint8_t reserved372;		/* Byte offset 0x372, CSR Addr 0x541b9, Direction=N/A */
+	uint8_t reserved373;		/* Byte offset 0x373, CSR Addr 0x541b9, Direction=N/A */
+	uint8_t reserved374;		/* Byte offset 0x374, CSR Addr 0x541ba, Direction=N/A */
+	uint8_t reserved375;		/* Byte offset 0x375, CSR Addr 0x541ba, Direction=N/A */
+	uint8_t reserved376;		/* Byte offset 0x376, CSR Addr 0x541bb, Direction=N/A */
+	uint8_t reserved377;		/* Byte offset 0x377, CSR Addr 0x541bb, Direction=N/A */
+	uint8_t reserved378;		/* Byte offset 0x378, CSR Addr 0x541bc, Direction=N/A */
+	uint8_t reserved379;		/* Byte offset 0x379, CSR Addr 0x541bc, Direction=N/A */
+	uint8_t reserved37a;		/* Byte offset 0x37a, CSR Addr 0x541bd, Direction=N/A */
+	uint8_t reserved37b;		/* Byte offset 0x37b, CSR Addr 0x541bd, Direction=N/A */
+	uint8_t reserved37c;		/* Byte offset 0x37c, CSR Addr 0x541be, Direction=N/A */
+	uint8_t reserved37d;		/* Byte offset 0x37d, CSR Addr 0x541be, Direction=N/A */
+	uint8_t reserved37e;		/* Byte offset 0x37e, CSR Addr 0x541bf, Direction=N/A */
+	uint8_t reserved37f;		/* Byte offset 0x37f, CSR Addr 0x541bf, Direction=N/A */
+	uint8_t reserved380;		/* Byte offset 0x380, CSR Addr 0x541c0, Direction=N/A */
+	uint8_t reserved381;		/* Byte offset 0x381, CSR Addr 0x541c0, Direction=N/A */
+	uint8_t reserved382;		/* Byte offset 0x382, CSR Addr 0x541c1, Direction=N/A */
+	uint8_t reserved383;		/* Byte offset 0x383, CSR Addr 0x541c1, Direction=N/A */
+	uint8_t reserved384;		/* Byte offset 0x384, CSR Addr 0x541c2, Direction=N/A */
+	uint8_t reserved385;		/* Byte offset 0x385, CSR Addr 0x541c2, Direction=N/A */
+	uint8_t reserved386;		/* Byte offset 0x386, CSR Addr 0x541c3, Direction=N/A */
+	uint8_t reserved387;		/* Byte offset 0x387, CSR Addr 0x541c3, Direction=N/A */
+	uint8_t reserved388;		/* Byte offset 0x388, CSR Addr 0x541c4, Direction=N/A */
+	uint8_t reserved389;		/* Byte offset 0x389, CSR Addr 0x541c4, Direction=N/A */
+	uint8_t reserved38a;		/* Byte offset 0x38a, CSR Addr 0x541c5, Direction=N/A */
+	uint8_t reserved38b;		/* Byte offset 0x38b, CSR Addr 0x541c5, Direction=N/A */
+	uint8_t reserved38c;		/* Byte offset 0x38c, CSR Addr 0x541c6, Direction=N/A */
+	uint8_t reserved38d;		/* Byte offset 0x38d, CSR Addr 0x541c6, Direction=N/A */
+	uint8_t reserved38e;		/* Byte offset 0x38e, CSR Addr 0x541c7, Direction=N/A */
+	uint8_t reserved38f;		/* Byte offset 0x38f, CSR Addr 0x541c7, Direction=N/A */
+	uint8_t reserved390;		/* Byte offset 0x390, CSR Addr 0x541c8, Direction=N/A */
+	uint8_t reserved391;		/* Byte offset 0x391, CSR Addr 0x541c8, Direction=N/A */
+	uint8_t reserved392;		/* Byte offset 0x392, CSR Addr 0x541c9, Direction=N/A */
+	uint8_t reserved393;		/* Byte offset 0x393, CSR Addr 0x541c9, Direction=N/A */
+	uint8_t reserved394;		/* Byte offset 0x394, CSR Addr 0x541ca, Direction=N/A */
+	uint8_t reserved395;		/* Byte offset 0x395, CSR Addr 0x541ca, Direction=N/A */
+	uint8_t reserved396;		/* Byte offset 0x396, CSR Addr 0x541cb, Direction=N/A */
+	uint8_t reserved397;		/* Byte offset 0x397, CSR Addr 0x541cb, Direction=N/A */
+	uint8_t reserved398;		/* Byte offset 0x398, CSR Addr 0x541cc, Direction=N/A */
+	uint8_t reserved399;		/* Byte offset 0x399, CSR Addr 0x541cc, Direction=N/A */
+	uint8_t reserved39a;		/* Byte offset 0x39a, CSR Addr 0x541cd, Direction=N/A */
+	uint8_t reserved39b;		/* Byte offset 0x39b, CSR Addr 0x541cd, Direction=N/A */
+	uint8_t reserved39c;		/* Byte offset 0x39c, CSR Addr 0x541ce, Direction=N/A */
+	uint8_t reserved39d;		/* Byte offset 0x39d, CSR Addr 0x541ce, Direction=N/A */
+	uint8_t reserved39e;		/* Byte offset 0x39e, CSR Addr 0x541cf, Direction=N/A */
+	uint8_t reserved39f;		/* Byte offset 0x39f, CSR Addr 0x541cf, Direction=N/A */
+	uint8_t reserved3a0;		/* Byte offset 0x3a0, CSR Addr 0x541d0, Direction=N/A */
+	uint8_t reserved3a1;		/* Byte offset 0x3a1, CSR Addr 0x541d0, Direction=N/A */
+	uint8_t reserved3a2;		/* Byte offset 0x3a2, CSR Addr 0x541d1, Direction=N/A */
+	uint8_t reserved3a3;		/* Byte offset 0x3a3, CSR Addr 0x541d1, Direction=N/A */
+	uint8_t reserved3a4;		/* Byte offset 0x3a4, CSR Addr 0x541d2, Direction=N/A */
+	uint8_t reserved3a5;		/* Byte offset 0x3a5, CSR Addr 0x541d2, Direction=N/A */
+	uint8_t reserved3a6;		/* Byte offset 0x3a6, CSR Addr 0x541d3, Direction=N/A */
+	uint8_t reserved3a7;		/* Byte offset 0x3a7, CSR Addr 0x541d3, Direction=N/A */
+	uint8_t reserved3a8;		/* Byte offset 0x3a8, CSR Addr 0x541d4, Direction=N/A */
+	uint8_t reserved3a9;		/* Byte offset 0x3a9, CSR Addr 0x541d4, Direction=N/A */
+	uint8_t reserved3aa;		/* Byte offset 0x3aa, CSR Addr 0x541d5, Direction=N/A */
+	uint8_t reserved3ab;		/* Byte offset 0x3ab, CSR Addr 0x541d5, Direction=N/A */
+	uint8_t reserved3ac;		/* Byte offset 0x3ac, CSR Addr 0x541d6, Direction=N/A */
+	uint8_t reserved3ad;		/* Byte offset 0x3ad, CSR Addr 0x541d6, Direction=N/A */
+	uint8_t reserved3ae;		/* Byte offset 0x3ae, CSR Addr 0x541d7, Direction=N/A */
+	uint8_t reserved3af;		/* Byte offset 0x3af, CSR Addr 0x541d7, Direction=N/A */
+	uint8_t reserved3b0;		/* Byte offset 0x3b0, CSR Addr 0x541d8, Direction=N/A */
+	uint8_t reserved3b1;		/* Byte offset 0x3b1, CSR Addr 0x541d8, Direction=N/A */
+	uint8_t reserved3b2;		/* Byte offset 0x3b2, CSR Addr 0x541d9, Direction=N/A */
+	uint8_t reserved3b3;		/* Byte offset 0x3b3, CSR Addr 0x541d9, Direction=N/A */
+	uint8_t reserved3b4;		/* Byte offset 0x3b4, CSR Addr 0x541da, Direction=N/A */
+	uint8_t reserved3b5;		/* Byte offset 0x3b5, CSR Addr 0x541da, Direction=N/A */
+	uint8_t reserved3b6;		/* Byte offset 0x3b6, CSR Addr 0x541db, Direction=N/A */
+	uint8_t reserved3b7;		/* Byte offset 0x3b7, CSR Addr 0x541db, Direction=N/A */
+	uint8_t reserved3b8;		/* Byte offset 0x3b8, CSR Addr 0x541dc, Direction=N/A */
+	uint8_t reserved3b9;		/* Byte offset 0x3b9, CSR Addr 0x541dc, Direction=N/A */
+	uint8_t reserved3ba;		/* Byte offset 0x3ba, CSR Addr 0x541dd, Direction=N/A */
+	uint8_t reserved3bb;		/* Byte offset 0x3bb, CSR Addr 0x541dd, Direction=N/A */
+	uint8_t reserved3bc;		/* Byte offset 0x3bc, CSR Addr 0x541de, Direction=N/A */
+	uint8_t reserved3bd;		/* Byte offset 0x3bd, CSR Addr 0x541de, Direction=N/A */
+	uint8_t reserved3be;		/* Byte offset 0x3be, CSR Addr 0x541df, Direction=N/A */
+	uint8_t reserved3bf;		/* Byte offset 0x3bf, CSR Addr 0x541df, Direction=N/A */
+	uint8_t reserved3c0;		/* Byte offset 0x3c0, CSR Addr 0x541e0, Direction=N/A */
+	uint8_t reserved3c1;		/* Byte offset 0x3c1, CSR Addr 0x541e0, Direction=N/A */
+	uint8_t reserved3c2;		/* Byte offset 0x3c2, CSR Addr 0x541e1, Direction=N/A */
+	uint8_t reserved3c3;		/* Byte offset 0x3c3, CSR Addr 0x541e1, Direction=N/A */
+	uint8_t reserved3c4;		/* Byte offset 0x3c4, CSR Addr 0x541e2, Direction=N/A */
+	uint8_t reserved3c5;		/* Byte offset 0x3c5, CSR Addr 0x541e2, Direction=N/A */
+	uint8_t reserved3c6;		/* Byte offset 0x3c6, CSR Addr 0x541e3, Direction=N/A */
+	uint8_t reserved3c7;		/* Byte offset 0x3c7, CSR Addr 0x541e3, Direction=N/A */
+	uint8_t reserved3c8;		/* Byte offset 0x3c8, CSR Addr 0x541e4, Direction=N/A */
+	uint8_t reserved3c9;		/* Byte offset 0x3c9, CSR Addr 0x541e4, Direction=N/A */
+	uint8_t reserved3ca;		/* Byte offset 0x3ca, CSR Addr 0x541e5, Direction=N/A */
+	uint8_t reserved3cb;		/* Byte offset 0x3cb, CSR Addr 0x541e5, Direction=N/A */
+	uint8_t reserved3cc;		/* Byte offset 0x3cc, CSR Addr 0x541e6, Direction=N/A */
+	uint8_t reserved3cd;		/* Byte offset 0x3cd, CSR Addr 0x541e6, Direction=N/A */
+	uint8_t reserved3ce;		/* Byte offset 0x3ce, CSR Addr 0x541e7, Direction=N/A */
+	uint8_t reserved3cf;		/* Byte offset 0x3cf, CSR Addr 0x541e7, Direction=N/A */
+	uint8_t reserved3d0;		/* Byte offset 0x3d0, CSR Addr 0x541e8, Direction=N/A */
+	uint8_t reserved3d1;		/* Byte offset 0x3d1, CSR Addr 0x541e8, Direction=N/A */
+	uint8_t reserved3d2;		/* Byte offset 0x3d2, CSR Addr 0x541e9, Direction=N/A */
+	uint8_t reserved3d3;		/* Byte offset 0x3d3, CSR Addr 0x541e9, Direction=N/A */
+	uint8_t reserved3d4;		/* Byte offset 0x3d4, CSR Addr 0x541ea, Direction=N/A */
+	uint8_t reserved3d5;		/* Byte offset 0x3d5, CSR Addr 0x541ea, Direction=N/A */
+	uint8_t reserved3d6;		/* Byte offset 0x3d6, CSR Addr 0x541eb, Direction=N/A */
+	uint8_t reserved3d7;		/* Byte offset 0x3d7, CSR Addr 0x541eb, Direction=N/A */
+	uint8_t reserved3d8;		/* Byte offset 0x3d8, CSR Addr 0x541ec, Direction=N/A */
+	uint8_t reserved3d9;		/* Byte offset 0x3d9, CSR Addr 0x541ec, Direction=N/A */
+	uint8_t reserved3da;		/* Byte offset 0x3da, CSR Addr 0x541ed, Direction=N/A */
+	uint8_t reserved3db;		/* Byte offset 0x3db, CSR Addr 0x541ed, Direction=N/A */
+	uint8_t reserved3dc;		/* Byte offset 0x3dc, CSR Addr 0x541ee, Direction=N/A */
+	uint8_t reserved3dd;		/* Byte offset 0x3dd, CSR Addr 0x541ee, Direction=N/A */
+	uint8_t reserved3de;		/* Byte offset 0x3de, CSR Addr 0x541ef, Direction=N/A */
+	uint8_t reserved3df;		/* Byte offset 0x3df, CSR Addr 0x541ef, Direction=N/A */
+	uint8_t reserved3e0;		/* Byte offset 0x3e0, CSR Addr 0x541f0, Direction=N/A */
+	uint8_t reserved3e1;		/* Byte offset 0x3e1, CSR Addr 0x541f0, Direction=N/A */
+	uint8_t reserved3e2;		/* Byte offset 0x3e2, CSR Addr 0x541f1, Direction=N/A */
+	uint8_t reserved3e3;		/* Byte offset 0x3e3, CSR Addr 0x541f1, Direction=N/A */
+	uint8_t reserved3e4;		/* Byte offset 0x3e4, CSR Addr 0x541f2, Direction=N/A */
+	uint8_t reserved3e5;		/* Byte offset 0x3e5, CSR Addr 0x541f2, Direction=N/A */
+	uint8_t reserved3e6;		/* Byte offset 0x3e6, CSR Addr 0x541f3, Direction=N/A */
+	uint8_t reserved3e7;		/* Byte offset 0x3e7, CSR Addr 0x541f3, Direction=N/A */
+	uint8_t reserved3e8;		/* Byte offset 0x3e8, CSR Addr 0x541f4, Direction=N/A */
+	uint8_t reserved3e9;		/* Byte offset 0x3e9, CSR Addr 0x541f4, Direction=N/A */
+	uint8_t reserved3ea;		/* Byte offset 0x3ea, CSR Addr 0x541f5, Direction=N/A */
+	uint8_t reserved3eb;		/* Byte offset 0x3eb, CSR Addr 0x541f5, Direction=N/A */
+	uint8_t reserved3ec;		/* Byte offset 0x3ec, CSR Addr 0x541f6, Direction=N/A */
+	uint8_t reserved3ed;		/* Byte offset 0x3ed, CSR Addr 0x541f6, Direction=N/A */
+	uint8_t reserved3ee;		/* Byte offset 0x3ee, CSR Addr 0x541f7, Direction=N/A */
+	uint8_t reserved3ef;		/* Byte offset 0x3ef, CSR Addr 0x541f7, Direction=N/A */
+	uint8_t reserved3f0;		/* Byte offset 0x3f0, CSR Addr 0x541f8, Direction=N/A */
+	uint8_t reserved3f1;		/* Byte offset 0x3f1, CSR Addr 0x541f8, Direction=N/A */
+	uint8_t reserved3f2;		/* Byte offset 0x3f2, CSR Addr 0x541f9, Direction=N/A */
+	uint8_t reserved3f3;		/* Byte offset 0x3f3, CSR Addr 0x541f9, Direction=N/A */
+	uint8_t reserved3f4;		/* Byte offset 0x3f4, CSR Addr 0x541fa, Direction=N/A */
+	uint8_t reserved3f5;		/* Byte offset 0x3f5, CSR Addr 0x541fa, Direction=N/A */
+	uint16_t alt_cas_l;		/*
+					 * Byte offset 0x3f6, CSR Addr 0x541fb, Direction=in
+					 * This field must be populated if RdDBI is enabled
+					 * (applicable when mr5[A12] == 1).
+					 * RdDBI is dynamically disabled in certain training steps,
+					 * and so the [RdDBI disabled] CAS Latency must be provided
+					 * in this field.
+					 * The required encoding is as follows:
+					 * alt_cas_l[0] == 0: use value in mr0
+					 * alt_cas_l[0] == 1: use value in alt_cas_l, i.e.,
+					 *   mr0{A[12],A[6],A[5],A[4],A[2]} = alt_cas_l[12,6,5,4,2]
+					 * Other bits are ignored
+					 */
+	uint8_t alt_wcas_l;		/*
+					 * Byte offset 0x3f8, CSR Addr 0x541fc, Direction=In
+					 * This field must be populated if 2tCK write preambles are
+					 * enabled (applicable when mr4[A12] == 1).
+					 * 2tCK write prambles are dynamically disabled in certain
+					 * training steps, and so the [1tCK write preamble] WCAS
+					 * Latency must be provided in this field.
+					 * The required encoding is as follows:
+					 * alt_wcas_l[0] == 0: use value in mr2
+					 * alt_wcas_l[0] == 1: use value in alt_wcas_l, i.e.,
+					 *   mr2{A[5],A[4],A[3]} = alt_wcas_l[5,4,3]
+					 * Other bits are ignored
+					 */
+	uint8_t d4misc;			/*
+					 * Byte offset 0x3f9, CSR Addr 0x541fc, Direction=In
+					 * Contains various options for training DDR4 Devices.
+					 *
+					 * Bit fields:
+					 *
+					 * d4misc[7:5,2,1] RFU, must be zero
+					 *
+					 * d4misc[0] = protect memory reset
+					 *   0x1 = dfi_reset_n cannot control BP_MEMRESERT_L to
+					 *         devices after training.
+					 *   0x0 = dfi_resert_n can control BP_MEMRESERT_L to
+					 *         devices after training
+					 *
+					 * d4misc[3]: reserved
+					 *
+					 * d4misc[4]: DRAM reset mode
+					 *   0x1 = Do not reset DRAM during devinit
+					 *   0x0 = Reset DRAM during devinit
+					 */
+} __packed __aligned(2);
+
+#endif /* MNPMUSRAMMSGBLOCK_DDR4_H */
diff --git a/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_lpddr4.h b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_lpddr4.h
new file mode 100644
index 0000000..fb1cd58
--- /dev/null
+++ b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_lpddr4.h
@@ -0,0 +1,925 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MNPMUSRAMMSGBLOCK_LPDDR4_H
+#define MNPMUSRAMMSGBLOCK_LPDDR4_H
+
+/* LPDDR4_1D training firmware message block structure
+ *
+ * Please refer to the Training Firmware App Note for futher information about
+ * the usage for Message Block.
+ */
+struct pmu_smb_ddr_1d {
+	uint8_t reserved00;		/*
+					 * Byte offset 0x00, CSR Addr 0x54000, Direction=In
+					 * reserved00[0:4] RFU, must be zero
+					 *
+					 * reserved00[5] = Quick Rd2D during 1D Training
+					 *   0x1 = Read Deskew will begin by enabling and quickly
+					 *   training the phy's per-lane reference voltages.
+					 *   Training the vrefDACs CSRs will increase the maximum 1D
+					 *   training time by around half a millisecond, but will
+					 *   improve 1D training accuracy on systems with
+					 *   significant voltage-offsets between lane read eyes.
+					 *   0x0 = Read Deskew will assume the messageblock's
+					 *   phyVref setting is optimal for all lanes.
+					 *
+					 * reserved00[6] = Enable High Effort WrDQ1D
+					 *   0x1 = WrDQ1D will conditionally retry training at
+					 *   several extra RxClkDly Timings. This will increase the
+					 *   maximum 1D training time by up to 4 extra iterations of
+					 *   WrDQ1D. This is only required in systems that suffer
+					 *   from very large, asymmetric eye-collapse when receiving
+					 *   PRBS patterns.
+					 *   0x0 = WrDQ1D assume rxClkDly values found by SI
+					 *   Friendly RdDqs1D will work for receiving PRBS patterns
+					 *
+					 * reserved00[7] = Optimize for the special hard macros in
+					 * TSMC28.
+					 *   0x1 = set if the phy being trained was manufactured in
+					 *   any TSMC28 process node.
+					 *   0x0 = otherwise, when not training a TSMC28 phy, leave
+					 *   this field as 0.
+					 */
+	uint8_t msgmisc;		/*
+					 * Byte offset 0x01, CSR Addr 0x54000, Direction=In
+					 * Contains various global options for training.
+					 *
+					 * Bit fields:
+					 *
+					 * msgmisc[0] MTESTEnable
+					 *   0x1 = Pulse primary digital test output bump at the end
+					 *   of each major training stage. This enables observation
+					 *   of training stage completion by observing the digital
+					 *   test output.
+					 *   0x0 = Do not pulse primary digital test output bump
+					 *
+					 * msgmisc[1] SimulationOnlyReset
+					 *   0x1 = Verilog only simulation option to shorten
+					 *   duration of DRAM reset pulse length to 1ns.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use reset pulse length specified by JEDEC
+					 *   standard.
+					 *
+					 * msgmisc[2] SimulationOnlyTraining
+					 *   0x1 = Verilog only simulation option to shorten the
+					 *   duration of the training steps by performing fewer
+					 *   iterations.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use standard training duration.
+					 *
+					 * msgmisc[3] Disable Boot Clock
+					 *   0x1 = Disable boot frequency clock when initializing
+					 *   DRAM. (not recommended)
+					 *   0x0 = Use Boot Frequency Clock
+					 *
+					 * msgmisc[4] Suppress streaming messages, including
+					 * assertions, regardless of hdtctrl setting.
+					 * Stage Completion messages, as well as training completion
+					 * and error messages are still sent depending on hdtctrl
+					 * setting.
+					 *
+					 * msgmisc[5] PerByteMaxRdLat
+					 *   0x1 = Each DBYTE will return dfi_rddata_valid at the
+					 *   lowest possible latency. This may result in unaligned
+					 *   data between bytes to be returned to the DFI.
+					 *   0x0 = Every DBYTE will return dfi_rddata_valid
+					 *   simultaneously. This will ensure that data bytes will
+					 *   return aligned accesses to the DFI.
+					 *
+					 * msgmisc[7-6] RFU, must be zero
+					 *
+					 * Notes:
+					 *
+					 * - SimulationOnlyReset and SimulationOnlyTraining can be
+					 *   used to speed up simulation run times, and must never
+					 *   be used in real silicon. Some VIPs may have checks on
+					 *   DRAM reset parameters that may need to be disabled when
+					 *   using SimulationOnlyReset.
+					 */
+	uint16_t pmurevision;		/*
+					 * Byte offset 0x02, CSR Addr 0x54001, Direction=Out
+					 * PMU firmware revision ID
+					 * After training is run, this address will contain the
+					 * revision ID of the firmware
+					 */
+	uint8_t pstate;			/*
+					 * Byte offset 0x04, CSR Addr 0x54002, Direction=In
+					 * Must be set to the target pstate to be trained
+					 *   0x0 = pstate 0
+					 *   0x1 = pstate 1
+					 *   0x2 = pstate 2
+					 *   0x3 = pstate 3
+					 *   All other encodings are reserved
+					 */
+	uint8_t pllbypassen;		/*
+					 * Byte offset 0x05, CSR Addr 0x54002, Direction=In
+					 * Set according to whether target pstate uses PHY PLL
+					 * bypass
+					 *   0x0 = PHY PLL is enabled for target pstate
+					 *   0x1 = PHY PLL is bypassed for target pstate
+					 */
+	uint16_t dramfreq;		/*
+					 * Byte offset 0x06, CSR Addr 0x54003, Direction=In
+					 * DDR data rate for the target pstate in units of MT/s.
+					 * For example enter 0x0640 for DDR1600.
+					 */
+	uint8_t dfifreqratio;		/*
+					 * Byte offset 0x08, CSR Addr 0x54004, Direction=In
+					 * Frequency ratio betwen DfiCtlClk and SDRAM memclk.
+					 *   0x1 = 1:1
+					 *   0x2 = 1:2
+					 *   0x4 = 1:4
+					 */
+	uint8_t bpznresval;		/*
+					 * Byte offset 0x09, CSR Addr 0x54004, Direction=In
+					 * Overwrite the value of precision resistor connected to
+					 * Phy BP_ZN
+					 *   0x00 = Do not program. Use current CSR value.
+					 *   0xf0 = 240 Ohm
+					 *   0x78 = 120 Ohm
+					 *   0x28 = 40 Ohm
+					 *   All other values are reserved.
+					 * It is recommended to set this to 0x00.
+					 */
+	uint8_t phyodtimpedance;	/*
+					 * Byte offset 0x0a, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the termination impedance in ohms
+					 * used by PHY during reads.
+					 *
+					 * 0x0 = Firmware skips programming (must be manually
+					 * programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal termination impedance values.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must determine the correct value
+					 * through SI simulation or other methods.
+					 */
+	uint8_t phydrvimpedance;	/*
+					 * Byte offset 0x0b, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the driver impedance in ohms used
+					 * by PHY during writes for all DBYTE drivers
+					 * (DQ/DM/DBI/DQS).
+					 *
+					 *   0x0 = Firmware skips programming (must be manually
+					 *   programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal R_on driver impedance values.
+					 *
+					 * For digital simulation, any value can be used that is not
+					 * Hi-Z. For silicon, the users must determine the correct
+					 * value through SI simulation or other methods.
+					 */
+	uint8_t phyvref;		/*
+					 * Byte offset 0x0c, CSR Addr 0x54006, Direction=In
+					 * Must be programmed with the Vref level to be used by the
+					 * PHY during reads
+					 *
+					 * The units of this field are a percentage of VDDQ
+					 * according to the following equation:
+					 *
+					 * Receiver Vref = VDDQ*phyvref[6:0]/128
+					 *
+					 * For example to set Vref at 0.25*VDDQ, set this field to
+					 * 0x20.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must calculate the analytical Vref by
+					 * using the impedances, terminations, and series resistance
+					 * present in the system.
+					 */
+	uint8_t lp4misc;		/*
+					 * Byte offset 0x0d, CSR Addr 0x54006, Direction=In
+					 * Lp4 specific options for training.
+					 *
+					 * Bit fields:
+					 *
+					 * lp4misc[0] Enable dfi_reset_n
+					 *
+					 *   0x0 = (Recommended) PHY internal registers control
+					 *   memreset during training, and also after training.
+					 *   dfi_reset_n cannot control the PHY BP_MEMRESET_L pin.
+					 *
+					 *   0x1 = Enables dfi_reset_n to control memreset after
+					 *   training. PHY Internal registers control memreset
+					 *   during training only. To ensure that no glitches occur
+					 *   on BP_MEMRESET at the end of training, The MC must
+					 *   drive dfi_reset_n=1'b1 _prior to starting training_
+					 *
+					 * lp4misc[7-1] RFU, must be zero
+					 */
+	uint8_t reserved0e;		/*
+					 * Byte offset 0x0e, CSR Addr 0x54007, Direction=In
+					 * Bit Field for enabling optional 2D training features
+					 * that impact both Rx2D and Tx2D.
+					 *
+					 * reserved0E[0:3]: bitTimeControl
+					 * input for the amount of data bits 2D writes/reads per DQ
+					 * before deciding if any specific voltage and delay setting
+					 * passes or fails. Every time this input increases by 1,
+					 * the number of 2D data comparisons is doubled. The 2D run
+					 * time will increase proportionally to the number of bit
+					 * times requested per point.
+					 *   0 = 288 bits per point (legacy behavior)
+					 *   1 = 576 bits per point
+					 *   2 = 1.125 kilobits per point
+					 *     . . .
+					 *   15 = 9 megabits per point
+					 *
+					 * reserved0E[4]: Exhaustive2D
+					 *   0 = 2D optimization assumes the optimal trained point
+					 *   is near the 1D trained point (legacy behavior)
+					 *   1 = 2D optimization searches the entire passing region
+					 *   at the cost of run time. Recommended for optimal
+					 *   results any time the optimal trained point is expected
+					 *   to be near the edges of the eyes instead of near the 1D
+					 *   trained point.
+					 *
+					 * reserved0E[5]: Detect Vref Eye Truncation, ignored if
+					 * eyeWeight2DControl == 0.
+					 *   0 = 2D optimizes for the passing region it can measure.
+					 *   1 = For every eye, 2D checks If the legal voltage range
+					 *   truncated the eye. If the true voltage margin cannot be
+					 *   measured, 2D will optimize heavily for delay margin
+					 *   instead of using incomplete voltage margin data. Eyes
+					 *   that are not truncated will still be optimized using
+					 *   user programmed weights.
+					 *
+					 * reserved0E[6]: eyeWeight2DControl
+					 *   0 = Use 8 bit weights for Delay_Weight2D and
+					 *   Voltage_Weight2D and disable TrunkV behavior.
+					 *   1 = Use 4 bit weights for Delay_weight2D and
+					 *   Voltage_Weight2D and enable TrunkV behavior.
+					 *
+					 * reserved0E[7]: RFU, must be 0
+					 */
+	uint8_t cstestfail;		/*
+					 * Byte offset 0x0f, CSR Addr 0x54007, Direction=Out
+					 * This field will be set if training fails on any rank.
+					 *   0x0 = No failures
+					 *   non-zero = one or more ranks failed training
+					 */
+	uint16_t sequencectrl;		/*
+					 * Byte offset 0x10, CSR Addr 0x54008, Direction=In
+					 * Controls the training steps to be run. Each bit
+					 * corresponds to a training step.
+					 *
+					 * If the bit is set to 1, the training step will run.
+					 * If the bit is set to 0, the training step will be
+					 * skipped.
+					 *
+					 * Training step to bit mapping:
+					 * sequencectrl[0] = Run DevInit - Device/phy
+					 *                   initialization. Should always be set.
+					 * sequencectrl[1] = Run WrLvl - Write leveling
+					 * sequencectrl[2] = Run RxEn - Read gate training
+					 * sequencectrl[3] = Run RdDQS1D - 1d read dqs training
+					 * sequencectrl[4] = Run WrDQ1D - 1d write dq training
+					 * sequencectrl[5] = RFU, must be zero
+					 * sequencectrl[6] = RFU, must be zero
+					 * sequencectrl[7] = RFU, must be zero
+					 * sequencectrl[8] = Run RdDeskew - Per lane read dq deskew
+					 *                   training
+					 * sequencectrl[9] = Run MxRdLat - Max read latency training
+					 * sequencectrl[11-10] = RFU, must be zero
+					 * sequencectrl[12] = Run LPCA - CA Training
+					 * sequencectrl[15-13] = RFU, must be zero
+					 */
+	uint8_t hdtctrl;		/*
+					 * Byte offset 0x12, CSR Addr 0x54009, Direction=In
+					 * To control the total number of debug messages, a
+					 * verbosity subfield (hdtctrl, Hardware Debug Trace
+					 * Control) exists in the message block. Every message has a
+					 * verbosity level associated with it, and as the hdtctrl
+					 * value is increased, less important s messages stop being
+					 * sent through the mailboxes. The meanings of several major
+					 * hdtctrl thresholds are explained below:
+					 *
+					 *   0x04 = Maximal debug messages (e.g., Eye contours)
+					 *   0x05 = Detailed debug messages (e.g. Eye delays)
+					 *   0x0A = Coarse debug messages (e.g. rank information)
+					 *   0xC8 = Stage completion
+					 *   0xC9 = Assertion messages
+					 *   0xFF = Firmware completion messages only
+					 */
+	uint8_t reserved13;		/*
+					 * Byte offset 0x13, CSR Addr 0x54009, Direction=In
+					 *
+					 *   0 = Default operation, unchanged.
+					 *   Others = RD DQ calibration Training steps are completed
+					 *   with user specified pattern.
+					 */
+	uint8_t reserved14;		/*
+					 * Byte offset 0x14, CSR Addr 0x5400a, Direction=In
+					 * Configure rd2D search iteration from a starting seed
+					 * point:
+					 *
+					 * reserved14[5:0]: If reserved14[6] is 0, Number of search
+					 * iterations (if 0, then default is 20); otherwise if this
+					 * value non zero, this value is used as a delta to filter
+					 * out points during the averaging: when averaging over a
+					 * dimension (delay or voltage), the points having a margin
+					 * smaller than the max of the eye in this dimension by at
+					 * least this delta value are filtered out.
+					 *
+					 * reserved14[6]: If set, instead of search, extract center
+					 * using an averaging function over the eye surface area,
+					 * where some points can be filtered out using
+					 * reserved14[5:0]
+					 *
+					 * reserved14[7]: if set, start search with large step size,
+					 * decreasing at each 4 iterations, down to 1 (do not care
+					 * if reserved14[6] is set)
+					 */
+	uint8_t reserved15;		/*
+					 * Byte offset 0x15, CSR Addr 0x5400a, Direction=In
+					 * Configure wr2D search iteration from a starting seed
+					 * point:
+					 *
+					 * reserved15[5:0]: If reserved15[6] is 0, Number of search
+					 * iterations (if 0, then default is 20); otherwise if this
+					 * value non zero, this value is used as a delta to filter
+					 * out points during the averaging: when averaging over a
+					 * dimension (delay or voltage), the points having a margin
+					 * smaller than the max of the eye in this dimension by at
+					 * least this delta value are filtered out.
+					 *
+					 * reserved15[6]: If set, instead of search, extract center
+					 * using an averaging function over the eye surface area,
+					 * where some points can be filtered out using
+					 * reserved15[5:0]
+					 *
+					 * reserved15[7]: if set, start search with large step size,
+					 * decreasing at each 4 iterations, down to 1 (do not care
+					 * if reserved15[6] is set)
+					 */
+	uint8_t dfimrlmargin;		/*
+					 * Byte offset 0x16, CSR Addr 0x5400b, Direction=In
+					 * Margin added to smallest passing trained DFI Max Read
+					 * Latency value, in units of DFI clocks. Recommended to be
+					 * >= 1.
+					 *
+					 * This margin must include the maximum positive drift
+					 * expected in tDQSCK over the target temperature and
+					 * voltage range of the users system.
+					 */
+	uint8_t reserved17;		/*
+					 * Byte offset 0x17, CSR Addr 0x5400b, Direction=In
+					 * Configure DB from which extra info is dump during 2D
+					 * training when maximal debug is set:
+					 *
+					 * reserved17[3:0]: first DB
+					 *
+					 * reserved17[7:4]: number of DB, including first DB (if 0,
+					 * no extra debug per DB is dump)
+					 */
+	uint8_t usebroadcastmr;		/*
+					 * Byte offset 0x18, CSR Addr 0x5400c, Direction=In
+					 * Training firmware can optionally set per rank mode
+					 * register values for DRAM partial array self-refresh
+					 * features if desired.
+					 *
+					 *   0x0 = Use mr<1:4, 11:14, 16:17, 22, 24>_a0 for rank 0
+					 *	   channel A
+					 *	   Use mr<1:4, 11:14, 16:17, 22, 24>_b0 for rank 0
+					 *	   channel B
+					 *	   Use mr<1:4, 11:14, 16:17, 22, 24>_a1 for rank 1
+					 *	   channel A
+					 *	   Use mr<1:4, 11:14, 16:17, 22, 24>_b1 for rank 1
+					 *	   channel B
+					 *
+					 *   0x1 = Use mr<1:4, 11:14, 16:17, 22, 24>_a0 setting for
+					 *	   all channels/ranks
+					 *
+					 * It is recommended in most LPDDR4 system configurations
+					 * to set this to 1.
+					 * It is recommended in LPDDR4x system configurations to
+					 * set this to 0.
+					 */
+	uint8_t lp4quickboot;		/*
+					 * Byte offset 0x19, CSR Addr 0x5400c, Direction=In
+					 * Enable Quickboot. It must be set to 0x0 since Quickboot
+					 * is only supported in dedicated Quickboot firmware.
+					 */
+	uint8_t reserved1a;		/*
+					 * Byte offset 0x1a, CSR Addr 0x5400d, Direction=In
+					 * Input for constraining the range of vref(DQ) values
+					 * training will collect data for, usually reducing training
+					 * time. However, too large of a voltage range may cause
+					 * longer 2D training times while too small of a voltage
+					 * range may truncate passing regions. When in doubt, leave
+					 * this field set to 0.
+					 * Used by 2D stages: Rd2D, Wr2D
+					 *
+					 * reserved1A[0-3]: Rd2D Voltage Range
+					 *   0 = Training will search all phy vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from phyVref
+					 *   2 = limit to +/-4 %VDDQ from phyVref
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from phyVref
+					 *
+					 * reserved1A[4-7]: Wr2D Voltage Range
+					 *   0 = Training will search all dram vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from mr14
+					 *   2 = limit to +/-4 %VDDQ from mr14
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from mr14
+					 */
+	uint8_t catrainopt;		/*
+					 * Byte offset 0x1b, CSR Addr 0x5400d, Direction=In
+					 * CA training option bit field
+					 * [0] CA VREF Training
+					 *   1 = Enable CA VREF Training
+					 *   0 = Disable CA VREF Training
+					 *  WARNING: catrainopt[0] must be set to the same value in
+					 *  1D and 2D training.
+					 *
+					 * [1] Train terminated Rank only
+					 *   1 = Only train terminated rank in CA training
+					 *   0 = Train all ranks in CA training
+					 *
+					 * [2-7] RFU must be zero
+					 */
+	uint8_t x8mode;			/*
+					 * Byte offset 0x1c, CSR Addr 0x5400e, Direction=In
+					 * X8 mode configuration:
+					 *   0x0 = x16 configuration for all devices
+					 *   0xF = x8 configuration for all devices
+					 * All other values are RFU
+					 */
+	uint8_t reserved1d;		/* Byte offset 0x1d, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1e;		/* Byte offset 0x1e, CSR Addr 0x5400f, Direction=N/A */
+	uint8_t share2dvrefresult;	/*
+					 * Byte offset 0x1f, CSR Addr 0x5400f, Direction=In
+					 * Bitmap that designates the phy's vref source for every
+					 * pstate
+					 * If share2dvrefresult[x] = 0, then after 2D training,
+					 * pstate x will continue using the phyVref provided in
+					 * pstate x's 1D messageblock.
+					 * If share2dvrefresult[x] = 1, then after 2D training,
+					 * pstate x will use the per-lane VrefDAC0/1 CSRs trained by
+					 * 2d training.
+					 */
+	uint8_t reserved20;		/* Byte offset 0x20, CSR Addr 0x54010, Direction=N/A */
+	uint8_t reserved21;		/* Byte offset 0x21, CSR Addr 0x54010, Direction=N/A */
+	uint16_t phyconfigoverride;	/*
+					 * Byte offset 0x22, CSR Addr 0x54011, Direction=In
+					 * Override PhyConfig csr.
+					 *   0x0: Use hardware csr value for PhyConfing
+					 *   (recommended)
+					 *   Other values: Use value for PhyConfig instead of
+					 *   Hardware value.
+					 *
+					 */
+	uint8_t enableddqscha;		/*
+					 * Byte offset 0x24, CSR Addr 0x54012, Direction=In
+					 * Total number of DQ bits enabled in PHY Channel A
+					 */
+	uint8_t cspresentcha;		/*
+					 * Byte offset 0x25, CSR Addr 0x54012, Direction=In
+					 * Indicates presence of DRAM at each chip select for PHY
+					 * channel A.
+					 *   0x1 = CS0 is populated with DRAM
+					 *   0x3 = CS0 and CS1 are populated with DRAM
+					 *
+					 * All other encodings are illegal
+					 */
+	int8_t cdd_cha_rr_1_0;		/*
+					 * Byte offset 0x26, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rr_0_1;		/*
+					 * Byte offset 0x27, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rw_1_1;		/*
+					 * Byte offset 0x28, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rw_1_0;		/*
+					 * Byte offset 0x29, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rw_0_1;		/*
+					 * Byte offset 0x2a, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rw_0_0;		/*
+					 * Byte offset 0x2b, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs0 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_wr_1_1;		/*
+					 * Byte offset 0x2c, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_wr_1_0;		/*
+					 * Byte offset 0x2d, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_wr_0_1;		/*
+					 * Byte offset 0x2e, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_wr_0_0;		/*
+					 * Byte offset 0x2f, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_ww_1_0;		/*
+					 * Byte offset 0x30, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 0 on Channel A.
+					 */
+	int8_t cdd_cha_ww_0_1;		/*
+					 * Byte offset 0x31, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 1 on Channel A.
+					 */
+	uint8_t mr1_a0;			/*
+					 * Byte offset 0x32, CSR Addr 0x54019, Direction=In
+					 * Value to be programmed in DRAM Mode Register 1
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr2_a0;			/*
+					 * Byte offset 0x33, CSR Addr 0x54019, Direction=In
+					 * Value to be programmed in DRAM Mode Register 2
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr3_a0;			/*
+					 * Byte offset 0x34, CSR Addr 0x5401a, Direction=In
+					 * Value to be programmed in DRAM Mode Register 3
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr4_a0;			/*
+					 * Byte offset 0x35, CSR Addr 0x5401a, Direction=In
+					 * Value to be programmed in DRAM Mode Register 4
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr11_a0;		/*
+					 * Byte offset 0x36, CSR Addr 0x5401b, Direction=In
+					 * Value to be programmed in DRAM Mode Register 11
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr12_a0;		/*
+					 * Byte offset 0x37, CSR Addr 0x5401b, Direction=In
+					 * Value to be programmed in DRAM Mode Register 12
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr13_a0;		/*
+					 * Byte offset 0x38, CSR Addr 0x5401c, Direction=In
+					 * Value to be programmed in DRAM Mode Register 13
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr14_a0;		/*
+					 * Byte offset 0x39, CSR Addr 0x5401c, Direction=In
+					 * Value to be programmed in DRAM Mode Register 14
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr16_a0;		/*
+					 * Byte offset 0x3a, CSR Addr 0x5401d, Direction=In
+					 * Value to be programmed in DRAM Mode Register 16
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr17_a0;		/*
+					 * Byte offset 0x3b, CSR Addr 0x5401d, Direction=In
+					 * Value to be programmed in DRAM Mode Register 17
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr22_a0;		/*
+					 * Byte offset 0x3c, CSR Addr 0x5401e, Direction=In
+					 * Value to be programmed in DRAM Mode Register 22
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr24_a0;		/*
+					 * Byte offset 0x3d, CSR Addr 0x5401e, Direction=In
+					 * Value to be programmed in DRAM Mode Register 24
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr1_a1;			/*
+					 * Byte offset 0x3e, CSR Addr 0x5401f, Direction=In
+					 * Value to be programmed in DRAM Mode Register 1
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr2_a1;			/*
+					 * Byte offset 0x3f, CSR Addr 0x5401f, Direction=In
+					 * Value to be programmed in DRAM Mode Register 2
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr3_a1;			/*
+					 * Byte offset 0x40, CSR Addr 0x54020, Direction=In
+					 * Value to be programmed in DRAM Mode Register 3
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr4_a1;			/*
+					 * Byte offset 0x41, CSR Addr 0x54020, Direction=In
+					 * Value to be programmed in DRAM Mode Register 4
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr11_a1;		/*
+					 * Byte offset 0x42, CSR Addr 0x54021, Direction=In
+					 * Value to be programmed in DRAM Mode Register 11
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr12_a1;		/*
+					 * Byte offset 0x43, CSR Addr 0x54021, Direction=In
+					 * Value to be programmed in DRAM Mode Register 12
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr13_a1;		/*
+					 * Byte offset 0x44, CSR Addr 0x54022, Direction=In
+					 * Value to be programmed in DRAM Mode Register 13
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr14_a1;		/*
+					 * Byte offset 0x45, CSR Addr 0x54022, Direction=In
+					 * Value to be programmed in DRAM Mode Register 14
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr16_a1;		/*
+					 * Byte offset 0x46, CSR Addr 0x54023, Direction=In
+					 * Value to be programmed in DRAM Mode Register 16
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr17_a1;		/*
+					 * Byte offset 0x47, CSR Addr 0x54023, Direction=In
+					 * Value to be programmed in DRAM Mode Register 17
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr22_a1;		/*
+					 * Byte offset 0x48, CSR Addr 0x54024, Direction=In
+					 * Value to be programmed in DRAM Mode Register 22
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr24_a1;		/*
+					 * Byte offset 0x49, CSR Addr 0x54024, Direction=In
+					 * Value to be programmed in DRAM Mode Register 24
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t caterminatingrankcha;	/* Byte offset 0x4a, CSR Addr 0x54025, Direction=In
+					 * Terminating Rank for CA bus on Channel A
+					 *   0x0 = Rank 0 is terminating rank
+					 *   0x1 = Rank 1 is terminating rank
+					 */
+	uint8_t reserved4b;		/* Byte offset 0x4b, CSR Addr 0x54025, Direction=N/A */
+	uint8_t reserved4c;		/* Byte offset 0x4c, CSR Addr 0x54026, Direction=N/A */
+	uint8_t reserved4d;		/* Byte offset 0x4d, CSR Addr 0x54026, Direction=N/A */
+	uint8_t reserved4e;		/* Byte offset 0x4e, CSR Addr 0x54027, Direction=N/A */
+	uint8_t reserved4f;		/* Byte offset 0x4f, CSR Addr 0x54027, Direction=N/A */
+	uint8_t reserved50;		/* Byte offset 0x50, CSR Addr 0x54028, Direction=N/A */
+	uint8_t reserved51;		/* Byte offset 0x51, CSR Addr 0x54028, Direction=N/A */
+	uint8_t reserved52;		/* Byte offset 0x52, CSR Addr 0x54029, Direction=N/A */
+	uint8_t reserved53;		/* Byte offset 0x53, CSR Addr 0x54029, Direction=N/A */
+	uint8_t reserved54;		/* Byte offset 0x54, CSR Addr 0x5402a, Direction=N/A */
+	uint8_t reserved55;		/* Byte offset 0x55, CSR Addr 0x5402a, Direction=N/A */
+	uint8_t reserved56;		/* Byte offset 0x56, CSR Addr 0x5402b, Direction=N/A */
+	uint8_t enableddqschb;		/*
+					 * Byte offset 0x57, CSR Addr 0x5402b, Direction=In
+					 * Total number of DQ bits enabled in PHY Channel B
+					 */
+	uint8_t cspresentchb;		/*
+					 * Byte offset 0x58, CSR Addr 0x5402c, Direction=In
+					 * Indicates presence of DRAM at each chip select for PHY
+					 * channel B.
+					 *   0x0 = No chip selects are populated with DRAM
+					 *   0x1 = CS0 is populated with DRAM
+					 *   0x3 = CS0 and CS1 are populated with DRAM
+					 *
+					 * All other encodings are illegal
+					 */
+	int8_t cdd_chb_rr_1_0;		/*
+					 * Byte offset 0x59, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rr_0_1;		/*
+					 * Byte offset 0x5a, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rw_1_1;		/*
+					 * Byte offset 0x5b, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rw_1_0;		/*
+					 * Byte offset 0x5c, CSR Addr 0x5402e, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rw_0_1;		/*
+					 * Byte offset 0x5d, CSR Addr 0x5402e, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rw_0_0;		/*
+					 * Byte offset 0x5e, CSR Addr 0x5402f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs01 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_wr_1_1;		/*
+					 * Byte offset 0x5f, CSR Addr 0x5402f, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_wr_1_0;		/*
+					 * Byte offset 0x60, CSR Addr 0x54030, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_wr_0_1;		/*
+					 * Byte offset 0x61, CSR Addr 0x54030, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_wr_0_0;		/*
+					 * Byte offset 0x62, CSR Addr 0x54031, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_ww_1_0;		/*
+					 * Byte offset 0x63, CSR Addr 0x54031, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 0 on Channel B.
+					 */
+	int8_t cdd_chb_ww_0_1;		/*
+					 * Byte offset 0x64, CSR Addr 0x54032, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 1 on Channel B.
+					 */
+	uint8_t mr1_b0;			/*
+					 * Byte offset 0x65, CSR Addr 0x54032, Direction=In
+					 * Value to be programmed in DRAM Mode Register 1
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr2_b0;			/*
+					 * Byte offset 0x66, CSR Addr 0x54033, Direction=In
+					 * Value to be programmed in DRAM Mode Register 2
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr3_b0;			/*
+					 * Byte offset 0x67, CSR Addr 0x54033, Direction=In
+					 * Value to be programmed in DRAM Mode Register 3
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr4_b0;			/*
+					 * Byte offset 0x68, CSR Addr 0x54034, Direction=In
+					 * Value to be programmed in DRAM Mode Register 4
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr11_b0;		/*
+					 * Byte offset 0x69, CSR Addr 0x54034, Direction=In
+					 * Value to be programmed in DRAM Mode Register 11
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr12_b0;		/*
+					 * Byte offset 0x6a, CSR Addr 0x54035, Direction=In
+					 * Value to be programmed in DRAM Mode Register 12
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr13_b0;		/*
+					 * Byte offset 0x6b, CSR Addr 0x54035, Direction=In
+					 * Value to be programmed in DRAM Mode Register 13
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr14_b0;		/*
+					 * Byte offset 0x6c, CSR Addr 0x54036, Direction=In
+					 * Value to be programmed in DRAM Mode Register 14
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr16_b0;		/*
+					 * Byte offset 0x6d, CSR Addr 0x54036, Direction=In
+					 * Value to be programmed in DRAM Mode Register 16
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr17_b0;		/*
+					 * Byte offset 0x6e, CSR Addr 0x54037, Direction=In
+					 * Value to be programmed in DRAM Mode Register 17
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr22_b0;		/*
+					 * Byte offset 0x6f, CSR Addr 0x54037, Direction=In
+					 * Value to be programmed in DRAM Mode Register 22
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr24_b0;		/*
+					 * Byte offset 0x70, CSR Addr 0x54038, Direction=In
+					 * Value to be programmed in DRAM Mode Register 24
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr1_b1;			/*
+					 * Byte offset 0x71, CSR Addr 0x54038, Direction=In
+					 * Value to be programmed in DRAM Mode Register 1
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr2_b1;			/*
+					 * Byte offset 0x72, CSR Addr 0x54039, Direction=In
+					 * Value to be programmed in DRAM Mode Register 2
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr3_b1;			/*
+					 * Byte offset 0x73, CSR Addr 0x54039, Direction=In
+					 * Value to be programmed in DRAM Mode Register 3
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr4_b1;			/*
+					 * Byte offset 0x74, CSR Addr 0x5403a, Direction=In
+					 * Value to be programmed in DRAM Mode Register 4
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr11_b1;		/*
+					 * Byte offset 0x75, CSR Addr 0x5403a, Direction=In
+					 * Value to be programmed in DRAM Mode Register 11
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr12_b1;		/*
+					 * Byte offset 0x76, CSR Addr 0x5403b, Direction=In
+					 * Value to be programmed in DRAM Mode Register 12
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr13_b1;		/*
+					 * Byte offset 0x77, CSR Addr 0x5403b, Direction=In
+					 * Value to be programmed in DRAM Mode Register 13
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr14_b1;		/*
+					 * Byte offset 0x78, CSR Addr 0x5403c, Direction=In
+					 * Value to be programmed in DRAM Mode Register 14
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr16_b1;		/*
+					 * Byte offset 0x79, CSR Addr 0x5403c, Direction=In
+					 * Value to be programmed in DRAM Mode Register 16
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr17_b1;		/*
+					 * Byte offset 0x7a, CSR Addr 0x5403d, Direction=In
+					 * Value to be programmed in DRAM Mode Register 17
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr22_b1;		/*
+					 * Byte offset 0x7b, CSR Addr 0x5403d, Direction=In
+					 * Value to be programmed in DRAM Mode Register 22
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr24_b1;		/*
+					 * Byte offset 0x7c, CSR Addr 0x5403e, Direction=In
+					 * Value to be programmed in DRAM Mode Register 24
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t caterminatingrankchb;	/* Byte offset 0x7d, CSR Addr 0x5403e, Direction=In
+					 * Terminating Rank for CA bus on Channel B
+					 *   0x0 = Rank 0 is terminating rank
+					 *   0x1 = Rank 1 is terminating rank
+					 */
+	uint8_t reserved7e;		/* Byte offset 0x7e, CSR Addr 0x5403f, Direction=N/A */
+	uint8_t reserved7f;		/* Byte offset 0x7f, CSR Addr 0x5403f, Direction=N/A */
+	uint8_t reserved80;		/* Byte offset 0x80, CSR Addr 0x54040, Direction=N/A */
+	uint8_t reserved81;		/* Byte offset 0x81, CSR Addr 0x54040, Direction=N/A */
+	uint8_t reserved82;		/* Byte offset 0x82, CSR Addr 0x54041, Direction=N/A */
+	uint8_t reserved83;		/* Byte offset 0x83, CSR Addr 0x54041, Direction=N/A */
+	uint8_t reserved84;		/* Byte offset 0x84, CSR Addr 0x54042, Direction=N/A */
+	uint8_t reserved85;		/* Byte offset 0x85, CSR Addr 0x54042, Direction=N/A */
+	uint8_t reserved86;		/* Byte offset 0x86, CSR Addr 0x54043, Direction=N/A */
+	uint8_t reserved87;		/* Byte offset 0x87, CSR Addr 0x54043, Direction=N/A */
+	uint8_t reserved88;		/* Byte offset 0x88, CSR Addr 0x54044, Direction=N/A */
+	uint8_t reserved89;		/* Byte offset 0x89, CSR Addr 0x54044, Direction=N/A */
+} __packed __aligned(2);
+
+#endif /* MNPMUSRAMMSGBLOCK_LPDDR4_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_csr_all_cdefines.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_csr_all_cdefines.h
new file mode 100644
index 0000000..99a8c4c
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_csr_all_cdefines.h
@@ -0,0 +1,6944 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_PHYINIT_CSR_ALL_DEFINES_H
+#define DDRPHY_PHYINIT_CSR_ALL_DEFINES_H
+
+/* ANIBx register offsets */
+#define CSR_MTESTMUXSEL_ADDR				0x1AU
+#define CSR_AFORCEDRVCONT_ADDR				0x27U
+#define CSR_AFORCETRICONT_ADDR				0x28U
+#define CSR_ATXIMPEDANCE_ADDR				0x43U
+#define CSR_ATESTPRBSERR_ADDR				0x53U
+#define CSR_ATXSLEWRATE_ADDR				0x55U
+#define CSR_ATESTPRBSERRCNT_ADDR			0x56U
+#define CSR_ATXDLY_ADDR					0x80U
+
+/* DBYTEx register offsets */
+#define CSR_DBYTEMISCMODE_ADDR				0x0U
+#define CSR_TSMBYTE0_ADDR				0x1U
+#define CSR_TRAININGPARAM_ADDR				0x2U
+#define CSR_USEDQSENREPLICA_ADDR			0x3U
+#define CSR_RXTRAINPATTERNENABLE_ADDR			0x10U
+#define CSR_TSMBYTE1_ADDR				0x11U
+#define CSR_TSMBYTE2_ADDR				0x12U
+#define CSR_TSMBYTE3_ADDR				0x13U
+#define CSR_TSMBYTE4_ADDR				0x14U
+#define CSR_TESTMODECONFIG_ADDR				0x17U
+#define CSR_TSMBYTE5_ADDR				0x18U
+/* MTESTMUXSEL already defined in ANIBx section */
+#define CSR_DTSMTRAINMODECTRL_ADDR			0x1FU
+#define CSR_DFIMRL_ADDR					0x20U
+#define CSR_ASYNCDBYTEMODE_ADDR				0x24U
+#define CSR_ASYNCDBYTETXEN_ADDR				0x26U
+#define CSR_ASYNCDBYTETXDATA_ADDR			0x28U
+#define CSR_ASYNCDBYTERXDATA_ADDR			0x2AU
+#define CSR_VREFDAC1_ADDR				0x30U
+#define CSR_TRAININGCNTR_ADDR				0x32U
+#define CSR_VREFDAC0_ADDR				0x40U
+#define CSR_TXIMPEDANCECTRL0_ADDR			0x41U
+#define CSR_DQDQSRCVCNTRL_ADDR				0x43U
+#define CSR_TXEQUALIZATIONMODE_ADDR			0x48U
+#define CSR_TXIMPEDANCECTRL1_ADDR			0x49U
+#define CSR_DQDQSRCVCNTRL1_ADDR				0x4AU
+#define CSR_TXIMPEDANCECTRL2_ADDR			0x4BU
+#define CSR_DQDQSRCVCNTRL2_ADDR				0x4CU
+#define CSR_TXODTDRVSTREN_ADDR				0x4DU
+#define CSR_RXFIFOCHECKSTATUS_ADDR			0x56U
+#define CSR_RXFIFOCHECKERRVALUES_ADDR			0x57U
+#define CSR_RXFIFOINFO_ADDR				0x58U
+#define CSR_RXFIFOVISIBILITY_ADDR			0x59U
+#define CSR_RXFIFOCONTENTSDQ3210_ADDR			0x5AU
+#define CSR_RXFIFOCONTENTSDQ7654_ADDR			0x5BU
+#define CSR_RXFIFOCONTENTSDBI_ADDR			0x5CU
+#define CSR_TXSLEWRATE_ADDR				0x5FU
+#define CSR_TRAININGINCDECDTSMEN_ADDR			0x62U
+#define CSR_RXPBDLYTG0_ADDR				0x68U
+#define CSR_RXPBDLYTG1_ADDR				0x69U
+#define CSR_RXPBDLYTG2_ADDR				0x6AU
+#define CSR_RXPBDLYTG3_ADDR				0x6BU
+#define CSR_RXENDLYTG0_ADDR				0x80U
+#define CSR_RXENDLYTG1_ADDR				0x81U
+#define CSR_RXENDLYTG2_ADDR				0x82U
+#define CSR_RXENDLYTG3_ADDR				0x83U
+#define CSR_RXCLKDLYTG0_ADDR				0x8CU
+#define CSR_RXCLKDLYTG1_ADDR				0x8DU
+#define CSR_RXCLKDLYTG2_ADDR				0x8EU
+#define CSR_RXCLKDLYTG3_ADDR				0x8FU
+#define CSR_RXCLKCDLYTG0_ADDR				0x90U
+#define CSR_RXCLKCDLYTG1_ADDR				0x91U
+#define CSR_RXCLKCDLYTG2_ADDR				0x92U
+#define CSR_RXCLKCDLYTG3_ADDR				0x93U
+#define CSR_DQ0LNSEL_ADDR				0xA0U
+#define CSR_DQ1LNSEL_ADDR				0xA1U
+#define CSR_DQ2LNSEL_ADDR				0xA2U
+#define CSR_DQ3LNSEL_ADDR				0xA3U
+#define CSR_DQ4LNSEL_ADDR				0xA4U
+#define CSR_DQ5LNSEL_ADDR				0xA5U
+#define CSR_DQ6LNSEL_ADDR				0xA6U
+#define CSR_DQ7LNSEL_ADDR				0xA7U
+#define CSR_PPTCTLSTATIC_ADDR				0xAAU
+#define CSR_PPTCTLDYN_ADDR				0xABU
+#define CSR_PPTINFO_ADDR				0xACU
+#define CSR_PPTRXENEVNT_ADDR				0xADU
+#define CSR_PPTDQSCNTINVTRNTG0_ADDR			0xAEU
+#define CSR_PPTDQSCNTINVTRNTG1_ADDR			0xAFU
+#define CSR_DTSMBLANKINGCTRL_ADDR			0xB1U
+#define CSR_TSM0_ADDR					0xB2U
+#define CSR_TSM1_ADDR					0xB3U
+#define CSR_TSM2_ADDR					0xB4U
+#define CSR_TSM3_ADDR					0xB5U
+#define CSR_TXCHKDATASELECTS_ADDR			0xB6U
+#define CSR_DTSMUPTHLDXINGIND_ADDR			0xB7U
+#define CSR_DTSMLOTHLDXINGIND_ADDR			0xB8U
+#define CSR_DBYTEALLDTSMCTRL0_ADDR			0xB9U
+#define CSR_DBYTEALLDTSMCTRL1_ADDR			0xBAU
+#define CSR_DBYTEALLDTSMCTRL2_ADDR			0xBBU
+#define CSR_TXDQDLYTG0_ADDR				0xC0U
+#define CSR_TXDQDLYTG1_ADDR				0xC1U
+#define CSR_TXDQDLYTG2_ADDR				0xC2U
+#define CSR_TXDQDLYTG3_ADDR				0xC3U
+#define CSR_TXDQSDLYTG0_ADDR				0xD0U
+#define CSR_TXDQSDLYTG1_ADDR				0xD1U
+#define CSR_TXDQSDLYTG2_ADDR				0xD2U
+#define CSR_TXDQSDLYTG3_ADDR				0xD3U
+#define CSR_DXLCDLSTATUS_ADDR				0xE4U
+
+/* MASTER0 register offsets */
+#define CSR_RXFIFOINIT_ADDR				0x0U
+#define CSR_FORCECLKDISABLE_ADDR			0x1U
+#define CSR_CLOCKINGCTRL_ADDR				0x2U
+#define CSR_FORCEINTERNALUPDATE_ADDR			0x3U
+#define CSR_PHYCONFIG_ADDR				0x4U
+#define CSR_PGCR_ADDR					0x5U
+#define CSR_TESTBUMPCNTRL1_ADDR				0x7U
+#define CSR_CALUCLKINFO_ADDR				0x8U
+#define CSR_TESTBUMPCNTRL_ADDR				0xAU
+#define CSR_SEQ0BDLY0_ADDR				0xBU
+#define CSR_SEQ0BDLY1_ADDR				0xCU
+#define CSR_SEQ0BDLY2_ADDR				0xDU
+#define CSR_SEQ0BDLY3_ADDR				0xEU
+#define CSR_PHYALERTSTATUS_ADDR				0xFU
+#define CSR_PPTTRAINSETUP_ADDR				0x10U
+#define CSR_PPTTRAINSETUP2_ADDR				0x11U
+#define CSR_ATESTMODE_ADDR				0x12U
+#define CSR_TXCALBINP_ADDR				0x14U
+#define CSR_TXCALBINN_ADDR				0x15U
+#define CSR_TXCALPOVR_ADDR				0x16U
+#define CSR_TXCALNOVR_ADDR				0x17U
+#define CSR_DFIMODE_ADDR				0x18U
+#define CSR_TRISTATEMODECA_ADDR				0x19U
+/* MTESTMUXSEL already defined in ANIBx section */
+#define CSR_MTESTPGMINFO_ADDR				0x1BU
+#define CSR_DYNPWRDNUP_ADDR				0x1CU
+#define CSR_PMIENABLE_ADDR				0x1DU
+#define CSR_PHYTID_ADDR					0x1EU
+#define CSR_HWTMRL_ADDR					0x20U
+#define CSR_DFIPHYUPD_ADDR				0x21U
+#define CSR_PDAMRSWRITEMODE_ADDR			0x22U
+#define CSR_DFIGEARDOWNCTL_ADDR				0x23U
+#define CSR_DQSPREAMBLECONTROL_ADDR			0x24U
+#define CSR_MASTERX4CONFIG_ADDR				0x25U
+#define CSR_WRLEVBITS_ADDR				0x26U
+#define CSR_ENABLECSMULTICAST_ADDR			0x27U
+#define CSR_HWTLPCSMULTICAST_ADDR			0x28U
+#define CSR_ACX4ANIBDIS_ADDR				0x2CU
+#define CSR_DMIPINPRESENT_ADDR				0x2DU
+#define CSR_ARDPTRINITVAL_ADDR				0x2EU
+#define CSR_DB0LCDLCALPHDETOUT_ADDR			0x30U
+#define CSR_DB1LCDLCALPHDETOUT_ADDR			0x31U
+#define CSR_DB2LCDLCALPHDETOUT_ADDR			0x32U
+#define CSR_DB3LCDLCALPHDETOUT_ADDR			0x33U
+#define CSR_DB4LCDLCALPHDETOUT_ADDR			0x34U
+#define CSR_DB5LCDLCALPHDETOUT_ADDR			0x35U
+#define CSR_DB6LCDLCALPHDETOUT_ADDR			0x36U
+#define CSR_DB7LCDLCALPHDETOUT_ADDR			0x37U
+#define CSR_DB8LCDLCALPHDETOUT_ADDR			0x38U
+#define CSR_DB9LCDLCALPHDETOUT_ADDR			0x39U
+#define CSR_DBYTEDLLMODECNTRL_ADDR			0x3AU
+#define CSR_DBYTERXENTRAIN_ADDR				0x3BU
+#define CSR_ANLCDLCALPHDETOUT_ADDR			0x3FU
+#define CSR_CALOFFSETS_ADDR				0x45U
+#define CSR_SARINITVALS_ADDR				0x47U
+#define CSR_CALPEXTOVR_ADDR				0x49U
+#define CSR_CALCMPR5OVR_ADDR				0x4AU
+#define CSR_CALNINTOVR_ADDR				0x4BU
+#define CSR_CALDRVSTR0_ADDR				0x50U
+#define CSR_PROCODTCTL_ADDR				0x55U
+#define CSR_PROCODTTIMECTL_ADDR				0x56U
+#define CSR_MEMALERTCONTROL_ADDR			0x5BU
+#define CSR_MEMALERTCONTROL2_ADDR			0x5CU
+#define CSR_MEMRESETL_ADDR				0x60U
+#define CSR_PUBMODE_ADDR				0x6EU
+#define CSR_MISCPHYSTATUS_ADDR				0x6FU
+#define CSR_CORELOOPBACKSEL_ADDR			0x70U
+#define CSR_DLLTRAINPARAM_ADDR				0x71U
+#define CSR_HWTLPCSENA_ADDR				0x72U
+#define CSR_HWTLPCSENB_ADDR				0x73U
+#define CSR_HWTLPCSENBYPASS_ADDR			0x74U
+#define CSR_DFICAMODE_ADDR				0x75U
+#define CSR_HWTCACTL_ADDR				0x76U
+#define CSR_HWTCAMODE_ADDR				0x77U
+#define CSR_DLLCONTROL_ADDR				0x78U
+#define CSR_PULSEDLLUPDATEPHASE_ADDR			0x79U
+#define CSR_HWTCONTROLOVR0_ADDR				0x7AU
+#define CSR_HWTCONTROLOVR1_ADDR				0x7BU
+#define CSR_DLLGAINCTL_ADDR				0x7CU
+#define CSR_DLLLOCKPARAM_ADDR				0x7DU
+#define CSR_HWTCONTROLVAL0_ADDR				0x7EU
+#define CSR_HWTCONTROLVAL1_ADDR				0x7FU
+#define CSR_ACSMGLBLSTART_ADDR				0x81U
+#define CSR_ACSMGLBLSGLSTPCTRL_ADDR			0x82U
+#define CSR_LCDLCALPHASE_ADDR				0x84U
+#define CSR_LCDLCALCTRL_ADDR				0x85U
+#define CSR_CALRATE_ADDR				0x88U
+#define CSR_CALZAP_ADDR					0x89U
+#define CSR_PSTATE_ADDR					0x8BU
+#define CSR_CALPREDRIVEROVERRIDE_ADDR			0x8CU
+#define CSR_PLLOUTGATECONTROL_ADDR			0x8DU
+#define CSR_UCMEMRESETCONTROL_ADDR			0x8FU
+#define CSR_PORCONTROL_ADDR				0x90U
+#define CSR_CALBUSY_ADDR				0x97U
+#define CSR_CALMISC2_ADDR				0x98U
+#define CSR_CALMISC_ADDR				0x9AU
+#define CSR_CALVREFS_ADDR				0x9BU
+#define CSR_CALCMPR5_ADDR				0x9CU
+#define CSR_CALNINT_ADDR				0x9DU
+#define CSR_CALPEXT_ADDR				0x9EU
+#define CSR_CALCMPINVERT_ADDR				0xA8U
+#define CSR_CALCMPANACNTRL_ADDR				0xAEU
+#define CSR_DFIRDDATACSDESTMAP_ADDR			0xB0U
+#define CSR_VREFINGLOBAL_ADDR				0xB2U
+#define CSR_DFIWRDATACSDESTMAP_ADDR			0xB4U
+#define CSR_MASUPDGOODCTR_ADDR				0xB5U
+#define CSR_PHYUPD0GOODCTR_ADDR				0xB6U
+#define CSR_PHYUPD1GOODCTR_ADDR				0xB7U
+#define CSR_CTLUPD0GOODCTR_ADDR				0xB8U
+#define CSR_CTLUPD1GOODCTR_ADDR				0xB9U
+#define CSR_MASUPDFAILCTR_ADDR				0xBAU
+#define CSR_PHYUPD0FAILCTR_ADDR				0xBBU
+#define CSR_PHYUPD1FAILCTR_ADDR				0xBCU
+#define CSR_PHYPERFCTRENABLE_ADDR			0xBDU
+#define CSR_DFIWRRDDATACSCONFIG_ADDR			0xBEU
+#define CSR_PLLPWRDN_ADDR				0xC3U
+#define CSR_PLLRESET_ADDR				0xC4U
+#define CSR_PLLCTRL2_ADDR				0xC5U
+#define CSR_PLLCTRL0_ADDR				0xC6U
+#define CSR_PLLCTRL1_ADDR				0xC7U
+#define CSR_PLLTST_ADDR					0xC8U
+#define CSR_PLLLOCKSTATUS_ADDR				0xC9U
+#define CSR_PLLTESTMODE_ADDR				0xCAU
+#define CSR_PLLCTRL3_ADDR				0xCBU
+#define CSR_PLLCTRL4_ADDR				0xCCU
+#define CSR_PLLENDOFCAL_ADDR				0xCDU
+#define CSR_PLLSTANDBYEFF_ADDR				0xCEU
+#define CSR_PLLDACVALOUT_ADDR				0xCFU
+#define CSR_DLYTESTSEQ_ADDR				0xD0U
+#define CSR_DLYTESTRINGSELDB_ADDR			0xD1U
+#define CSR_DLYTESTRINGSELAC_ADDR			0xD2U
+#define CSR_DLYTESTCNTDFICLKIV_ADDR			0xD3U
+#define CSR_DLYTESTCNTDFICLK_ADDR			0xD4U
+#define CSR_DLYTESTCNTRINGOSCDB0_ADDR			0xD5U
+#define CSR_DLYTESTCNTRINGOSCDB1_ADDR			0xD6U
+#define CSR_DLYTESTCNTRINGOSCDB2_ADDR			0xD7U
+#define CSR_DLYTESTCNTRINGOSCDB3_ADDR			0xD8U
+#define CSR_DLYTESTCNTRINGOSCDB4_ADDR			0xD9U
+#define CSR_DLYTESTCNTRINGOSCDB5_ADDR			0xDAU
+#define CSR_DLYTESTCNTRINGOSCDB6_ADDR			0xDBU
+#define CSR_DLYTESTCNTRINGOSCDB7_ADDR			0xDCU
+#define CSR_DLYTESTCNTRINGOSCDB8_ADDR			0xDDU
+#define CSR_DLYTESTCNTRINGOSCDB9_ADDR			0xDEU
+#define CSR_DLYTESTCNTRINGOSCAC_ADDR			0xDFU
+#define CSR_MSTLCDLDBGCNTL_ADDR				0xE0U
+#define CSR_MSTLCDL0DBGRES_ADDR				0xE1U
+#define CSR_MSTLCDL1DBGRES_ADDR				0xE2U
+#define CSR_LCDLDBGCNTL_ADDR				0xE3U
+#define CSR_ACLCDLSTATUS_ADDR				0xE4U
+#define CSR_CUSTPHYREV_ADDR				0xEDU
+#define CSR_PHYREV_ADDR					0xEEU
+#define CSR_LP3EXITSEQ0BSTARTVECTOR_ADDR		0xEFU
+#define CSR_DFIFREQXLAT0_ADDR				0xF0U
+#define CSR_DFIFREQXLAT1_ADDR				0xF1U
+#define CSR_DFIFREQXLAT2_ADDR				0xF2U
+#define CSR_DFIFREQXLAT3_ADDR				0xF3U
+#define CSR_DFIFREQXLAT4_ADDR				0xF4U
+#define CSR_DFIFREQXLAT5_ADDR				0xF5U
+#define CSR_DFIFREQXLAT6_ADDR				0xF6U
+#define CSR_DFIFREQXLAT7_ADDR				0xF7U
+#define CSR_TXRDPTRINIT_ADDR				0xF8U
+#define CSR_DFIINITCOMPLETE_ADDR			0xF9U
+#define CSR_DFIFREQRATIO_ADDR				0xFAU
+#define CSR_RXFIFOCHECKS_ADDR				0xFBU
+#define CSR_MTESTDTOCTRL_ADDR				0xFFU
+#define CSR_MAPCAA0TODFI_ADDR				0x100U
+#define CSR_MAPCAA1TODFI_ADDR				0x101U
+#define CSR_MAPCAA2TODFI_ADDR				0x102U
+#define CSR_MAPCAA3TODFI_ADDR				0x103U
+#define CSR_MAPCAA4TODFI_ADDR				0x104U
+#define CSR_MAPCAA5TODFI_ADDR				0x105U
+#define CSR_MAPCAA6TODFI_ADDR				0x106U
+#define CSR_MAPCAA7TODFI_ADDR				0x107U
+#define CSR_MAPCAA8TODFI_ADDR				0x108U
+#define CSR_MAPCAA9TODFI_ADDR				0x109U
+#define CSR_MAPCAB0TODFI_ADDR				0x110U
+#define CSR_MAPCAB1TODFI_ADDR				0x111U
+#define CSR_MAPCAB2TODFI_ADDR				0x112U
+#define CSR_MAPCAB3TODFI_ADDR				0x113U
+#define CSR_MAPCAB4TODFI_ADDR				0x114U
+#define CSR_MAPCAB5TODFI_ADDR				0x115U
+#define CSR_MAPCAB6TODFI_ADDR				0x116U
+#define CSR_MAPCAB7TODFI_ADDR				0x117U
+#define CSR_MAPCAB8TODFI_ADDR				0x118U
+#define CSR_MAPCAB9TODFI_ADDR				0x119U
+#define CSR_PHYINTERRUPTENABLE_ADDR			0x11BU
+#define CSR_PHYINTERRUPTFWCONTROL_ADDR			0x11CU
+#define CSR_PHYINTERRUPTMASK_ADDR			0x11DU
+#define CSR_PHYINTERRUPTCLEAR_ADDR			0x11EU
+#define CSR_PHYINTERRUPTSTATUS_ADDR			0x11FU
+#define CSR_HWTSWIZZLEHWTADDRESS0_ADDR			0x120U
+#define CSR_HWTSWIZZLEHWTADDRESS1_ADDR			0x121U
+#define CSR_HWTSWIZZLEHWTADDRESS2_ADDR			0x122U
+#define CSR_HWTSWIZZLEHWTADDRESS3_ADDR			0x123U
+#define CSR_HWTSWIZZLEHWTADDRESS4_ADDR			0x124U
+#define CSR_HWTSWIZZLEHWTADDRESS5_ADDR			0x125U
+#define CSR_HWTSWIZZLEHWTADDRESS6_ADDR			0x126U
+#define CSR_HWTSWIZZLEHWTADDRESS7_ADDR			0x127U
+#define CSR_HWTSWIZZLEHWTADDRESS8_ADDR			0x128U
+#define CSR_HWTSWIZZLEHWTADDRESS9_ADDR			0x129U
+#define CSR_HWTSWIZZLEHWTADDRESS10_ADDR			0x12AU
+#define CSR_HWTSWIZZLEHWTADDRESS11_ADDR			0x12BU
+#define CSR_HWTSWIZZLEHWTADDRESS12_ADDR			0x12CU
+#define CSR_HWTSWIZZLEHWTADDRESS13_ADDR			0x12DU
+#define CSR_HWTSWIZZLEHWTADDRESS14_ADDR			0x12EU
+#define CSR_HWTSWIZZLEHWTADDRESS15_ADDR			0x12FU
+#define CSR_HWTSWIZZLEHWTADDRESS17_ADDR			0x130U
+#define CSR_HWTSWIZZLEHWTACTN_ADDR			0x131U
+#define CSR_HWTSWIZZLEHWTBANK0_ADDR			0x132U
+#define CSR_HWTSWIZZLEHWTBANK1_ADDR			0x133U
+#define CSR_HWTSWIZZLEHWTBANK2_ADDR			0x134U
+#define CSR_HWTSWIZZLEHWTBG0_ADDR			0x135U
+#define CSR_HWTSWIZZLEHWTBG1_ADDR			0x136U
+#define CSR_HWTSWIZZLEHWTCASN_ADDR			0x137U
+#define CSR_HWTSWIZZLEHWTRASN_ADDR			0x138U
+#define CSR_HWTSWIZZLEHWTWEN_ADDR			0x139U
+#define CSR_HWTSWIZZLEHWTPARITYIN_ADDR			0x13AU
+#define CSR_DFIHANDSHAKEDELAYS0_ADDR			0x13CU
+#define CSR_DFIHANDSHAKEDELAYS1_ADDR			0x13DU
+#define CSR_REMOTEIMPCAL_ADDR				0x13EU
+#define CSR_ACLOOPBACKCTL_ADDR				0x13FU
+
+/* ACSM0 register offsets */
+#define CSR_ACSMSEQ0X0_ADDR				0x0U
+#define CSR_ACSMSEQ0X1_ADDR				0x1U
+#define CSR_ACSMSEQ0X2_ADDR				0x2U
+#define CSR_ACSMSEQ0X3_ADDR				0x3U
+#define CSR_ACSMSEQ0X4_ADDR				0x4U
+#define CSR_ACSMSEQ0X5_ADDR				0x5U
+#define CSR_ACSMSEQ0X6_ADDR				0x6U
+#define CSR_ACSMSEQ0X7_ADDR				0x7U
+#define CSR_ACSMSEQ0X8_ADDR				0x8U
+#define CSR_ACSMSEQ0X9_ADDR				0x9U
+#define CSR_ACSMSEQ0X10_ADDR				0xAU
+#define CSR_ACSMSEQ0X11_ADDR				0xBU
+#define CSR_ACSMSEQ0X12_ADDR				0xCU
+#define CSR_ACSMSEQ0X13_ADDR				0xDU
+#define CSR_ACSMSEQ0X14_ADDR				0xEU
+#define CSR_ACSMSEQ0X15_ADDR				0xFU
+#define CSR_ACSMSEQ0X16_ADDR				0x10U
+#define CSR_ACSMSEQ0X17_ADDR				0x11U
+#define CSR_ACSMSEQ0X18_ADDR				0x12U
+#define CSR_ACSMSEQ0X19_ADDR				0x13U
+#define CSR_ACSMSEQ0X20_ADDR				0x14U
+#define CSR_ACSMSEQ0X21_ADDR				0x15U
+#define CSR_ACSMSEQ0X22_ADDR				0x16U
+#define CSR_ACSMSEQ0X23_ADDR				0x17U
+#define CSR_ACSMSEQ0X24_ADDR				0x18U
+#define CSR_ACSMSEQ0X25_ADDR				0x19U
+#define CSR_ACSMSEQ0X26_ADDR				0x1AU
+#define CSR_ACSMSEQ0X27_ADDR				0x1BU
+#define CSR_ACSMSEQ0X28_ADDR				0x1CU
+#define CSR_ACSMSEQ0X29_ADDR				0x1DU
+#define CSR_ACSMSEQ0X30_ADDR				0x1EU
+#define CSR_ACSMSEQ0X31_ADDR				0x1FU
+#define CSR_ACSMSEQ1X0_ADDR				0x20U
+#define CSR_ACSMSEQ1X1_ADDR				0x21U
+#define CSR_ACSMSEQ1X2_ADDR				0x22U
+#define CSR_ACSMSEQ1X3_ADDR				0x23U
+#define CSR_ACSMSEQ1X4_ADDR				0x24U
+#define CSR_ACSMSEQ1X5_ADDR				0x25U
+#define CSR_ACSMSEQ1X6_ADDR				0x26U
+#define CSR_ACSMSEQ1X7_ADDR				0x27U
+#define CSR_ACSMSEQ1X8_ADDR				0x28U
+#define CSR_ACSMSEQ1X9_ADDR				0x29U
+#define CSR_ACSMSEQ1X10_ADDR				0x2AU
+#define CSR_ACSMSEQ1X11_ADDR				0x2BU
+#define CSR_ACSMSEQ1X12_ADDR				0x2CU
+#define CSR_ACSMSEQ1X13_ADDR				0x2DU
+#define CSR_ACSMSEQ1X14_ADDR				0x2EU
+#define CSR_ACSMSEQ1X15_ADDR				0x2FU
+#define CSR_ACSMSEQ1X16_ADDR				0x30U
+#define CSR_ACSMSEQ1X17_ADDR				0x31U
+#define CSR_ACSMSEQ1X18_ADDR				0x32U
+#define CSR_ACSMSEQ1X19_ADDR				0x33U
+#define CSR_ACSMSEQ1X20_ADDR				0x34U
+#define CSR_ACSMSEQ1X21_ADDR				0x35U
+#define CSR_ACSMSEQ1X22_ADDR				0x36U
+#define CSR_ACSMSEQ1X23_ADDR				0x37U
+#define CSR_ACSMSEQ1X24_ADDR				0x38U
+#define CSR_ACSMSEQ1X25_ADDR				0x39U
+#define CSR_ACSMSEQ1X26_ADDR				0x3AU
+#define CSR_ACSMSEQ1X27_ADDR				0x3BU
+#define CSR_ACSMSEQ1X28_ADDR				0x3CU
+#define CSR_ACSMSEQ1X29_ADDR				0x3DU
+#define CSR_ACSMSEQ1X30_ADDR				0x3EU
+#define CSR_ACSMSEQ1X31_ADDR				0x3FU
+#define CSR_ACSMSEQ2X0_ADDR				0x40U
+#define CSR_ACSMSEQ2X1_ADDR				0x41U
+#define CSR_ACSMSEQ2X2_ADDR				0x42U
+#define CSR_ACSMSEQ2X3_ADDR				0x43U
+#define CSR_ACSMSEQ2X4_ADDR				0x44U
+#define CSR_ACSMSEQ2X5_ADDR				0x45U
+#define CSR_ACSMSEQ2X6_ADDR				0x46U
+#define CSR_ACSMSEQ2X7_ADDR				0x47U
+#define CSR_ACSMSEQ2X8_ADDR				0x48U
+#define CSR_ACSMSEQ2X9_ADDR				0x49U
+#define CSR_ACSMSEQ2X10_ADDR				0x4AU
+#define CSR_ACSMSEQ2X11_ADDR				0x4BU
+#define CSR_ACSMSEQ2X12_ADDR				0x4CU
+#define CSR_ACSMSEQ2X13_ADDR				0x4DU
+#define CSR_ACSMSEQ2X14_ADDR				0x4EU
+#define CSR_ACSMSEQ2X15_ADDR				0x4FU
+#define CSR_ACSMSEQ2X16_ADDR				0x50U
+#define CSR_ACSMSEQ2X17_ADDR				0x51U
+#define CSR_ACSMSEQ2X18_ADDR				0x52U
+#define CSR_ACSMSEQ2X19_ADDR				0x53U
+#define CSR_ACSMSEQ2X20_ADDR				0x54U
+#define CSR_ACSMSEQ2X21_ADDR				0x55U
+#define CSR_ACSMSEQ2X22_ADDR				0x56U
+#define CSR_ACSMSEQ2X23_ADDR				0x57U
+#define CSR_ACSMSEQ2X24_ADDR				0x58U
+#define CSR_ACSMSEQ2X25_ADDR				0x59U
+#define CSR_ACSMSEQ2X26_ADDR				0x5AU
+#define CSR_ACSMSEQ2X27_ADDR				0x5BU
+#define CSR_ACSMSEQ2X28_ADDR				0x5CU
+#define CSR_ACSMSEQ2X29_ADDR				0x5DU
+#define CSR_ACSMSEQ2X30_ADDR				0x5EU
+#define CSR_ACSMSEQ2X31_ADDR				0x5FU
+#define CSR_ACSMSEQ3X0_ADDR				0x60U
+#define CSR_ACSMSEQ3X1_ADDR				0x61U
+#define CSR_ACSMSEQ3X2_ADDR				0x62U
+#define CSR_ACSMSEQ3X3_ADDR				0x63U
+#define CSR_ACSMSEQ3X4_ADDR				0x64U
+#define CSR_ACSMSEQ3X5_ADDR				0x65U
+#define CSR_ACSMSEQ3X6_ADDR				0x66U
+#define CSR_ACSMSEQ3X7_ADDR				0x67U
+#define CSR_ACSMSEQ3X8_ADDR				0x68U
+#define CSR_ACSMSEQ3X9_ADDR				0x69U
+#define CSR_ACSMSEQ3X10_ADDR				0x6AU
+#define CSR_ACSMSEQ3X11_ADDR				0x6BU
+#define CSR_ACSMSEQ3X12_ADDR				0x6CU
+#define CSR_ACSMSEQ3X13_ADDR				0x6DU
+#define CSR_ACSMSEQ3X14_ADDR				0x6EU
+#define CSR_ACSMSEQ3X15_ADDR				0x6FU
+#define CSR_ACSMSEQ3X16_ADDR				0x70U
+#define CSR_ACSMSEQ3X17_ADDR				0x71U
+#define CSR_ACSMSEQ3X18_ADDR				0x72U
+#define CSR_ACSMSEQ3X19_ADDR				0x73U
+#define CSR_ACSMSEQ3X20_ADDR				0x74U
+#define CSR_ACSMSEQ3X21_ADDR				0x75U
+#define CSR_ACSMSEQ3X22_ADDR				0x76U
+#define CSR_ACSMSEQ3X23_ADDR				0x77U
+#define CSR_ACSMSEQ3X24_ADDR				0x78U
+#define CSR_ACSMSEQ3X25_ADDR				0x79U
+#define CSR_ACSMSEQ3X26_ADDR				0x7AU
+#define CSR_ACSMSEQ3X27_ADDR				0x7BU
+#define CSR_ACSMSEQ3X28_ADDR				0x7CU
+#define CSR_ACSMSEQ3X29_ADDR				0x7DU
+#define CSR_ACSMSEQ3X30_ADDR				0x7EU
+#define CSR_ACSMSEQ3X31_ADDR				0x7FU
+#define CSR_ACSMPLAYBACK0X0_ADDR			0x80U
+#define CSR_ACSMPLAYBACK1X0_ADDR			0x81U
+#define CSR_ACSMPLAYBACK0X1_ADDR			0x82U
+#define CSR_ACSMPLAYBACK1X1_ADDR			0x83U
+#define CSR_ACSMPLAYBACK0X2_ADDR			0x84U
+#define CSR_ACSMPLAYBACK1X2_ADDR			0x85U
+#define CSR_ACSMPLAYBACK0X3_ADDR			0x86U
+#define CSR_ACSMPLAYBACK1X3_ADDR			0x87U
+#define CSR_ACSMPLAYBACK0X4_ADDR			0x88U
+#define CSR_ACSMPLAYBACK1X4_ADDR			0x89U
+#define CSR_ACSMPLAYBACK0X5_ADDR			0x8AU
+#define CSR_ACSMPLAYBACK1X5_ADDR			0x8BU
+#define CSR_ACSMPLAYBACK0X6_ADDR			0x8CU
+#define CSR_ACSMPLAYBACK1X6_ADDR			0x8DU
+#define CSR_ACSMPLAYBACK0X7_ADDR			0x8EU
+#define CSR_ACSMPLAYBACK1X7_ADDR			0x8FU
+#define CSR_ACSMPSTATEOVREN_ADDR			0x90U
+#define CSR_ACSMPSTATEOVRVAL_ADDR			0x91U
+#define CSR_ACSMCTRL23_ADDR				0xC0U
+#define CSR_ACSMCKEVAL_ADDR				0xC2U
+#define CSR_LOWSPEEDCLOCKDIVIDER_ADDR			0xC8U
+#define CSR_ACSMCSMAPCTRL0_ADDR				0xD0U
+#define CSR_ACSMCSMAPCTRL1_ADDR				0xD1U
+#define CSR_ACSMCSMAPCTRL2_ADDR				0xD2U
+#define CSR_ACSMCSMAPCTRL3_ADDR				0xD3U
+#define CSR_ACSMCSMAPCTRL4_ADDR				0xD4U
+#define CSR_ACSMCSMAPCTRL5_ADDR				0xD5U
+#define CSR_ACSMCSMAPCTRL6_ADDR				0xD6U
+#define CSR_ACSMCSMAPCTRL7_ADDR				0xD7U
+#define CSR_ACSMCSMAPCTRL8_ADDR				0xD8U
+#define CSR_ACSMCSMAPCTRL9_ADDR				0xD9U
+#define CSR_ACSMCSMAPCTRL10_ADDR			0xDAU
+#define CSR_ACSMCSMAPCTRL11_ADDR			0xDBU
+#define CSR_ACSMCSMAPCTRL12_ADDR			0xDCU
+#define CSR_ACSMCSMAPCTRL13_ADDR			0xDDU
+#define CSR_ACSMCSMAPCTRL14_ADDR			0xDEU
+#define CSR_ACSMCSMAPCTRL15_ADDR			0xDFU
+#define CSR_ACSMODTCTRL0_ADDR				0xE0U
+#define CSR_ACSMODTCTRL1_ADDR				0xE1U
+#define CSR_ACSMODTCTRL2_ADDR				0xE2U
+#define CSR_ACSMODTCTRL3_ADDR				0xE3U
+#define CSR_ACSMODTCTRL4_ADDR				0xE4U
+#define CSR_ACSMODTCTRL5_ADDR				0xE5U
+#define CSR_ACSMODTCTRL6_ADDR				0xE6U
+#define CSR_ACSMODTCTRL7_ADDR				0xE7U
+#define CSR_ACSMODTCTRL8_ADDR				0xE8U
+#define CSR_ACSMCTRL16_ADDR				0xE9U
+#define CSR_LOWSPEEDCLOCKSTOPVAL_ADDR			0xEAU
+#define CSR_ACSMCTRL18_ADDR				0xEBU
+#define CSR_ACSMCTRL19_ADDR				0xECU
+#define CSR_ACSMCTRL20_ADDR				0xEDU
+#define CSR_ACSMCTRL21_ADDR				0xEEU
+#define CSR_ACSMCTRL22_ADDR				0xEFU
+#define CSR_ACSMCTRL0_ADDR				0xF0U
+#define CSR_ACSMCTRL1_ADDR				0xF1U
+#define CSR_ACSMCTRL2_ADDR				0xF2U
+#define CSR_ACSMCTRL3_ADDR				0xF3U
+#define CSR_ACSMCTRL4_ADDR				0xF4U
+#define CSR_ACSMCTRL5_ADDR				0xF5U
+#define CSR_ACSMCTRL6_ADDR				0xF6U
+#define CSR_ACSMCTRL7_ADDR				0xF7U
+#define CSR_ACSMCTRL8_ADDR				0xF8U
+#define CSR_ACSMCTRL9_ADDR				0xF9U
+#define CSR_ACSMCTRL10_ADDR				0xFAU
+#define CSR_ACSMCTRL11_ADDR				0xFBU
+#define CSR_ACSMCTRL12_ADDR				0xFCU
+#define CSR_ACSMCTRL13_ADDR				0xFDU
+#define CSR_ACSMCTRL14_ADDR				0xFEU
+#define CSR_ACSMCTRL15_ADDR				0xFFU
+
+/* PPGC0 register offsets */
+#define CSR_PPGCCTRL1_ADDR				0x11U
+#define CSR_PPGCLANE2CRCINMAP0_ADDR			0x15U
+#define CSR_PPGCLANE2CRCINMAP1_ADDR			0x16U
+#define CSR_PRBSTAPDLY0_ADDR				0x24U
+#define CSR_PRBSTAPDLY1_ADDR				0x25U
+#define CSR_PRBSTAPDLY2_ADDR				0x26U
+#define CSR_PRBSTAPDLY3_ADDR				0x27U
+#define CSR_GENPRBSBYTE0_ADDR				0x30U
+#define CSR_GENPRBSBYTE1_ADDR				0x31U
+#define CSR_GENPRBSBYTE2_ADDR				0x32U
+#define CSR_GENPRBSBYTE3_ADDR				0x33U
+#define CSR_GENPRBSBYTE4_ADDR				0x34U
+#define CSR_GENPRBSBYTE5_ADDR				0x35U
+#define CSR_GENPRBSBYTE6_ADDR				0x36U
+#define CSR_GENPRBSBYTE7_ADDR				0x37U
+#define CSR_GENPRBSBYTE8_ADDR				0x38U
+#define CSR_GENPRBSBYTE9_ADDR				0x39U
+#define CSR_GENPRBSBYTE10_ADDR				0x3AU
+#define CSR_GENPRBSBYTE11_ADDR				0x3BU
+#define CSR_GENPRBSBYTE12_ADDR				0x3CU
+#define CSR_GENPRBSBYTE13_ADDR				0x3DU
+#define CSR_GENPRBSBYTE14_ADDR				0x3EU
+#define CSR_GENPRBSBYTE15_ADDR				0x3FU
+#define CSR_PRBSGENCTL_ADDR				0x60U
+#define CSR_PRBSGENSTATELO_ADDR				0x61U
+#define CSR_PRBSGENSTATEHI_ADDR				0x62U
+#define CSR_PRBSCHKSTATELO_ADDR				0x63U
+#define CSR_PRBSCHKSTATEHI_ADDR				0x64U
+#define CSR_PRBSGENCTL1_ADDR				0x65U
+#define CSR_PRBSGENCTL2_ADDR				0x66U
+
+/* INITENG0 register offsets */
+#define CSR_PRESEQUENCEREG0B0S0_ADDR			0x0U
+#define CSR_PRESEQUENCEREG0B0S1_ADDR			0x1U
+#define CSR_PRESEQUENCEREG0B0S2_ADDR			0x2U
+#define CSR_PRESEQUENCEREG0B1S0_ADDR			0x3U
+#define CSR_PRESEQUENCEREG0B1S1_ADDR			0x4U
+#define CSR_PRESEQUENCEREG0B1S2_ADDR			0x5U
+#define CSR_POSTSEQUENCEREG0B0S0_ADDR			0x6U
+#define CSR_POSTSEQUENCEREG0B0S1_ADDR			0x7U
+#define CSR_POSTSEQUENCEREG0B0S2_ADDR			0x8U
+#define CSR_POSTSEQUENCEREG0B1S0_ADDR			0x9U
+#define CSR_POSTSEQUENCEREG0B1S1_ADDR			0xAU
+#define CSR_POSTSEQUENCEREG0B1S2_ADDR			0xBU
+#define CSR_SEQ0BDISABLEFLAG0_ADDR			0xCU
+#define CSR_SEQ0BDISABLEFLAG1_ADDR			0xDU
+#define CSR_SEQ0BDISABLEFLAG2_ADDR			0xEU
+#define CSR_SEQ0BDISABLEFLAG3_ADDR			0xFU
+#define CSR_SEQ0BDISABLEFLAG4_ADDR			0x10U
+#define CSR_SEQ0BDISABLEFLAG5_ADDR			0x11U
+#define CSR_SEQ0BDISABLEFLAG6_ADDR			0x12U
+#define CSR_SEQ0BDISABLEFLAG7_ADDR			0x13U
+#define CSR_STARTVECTOR0B0_ADDR				0x17U
+#define CSR_STARTVECTOR0B1_ADDR				0x18U
+#define CSR_STARTVECTOR0B2_ADDR				0x19U
+#define CSR_STARTVECTOR0B3_ADDR				0x1AU
+#define CSR_STARTVECTOR0B4_ADDR				0x1BU
+#define CSR_STARTVECTOR0B5_ADDR				0x1CU
+#define CSR_STARTVECTOR0B6_ADDR				0x1DU
+#define CSR_STARTVECTOR0B7_ADDR				0x1EU
+#define CSR_STARTVECTOR0B8_ADDR				0x1FU
+#define CSR_STARTVECTOR0B9_ADDR				0x20U
+#define CSR_STARTVECTOR0B10_ADDR			0x21U
+#define CSR_STARTVECTOR0B11_ADDR			0x22U
+#define CSR_STARTVECTOR0B12_ADDR			0x23U
+#define CSR_STARTVECTOR0B13_ADDR			0x24U
+#define CSR_STARTVECTOR0B14_ADDR			0x25U
+#define CSR_STARTVECTOR0B15_ADDR			0x26U
+#define CSR_SEQ0BWAITCONDSEL_ADDR			0x27U
+#define CSR_PHYINLP3_ADDR				0x28U
+#define CSR_SEQUENCEREG0B0S0_ADDR			0x29U
+#define CSR_SEQUENCEREG0B0S1_ADDR			0x2AU
+#define CSR_SEQUENCEREG0B0S2_ADDR			0x2BU
+#define CSR_SEQUENCEREG0B1S0_ADDR			0x2CU
+#define CSR_SEQUENCEREG0B1S1_ADDR			0x2DU
+#define CSR_SEQUENCEREG0B1S2_ADDR			0x2EU
+#define CSR_SEQUENCEREG0B2S0_ADDR			0x2FU
+#define CSR_SEQUENCEREG0B2S1_ADDR			0x30U
+#define CSR_SEQUENCEREG0B2S2_ADDR			0x31U
+#define CSR_SEQUENCEREG0B3S0_ADDR			0x32U
+#define CSR_SEQUENCEREG0B3S1_ADDR			0x33U
+#define CSR_SEQUENCEREG0B3S2_ADDR			0x34U
+#define CSR_SEQUENCEREG0B4S0_ADDR			0x35U
+#define CSR_SEQUENCEREG0B4S1_ADDR			0x36U
+#define CSR_SEQUENCEREG0B4S2_ADDR			0x37U
+#define CSR_SEQUENCEREG0B5S0_ADDR			0x38U
+#define CSR_SEQUENCEREG0B5S1_ADDR			0x39U
+#define CSR_SEQUENCEREG0B5S2_ADDR			0x3AU
+#define CSR_SEQUENCEREG0B6S0_ADDR			0x3BU
+#define CSR_SEQUENCEREG0B6S1_ADDR			0x3CU
+#define CSR_SEQUENCEREG0B6S2_ADDR			0x3DU
+#define CSR_SEQUENCEREG0B7S0_ADDR			0x3EU
+#define CSR_SEQUENCEREG0B7S1_ADDR			0x3FU
+#define CSR_SEQUENCEREG0B7S2_ADDR			0x40U
+#define CSR_SEQUENCEREG0B8S0_ADDR			0x41U
+#define CSR_SEQUENCEREG0B8S1_ADDR			0x42U
+#define CSR_SEQUENCEREG0B8S2_ADDR			0x43U
+#define CSR_SEQUENCEREG0B9S0_ADDR			0x44U
+#define CSR_SEQUENCEREG0B9S1_ADDR			0x45U
+#define CSR_SEQUENCEREG0B9S2_ADDR			0x46U
+#define CSR_SEQUENCEREG0B10S0_ADDR			0x47U
+#define CSR_SEQUENCEREG0B10S1_ADDR			0x48U
+#define CSR_SEQUENCEREG0B10S2_ADDR			0x49U
+#define CSR_SEQUENCEREG0B11S0_ADDR			0x4AU
+#define CSR_SEQUENCEREG0B11S1_ADDR			0x4BU
+#define CSR_SEQUENCEREG0B11S2_ADDR			0x4CU
+#define CSR_SEQUENCEREG0B12S0_ADDR			0x4DU
+#define CSR_SEQUENCEREG0B12S1_ADDR			0x4EU
+#define CSR_SEQUENCEREG0B12S2_ADDR			0x4FU
+#define CSR_SEQUENCEREG0B13S0_ADDR			0x50U
+#define CSR_SEQUENCEREG0B13S1_ADDR			0x51U
+#define CSR_SEQUENCEREG0B13S2_ADDR			0x52U
+#define CSR_SEQUENCEREG0B14S0_ADDR			0x53U
+#define CSR_SEQUENCEREG0B14S1_ADDR			0x54U
+#define CSR_SEQUENCEREG0B14S2_ADDR			0x55U
+#define CSR_SEQUENCEREG0B15S0_ADDR			0x56U
+#define CSR_SEQUENCEREG0B15S1_ADDR			0x57U
+#define CSR_SEQUENCEREG0B15S2_ADDR			0x58U
+#define CSR_SEQUENCEREG0B16S0_ADDR			0x59U
+#define CSR_SEQUENCEREG0B16S1_ADDR			0x5AU
+#define CSR_SEQUENCEREG0B16S2_ADDR			0x5BU
+#define CSR_SEQUENCEREG0B17S0_ADDR			0x5CU
+#define CSR_SEQUENCEREG0B17S1_ADDR			0x5DU
+#define CSR_SEQUENCEREG0B17S2_ADDR			0x5EU
+#define CSR_SEQUENCEREG0B18S0_ADDR			0x5FU
+#define CSR_SEQUENCEREG0B18S1_ADDR			0x60U
+#define CSR_SEQUENCEREG0B18S2_ADDR			0x61U
+#define CSR_SEQUENCEREG0B19S0_ADDR			0x62U
+#define CSR_SEQUENCEREG0B19S1_ADDR			0x63U
+#define CSR_SEQUENCEREG0B19S2_ADDR			0x64U
+#define CSR_SEQUENCEREG0B20S0_ADDR			0x65U
+#define CSR_SEQUENCEREG0B20S1_ADDR			0x66U
+#define CSR_SEQUENCEREG0B20S2_ADDR			0x67U
+#define CSR_SEQUENCEREG0B21S0_ADDR			0x68U
+#define CSR_SEQUENCEREG0B21S1_ADDR			0x69U
+#define CSR_SEQUENCEREG0B21S2_ADDR			0x6AU
+#define CSR_SEQUENCEREG0B22S0_ADDR			0x6BU
+#define CSR_SEQUENCEREG0B22S1_ADDR			0x6CU
+#define CSR_SEQUENCEREG0B22S2_ADDR			0x6DU
+#define CSR_SEQUENCEREG0B23S0_ADDR			0x6EU
+#define CSR_SEQUENCEREG0B23S1_ADDR			0x6FU
+#define CSR_SEQUENCEREG0B23S2_ADDR			0x70U
+#define CSR_SEQUENCEREG0B24S0_ADDR			0x71U
+#define CSR_SEQUENCEREG0B24S1_ADDR			0x72U
+#define CSR_SEQUENCEREG0B24S2_ADDR			0x73U
+#define CSR_SEQUENCEREG0B25S0_ADDR			0x74U
+#define CSR_SEQUENCEREG0B25S1_ADDR			0x75U
+#define CSR_SEQUENCEREG0B25S2_ADDR			0x76U
+#define CSR_SEQUENCEREG0B26S0_ADDR			0x77U
+#define CSR_SEQUENCEREG0B26S1_ADDR			0x78U
+#define CSR_SEQUENCEREG0B26S2_ADDR			0x79U
+#define CSR_SEQUENCEREG0B27S0_ADDR			0x7AU
+#define CSR_SEQUENCEREG0B27S1_ADDR			0x7BU
+#define CSR_SEQUENCEREG0B27S2_ADDR			0x7CU
+#define CSR_SEQUENCEREG0B28S0_ADDR			0x7DU
+#define CSR_SEQUENCEREG0B28S1_ADDR			0x7EU
+#define CSR_SEQUENCEREG0B28S2_ADDR			0x7FU
+#define CSR_SEQUENCEREG0B29S0_ADDR			0x80U
+#define CSR_SEQUENCEREG0B29S1_ADDR			0x81U
+#define CSR_SEQUENCEREG0B29S2_ADDR			0x82U
+#define CSR_SEQUENCEREG0B30S0_ADDR			0x83U
+#define CSR_SEQUENCEREG0B30S1_ADDR			0x84U
+#define CSR_SEQUENCEREG0B30S2_ADDR			0x85U
+#define CSR_SEQUENCEREG0B31S0_ADDR			0x86U
+#define CSR_SEQUENCEREG0B31S1_ADDR			0x87U
+#define CSR_SEQUENCEREG0B31S2_ADDR			0x88U
+#define CSR_SEQUENCEREG0B32S0_ADDR			0x89U
+#define CSR_SEQUENCEREG0B32S1_ADDR			0x8AU
+#define CSR_SEQUENCEREG0B32S2_ADDR			0x8BU
+#define CSR_SEQUENCEREG0B33S0_ADDR			0x8CU
+#define CSR_SEQUENCEREG0B33S1_ADDR			0x8DU
+#define CSR_SEQUENCEREG0B33S2_ADDR			0x8EU
+#define CSR_SEQUENCEREG0B34S0_ADDR			0x8FU
+#define CSR_SEQUENCEREG0B34S1_ADDR			0x90U
+#define CSR_SEQUENCEREG0B34S2_ADDR			0x91U
+#define CSR_SEQUENCEREG0B35S0_ADDR			0x92U
+#define CSR_SEQUENCEREG0B35S1_ADDR			0x93U
+#define CSR_SEQUENCEREG0B35S2_ADDR			0x94U
+#define CSR_SEQUENCEREG0B36S0_ADDR			0x95U
+#define CSR_SEQUENCEREG0B36S1_ADDR			0x96U
+#define CSR_SEQUENCEREG0B36S2_ADDR			0x97U
+#define CSR_SEQUENCEREG0B37S0_ADDR			0x98U
+#define CSR_SEQUENCEREG0B37S1_ADDR			0x99U
+#define CSR_SEQUENCEREG0B37S2_ADDR			0x9AU
+#define CSR_SEQUENCEREG0B38S0_ADDR			0x9BU
+#define CSR_SEQUENCEREG0B38S1_ADDR			0x9CU
+#define CSR_SEQUENCEREG0B38S2_ADDR			0x9DU
+#define CSR_SEQUENCEREG0B39S0_ADDR			0x9EU
+#define CSR_SEQUENCEREG0B39S1_ADDR			0x9FU
+#define CSR_SEQUENCEREG0B39S2_ADDR			0xA0U
+#define CSR_SEQUENCEREG0B40S0_ADDR			0xA1U
+#define CSR_SEQUENCEREG0B40S1_ADDR			0xA2U
+#define CSR_SEQUENCEREG0B40S2_ADDR			0xA3U
+#define CSR_SEQUENCEREG0B41S0_ADDR			0xA4U
+#define CSR_SEQUENCEREG0B41S1_ADDR			0xA5U
+#define CSR_SEQUENCEREG0B41S2_ADDR			0xA6U
+#define CSR_SEQUENCEREG0B42S0_ADDR			0xA7U
+#define CSR_SEQUENCEREG0B42S1_ADDR			0xA8U
+#define CSR_SEQUENCEREG0B42S2_ADDR			0xA9U
+#define CSR_SEQUENCEREG0B43S0_ADDR			0xAAU
+#define CSR_SEQUENCEREG0B43S1_ADDR			0xABU
+#define CSR_SEQUENCEREG0B43S2_ADDR			0xACU
+#define CSR_SEQUENCEREG0B44S0_ADDR			0xADU
+#define CSR_SEQUENCEREG0B44S1_ADDR			0xAEU
+#define CSR_SEQUENCEREG0B44S2_ADDR			0xAFU
+#define CSR_SEQUENCEREG0B45S0_ADDR			0xB0U
+#define CSR_SEQUENCEREG0B45S1_ADDR			0xB1U
+#define CSR_SEQUENCEREG0B45S2_ADDR			0xB2U
+#define CSR_SEQUENCEREG0B46S0_ADDR			0xB3U
+#define CSR_SEQUENCEREG0B46S1_ADDR			0xB4U
+#define CSR_SEQUENCEREG0B46S2_ADDR			0xB5U
+#define CSR_SEQUENCEREG0B47S0_ADDR			0xB6U
+#define CSR_SEQUENCEREG0B47S1_ADDR			0xB7U
+#define CSR_SEQUENCEREG0B47S2_ADDR			0xB8U
+#define CSR_SEQUENCEREG0B48S0_ADDR			0xB9U
+#define CSR_SEQUENCEREG0B48S1_ADDR			0xBAU
+#define CSR_SEQUENCEREG0B48S2_ADDR			0xBBU
+#define CSR_SEQUENCEREG0B49S0_ADDR			0xBCU
+#define CSR_SEQUENCEREG0B49S1_ADDR			0xBDU
+#define CSR_SEQUENCEREG0B49S2_ADDR			0xBEU
+#define CSR_SEQUENCEREG0B50S0_ADDR			0xBFU
+#define CSR_SEQUENCEREG0B50S1_ADDR			0xC0U
+#define CSR_SEQUENCEREG0B50S2_ADDR			0xC1U
+#define CSR_SEQUENCEREG0B51S0_ADDR			0xC2U
+#define CSR_SEQUENCEREG0B51S1_ADDR			0xC3U
+#define CSR_SEQUENCEREG0B51S2_ADDR			0xC4U
+#define CSR_SEQUENCEREG0B52S0_ADDR			0xC5U
+#define CSR_SEQUENCEREG0B52S1_ADDR			0xC6U
+#define CSR_SEQUENCEREG0B52S2_ADDR			0xC7U
+#define CSR_SEQUENCEREG0B53S0_ADDR			0xC8U
+#define CSR_SEQUENCEREG0B53S1_ADDR			0xC9U
+#define CSR_SEQUENCEREG0B53S2_ADDR			0xCAU
+#define CSR_SEQUENCEREG0B54S0_ADDR			0xCBU
+#define CSR_SEQUENCEREG0B54S1_ADDR			0xCCU
+#define CSR_SEQUENCEREG0B54S2_ADDR			0xCDU
+#define CSR_SEQUENCEREG0B55S0_ADDR			0xCEU
+#define CSR_SEQUENCEREG0B55S1_ADDR			0xCFU
+#define CSR_SEQUENCEREG0B55S2_ADDR			0xD0U
+#define CSR_SEQUENCEREG0B56S0_ADDR			0xD1U
+#define CSR_SEQUENCEREG0B56S1_ADDR			0xD2U
+#define CSR_SEQUENCEREG0B56S2_ADDR			0xD3U
+#define CSR_SEQUENCEREG0B57S0_ADDR			0xD4U
+#define CSR_SEQUENCEREG0B57S1_ADDR			0xD5U
+#define CSR_SEQUENCEREG0B57S2_ADDR			0xD6U
+#define CSR_SEQUENCEREG0B58S0_ADDR			0xD7U
+#define CSR_SEQUENCEREG0B58S1_ADDR			0xD8U
+#define CSR_SEQUENCEREG0B58S2_ADDR			0xD9U
+#define CSR_SEQUENCEREG0B59S0_ADDR			0xDAU
+#define CSR_SEQUENCEREG0B59S1_ADDR			0xDBU
+#define CSR_SEQUENCEREG0B59S2_ADDR			0xDCU
+#define CSR_SEQUENCEREG0B60S0_ADDR			0xDDU
+#define CSR_SEQUENCEREG0B60S1_ADDR			0xDEU
+#define CSR_SEQUENCEREG0B60S2_ADDR			0xDFU
+#define CSR_SEQUENCEREG0B61S0_ADDR			0xE0U
+#define CSR_SEQUENCEREG0B61S1_ADDR			0xE1U
+#define CSR_SEQUENCEREG0B61S2_ADDR			0xE2U
+#define CSR_SEQUENCEREG0B62S0_ADDR			0xE3U
+#define CSR_SEQUENCEREG0B62S1_ADDR			0xE4U
+#define CSR_SEQUENCEREG0B62S2_ADDR			0xE5U
+#define CSR_SEQUENCEREG0B63S0_ADDR			0xE6U
+#define CSR_SEQUENCEREG0B63S1_ADDR			0xE7U
+#define CSR_SEQUENCEREG0B63S2_ADDR			0xE8U
+#define CSR_SEQUENCEREG0B64S0_ADDR			0xE9U
+#define CSR_SEQUENCEREG0B64S1_ADDR			0xEAU
+#define CSR_SEQUENCEREG0B64S2_ADDR			0xEBU
+#define CSR_SEQUENCEREG0B65S0_ADDR			0xECU
+#define CSR_SEQUENCEREG0B65S1_ADDR			0xEDU
+#define CSR_SEQUENCEREG0B65S2_ADDR			0xEEU
+#define CSR_SEQUENCEREG0B66S0_ADDR			0xEFU
+#define CSR_SEQUENCEREG0B66S1_ADDR			0xF0U
+#define CSR_SEQUENCEREG0B66S2_ADDR			0xF1U
+#define CSR_SEQUENCEREG0B67S0_ADDR			0xF2U
+#define CSR_SEQUENCEREG0B67S1_ADDR			0xF3U
+#define CSR_SEQUENCEREG0B67S2_ADDR			0xF4U
+#define CSR_SEQUENCEREG0B68S0_ADDR			0xF5U
+#define CSR_SEQUENCEREG0B68S1_ADDR			0xF6U
+#define CSR_SEQUENCEREG0B68S2_ADDR			0xF7U
+#define CSR_SEQUENCEREG0B69S0_ADDR			0xF8U
+#define CSR_SEQUENCEREG0B69S1_ADDR			0xF9U
+#define CSR_SEQUENCEREG0B69S2_ADDR			0xFAU
+#define CSR_SEQUENCEREG0B70S0_ADDR			0xFBU
+#define CSR_SEQUENCEREG0B70S1_ADDR			0xFCU
+#define CSR_SEQUENCEREG0B70S2_ADDR			0xFDU
+#define CSR_SEQUENCEREG0B71S0_ADDR			0xFEU
+#define CSR_SEQUENCEREG0B71S1_ADDR			0xFFU
+#define CSR_SEQUENCEREG0B71S2_ADDR			0x100U
+#define CSR_SEQUENCEREG0B72S0_ADDR			0x101U
+#define CSR_SEQUENCEREG0B72S1_ADDR			0x102U
+#define CSR_SEQUENCEREG0B72S2_ADDR			0x103U
+#define CSR_SEQUENCEREG0B73S0_ADDR			0x104U
+#define CSR_SEQUENCEREG0B73S1_ADDR			0x105U
+#define CSR_SEQUENCEREG0B73S2_ADDR			0x106U
+#define CSR_SEQUENCEREG0B74S0_ADDR			0x107U
+#define CSR_SEQUENCEREG0B74S1_ADDR			0x108U
+#define CSR_SEQUENCEREG0B74S2_ADDR			0x109U
+#define CSR_SEQUENCEREG0B75S0_ADDR			0x10AU
+#define CSR_SEQUENCEREG0B75S1_ADDR			0x10BU
+#define CSR_SEQUENCEREG0B75S2_ADDR			0x10CU
+#define CSR_SEQUENCEREG0B76S0_ADDR			0x10DU
+#define CSR_SEQUENCEREG0B76S1_ADDR			0x10EU
+#define CSR_SEQUENCEREG0B76S2_ADDR			0x10FU
+#define CSR_SEQUENCEREG0B77S0_ADDR			0x110U
+#define CSR_SEQUENCEREG0B77S1_ADDR			0x111U
+#define CSR_SEQUENCEREG0B77S2_ADDR			0x112U
+#define CSR_SEQUENCEREG0B78S0_ADDR			0x113U
+#define CSR_SEQUENCEREG0B78S1_ADDR			0x114U
+#define CSR_SEQUENCEREG0B78S2_ADDR			0x115U
+#define CSR_SEQUENCEREG0B79S0_ADDR			0x116U
+#define CSR_SEQUENCEREG0B79S1_ADDR			0x117U
+#define CSR_SEQUENCEREG0B79S2_ADDR			0x118U
+#define CSR_SEQUENCEREG0B80S0_ADDR			0x119U
+#define CSR_SEQUENCEREG0B80S1_ADDR			0x11AU
+#define CSR_SEQUENCEREG0B80S2_ADDR			0x11BU
+#define CSR_SEQUENCEREG0B81S0_ADDR			0x11CU
+#define CSR_SEQUENCEREG0B81S1_ADDR			0x11DU
+#define CSR_SEQUENCEREG0B81S2_ADDR			0x11EU
+#define CSR_SEQUENCEREG0B82S0_ADDR			0x11FU
+#define CSR_SEQUENCEREG0B82S1_ADDR			0x120U
+#define CSR_SEQUENCEREG0B82S2_ADDR			0x121U
+#define CSR_SEQUENCEREG0B83S0_ADDR			0x122U
+#define CSR_SEQUENCEREG0B83S1_ADDR			0x123U
+#define CSR_SEQUENCEREG0B83S2_ADDR			0x124U
+#define CSR_SEQUENCEREG0B84S0_ADDR			0x125U
+#define CSR_SEQUENCEREG0B84S1_ADDR			0x126U
+#define CSR_SEQUENCEREG0B84S2_ADDR			0x127U
+#define CSR_SEQUENCEREG0B85S0_ADDR			0x128U
+#define CSR_SEQUENCEREG0B85S1_ADDR			0x129U
+#define CSR_SEQUENCEREG0B85S2_ADDR			0x12AU
+#define CSR_SEQUENCEREG0B86S0_ADDR			0x12BU
+#define CSR_SEQUENCEREG0B86S1_ADDR			0x12CU
+#define CSR_SEQUENCEREG0B86S2_ADDR			0x12DU
+#define CSR_SEQUENCEREG0B87S0_ADDR			0x12EU
+#define CSR_SEQUENCEREG0B87S1_ADDR			0x12FU
+#define CSR_SEQUENCEREG0B87S2_ADDR			0x130U
+#define CSR_SEQUENCEREG0B88S0_ADDR			0x131U
+#define CSR_SEQUENCEREG0B88S1_ADDR			0x132U
+#define CSR_SEQUENCEREG0B88S2_ADDR			0x133U
+#define CSR_SEQUENCEREG0B89S0_ADDR			0x134U
+#define CSR_SEQUENCEREG0B89S1_ADDR			0x135U
+#define CSR_SEQUENCEREG0B89S2_ADDR			0x136U
+#define CSR_SEQUENCEREG0B90S0_ADDR			0x137U
+#define CSR_SEQUENCEREG0B90S1_ADDR			0x138U
+#define CSR_SEQUENCEREG0B90S2_ADDR			0x139U
+#define CSR_SEQUENCEREG0B91S0_ADDR			0x13AU
+#define CSR_SEQUENCEREG0B91S1_ADDR			0x13BU
+#define CSR_SEQUENCEREG0B91S2_ADDR			0x13CU
+#define CSR_SEQUENCEREG0B92S0_ADDR			0x13DU
+#define CSR_SEQUENCEREG0B92S1_ADDR			0x13EU
+#define CSR_SEQUENCEREG0B92S2_ADDR			0x13FU
+#define CSR_SEQUENCEREG0B93S0_ADDR			0x140U
+#define CSR_SEQUENCEREG0B93S1_ADDR			0x141U
+#define CSR_SEQUENCEREG0B93S2_ADDR			0x142U
+#define CSR_SEQUENCEREG0B94S0_ADDR			0x143U
+#define CSR_SEQUENCEREG0B94S1_ADDR			0x144U
+#define CSR_SEQUENCEREG0B94S2_ADDR			0x145U
+#define CSR_SEQUENCEREG0B95S0_ADDR			0x146U
+#define CSR_SEQUENCEREG0B95S1_ADDR			0x147U
+#define CSR_SEQUENCEREG0B95S2_ADDR			0x148U
+#define CSR_SEQUENCEREG0B96S0_ADDR			0x149U
+#define CSR_SEQUENCEREG0B96S1_ADDR			0x14AU
+#define CSR_SEQUENCEREG0B96S2_ADDR			0x14BU
+#define CSR_SEQUENCEREG0B97S0_ADDR			0x14CU
+#define CSR_SEQUENCEREG0B97S1_ADDR			0x14DU
+#define CSR_SEQUENCEREG0B97S2_ADDR			0x14EU
+#define CSR_SEQUENCEREG0B98S0_ADDR			0x14FU
+#define CSR_SEQUENCEREG0B98S1_ADDR			0x150U
+#define CSR_SEQUENCEREG0B98S2_ADDR			0x151U
+#define CSR_SEQUENCEREG0B99S0_ADDR			0x152U
+#define CSR_SEQUENCEREG0B99S1_ADDR			0x153U
+#define CSR_SEQUENCEREG0B99S2_ADDR			0x154U
+#define CSR_SEQUENCEREG0B100S0_ADDR			0x155U
+#define CSR_SEQUENCEREG0B100S1_ADDR			0x156U
+#define CSR_SEQUENCEREG0B100S2_ADDR			0x157U
+#define CSR_SEQUENCEREG0B101S0_ADDR			0x158U
+#define CSR_SEQUENCEREG0B101S1_ADDR			0x159U
+#define CSR_SEQUENCEREG0B101S2_ADDR			0x15AU
+#define CSR_SEQUENCEREG0B102S0_ADDR			0x15BU
+#define CSR_SEQUENCEREG0B102S1_ADDR			0x15CU
+#define CSR_SEQUENCEREG0B102S2_ADDR			0x15DU
+#define CSR_SEQUENCEREG0B103S0_ADDR			0x15EU
+#define CSR_SEQUENCEREG0B103S1_ADDR			0x15FU
+#define CSR_SEQUENCEREG0B103S2_ADDR			0x160U
+#define CSR_SEQUENCEREG0B104S0_ADDR			0x161U
+#define CSR_SEQUENCEREG0B104S1_ADDR			0x162U
+#define CSR_SEQUENCEREG0B104S2_ADDR			0x163U
+#define CSR_SEQUENCEREG0B105S0_ADDR			0x164U
+#define CSR_SEQUENCEREG0B105S1_ADDR			0x165U
+#define CSR_SEQUENCEREG0B105S2_ADDR			0x166U
+#define CSR_SEQUENCEREG0B106S0_ADDR			0x167U
+#define CSR_SEQUENCEREG0B106S1_ADDR			0x168U
+#define CSR_SEQUENCEREG0B106S2_ADDR			0x169U
+#define CSR_SEQUENCEREG0B107S0_ADDR			0x16AU
+#define CSR_SEQUENCEREG0B107S1_ADDR			0x16BU
+#define CSR_SEQUENCEREG0B107S2_ADDR			0x16CU
+#define CSR_SEQUENCEREG0B108S0_ADDR			0x16DU
+#define CSR_SEQUENCEREG0B108S1_ADDR			0x16EU
+#define CSR_SEQUENCEREG0B108S2_ADDR			0x16FU
+#define CSR_SEQUENCEREG0B109S0_ADDR			0x170U
+#define CSR_SEQUENCEREG0B109S1_ADDR			0x171U
+#define CSR_SEQUENCEREG0B109S2_ADDR			0x172U
+#define CSR_SEQUENCEREG0B110S0_ADDR			0x173U
+#define CSR_SEQUENCEREG0B110S1_ADDR			0x174U
+#define CSR_SEQUENCEREG0B110S2_ADDR			0x175U
+#define CSR_SEQUENCEREG0B111S0_ADDR			0x176U
+#define CSR_SEQUENCEREG0B111S1_ADDR			0x177U
+#define CSR_SEQUENCEREG0B111S2_ADDR			0x178U
+#define CSR_SEQUENCEREG0B112S0_ADDR			0x179U
+#define CSR_SEQUENCEREG0B112S1_ADDR			0x17AU
+#define CSR_SEQUENCEREG0B112S2_ADDR			0x17BU
+#define CSR_SEQUENCEREG0B113S0_ADDR			0x17CU
+#define CSR_SEQUENCEREG0B113S1_ADDR			0x17DU
+#define CSR_SEQUENCEREG0B113S2_ADDR			0x17EU
+#define CSR_SEQUENCEREG0B114S0_ADDR			0x17FU
+#define CSR_SEQUENCEREG0B114S1_ADDR			0x180U
+#define CSR_SEQUENCEREG0B114S2_ADDR			0x181U
+#define CSR_SEQUENCEREG0B115S0_ADDR			0x182U
+#define CSR_SEQUENCEREG0B115S1_ADDR			0x183U
+#define CSR_SEQUENCEREG0B115S2_ADDR			0x184U
+#define CSR_SEQUENCEREG0B116S0_ADDR			0x185U
+#define CSR_SEQUENCEREG0B116S1_ADDR			0x186U
+#define CSR_SEQUENCEREG0B116S2_ADDR			0x187U
+#define CSR_SEQUENCEREG0B117S0_ADDR			0x188U
+#define CSR_SEQUENCEREG0B117S1_ADDR			0x189U
+#define CSR_SEQUENCEREG0B117S2_ADDR			0x18AU
+#define CSR_SEQUENCEREG0B118S0_ADDR			0x18BU
+#define CSR_SEQUENCEREG0B118S1_ADDR			0x18CU
+#define CSR_SEQUENCEREG0B118S2_ADDR			0x18DU
+#define CSR_SEQUENCEREG0B119S0_ADDR			0x18EU
+#define CSR_SEQUENCEREG0B119S1_ADDR			0x18FU
+#define CSR_SEQUENCEREG0B119S2_ADDR			0x190U
+#define CSR_SEQUENCEREG0B120S0_ADDR			0x191U
+#define CSR_SEQUENCEREG0B120S1_ADDR			0x192U
+#define CSR_SEQUENCEREG0B120S2_ADDR			0x193U
+#define CSR_SEQUENCEREG0B121S0_ADDR			0x194U
+#define CSR_SEQUENCEREG0B121S1_ADDR			0x195U
+#define CSR_SEQUENCEREG0B121S2_ADDR			0x196U
+#define CSR_SEQ0BGPR1_ADDR				0x201U
+#define CSR_SEQ0BGPR2_ADDR				0x202U
+#define CSR_SEQ0BGPR3_ADDR				0x203U
+#define CSR_SEQ0BGPR4_ADDR				0x204U
+#define CSR_SEQ0BGPR5_ADDR				0x205U
+#define CSR_SEQ0BGPR6_ADDR				0x206U
+#define CSR_SEQ0BGPR7_ADDR				0x207U
+#define CSR_SEQ0BGPR8_ADDR				0x208U
+#define CSR_SEQ0BFIXEDADDRBITS_ADDR			0x2FFU
+
+/* DRTUB0 register offsets */
+#define CSR_DCTSHADOWREGS_ADDR				0x4U
+#define CSR_DCTWRITEONLYSHADOW_ADDR			0x30U
+#define CSR_UCTWRITEONLY_ADDR				0x32U
+#define CSR_UCTWRITEPROT_ADDR				0x33U
+#define CSR_UCTDATWRITEONLY_ADDR			0x34U
+#define CSR_UCTDATWRITEPROT_ADDR			0x35U
+#define CSR_UCTLERR_ADDR				0x36U
+#define CSR_UCCLKHCLKENABLES_ADDR			0x80U
+#define CSR_CURPSTATE0B_ADDR				0x81U
+#define CSR_CLRWAKEUPSTICKY_ADDR			0x95U
+#define CSR_WAKEUPMASK_ADDR				0x96U
+#define CSR_CUSTPUBREV_ADDR				0xEDU
+#define CSR_PUBREV_ADDR					0xEEU
+
+/* APBONLY0 register offsets */
+#define CSR_MICROCONTMUXSEL_ADDR			0x0U
+#define CSR_UCTSHADOWREGS_ADDR				0x4U
+#define CSR_DCTWRITEONLY_ADDR				0x30U
+#define CSR_DCTWRITEPROT_ADDR				0x31U
+#define CSR_UCTWRITEONLYSHADOW_ADDR			0x32U
+#define CSR_UCTDATWRITEONLYSHADOW_ADDR			0x34U
+#define CSR_NEVERGATECSRCLOCK_ADDR			0x35U
+#define CSR_DFICFGRDDATAVALIDTICKS_ADDR			0x37U
+#define CSR_MICRORESET_ADDR				0x99U
+#define CSR_SEQUENCEROVERRIDE_ADDR			0xE7U
+#define CSR_DFIINITCOMPLETESHADOW_ADDR			0xFAU
+
+/* ANIBx register bit fields */
+/* CSR_MTESTMUXSEL */
+#define CSR_MTESTMUXSEL_LSB				0
+#define CSR_MTESTMUXSEL_MASK				GENMASK_32(5, 0)
+/* CSR_AFORCEDRVCONT */
+#define CSR_AFORCEDRVCONT_LSB				0
+#define CSR_AFORCEDRVCONT_MASK				GENMASK_32(3, 0)
+/* CSR_AFORCETRICONT */
+#define CSR_AFORCETRICONT_LSB				0
+#define CSR_AFORCETRICONT_MASK				GENMASK_32(3, 0)
+/* CSR_ATXIMPEDANCE */
+#define CSR_ATXIMPEDANCE_LSB				0
+#define CSR_ATXIMPEDANCE_MASK				GENMASK_32(9, 0)
+#define CSR_ADRVSTRENP_LSB				0
+#define CSR_ADRVSTRENP_MASK				GENMASK_32(4, 0)
+#define CSR_ADRVSTRENN_LSB				5
+#define CSR_ADRVSTRENN_MASK				GENMASK_32(9, 5)
+/* CSR_ATESTPRBSERR */
+#define CSR_ATESTPRBSERR_LSB				0
+#define CSR_ATESTPRBSERR_MASK				GENMASK_32(3, 0)
+/* CSR_ATXSLEWRATE */
+#define CSR_ATXSLEWRATE_LSB				0
+#define CSR_ATXSLEWRATE_MASK				GENMASK_32(10, 0)
+#define CSR_ATXPREP_LSB					0
+#define CSR_ATXPREP_MASK				GENMASK_32(3, 0)
+#define CSR_ATXPREN_LSB					4
+#define CSR_ATXPREN_MASK				GENMASK_32(7, 4)
+#define CSR_ATXPREDRVMODE_LSB				8
+#define CSR_ATXPREDRVMODE_MASK				GENMASK_32(10, 8)
+/* CSR_ATESTPRBSERRCNT */
+#define CSR_ATESTPRBSERRCNT_LSB				0
+#define CSR_ATESTPRBSERRCNT_MASK			GENMASK_32(15, 0)
+/* CSR_ATXDLY */
+#define CSR_ATXDLY_LSB					0
+#define CSR_ATXDLY_MASK					GENMASK_32(6, 0)
+
+/* DBYTEx register bit fields */
+/* CSR_DBYTEMISCMODE */
+#define CSR_DBYTEMISCMODE_LSB				2
+#define CSR_DBYTEMISCMODE_MASK				BIT(2)
+#define CSR_DBYTEDISABLE_LSB				2
+#define CSR_DBYTEDISABLE_MASK				BIT(2)
+/* CSR_TSMBYTE0 */
+#define CSR_TSMBYTE0_LSB				0
+#define CSR_TSMBYTE0_MASK				GENMASK_32(15, 0)
+#define CSR_PERPHTRAINEN_LSB				0
+#define CSR_PERPHTRAINEN_MASK				BIT(0)
+#define CSR_EYEINC_LSB					1
+#define CSR_EYEINC_MASK					BIT(1)
+#define CSR_EDGEINC_LSB					2
+#define CSR_EDGEINC_MASK				BIT(2)
+#define CSR_EDGEEYEMXSEL_LSB				3
+#define CSR_EDGEEYEMXSEL_MASK				BIT(3)
+#define CSR_TSMBYTE0RSVD_LSB				4
+#define CSR_TSMBYTE0RSVD_MASK				GENMASK_32(5, 4)
+#define CSR_DIMMBROADINC_LSB				6
+#define CSR_DIMMBROADINC_MASK				BIT(6)
+#define CSR_DIMMINC_LSB					7
+#define CSR_DIMMINC_MASK				GENMASK_32(8, 7)
+#define CSR_COARSEINC_LSB				9
+#define CSR_COARSEINC_MASK				BIT(9)
+#define CSR_DELAYINC_LSB				10
+#define CSR_DELAYINC_MASK				BIT(10)
+#define CSR_RXINC_LSB					11
+#define CSR_RXINC_MASK					BIT(11)
+#define CSR_RXPERTRAIN_LSB				12
+#define CSR_RXPERTRAIN_MASK				BIT(12)
+#define CSR_TXPERTRAIN_LSB				13
+#define CSR_TXPERTRAIN_MASK				BIT(13)
+#define CSR_DMTRAIN_LSB					14
+#define CSR_DMTRAIN_MASK				BIT(14)
+#define CSR_WRLEVTRAIN_LSB				15
+#define CSR_WRLEVTRAIN_MASK				BIT(15)
+/* CSR_TRAININGPARAM */
+#define CSR_TRAININGPARAM_LSB				0
+#define CSR_TRAININGPARAM_MASK				GENMASK_32(15, 0)
+#define CSR_ENDYNRATEREDUCTION_LSB			0
+#define CSR_ENDYNRATEREDUCTION_MASK			BIT(0)
+#define CSR_TRAININGPARAM01RSVD_LSB			1
+#define CSR_TRAININGPARAM01RSVD_MASK			BIT(1)
+#define CSR_TRAINENRXCLK_LSB				2
+#define CSR_TRAINENRXCLK_MASK				BIT(2)
+#define CSR_TRAINENRXEN_LSB				3
+#define CSR_TRAINENRXEN_MASK				BIT(3)
+#define CSR_TRAINENTXDQS_LSB				4
+#define CSR_TRAINENTXDQS_MASK				BIT(4)
+#define CSR_TRAINENTXDQ_LSB				5
+#define CSR_TRAINENTXDQ_MASK				BIT(5)
+#define CSR_TRAINENVREFDAC1_LSB				6
+#define CSR_TRAINENVREFDAC1_MASK			BIT(6)
+#define CSR_TRAINENVREFDAC0_LSB				7
+#define CSR_TRAINENVREFDAC0_MASK			BIT(7)
+#define CSR_TRAINENRXPBD_LSB				8
+#define CSR_TRAINENRXPBD_MASK				BIT(8)
+#define CSR_ROLLINTOCOARSE_LSB				9
+#define CSR_ROLLINTOCOARSE_MASK				BIT(9)
+#define CSR_TRAINUSINGNATIVEDDLCNTL_LSB			10
+#define CSR_TRAINUSINGNATIVEDDLCNTL_MASK		BIT(10)
+#define CSR_TRAININGPARAM11RSVD_LSB			11
+#define CSR_TRAININGPARAM11RSVD_MASK			BIT(11)
+#define CSR_TRAININGPARAM12RSVD_LSB			12
+#define CSR_TRAININGPARAM12RSVD_MASK			BIT(12)
+#define CSR_INCDECRATE_LSB				13
+#define CSR_INCDECRATE_MASK				GENMASK_32(15, 13)
+/* CSR_USEDQSENREPLICA */
+#define CSR_USEDQSENREPLICA_LSB				0
+#define CSR_USEDQSENREPLICA_MASK			BIT(0)
+/* CSR_RXTRAINPATTERNENABLE */
+#define CSR_RXTRAINPATTERNENABLE_LSB			0
+#define CSR_RXTRAINPATTERNENABLE_MASK			BIT(0)
+/* CSR_TSMBYTE1 */
+#define CSR_TSMBYTE1_LSB				0
+#define CSR_TSMBYTE1_MASK				GENMASK_32(15, 0)
+#define CSR_DTSMBDSTP_LSB				0
+#define CSR_DTSMBDSTP_MASK				GENMASK_32(7, 0)
+#define CSR_DTSMGDSTP_LSB				8
+#define CSR_DTSMGDSTP_MASK				GENMASK_32(15, 8)
+/* CSR_TSMBYTE2 */
+#define CSR_TSMBYTE2_LSB				0
+#define CSR_TSMBYTE2_MASK				GENMASK_32(15, 0)
+#define CSR_DTSMGDBAR_LSB				0
+#define CSR_DTSMGDBAR_MASK				GENMASK_32(15, 0)
+/* CSR_TSMBYTE3 */
+#define CSR_TSMBYTE3_LSB				0
+#define CSR_TSMBYTE3_MASK				GENMASK_32(8, 0)
+#define CSR_DTSMINCDECMODE_LSB				0
+#define CSR_DTSMINCDECMODE_MASK				BIT(0)
+#define CSR_DTSMINCDECCTRL_LSB				1
+#define CSR_DTSMINCDECCTRL_MASK				BIT(1)
+#define CSR_ENBLRXSAMPFLOPS_LSB				2
+#define CSR_ENBLRXSAMPFLOPS_MASK			BIT(2)
+#define CSR_SELRXSAMPFLOPS_LSB				3
+#define CSR_SELRXSAMPFLOPS_MASK				BIT(3)
+#define CSR_SELRXBYBASS_LSB				4
+#define CSR_SELRXBYBASS_MASK				BIT(4)
+#define CSR_DTSMIGNUPDATEACK_LSB			5
+#define CSR_DTSMIGNUPDATEACK_MASK			BIT(5)
+#define CSR_ENABLERXDQASYNC_LSB				6
+#define CSR_ENABLERXDQASYNC_MASK			BIT(6)
+#define CSR_DTSMSTATICCMPR_LSB				7
+#define CSR_DTSMSTATICCMPR_MASK				BIT(7)
+#define CSR_DTSMSTATICCMPRVAL_LSB			8
+#define CSR_DTSMSTATICCMPRVAL_MASK			BIT(8)
+/* CSR_TSMBYTE4 */
+#define CSR_TSMBYTE4_LSB				0
+#define CSR_TSMBYTE4_MASK				GENMASK_32(3, 0)
+#define CSR_DTSMINCDECPW_LSB				0
+#define CSR_DTSMINCDECPW_MASK				GENMASK_32(3, 0)
+/* CSR_TESTMODECONFIG */
+#define CSR_TESTMODECONFIG_LSB				0
+#define CSR_TESTMODECONFIG_MASK				GENMASK_32(9, 0)
+#define CSR_LOOPBACKEN_LSB				0
+#define CSR_LOOPBACKEN_MASK				BIT(0)
+#define CSR_RSVDTESTDLLEN_LSB				1
+#define CSR_RSVDTESTDLLEN_MASK				BIT(1)
+#define CSR_RSVDTWOTCKTXDQSPRE_LSB			2
+#define CSR_RSVDTWOTCKTXDQSPRE_MASK			BIT(2)
+#define CSR_TESTMODERSVD_LSB				3
+#define CSR_TESTMODERSVD_MASK				GENMASK_32(7, 3)
+#define CSR_LOOPBACKDISDQSTRI_LSB			8
+#define CSR_LOOPBACKDISDQSTRI_MASK			BIT(8)
+#define CSR_RSVDDISTXDQEQPREAMBLE_LSB			9
+#define CSR_RSVDDISTXDQEQPREAMBLE_MASK			BIT(9)
+/* CSR_TSMBYTE5 */
+#define CSR_TSMBYTE5_LSB				0
+#define CSR_TSMBYTE5_MASK				GENMASK_32(15, 0)
+#define CSR_DTSMBDBAR_LSB				0
+#define CSR_DTSMBDBAR_MASK				GENMASK_32(15, 0)
+/* MTESTMUXSEL already defined in ANIBx section */
+/* CSR_DTSMTRAINMODECTRL */
+#define CSR_DTSMTRAINMODECTRL_LSB			0
+#define CSR_DTSMTRAINMODECTRL_MASK			GENMASK_32(3, 0)
+#define CSR_DTSMSOELANEMODE_LSB				0
+#define CSR_DTSMSOELANEMODE_MASK			GENMASK_32(1, 0)
+#define CSR_DTSMBYTEERRANDMODE_LSB			2
+#define CSR_DTSMBYTEERRANDMODE_MASK			BIT(2)
+#define CSR_DTSMNIBERRMODE_LSB				3
+#define CSR_DTSMNIBERRMODE_MASK				BIT(3)
+/* CSR_DFIMRL */
+#define CSR_DFIMRL_LSB					0
+#define CSR_DFIMRL_MASK					GENMASK_32(4, 0)
+/* CSR_ASYNCDBYTEMODE */
+#define CSR_ASYNCDBYTEMODE_LSB				0
+#define CSR_ASYNCDBYTEMODE_MASK				GENMASK_32(8, 0)
+/* CSR_ASYNCDBYTETXEN */
+#define CSR_ASYNCDBYTETXEN_LSB				0
+#define CSR_ASYNCDBYTETXEN_MASK				GENMASK_32(11, 0)
+/* CSR_ASYNCDBYTETXDATA */
+#define CSR_ASYNCDBYTETXDATA_LSB			0
+#define CSR_ASYNCDBYTETXDATA_MASK			GENMASK_32(11, 0)
+/* CSR_ASYNCDBYTERXDATA */
+#define CSR_ASYNCDBYTERXDATA_LSB			0
+#define CSR_ASYNCDBYTERXDATA_MASK			GENMASK_32(11, 0)
+/* CSR_VREFDAC1 */
+#define CSR_VREFDAC1_LSB				0
+#define CSR_VREFDAC1_MASK				GENMASK_32(6, 0)
+/* CSR_TRAININGCNTR */
+#define CSR_TRAININGCNTR_LSB				0
+#define CSR_TRAININGCNTR_MASK				GENMASK_32(15, 0)
+#define CSR_TRAININGCNTRFINE_LSB			0
+#define CSR_TRAININGCNTRFINE_MASK			GENMASK_32(9, 0)
+#define CSR_TRAININGCNTRCOARSE_LSB			10
+#define CSR_TRAININGCNTRCOARSE_MASK			GENMASK_32(15, 10)
+/* CSR_VREFDAC0 */
+#define CSR_VREFDAC0_LSB				0
+#define CSR_VREFDAC0_MASK				GENMASK_32(6, 0)
+/* CSR_TXIMPEDANCECTRL0 */
+#define CSR_TXIMPEDANCECTRL0_LSB			0
+#define CSR_TXIMPEDANCECTRL0_MASK			GENMASK_32(11, 0)
+#define CSR_DRVSTRENDQP_LSB				0
+#define CSR_DRVSTRENDQP_MASK				GENMASK_32(5, 0)
+#define CSR_DRVSTRENDQN_LSB				6
+#define CSR_DRVSTRENDQN_MASK				GENMASK_32(11, 6)
+/* CSR_DQDQSRCVCNTRL */
+#define CSR_DQDQSRCVCNTRL_LSB				0
+#define CSR_DQDQSRCVCNTRL_MASK				GENMASK_32(15, 0)
+#define CSR_SELANALOGVREF_LSB				0
+#define CSR_SELANALOGVREF_MASK				BIT(0)
+#define CSR_EXTVREFRANGE_LSB				1
+#define CSR_EXTVREFRANGE_MASK				BIT(1)
+#define CSR_DFECTRL_LSB					2
+#define CSR_DFECTRL_MASK				GENMASK_32(3, 2)
+#define CSR_MAJORMODEDBYTE_LSB				4
+#define CSR_MAJORMODEDBYTE_MASK				GENMASK_32(6, 4)
+#define CSR_GAINCURRADJ_LSB				7
+#define CSR_GAINCURRADJ_MASK				GENMASK_32(11, 7)
+#define CSR_RESERVED_LSB				12
+#define CSR_RESERVED_MASK				GENMASK_32(15, 12)
+/* CSR_TXEQUALIZATIONMODE */
+#define CSR_TXEQUALIZATIONMODE_LSB			0
+#define CSR_TXEQUALIZATIONMODE_MASK			GENMASK_32(1, 0)
+#define CSR_TXEQMODE_LSB				0
+#define CSR_TXEQMODE_MASK				GENMASK_32(1, 0)
+/* CSR_TXIMPEDANCECTRL1 */
+#define CSR_TXIMPEDANCECTRL1_LSB			0
+#define CSR_TXIMPEDANCECTRL1_MASK			GENMASK_32(11, 0)
+#define CSR_DRVSTRENFSDQP_LSB				0
+#define CSR_DRVSTRENFSDQP_MASK				GENMASK_32(5, 0)
+#define CSR_DRVSTRENFSDQN_LSB				6
+#define CSR_DRVSTRENFSDQN_MASK				GENMASK_32(11, 6)
+/* CSR_DQDQSRCVCNTRL1 */
+#define CSR_DQDQSRCVCNTRL1_LSB				0
+#define CSR_DQDQSRCVCNTRL1_MASK				GENMASK_32(11, 0)
+#define CSR_POWERDOWNRCVR_LSB				0
+#define CSR_POWERDOWNRCVR_MASK				GENMASK_32(8, 0)
+#define CSR_POWERDOWNRCVRDQS_LSB			9
+#define CSR_POWERDOWNRCVRDQS_MASK			BIT(9)
+#define CSR_RXPADSTANDBYEN_LSB				10
+#define CSR_RXPADSTANDBYEN_MASK				BIT(10)
+#define CSR_ENLPREQPDR_LSB				11
+#define CSR_ENLPREQPDR_MASK				BIT(11)
+/* CSR_TXIMPEDANCECTRL2 */
+#define CSR_TXIMPEDANCECTRL2_LSB			0
+#define CSR_TXIMPEDANCECTRL2_MASK			GENMASK_32(11, 0)
+#define CSR_DRVSTRENEQHIDQP_LSB				0
+#define CSR_DRVSTRENEQHIDQP_MASK			GENMASK_32(5, 0)
+#define CSR_DRVSTRENEQLODQN_LSB				6
+#define CSR_DRVSTRENEQLODQN_MASK			GENMASK_32(11, 6)
+/* CSR_DQDQSRCVCNTRL2 */
+#define CSR_DQDQSRCVCNTRL2_LSB				0
+#define CSR_DQDQSRCVCNTRL2_MASK				BIT(0)
+#define CSR_ENRXAGRESSIVEPDR_LSB			0
+#define CSR_ENRXAGRESSIVEPDR_MASK			BIT(0)
+/* CSR_TXODTDRVSTREN */
+#define CSR_TXODTDRVSTREN_LSB				0
+#define CSR_TXODTDRVSTREN_MASK				GENMASK_32(11, 0)
+#define CSR_ODTSTRENP_LSB				0
+#define CSR_ODTSTRENP_MASK				GENMASK_32(5, 0)
+#define CSR_ODTSTRENN_LSB				6
+#define CSR_ODTSTRENN_MASK				GENMASK_32(11, 6)
+/* CSR_RXFIFOCHECKSTATUS */
+#define CSR_RXFIFOCHECKSTATUS_LSB			0
+#define CSR_RXFIFOCHECKSTATUS_MASK			GENMASK_32(1, 0)
+#define CSR_RXFIFOLOCERR_LSB				0
+#define CSR_RXFIFOLOCERR_MASK				BIT(0)
+#define CSR_RXFIFOLOCUERR_LSB				1
+#define CSR_RXFIFOLOCUERR_MASK				BIT(1)
+/* CSR_RXFIFOCHECKERRVALUES */
+#define CSR_RXFIFOCHECKERRVALUES_LSB			0
+#define CSR_RXFIFOCHECKERRVALUES_MASK			GENMASK_32(15, 0)
+#define CSR_RXFIFORDLOCERRVALUE_LSB			0
+#define CSR_RXFIFORDLOCERRVALUE_MASK			GENMASK_32(3, 0)
+#define CSR_RXFIFOWRLOCERRVALUE_LSB			4
+#define CSR_RXFIFOWRLOCERRVALUE_MASK			GENMASK_32(7, 4)
+#define CSR_RXFIFORDLOCUERRVALUE_LSB			8
+#define CSR_RXFIFORDLOCUERRVALUE_MASK			GENMASK_32(11, 8)
+#define CSR_RXFIFOWRLOCUERRVALUE_LSB			12
+#define CSR_RXFIFOWRLOCUERRVALUE_MASK			GENMASK_32(15, 12)
+/* CSR_RXFIFOINFO */
+#define CSR_RXFIFOINFO_LSB				0
+#define CSR_RXFIFOINFO_MASK				GENMASK_32(15, 0)
+#define CSR_RXFIFORDLOC_LSB				0
+#define CSR_RXFIFORDLOC_MASK				GENMASK_32(3, 0)
+#define CSR_RXFIFOWRLOC_LSB				4
+#define CSR_RXFIFOWRLOC_MASK				GENMASK_32(7, 4)
+#define CSR_RXFIFORDLOCU_LSB				8
+#define CSR_RXFIFORDLOCU_MASK				GENMASK_32(11, 8)
+#define CSR_RXFIFOWRLOCU_LSB				12
+#define CSR_RXFIFOWRLOCU_MASK				GENMASK_32(15, 12)
+/* CSR_RXFIFOVISIBILITY */
+#define CSR_RXFIFOVISIBILITY_LSB			0
+#define CSR_RXFIFOVISIBILITY_MASK			GENMASK_32(4, 0)
+#define CSR_RXFIFORDPTR_LSB				0
+#define CSR_RXFIFORDPTR_MASK				GENMASK_32(2, 0)
+#define CSR_RXFIFORDPTROVR_LSB				3
+#define CSR_RXFIFORDPTROVR_MASK				BIT(3)
+#define CSR_RXFIFORDEN_LSB				4
+#define CSR_RXFIFORDEN_MASK				BIT(4)
+/* CSR_RXFIFOCONTENTSDQ3210 */
+#define CSR_RXFIFOCONTENTSDQ3210_LSB			0
+#define CSR_RXFIFOCONTENTSDQ3210_MASK			GENMASK_32(15, 0)
+/* CSR_RXFIFOCONTENTSDQ7654 */
+#define CSR_RXFIFOCONTENTSDQ7654_LSB			0
+#define CSR_RXFIFOCONTENTSDQ7654_MASK			GENMASK_32(15, 0)
+/* CSR_RXFIFOCONTENTSDBI */
+#define CSR_RXFIFOCONTENTSDBI_LSB			0
+#define CSR_RXFIFOCONTENTSDBI_MASK			GENMASK_32(3, 0)
+/* CSR_TXSLEWRATE */
+#define CSR_TXSLEWRATE_LSB				0
+#define CSR_TXSLEWRATE_MASK				GENMASK_32(10, 0)
+#define CSR_TXPREP_LSB					0
+#define CSR_TXPREP_MASK					GENMASK_32(3, 0)
+#define CSR_TXPREN_LSB					4
+#define CSR_TXPREN_MASK					GENMASK_32(7, 4)
+#define CSR_TXPREDRVMODE_LSB				8
+#define CSR_TXPREDRVMODE_MASK				GENMASK_32(10, 8)
+/* CSR_TRAININGINCDECDTSMEN */
+#define CSR_TRAININGINCDECDTSMEN_LSB			0
+#define CSR_TRAININGINCDECDTSMEN_MASK			GENMASK_32(8, 0)
+/* CSR_RXPBDLYTG0 */
+#define CSR_RXPBDLYTG0_LSB				0
+#define CSR_RXPBDLYTG0_MASK				GENMASK_32(6, 0)
+/* CSR_RXPBDLYTG1 */
+#define CSR_RXPBDLYTG1_LSB				0
+#define CSR_RXPBDLYTG1_MASK				GENMASK_32(6, 0)
+/* CSR_RXPBDLYTG2 */
+#define CSR_RXPBDLYTG2_LSB				0
+#define CSR_RXPBDLYTG2_MASK				GENMASK_32(6, 0)
+/* CSR_RXPBDLYTG3 */
+#define CSR_RXPBDLYTG3_LSB				0
+#define CSR_RXPBDLYTG3_MASK				GENMASK_32(6, 0)
+/* CSR_RXENDLYTG0 */
+#define CSR_RXENDLYTG0_LSB				0
+#define CSR_RXENDLYTG0_MASK				GENMASK_32(10, 0)
+/* CSR_RXENDLYTG1 */
+#define CSR_RXENDLYTG1_LSB				0
+#define CSR_RXENDLYTG1_MASK				GENMASK_32(10, 0)
+/* CSR_RXENDLYTG2 */
+#define CSR_RXENDLYTG2_LSB				0
+#define CSR_RXENDLYTG2_MASK				GENMASK_32(10, 0)
+/* CSR_RXENDLYTG3 */
+#define CSR_RXENDLYTG3_LSB				0
+#define CSR_RXENDLYTG3_MASK				GENMASK_32(10, 0)
+/* CSR_RXCLKDLYTG0 */
+#define CSR_RXCLKDLYTG0_LSB				0
+#define CSR_RXCLKDLYTG0_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKDLYTG1 */
+#define CSR_RXCLKDLYTG1_LSB				0
+#define CSR_RXCLKDLYTG1_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKDLYTG2 */
+#define CSR_RXCLKDLYTG2_LSB				0
+#define CSR_RXCLKDLYTG2_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKDLYTG3 */
+#define CSR_RXCLKDLYTG3_LSB				0
+#define CSR_RXCLKDLYTG3_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKCDLYTG0 */
+#define CSR_RXCLKCDLYTG0_LSB				0
+#define CSR_RXCLKCDLYTG0_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKCDLYTG1 */
+#define CSR_RXCLKCDLYTG1_LSB				0
+#define CSR_RXCLKCDLYTG1_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKCDLYTG2 */
+#define CSR_RXCLKCDLYTG2_LSB				0
+#define CSR_RXCLKCDLYTG2_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKCDLYTG3 */
+#define CSR_RXCLKCDLYTG3_LSB				0
+#define CSR_RXCLKCDLYTG3_MASK				GENMASK_32(5, 0)
+/* CSR_DQ0LNSEL */
+#define CSR_DQ0LNSEL_LSB				0
+#define CSR_DQ0LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ1LNSEL */
+#define CSR_DQ1LNSEL_LSB				0
+#define CSR_DQ1LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ2LNSEL */
+#define CSR_DQ2LNSEL_LSB				0
+#define CSR_DQ2LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ3LNSEL */
+#define CSR_DQ3LNSEL_LSB				0
+#define CSR_DQ3LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ4LNSEL */
+#define CSR_DQ4LNSEL_LSB				0
+#define CSR_DQ4LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ5LNSEL */
+#define CSR_DQ5LNSEL_LSB				0
+#define CSR_DQ5LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ6LNSEL */
+#define CSR_DQ6LNSEL_LSB				0
+#define CSR_DQ6LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ7LNSEL */
+#define CSR_DQ7LNSEL_LSB				0
+#define CSR_DQ7LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_PPTCTLSTATIC */
+#define CSR_PPTCTLSTATIC_LSB				0
+#define CSR_PPTCTLSTATIC_MASK				GENMASK_32(11, 0)
+#define CSR_PPTENDQS2DQTG0_LSB				0
+#define CSR_PPTENDQS2DQTG0_MASK				BIT(0)
+#define CSR_PPTENDQS2DQTG1_LSB				1
+#define CSR_PPTENDQS2DQTG1_MASK				BIT(1)
+#define CSR_DOCBYTESELTG0_LSB				2
+#define CSR_DOCBYTESELTG0_MASK				BIT(2)
+#define CSR_DOCBYTESELTG1_LSB				3
+#define CSR_DOCBYTESELTG1_MASK				BIT(3)
+#define CSR_PPTINFOSEL_LSB				4
+#define CSR_PPTINFOSEL_MASK				GENMASK_32(7, 4)
+#define CSR_PPTENRXENDLYTG0_LSB				8
+#define CSR_PPTENRXENDLYTG0_MASK			BIT(8)
+#define CSR_PPTENRXENDLYTG1_LSB				9
+#define CSR_PPTENRXENDLYTG1_MASK			BIT(9)
+#define CSR_PPTENRXENBACKOFF_LSB			10
+#define CSR_PPTENRXENBACKOFF_MASK			GENMASK_32(11, 10)
+/* CSR_PPTCTLDYN */
+#define CSR_PPTCTLDYN_LSB				0
+#define CSR_PPTCTLDYN_MASK				GENMASK_32(1, 0)
+#define CSR_PPTDQS2DQACTIVE_LSB				0
+#define CSR_PPTDQS2DQACTIVE_MASK			BIT(0)
+#define CSR_PPTENRXENUSEDQSSAMPVAL_LSB			1
+#define CSR_PPTENRXENUSEDQSSAMPVAL_MASK			BIT(1)
+/* CSR_PPTINFO */
+#define CSR_PPTINFO_LSB					0
+#define CSR_PPTINFO_MASK				GENMASK_32(15, 0)
+/* CSR_PPTRXENEVNT */
+#define CSR_PPTRXENEVNT_LSB				0
+#define CSR_PPTRXENEVNT_MASK				GENMASK_32(1, 0)
+#define CSR_PPTRXENINIT_LSB				0
+#define CSR_PPTRXENINIT_MASK				BIT(0)
+#define CSR_PPTRXENMHUI_LSB				1
+#define CSR_PPTRXENMHUI_MASK				BIT(1)
+/* CSR_PPTDQSCNTINVTRNTG0 */
+#define CSR_PPTDQSCNTINVTRNTG0_LSB			0
+#define CSR_PPTDQSCNTINVTRNTG0_MASK			GENMASK_32(15, 0)
+/* CSR_PPTDQSCNTINVTRNTG1 */
+#define CSR_PPTDQSCNTINVTRNTG1_LSB			0
+#define CSR_PPTDQSCNTINVTRNTG1_MASK			GENMASK_32(15, 0)
+/* CSR_DTSMBLANKINGCTRL */
+#define CSR_DTSMBLANKINGCTRL_LSB			0
+#define CSR_DTSMBLANKINGCTRL_MASK			GENMASK_32(9, 0)
+#define CSR_DTSMBLANK_LSB				0
+#define CSR_DTSMBLANK_MASK				GENMASK_32(9, 0)
+/* CSR_TSM0 */
+#define CSR_TSM0_LSB					0
+#define CSR_TSM0_MASK					GENMASK_32(13, 0)
+#define CSR_DTSMENB_LSB					0
+#define CSR_DTSMENB_MASK				BIT(0)
+#define CSR_DTSMDIR_LSB					1
+#define CSR_DTSMDIR_MASK				BIT(1)
+#define CSR_DTSMIGNFRST_LSB				2
+#define CSR_DTSMIGNFRST_MASK				BIT(2)
+#define CSR_DTSMODDPHASE_LSB				3
+#define CSR_DTSMODDPHASE_MASK				BIT(3)
+#define CSR_DTSMFLTPRE_LSB				4
+#define CSR_DTSMFLTPRE_MASK				BIT(4)
+#define CSR_DTSMFLTCUR_LSB				5
+#define CSR_DTSMFLTCUR_MASK				BIT(5)
+#define CSR_DTSMFLTNXT_LSB				6
+#define CSR_DTSMFLTNXT_MASK				BIT(6)
+#define CSR_DTSMFLTVAL_LSB				7
+#define CSR_DTSMFLTVAL_MASK				GENMASK_32(9, 7)
+#define CSR_DTSMMSKBIT_LSB				10
+#define CSR_DTSMMSKBIT_MASK				GENMASK_32(13, 10)
+/* CSR_TSM1 */
+#define CSR_TSM1_LSB					0
+#define CSR_TSM1_MASK					GENMASK_32(15, 0)
+#define CSR_DTSMERRCNT_LSB				0
+#define CSR_DTSMERRCNT_MASK				GENMASK_32(15, 0)
+/* CSR_TSM2 */
+#define CSR_TSM2_LSB					0
+#define CSR_TSM2_MASK					BIT(0)
+#define CSR_DTSMDISERRCHK_LSB				0
+#define CSR_DTSMDISERRCHK_MASK				BIT(0)
+/* CSR_TSM3 */
+#define CSR_TSM3_LSB					0
+#define CSR_TSM3_MASK					GENMASK_32(9, 0)
+#define CSR_DTSMCLRERRCNTMSK_LSB			0
+#define CSR_DTSMCLRERRCNTMSK_MASK			GENMASK_32(8, 0)
+#define CSR_DTSMCLRERRCNT_LSB				9
+#define CSR_DTSMCLRERRCNT_MASK				BIT(9)
+/* CSR_TXCHKDATASELECTS */
+#define CSR_TXCHKDATASELECTS_LSB			0
+#define CSR_TXCHKDATASELECTS_MASK			GENMASK_32(1, 0)
+#define CSR_SELCHKTOTX_LSB				0
+#define CSR_SELCHKTOTX_MASK				BIT(0)
+#define CSR_SELTXTOCHK_LSB				1
+#define CSR_SELTXTOCHK_MASK				BIT(1)
+/* CSR_DTSMUPTHLDXINGIND */
+#define CSR_DTSMUPTHLDXINGIND_LSB			0
+#define CSR_DTSMUPTHLDXINGIND_MASK			GENMASK_32(8, 0)
+/* CSR_DTSMLOTHLDXINGIND */
+#define CSR_DTSMLOTHLDXINGIND_LSB			0
+#define CSR_DTSMLOTHLDXINGIND_MASK			GENMASK_32(8, 0)
+/* CSR_DBYTEALLDTSMCTRL0 */
+#define CSR_DBYTEALLDTSMCTRL0_LSB			0
+#define CSR_DBYTEALLDTSMCTRL0_MASK			GENMASK_32(8, 0)
+#define CSR_DTSMINHIBDTSM_LSB				0
+#define CSR_DTSMINHIBDTSM_MASK				GENMASK_32(8, 0)
+/* CSR_DBYTEALLDTSMCTRL1 */
+#define CSR_DBYTEALLDTSMCTRL1_LSB			0
+#define CSR_DBYTEALLDTSMCTRL1_MASK			GENMASK_32(8, 0)
+#define CSR_DTSMGATEINC_LSB				0
+#define CSR_DTSMGATEINC_MASK				GENMASK_32(8, 0)
+/* CSR_DBYTEALLDTSMCTRL2 */
+#define CSR_DBYTEALLDTSMCTRL2_LSB			0
+#define CSR_DBYTEALLDTSMCTRL2_MASK			GENMASK_32(8, 0)
+#define CSR_DTSMGATEDEC_LSB				0
+#define CSR_DTSMGATEDEC_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQDLYTG0 */
+#define CSR_TXDQDLYTG0_LSB				0
+#define CSR_TXDQDLYTG0_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQDLYTG1 */
+#define CSR_TXDQDLYTG1_LSB				0
+#define CSR_TXDQDLYTG1_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQDLYTG2 */
+#define CSR_TXDQDLYTG2_LSB				0
+#define CSR_TXDQDLYTG2_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQDLYTG3 */
+#define CSR_TXDQDLYTG3_LSB				0
+#define CSR_TXDQDLYTG3_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQSDLYTG0 */
+#define CSR_TXDQSDLYTG0_LSB				0
+#define CSR_TXDQSDLYTG0_MASK				GENMASK_32(9, 0)
+/* CSR_TXDQSDLYTG1 */
+#define CSR_TXDQSDLYTG1_LSB				0
+#define CSR_TXDQSDLYTG1_MASK				GENMASK_32(9, 0)
+/* CSR_TXDQSDLYTG2 */
+#define CSR_TXDQSDLYTG2_LSB				0
+#define CSR_TXDQSDLYTG2_MASK				GENMASK_32(9, 0)
+/* CSR_TXDQSDLYTG3 */
+#define CSR_TXDQSDLYTG3_LSB				0
+#define CSR_TXDQSDLYTG3_MASK				GENMASK_32(9, 0)
+/* CSR_DXLCDLSTATUS_ADDR */
+#define CSR_DXLCDLSTATUS_LSB				0
+#define CSR_DXLCDLSTATUS_MASK				GENMASK_32(13, 0)
+#define CSR_DXLCDLFINESNAPVAL_LSB			0
+#define CSR_DXLCDLFINESNAPVAL_MASK			GENMASK_32(9, 0)
+#define CSR_DXLCDLPHDSNAPVAL_LSB			10
+#define CSR_DXLCDLPHDSNAPVAL_MASK			BIT(10)
+#define CSR_DXLCDLSTICKYLOCK_LSB			11
+#define CSR_DXLCDLSTICKYLOCK_MASK			BIT(11)
+#define CSR_DXLCDLSTICKYUNLOCK_LSB			12
+#define CSR_DXLCDLSTICKYUNLOCK_MASK			BIT(12)
+#define CSR_DXLCDLLIVELOCK_LSB				13
+#define CSR_DXLCDLLIVELOCK_MASK				BIT(13)
+
+/* MASTER0 register offsets */
+/* CSR_RXFIFOINIT */
+#define CSR_RXFIFOINIT_LSB				0
+#define CSR_RXFIFOINIT_MASK				GENMASK_32(1, 0)
+#define CSR_RXFIFOINITPTR_LSB				0
+#define CSR_RXFIFOINITPTR_MASK				BIT(0)
+#define CSR_INHIBITRXFIFORD_LSB				1
+#define CSR_INHIBITRXFIFORD_MASK			BIT(1)
+/* CSR_FORCECLKDISABLE */
+#define CSR_FORCECLKDISABLE_LSB				0
+#define CSR_FORCECLKDISABLE_MASK			GENMASK_32(3, 0)
+/* CSR_CLOCKINGCTRL */
+#define CSR_CLOCKINGCTRL_LSB				0
+#define CSR_CLOCKINGCTRL_MASK				GENMASK_32(1, 0)
+#define CSR_PCLKENASYNCCTRL_LSB				0
+#define CSR_PCLKENASYNCCTRL_MASK			BIT(0)
+#define CSR_DLLTRACKENCTRL_LSB				1
+#define CSR_DLLTRACKENCTRL_MASK				BIT(1)
+/* CSR_FORCEINTERNALUPDATE */
+#define CSR_FORCEINTERNALUPDATE_LSB			0
+#define CSR_FORCEINTERNALUPDATE_MASK			BIT(0)
+/* CSR_PHYCONFIG */
+#define CSR_PHYCONFIG_LSB				0
+#define CSR_PHYCONFIG_MASK				GENMASK_32(9, 0)
+#define CSR_PHYCONFIGANIBS_LSB				0
+#define CSR_PHYCONFIGANIBS_MASK				GENMASK_32(3, 0)
+#define CSR_PHYCONFIGDBYTES_LSB				4
+#define CSR_PHYCONFIGDBYTES_MASK			GENMASK_32(7, 4)
+#define CSR_PHYCONFIGDFI_LSB				8
+#define CSR_PHYCONFIGDFI_MASK				GENMASK_32(9, 8)
+/* CSR_PGCR */
+#define CSR_PGCR_LSB					0
+#define CSR_PGCR_MASK					BIT(0)
+#define CSR_RXCLKRISEFALLMODE_LSB			0
+#define CSR_RXCLKRISEFALLMODE_MASK			BIT(0)
+/* CSR_TESTBUMPCNTRL1 */
+#define CSR_TESTBUMPCNTRL1_LSB				0
+#define CSR_TESTBUMPCNTRL1_MASK				GENMASK_32(15, 0)
+#define CSR_TESTMAJORMODE_LSB				0
+#define CSR_TESTMAJORMODE_MASK				GENMASK_32(2, 0)
+#define CSR_TESTBIASBYPASSEN_LSB			3
+#define CSR_TESTBIASBYPASSEN_MASK			BIT(3)
+#define CSR_TESTANALOGOUTCTRL_LSB			4
+#define CSR_TESTANALOGOUTCTRL_MASK			GENMASK_32(7, 4)
+#define CSR_TESTGAINCURRADJ_LSB				8
+#define CSR_TESTGAINCURRADJ_MASK			GENMASK_32(12, 8)
+#define CSR_TESTSELEXTERNALVREF_LSB			13
+#define CSR_TESTSELEXTERNALVREF_MASK			BIT(13)
+#define CSR_TESTEXTVREFRANGE_LSB			14
+#define CSR_TESTEXTVREFRANGE_MASK			BIT(14)
+#define CSR_TESTPOWERGATEEN_LSB				15
+#define CSR_TESTPOWERGATEEN_MASK			BIT(15)
+/* CSR_CALUCLKINFO */
+#define CSR_CALUCLKINFO_LSB				0
+#define CSR_CALUCLKINFO_MASK				GENMASK_32(10, 0)
+#define CSR_CALUCLKTICKSPER1US_LSB			0
+#define CSR_CALUCLKTICKSPER1US_MASK			GENMASK_32(10, 0)
+/* CSR_TESTBUMPCNTRL */
+#define CSR_TESTBUMPCNTRL_LSB				0
+#define CSR_TESTBUMPCNTRL_MASK				GENMASK_32(9, 0)
+#define CSR_TESTBUMPEN_LSB				0
+#define CSR_TESTBUMPEN_MASK				GENMASK_32(1, 0)
+#define CSR_TESTBUMPTOGGLE_LSB				2
+#define CSR_TESTBUMPTOGGLE_MASK				BIT(2)
+#define CSR_TESTBUMPDATASEL_LSB				3
+#define CSR_TESTBUMPDATASEL_MASK			GENMASK_32(8, 3)
+#define CSR_FORCEMTESTONALERT_LSB			9
+#define CSR_FORCEMTESTONALERT_MASK			BIT(9)
+/* CSR_SEQ0BDLY0 */
+#define CSR_SEQ0BDLY0_LSB				0
+#define CSR_SEQ0BDLY0_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BDLY1 */
+#define CSR_SEQ0BDLY1_LSB				0
+#define CSR_SEQ0BDLY1_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BDLY2 */
+#define CSR_SEQ0BDLY2_LSB				0
+#define CSR_SEQ0BDLY2_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BDLY3 */
+#define CSR_SEQ0BDLY3_LSB				0
+#define CSR_SEQ0BDLY3_MASK				GENMASK_32(15, 0)
+/* CSR_PHYALERTSTATUS */
+#define CSR_PHYALERTSTATUS_LSB				0
+#define CSR_PHYALERTSTATUS_MASK				BIT(0)
+#define CSR_PHYALERT_LSB				0
+#define CSR_PHYALERT_MASK				BIT(0)
+/* CSR_PPTTRAINSETUP */
+#define CSR_PPTTRAINSETUP_LSB				0
+#define CSR_PPTTRAINSETUP_MASK				GENMASK_32(6, 0)
+#define CSR_PHYMSTRTRAININTERVAL_LSB			0
+#define CSR_PHYMSTRTRAININTERVAL_MASK			GENMASK_32(3, 0)
+#define CSR_PHYMSTRMAXREQTOACK_LSB			4
+#define CSR_PHYMSTRMAXREQTOACK_MASK			GENMASK_32(6, 4)
+/* CSR_PPTTRAINSETUP2 */
+#define CSR_PPTTRAINSETUP2_LSB				0
+#define CSR_PPTTRAINSETUP2_MASK				GENMASK_32(2, 0)
+#define CSR_PHYMSTRFREQOVERRIDE_LSB			0
+#define CSR_PHYMSTRFREQOVERRIDE_MASK			GENMASK_32(2, 0)
+/* CSR_ATESTMODE */
+#define CSR_ATESTMODE_LSB				0
+#define CSR_ATESTMODE_MASK				GENMASK_32(4, 0)
+#define CSR_ATESTPRBSEN_LSB				0
+#define CSR_ATESTPRBSEN_MASK				BIT(0)
+#define CSR_ATESTCLKEN_LSB				1
+#define CSR_ATESTCLKEN_MASK				BIT(1)
+#define CSR_ATESTMODESEL_LSB				2
+#define CSR_ATESTMODESEL_MASK				GENMASK_32(4, 2)
+/* CSR_TXCALBINP */
+#define CSR_TXCALBINP_LSB				0
+#define CSR_TXCALBINP_MASK				GENMASK_32(4, 0)
+/* CSR_TXCALBINN */
+#define CSR_TXCALBINN_LSB				0
+#define CSR_TXCALBINN_MASK				GENMASK_32(4, 0)
+/* CSR_TXCALPOVR */
+#define CSR_TXCALPOVR_LSB				0
+#define CSR_TXCALPOVR_MASK				GENMASK_32(5, 0)
+#define CSR_TXCALBINPOVRVAL_LSB				0
+#define CSR_TXCALBINPOVRVAL_MASK			GENMASK_32(4, 0)
+#define CSR_TXCALBINPOVREN_LSB				5
+#define CSR_TXCALBINPOVREN_MASK				BIT(5)
+/* CSR_TXCALNOVR */
+#define CSR_TXCALNOVR_LSB				0
+#define CSR_TXCALNOVR_MASK				GENMASK_32(5, 0)
+#define CSR_TXCALBINNOVRVAL_LSB				0
+#define CSR_TXCALBINNOVRVAL_MASK			GENMASK_32(4, 0)
+#define CSR_TXCALBINNOVREN_LSB				5
+#define CSR_TXCALBINNOVREN_MASK				BIT(5)
+/* CSR_DFIMODE */
+#define CSR_DFIMODE_LSB					0
+#define CSR_DFIMODE_MASK				GENMASK_32(2, 0)
+#define CSR_DFI0ENABLE_LSB				0
+#define CSR_DFI0ENABLE_MASK				BIT(0)
+#define CSR_DFI1ENABLE_LSB				1
+#define CSR_DFI1ENABLE_MASK				BIT(1)
+#define CSR_DFI1OVERRIDE_LSB				2
+#define CSR_DFI1OVERRIDE_MASK				BIT(2)
+/* CSR_TRISTATEMODECA */
+#define CSR_TRISTATEMODECA_LSB				0
+#define CSR_TRISTATEMODECA_MASK				GENMASK_32(3, 0)
+#define CSR_DISDYNADRTRI_LSB				0
+#define CSR_DISDYNADRTRI_MASK				BIT(0)
+#define CSR_DDR2TMODE_LSB				1
+#define CSR_DDR2TMODE_MASK				BIT(1)
+#define CSR_CKDISVAL_LSB				2
+#define CSR_CKDISVAL_MASK				GENMASK_32(3, 2)
+/* MTESTMUXSEL already defined in ANIBx section */
+/* CSR_MTESTPGMINFO */
+#define CSR_MTESTPGMINFO_LSB				0
+#define CSR_MTESTPGMINFO_MASK				BIT(0)
+/* CSR_DYNPWRDNUP */
+#define CSR_DYNPWRDNUP_LSB				0
+#define CSR_DYNPWRDNUP_MASK				BIT(0)
+#define CSR_DYNPOWERDOWN_LSB				0
+#define CSR_DYNPOWERDOWN_MASK				BIT(0)
+/* CSR_PMIENABLE */
+#define CSR_PMIENABLE_LSB				0
+#define CSR_PMIENABLE_MASK				BIT(0)
+/* CSR_PHYTID */
+#define CSR_PHYTID_LSB					0
+#define CSR_PHYTID_MASK					GENMASK_32(15, 0)
+/* CSR_HWTMRL */
+#define CSR_HWTMRL_LSB					0
+#define CSR_HWTMRL_MASK					GENMASK_32(4, 0)
+/* CSR_DFIPHYUPD */
+#define CSR_DFIPHYUPD_LSB				0
+#define CSR_DFIPHYUPD_MASK				GENMASK_32(15, 0)
+#define CSR_DFIPHYUPDCNT_LSB				0
+#define CSR_DFIPHYUPDCNT_MASK				GENMASK_32(3, 0)
+#define CSR_DFIPHYUPDRESP_LSB				4
+#define CSR_DFIPHYUPDRESP_MASK				GENMASK_32(6, 4)
+#define CSR_DFIPHYUPDMODE_LSB				7
+#define CSR_DFIPHYUPDMODE_MASK				BIT(7)
+#define CSR_DFIPHYUPDTHRESHOLD_LSB			8
+#define CSR_DFIPHYUPDTHRESHOLD_MASK			GENMASK_32(11, 8)
+#define CSR_DFIPHYUPDINTTHRESHOLD_LSB			12
+#define CSR_DFIPHYUPDINTTHRESHOLD_MASK			GENMASK_32(15, 12)
+/* CSR_PDAMRSWRITEMODE */
+#define CSR_PDAMRSWRITEMODE_LSB				0
+#define CSR_PDAMRSWRITEMODE_MASK			BIT(0)
+/* CSR_DFIGEARDOWNCTL */
+#define CSR_DFIGEARDOWNCTL_LSB				0
+#define CSR_DFIGEARDOWNCTL_MASK				GENMASK_32(1, 0)
+/* CSR_DQSPREAMBLECONTROL */
+#define CSR_DQSPREAMBLECONTROL_LSB			0
+#define CSR_DQSPREAMBLECONTROL_MASK			GENMASK_32(8, 0)
+#define CSR_TWOTCKRXDQSPRE_LSB				0
+#define CSR_TWOTCKRXDQSPRE_MASK				BIT(0)
+#define CSR_TWOTCKTXDQSPRE_LSB				1
+#define CSR_TWOTCKTXDQSPRE_MASK				BIT(1)
+#define CSR_POSITIONDFEINIT_LSB				2
+#define CSR_POSITIONDFEINIT_MASK			GENMASK_32(4, 2)
+#define CSR_LP4TGLTWOTCKTXDQSPRE_LSB			5
+#define CSR_LP4TGLTWOTCKTXDQSPRE_MASK			BIT(5)
+#define CSR_LP4POSTAMBLEEXT_LSB				6
+#define CSR_LP4POSTAMBLEEXT_MASK			BIT(6)
+#define CSR_LP4STTCPREBRIDGERXEN_LSB			7
+#define CSR_LP4STTCPREBRIDGERXEN_MASK			BIT(7)
+#define CSR_WDQSEXTENSION_LSB				8
+#define CSR_WDQSEXTENSION_MASK				BIT(8)
+/* CSR_MASTERX4CONFIG */
+#define CSR_MASTERX4CONFIG_LSB				0
+#define CSR_MASTERX4CONFIG_MASK				GENMASK_32(3, 0)
+#define CSR_X4TG_LSB					0
+#define CSR_X4TG_MASK					GENMASK_32(3, 0)
+/* CSR_WRLEVBITS */
+#define CSR_WRLEVBITS_LSB				0
+#define CSR_WRLEVBITS_MASK				GENMASK_32(7, 0)
+#define CSR_WRLEVFORDQSL_LSB				0
+#define CSR_WRLEVFORDQSL_MASK				GENMASK_32(3, 0)
+#define CSR_WRLEVFORDQSU_LSB				4
+#define CSR_WRLEVFORDQSU_MASK				GENMASK_32(7, 4)
+/* CSR_ENABLECSMULTICAST */
+#define CSR_ENABLECSMULTICAST_LSB			0
+#define CSR_ENABLECSMULTICAST_MASK			BIT(0)
+/* CSR_HWTLPCSMULTICAST */
+#define CSR_HWTLPCSMULTICAST_LSB			0
+#define CSR_HWTLPCSMULTICAST_MASK			BIT(0)
+/* CSR_ACX4ANIBDIS */
+#define CSR_ACX4ANIBDIS_LSB				0
+#define CSR_ACX4ANIBDIS_MASK				GENMASK_32(11, 0)
+/* CSR_DMIPINPRESENT */
+#define CSR_DMIPINPRESENT_LSB				0
+#define CSR_DMIPINPRESENT_MASK				BIT(0)
+#define CSR_RDDBIENABLED_LSB				0
+#define CSR_RDDBIENABLED_MASK				BIT(0)
+/* CSR_ARDPTRINITVAL */
+#define CSR_ARDPTRINITVAL_LSB				0
+#define CSR_ARDPTRINITVAL_MASK				GENMASK_32(3, 0)
+/* CSR_DB0LCDLCALPHDETOUT */
+#define CSR_DB0LCDLCALPHDETOUT_LSB			0
+#define CSR_DB0LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB1LCDLCALPHDETOUT */
+#define CSR_DB1LCDLCALPHDETOUT_LSB			0
+#define CSR_DB1LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB2LCDLCALPHDETOUT */
+#define CSR_DB2LCDLCALPHDETOUT_LSB			0
+#define CSR_DB2LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB3LCDLCALPHDETOUT */
+#define CSR_DB3LCDLCALPHDETOUT_LSB			0
+#define CSR_DB3LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB4LCDLCALPHDETOUT */
+#define CSR_DB4LCDLCALPHDETOUT_LSB			0
+#define CSR_DB4LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB5LCDLCALPHDETOUT */
+#define CSR_DB5LCDLCALPHDETOUT_LSB			0
+#define CSR_DB5LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB6LCDLCALPHDETOUT */
+#define CSR_DB6LCDLCALPHDETOUT_LSB			0
+#define CSR_DB6LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB7LCDLCALPHDETOUT */
+#define CSR_DB7LCDLCALPHDETOUT_LSB			0
+#define CSR_DB7LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB8LCDLCALPHDETOUT */
+#define CSR_DB8LCDLCALPHDETOUT_LSB			0
+#define CSR_DB8LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB9LCDLCALPHDETOUT */
+#define CSR_DB9LCDLCALPHDETOUT_LSB			0
+#define CSR_DB9LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DBYTEDLLMODECNTRL */
+#define CSR_DBYTEDLLMODECNTRL_LSB			1
+#define CSR_DBYTEDLLMODECNTRL_MASK			BIT(1)
+#define CSR_DLLRXPREAMBLEMODE_LSB			1
+#define CSR_DLLRXPREAMBLEMODE_MASK			BIT(1)
+/* CSR_DBYTERXENTRAIN */
+#define CSR_DBYTERXENTRAIN_LSB				0
+#define CSR_DBYTERXENTRAIN_MASK				BIT(0)
+#define CSR_RXENTRAIN_LSB				0
+#define CSR_RXENTRAIN_MASK				BIT(0)
+/* CSR_ANLCDLCALPHDETOUT */
+#define CSR_ANLCDLCALPHDETOUT_LSB			0
+#define CSR_ANLCDLCALPHDETOUT_MASK			GENMASK_32(11, 0)
+/* CSR_CALOFFSETS */
+#define CSR_CALOFFSETS_LSB				0
+#define CSR_CALOFFSETS_MASK				GENMASK_32(13, 0)
+#define CSR_CALCMPR5OFFSET_LSB				0
+#define CSR_CALCMPR5OFFSET_MASK				GENMASK_32(5, 0)
+#define CSR_CALDRVPDTHOFFSET_LSB			6
+#define CSR_CALDRVPDTHOFFSET_MASK			GENMASK_32(9, 6)
+#define CSR_CALDRVPUTHOFFSET_LSB			10
+#define CSR_CALDRVPUTHOFFSET_MASK			GENMASK_32(13, 10)
+/* CSR_SARINITVALS */
+#define CSR_SARINITVALS_LSB				0
+#define CSR_SARINITVALS_MASK				GENMASK_32(8, 0)
+#define CSR_SARINITOFFSET05_LSB				0
+#define CSR_SARINITOFFSET05_MASK			GENMASK_32(2, 0)
+#define CSR_SARINITNINT_LSB				3
+#define CSR_SARINITNINT_MASK				GENMASK_32(5, 3)
+#define CSR_SARINITPEXT_LSB				6
+#define CSR_SARINITPEXT_MASK				GENMASK_32(8, 6)
+/* CSR_CALPEXTOVR */
+#define CSR_CALPEXTOVR_LSB				0
+#define CSR_CALPEXTOVR_MASK				GENMASK_32(4, 0)
+/* CSR_CALCMPR5OVR */
+#define CSR_CALCMPR5OVR_LSB				0
+#define CSR_CALCMPR5OVR_MASK				GENMASK_32(7, 0)
+/* CSR_CALNINTOVR */
+#define CSR_CALNINTOVR_LSB				0
+#define CSR_CALNINTOVR_MASK				GENMASK_32(4, 0)
+/* CSR_CALDRVSTR0 */
+#define CSR_CALDRVSTR0_LSB				0
+#define CSR_CALDRVSTR0_MASK				GENMASK_32(7, 0)
+#define CSR_CALDRVSTRPD50_LSB				0
+#define CSR_CALDRVSTRPD50_MASK				GENMASK_32(3, 0)
+#define CSR_CALDRVSTRPU50_LSB				4
+#define CSR_CALDRVSTRPU50_MASK				GENMASK_32(7, 4)
+/* CSR_PROCODTCTL */
+#define CSR_PROCODTCTL_LSB				0
+#define CSR_PROCODTCTL_MASK				GENMASK_32(1, 0)
+#define CSR_PROCODTALWAYSOFF_LSB			0
+#define CSR_PROCODTALWAYSOFF_MASK			BIT(0)
+#define CSR_PROCODTALWAYSON_LSB				1
+#define CSR_PROCODTALWAYSON_MASK			BIT(1)
+/* CSR_PROCODTTIMECTL */
+#define CSR_PROCODTTIMECTL_LSB				0
+#define CSR_PROCODTTIMECTL_MASK				GENMASK_32(5, 0)
+#define CSR_PODTTAILWIDTH_LSB				0
+#define CSR_PODTTAILWIDTH_MASK				GENMASK_32(1, 0)
+#define CSR_PODTSTARTDELAY_LSB				2
+#define CSR_PODTSTARTDELAY_MASK				GENMASK_32(3, 2)
+#define CSR_PODTTAILWIDTHEXT_LSB			4
+#define CSR_PODTTAILWIDTHEXT_MASK			GENMASK_32(5, 4)
+/* CSR_MEMALERTCONTROL */
+#define CSR_MEMALERTCONTROL_LSB				0
+#define CSR_MEMALERTCONTROL_MASK			GENMASK_32(15, 0)
+#define CSR_MALERTVREFLEVEL_LSB				0
+#define CSR_MALERTVREFLEVEL_MASK			GENMASK_32(6, 0)
+#define CSR_MALERTVREFEXTEN_LSB				7
+#define CSR_MALERTVREFEXTEN_MASK			BIT(7)
+#define CSR_MALERTPUSTREN_LSB				8
+#define CSR_MALERTPUSTREN_MASK				GENMASK_32(11, 8)
+#define CSR_MALERTPUEN_LSB				12
+#define CSR_MALERTPUEN_MASK				BIT(12)
+#define CSR_MALERTRXEN_LSB				13
+#define CSR_MALERTRXEN_MASK				BIT(13)
+#define CSR_MALERTDISABLEVAL_LSB			14
+#define CSR_MALERTDISABLEVAL_MASK			BIT(14)
+#define CSR_MALERTFORCEERROR_LSB			15
+#define CSR_MALERTFORCEERROR_MASK			BIT(15)
+/* CSR_MEMALERTCONTROL2 */
+#define CSR_MEMALERTCONTROL2_LSB			0
+#define CSR_MEMALERTCONTROL2_MASK			BIT(0)
+#define CSR_MALERTSYNCBYPASS_LSB			0
+#define CSR_MALERTSYNCBYPASS_MASK			BIT(0)
+/* CSR_MEMRESETL */
+#define CSR_MEMRESETL_LSB				0
+#define CSR_MEMRESETL_MASK				GENMASK_32(1, 0)
+#define CSR_MEMRESETLVALUE_LSB				0
+#define CSR_MEMRESETLVALUE_MASK				BIT(0)
+#define CSR_PROTECTMEMRESET_LSB				1
+#define CSR_PROTECTMEMRESET_MASK			BIT(1)
+/* CSR_PUBMODE */
+#define CSR_PUBMODE_LSB					0
+#define CSR_PUBMODE_MASK				BIT(0)
+#define CSR_HWTMEMSRC_LSB				0
+#define CSR_HWTMEMSRC_MASK				BIT(0)
+/* CSR_MISCPHYSTATUS */
+#define CSR_MISCPHYSTATUS_LSB				0
+#define CSR_MISCPHYSTATUS_MASK				GENMASK_32(1, 0)
+#define CSR_DCTSANE_LSB					0
+#define CSR_DCTSANE_MASK				BIT(0)
+#define CSR_PORMEMRESET_LSB				1
+#define CSR_PORMEMRESET_MASK				BIT(1)
+/* CSR_CORELOOPBACKSEL */
+#define CSR_CORELOOPBACKSEL_LSB				0
+#define CSR_CORELOOPBACKSEL_MASK			BIT(0)
+/* CSR_DLLTRAINPARAM */
+#define CSR_DLLTRAINPARAM_LSB				0
+#define CSR_DLLTRAINPARAM_MASK				GENMASK_32(1, 0)
+#define CSR_EXTENDPHDTIME_LSB				0
+#define CSR_EXTENDPHDTIME_MASK				GENMASK_32(1, 0)
+/* CSR_HWTLPCSENA */
+#define CSR_HWTLPCSENA_LSB				0
+#define CSR_HWTLPCSENA_MASK				GENMASK_32(1, 0)
+/* CSR_HWTLPCSENB */
+#define CSR_HWTLPCSENB_LSB				0
+#define CSR_HWTLPCSENB_MASK				GENMASK_32(1, 0)
+/* CSR_HWTLPCSENBYPASS */
+#define CSR_HWTLPCSENBYPASS_LSB				0
+#define CSR_HWTLPCSENBYPASS_MASK			BIT(0)
+/* CSR_DFICAMODE */
+#define CSR_DFICAMODE_LSB				0
+#define CSR_DFICAMODE_MASK				GENMASK_32(3, 0)
+#define CSR_DFILP3CAMODE_LSB				0
+#define CSR_DFILP3CAMODE_MASK				BIT(0)
+#define CSR_DFID4CAMODE_LSB				1
+#define CSR_DFID4CAMODE_MASK				BIT(1)
+#define CSR_DFILP4CAMODE_LSB				2
+#define CSR_DFILP4CAMODE_MASK				BIT(2)
+#define CSR_DFID4ALTCAMODE_LSB				3
+#define CSR_DFID4ALTCAMODE_MASK				BIT(3)
+/* CSR_HWTCACTL */
+#define CSR_HWTCACTL_LSB				0
+#define CSR_HWTCACTL_MASK				BIT(0)
+#define CSR_HWTDISDYNADRTRI_LSB				0
+#define CSR_HWTDISDYNADRTRI_MASK			BIT(0)
+/* CSR_HWTCAMODE */
+#define CSR_HWTCAMODE_LSB				0
+#define CSR_HWTCAMODE_MASK				GENMASK_32(5, 0)
+#define CSR_HWTLP3CAMODE_LSB				0
+#define CSR_HWTLP3CAMODE_MASK				BIT(0)
+#define CSR_HWTD4CAMODE_LSB				1
+#define CSR_HWTD4CAMODE_MASK				BIT(1)
+#define CSR_HWTLP4CAMODE_LSB				2
+#define CSR_HWTLP4CAMODE_MASK				BIT(2)
+#define CSR_HWTD4ALTCAMODE_LSB				3
+#define CSR_HWTD4ALTCAMODE_MASK				BIT(3)
+#define CSR_HWTCSINVERT_LSB				4
+#define CSR_HWTCSINVERT_MASK				BIT(4)
+#define CSR_HWTDBIINVERT_LSB				5
+#define CSR_HWTDBIINVERT_MASK				BIT(5)
+/* CSR_DLLCONTROL */
+#define CSR_DLLCONTROL_LSB				0
+#define CSR_DLLCONTROL_MASK				GENMASK_32(2, 0)
+#define CSR_DLLRESETRELOCK_LSB				0
+#define CSR_DLLRESETRELOCK_MASK				BIT(0)
+#define CSR_DLLRESETSLAVE_LSB				1
+#define CSR_DLLRESETSLAVE_MASK				BIT(1)
+#define CSR_DLLRESETRSVD_LSB				2
+#define CSR_DLLRESETRSVD_MASK				BIT(2)
+/* CSR_PULSEDLLUPDATEPHASE */
+#define CSR_PULSEDLLUPDATEPHASE_LSB			0
+#define CSR_PULSEDLLUPDATEPHASE_MASK			GENMASK_32(7, 0)
+#define CSR_PULSEDBYTEDLLUPDATEPHASE_LSB		0
+#define CSR_PULSEDBYTEDLLUPDATEPHASE_MASK		BIT(0)
+#define CSR_PULSEACKDLLUPDATEPHASE_LSB			1
+#define CSR_PULSEACKDLLUPDATEPHASE_MASK			BIT(1)
+#define CSR_PULSEACADLLUPDATEPHASE_LSB			2
+#define CSR_PULSEACADLLUPDATEPHASE_MASK			BIT(2)
+#define CSR_UPDATEPHASEDESTRESERVED_LSB			3
+#define CSR_UPDATEPHASEDESTRESERVED_MASK		GENMASK_32(5, 3)
+#define CSR_TRAINUPDATEPHASEONLONGBUBBLE_LSB		6
+#define CSR_TRAINUPDATEPHASEONLONGBUBBLE_MASK		BIT(6)
+#define CSR_ALWAYSUPDATELCDLPHASE_LSB			7
+#define CSR_ALWAYSUPDATELCDLPHASE_MASK			BIT(7)
+/* CSR_HWTCONTROLOVR0 */
+#define CSR_HWTCONTROLOVR0_LSB				0
+#define CSR_HWTCONTROLOVR0_MASK				GENMASK_32(12, 0)
+#define CSR_HWTCS0OVR0_LSB				0
+#define CSR_HWTCS0OVR0_MASK				BIT(0)
+#define CSR_HWTCS1OVR0_LSB				1
+#define CSR_HWTCS1OVR0_MASK				BIT(1)
+#define CSR_HWTCS2OVR0_LSB				2
+#define CSR_HWTCS2OVR0_MASK				BIT(2)
+#define CSR_HWTCS3OVR0_LSB				3
+#define CSR_HWTCS3OVR0_MASK				BIT(3)
+#define CSR_HWTCKE0OVR0_LSB				4
+#define CSR_HWTCKE0OVR0_MASK				BIT(4)
+#define CSR_HWTCKE1OVR0_LSB				5
+#define CSR_HWTCKE1OVR0_MASK				BIT(5)
+#define CSR_HWTCKE2OVR0_LSB				6
+#define CSR_HWTCKE2OVR0_MASK				BIT(6)
+#define CSR_HWTCKE3OVR0_LSB				7
+#define CSR_HWTCKE3OVR0_MASK				BIT(7)
+#define CSR_HWTODT0OVR0_LSB				8
+#define CSR_HWTODT0OVR0_MASK				BIT(8)
+#define CSR_HWTODT1OVR0_LSB				9
+#define CSR_HWTODT1OVR0_MASK				BIT(9)
+#define CSR_HWTODT2OVR0_LSB				10
+#define CSR_HWTODT2OVR0_MASK				BIT(10)
+#define CSR_HWTODT3OVR0_LSB				11
+#define CSR_HWTODT3OVR0_MASK				BIT(11)
+#define CSR_HWTPARITYOVR0_LSB				12
+#define CSR_HWTPARITYOVR0_MASK				BIT(12)
+/* CSR_HWTCONTROLOVR1 */
+#define CSR_HWTCONTROLOVR1_LSB				0
+#define CSR_HWTCONTROLOVR1_MASK				GENMASK_32(12, 0)
+#define CSR_HWTCS0OVR1_LSB				0
+#define CSR_HWTCS0OVR1_MASK				BIT(0)
+#define CSR_HWTCS1OVR1_LSB				1
+#define CSR_HWTCS1OVR1_MASK				BIT(1)
+#define CSR_HWTCS2OVR1_LSB				2
+#define CSR_HWTCS2OVR1_MASK				BIT(2)
+#define CSR_HWTCS3OVR1_LSB				3
+#define CSR_HWTCS3OVR1_MASK				BIT(3)
+#define CSR_HWTCKE0OVR1_LSB				4
+#define CSR_HWTCKE0OVR1_MASK				BIT(4)
+#define CSR_HWTCKE1OVR1_LSB				5
+#define CSR_HWTCKE1OVR1_MASK				BIT(5)
+#define CSR_HWTCKE2OVR1_LSB				6
+#define CSR_HWTCKE2OVR1_MASK				BIT(6)
+#define CSR_HWTCKE3OVR1_LSB				7
+#define CSR_HWTCKE3OVR1_MASK				BIT(7)
+#define CSR_HWTODT0OVR1_LSB				8
+#define CSR_HWTODT0OVR1_MASK				BIT(8)
+#define CSR_HWTODT1OVR1_LSB				9
+#define CSR_HWTODT1OVR1_MASK				BIT(9)
+#define CSR_HWTODT2OVR1_LSB				10
+#define CSR_HWTODT2OVR1_MASK				BIT(10)
+#define CSR_HWTODT3OVR1_LSB				11
+#define CSR_HWTODT3OVR1_MASK				BIT(11)
+#define CSR_HWTPARITYOVR1_LSB				12
+#define CSR_HWTPARITYOVR1_MASK				BIT(12)
+/* CSR_DLLGAINCTL */
+#define CSR_DLLGAINCTL_LSB				0
+#define CSR_DLLGAINCTL_MASK				GENMASK_32(11, 0)
+#define CSR_DLLGAINIV_LSB				0
+#define CSR_DLLGAINIV_MASK				GENMASK_32(3, 0)
+#define CSR_DLLGAINTV_LSB				4
+#define CSR_DLLGAINTV_MASK				GENMASK_32(7, 4)
+#define CSR_DLLSEEDSEL_LSB				8
+#define CSR_DLLSEEDSEL_MASK				GENMASK_32(11, 8)
+/* CSR_DLLLOCKPARAM */
+#define CSR_DLLLOCKPARAM_LSB				0
+#define CSR_DLLLOCKPARAM_MASK				GENMASK_32(12, 0)
+#define CSR_DISDLLSEEDSEL_LSB				0
+#define CSR_DISDLLSEEDSEL_MASK				BIT(0)
+#define CSR_DISDLLGAINIVSEED_LSB			1
+#define CSR_DISDLLGAINIVSEED_MASK			BIT(1)
+#define CSR_DLLLOCKPARAMSPARE_LSB			2
+#define CSR_DLLLOCKPARAMSPARE_MASK			GENMASK_32(3, 2)
+#define CSR_LCDLSEED0_LSB				4
+#define CSR_LCDLSEED0_MASK				GENMASK_32(12, 4)
+/* CSR_HWTCONTROLVAL0 */
+#define CSR_HWTCONTROLVAL0_LSB				0
+#define CSR_HWTCONTROLVAL0_MASK				GENMASK_32(12, 0)
+#define CSR_HWTCS0VAL0_LSB				0
+#define CSR_HWTCS0VAL0_MASK				BIT(0)
+#define CSR_HWTCS1VAL0_LSB				1
+#define CSR_HWTCS1VAL0_MASK				BIT(1)
+#define CSR_HWTCS2VAL0_LSB				2
+#define CSR_HWTCS2VAL0_MASK				BIT(2)
+#define CSR_HWTCS3VAL0_LSB				3
+#define CSR_HWTCS3VAL0_MASK				BIT(3)
+#define CSR_HWTCKE0VAL0_LSB				4
+#define CSR_HWTCKE0VAL0_MASK				BIT(4)
+#define CSR_HWTCKE1VAL0_LSB				5
+#define CSR_HWTCKE1VAL0_MASK				BIT(5)
+#define CSR_HWTCKE2VAL0_LSB				6
+#define CSR_HWTCKE2VAL0_MASK				BIT(6)
+#define CSR_HWTCKE3VAL0_LSB				7
+#define CSR_HWTCKE3VAL0_MASK				BIT(7)
+#define CSR_HWTODT0VAL0_LSB				8
+#define CSR_HWTODT0VAL0_MASK				BIT(8)
+#define CSR_HWTODT1VAL0_LSB				9
+#define CSR_HWTODT1VAL0_MASK				BIT(9)
+#define CSR_HWTODT2VAL0_LSB				10
+#define CSR_HWTODT2VAL0_MASK				BIT(10)
+#define CSR_HWTODT3VAL0_LSB				11
+#define CSR_HWTODT3VAL0_MASK				BIT(11)
+#define CSR_HWTPARITYVAL0_LSB				12
+#define CSR_HWTPARITYVAL0_MASK				BIT(12)
+/* CSR_HWTCONTROLVAL1 */
+#define CSR_HWTCONTROLVAL1_LSB				0
+#define CSR_HWTCONTROLVAL1_MASK				GENMASK_32(12, 0)
+#define CSR_HWTCS0VAL1_LSB				0
+#define CSR_HWTCS0VAL1_MASK				BIT(0)
+#define CSR_HWTCS1VAL1_LSB				1
+#define CSR_HWTCS1VAL1_MASK				BIT(1)
+#define CSR_HWTCS2VAL1_LSB				2
+#define CSR_HWTCS2VAL1_MASK				BIT(2)
+#define CSR_HWTCS3VAL1_LSB				3
+#define CSR_HWTCS3VAL1_MASK				BIT(3)
+#define CSR_HWTCKE0VAL1_LSB				4
+#define CSR_HWTCKE0VAL1_MASK				BIT(4)
+#define CSR_HWTCKE1VAL1_LSB				5
+#define CSR_HWTCKE1VAL1_MASK				BIT(5)
+#define CSR_HWTCKE2VAL1_LSB				6
+#define CSR_HWTCKE2VAL1_MASK				BIT(6)
+#define CSR_HWTCKE3VAL1_LSB				7
+#define CSR_HWTCKE3VAL1_MASK				BIT(7)
+#define CSR_HWTODT0VAL1_LSB				8
+#define CSR_HWTODT0VAL1_MASK				BIT(8)
+#define CSR_HWTODT1VAL1_LSB				9
+#define CSR_HWTODT1VAL1_MASK				BIT(9)
+#define CSR_HWTODT2VAL1_LSB				10
+#define CSR_HWTODT2VAL1_MASK				BIT(10)
+#define CSR_HWTODT3VAL1_LSB				11
+#define CSR_HWTODT3VAL1_MASK				BIT(11)
+#define CSR_HWTPARITYVAL1_LSB				12
+#define CSR_HWTPARITYVAL1_MASK				BIT(12)
+/* CSR_ACSMGLBLSTART */
+#define CSR_ACSMGLBLSTART_LSB				0
+#define CSR_ACSMGLBLSTART_MASK				BIT(0)
+/* CSR_ACSMGLBLSGLSTPCTRL */
+#define CSR_ACSMGLBLSGLSTPCTRL_LSB			0
+#define CSR_ACSMGLBLSGLSTPCTRL_MASK			GENMASK_32(1, 0)
+#define CSR_ACSMSGLSTPMODE_LSB				0
+#define CSR_ACSMSGLSTPMODE_MASK				BIT(0)
+#define CSR_ACSMSGLSTP_LSB				1
+#define CSR_ACSMSGLSTP_MASK				BIT(1)
+/* CSR_LCDLCALPHASE */
+#define CSR_LCDLCALPHASE_LSB				0
+#define CSR_LCDLCALPHASE_MASK				GENMASK_32(8, 0)
+/* CSR_LCDLCALCTRL */
+#define CSR_LCDLCALCTRL_LSB				0
+#define CSR_LCDLCALCTRL_MASK				GENMASK_32(6, 0)
+#define CSR_LCDLCALMODE_LSB				0
+#define CSR_LCDLCALMODE_MASK				BIT(0)
+#define CSR_LCDLCALSLOWCLKSEL_LSB			1
+#define CSR_LCDLCALSLOWCLKSEL_MASK			BIT(1)
+#define CSR_LCDLCALEN_LSB				2
+#define CSR_LCDLCALEN_MASK				BIT(2)
+#define CSR_LCDLCALPHASEUPDATE_LSB			3
+#define CSR_LCDLCALPHASEUPDATE_MASK			BIT(3)
+#define CSR_LCDLCALCLKEN_LSB				4
+#define CSR_LCDLCALCLKEN_MASK				BIT(4)
+#define CSR_LCDLCALSAMPEN_LSB				5
+#define CSR_LCDLCALSAMPEN_MASK				BIT(5)
+#define CSR_LCDLCALSLOWCLKEN_LSB			6
+#define CSR_LCDLCALSLOWCLKEN_MASK			BIT(6)
+/* CSR_CALRATE */
+#define CSR_CALRATE_LSB					0
+#define CSR_CALRATE_MASK				GENMASK_32(6, 0)
+#define CSR_CALINTERVAL_LSB				0
+#define CSR_CALINTERVAL_MASK				GENMASK_32(3, 0)
+#define CSR_CALRUN_LSB					4
+#define CSR_CALRUN_MASK					BIT(4)
+#define CSR_CALONCE_LSB					5
+#define CSR_CALONCE_MASK				BIT(5)
+#define CSR_DISABLEBACKGROUNDZQUPDATES_LSB		6
+#define CSR_DISABLEBACKGROUNDZQUPDATES_MASK		BIT(6)
+/* CSR_CALZAP */
+#define CSR_CALZAP_LSB					0
+#define CSR_CALZAP_MASK					BIT(0)
+/* CSR_PSTATE */
+#define CSR_PSTATE_LSB					0
+#define CSR_PSTATE_MASK					GENMASK_32(3, 0)
+/* CSR_CALPREDRIVEROVERRIDE */
+#define CSR_CALPREDRIVEROVERRIDE_LSB			0
+#define CSR_CALPREDRIVEROVERRIDE_MASK			GENMASK_32(7, 0)
+#define CSR_TXPREOVN_LSB				0
+#define CSR_TXPREOVN_MASK				GENMASK_32(3, 0)
+#define CSR_TXPREOVP_LSB				4
+#define CSR_TXPREOVP_MASK				GENMASK_32(7, 4)
+/* CSR_PLLOUTGATECONTROL */
+#define CSR_PLLOUTGATECONTROL_LSB			0
+#define CSR_PLLOUTGATECONTROL_MASK			GENMASK_32(1, 0)
+#define CSR_PCLKGATEEN_LSB				0
+#define CSR_PCLKGATEEN_MASK				BIT(0)
+#define CSR_RESERVED2X1_LSB				1
+#define CSR_RESERVED2X1_MASK				BIT(1)
+/* CSR_UCMEMRESETCONTROL */
+#define CSR_UCMEMRESETCONTROL_LSB			0
+#define CSR_UCMEMRESETCONTROL_MASK			BIT(0)
+#define CSR_UCDCTSANE_LSB				0
+#define CSR_UCDCTSANE_MASK				BIT(0)
+/* CSR_PORCONTROL */
+#define CSR_PORCONTROL_LSB				0
+#define CSR_PORCONTROL_MASK				BIT(0)
+#define CSR_PLLDLLLOCKDONE_LSB				0
+#define CSR_PLLDLLLOCKDONE_MASK				BIT(0)
+/* CSR_CALBUSY */
+#define CSR_CALBUSY_LSB					0
+#define CSR_CALBUSY_MASK				BIT(0)
+/* CSR_CALMISC2 */
+#define CSR_CALMISC2_LSB				0
+#define CSR_CALMISC2_MASK				GENMASK_32(15, 0)
+#define CSR_CALNUMVOTES_LSB				0
+#define CSR_CALNUMVOTES_MASK				GENMASK_32(2, 0)
+#define CSR_RESERVED10X3_LSB				3
+#define CSR_RESERVED10X3_MASK				GENMASK_32(10, 3)
+#define CSR_RESERVED11_LSB				11
+#define CSR_RESERVED11_MASK				BIT(11)
+#define CSR_CALCMPTRRESTRIM_LSB				12
+#define CSR_CALCMPTRRESTRIM_MASK			BIT(12)
+#define CSR_CALCANCELROUNDERRDIS_LSB			13
+#define CSR_CALCANCELROUNDERRDIS_MASK			BIT(13)
+#define CSR_CALSLOWCMPANA_LSB				14
+#define CSR_CALSLOWCMPANA_MASK				BIT(14)
+#define CSR_RESERVED15_LSB				15
+#define CSR_RESERVED15_MASK				BIT(15)
+/* CSR_CALMISC */
+#define CSR_CALMISC_LSB					0
+#define CSR_CALMISC_MASK				GENMASK_32(2, 0)
+#define CSR_CALCMPR5DIS_LSB				0
+#define CSR_CALCMPR5DIS_MASK				BIT(0)
+#define CSR_CALNINTDIS_LSB				1
+#define CSR_CALNINTDIS_MASK				BIT(1)
+#define CSR_CALPEXTDIS_LSB				2
+#define CSR_CALPEXTDIS_MASK				BIT(2)
+/* CSR_CALVREFS */
+#define CSR_CALVREFS_LSB				0
+#define CSR_CALVREFS_MASK				GENMASK_32(1, 0)
+/* CSR_CALCMPR5 */
+#define CSR_CALCMPR5_LSB				0
+#define CSR_CALCMPR5_MASK				GENMASK_32(7, 0)
+/* CSR_CALNINT */
+#define CSR_CALNINT_LSB					0
+#define CSR_CALNINT_MASK				GENMASK_32(4, 0)
+#define CSR_CALNINTTHB_LSB				0
+#define CSR_CALNINTTHB_MASK				GENMASK_32(4, 0)
+/* CSR_CALPEXT */
+#define CSR_CALPEXT_LSB					0
+#define CSR_CALPEXT_MASK				GENMASK_32(4, 0)
+#define CSR_CALPEXTTHB_LSB				0
+#define CSR_CALPEXTTHB_MASK				GENMASK_32(4, 0)
+/* CSR_CALCMPINVERT */
+#define CSR_CALCMPINVERT_LSB				0
+#define CSR_CALCMPINVERT_MASK				GENMASK_32(4, 0)
+#define CSR_CMPINVERTCALDAC50_LSB			0
+#define CSR_CMPINVERTCALDAC50_MASK			BIT(0)
+#define CSR_CMPINVERTCALDRVPD50_LSB			1
+#define CSR_CMPINVERTCALDRVPD50_MASK			BIT(1)
+#define CSR_CMPINVERTCALDRVPU50_LSB			2
+#define CSR_CMPINVERTCALDRVPU50_MASK			BIT(2)
+#define CSR_CMPINVERTCALODTPD_LSB			3
+#define CSR_CMPINVERTCALODTPD_MASK			BIT(3)
+#define CSR_CMPINVERTCALODTPU_LSB			4
+#define CSR_CMPINVERTCALODTPU_MASK			BIT(4)
+/* CSR_CALCMPANACNTRL */
+#define CSR_CALCMPANACNTRL_LSB				0
+#define CSR_CALCMPANACNTRL_MASK				GENMASK_32(9, 0)
+#define CSR_CMPRGAINCURRADJ_LSB				0
+#define CSR_CMPRGAINCURRADJ_MASK			GENMASK_32(7, 0)
+#define CSR_CMPRGAINRESADJ_LSB				8
+#define CSR_CMPRGAINRESADJ_MASK				BIT(8)
+#define CSR_CMPRBIASBYPASSEN_LSB			9
+#define CSR_CMPRBIASBYPASSEN_MASK			BIT(9)
+/* CSR_DFIRDDATACSDESTMAP */
+#define CSR_DFIRDDATACSDESTMAP_LSB			0
+#define CSR_DFIRDDATACSDESTMAP_MASK			GENMASK_32(7, 0)
+#define CSR_DFIRDDESTM0_LSB				0
+#define CSR_DFIRDDESTM0_MASK				GENMASK_32(1, 0)
+#define CSR_DFIRDDESTM1_LSB				2
+#define CSR_DFIRDDESTM1_MASK				GENMASK_32(3, 2)
+#define CSR_DFIRDDESTM2_LSB				4
+#define CSR_DFIRDDESTM2_MASK				GENMASK_32(5, 4)
+#define CSR_DFIRDDESTM3_LSB				6
+#define CSR_DFIRDDESTM3_MASK				GENMASK_32(7, 6)
+/* CSR_VREFINGLOBAL */
+#define CSR_VREFINGLOBAL_LSB				0
+#define CSR_VREFINGLOBAL_MASK				GENMASK_32(14, 0)
+#define CSR_GLOBALVREFINSEL_LSB				0
+#define CSR_GLOBALVREFINSEL_MASK			GENMASK_32(2, 0)
+#define CSR_GLOBALVREFINDAC_LSB				3
+#define CSR_GLOBALVREFINDAC_MASK			GENMASK_32(9, 3)
+#define CSR_GLOBALVREFINTRIM_LSB			10
+#define CSR_GLOBALVREFINTRIM_MASK			GENMASK_32(13, 10)
+#define CSR_GLOBALVREFINMODE_LSB			14
+#define CSR_GLOBALVREFINMODE_MASK			BIT(14)
+/* CSR_DFIWRDATACSDESTMAP */
+#define CSR_DFIWRDATACSDESTMAP_LSB			0
+#define CSR_DFIWRDATACSDESTMAP_MASK			GENMASK_32(7, 0)
+#define CSR_DFIWRDESTM0_LSB				0
+#define CSR_DFIWRDESTM0_MASK				GENMASK_32(1, 0)
+#define CSR_DFIWRDESTM1_LSB				2
+#define CSR_DFIWRDESTM1_MASK				GENMASK_32(3, 2)
+#define CSR_DFIWRDESTM2_LSB				4
+#define CSR_DFIWRDESTM2_MASK				GENMASK_32(5, 4)
+#define CSR_DFIWRDESTM3_LSB				6
+#define CSR_DFIWRDESTM3_MASK				GENMASK_32(7, 6)
+/* CSR_MASUPDGOODCTR */
+#define CSR_MASUPDGOODCTR_LSB				0
+#define CSR_MASUPDGOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYUPD0GOODCTR */
+#define CSR_PHYUPD0GOODCTR_LSB				0
+#define CSR_PHYUPD0GOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYUPD1GOODCTR */
+#define CSR_PHYUPD1GOODCTR_LSB				0
+#define CSR_PHYUPD1GOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_CTLUPD0GOODCTR */
+#define CSR_CTLUPD0GOODCTR_LSB				0
+#define CSR_CTLUPD0GOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_CTLUPD1GOODCTR */
+#define CSR_CTLUPD1GOODCTR_LSB				0
+#define CSR_CTLUPD1GOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_MASUPDFAILCTR */
+#define CSR_MASUPDFAILCTR_LSB				0
+#define CSR_MASUPDFAILCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYUPD0FAILCTR */
+#define CSR_PHYUPD0FAILCTR_LSB				0
+#define CSR_PHYUPD0FAILCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYUPD1FAILCTR */
+#define CSR_PHYUPD1FAILCTR_LSB				0
+#define CSR_PHYUPD1FAILCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYPERFCTRENABLE */
+#define CSR_PHYPERFCTRENABLE_LSB			0
+#define CSR_PHYPERFCTRENABLE_MASK			GENMASK_32(7, 0)
+#define CSR_MASUPDGOODCTL_LSB				0
+#define CSR_MASUPDGOODCTL_MASK				BIT(0)
+#define CSR_PHYUPD0GOODCTL_LSB				1
+#define CSR_PHYUPD0GOODCTL_MASK				BIT(1)
+#define CSR_PHYUPD1GOODCTL_LSB				2
+#define CSR_PHYUPD1GOODCTL_MASK				BIT(2)
+#define CSR_CTLUPD0GOODCTL_LSB				3
+#define CSR_CTLUPD0GOODCTL_MASK				BIT(3)
+#define CSR_CTLUPD1GOODCTL_LSB				4
+#define CSR_CTLUPD1GOODCTL_MASK				BIT(4)
+#define CSR_MASUPDFAILCTL_LSB				5
+#define CSR_MASUPDFAILCTL_MASK				BIT(5)
+#define CSR_PHYUPD0FAILCTL_LSB				6
+#define CSR_PHYUPD0FAILCTL_MASK				BIT(6)
+#define CSR_PHYUPD1FAILCTL_LSB				7
+#define CSR_PHYUPD1FAILCTL_MASK				BIT(7)
+/* CSR_DFIWRRDDATACSCONFIG */
+#define CSR_DFIWRRDDATACSCONFIG_LSB			0
+#define CSR_DFIWRRDDATACSCONFIG_MASK			GENMASK_32(1, 0)
+#define CSR_DFIWRDATACSPOLARITY_LSB			0
+#define CSR_DFIWRDATACSPOLARITY_MASK			BIT(0)
+#define CSR_DFIRDDATACSPOLARITY_LSB			1
+#define CSR_DFIRDDATACSPOLARITY_MASK			BIT(1)
+/* CSR_PLLPWRDN */
+#define CSR_PLLPWRDN_LSB				0
+#define CSR_PLLPWRDN_MASK				BIT(0)
+/* CSR_PLLRESET */
+#define CSR_PLLRESET_LSB				0
+#define CSR_PLLRESET_MASK				BIT(0)
+/* CSR_PLLCTRL2 */
+#define CSR_PLLCTRL2_LSB				0
+#define CSR_PLLCTRL2_MASK				GENMASK_32(4, 0)
+#define CSR_PLLFREQSEL_LSB				0
+#define CSR_PLLFREQSEL_MASK				GENMASK_32(4, 0)
+/* CSR_PLLCTRL0 */
+#define CSR_PLLCTRL0_LSB				0
+#define CSR_PLLCTRL0_MASK				GENMASK_32(15, 0)
+#define CSR_PLLSTANDBY_LSB				0
+#define CSR_PLLSTANDBY_MASK				BIT(0)
+#define CSR_PLLBYPSEL_LSB				1
+#define CSR_PLLBYPSEL_MASK				BIT(1)
+#define CSR_PLLX2MODE_LSB				2
+#define CSR_PLLX2MODE_MASK				BIT(2)
+#define CSR_PLLOUTBYPEN_LSB				3
+#define CSR_PLLOUTBYPEN_MASK				BIT(3)
+#define CSR_PLLPRESET_LSB				4
+#define CSR_PLLPRESET_MASK				BIT(4)
+#define CSR_PLLBYPASSMODE_LSB				5
+#define CSR_PLLBYPASSMODE_MASK				BIT(5)
+#define CSR_PLLSELDFIFREQRATIO_LSB			6
+#define CSR_PLLSELDFIFREQRATIO_MASK			BIT(6)
+#define CSR_PLLSYNCBUSFLUSH_LSB				7
+#define CSR_PLLSYNCBUSFLUSH_MASK			BIT(7)
+#define CSR_PLLSYNCBUSBYP_LSB				8
+#define CSR_PLLSYNCBUSBYP_MASK				BIT(8)
+#define CSR_PLLRESERVED10X9_LSB				9
+#define CSR_PLLRESERVED10X9_MASK			GENMASK_32(10, 9)
+#define CSR_PLLGEARSHIFT_LSB				11
+#define CSR_PLLGEARSHIFT_MASK				BIT(11)
+#define CSR_PLLLOCKCNTSEL_LSB				12
+#define CSR_PLLLOCKCNTSEL_MASK				BIT(12)
+#define CSR_PLLLOCKPHSEL_LSB				13
+#define CSR_PLLLOCKPHSEL_MASK				GENMASK_32(14, 13)
+#define CSR_PLLSPARECTRL0_LSB				15
+#define CSR_PLLSPARECTRL0_MASK				BIT(15)
+/* CSR_PLLCTRL1 */
+#define CSR_PLLCTRL1_LSB				0
+#define CSR_PLLCTRL1_MASK				GENMASK_32(8, 0)
+#define CSR_PLLCPINTCTRL_LSB				0
+#define CSR_PLLCPINTCTRL_MASK				GENMASK_32(4, 0)
+#define CSR_PLLCPPROPCTRL_LSB				5
+#define CSR_PLLCPPROPCTRL_MASK				GENMASK_32(8, 5)
+/* CSR_PLLTST */
+#define CSR_PLLTST_LSB					0
+#define CSR_PLLTST_MASK					GENMASK_32(8, 0)
+#define CSR_PLLANATSTEN_LSB				0
+#define CSR_PLLANATSTEN_MASK				BIT(0)
+#define CSR_PLLANATSTSEL_LSB				1
+#define CSR_PLLANATSTSEL_MASK				GENMASK_32(4, 1)
+#define CSR_PLLDIGTSTSEL_LSB				5
+#define CSR_PLLDIGTSTSEL_MASK				GENMASK_32(8, 5)
+/* CSR_PLLLOCKSTATUS */
+#define CSR_PLLLOCKSTATUS_LSB				0
+#define CSR_PLLLOCKSTATUS_MASK				BIT(0)
+/* CSR_PLLTESTMODE */
+#define CSR_PLLTESTMODE_LSB				0
+#define CSR_PLLTESTMODE_MASK				GENMASK_32(15, 0)
+/* CSR_PLLCTRL3 */
+#define CSR_PLLCTRL3_LSB				0
+#define CSR_PLLCTRL3_MASK				GENMASK_32(15, 0)
+#define CSR_PLLSPARE_LSB				0
+#define CSR_PLLSPARE_MASK				GENMASK_32(3, 0)
+#define CSR_PLLMAXRANGE_LSB				4
+#define CSR_PLLMAXRANGE_MASK				GENMASK_32(8, 4)
+#define CSR_PLLDACVALIN_LSB				9
+#define CSR_PLLDACVALIN_MASK				GENMASK_32(13, 9)
+#define CSR_PLLFORCECAL_LSB				14
+#define CSR_PLLFORCECAL_MASK				BIT(14)
+#define CSR_PLLENCAL_LSB				15
+#define CSR_PLLENCAL_MASK				BIT(15)
+/* CSR_PLLCTRL4 */
+#define CSR_PLLCTRL4_LSB				0
+#define CSR_PLLCTRL4_MASK				GENMASK_32(8, 0)
+#define CSR_PLLCPINTGSCTRL_LSB				0
+#define CSR_PLLCPINTGSCTRL_MASK				GENMASK_32(4, 0)
+#define CSR_PLLCPPROPGSCTRL_LSB				5
+#define CSR_PLLCPPROPGSCTRL_MASK			GENMASK_32(8, 5)
+/* CSR_PLLENDOFCAL */
+#define CSR_PLLENDOFCAL_LSB				0
+#define CSR_PLLENDOFCAL_MASK				BIT(0)
+/* CSR_PLLSTANDBYEFF */
+#define CSR_PLLSTANDBYEFF_LSB				0
+#define CSR_PLLSTANDBYEFF_MASK				BIT(0)
+/* CSR_PLLDACVALOUT */
+#define CSR_PLLDACVALOUT_LSB				0
+#define CSR_PLLDACVALOUT_MASK				GENMASK_32(4, 0)
+/* CSR_DLYTESTSEQ */
+#define CSR_DLYTESTSEQ_LSB				0
+#define CSR_DLYTESTSEQ_MASK				GENMASK_32(5, 0)
+#define CSR_DLYTESTEN_LSB				0
+#define CSR_DLYTESTEN_MASK				BIT(0)
+#define CSR_DLYTESTCNTINIT_LSB				1
+#define CSR_DLYTESTCNTINIT_MASK				BIT(1)
+#define CSR_DLYTESTENOVERRIDE1_LSB			2
+#define CSR_DLYTESTENOVERRIDE1_MASK			BIT(2)
+#define CSR_DLYTESTENOVERRIDE2_LSB			3
+#define CSR_DLYTESTENOVERRIDE2_MASK			BIT(3)
+#define CSR_SYNCDLYMULTIPLIER_LSB			4
+#define CSR_SYNCDLYMULTIPLIER_MASK			GENMASK_32(5, 4)
+/* CSR_DLYTESTRINGSELDB */
+#define CSR_DLYTESTRINGSELDB_LSB			0
+#define CSR_DLYTESTRINGSELDB_MASK			GENMASK_32(4, 0)
+#define CSR_DLYTESTCUTDB_LSB				0
+#define CSR_DLYTESTCUTDB_MASK				GENMASK_32(4, 0)
+/* CSR_DLYTESTRINGSELAC */
+#define CSR_DLYTESTRINGSELAC_LSB			0
+#define CSR_DLYTESTRINGSELAC_MASK			GENMASK_32(4, 0)
+#define CSR_DLYTESTCUTAC_LSB				0
+#define CSR_DLYTESTCUTAC_MASK				GENMASK_32(4, 0)
+/* CSR_DLYTESTCNTDFICLKIV */
+#define CSR_DLYTESTCNTDFICLKIV_LSB			0
+#define CSR_DLYTESTCNTDFICLKIV_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTDFICLK */
+#define CSR_DLYTESTCNTDFICLK_LSB			0
+#define CSR_DLYTESTCNTDFICLK_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB0 */
+#define CSR_DLYTESTCNTRINGOSCDB0_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB0_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB1 */
+#define CSR_DLYTESTCNTRINGOSCDB1_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB1_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB2 */
+#define CSR_DLYTESTCNTRINGOSCDB2_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB2_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB3 */
+#define CSR_DLYTESTCNTRINGOSCDB3_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB3_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB4 */
+#define CSR_DLYTESTCNTRINGOSCDB4_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB4_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB5 */
+#define CSR_DLYTESTCNTRINGOSCDB5_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB5_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB6 */
+#define CSR_DLYTESTCNTRINGOSCDB6_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB6_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB7 */
+#define CSR_DLYTESTCNTRINGOSCDB7_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB7_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB8 */
+#define CSR_DLYTESTCNTRINGOSCDB8_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB8_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB9 */
+#define CSR_DLYTESTCNTRINGOSCDB9_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB9_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCAC */
+#define CSR_DLYTESTCNTRINGOSCAC_LSB			0
+#define CSR_DLYTESTCNTRINGOSCAC_MASK			GENMASK_32(15, 0)
+/* CSR_MSTLCDLDBGCNTL */
+#define CSR_MSTLCDLDBGCNTL_LSB				0
+#define CSR_MSTLCDLDBGCNTL_MASK				GENMASK_32(11, 0)
+#define CSR_MSTLCDLFINEOVRVAL_LSB			0
+#define CSR_MSTLCDLFINEOVRVAL_MASK			GENMASK_32(8, 0)
+#define CSR_MSTLCDLFINEOVR_LSB				9
+#define CSR_MSTLCDLFINEOVR_MASK				BIT(9)
+#define CSR_MSTLCDLFINESNAP_LSB				10
+#define CSR_MSTLCDLFINESNAP_MASK			BIT(10)
+#define CSR_MSTLCDLTSTENABLE_LSB			11
+#define CSR_MSTLCDLTSTENABLE_MASK			BIT(11)
+/* CSR_MSTLCDL0DBGRES */
+#define CSR_MSTLCDL0DBGRES_LSB				0
+#define CSR_MSTLCDL0DBGRES_MASK				GENMASK_32(12, 0)
+#define CSR_MSTLCDL0FINESNAPVAL_LSB			0
+#define CSR_MSTLCDL0FINESNAPVAL_MASK			GENMASK_32(8, 0)
+#define CSR_MSTLCDL0PHDSNAPVAL_LSB			9
+#define CSR_MSTLCDL0PHDSNAPVAL_MASK			BIT(9)
+#define CSR_MSTLCDL0STICKYLOCK_LSB			10
+#define CSR_MSTLCDL0STICKYLOCK_MASK			BIT(10)
+#define CSR_MSTLCDL0STICKYUNLOCK_LSB			11
+#define CSR_MSTLCDL0STICKYUNLOCK_MASK			BIT(11)
+#define CSR_MSTLCDL0LIVELOCK_LSB			12
+#define CSR_MSTLCDL0LIVELOCK_MASK			BIT(12)
+/* CSR_MSTLCDL1DBGRES */
+#define CSR_MSTLCDL1DBGRES_LSB				0
+#define CSR_MSTLCDL1DBGRES_MASK				GENMASK_32(12, 0)
+#define CSR_MSTLCDL1FINESNAPVAL_LSB			0
+#define CSR_MSTLCDL1FINESNAPVAL_MASK			GENMASK_32(8, 0)
+#define CSR_MSTLCDL1PHDSNAPVAL_LSB			9
+#define CSR_MSTLCDL1PHDSNAPVAL_MASK			BIT(9)
+#define CSR_MSTLCDL1STICKYLOCK_LSB			10
+#define CSR_MSTLCDL1STICKYLOCK_MASK			BIT(10)
+#define CSR_MSTLCDL1STICKYUNLOCK_LSB			11
+#define CSR_MSTLCDL1STICKYUNLOCK_MASK			BIT(11)
+#define CSR_MSTLCDL1LIVELOCK_LSB			12
+#define CSR_MSTLCDL1LIVELOCK_MASK			BIT(12)
+/* CSR_LCDLDBGCNTL */
+#define CSR_LCDLDBGCNTL_LSB				0
+#define CSR_LCDLDBGCNTL_MASK				GENMASK_32(15, 0)
+#define CSR_LCDLFINEOVRVAL_LSB				0
+#define CSR_LCDLFINEOVRVAL_MASK				GENMASK_32(8, 0)
+#define CSR_LCDLFINEOVR_LSB				9
+#define CSR_LCDLFINEOVR_MASK				BIT(9)
+#define CSR_LCDLFINESNAP_LSB				10
+#define CSR_LCDLFINESNAP_MASK				BIT(10)
+#define CSR_LCDLTSTENABLE_LSB				11
+#define CSR_LCDLTSTENABLE_MASK				BIT(11)
+#define CSR_LCDLSTATUSSEL_LSB				12
+#define CSR_LCDLSTATUSSEL_MASK				GENMASK_32(15, 12)
+/* CSR_ACLCDLSTATUS */
+#define CSR_ACLCDLSTATUS_LSB				0
+#define CSR_ACLCDLSTATUS_MASK				GENMASK_32(13, 0)
+#define CSR_ACLCDLFINESNAPVAL_LSB			0
+#define CSR_ACLCDLFINESNAPVAL_MASK			GENMASK_32(9, 0)
+#define CSR_ACLCDLPHDSNAPVAL_LSB			10
+#define CSR_ACLCDLPHDSNAPVAL_MASK			BIT(10)
+#define CSR_ACLCDLSTICKYLOCK_LSB			11
+#define CSR_ACLCDLSTICKYLOCK_MASK			BIT(11)
+#define CSR_ACLCDLSTICKYUNLOCK_LSB			12
+#define CSR_ACLCDLSTICKYUNLOCK_MASK			BIT(12)
+#define CSR_ACLCDLLIVELOCK_LSB				13
+#define CSR_ACLCDLLIVELOCK_MASK				BIT(13)
+/* CSR_CUSTPHYREV */
+#define CSR_CUSTPHYREV_LSB				0
+#define CSR_CUSTPHYREV_MASK				GENMASK_32(5, 0)
+/* CSR_PHYREV */
+#define CSR_PHYREV_LSB					0
+#define CSR_PHYREV_MASK					GENMASK_32(15, 0)
+#define CSR_PHYMNR_LSB					0
+#define CSR_PHYMNR_MASK					GENMASK_32(3, 0)
+#define CSR_PHYMDR_LSB					4
+#define CSR_PHYMDR_MASK					GENMASK_32(7, 4)
+#define CSR_PHYMJR_LSB					8
+#define CSR_PHYMJR_MASK					GENMASK_32(15, 8)
+/* CSR_LP3EXITSEQ0BSTARTVECTOR */
+#define CSR_LP3EXITSEQ0BSTARTVECTOR_LSB			0
+#define CSR_LP3EXITSEQ0BSTARTVECTOR_MASK		GENMASK_32(7, 0)
+#define CSR_LP3EXITSEQ0BSTARTVECPLLENABLED_LSB		0
+#define CSR_LP3EXITSEQ0BSTARTVECPLLENABLED_MASK		GENMASK_32(3, 0)
+#define CSR_LP3EXITSEQ0BSTARTVECPLLBYPASSED_LSB		4
+#define CSR_LP3EXITSEQ0BSTARTVECPLLBYPASSED_MASK	GENMASK_32(7, 4)
+/* CSR_DFIFREQXLAT0 */
+#define CSR_DFIFREQXLAT0_LSB				0
+#define CSR_DFIFREQXLAT0_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL0_LSB				0
+#define CSR_DFIFREQXLATVAL0_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL1_LSB				4
+#define CSR_DFIFREQXLATVAL1_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL2_LSB				8
+#define CSR_DFIFREQXLATVAL2_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL3_LSB				12
+#define CSR_DFIFREQXLATVAL3_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT1 */
+#define CSR_DFIFREQXLAT1_LSB				0
+#define CSR_DFIFREQXLAT1_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL4_LSB				0
+#define CSR_DFIFREQXLATVAL4_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL5_LSB				4
+#define CSR_DFIFREQXLATVAL5_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL6_LSB				8
+#define CSR_DFIFREQXLATVAL6_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL7_LSB				12
+#define CSR_DFIFREQXLATVAL7_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT2 */
+#define CSR_DFIFREQXLAT2_LSB				0
+#define CSR_DFIFREQXLAT2_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL8_LSB				0
+#define CSR_DFIFREQXLATVAL8_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL9_LSB				4
+#define CSR_DFIFREQXLATVAL9_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL10_LSB			8
+#define CSR_DFIFREQXLATVAL10_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL11_LSB			12
+#define CSR_DFIFREQXLATVAL11_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT3 */
+#define CSR_DFIFREQXLAT3_LSB				0
+#define CSR_DFIFREQXLAT3_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL12_LSB			0
+#define CSR_DFIFREQXLATVAL12_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL13_LSB			4
+#define CSR_DFIFREQXLATVAL13_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL14_LSB			8
+#define CSR_DFIFREQXLATVAL14_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL15_LSB			12
+#define CSR_DFIFREQXLATVAL15_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT4 */
+#define CSR_DFIFREQXLAT4_LSB				0
+#define CSR_DFIFREQXLAT4_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL16_LSB			0
+#define CSR_DFIFREQXLATVAL16_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL17_LSB			4
+#define CSR_DFIFREQXLATVAL17_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL18_LSB			8
+#define CSR_DFIFREQXLATVAL18_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL19_LSB			12
+#define CSR_DFIFREQXLATVAL19_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT5 */
+#define CSR_DFIFREQXLAT5_LSB				0
+#define CSR_DFIFREQXLAT5_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL20_LSB			0
+#define CSR_DFIFREQXLATVAL20_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL21_LSB			4
+#define CSR_DFIFREQXLATVAL21_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL22_LSB			8
+#define CSR_DFIFREQXLATVAL22_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL23_LSB			12
+#define CSR_DFIFREQXLATVAL23_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT6 */
+#define CSR_DFIFREQXLAT6_LSB				0
+#define CSR_DFIFREQXLAT6_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL24_LSB			0
+#define CSR_DFIFREQXLATVAL24_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL25_LSB			4
+#define CSR_DFIFREQXLATVAL25_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL26_LSB			8
+#define CSR_DFIFREQXLATVAL26_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL27_LSB			12
+#define CSR_DFIFREQXLATVAL27_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT7 */
+#define CSR_DFIFREQXLAT7_LSB				0
+#define CSR_DFIFREQXLAT7_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL28_LSB			0
+#define CSR_DFIFREQXLATVAL28_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL29_LSB			4
+#define CSR_DFIFREQXLATVAL29_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL30_LSB			8
+#define CSR_DFIFREQXLATVAL30_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL31_LSB			12
+#define CSR_DFIFREQXLATVAL31_MASK			GENMASK_32(15, 12)
+/* CSR_TXRDPTRINIT */
+#define CSR_TXRDPTRINIT_LSB				0
+#define CSR_TXRDPTRINIT_MASK				BIT(0)
+/* CSR_DFIINITCOMPLETE */
+#define CSR_DFIINITCOMPLETE_LSB				0
+#define CSR_DFIINITCOMPLETE_MASK			BIT(0)
+/* CSR_DFIFREQRATIO */
+#define CSR_DFIFREQRATIO_LSB				0
+#define CSR_DFIFREQRATIO_MASK				GENMASK_32(1, 0)
+/* CSR_RXFIFOCHECKS */
+#define CSR_RXFIFOCHECKS_LSB				0
+#define CSR_RXFIFOCHECKS_MASK				BIT(0)
+#define CSR_DOFREQUENTRXFIFOCHECKS_LSB			0
+#define CSR_DOFREQUENTRXFIFOCHECKS_MASK			BIT(0)
+/* CSR_MTESTDTOCTRL */
+#define CSR_MTESTDTOCTRL_LSB				0
+#define CSR_MTESTDTOCTRL_MASK				BIT(0)
+#define CSR_MTESTDTOEN_LSB				0
+#define CSR_MTESTDTOEN_MASK				BIT(0)
+/* CSR_MAPCAA0TODFI */
+#define CSR_MAPCAA0TODFI_LSB				0
+#define CSR_MAPCAA0TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA1TODFI */
+#define CSR_MAPCAA1TODFI_LSB				0
+#define CSR_MAPCAA1TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA2TODFI */
+#define CSR_MAPCAA2TODFI_LSB				0
+#define CSR_MAPCAA2TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA3TODFI */
+#define CSR_MAPCAA3TODFI_LSB				0
+#define CSR_MAPCAA3TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA4TODFI */
+#define CSR_MAPCAA4TODFI_LSB				0
+#define CSR_MAPCAA4TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA5TODFI */
+#define CSR_MAPCAA5TODFI_LSB				0
+#define CSR_MAPCAA5TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA6TODFI */
+#define CSR_MAPCAA6TODFI_LSB				0
+#define CSR_MAPCAA6TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA7TODFI */
+#define CSR_MAPCAA7TODFI_LSB				0
+#define CSR_MAPCAA7TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA8TODFI */
+#define CSR_MAPCAA8TODFI_LSB				0
+#define CSR_MAPCAA8TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA9TODFI */
+#define CSR_MAPCAA9TODFI_LSB				0
+#define CSR_MAPCAA9TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB0TODFI */
+#define CSR_MAPCAB0TODFI_LSB				0
+#define CSR_MAPCAB0TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB1TODFI */
+#define CSR_MAPCAB1TODFI_LSB				0
+#define CSR_MAPCAB1TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB2TODFI */
+#define CSR_MAPCAB2TODFI_LSB				0
+#define CSR_MAPCAB2TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB3TODFI */
+#define CSR_MAPCAB3TODFI_LSB				0
+#define CSR_MAPCAB3TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB4TODFI */
+#define CSR_MAPCAB4TODFI_LSB				0
+#define CSR_MAPCAB4TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB5TODFI */
+#define CSR_MAPCAB5TODFI_LSB				0
+#define CSR_MAPCAB5TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB6TODFI */
+#define CSR_MAPCAB6TODFI_LSB				0
+#define CSR_MAPCAB6TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB7TODFI */
+#define CSR_MAPCAB7TODFI_LSB				0
+#define CSR_MAPCAB7TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB8TODFI */
+#define CSR_MAPCAB8TODFI_LSB				0
+#define CSR_MAPCAB8TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB9TODFI */
+#define CSR_MAPCAB9TODFI_LSB				0
+#define CSR_MAPCAB9TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_PHYINTERRUPTENABLE */
+#define CSR_PHYINTERRUPTENABLE_LSB			0
+#define CSR_PHYINTERRUPTENABLE_MASK			GENMASK_32(15, 0)
+#define CSR_PHYTRNGCMPLTEN_LSB				0
+#define CSR_PHYTRNGCMPLTEN_MASK				BIT(0)
+#define CSR_PHYINITCMPLTEN_LSB				1
+#define CSR_PHYINITCMPLTEN_MASK				BIT(1)
+#define CSR_PHYTRNGFAILEN_LSB				2
+#define CSR_PHYTRNGFAILEN_MASK				BIT(2)
+#define CSR_PHYFWRESERVEDEN_LSB				3
+#define CSR_PHYFWRESERVEDEN_MASK			GENMASK_32(7, 3)
+#define CSR_PHYVTDRIFTALARMEN_LSB			8
+#define CSR_PHYVTDRIFTALARMEN_MASK			GENMASK_32(9, 8)
+#define CSR_PHYRXFIFOCHECKEN_LSB			10
+#define CSR_PHYRXFIFOCHECKEN_MASK			BIT(10)
+#define CSR_PHYHWRESERVEDEN_LSB				11
+#define CSR_PHYHWRESERVEDEN_MASK			GENMASK_32(15, 11)
+/* CSR_PHYINTERRUPTFWCONTROL */
+#define CSR_PHYINTERRUPTFWCONTROL_LSB			0
+#define CSR_PHYINTERRUPTFWCONTROL_MASK			GENMASK_32(7, 0)
+#define CSR_PHYTRNGCMPLTFW_LSB				0
+#define CSR_PHYTRNGCMPLTFW_MASK				BIT(0)
+#define CSR_PHYINITCMPLTFW_LSB				1
+#define CSR_PHYINITCMPLTFW_MASK				BIT(1)
+#define CSR_PHYTRNGFAILFW_LSB				2
+#define CSR_PHYTRNGFAILFW_MASK				BIT(2)
+#define CSR_PHYFWRESERVEDFW_LSB				3
+#define CSR_PHYFWRESERVEDFW_MASK			GENMASK_32(7, 3)
+/* CSR_PHYINTERRUPTMASK */
+#define CSR_PHYINTERRUPTMASK_LSB			0
+#define CSR_PHYINTERRUPTMASK_MASK			GENMASK_32(15, 0)
+#define CSR_PHYTRNGCMPLTMSK_LSB				0
+#define CSR_PHYTRNGCMPLTMSK_MASK			BIT(0)
+#define CSR_PHYINITCMPLTMSK_LSB				1
+#define CSR_PHYINITCMPLTMSK_MASK			BIT(1)
+#define CSR_PHYTRNGFAILMSK_LSB				2
+#define CSR_PHYTRNGFAILMSK_MASK				BIT(2)
+#define CSR_PHYFWRESERVEDMSK_LSB			3
+#define CSR_PHYFWRESERVEDMSK_MASK			GENMASK_32(7, 3)
+#define CSR_PHYVTDRIFTALARMMSK_LSB			8
+#define CSR_PHYVTDRIFTALARMMSK_MASK			GENMASK_32(9, 8)
+#define CSR_PHYRXFIFOCHECKMSK_LSB			10
+#define CSR_PHYRXFIFOCHECKMSK_MASK			BIT(10)
+#define CSR_PHYHWRESERVEDMSK_LSB			11
+#define CSR_PHYHWRESERVEDMSK_MASK			GENMASK_32(15, 11)
+/* CSR_PHYINTERRUPTCLEAR */
+#define CSR_PHYINTERRUPTCLEAR_LSB			0
+#define CSR_PHYINTERRUPTCLEAR_MASK			GENMASK_32(15, 0)
+#define CSR_PHYTRNGCMPLTCLR_LSB				0
+#define CSR_PHYTRNGCMPLTCLR_MASK			BIT(0)
+#define CSR_PHYINITCMPLTCLR_LSB				1
+#define CSR_PHYINITCMPLTCLR_MASK			BIT(1)
+#define CSR_PHYTRNGFAILCLR_LSB				2
+#define CSR_PHYTRNGFAILCLR_MASK				BIT(2)
+#define CSR_PHYFWRESERVEDCLR_LSB			3
+#define CSR_PHYFWRESERVEDCLR_MASK			GENMASK_32(7, 3)
+#define CSR_PHYVTDRIFTALARMCLR_LSB			8
+#define CSR_PHYVTDRIFTALARMCLR_MASK			GENMASK_32(9, 8)
+#define CSR_PHYRXFIFOCHECKCLR_LSB			10
+#define CSR_PHYRXFIFOCHECKCLR_MASK			BIT(10)
+#define CSR_PHYHWRESERVEDCLR_LSB			11
+#define CSR_PHYHWRESERVEDCLR_MASK			GENMASK_32(15, 11)
+/* CSR_PHYINTERRUPTSTATUS */
+#define CSR_PHYINTERRUPTSTATUS_LSB			0
+#define CSR_PHYINTERRUPTSTATUS_MASK			GENMASK_32(15, 0)
+#define CSR_PHYTRNGCMPLT_LSB				0
+#define CSR_PHYTRNGCMPLT_MASK				BIT(0)
+#define CSR_PHYINITCMPLT_LSB				1
+#define CSR_PHYINITCMPLT_MASK				BIT(1)
+#define CSR_PHYTRNGFAIL_LSB				2
+#define CSR_PHYTRNGFAIL_MASK				BIT(2)
+#define CSR_PHYFWRESERVED_LSB				3
+#define CSR_PHYFWRESERVED_MASK				GENMASK_32(7, 3)
+#define CSR_VTDRIFTALARM_LSB				8
+#define CSR_VTDRIFTALARM_MASK				GENMASK_32(9, 8)
+#define CSR_PHYRXFIFOCHECK_LSB				10
+#define CSR_PHYRXFIFOCHECK_MASK				BIT(10)
+#define CSR_PHYHWRESERVED_LSB				11
+#define CSR_PHYHWRESERVED_MASK				GENMASK_32(15, 11)
+/* CSR_HWTSWIZZLEHWTADDRESS0 */
+#define CSR_HWTSWIZZLEHWTADDRESS0_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS0_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS1 */
+#define CSR_HWTSWIZZLEHWTADDRESS1_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS1_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS2 */
+#define CSR_HWTSWIZZLEHWTADDRESS2_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS2_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS3 */
+#define CSR_HWTSWIZZLEHWTADDRESS3_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS3_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS4 */
+#define CSR_HWTSWIZZLEHWTADDRESS4_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS4_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS5 */
+#define CSR_HWTSWIZZLEHWTADDRESS5_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS5_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS6 */
+#define CSR_HWTSWIZZLEHWTADDRESS6_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS6_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS7 */
+#define CSR_HWTSWIZZLEHWTADDRESS7_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS7_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS8 */
+#define CSR_HWTSWIZZLEHWTADDRESS8_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS8_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS9 */
+#define CSR_HWTSWIZZLEHWTADDRESS9_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS9_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS10 */
+#define CSR_HWTSWIZZLEHWTADDRESS10_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS10_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS11 */
+#define CSR_HWTSWIZZLEHWTADDRESS11_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS11_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS12 */
+#define CSR_HWTSWIZZLEHWTADDRESS12_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS12_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS13 */
+#define CSR_HWTSWIZZLEHWTADDRESS13_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS13_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS14 */
+#define CSR_HWTSWIZZLEHWTADDRESS14_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS14_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS15 */
+#define CSR_HWTSWIZZLEHWTADDRESS15_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS15_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS17 */
+#define CSR_HWTSWIZZLEHWTADDRESS17_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS17_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTACTN */
+#define CSR_HWTSWIZZLEHWTACTN_LSB			0
+#define CSR_HWTSWIZZLEHWTACTN_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBANK0 */
+#define CSR_HWTSWIZZLEHWTBANK0_LSB			0
+#define CSR_HWTSWIZZLEHWTBANK0_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBANK1 */
+#define CSR_HWTSWIZZLEHWTBANK1_LSB			0
+#define CSR_HWTSWIZZLEHWTBANK1_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBANK2 */
+#define CSR_HWTSWIZZLEHWTBANK2_LSB			0
+#define CSR_HWTSWIZZLEHWTBANK2_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBG0 */
+#define CSR_HWTSWIZZLEHWTBG0_LSB			0
+#define CSR_HWTSWIZZLEHWTBG0_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBG1 */
+#define CSR_HWTSWIZZLEHWTBG1_LSB			0
+#define CSR_HWTSWIZZLEHWTBG1_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTCASN */
+#define CSR_HWTSWIZZLEHWTCASN_LSB			0
+#define CSR_HWTSWIZZLEHWTCASN_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTRASN */
+#define CSR_HWTSWIZZLEHWTRASN_LSB			0
+#define CSR_HWTSWIZZLEHWTRASN_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTWEN */
+#define CSR_HWTSWIZZLEHWTWEN_LSB			0
+#define CSR_HWTSWIZZLEHWTWEN_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTPARITYIN */
+#define CSR_HWTSWIZZLEHWTPARITYIN_LSB			0
+#define CSR_HWTSWIZZLEHWTPARITYIN_MASK			GENMASK_32(4, 0)
+/* CSR_DFIHANDSHAKEDELAYS0 */
+#define CSR_DFIHANDSHAKEDELAYS0_LSB			0
+#define CSR_DFIHANDSHAKEDELAYS0_MASK			GENMASK_32(15, 0)
+#define CSR_PHYUPDACKDELAY0_LSB				0
+#define CSR_PHYUPDACKDELAY0_MASK			GENMASK_32(3, 0)
+#define CSR_PHYUPDREQDELAY0_LSB				4
+#define CSR_PHYUPDREQDELAY0_MASK			GENMASK_32(7, 4)
+#define CSR_CTRLUPDACKDELAY0_LSB			8
+#define CSR_CTRLUPDACKDELAY0_MASK			GENMASK_32(11, 8)
+#define CSR_CTRLUPDREQDELAY0_LSB			12
+#define CSR_CTRLUPDREQDELAY0_MASK			GENMASK_32(15, 12)
+/* CSR_DFIHANDSHAKEDELAYS1 */
+#define CSR_DFIHANDSHAKEDELAYS1_LSB			0
+#define CSR_DFIHANDSHAKEDELAYS1_MASK			GENMASK_32(15, 0)
+#define CSR_PHYUPDACKDELAY1_LSB				0
+#define CSR_PHYUPDACKDELAY1_MASK			GENMASK_32(3, 0)
+#define CSR_PHYUPDREQDELAY1_LSB				4
+#define CSR_PHYUPDREQDELAY1_MASK			GENMASK_32(7, 4)
+#define CSR_CTRLUPDACKDELAY1_LSB			8
+#define CSR_CTRLUPDACKDELAY1_MASK			GENMASK_32(11, 8)
+#define CSR_CTRLUPDREQDELAY1_LSB			12
+#define CSR_CTRLUPDREQDELAY1_MASK			GENMASK_32(15, 12)
+/* CSR_REMOTEIMPCAL */
+#define CSR_REMOTEIMPCAL_LSB				0
+#define CSR_REMOTEIMPCAL_MASK				GENMASK_32(1, 0)
+#define CSR_CALIBSLAVE_LSB				0
+#define CSR_CALIBSLAVE_MASK				BIT(0)
+#define CSR_SLAVECODEUPDATED_LSB			1
+#define CSR_SLAVECODEUPDATED_MASK			BIT(1)
+/* CSR_ACLOOPBACKCTL */
+#define CSR_ACLOOPBACKCTL_LSB				0
+#define CSR_ACLOOPBACKCTL_MASK				GENMASK_32(1, 0)
+#define CSR_TERMINATION_LSB				0
+#define CSR_TERMINATION_MASK				BIT(0)
+#define CSR_NOISECANCEL_LSB				1
+#define CSR_NOISECANCEL_MASK				BIT(1)
+
+/* ACSM0 register offsets */
+/* CSR_ACSMSEQ0X0 */
+#define CSR_ACSMSEQ0X0_LSB				0
+#define CSR_ACSMSEQ0X0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY0_LSB				0
+#define CSR_ACSMMCLKDLY0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE0_LSB				8
+#define CSR_ACSMDDRWE0_MASK				BIT(8)
+#define CSR_ACSMDDRCAS0_LSB				9
+#define CSR_ACSMDDRCAS0_MASK				BIT(9)
+#define CSR_ACSMDDRRAS0_LSB				10
+#define CSR_ACSMDDRRAS0_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET0_LSB				11
+#define CSR_ACSMDDRCKESET0_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR0_LSB				12
+#define CSR_ACSMDDRCKECLR0_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD0_LSB				13
+#define CSR_ACSMSEQGATECMD0_MASK			BIT(13)
+#define CSR_ACSMSEQTERM0_LSB				14
+#define CSR_ACSMSEQTERM0_MASK				BIT(14)
+#define CSR_ACSMLP3CA30_LSB				15
+#define CSR_ACSMLP3CA30_MASK				BIT(15)
+/* CSR_ACSMSEQ0X1 */
+#define CSR_ACSMSEQ0X1_LSB				0
+#define CSR_ACSMSEQ0X1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY1_LSB				0
+#define CSR_ACSMMCLKDLY1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE1_LSB				8
+#define CSR_ACSMDDRWE1_MASK				BIT(8)
+#define CSR_ACSMDDRCAS1_LSB				9
+#define CSR_ACSMDDRCAS1_MASK				BIT(9)
+#define CSR_ACSMDDRRAS1_LSB				10
+#define CSR_ACSMDDRRAS1_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET1_LSB				11
+#define CSR_ACSMDDRCKESET1_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR1_LSB				12
+#define CSR_ACSMDDRCKECLR1_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD1_LSB				13
+#define CSR_ACSMSEQGATECMD1_MASK			BIT(13)
+#define CSR_ACSMSEQTERM1_LSB				14
+#define CSR_ACSMSEQTERM1_MASK				BIT(14)
+#define CSR_ACSMLP3CA31_LSB				15
+#define CSR_ACSMLP3CA31_MASK				BIT(15)
+/* CSR_ACSMSEQ0X2 */
+#define CSR_ACSMSEQ0X2_LSB				0
+#define CSR_ACSMSEQ0X2_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY2_LSB				0
+#define CSR_ACSMMCLKDLY2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE2_LSB				8
+#define CSR_ACSMDDRWE2_MASK				BIT(8)
+#define CSR_ACSMDDRCAS2_LSB				9
+#define CSR_ACSMDDRCAS2_MASK				BIT(9)
+#define CSR_ACSMDDRRAS2_LSB				10
+#define CSR_ACSMDDRRAS2_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET2_LSB				11
+#define CSR_ACSMDDRCKESET2_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR2_LSB				12
+#define CSR_ACSMDDRCKECLR2_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD2_LSB				13
+#define CSR_ACSMSEQGATECMD2_MASK			BIT(13)
+#define CSR_ACSMSEQTERM2_LSB				14
+#define CSR_ACSMSEQTERM2_MASK				BIT(14)
+#define CSR_ACSMLP3CA32_LSB				15
+#define CSR_ACSMLP3CA32_MASK				BIT(15)
+/* CSR_ACSMSEQ0X3 */
+#define CSR_ACSMSEQ0X3_LSB				0
+#define CSR_ACSMSEQ0X3_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY3_LSB				0
+#define CSR_ACSMMCLKDLY3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE3_LSB				8
+#define CSR_ACSMDDRWE3_MASK				BIT(8)
+#define CSR_ACSMDDRCAS3_LSB				9
+#define CSR_ACSMDDRCAS3_MASK				BIT(9)
+#define CSR_ACSMDDRRAS3_LSB				10
+#define CSR_ACSMDDRRAS3_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET3_LSB				11
+#define CSR_ACSMDDRCKESET3_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR3_LSB				12
+#define CSR_ACSMDDRCKECLR3_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD3_LSB				13
+#define CSR_ACSMSEQGATECMD3_MASK			BIT(13)
+#define CSR_ACSMSEQTERM3_LSB				14
+#define CSR_ACSMSEQTERM3_MASK				BIT(14)
+#define CSR_ACSMLP3CA33_LSB				15
+#define CSR_ACSMLP3CA33_MASK				BIT(15)
+/* CSR_ACSMSEQ0X4 */
+#define CSR_ACSMSEQ0X4_LSB				0
+#define CSR_ACSMSEQ0X4_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY4_LSB				0
+#define CSR_ACSMMCLKDLY4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE4_LSB				8
+#define CSR_ACSMDDRWE4_MASK				BIT(8)
+#define CSR_ACSMDDRCAS4_LSB				9
+#define CSR_ACSMDDRCAS4_MASK				BIT(9)
+#define CSR_ACSMDDRRAS4_LSB				10
+#define CSR_ACSMDDRRAS4_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET4_LSB				11
+#define CSR_ACSMDDRCKESET4_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR4_LSB				12
+#define CSR_ACSMDDRCKECLR4_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD4_LSB				13
+#define CSR_ACSMSEQGATECMD4_MASK			BIT(13)
+#define CSR_ACSMSEQTERM4_LSB				14
+#define CSR_ACSMSEQTERM4_MASK				BIT(14)
+#define CSR_ACSMLP3CA34_LSB				15
+#define CSR_ACSMLP3CA34_MASK				BIT(15)
+/* CSR_ACSMSEQ0X5 */
+#define CSR_ACSMSEQ0X5_LSB				0
+#define CSR_ACSMSEQ0X5_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY5_LSB				0
+#define CSR_ACSMMCLKDLY5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE5_LSB				8
+#define CSR_ACSMDDRWE5_MASK				BIT(8)
+#define CSR_ACSMDDRCAS5_LSB				9
+#define CSR_ACSMDDRCAS5_MASK				BIT(9)
+#define CSR_ACSMDDRRAS5_LSB				10
+#define CSR_ACSMDDRRAS5_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET5_LSB				11
+#define CSR_ACSMDDRCKESET5_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR5_LSB				12
+#define CSR_ACSMDDRCKECLR5_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD5_LSB				13
+#define CSR_ACSMSEQGATECMD5_MASK			BIT(13)
+#define CSR_ACSMSEQTERM5_LSB				14
+#define CSR_ACSMSEQTERM5_MASK				BIT(14)
+#define CSR_ACSMLP3CA35_LSB				15
+#define CSR_ACSMLP3CA35_MASK				BIT(15)
+/* CSR_ACSMSEQ0X6 */
+#define CSR_ACSMSEQ0X6_LSB				0
+#define CSR_ACSMSEQ0X6_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY6_LSB				0
+#define CSR_ACSMMCLKDLY6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE6_LSB				8
+#define CSR_ACSMDDRWE6_MASK				BIT(8)
+#define CSR_ACSMDDRCAS6_LSB				9
+#define CSR_ACSMDDRCAS6_MASK				BIT(9)
+#define CSR_ACSMDDRRAS6_LSB				10
+#define CSR_ACSMDDRRAS6_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET6_LSB				11
+#define CSR_ACSMDDRCKESET6_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR6_LSB				12
+#define CSR_ACSMDDRCKECLR6_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD6_LSB				13
+#define CSR_ACSMSEQGATECMD6_MASK			BIT(13)
+#define CSR_ACSMSEQTERM6_LSB				14
+#define CSR_ACSMSEQTERM6_MASK				BIT(14)
+#define CSR_ACSMLP3CA36_LSB				15
+#define CSR_ACSMLP3CA36_MASK				BIT(15)
+/* CSR_ACSMSEQ0X7 */
+#define CSR_ACSMSEQ0X7_LSB				0
+#define CSR_ACSMSEQ0X7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY7_LSB				0
+#define CSR_ACSMMCLKDLY7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE7_LSB				8
+#define CSR_ACSMDDRWE7_MASK				BIT(8)
+#define CSR_ACSMDDRCAS7_LSB				9
+#define CSR_ACSMDDRCAS7_MASK				BIT(9)
+#define CSR_ACSMDDRRAS7_LSB				10
+#define CSR_ACSMDDRRAS7_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET7_LSB				11
+#define CSR_ACSMDDRCKESET7_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR7_LSB				12
+#define CSR_ACSMDDRCKECLR7_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD7_LSB				13
+#define CSR_ACSMSEQGATECMD7_MASK			BIT(13)
+#define CSR_ACSMSEQTERM7_LSB				14
+#define CSR_ACSMSEQTERM7_MASK				BIT(14)
+#define CSR_ACSMLP3CA37_LSB				15
+#define CSR_ACSMLP3CA37_MASK				BIT(15)
+/* CSR_ACSMSEQ0X8 */
+#define CSR_ACSMSEQ0X8_LSB				0
+#define CSR_ACSMSEQ0X8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY8_LSB				0
+#define CSR_ACSMMCLKDLY8_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE8_LSB				8
+#define CSR_ACSMDDRWE8_MASK				BIT(8)
+#define CSR_ACSMDDRCAS8_LSB				9
+#define CSR_ACSMDDRCAS8_MASK				BIT(9)
+#define CSR_ACSMDDRRAS8_LSB				10
+#define CSR_ACSMDDRRAS8_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET8_LSB				11
+#define CSR_ACSMDDRCKESET8_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR8_LSB				12
+#define CSR_ACSMDDRCKECLR8_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD8_LSB				13
+#define CSR_ACSMSEQGATECMD8_MASK			BIT(13)
+#define CSR_ACSMSEQTERM8_LSB				14
+#define CSR_ACSMSEQTERM8_MASK				BIT(14)
+#define CSR_ACSMLP3CA38_LSB				15
+#define CSR_ACSMLP3CA38_MASK				BIT(15)
+/* CSR_ACSMSEQ0X9 */
+#define CSR_ACSMSEQ0X9_LSB				0
+#define CSR_ACSMSEQ0X9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY9_LSB				0
+#define CSR_ACSMMCLKDLY9_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE9_LSB				8
+#define CSR_ACSMDDRWE9_MASK				BIT(8)
+#define CSR_ACSMDDRCAS9_LSB				9
+#define CSR_ACSMDDRCAS9_MASK				BIT(9)
+#define CSR_ACSMDDRRAS9_LSB				10
+#define CSR_ACSMDDRRAS9_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET9_LSB				11
+#define CSR_ACSMDDRCKESET9_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR9_LSB				12
+#define CSR_ACSMDDRCKECLR9_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD9_LSB				13
+#define CSR_ACSMSEQGATECMD9_MASK			BIT(13)
+#define CSR_ACSMSEQTERM9_LSB				14
+#define CSR_ACSMSEQTERM9_MASK				BIT(14)
+#define CSR_ACSMLP3CA39_LSB				15
+#define CSR_ACSMLP3CA39_MASK				BIT(15)
+/* CSR_ACSMSEQ0X10 */
+#define CSR_ACSMSEQ0X10_LSB				0
+#define CSR_ACSMSEQ0X10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY10_LSB				0
+#define CSR_ACSMMCLKDLY10_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE10_LSB				8
+#define CSR_ACSMDDRWE10_MASK				BIT(8)
+#define CSR_ACSMDDRCAS10_LSB				9
+#define CSR_ACSMDDRCAS10_MASK				BIT(9)
+#define CSR_ACSMDDRRAS10_LSB				10
+#define CSR_ACSMDDRRAS10_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET10_LSB				11
+#define CSR_ACSMDDRCKESET10_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR10_LSB				12
+#define CSR_ACSMDDRCKECLR10_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD10_LSB			13
+#define CSR_ACSMSEQGATECMD10_MASK			BIT(13)
+#define CSR_ACSMSEQTERM10_LSB				14
+#define CSR_ACSMSEQTERM10_MASK				BIT(14)
+#define CSR_ACSMLP3CA310_LSB				15
+#define CSR_ACSMLP3CA310_MASK				BIT(15)
+/* CSR_ACSMSEQ0X11 */
+#define CSR_ACSMSEQ0X11_LSB				0
+#define CSR_ACSMSEQ0X11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY11_LSB				0
+#define CSR_ACSMMCLKDLY11_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE11_LSB				8
+#define CSR_ACSMDDRWE11_MASK				BIT(8)
+#define CSR_ACSMDDRCAS11_LSB				9
+#define CSR_ACSMDDRCAS11_MASK				BIT(9)
+#define CSR_ACSMDDRRAS11_LSB				10
+#define CSR_ACSMDDRRAS11_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET11_LSB				11
+#define CSR_ACSMDDRCKESET11_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR11_LSB				12
+#define CSR_ACSMDDRCKECLR11_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD11_LSB			13
+#define CSR_ACSMSEQGATECMD11_MASK			BIT(13)
+#define CSR_ACSMSEQTERM11_LSB				14
+#define CSR_ACSMSEQTERM11_MASK				BIT(14)
+#define CSR_ACSMLP3CA311_LSB				15
+#define CSR_ACSMLP3CA311_MASK				BIT(15)
+/* CSR_ACSMSEQ0X12 */
+#define CSR_ACSMSEQ0X12_LSB				0
+#define CSR_ACSMSEQ0X12_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY12_LSB				0
+#define CSR_ACSMMCLKDLY12_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE12_LSB				8
+#define CSR_ACSMDDRWE12_MASK				BIT(8)
+#define CSR_ACSMDDRCAS12_LSB				9
+#define CSR_ACSMDDRCAS12_MASK				BIT(9)
+#define CSR_ACSMDDRRAS12_LSB				10
+#define CSR_ACSMDDRRAS12_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET12_LSB				11
+#define CSR_ACSMDDRCKESET12_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR12_LSB				12
+#define CSR_ACSMDDRCKECLR12_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD12_LSB			13
+#define CSR_ACSMSEQGATECMD12_MASK			BIT(13)
+#define CSR_ACSMSEQTERM12_LSB				14
+#define CSR_ACSMSEQTERM12_MASK				BIT(14)
+#define CSR_ACSMLP3CA312_LSB				15
+#define CSR_ACSMLP3CA312_MASK				BIT(15)
+/* CSR_ACSMSEQ0X13 */
+#define CSR_ACSMSEQ0X13_LSB				0
+#define CSR_ACSMSEQ0X13_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY13_LSB				0
+#define CSR_ACSMMCLKDLY13_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE13_LSB				8
+#define CSR_ACSMDDRWE13_MASK				BIT(8)
+#define CSR_ACSMDDRCAS13_LSB				9
+#define CSR_ACSMDDRCAS13_MASK				BIT(9)
+#define CSR_ACSMDDRRAS13_LSB				10
+#define CSR_ACSMDDRRAS13_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET13_LSB				11
+#define CSR_ACSMDDRCKESET13_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR13_LSB				12
+#define CSR_ACSMDDRCKECLR13_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD13_LSB			13
+#define CSR_ACSMSEQGATECMD13_MASK			BIT(13)
+#define CSR_ACSMSEQTERM13_LSB				14
+#define CSR_ACSMSEQTERM13_MASK				BIT(14)
+#define CSR_ACSMLP3CA313_LSB				15
+#define CSR_ACSMLP3CA313_MASK				BIT(15)
+/* CSR_ACSMSEQ0X14 */
+#define CSR_ACSMSEQ0X14_LSB				0
+#define CSR_ACSMSEQ0X14_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY14_LSB				0
+#define CSR_ACSMMCLKDLY14_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE14_LSB				8
+#define CSR_ACSMDDRWE14_MASK				BIT(8)
+#define CSR_ACSMDDRCAS14_LSB				9
+#define CSR_ACSMDDRCAS14_MASK				BIT(9)
+#define CSR_ACSMDDRRAS14_LSB				10
+#define CSR_ACSMDDRRAS14_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET14_LSB				11
+#define CSR_ACSMDDRCKESET14_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR14_LSB				12
+#define CSR_ACSMDDRCKECLR14_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD14_LSB			13
+#define CSR_ACSMSEQGATECMD14_MASK			BIT(13)
+#define CSR_ACSMSEQTERM14_LSB				14
+#define CSR_ACSMSEQTERM14_MASK				BIT(14)
+#define CSR_ACSMLP3CA314_LSB				15
+#define CSR_ACSMLP3CA314_MASK				BIT(15)
+/* CSR_ACSMSEQ0X15 */
+#define CSR_ACSMSEQ0X15_LSB				0
+#define CSR_ACSMSEQ0X15_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY15_LSB				0
+#define CSR_ACSMMCLKDLY15_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE15_LSB				8
+#define CSR_ACSMDDRWE15_MASK				BIT(8)
+#define CSR_ACSMDDRCAS15_LSB				9
+#define CSR_ACSMDDRCAS15_MASK				BIT(9)
+#define CSR_ACSMDDRRAS15_LSB				10
+#define CSR_ACSMDDRRAS15_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET15_LSB				11
+#define CSR_ACSMDDRCKESET15_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR15_LSB				12
+#define CSR_ACSMDDRCKECLR15_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD15_LSB			13
+#define CSR_ACSMSEQGATECMD15_MASK			BIT(13)
+#define CSR_ACSMSEQTERM15_LSB				14
+#define CSR_ACSMSEQTERM15_MASK				BIT(14)
+#define CSR_ACSMLP3CA315_LSB				15
+#define CSR_ACSMLP3CA315_MASK				BIT(15)
+/* CSR_ACSMSEQ0X16 */
+#define CSR_ACSMSEQ0X16_LSB				0
+#define CSR_ACSMSEQ0X16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY16_LSB				0
+#define CSR_ACSMMCLKDLY16_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE16_LSB				8
+#define CSR_ACSMDDRWE16_MASK				BIT(8)
+#define CSR_ACSMDDRCAS16_LSB				9
+#define CSR_ACSMDDRCAS16_MASK				BIT(9)
+#define CSR_ACSMDDRRAS16_LSB				10
+#define CSR_ACSMDDRRAS16_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET16_LSB				11
+#define CSR_ACSMDDRCKESET16_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR16_LSB				12
+#define CSR_ACSMDDRCKECLR16_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD16_LSB			13
+#define CSR_ACSMSEQGATECMD16_MASK			BIT(13)
+#define CSR_ACSMSEQTERM16_LSB				14
+#define CSR_ACSMSEQTERM16_MASK				BIT(14)
+#define CSR_ACSMLP3CA316_LSB				15
+#define CSR_ACSMLP3CA316_MASK				BIT(15)
+/* CSR_ACSMSEQ0X17 */
+#define CSR_ACSMSEQ0X17_LSB				0
+#define CSR_ACSMSEQ0X17_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY17_LSB				0
+#define CSR_ACSMMCLKDLY17_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE17_LSB				8
+#define CSR_ACSMDDRWE17_MASK				BIT(8)
+#define CSR_ACSMDDRCAS17_LSB				9
+#define CSR_ACSMDDRCAS17_MASK				BIT(9)
+#define CSR_ACSMDDRRAS17_LSB				10
+#define CSR_ACSMDDRRAS17_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET17_LSB				11
+#define CSR_ACSMDDRCKESET17_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR17_LSB				12
+#define CSR_ACSMDDRCKECLR17_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD17_LSB			13
+#define CSR_ACSMSEQGATECMD17_MASK			BIT(13)
+#define CSR_ACSMSEQTERM17_LSB				14
+#define CSR_ACSMSEQTERM17_MASK				BIT(14)
+#define CSR_ACSMLP3CA317_LSB				15
+#define CSR_ACSMLP3CA317_MASK				BIT(15)
+/* CSR_ACSMSEQ0X18 */
+#define CSR_ACSMSEQ0X18_LSB				0
+#define CSR_ACSMSEQ0X18_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY18_LSB				0
+#define CSR_ACSMMCLKDLY18_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE18_LSB				8
+#define CSR_ACSMDDRWE18_MASK				BIT(8)
+#define CSR_ACSMDDRCAS18_LSB				9
+#define CSR_ACSMDDRCAS18_MASK				BIT(9)
+#define CSR_ACSMDDRRAS18_LSB				10
+#define CSR_ACSMDDRRAS18_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET18_LSB				11
+#define CSR_ACSMDDRCKESET18_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR18_LSB				12
+#define CSR_ACSMDDRCKECLR18_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD18_LSB			13
+#define CSR_ACSMSEQGATECMD18_MASK			BIT(13)
+#define CSR_ACSMSEQTERM18_LSB				14
+#define CSR_ACSMSEQTERM18_MASK				BIT(14)
+#define CSR_ACSMLP3CA318_LSB				15
+#define CSR_ACSMLP3CA318_MASK				BIT(15)
+/* CSR_ACSMSEQ0X19 */
+#define CSR_ACSMSEQ0X19_LSB				0
+#define CSR_ACSMSEQ0X19_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY19_LSB				0
+#define CSR_ACSMMCLKDLY19_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE19_LSB				8
+#define CSR_ACSMDDRWE19_MASK				BIT(8)
+#define CSR_ACSMDDRCAS19_LSB				9
+#define CSR_ACSMDDRCAS19_MASK				BIT(9)
+#define CSR_ACSMDDRRAS19_LSB				10
+#define CSR_ACSMDDRRAS19_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET19_LSB				11
+#define CSR_ACSMDDRCKESET19_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR19_LSB				12
+#define CSR_ACSMDDRCKECLR19_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD19_LSB			13
+#define CSR_ACSMSEQGATECMD19_MASK			BIT(13)
+#define CSR_ACSMSEQTERM19_LSB				14
+#define CSR_ACSMSEQTERM19_MASK				BIT(14)
+#define CSR_ACSMLP3CA319_LSB				15
+#define CSR_ACSMLP3CA319_MASK				BIT(15)
+/* CSR_ACSMSEQ0X20 */
+#define CSR_ACSMSEQ0X20_LSB				0
+#define CSR_ACSMSEQ0X20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY20_LSB				0
+#define CSR_ACSMMCLKDLY20_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE20_LSB				8
+#define CSR_ACSMDDRWE20_MASK				BIT(8)
+#define CSR_ACSMDDRCAS20_LSB				9
+#define CSR_ACSMDDRCAS20_MASK				BIT(9)
+#define CSR_ACSMDDRRAS20_LSB				10
+#define CSR_ACSMDDRRAS20_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET20_LSB				11
+#define CSR_ACSMDDRCKESET20_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR20_LSB				12
+#define CSR_ACSMDDRCKECLR20_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD20_LSB			13
+#define CSR_ACSMSEQGATECMD20_MASK			BIT(13)
+#define CSR_ACSMSEQTERM20_LSB				14
+#define CSR_ACSMSEQTERM20_MASK				BIT(14)
+#define CSR_ACSMLP3CA320_LSB				15
+#define CSR_ACSMLP3CA320_MASK				BIT(15)
+/* CSR_ACSMSEQ0X21 */
+#define CSR_ACSMSEQ0X21_LSB				0
+#define CSR_ACSMSEQ0X21_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY21_LSB				0
+#define CSR_ACSMMCLKDLY21_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE21_LSB				8
+#define CSR_ACSMDDRWE21_MASK				BIT(8)
+#define CSR_ACSMDDRCAS21_LSB				9
+#define CSR_ACSMDDRCAS21_MASK				BIT(9)
+#define CSR_ACSMDDRRAS21_LSB				10
+#define CSR_ACSMDDRRAS21_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET21_LSB				11
+#define CSR_ACSMDDRCKESET21_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR21_LSB				12
+#define CSR_ACSMDDRCKECLR21_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD21_LSB			13
+#define CSR_ACSMSEQGATECMD21_MASK			BIT(13)
+#define CSR_ACSMSEQTERM21_LSB				14
+#define CSR_ACSMSEQTERM21_MASK				BIT(14)
+#define CSR_ACSMLP3CA321_LSB				15
+#define CSR_ACSMLP3CA321_MASK				BIT(15)
+/* CSR_ACSMSEQ0X22 */
+#define CSR_ACSMSEQ0X22_LSB				0
+#define CSR_ACSMSEQ0X22_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY22_LSB				0
+#define CSR_ACSMMCLKDLY22_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE22_LSB				8
+#define CSR_ACSMDDRWE22_MASK				BIT(8)
+#define CSR_ACSMDDRCAS22_LSB				9
+#define CSR_ACSMDDRCAS22_MASK				BIT(9)
+#define CSR_ACSMDDRRAS22_LSB				10
+#define CSR_ACSMDDRRAS22_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET22_LSB				11
+#define CSR_ACSMDDRCKESET22_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR22_LSB				12
+#define CSR_ACSMDDRCKECLR22_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD22_LSB			13
+#define CSR_ACSMSEQGATECMD22_MASK			BIT(13)
+#define CSR_ACSMSEQTERM22_LSB				14
+#define CSR_ACSMSEQTERM22_MASK				BIT(14)
+#define CSR_ACSMLP3CA322_LSB				15
+#define CSR_ACSMLP3CA322_MASK				BIT(15)
+/* CSR_ACSMSEQ0X23 */
+#define CSR_ACSMSEQ0X23_LSB				0
+#define CSR_ACSMSEQ0X23_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY23_LSB				0
+#define CSR_ACSMMCLKDLY23_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE23_LSB				8
+#define CSR_ACSMDDRWE23_MASK				BIT(8)
+#define CSR_ACSMDDRCAS23_LSB				9
+#define CSR_ACSMDDRCAS23_MASK				BIT(9)
+#define CSR_ACSMDDRRAS23_LSB				10
+#define CSR_ACSMDDRRAS23_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET23_LSB				11
+#define CSR_ACSMDDRCKESET23_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR23_LSB				12
+#define CSR_ACSMDDRCKECLR23_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD23_LSB			13
+#define CSR_ACSMSEQGATECMD23_MASK			BIT(13)
+#define CSR_ACSMSEQTERM23_LSB				14
+#define CSR_ACSMSEQTERM23_MASK				BIT(14)
+#define CSR_ACSMLP3CA323_LSB				15
+#define CSR_ACSMLP3CA323_MASK				BIT(15)
+/* CSR_ACSMSEQ0X24 */
+#define CSR_ACSMSEQ0X24_LSB				0
+#define CSR_ACSMSEQ0X24_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY24_LSB				0
+#define CSR_ACSMMCLKDLY24_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE24_LSB				8
+#define CSR_ACSMDDRWE24_MASK				BIT(8)
+#define CSR_ACSMDDRCAS24_LSB				9
+#define CSR_ACSMDDRCAS24_MASK				BIT(9)
+#define CSR_ACSMDDRRAS24_LSB				10
+#define CSR_ACSMDDRRAS24_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET24_LSB				11
+#define CSR_ACSMDDRCKESET24_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR24_LSB				12
+#define CSR_ACSMDDRCKECLR24_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD24_LSB			13
+#define CSR_ACSMSEQGATECMD24_MASK			BIT(13)
+#define CSR_ACSMSEQTERM24_LSB				14
+#define CSR_ACSMSEQTERM24_MASK				BIT(14)
+#define CSR_ACSMLP3CA324_LSB				15
+#define CSR_ACSMLP3CA324_MASK				BIT(15)
+/* CSR_ACSMSEQ0X25 */
+#define CSR_ACSMSEQ0X25_LSB				0
+#define CSR_ACSMSEQ0X25_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY25_LSB				0
+#define CSR_ACSMMCLKDLY25_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE25_LSB				8
+#define CSR_ACSMDDRWE25_MASK				BIT(8)
+#define CSR_ACSMDDRCAS25_LSB				9
+#define CSR_ACSMDDRCAS25_MASK				BIT(9)
+#define CSR_ACSMDDRRAS25_LSB				10
+#define CSR_ACSMDDRRAS25_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET25_LSB				11
+#define CSR_ACSMDDRCKESET25_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR25_LSB				12
+#define CSR_ACSMDDRCKECLR25_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD25_LSB			13
+#define CSR_ACSMSEQGATECMD25_MASK			BIT(13)
+#define CSR_ACSMSEQTERM25_LSB				14
+#define CSR_ACSMSEQTERM25_MASK				BIT(14)
+#define CSR_ACSMLP3CA325_LSB				15
+#define CSR_ACSMLP3CA325_MASK				BIT(15)
+/* CSR_ACSMSEQ0X26 */
+#define CSR_ACSMSEQ0X26_LSB				0
+#define CSR_ACSMSEQ0X26_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY26_LSB				0
+#define CSR_ACSMMCLKDLY26_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE26_LSB				8
+#define CSR_ACSMDDRWE26_MASK				BIT(8)
+#define CSR_ACSMDDRCAS26_LSB				9
+#define CSR_ACSMDDRCAS26_MASK				BIT(9)
+#define CSR_ACSMDDRRAS26_LSB				10
+#define CSR_ACSMDDRRAS26_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET26_LSB				11
+#define CSR_ACSMDDRCKESET26_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR26_LSB				12
+#define CSR_ACSMDDRCKECLR26_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD26_LSB			13
+#define CSR_ACSMSEQGATECMD26_MASK			BIT(13)
+#define CSR_ACSMSEQTERM26_LSB				14
+#define CSR_ACSMSEQTERM26_MASK				BIT(14)
+#define CSR_ACSMLP3CA326_LSB				15
+#define CSR_ACSMLP3CA326_MASK				BIT(15)
+/* CSR_ACSMSEQ0X27 */
+#define CSR_ACSMSEQ0X27_LSB				0
+#define CSR_ACSMSEQ0X27_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY27_LSB				0
+#define CSR_ACSMMCLKDLY27_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE27_LSB				8
+#define CSR_ACSMDDRWE27_MASK				BIT(8)
+#define CSR_ACSMDDRCAS27_LSB				9
+#define CSR_ACSMDDRCAS27_MASK				BIT(9)
+#define CSR_ACSMDDRRAS27_LSB				10
+#define CSR_ACSMDDRRAS27_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET27_LSB				11
+#define CSR_ACSMDDRCKESET27_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR27_LSB				12
+#define CSR_ACSMDDRCKECLR27_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD27_LSB			13
+#define CSR_ACSMSEQGATECMD27_MASK			BIT(13)
+#define CSR_ACSMSEQTERM27_LSB				14
+#define CSR_ACSMSEQTERM27_MASK				BIT(14)
+#define CSR_ACSMLP3CA327_LSB				15
+#define CSR_ACSMLP3CA327_MASK				BIT(15)
+/* CSR_ACSMSEQ0X28 */
+#define CSR_ACSMSEQ0X28_LSB				0
+#define CSR_ACSMSEQ0X28_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY28_LSB				0
+#define CSR_ACSMMCLKDLY28_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE28_LSB				8
+#define CSR_ACSMDDRWE28_MASK				BIT(8)
+#define CSR_ACSMDDRCAS28_LSB				9
+#define CSR_ACSMDDRCAS28_MASK				BIT(9)
+#define CSR_ACSMDDRRAS28_LSB				10
+#define CSR_ACSMDDRRAS28_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET28_LSB				11
+#define CSR_ACSMDDRCKESET28_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR28_LSB				12
+#define CSR_ACSMDDRCKECLR28_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD28_LSB			13
+#define CSR_ACSMSEQGATECMD28_MASK			BIT(13)
+#define CSR_ACSMSEQTERM28_LSB				14
+#define CSR_ACSMSEQTERM28_MASK				BIT(14)
+#define CSR_ACSMLP3CA328_LSB				15
+#define CSR_ACSMLP3CA328_MASK				BIT(15)
+/* CSR_ACSMSEQ0X29 */
+#define CSR_ACSMSEQ0X29_LSB				0
+#define CSR_ACSMSEQ0X29_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY29_LSB				0
+#define CSR_ACSMMCLKDLY29_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE29_LSB				8
+#define CSR_ACSMDDRWE29_MASK				BIT(8)
+#define CSR_ACSMDDRCAS29_LSB				9
+#define CSR_ACSMDDRCAS29_MASK				BIT(9)
+#define CSR_ACSMDDRRAS29_LSB				10
+#define CSR_ACSMDDRRAS29_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET29_LSB				11
+#define CSR_ACSMDDRCKESET29_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR29_LSB				12
+#define CSR_ACSMDDRCKECLR29_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD29_LSB			13
+#define CSR_ACSMSEQGATECMD29_MASK			BIT(13)
+#define CSR_ACSMSEQTERM29_LSB				14
+#define CSR_ACSMSEQTERM29_MASK				BIT(14)
+#define CSR_ACSMLP3CA329_LSB				15
+#define CSR_ACSMLP3CA329_MASK				BIT(15)
+/* CSR_ACSMSEQ0X30 */
+#define CSR_ACSMSEQ0X30_LSB				0
+#define CSR_ACSMSEQ0X30_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY30_LSB				0
+#define CSR_ACSMMCLKDLY30_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE30_LSB				8
+#define CSR_ACSMDDRWE30_MASK				BIT(8)
+#define CSR_ACSMDDRCAS30_LSB				9
+#define CSR_ACSMDDRCAS30_MASK				BIT(9)
+#define CSR_ACSMDDRRAS30_LSB				10
+#define CSR_ACSMDDRRAS30_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET30_LSB				11
+#define CSR_ACSMDDRCKESET30_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR30_LSB				12
+#define CSR_ACSMDDRCKECLR30_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD30_LSB			13
+#define CSR_ACSMSEQGATECMD30_MASK			BIT(13)
+#define CSR_ACSMSEQTERM30_LSB				14
+#define CSR_ACSMSEQTERM30_MASK				BIT(14)
+#define CSR_ACSMLP3CA330_LSB				15
+#define CSR_ACSMLP3CA330_MASK				BIT(15)
+/* CSR_ACSMSEQ0X31 */
+#define CSR_ACSMSEQ0X31_LSB				0
+#define CSR_ACSMSEQ0X31_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY31_LSB				0
+#define CSR_ACSMMCLKDLY31_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE31_LSB				8
+#define CSR_ACSMDDRWE31_MASK				BIT(8)
+#define CSR_ACSMDDRCAS31_LSB				9
+#define CSR_ACSMDDRCAS31_MASK				BIT(9)
+#define CSR_ACSMDDRRAS31_LSB				10
+#define CSR_ACSMDDRRAS31_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET31_LSB				11
+#define CSR_ACSMDDRCKESET31_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR31_LSB				12
+#define CSR_ACSMDDRCKECLR31_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD31_LSB			13
+#define CSR_ACSMSEQGATECMD31_MASK			BIT(13)
+#define CSR_ACSMSEQTERM31_LSB				14
+#define CSR_ACSMSEQTERM31_MASK				BIT(14)
+#define CSR_ACSMLP3CA331_LSB				15
+#define CSR_ACSMLP3CA331_MASK				BIT(15)
+/* CSR_ACSMSEQ1X0 */
+#define CSR_ACSMSEQ1X0_LSB				0
+#define CSR_ACSMSEQ1X0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS0_LSB				0
+#define CSR_ACSMDDRCS0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN0_LSB				8
+#define CSR_ACSMSAVEGEN0_MASK				BIT(8)
+#define CSR_ACSMLOADCHK0_LSB				9
+#define CSR_ACSMLOADCHK0_MASK				BIT(9)
+#define CSR_ACSMNORXENB0_LSB				10
+#define CSR_ACSMNORXENB0_MASK				BIT(10)
+#define CSR_ACSMNORXVAL0_LSB				11
+#define CSR_ACSMNORXVAL0_MASK				BIT(11)
+#define CSR_ACSMDDRBNK0_LSB				12
+#define CSR_ACSMDDRBNK0_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X1 */
+#define CSR_ACSMSEQ1X1_LSB				0
+#define CSR_ACSMSEQ1X1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS1_LSB				0
+#define CSR_ACSMDDRCS1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN1_LSB				8
+#define CSR_ACSMSAVEGEN1_MASK				BIT(8)
+#define CSR_ACSMLOADCHK1_LSB				9
+#define CSR_ACSMLOADCHK1_MASK				BIT(9)
+#define CSR_ACSMNORXENB1_LSB				10
+#define CSR_ACSMNORXENB1_MASK				BIT(10)
+#define CSR_ACSMNORXVAL1_LSB				11
+#define CSR_ACSMNORXVAL1_MASK				BIT(11)
+#define CSR_ACSMDDRBNK1_LSB				12
+#define CSR_ACSMDDRBNK1_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X2 */
+#define CSR_ACSMSEQ1X2_LSB				0
+#define CSR_ACSMSEQ1X2_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS2_LSB				0
+#define CSR_ACSMDDRCS2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN2_LSB				8
+#define CSR_ACSMSAVEGEN2_MASK				BIT(8)
+#define CSR_ACSMLOADCHK2_LSB				9
+#define CSR_ACSMLOADCHK2_MASK				BIT(9)
+#define CSR_ACSMNORXENB2_LSB				10
+#define CSR_ACSMNORXENB2_MASK				BIT(10)
+#define CSR_ACSMNORXVAL2_LSB				11
+#define CSR_ACSMNORXVAL2_MASK				BIT(11)
+#define CSR_ACSMDDRBNK2_LSB				12
+#define CSR_ACSMDDRBNK2_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X3 */
+#define CSR_ACSMSEQ1X3_LSB				0
+#define CSR_ACSMSEQ1X3_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS3_LSB				0
+#define CSR_ACSMDDRCS3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN3_LSB				8
+#define CSR_ACSMSAVEGEN3_MASK				BIT(8)
+#define CSR_ACSMLOADCHK3_LSB				9
+#define CSR_ACSMLOADCHK3_MASK				BIT(9)
+#define CSR_ACSMNORXENB3_LSB				10
+#define CSR_ACSMNORXENB3_MASK				BIT(10)
+#define CSR_ACSMNORXVAL3_LSB				11
+#define CSR_ACSMNORXVAL3_MASK				BIT(11)
+#define CSR_ACSMDDRBNK3_LSB				12
+#define CSR_ACSMDDRBNK3_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X4 */
+#define CSR_ACSMSEQ1X4_LSB				0
+#define CSR_ACSMSEQ1X4_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS4_LSB				0
+#define CSR_ACSMDDRCS4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN4_LSB				8
+#define CSR_ACSMSAVEGEN4_MASK				BIT(8)
+#define CSR_ACSMLOADCHK4_LSB				9
+#define CSR_ACSMLOADCHK4_MASK				BIT(9)
+#define CSR_ACSMNORXENB4_LSB				10
+#define CSR_ACSMNORXENB4_MASK				BIT(10)
+#define CSR_ACSMNORXVAL4_LSB				11
+#define CSR_ACSMNORXVAL4_MASK				BIT(11)
+#define CSR_ACSMDDRBNK4_LSB				12
+#define CSR_ACSMDDRBNK4_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X5 */
+#define CSR_ACSMSEQ1X5_LSB				0
+#define CSR_ACSMSEQ1X5_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS5_LSB				0
+#define CSR_ACSMDDRCS5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN5_LSB				8
+#define CSR_ACSMSAVEGEN5_MASK				BIT(8)
+#define CSR_ACSMLOADCHK5_LSB				9
+#define CSR_ACSMLOADCHK5_MASK				BIT(9)
+#define CSR_ACSMNORXENB5_LSB				10
+#define CSR_ACSMNORXENB5_MASK				BIT(10)
+#define CSR_ACSMNORXVAL5_LSB				11
+#define CSR_ACSMNORXVAL5_MASK				BIT(11)
+#define CSR_ACSMDDRBNK5_LSB				12
+#define CSR_ACSMDDRBNK5_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X6 */
+#define CSR_ACSMSEQ1X6_LSB				0
+#define CSR_ACSMSEQ1X6_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS6_LSB				0
+#define CSR_ACSMDDRCS6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN6_LSB				8
+#define CSR_ACSMSAVEGEN6_MASK				BIT(8)
+#define CSR_ACSMLOADCHK6_LSB				9
+#define CSR_ACSMLOADCHK6_MASK				BIT(9)
+#define CSR_ACSMNORXENB6_LSB				10
+#define CSR_ACSMNORXENB6_MASK				BIT(10)
+#define CSR_ACSMNORXVAL6_LSB				11
+#define CSR_ACSMNORXVAL6_MASK				BIT(11)
+#define CSR_ACSMDDRBNK6_LSB				12
+#define CSR_ACSMDDRBNK6_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X7 */
+#define CSR_ACSMSEQ1X7_LSB				0
+#define CSR_ACSMSEQ1X7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS7_LSB				0
+#define CSR_ACSMDDRCS7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN7_LSB				8
+#define CSR_ACSMSAVEGEN7_MASK				BIT(8)
+#define CSR_ACSMLOADCHK7_LSB				9
+#define CSR_ACSMLOADCHK7_MASK				BIT(9)
+#define CSR_ACSMNORXENB7_LSB				10
+#define CSR_ACSMNORXENB7_MASK				BIT(10)
+#define CSR_ACSMNORXVAL7_LSB				11
+#define CSR_ACSMNORXVAL7_MASK				BIT(11)
+#define CSR_ACSMDDRBNK7_LSB				12
+#define CSR_ACSMDDRBNK7_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X8 */
+#define CSR_ACSMSEQ1X8_LSB				0
+#define CSR_ACSMSEQ1X8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS8_LSB				0
+#define CSR_ACSMDDRCS8_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN8_LSB				8
+#define CSR_ACSMSAVEGEN8_MASK				BIT(8)
+#define CSR_ACSMLOADCHK8_LSB				9
+#define CSR_ACSMLOADCHK8_MASK				BIT(9)
+#define CSR_ACSMNORXENB8_LSB				10
+#define CSR_ACSMNORXENB8_MASK				BIT(10)
+#define CSR_ACSMNORXVAL8_LSB				11
+#define CSR_ACSMNORXVAL8_MASK				BIT(11)
+#define CSR_ACSMDDRBNK8_LSB				12
+#define CSR_ACSMDDRBNK8_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X9 */
+#define CSR_ACSMSEQ1X9_LSB				0
+#define CSR_ACSMSEQ1X9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS9_LSB				0
+#define CSR_ACSMDDRCS9_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN9_LSB				8
+#define CSR_ACSMSAVEGEN9_MASK				BIT(8)
+#define CSR_ACSMLOADCHK9_LSB				9
+#define CSR_ACSMLOADCHK9_MASK				BIT(9)
+#define CSR_ACSMNORXENB9_LSB				10
+#define CSR_ACSMNORXENB9_MASK				BIT(10)
+#define CSR_ACSMNORXVAL9_LSB				11
+#define CSR_ACSMNORXVAL9_MASK				BIT(11)
+#define CSR_ACSMDDRBNK9_LSB				12
+#define CSR_ACSMDDRBNK9_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X10 */
+#define CSR_ACSMSEQ1X10_LSB				0
+#define CSR_ACSMSEQ1X10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS10_LSB				0
+#define CSR_ACSMDDRCS10_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN10_LSB				8
+#define CSR_ACSMSAVEGEN10_MASK				BIT(8)
+#define CSR_ACSMLOADCHK10_LSB				9
+#define CSR_ACSMLOADCHK10_MASK				BIT(9)
+#define CSR_ACSMNORXENB10_LSB				10
+#define CSR_ACSMNORXENB10_MASK				BIT(10)
+#define CSR_ACSMNORXVAL10_LSB				11
+#define CSR_ACSMNORXVAL10_MASK				BIT(11)
+#define CSR_ACSMDDRBNK10_LSB				12
+#define CSR_ACSMDDRBNK10_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X11 */
+#define CSR_ACSMSEQ1X11_LSB				0
+#define CSR_ACSMSEQ1X11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS11_LSB				0
+#define CSR_ACSMDDRCS11_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN11_LSB				8
+#define CSR_ACSMSAVEGEN11_MASK				BIT(8)
+#define CSR_ACSMLOADCHK11_LSB				9
+#define CSR_ACSMLOADCHK11_MASK				BIT(9)
+#define CSR_ACSMNORXENB11_LSB				10
+#define CSR_ACSMNORXENB11_MASK				BIT(10)
+#define CSR_ACSMNORXVAL11_LSB				11
+#define CSR_ACSMNORXVAL11_MASK				BIT(11)
+#define CSR_ACSMDDRBNK11_LSB				12
+#define CSR_ACSMDDRBNK11_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X12 */
+#define CSR_ACSMSEQ1X12_LSB				0
+#define CSR_ACSMSEQ1X12_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS12_LSB				0
+#define CSR_ACSMDDRCS12_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN12_LSB				8
+#define CSR_ACSMSAVEGEN12_MASK				BIT(8)
+#define CSR_ACSMLOADCHK12_LSB				9
+#define CSR_ACSMLOADCHK12_MASK				BIT(9)
+#define CSR_ACSMNORXENB12_LSB				10
+#define CSR_ACSMNORXENB12_MASK				BIT(10)
+#define CSR_ACSMNORXVAL12_LSB				11
+#define CSR_ACSMNORXVAL12_MASK				BIT(11)
+#define CSR_ACSMDDRBNK12_LSB				12
+#define CSR_ACSMDDRBNK12_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X13 */
+#define CSR_ACSMSEQ1X13_LSB				0
+#define CSR_ACSMSEQ1X13_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS13_LSB				0
+#define CSR_ACSMDDRCS13_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN13_LSB				8
+#define CSR_ACSMSAVEGEN13_MASK				BIT(8)
+#define CSR_ACSMLOADCHK13_LSB				9
+#define CSR_ACSMLOADCHK13_MASK				BIT(9)
+#define CSR_ACSMNORXENB13_LSB				10
+#define CSR_ACSMNORXENB13_MASK				BIT(10)
+#define CSR_ACSMNORXVAL13_LSB				11
+#define CSR_ACSMNORXVAL13_MASK				BIT(11)
+#define CSR_ACSMDDRBNK13_LSB				12
+#define CSR_ACSMDDRBNK13_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X14 */
+#define CSR_ACSMSEQ1X14_LSB				0
+#define CSR_ACSMSEQ1X14_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS14_LSB				0
+#define CSR_ACSMDDRCS14_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN14_LSB				8
+#define CSR_ACSMSAVEGEN14_MASK				BIT(8)
+#define CSR_ACSMLOADCHK14_LSB				9
+#define CSR_ACSMLOADCHK14_MASK				BIT(9)
+#define CSR_ACSMNORXENB14_LSB				10
+#define CSR_ACSMNORXENB14_MASK				BIT(10)
+#define CSR_ACSMNORXVAL14_LSB				11
+#define CSR_ACSMNORXVAL14_MASK				BIT(11)
+#define CSR_ACSMDDRBNK14_LSB				12
+#define CSR_ACSMDDRBNK14_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X15 */
+#define CSR_ACSMSEQ1X15_LSB				0
+#define CSR_ACSMSEQ1X15_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS15_LSB				0
+#define CSR_ACSMDDRCS15_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN15_LSB				8
+#define CSR_ACSMSAVEGEN15_MASK				BIT(8)
+#define CSR_ACSMLOADCHK15_LSB				9
+#define CSR_ACSMLOADCHK15_MASK				BIT(9)
+#define CSR_ACSMNORXENB15_LSB				10
+#define CSR_ACSMNORXENB15_MASK				BIT(10)
+#define CSR_ACSMNORXVAL15_LSB				11
+#define CSR_ACSMNORXVAL15_MASK				BIT(11)
+#define CSR_ACSMDDRBNK15_LSB				12
+#define CSR_ACSMDDRBNK15_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X16 */
+#define CSR_ACSMSEQ1X16_LSB				0
+#define CSR_ACSMSEQ1X16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS16_LSB				0
+#define CSR_ACSMDDRCS16_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN16_LSB				8
+#define CSR_ACSMSAVEGEN16_MASK				BIT(8)
+#define CSR_ACSMLOADCHK16_LSB				9
+#define CSR_ACSMLOADCHK16_MASK				BIT(9)
+#define CSR_ACSMNORXENB16_LSB				10
+#define CSR_ACSMNORXENB16_MASK				BIT(10)
+#define CSR_ACSMNORXVAL16_LSB				11
+#define CSR_ACSMNORXVAL16_MASK				BIT(11)
+#define CSR_ACSMDDRBNK16_LSB				12
+#define CSR_ACSMDDRBNK16_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X17 */
+#define CSR_ACSMSEQ1X17_LSB				0
+#define CSR_ACSMSEQ1X17_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS17_LSB				0
+#define CSR_ACSMDDRCS17_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN17_LSB				8
+#define CSR_ACSMSAVEGEN17_MASK				BIT(8)
+#define CSR_ACSMLOADCHK17_LSB				9
+#define CSR_ACSMLOADCHK17_MASK				BIT(9)
+#define CSR_ACSMNORXENB17_LSB				10
+#define CSR_ACSMNORXENB17_MASK				BIT(10)
+#define CSR_ACSMNORXVAL17_LSB				11
+#define CSR_ACSMNORXVAL17_MASK				BIT(11)
+#define CSR_ACSMDDRBNK17_LSB				12
+#define CSR_ACSMDDRBNK17_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X18 */
+#define CSR_ACSMSEQ1X18_LSB				0
+#define CSR_ACSMSEQ1X18_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS18_LSB				0
+#define CSR_ACSMDDRCS18_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN18_LSB				8
+#define CSR_ACSMSAVEGEN18_MASK				BIT(8)
+#define CSR_ACSMLOADCHK18_LSB				9
+#define CSR_ACSMLOADCHK18_MASK				BIT(9)
+#define CSR_ACSMNORXENB18_LSB				10
+#define CSR_ACSMNORXENB18_MASK				BIT(10)
+#define CSR_ACSMNORXVAL18_LSB				11
+#define CSR_ACSMNORXVAL18_MASK				BIT(11)
+#define CSR_ACSMDDRBNK18_LSB				12
+#define CSR_ACSMDDRBNK18_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X19 */
+#define CSR_ACSMSEQ1X19_LSB				0
+#define CSR_ACSMSEQ1X19_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS19_LSB				0
+#define CSR_ACSMDDRCS19_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN19_LSB				8
+#define CSR_ACSMSAVEGEN19_MASK				BIT(8)
+#define CSR_ACSMLOADCHK19_LSB				9
+#define CSR_ACSMLOADCHK19_MASK				BIT(9)
+#define CSR_ACSMNORXENB19_LSB				10
+#define CSR_ACSMNORXENB19_MASK				BIT(10)
+#define CSR_ACSMNORXVAL19_LSB				11
+#define CSR_ACSMNORXVAL19_MASK				BIT(11)
+#define CSR_ACSMDDRBNK19_LSB				12
+#define CSR_ACSMDDRBNK19_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X20 */
+#define CSR_ACSMSEQ1X20_LSB				0
+#define CSR_ACSMSEQ1X20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS20_LSB				0
+#define CSR_ACSMDDRCS20_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN20_LSB				8
+#define CSR_ACSMSAVEGEN20_MASK				BIT(8)
+#define CSR_ACSMLOADCHK20_LSB				9
+#define CSR_ACSMLOADCHK20_MASK				BIT(9)
+#define CSR_ACSMNORXENB20_LSB				10
+#define CSR_ACSMNORXENB20_MASK				BIT(10)
+#define CSR_ACSMNORXVAL20_LSB				11
+#define CSR_ACSMNORXVAL20_MASK				BIT(11)
+#define CSR_ACSMDDRBNK20_LSB				12
+#define CSR_ACSMDDRBNK20_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X21 */
+#define CSR_ACSMSEQ1X21_LSB				0
+#define CSR_ACSMSEQ1X21_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS21_LSB				0
+#define CSR_ACSMDDRCS21_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN21_LSB				8
+#define CSR_ACSMSAVEGEN21_MASK				BIT(8)
+#define CSR_ACSMLOADCHK21_LSB				9
+#define CSR_ACSMLOADCHK21_MASK				BIT(9)
+#define CSR_ACSMNORXENB21_LSB				10
+#define CSR_ACSMNORXENB21_MASK				BIT(10)
+#define CSR_ACSMNORXVAL21_LSB				11
+#define CSR_ACSMNORXVAL21_MASK				BIT(11)
+#define CSR_ACSMDDRBNK21_LSB				12
+#define CSR_ACSMDDRBNK21_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X22 */
+#define CSR_ACSMSEQ1X22_LSB				0
+#define CSR_ACSMSEQ1X22_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS22_LSB				0
+#define CSR_ACSMDDRCS22_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN22_LSB				8
+#define CSR_ACSMSAVEGEN22_MASK				BIT(8)
+#define CSR_ACSMLOADCHK22_LSB				9
+#define CSR_ACSMLOADCHK22_MASK				BIT(9)
+#define CSR_ACSMNORXENB22_LSB				10
+#define CSR_ACSMNORXENB22_MASK				BIT(10)
+#define CSR_ACSMNORXVAL22_LSB				11
+#define CSR_ACSMNORXVAL22_MASK				BIT(11)
+#define CSR_ACSMDDRBNK22_LSB				12
+#define CSR_ACSMDDRBNK22_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X23 */
+#define CSR_ACSMSEQ1X23_LSB				0
+#define CSR_ACSMSEQ1X23_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS23_LSB				0
+#define CSR_ACSMDDRCS23_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN23_LSB				8
+#define CSR_ACSMSAVEGEN23_MASK				BIT(8)
+#define CSR_ACSMLOADCHK23_LSB				9
+#define CSR_ACSMLOADCHK23_MASK				BIT(9)
+#define CSR_ACSMNORXENB23_LSB				10
+#define CSR_ACSMNORXENB23_MASK				BIT(10)
+#define CSR_ACSMNORXVAL23_LSB				11
+#define CSR_ACSMNORXVAL23_MASK				BIT(11)
+#define CSR_ACSMDDRBNK23_LSB				12
+#define CSR_ACSMDDRBNK23_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X24 */
+#define CSR_ACSMSEQ1X24_LSB				0
+#define CSR_ACSMSEQ1X24_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS24_LSB				0
+#define CSR_ACSMDDRCS24_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN24_LSB				8
+#define CSR_ACSMSAVEGEN24_MASK				BIT(8)
+#define CSR_ACSMLOADCHK24_LSB				9
+#define CSR_ACSMLOADCHK24_MASK				BIT(9)
+#define CSR_ACSMNORXENB24_LSB				10
+#define CSR_ACSMNORXENB24_MASK				BIT(10)
+#define CSR_ACSMNORXVAL24_LSB				11
+#define CSR_ACSMNORXVAL24_MASK				BIT(11)
+#define CSR_ACSMDDRBNK24_LSB				12
+#define CSR_ACSMDDRBNK24_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X25 */
+#define CSR_ACSMSEQ1X25_LSB				0
+#define CSR_ACSMSEQ1X25_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS25_LSB				0
+#define CSR_ACSMDDRCS25_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN25_LSB				8
+#define CSR_ACSMSAVEGEN25_MASK				BIT(8)
+#define CSR_ACSMLOADCHK25_LSB				9
+#define CSR_ACSMLOADCHK25_MASK				BIT(9)
+#define CSR_ACSMNORXENB25_LSB				10
+#define CSR_ACSMNORXENB25_MASK				BIT(10)
+#define CSR_ACSMNORXVAL25_LSB				11
+#define CSR_ACSMNORXVAL25_MASK				BIT(11)
+#define CSR_ACSMDDRBNK25_LSB				12
+#define CSR_ACSMDDRBNK25_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X26 */
+#define CSR_ACSMSEQ1X26_LSB				0
+#define CSR_ACSMSEQ1X26_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS26_LSB				0
+#define CSR_ACSMDDRCS26_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN26_LSB				8
+#define CSR_ACSMSAVEGEN26_MASK				BIT(8)
+#define CSR_ACSMLOADCHK26_LSB				9
+#define CSR_ACSMLOADCHK26_MASK				BIT(9)
+#define CSR_ACSMNORXENB26_LSB				10
+#define CSR_ACSMNORXENB26_MASK				BIT(10)
+#define CSR_ACSMNORXVAL26_LSB				11
+#define CSR_ACSMNORXVAL26_MASK				BIT(11)
+#define CSR_ACSMDDRBNK26_LSB				12
+#define CSR_ACSMDDRBNK26_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X27 */
+#define CSR_ACSMSEQ1X27_LSB				0
+#define CSR_ACSMSEQ1X27_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS27_LSB				0
+#define CSR_ACSMDDRCS27_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN27_LSB				8
+#define CSR_ACSMSAVEGEN27_MASK				BIT(8)
+#define CSR_ACSMLOADCHK27_LSB				9
+#define CSR_ACSMLOADCHK27_MASK				BIT(9)
+#define CSR_ACSMNORXENB27_LSB				10
+#define CSR_ACSMNORXENB27_MASK				BIT(10)
+#define CSR_ACSMNORXVAL27_LSB				11
+#define CSR_ACSMNORXVAL27_MASK				BIT(11)
+#define CSR_ACSMDDRBNK27_LSB				12
+#define CSR_ACSMDDRBNK27_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X28 */
+#define CSR_ACSMSEQ1X28_LSB				0
+#define CSR_ACSMSEQ1X28_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS28_LSB				0
+#define CSR_ACSMDDRCS28_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN28_LSB				8
+#define CSR_ACSMSAVEGEN28_MASK				BIT(8)
+#define CSR_ACSMLOADCHK28_LSB				9
+#define CSR_ACSMLOADCHK28_MASK				BIT(9)
+#define CSR_ACSMNORXENB28_LSB				10
+#define CSR_ACSMNORXENB28_MASK				BIT(10)
+#define CSR_ACSMNORXVAL28_LSB				11
+#define CSR_ACSMNORXVAL28_MASK				BIT(11)
+#define CSR_ACSMDDRBNK28_LSB				12
+#define CSR_ACSMDDRBNK28_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X29 */
+#define CSR_ACSMSEQ1X29_LSB				0
+#define CSR_ACSMSEQ1X29_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS29_LSB				0
+#define CSR_ACSMDDRCS29_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN29_LSB				8
+#define CSR_ACSMSAVEGEN29_MASK				BIT(8)
+#define CSR_ACSMLOADCHK29_LSB				9
+#define CSR_ACSMLOADCHK29_MASK				BIT(9)
+#define CSR_ACSMNORXENB29_LSB				10
+#define CSR_ACSMNORXENB29_MASK				BIT(10)
+#define CSR_ACSMNORXVAL29_LSB				11
+#define CSR_ACSMNORXVAL29_MASK				BIT(11)
+#define CSR_ACSMDDRBNK29_LSB				12
+#define CSR_ACSMDDRBNK29_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X30 */
+#define CSR_ACSMSEQ1X30_LSB				0
+#define CSR_ACSMSEQ1X30_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS30_LSB				0
+#define CSR_ACSMDDRCS30_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN30_LSB				8
+#define CSR_ACSMSAVEGEN30_MASK				BIT(8)
+#define CSR_ACSMLOADCHK30_LSB				9
+#define CSR_ACSMLOADCHK30_MASK				BIT(9)
+#define CSR_ACSMNORXENB30_LSB				10
+#define CSR_ACSMNORXENB30_MASK				BIT(10)
+#define CSR_ACSMNORXVAL30_LSB				11
+#define CSR_ACSMNORXVAL30_MASK				BIT(11)
+#define CSR_ACSMDDRBNK30_LSB				12
+#define CSR_ACSMDDRBNK30_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X31 */
+#define CSR_ACSMSEQ1X31_LSB				0
+#define CSR_ACSMSEQ1X31_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS31_LSB				0
+#define CSR_ACSMDDRCS31_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN31_LSB				8
+#define CSR_ACSMSAVEGEN31_MASK				BIT(8)
+#define CSR_ACSMLOADCHK31_LSB				9
+#define CSR_ACSMLOADCHK31_MASK				BIT(9)
+#define CSR_ACSMNORXENB31_LSB				10
+#define CSR_ACSMNORXENB31_MASK				BIT(10)
+#define CSR_ACSMNORXVAL31_LSB				11
+#define CSR_ACSMNORXVAL31_MASK				BIT(11)
+#define CSR_ACSMDDRBNK31_LSB				12
+#define CSR_ACSMDDRBNK31_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ2X0 */
+#define CSR_ACSMSEQ2X0_LSB				0
+#define CSR_ACSMSEQ2X0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X0_LSB			0
+#define CSR_ACSMDDRADRX15X0X0_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X1 */
+#define CSR_ACSMSEQ2X1_LSB				0
+#define CSR_ACSMSEQ2X1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X1_LSB			0
+#define CSR_ACSMDDRADRX15X0X1_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X2 */
+#define CSR_ACSMSEQ2X2_LSB				0
+#define CSR_ACSMSEQ2X2_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X2_LSB			0
+#define CSR_ACSMDDRADRX15X0X2_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X3 */
+#define CSR_ACSMSEQ2X3_LSB				0
+#define CSR_ACSMSEQ2X3_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X3_LSB			0
+#define CSR_ACSMDDRADRX15X0X3_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X4 */
+#define CSR_ACSMSEQ2X4_LSB				0
+#define CSR_ACSMSEQ2X4_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X4_LSB			0
+#define CSR_ACSMDDRADRX15X0X4_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X5 */
+#define CSR_ACSMSEQ2X5_LSB				0
+#define CSR_ACSMSEQ2X5_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X5_LSB			0
+#define CSR_ACSMDDRADRX15X0X5_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X6 */
+#define CSR_ACSMSEQ2X6_LSB				0
+#define CSR_ACSMSEQ2X6_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X6_LSB			0
+#define CSR_ACSMDDRADRX15X0X6_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X7 */
+#define CSR_ACSMSEQ2X7_LSB				0
+#define CSR_ACSMSEQ2X7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X7_LSB			0
+#define CSR_ACSMDDRADRX15X0X7_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X8 */
+#define CSR_ACSMSEQ2X8_LSB				0
+#define CSR_ACSMSEQ2X8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X8_LSB			0
+#define CSR_ACSMDDRADRX15X0X8_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X9 */
+#define CSR_ACSMSEQ2X9_LSB				0
+#define CSR_ACSMSEQ2X9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X9_LSB			0
+#define CSR_ACSMDDRADRX15X0X9_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X10 */
+#define CSR_ACSMSEQ2X10_LSB				0
+#define CSR_ACSMSEQ2X10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X10_LSB			0
+#define CSR_ACSMDDRADRX15X0X10_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X11 */
+#define CSR_ACSMSEQ2X11_LSB				0
+#define CSR_ACSMSEQ2X11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X11_LSB			0
+#define CSR_ACSMDDRADRX15X0X11_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X12 */
+#define CSR_ACSMSEQ2X12_LSB				0
+#define CSR_ACSMSEQ2X12_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X12_LSB			0
+#define CSR_ACSMDDRADRX15X0X12_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X13 */
+#define CSR_ACSMSEQ2X13_LSB				0
+#define CSR_ACSMSEQ2X13_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X13_LSB			0
+#define CSR_ACSMDDRADRX15X0X13_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X14 */
+#define CSR_ACSMSEQ2X14_LSB				0
+#define CSR_ACSMSEQ2X14_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X14_LSB			0
+#define CSR_ACSMDDRADRX15X0X14_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X15 */
+#define CSR_ACSMSEQ2X15_LSB				0
+#define CSR_ACSMSEQ2X15_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X15_LSB			0
+#define CSR_ACSMDDRADRX15X0X15_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X16 */
+#define CSR_ACSMSEQ2X16_LSB				0
+#define CSR_ACSMSEQ2X16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X16_LSB			0
+#define CSR_ACSMDDRADRX15X0X16_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X17 */
+#define CSR_ACSMSEQ2X17_LSB				0
+#define CSR_ACSMSEQ2X17_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X17_LSB			0
+#define CSR_ACSMDDRADRX15X0X17_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X18 */
+#define CSR_ACSMSEQ2X18_LSB				0
+#define CSR_ACSMSEQ2X18_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X18_LSB			0
+#define CSR_ACSMDDRADRX15X0X18_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X19 */
+#define CSR_ACSMSEQ2X19_LSB				0
+#define CSR_ACSMSEQ2X19_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X19_LSB			0
+#define CSR_ACSMDDRADRX15X0X19_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X20 */
+#define CSR_ACSMSEQ2X20_LSB				0
+#define CSR_ACSMSEQ2X20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X20_LSB			0
+#define CSR_ACSMDDRADRX15X0X20_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X21 */
+#define CSR_ACSMSEQ2X21_LSB				0
+#define CSR_ACSMSEQ2X21_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X21_LSB			0
+#define CSR_ACSMDDRADRX15X0X21_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X22 */
+#define CSR_ACSMSEQ2X22_LSB				0
+#define CSR_ACSMSEQ2X22_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X22_LSB			0
+#define CSR_ACSMDDRADRX15X0X22_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X23 */
+#define CSR_ACSMSEQ2X23_LSB				0
+#define CSR_ACSMSEQ2X23_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X23_LSB			0
+#define CSR_ACSMDDRADRX15X0X23_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X24 */
+#define CSR_ACSMSEQ2X24_LSB				0
+#define CSR_ACSMSEQ2X24_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X24_LSB			0
+#define CSR_ACSMDDRADRX15X0X24_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X25 */
+#define CSR_ACSMSEQ2X25_LSB				0
+#define CSR_ACSMSEQ2X25_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X25_LSB			0
+#define CSR_ACSMDDRADRX15X0X25_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X26 */
+#define CSR_ACSMSEQ2X26_LSB				0
+#define CSR_ACSMSEQ2X26_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X26_LSB			0
+#define CSR_ACSMDDRADRX15X0X26_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X27 */
+#define CSR_ACSMSEQ2X27_LSB				0
+#define CSR_ACSMSEQ2X27_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X27_LSB			0
+#define CSR_ACSMDDRADRX15X0X27_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X28 */
+#define CSR_ACSMSEQ2X28_LSB				0
+#define CSR_ACSMSEQ2X28_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X28_LSB			0
+#define CSR_ACSMDDRADRX15X0X28_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X29 */
+#define CSR_ACSMSEQ2X29_LSB				0
+#define CSR_ACSMSEQ2X29_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X29_LSB			0
+#define CSR_ACSMDDRADRX15X0X29_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X30 */
+#define CSR_ACSMSEQ2X30_LSB				0
+#define CSR_ACSMSEQ2X30_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X30_LSB			0
+#define CSR_ACSMDDRADRX15X0X30_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X31 */
+#define CSR_ACSMSEQ2X31_LSB				0
+#define CSR_ACSMSEQ2X31_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X31_LSB			0
+#define CSR_ACSMDDRADRX15X0X31_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ3X0 */
+#define CSR_ACSMSEQ3X0_LSB				0
+#define CSR_ACSMSEQ3X0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT0_LSB				0
+#define CSR_ACSMCMDREPCNT0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV0_LSB				8
+#define CSR_ACSMADRADV0_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV0_LSB				10
+#define CSR_ACSMBNKADV0_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD0_LSB				12
+#define CSR_ACSMADRSELLOAD0_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD0_LSB				14
+#define CSR_ACSMBNKSELLOAD0_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE0_LSB				15
+#define CSR_ACSMLONGBUBBLE0_MASK			BIT(15)
+/* CSR_ACSMSEQ3X1 */
+#define CSR_ACSMSEQ3X1_LSB				0
+#define CSR_ACSMSEQ3X1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT1_LSB				0
+#define CSR_ACSMCMDREPCNT1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV1_LSB				8
+#define CSR_ACSMADRADV1_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV1_LSB				10
+#define CSR_ACSMBNKADV1_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD1_LSB				12
+#define CSR_ACSMADRSELLOAD1_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD1_LSB				14
+#define CSR_ACSMBNKSELLOAD1_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE1_LSB				15
+#define CSR_ACSMLONGBUBBLE1_MASK			BIT(15)
+/* CSR_ACSMSEQ3X2 */
+#define CSR_ACSMSEQ3X2_LSB				0
+#define CSR_ACSMSEQ3X2_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT2_LSB				0
+#define CSR_ACSMCMDREPCNT2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV2_LSB				8
+#define CSR_ACSMADRADV2_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV2_LSB				10
+#define CSR_ACSMBNKADV2_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD2_LSB				12
+#define CSR_ACSMADRSELLOAD2_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD2_LSB				14
+#define CSR_ACSMBNKSELLOAD2_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE2_LSB				15
+#define CSR_ACSMLONGBUBBLE2_MASK			BIT(15)
+/* CSR_ACSMSEQ3X3 */
+#define CSR_ACSMSEQ3X3_LSB				0
+#define CSR_ACSMSEQ3X3_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT3_LSB				0
+#define CSR_ACSMCMDREPCNT3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV3_LSB				8
+#define CSR_ACSMADRADV3_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV3_LSB				10
+#define CSR_ACSMBNKADV3_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD3_LSB				12
+#define CSR_ACSMADRSELLOAD3_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD3_LSB				14
+#define CSR_ACSMBNKSELLOAD3_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE3_LSB				15
+#define CSR_ACSMLONGBUBBLE3_MASK			BIT(15)
+/* CSR_ACSMSEQ3X4 */
+#define CSR_ACSMSEQ3X4_LSB				0
+#define CSR_ACSMSEQ3X4_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT4_LSB				0
+#define CSR_ACSMCMDREPCNT4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV4_LSB				8
+#define CSR_ACSMADRADV4_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV4_LSB				10
+#define CSR_ACSMBNKADV4_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD4_LSB				12
+#define CSR_ACSMADRSELLOAD4_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD4_LSB				14
+#define CSR_ACSMBNKSELLOAD4_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE4_LSB				15
+#define CSR_ACSMLONGBUBBLE4_MASK			BIT(15)
+/* CSR_ACSMSEQ3X5 */
+#define CSR_ACSMSEQ3X5_LSB				0
+#define CSR_ACSMSEQ3X5_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT5_LSB				0
+#define CSR_ACSMCMDREPCNT5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV5_LSB				8
+#define CSR_ACSMADRADV5_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV5_LSB				10
+#define CSR_ACSMBNKADV5_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD5_LSB				12
+#define CSR_ACSMADRSELLOAD5_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD5_LSB				14
+#define CSR_ACSMBNKSELLOAD5_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE5_LSB				15
+#define CSR_ACSMLONGBUBBLE5_MASK			BIT(15)
+/* CSR_ACSMSEQ3X6 */
+#define CSR_ACSMSEQ3X6_LSB				0
+#define CSR_ACSMSEQ3X6_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT6_LSB				0
+#define CSR_ACSMCMDREPCNT6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV6_LSB				8
+#define CSR_ACSMADRADV6_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV6_LSB				10
+#define CSR_ACSMBNKADV6_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD6_LSB				12
+#define CSR_ACSMADRSELLOAD6_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD6_LSB				14
+#define CSR_ACSMBNKSELLOAD6_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE6_LSB				15
+#define CSR_ACSMLONGBUBBLE6_MASK			BIT(15)
+/* CSR_ACSMSEQ3X7 */
+#define CSR_ACSMSEQ3X7_LSB				0
+#define CSR_ACSMSEQ3X7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT7_LSB				0
+#define CSR_ACSMCMDREPCNT7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV7_LSB				8
+#define CSR_ACSMADRADV7_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV7_LSB				10
+#define CSR_ACSMBNKADV7_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD7_LSB				12
+#define CSR_ACSMADRSELLOAD7_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD7_LSB				14
+#define CSR_ACSMBNKSELLOAD7_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE7_LSB				15
+#define CSR_ACSMLONGBUBBLE7_MASK			BIT(15)
+/* CSR_ACSMSEQ3X8 */
+#define CSR_ACSMSEQ3X8_LSB				0
+#define CSR_ACSMSEQ3X8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT8_LSB				0
+#define CSR_ACSMCMDREPCNT8_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV8_LSB				8
+#define CSR_ACSMADRADV8_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV8_LSB				10
+#define CSR_ACSMBNKADV8_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD8_LSB				12
+#define CSR_ACSMADRSELLOAD8_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD8_LSB				14
+#define CSR_ACSMBNKSELLOAD8_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE8_LSB				15
+#define CSR_ACSMLONGBUBBLE8_MASK			BIT(15)
+/* CSR_ACSMSEQ3X9 */
+#define CSR_ACSMSEQ3X9_LSB				0
+#define CSR_ACSMSEQ3X9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT9_LSB				0
+#define CSR_ACSMCMDREPCNT9_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV9_LSB				8
+#define CSR_ACSMADRADV9_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV9_LSB				10
+#define CSR_ACSMBNKADV9_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD9_LSB				12
+#define CSR_ACSMADRSELLOAD9_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD9_LSB				14
+#define CSR_ACSMBNKSELLOAD9_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE9_LSB				15
+#define CSR_ACSMLONGBUBBLE9_MASK			BIT(15)
+/* CSR_ACSMSEQ3X10 */
+#define CSR_ACSMSEQ3X10_LSB				0
+#define CSR_ACSMSEQ3X10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT10_LSB				0
+#define CSR_ACSMCMDREPCNT10_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV10_LSB				8
+#define CSR_ACSMADRADV10_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV10_LSB				10
+#define CSR_ACSMBNKADV10_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD10_LSB			12
+#define CSR_ACSMADRSELLOAD10_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD10_LSB			14
+#define CSR_ACSMBNKSELLOAD10_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE10_LSB			15
+#define CSR_ACSMLONGBUBBLE10_MASK			BIT(15)
+/* CSR_ACSMSEQ3X11 */
+#define CSR_ACSMSEQ3X11_LSB				0
+#define CSR_ACSMSEQ3X11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT11_LSB				0
+#define CSR_ACSMCMDREPCNT11_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV11_LSB				8
+#define CSR_ACSMADRADV11_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV11_LSB				10
+#define CSR_ACSMBNKADV11_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD11_LSB			12
+#define CSR_ACSMADRSELLOAD11_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD11_LSB			14
+#define CSR_ACSMBNKSELLOAD11_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE11_LSB			15
+#define CSR_ACSMLONGBUBBLE11_MASK			BIT(15)
+/* CSR_ACSMSEQ3X12 */
+#define CSR_ACSMSEQ3X12_LSB				0
+#define CSR_ACSMSEQ3X12_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT12_LSB				0
+#define CSR_ACSMCMDREPCNT12_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV12_LSB				8
+#define CSR_ACSMADRADV12_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV12_LSB				10
+#define CSR_ACSMBNKADV12_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD12_LSB			12
+#define CSR_ACSMADRSELLOAD12_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD12_LSB			14
+#define CSR_ACSMBNKSELLOAD12_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE12_LSB			15
+#define CSR_ACSMLONGBUBBLE12_MASK			BIT(15)
+/* CSR_ACSMSEQ3X13 */
+#define CSR_ACSMSEQ3X13_LSB				0
+#define CSR_ACSMSEQ3X13_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT13_LSB				0
+#define CSR_ACSMCMDREPCNT13_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV13_LSB				8
+#define CSR_ACSMADRADV13_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV13_LSB				10
+#define CSR_ACSMBNKADV13_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD13_LSB			12
+#define CSR_ACSMADRSELLOAD13_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD13_LSB			14
+#define CSR_ACSMBNKSELLOAD13_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE13_LSB			15
+#define CSR_ACSMLONGBUBBLE13_MASK			BIT(15)
+/* CSR_ACSMSEQ3X14 */
+#define CSR_ACSMSEQ3X14_LSB				0
+#define CSR_ACSMSEQ3X14_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT14_LSB				0
+#define CSR_ACSMCMDREPCNT14_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV14_LSB				8
+#define CSR_ACSMADRADV14_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV14_LSB				10
+#define CSR_ACSMBNKADV14_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD14_LSB			12
+#define CSR_ACSMADRSELLOAD14_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD14_LSB			14
+#define CSR_ACSMBNKSELLOAD14_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE14_LSB			15
+#define CSR_ACSMLONGBUBBLE14_MASK			BIT(15)
+/* CSR_ACSMSEQ3X15 */
+#define CSR_ACSMSEQ3X15_LSB				0
+#define CSR_ACSMSEQ3X15_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT15_LSB				0
+#define CSR_ACSMCMDREPCNT15_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV15_LSB				8
+#define CSR_ACSMADRADV15_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV15_LSB				10
+#define CSR_ACSMBNKADV15_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD15_LSB			12
+#define CSR_ACSMADRSELLOAD15_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD15_LSB			14
+#define CSR_ACSMBNKSELLOAD15_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE15_LSB			15
+#define CSR_ACSMLONGBUBBLE15_MASK			BIT(15)
+/* CSR_ACSMSEQ3X16 */
+#define CSR_ACSMSEQ3X16_LSB				0
+#define CSR_ACSMSEQ3X16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT16_LSB				0
+#define CSR_ACSMCMDREPCNT16_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV16_LSB				8
+#define CSR_ACSMADRADV16_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV16_LSB				10
+#define CSR_ACSMBNKADV16_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD16_LSB			12
+#define CSR_ACSMADRSELLOAD16_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD16_LSB			14
+#define CSR_ACSMBNKSELLOAD16_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE16_LSB			15
+#define CSR_ACSMLONGBUBBLE16_MASK			BIT(15)
+/* CSR_ACSMSEQ3X17 */
+#define CSR_ACSMSEQ3X17_LSB				0
+#define CSR_ACSMSEQ3X17_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT17_LSB				0
+#define CSR_ACSMCMDREPCNT17_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV17_LSB				8
+#define CSR_ACSMADRADV17_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV17_LSB				10
+#define CSR_ACSMBNKADV17_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD17_LSB			12
+#define CSR_ACSMADRSELLOAD17_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD17_LSB			14
+#define CSR_ACSMBNKSELLOAD17_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE17_LSB			15
+#define CSR_ACSMLONGBUBBLE17_MASK			BIT(15)
+/* CSR_ACSMSEQ3X18 */
+#define CSR_ACSMSEQ3X18_LSB				0
+#define CSR_ACSMSEQ3X18_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT18_LSB				0
+#define CSR_ACSMCMDREPCNT18_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV18_LSB				8
+#define CSR_ACSMADRADV18_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV18_LSB				10
+#define CSR_ACSMBNKADV18_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD18_LSB			12
+#define CSR_ACSMADRSELLOAD18_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD18_LSB			14
+#define CSR_ACSMBNKSELLOAD18_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE18_LSB			15
+#define CSR_ACSMLONGBUBBLE18_MASK			BIT(15)
+/* CSR_ACSMSEQ3X19 */
+#define CSR_ACSMSEQ3X19_LSB				0
+#define CSR_ACSMSEQ3X19_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT19_LSB				0
+#define CSR_ACSMCMDREPCNT19_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV19_LSB				8
+#define CSR_ACSMADRADV19_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV19_LSB				10
+#define CSR_ACSMBNKADV19_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD19_LSB			12
+#define CSR_ACSMADRSELLOAD19_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD19_LSB			14
+#define CSR_ACSMBNKSELLOAD19_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE19_LSB			15
+#define CSR_ACSMLONGBUBBLE19_MASK			BIT(15)
+/* CSR_ACSMSEQ3X20 */
+#define CSR_ACSMSEQ3X20_LSB				0
+#define CSR_ACSMSEQ3X20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT20_LSB				0
+#define CSR_ACSMCMDREPCNT20_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV20_LSB				8
+#define CSR_ACSMADRADV20_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV20_LSB				10
+#define CSR_ACSMBNKADV20_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD20_LSB			12
+#define CSR_ACSMADRSELLOAD20_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD20_LSB			14
+#define CSR_ACSMBNKSELLOAD20_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE20_LSB			15
+#define CSR_ACSMLONGBUBBLE20_MASK			BIT(15)
+/* CSR_ACSMSEQ3X21 */
+#define CSR_ACSMSEQ3X21_LSB				0
+#define CSR_ACSMSEQ3X21_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT21_LSB				0
+#define CSR_ACSMCMDREPCNT21_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV21_LSB				8
+#define CSR_ACSMADRADV21_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV21_LSB				10
+#define CSR_ACSMBNKADV21_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD21_LSB			12
+#define CSR_ACSMADRSELLOAD21_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD21_LSB			14
+#define CSR_ACSMBNKSELLOAD21_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE21_LSB			15
+#define CSR_ACSMLONGBUBBLE21_MASK			BIT(15)
+/* CSR_ACSMSEQ3X22 */
+#define CSR_ACSMSEQ3X22_LSB				0
+#define CSR_ACSMSEQ3X22_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT22_LSB				0
+#define CSR_ACSMCMDREPCNT22_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV22_LSB				8
+#define CSR_ACSMADRADV22_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV22_LSB				10
+#define CSR_ACSMBNKADV22_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD22_LSB			12
+#define CSR_ACSMADRSELLOAD22_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD22_LSB			14
+#define CSR_ACSMBNKSELLOAD22_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE22_LSB			15
+#define CSR_ACSMLONGBUBBLE22_MASK			BIT(15)
+/* CSR_ACSMSEQ3X23 */
+#define CSR_ACSMSEQ3X23_LSB				0
+#define CSR_ACSMSEQ3X23_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT23_LSB				0
+#define CSR_ACSMCMDREPCNT23_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV23_LSB				8
+#define CSR_ACSMADRADV23_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV23_LSB				10
+#define CSR_ACSMBNKADV23_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD23_LSB			12
+#define CSR_ACSMADRSELLOAD23_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD23_LSB			14
+#define CSR_ACSMBNKSELLOAD23_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE23_LSB			15
+#define CSR_ACSMLONGBUBBLE23_MASK			BIT(15)
+/* CSR_ACSMSEQ3X24 */
+#define CSR_ACSMSEQ3X24_LSB				0
+#define CSR_ACSMSEQ3X24_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT24_LSB				0
+#define CSR_ACSMCMDREPCNT24_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV24_LSB				8
+#define CSR_ACSMADRADV24_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV24_LSB				10
+#define CSR_ACSMBNKADV24_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD24_LSB			12
+#define CSR_ACSMADRSELLOAD24_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD24_LSB			14
+#define CSR_ACSMBNKSELLOAD24_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE24_LSB			15
+#define CSR_ACSMLONGBUBBLE24_MASK			BIT(15)
+/* CSR_ACSMSEQ3X25 */
+#define CSR_ACSMSEQ3X25_LSB				0
+#define CSR_ACSMSEQ3X25_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT25_LSB				0
+#define CSR_ACSMCMDREPCNT25_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV25_LSB				8
+#define CSR_ACSMADRADV25_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV25_LSB				10
+#define CSR_ACSMBNKADV25_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD25_LSB			12
+#define CSR_ACSMADRSELLOAD25_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD25_LSB			14
+#define CSR_ACSMBNKSELLOAD25_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE25_LSB			15
+#define CSR_ACSMLONGBUBBLE25_MASK			BIT(15)
+/* CSR_ACSMSEQ3X26 */
+#define CSR_ACSMSEQ3X26_LSB				0
+#define CSR_ACSMSEQ3X26_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT26_LSB				0
+#define CSR_ACSMCMDREPCNT26_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV26_LSB				8
+#define CSR_ACSMADRADV26_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV26_LSB				10
+#define CSR_ACSMBNKADV26_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD26_LSB			12
+#define CSR_ACSMADRSELLOAD26_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD26_LSB			14
+#define CSR_ACSMBNKSELLOAD26_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE26_LSB			15
+#define CSR_ACSMLONGBUBBLE26_MASK			BIT(15)
+/* CSR_ACSMSEQ3X27 */
+#define CSR_ACSMSEQ3X27_LSB				0
+#define CSR_ACSMSEQ3X27_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT27_LSB				0
+#define CSR_ACSMCMDREPCNT27_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV27_LSB				8
+#define CSR_ACSMADRADV27_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV27_LSB				10
+#define CSR_ACSMBNKADV27_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD27_LSB			12
+#define CSR_ACSMADRSELLOAD27_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD27_LSB			14
+#define CSR_ACSMBNKSELLOAD27_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE27_LSB			15
+#define CSR_ACSMLONGBUBBLE27_MASK			BIT(15)
+/* CSR_ACSMSEQ3X28 */
+#define CSR_ACSMSEQ3X28_LSB				0
+#define CSR_ACSMSEQ3X28_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT28_LSB				0
+#define CSR_ACSMCMDREPCNT28_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV28_LSB				8
+#define CSR_ACSMADRADV28_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV28_LSB				10
+#define CSR_ACSMBNKADV28_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD28_LSB			12
+#define CSR_ACSMADRSELLOAD28_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD28_LSB			14
+#define CSR_ACSMBNKSELLOAD28_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE28_LSB			15
+#define CSR_ACSMLONGBUBBLE28_MASK			BIT(15)
+/* CSR_ACSMSEQ3X29 */
+#define CSR_ACSMSEQ3X29_LSB				0
+#define CSR_ACSMSEQ3X29_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT29_LSB				0
+#define CSR_ACSMCMDREPCNT29_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV29_LSB				8
+#define CSR_ACSMADRADV29_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV29_LSB				10
+#define CSR_ACSMBNKADV29_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD29_LSB			12
+#define CSR_ACSMADRSELLOAD29_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD29_LSB			14
+#define CSR_ACSMBNKSELLOAD29_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE29_LSB			15
+#define CSR_ACSMLONGBUBBLE29_MASK			BIT(15)
+/* CSR_ACSMSEQ3X30 */
+#define CSR_ACSMSEQ3X30_LSB				0
+#define CSR_ACSMSEQ3X30_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT30_LSB				0
+#define CSR_ACSMCMDREPCNT30_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV30_LSB				8
+#define CSR_ACSMADRADV30_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV30_LSB				10
+#define CSR_ACSMBNKADV30_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD30_LSB			12
+#define CSR_ACSMADRSELLOAD30_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD30_LSB			14
+#define CSR_ACSMBNKSELLOAD30_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE30_LSB			15
+#define CSR_ACSMLONGBUBBLE30_MASK			BIT(15)
+/* CSR_ACSMSEQ3X31 */
+#define CSR_ACSMSEQ3X31_LSB				0
+#define CSR_ACSMSEQ3X31_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT31_LSB				0
+#define CSR_ACSMCMDREPCNT31_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV31_LSB				8
+#define CSR_ACSMADRADV31_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV31_LSB				10
+#define CSR_ACSMBNKADV31_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD31_LSB			12
+#define CSR_ACSMADRSELLOAD31_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD31_LSB			14
+#define CSR_ACSMBNKSELLOAD31_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE31_LSB			15
+#define CSR_ACSMLONGBUBBLE31_MASK			BIT(15)
+/* CSR_ACSMPLAYBACK0X0 */
+#define CSR_ACSMPLAYBACK0X0_LSB				0
+#define CSR_ACSMPLAYBACK0X0_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X0 */
+#define CSR_ACSMPLAYBACK1X0_LSB				0
+#define CSR_ACSMPLAYBACK1X0_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X1 */
+#define CSR_ACSMPLAYBACK0X1_LSB				0
+#define CSR_ACSMPLAYBACK0X1_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X1 */
+#define CSR_ACSMPLAYBACK1X1_LSB				0
+#define CSR_ACSMPLAYBACK1X1_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X2 */
+#define CSR_ACSMPLAYBACK0X2_LSB				0
+#define CSR_ACSMPLAYBACK0X2_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X2 */
+#define CSR_ACSMPLAYBACK1X2_LSB				0
+#define CSR_ACSMPLAYBACK1X2_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X3 */
+#define CSR_ACSMPLAYBACK0X3_LSB				0
+#define CSR_ACSMPLAYBACK0X3_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X3 */
+#define CSR_ACSMPLAYBACK1X3_LSB				0
+#define CSR_ACSMPLAYBACK1X3_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X4 */
+#define CSR_ACSMPLAYBACK0X4_LSB				0
+#define CSR_ACSMPLAYBACK0X4_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X4 */
+#define CSR_ACSMPLAYBACK1X4_LSB				0
+#define CSR_ACSMPLAYBACK1X4_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X5 */
+#define CSR_ACSMPLAYBACK0X5_LSB				0
+#define CSR_ACSMPLAYBACK0X5_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X5 */
+#define CSR_ACSMPLAYBACK1X5_LSB				0
+#define CSR_ACSMPLAYBACK1X5_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X6 */
+#define CSR_ACSMPLAYBACK0X6_LSB				0
+#define CSR_ACSMPLAYBACK0X6_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X6 */
+#define CSR_ACSMPLAYBACK1X6_LSB				0
+#define CSR_ACSMPLAYBACK1X6_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X7 */
+#define CSR_ACSMPLAYBACK0X7_LSB				0
+#define CSR_ACSMPLAYBACK0X7_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X7 */
+#define CSR_ACSMPLAYBACK1X7_LSB				0
+#define CSR_ACSMPLAYBACK1X7_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPSTATEOVREN */
+#define CSR_ACSMPSTATEOVREN_LSB				0
+#define CSR_ACSMPSTATEOVREN_MASK			BIT(0)
+/* CSR_ACSMPSTATEOVRVAL */
+#define CSR_ACSMPSTATEOVRVAL_LSB			0
+#define CSR_ACSMPSTATEOVRVAL_MASK			GENMASK_32(3, 0)
+/* CSR_ACSMCTRL23 */
+#define CSR_ACSMCTRL23_LSB				0
+#define CSR_ACSMCTRL23_MASK				GENMASK_32(12, 0)
+#define CSR_ACSMCSMASK_LSB				0
+#define CSR_ACSMCSMASK_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMCSMODE_LSB				8
+#define CSR_ACSMCSMODE_MASK				BIT(8)
+#define CSR_ACSMPARMASK_LSB				9
+#define CSR_ACSMPARMASK_MASK				GENMASK_32(12, 9)
+/* CSR_ACSMCKEVAL */
+#define CSR_ACSMCKEVAL_LSB				0
+#define CSR_ACSMCKEVAL_MASK				GENMASK_32(3, 0)
+/* CSR_LOWSPEEDCLOCKDIVIDER */
+#define CSR_LOWSPEEDCLOCKDIVIDER_LSB			0
+#define CSR_LOWSPEEDCLOCKDIVIDER_MASK			GENMASK_32(5, 0)
+/* CSR_ACSMCSMAPCTRL0 */
+#define CSR_ACSMCSMAPCTRL0_LSB				0
+#define CSR_ACSMCSMAPCTRL0_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP0_LSB				0
+#define CSR_ACSMCSMAP0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP0_LSB				8
+#define CSR_ACSMDESTMAP0_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP0_LSB				12
+#define CSR_ACSMODTMAP0_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL1 */
+#define CSR_ACSMCSMAPCTRL1_LSB				0
+#define CSR_ACSMCSMAPCTRL1_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP1_LSB				0
+#define CSR_ACSMCSMAP1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP1_LSB				8
+#define CSR_ACSMDESTMAP1_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP1_LSB				12
+#define CSR_ACSMODTMAP1_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL2 */
+#define CSR_ACSMCSMAPCTRL2_LSB				0
+#define CSR_ACSMCSMAPCTRL2_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP2_LSB				0
+#define CSR_ACSMCSMAP2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP2_LSB				8
+#define CSR_ACSMDESTMAP2_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP2_LSB				12
+#define CSR_ACSMODTMAP2_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL3 */
+#define CSR_ACSMCSMAPCTRL3_LSB				0
+#define CSR_ACSMCSMAPCTRL3_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP3_LSB				0
+#define CSR_ACSMCSMAP3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP3_LSB				8
+#define CSR_ACSMDESTMAP3_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP3_LSB				12
+#define CSR_ACSMODTMAP3_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL4 */
+#define CSR_ACSMCSMAPCTRL4_LSB				0
+#define CSR_ACSMCSMAPCTRL4_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP4_LSB				0
+#define CSR_ACSMCSMAP4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP4_LSB				8
+#define CSR_ACSMDESTMAP4_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP4_LSB				12
+#define CSR_ACSMODTMAP4_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL5 */
+#define CSR_ACSMCSMAPCTRL5_LSB				0
+#define CSR_ACSMCSMAPCTRL5_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP5_LSB				0
+#define CSR_ACSMCSMAP5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP5_LSB				8
+#define CSR_ACSMDESTMAP5_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP5_LSB				12
+#define CSR_ACSMODTMAP5_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL6 */
+#define CSR_ACSMCSMAPCTRL6_LSB				0
+#define CSR_ACSMCSMAPCTRL6_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP6_LSB				0
+#define CSR_ACSMCSMAP6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP6_LSB				8
+#define CSR_ACSMDESTMAP6_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP6_LSB				12
+#define CSR_ACSMODTMAP6_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL7 */
+#define CSR_ACSMCSMAPCTRL7_LSB				0
+#define CSR_ACSMCSMAPCTRL7_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP7_LSB				0
+#define CSR_ACSMCSMAP7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP7_LSB				8
+#define CSR_ACSMDESTMAP7_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP7_LSB				12
+#define CSR_ACSMODTMAP7_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL8 */
+#define CSR_ACSMCSMAPCTRL8_LSB				0
+#define CSR_ACSMCSMAPCTRL8_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP8_LSB				0
+#define CSR_ACSMCSMAP8_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP8_LSB				8
+#define CSR_ACSMDESTMAP8_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP8_LSB				12
+#define CSR_ACSMODTMAP8_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL9 */
+#define CSR_ACSMCSMAPCTRL9_LSB				0
+#define CSR_ACSMCSMAPCTRL9_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP9_LSB				0
+#define CSR_ACSMCSMAP9_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP9_LSB				8
+#define CSR_ACSMDESTMAP9_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP9_LSB				12
+#define CSR_ACSMODTMAP9_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL10 */
+#define CSR_ACSMCSMAPCTRL10_LSB				0
+#define CSR_ACSMCSMAPCTRL10_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP10_LSB				0
+#define CSR_ACSMCSMAP10_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP10_LSB				8
+#define CSR_ACSMDESTMAP10_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP10_LSB				12
+#define CSR_ACSMODTMAP10_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL11 */
+#define CSR_ACSMCSMAPCTRL11_LSB				0
+#define CSR_ACSMCSMAPCTRL11_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP11_LSB				0
+#define CSR_ACSMCSMAP11_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP11_LSB				8
+#define CSR_ACSMDESTMAP11_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP11_LSB				12
+#define CSR_ACSMODTMAP11_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL12 */
+#define CSR_ACSMCSMAPCTRL12_LSB				0
+#define CSR_ACSMCSMAPCTRL12_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP12_LSB				0
+#define CSR_ACSMCSMAP12_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP12_LSB				8
+#define CSR_ACSMDESTMAP12_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP12_LSB				12
+#define CSR_ACSMODTMAP12_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL13 */
+#define CSR_ACSMCSMAPCTRL13_LSB				0
+#define CSR_ACSMCSMAPCTRL13_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP13_LSB				0
+#define CSR_ACSMCSMAP13_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP13_LSB				8
+#define CSR_ACSMDESTMAP13_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP13_LSB				12
+#define CSR_ACSMODTMAP13_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL14 */
+#define CSR_ACSMCSMAPCTRL14_LSB				0
+#define CSR_ACSMCSMAPCTRL14_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP14_LSB				0
+#define CSR_ACSMCSMAP14_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP14_LSB				8
+#define CSR_ACSMDESTMAP14_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP14_LSB				12
+#define CSR_ACSMODTMAP14_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL15 */
+#define CSR_ACSMCSMAPCTRL15_LSB				0
+#define CSR_ACSMCSMAPCTRL15_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP15_LSB				0
+#define CSR_ACSMCSMAP15_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP15_LSB				8
+#define CSR_ACSMDESTMAP15_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP15_LSB				12
+#define CSR_ACSMODTMAP15_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMODTCTRL0 */
+#define CSR_ACSMODTCTRL0_LSB				0
+#define CSR_ACSMODTCTRL0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS0_LSB				0
+#define CSR_ACSMODTWRPATCS0_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS0_LSB				4
+#define CSR_ACSMODTRDPATCS0_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL1 */
+#define CSR_ACSMODTCTRL1_LSB				0
+#define CSR_ACSMODTCTRL1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS1_LSB				0
+#define CSR_ACSMODTWRPATCS1_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS1_LSB				4
+#define CSR_ACSMODTRDPATCS1_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL2 */
+#define CSR_ACSMODTCTRL2_LSB				0
+#define CSR_ACSMODTCTRL2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS2_LSB				0
+#define CSR_ACSMODTWRPATCS2_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS2_LSB				4
+#define CSR_ACSMODTRDPATCS2_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL3 */
+#define CSR_ACSMODTCTRL3_LSB				0
+#define CSR_ACSMODTCTRL3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS3_LSB				0
+#define CSR_ACSMODTWRPATCS3_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS3_LSB				4
+#define CSR_ACSMODTRDPATCS3_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL4 */
+#define CSR_ACSMODTCTRL4_LSB				0
+#define CSR_ACSMODTCTRL4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS4_LSB				0
+#define CSR_ACSMODTWRPATCS4_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS4_LSB				4
+#define CSR_ACSMODTRDPATCS4_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL5 */
+#define CSR_ACSMODTCTRL5_LSB				0
+#define CSR_ACSMODTCTRL5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS5_LSB				0
+#define CSR_ACSMODTWRPATCS5_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS5_LSB				4
+#define CSR_ACSMODTRDPATCS5_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL6 */
+#define CSR_ACSMODTCTRL6_LSB				0
+#define CSR_ACSMODTCTRL6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS6_LSB				0
+#define CSR_ACSMODTWRPATCS6_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS6_LSB				4
+#define CSR_ACSMODTRDPATCS6_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL7 */
+#define CSR_ACSMODTCTRL7_LSB				0
+#define CSR_ACSMODTCTRL7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS7_LSB				0
+#define CSR_ACSMODTWRPATCS7_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS7_LSB				4
+#define CSR_ACSMODTRDPATCS7_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL8 */
+#define CSR_ACSMODTCTRL8_LSB				0
+#define CSR_ACSMODTCTRL8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMODTWRDURCTRL_LSB			0
+#define CSR_ACSMODTWRDURCTRL_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDDURCTRL_LSB			4
+#define CSR_ACSMODTRDDURCTRL_MASK			GENMASK_32(7, 4)
+#define CSR_ACSMODTWRSTRTCTRL_LSB			8
+#define CSR_ACSMODTWRSTRTCTRL_MASK			GENMASK_32(11, 8)
+#define CSR_ACSMODTRDSTRTCTRL_LSB			12
+#define CSR_ACSMODTRDSTRTCTRL_MASK			GENMASK_32(15, 12)
+/* CSR_ACSMCTRL16 */
+#define CSR_ACSMCTRL16_LSB				0
+#define CSR_ACSMCTRL16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRUP_LSB				0
+#define CSR_ACSMDDRADRUP_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMHIGHADDR_LSB				4
+#define CSR_ACSMHIGHADDR_MASK				BIT(4)
+#define CSR_ACSMADR13PLUGHOLE_LSB			5
+#define CSR_ACSMADR13PLUGHOLE_MASK			BIT(5)
+#define CSR_ACSMCTRL16RSVD_LSB				6
+#define CSR_ACSMCTRL16RSVD_MASK				BIT(6)
+#define CSR_ACSMWRTLVLODTCTRL_LSB			7
+#define CSR_ACSMWRTLVLODTCTRL_MASK			BIT(7)
+#define CSR_ACSMWRTLVLODT_LSB				8
+#define CSR_ACSMWRTLVLODT_MASK				GENMASK_32(11, 8)
+#define CSR_ACSM2TGRPINHIBIT_LSB			12
+#define CSR_ACSM2TGRPINHIBIT_MASK			GENMASK_32(15, 12)
+/* CSR_LOWSPEEDCLOCKSTOPVAL */
+#define CSR_LOWSPEEDCLOCKSTOPVAL_LSB			0
+#define CSR_LOWSPEEDCLOCKSTOPVAL_MASK			BIT(0)
+/* CSR_ACSMCTRL18 */
+#define CSR_ACSMCTRL18_LSB				0
+#define CSR_ACSMCTRL18_MASK				GENMASK_32(1, 0)
+#define CSR_ACSMLOCALDONE_LSB				0
+#define CSR_ACSMLOCALDONE_MASK				BIT(0)
+#define CSR_ACSMSTOPONERRASRTD_LSB			1
+#define CSR_ACSMSTOPONERRASRTD_MASK			BIT(1)
+/* CSR_ACSMCTRL19 */
+#define CSR_ACSMCTRL19_LSB				0
+#define CSR_ACSMCTRL19_MASK				GENMASK_32(2, 0)
+#define CSR_ACSMVISSEL_LSB				0
+#define CSR_ACSMVISSEL_MASK				GENMASK_32(2, 0)
+/* CSR_ACSMCTRL20 */
+#define CSR_ACSMCTRL20_LSB				0
+#define CSR_ACSMCTRL20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMVISVAL_LSB				0
+#define CSR_ACSMVISVAL_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL21 */
+#define CSR_ACSMCTRL21_LSB				0
+#define CSR_ACSMCTRL21_MASK				GENMASK_32(11, 0)
+#define CSR_ACSMMAPDIMMCS0_LSB				0
+#define CSR_ACSMMAPDIMMCS0_MASK				GENMASK_32(2, 0)
+#define CSR_ACSMMAPDIMMCS1_LSB				3
+#define CSR_ACSMMAPDIMMCS1_MASK				GENMASK_32(5, 3)
+#define CSR_ACSMMAPDIMMCS2_LSB				6
+#define CSR_ACSMMAPDIMMCS2_MASK				GENMASK_32(8, 6)
+#define CSR_ACSMMAPDIMMCS3_LSB				9
+#define CSR_ACSMMAPDIMMCS3_MASK				GENMASK_32(11, 9)
+/* CSR_ACSMCTRL22 */
+#define CSR_ACSMCTRL22_LSB				0
+#define CSR_ACSMCTRL22_MASK				GENMASK_32(11, 0)
+#define CSR_ACSMMAPDIMMCS4_LSB				0
+#define CSR_ACSMMAPDIMMCS4_MASK				GENMASK_32(2, 0)
+#define CSR_ACSMMAPDIMMCS5_LSB				3
+#define CSR_ACSMMAPDIMMCS5_MASK				GENMASK_32(5, 3)
+#define CSR_ACSMMAPDIMMCS6_LSB				6
+#define CSR_ACSMMAPDIMMCS6_MASK				GENMASK_32(8, 6)
+#define CSR_ACSMMAPDIMMCS7_LSB				9
+#define CSR_ACSMMAPDIMMCS7_MASK				GENMASK_32(11, 9)
+/* CSR_ACSMCTRL0 */
+#define CSR_ACSMCTRL0_LSB				0
+#define CSR_ACSMCTRL0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMRSVDCTRL00_LSB				0
+#define CSR_ACSMRSVDCTRL00_MASK				BIT(0)
+#define CSR_ACSMDYNBLMODE_LSB				1
+#define CSR_ACSMDYNBLMODE_MASK				BIT(1)
+#define CSR_ACSMBURSTLEN_LSB				2
+#define CSR_ACSMBURSTLEN_MASK				BIT(2)
+#define CSR_ACSMINFLOOP_LSB				3
+#define CSR_ACSMINFLOOP_MASK				BIT(3)
+#define CSR_ACSMRXVALMODE_LSB				4
+#define CSR_ACSMRXVALMODE_MASK				BIT(4)
+#define CSR_ACSMSTPONERRMODE_LSB			5
+#define CSR_ACSMSTPONERRMODE_MASK			BIT(5)
+#define CSR_ACSM2TMODE_LSB				6
+#define CSR_ACSM2TMODE_MASK				BIT(6)
+#define CSR_ACSMTRAINSOEMODE_LSB			7
+#define CSR_ACSMTRAINSOEMODE_MASK			BIT(7)
+#define CSR_ACSMGATEDDRCMD_LSB				8
+#define CSR_ACSMGATEDDRCMD_MASK				BIT(8)
+#define CSR_ACSMGEARDOWNMODE_LSB			9
+#define CSR_ACSMGEARDOWNMODE_MASK			BIT(9)
+#define CSR_ACSMGEARDOWNPHASE_LSB			10
+#define CSR_ACSMGEARDOWNPHASE_MASK			BIT(10)
+#define CSR_ACSMGEARDOWNSYNC_LSB			11
+#define CSR_ACSMGEARDOWNSYNC_MASK			BIT(11)
+#define CSR_ACSMCAPRBSMODE_LSB				12
+#define CSR_ACSMCAPRBSMODE_MASK				BIT(12)
+#define CSR_ACSMGATERXFIFOWRITE_LSB			13
+#define CSR_ACSMGATERXFIFOWRITE_MASK			BIT(13)
+#define CSR_ACSMPARMODE_LSB				14
+#define CSR_ACSMPARMODE_MASK				BIT(14)
+#define CSR_ACSMTDSMODE_LSB				15
+#define CSR_ACSMTDSMODE_MASK				BIT(15)
+/* CSR_ACSMCTRL1 */
+#define CSR_ACSMCTRL1_LSB				0
+#define CSR_ACSMCTRL1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMREPCNT_LSB				0
+#define CSR_ACSMREPCNT_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL2 */
+#define CSR_ACSMCTRL2_LSB				0
+#define CSR_ACSMCTRL2_MASK				GENMASK_32(4, 0)
+#define CSR_ACSMSTARTPTR_LSB				0
+#define CSR_ACSMSTARTPTR_MASK				GENMASK_32(4, 0)
+/* CSR_ACSMCTRL3 */
+#define CSR_ACSMCTRL3_LSB				0
+#define CSR_ACSMCTRL3_MASK				GENMASK_32(4, 0)
+#define CSR_ACSMLOOPPTR_LSB				0
+#define CSR_ACSMLOOPPTR_MASK				GENMASK_32(4, 0)
+/* CSR_ACSMCTRL4 */
+#define CSR_ACSMCTRL4_LSB				0
+#define CSR_ACSMCTRL4_MASK				GENMASK_32(4, 0)
+#define CSR_ACSMENDPTR_LSB				0
+#define CSR_ACSMENDPTR_MASK				GENMASK_32(4, 0)
+/* CSR_ACSMCTRL5 */
+#define CSR_ACSMCTRL5_LSB				0
+#define CSR_ACSMCTRL5_MASK				GENMASK_32(13, 0)
+#define CSR_ACSMMXRDLAT_LSB				0
+#define CSR_ACSMMXRDLAT_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMRCASLAT_LSB				8
+#define CSR_ACSMRCASLAT_MASK				GENMASK_32(13, 8)
+/* CSR_ACSMCTRL6 */
+#define CSR_ACSMCTRL6_LSB				0
+#define CSR_ACSMCTRL6_MASK				GENMASK_32(10, 0)
+#define CSR_ACSMWCASLAT_LSB				0
+#define CSR_ACSMWCASLAT_MASK				GENMASK_32(5, 0)
+#define CSR_ACSMWRRSVD_LSB				6
+#define CSR_ACSMWRRSVD_MASK				GENMASK_32(7, 6)
+#define CSR_ACSMWRDATLAT_LSB				8
+#define CSR_ACSMWRDATLAT_MASK				GENMASK_32(10, 8)
+/* CSR_ACSMCTRL7 */
+#define CSR_ACSMCTRL7_LSB				0
+#define CSR_ACSMCTRL7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMRASPCFG_LSB				0
+#define CSR_ACSMRASPCFG_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL8 */
+#define CSR_ACSMCTRL8_LSB				0
+#define CSR_ACSMCTRL8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMRASPSEED_LSB				0
+#define CSR_ACSMRASPSEED_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL9 */
+#define CSR_ACSMCTRL9_LSB				0
+#define CSR_ACSMCTRL9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCASPCFG_LSB				0
+#define CSR_ACSMCASPCFG_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL10 */
+#define CSR_ACSMCTRL10_LSB				0
+#define CSR_ACSMCTRL10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCASPSEED_LSB				0
+#define CSR_ACSMCASPSEED_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL11 */
+#define CSR_ACSMCTRL11_LSB				0
+#define CSR_ACSMCTRL11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMRASADRINC_LSB				0
+#define CSR_ACSMRASADRINC_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMCASADRINC_LSB				8
+#define CSR_ACSMCASADRINC_MASK				GENMASK_32(15, 8)
+/* CSR_ACSMCTRL12 */
+#define CSR_ACSMCTRL12_LSB				0
+#define CSR_ACSMCTRL12_MASK				GENMASK_32(11, 0)
+#define CSR_ACSMBNKPCFG_LSB				0
+#define CSR_ACSMBNKPCFG_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMBNKPSEED_LSB				4
+#define CSR_ACSMBNKPSEED_MASK				GENMASK_32(7, 4)
+#define CSR_ACSMBNKADRINC_LSB				8
+#define CSR_ACSMBNKADRINC_MASK				GENMASK_32(11, 8)
+/* CSR_ACSMCTRL13 */
+#define CSR_ACSMCTRL13_LSB				0
+#define CSR_ACSMCTRL13_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMCKEENB_LSB				0
+#define CSR_ACSMCKEENB_MASK				GENMASK_32(3, 0)
+/* CSR_ACSMCTRL14 */
+#define CSR_ACSMCTRL14_LSB				0
+#define CSR_ACSMCTRL14_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMRASPCFGUP_LSB				0
+#define CSR_ACSMRASPCFGUP_MASK				GENMASK_32(3, 0)
+/* CSR_ACSMCTRL15 */
+#define CSR_ACSMCTRL15_LSB				0
+#define CSR_ACSMCTRL15_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMRASPSEEDUP_LSB				0
+#define CSR_ACSMRASPSEEDUP_MASK				GENMASK_32(3, 0)
+
+/* PPGC0 register offsets */
+/* CSR_PPGCCTRL1 */
+#define CSR_PPGCCTRL1_LSB				1
+#define CSR_PPGCCTRL1_MASK				GENMASK_32(4, 1)
+#define CSR_HWTTXDBIEN_LSB				1
+#define CSR_HWTTXDBIEN_MASK				BIT(1)
+#define CSR_HWTRXDBIEN_LSB				2
+#define CSR_HWTRXDBIEN_MASK				BIT(2)
+#define CSR_HWTTXDMDBIVAL_LSB				3
+#define CSR_HWTTXDMDBIVAL_MASK				BIT(3)
+#define CSR_HWTTXDMDBISEL_LSB				4
+#define CSR_HWTTXDMDBISEL_MASK				BIT(4)
+/* CSR_PPGCLANE2CRCINMAP0 */
+#define CSR_PPGCLANE2CRCINMAP0_LSB			0
+#define CSR_PPGCLANE2CRCINMAP0_MASK			GENMASK_32(11, 0)
+#define CSR_PPGCCRCLANEMAP0_LSB				0
+#define CSR_PPGCCRCLANEMAP0_MASK			GENMASK_32(2, 0)
+#define CSR_PPGCCRCLANEMAP1_LSB				3
+#define CSR_PPGCCRCLANEMAP1_MASK			GENMASK_32(5, 3)
+#define CSR_PPGCCRCLANEMAP2_LSB				6
+#define CSR_PPGCCRCLANEMAP2_MASK			GENMASK_32(8, 6)
+#define CSR_PPGCCRCLANEMAP3_LSB				9
+#define CSR_PPGCCRCLANEMAP3_MASK			GENMASK_32(11, 9)
+/* CSR_PPGCLANE2CRCINMAP1 */
+#define CSR_PPGCLANE2CRCINMAP1_LSB			0
+#define CSR_PPGCLANE2CRCINMAP1_MASK			GENMASK_32(11, 0)
+#define CSR_PPGCCRCLANEMAP4_LSB				0
+#define CSR_PPGCCRCLANEMAP4_MASK			GENMASK_32(2, 0)
+#define CSR_PPGCCRCLANEMAP5_LSB				3
+#define CSR_PPGCCRCLANEMAP5_MASK			GENMASK_32(5, 3)
+#define CSR_PPGCCRCLANEMAP6_LSB				6
+#define CSR_PPGCCRCLANEMAP6_MASK			GENMASK_32(8, 6)
+#define CSR_PPGCCRCLANEMAP7_LSB				9
+#define CSR_PPGCCRCLANEMAP7_MASK			GENMASK_32(11, 9)
+/* CSR_PRBSTAPDLY0 */
+#define CSR_PRBSTAPDLY0_LSB				0
+#define CSR_PRBSTAPDLY0_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSTAPDLY1 */
+#define CSR_PRBSTAPDLY1_LSB				0
+#define CSR_PRBSTAPDLY1_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSTAPDLY2 */
+#define CSR_PRBSTAPDLY2_LSB				0
+#define CSR_PRBSTAPDLY2_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSTAPDLY3 */
+#define CSR_PRBSTAPDLY3_LSB				0
+#define CSR_PRBSTAPDLY3_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE0 */
+#define CSR_GENPRBSBYTE0_LSB				0
+#define CSR_GENPRBSBYTE0_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE1² */
+#define CSR_GENPRBSBYTE1_LSB				0
+#define CSR_GENPRBSBYTE1_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE2 */
+#define CSR_GENPRBSBYTE2_LSB				0
+#define CSR_GENPRBSBYTE2_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE3 */
+#define CSR_GENPRBSBYTE3_LSB				0
+#define CSR_GENPRBSBYTE3_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE4 */
+#define CSR_GENPRBSBYTE4_LSB				0
+#define CSR_GENPRBSBYTE4_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE5 */
+#define CSR_GENPRBSBYTE5_LSB				0
+#define CSR_GENPRBSBYTE5_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE6 */
+#define CSR_GENPRBSBYTE6_LSB				0
+#define CSR_GENPRBSBYTE6_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE7 */
+#define CSR_GENPRBSBYTE7_LSB				0
+#define CSR_GENPRBSBYTE7_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE8 */
+#define CSR_GENPRBSBYTE8_LSB				0
+#define CSR_GENPRBSBYTE8_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE9 */
+#define CSR_GENPRBSBYTE9_LSB				0
+#define CSR_GENPRBSBYTE9_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE10 */
+#define CSR_GENPRBSBYTE10_LSB				0
+#define CSR_GENPRBSBYTE10_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE11 */
+#define CSR_GENPRBSBYTE11_LSB				0
+#define CSR_GENPRBSBYTE11_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE12 */
+#define CSR_GENPRBSBYTE12_LSB				0
+#define CSR_GENPRBSBYTE12_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE13 */
+#define CSR_GENPRBSBYTE13_LSB				0
+#define CSR_GENPRBSBYTE13_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE14 */
+#define CSR_GENPRBSBYTE14_LSB				0
+#define CSR_GENPRBSBYTE14_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE15 */
+#define CSR_GENPRBSBYTE15_LSB				0
+#define CSR_GENPRBSBYTE15_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSGENCTL */
+#define CSR_PRBSGENCTL_LSB				0
+#define CSR_PRBSGENCTL_MASK				GENMASK_32(6, 0)
+#define CSR_PPGCMODE_LSB				0
+#define CSR_PPGCMODE_MASK				BIT(0)
+#define CSR_PPGCDMMODE_LSB				1
+#define CSR_PPGCDMMODE_MASK				BIT(1)
+#define CSR_PPGCLDFFMODE_LSB				2
+#define CSR_PPGCLDFFMODE_MASK				BIT(2)
+#define CSR_PPGCSEL23BPRBS_LSB				3
+#define CSR_PPGCSEL23BPRBS_MASK				BIT(3)
+#define CSR_PPGCPATADV_LSB				4
+#define CSR_PPGCPATADV_MASK				GENMASK_32(5, 4)
+#define CSR_PPGCENBPATSTRESSMODE_LSB			6
+#define CSR_PPGCENBPATSTRESSMODE_MASK			BIT(6)
+/* CSR_PRBSGENSTATELO */
+#define CSR_PRBSGENSTATELO_LSB				0
+#define CSR_PRBSGENSTATELO_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSGENSTATEHI */
+#define CSR_PRBSGENSTATEHI_LSB				0
+#define CSR_PRBSGENSTATEHI_MASK				GENMASK_32(6, 0)
+/* CSR_PRBSCHKSTATELO */
+#define CSR_PRBSCHKSTATELO_LSB				0
+#define CSR_PRBSCHKSTATELO_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSCHKSTATEHI */
+#define CSR_PRBSCHKSTATEHI_LSB				0
+#define CSR_PRBSCHKSTATEHI_MASK				GENMASK_32(6, 0)
+/* CSR_PRBSGENCTL1 */
+#define CSR_PRBSGENCTL1_LSB				0
+#define CSR_PRBSGENCTL1_MASK				GENMASK_32(8, 0)
+#define CSR_PPGCMODELANE_LSB				0
+#define CSR_PPGCMODELANE_MASK				GENMASK_32(8, 0)
+/* CSR_PRBSGENCTL2 */
+#define CSR_PRBSGENCTL2_LSB				0
+#define CSR_PRBSGENCTL2_MASK				GENMASK_32(15, 0)
+#define CSR_PPGCMSKPERIODLIM_LSB			0
+#define CSR_PPGCMSKPERIODLIM_MASK			GENMASK_32(15, 0)
+
+/* INITENG0 register offsets */
+/* CSR_PRESEQUENCEREG0B0S0 */
+#define CSR_PRESEQUENCEREG0B0S0_LSB			0
+#define CSR_PRESEQUENCEREG0B0S0_MASK			GENMASK_32(15, 0)
+/* CSR_PRESEQUENCEREG0B0S1 */
+#define CSR_PRESEQUENCEREG0B0S1_LSB			0
+#define CSR_PRESEQUENCEREG0B0S1_MASK			GENMASK_32(15, 0)
+/* CSR_PRESEQUENCEREG0B0S2 */
+#define CSR_PRESEQUENCEREG0B0S2_LSB			0
+#define CSR_PRESEQUENCEREG0B0S2_MASK			GENMASK_32(8, 0)
+/* CSR_PRESEQUENCEREG0B1S0 */
+#define CSR_PRESEQUENCEREG0B1S0_LSB			0
+#define CSR_PRESEQUENCEREG0B1S0_MASK			GENMASK_32(15, 0)
+/* CSR_PRESEQUENCEREG0B1S1 */
+#define CSR_PRESEQUENCEREG0B1S1_LSB			0
+#define CSR_PRESEQUENCEREG0B1S1_MASK			GENMASK_32(15, 0)
+/* CSR_PRESEQUENCEREG0B1S2 */
+#define CSR_PRESEQUENCEREG0B1S2_LSB			0
+#define CSR_PRESEQUENCEREG0B1S2_MASK			GENMASK_32(8, 0)
+/* CSR_POSTSEQUENCEREG0B0S0 */
+#define CSR_POSTSEQUENCEREG0B0S0_LSB			0
+#define CSR_POSTSEQUENCEREG0B0S0_MASK			GENMASK_32(15, 0)
+/* CSR_POSTSEQUENCEREG0B0S1 */
+#define CSR_POSTSEQUENCEREG0B0S1_LSB			0
+#define CSR_POSTSEQUENCEREG0B0S1_MASK			GENMASK_32(15, 0)
+/* CSR_POSTSEQUENCEREG0B0S2 */
+#define CSR_POSTSEQUENCEREG0B0S2_LSB			0
+#define CSR_POSTSEQUENCEREG0B0S2_MASK			GENMASK_32(8, 0)
+/* CSR_POSTSEQUENCEREG0B1S0 */
+#define CSR_POSTSEQUENCEREG0B1S0_LSB			0
+#define CSR_POSTSEQUENCEREG0B1S0_MASK			GENMASK_32(15, 0)
+/* CSR_POSTSEQUENCEREG0B1S1 */
+#define CSR_POSTSEQUENCEREG0B1S1_LSB			0
+#define CSR_POSTSEQUENCEREG0B1S1_MASK			GENMASK_32(15, 0)
+/* CSR_POSTSEQUENCEREG0B1S2 */
+#define CSR_POSTSEQUENCEREG0B1S2_LSB			0
+#define CSR_POSTSEQUENCEREG0B1S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQ0BDISABLEFLAG0 */
+#define CSR_SEQ0BDISABLEFLAG0_LSB			0
+#define CSR_SEQ0BDISABLEFLAG0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG1 */
+#define CSR_SEQ0BDISABLEFLAG1_LSB			0
+#define CSR_SEQ0BDISABLEFLAG1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG2 */
+#define CSR_SEQ0BDISABLEFLAG2_LSB			0
+#define CSR_SEQ0BDISABLEFLAG2_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG3 */
+#define CSR_SEQ0BDISABLEFLAG3_LSB			0
+#define CSR_SEQ0BDISABLEFLAG3_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG4 */
+#define CSR_SEQ0BDISABLEFLAG4_LSB			0
+#define CSR_SEQ0BDISABLEFLAG4_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG5 */
+#define CSR_SEQ0BDISABLEFLAG5_LSB			0
+#define CSR_SEQ0BDISABLEFLAG5_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG6 */
+#define CSR_SEQ0BDISABLEFLAG6_LSB			0
+#define CSR_SEQ0BDISABLEFLAG6_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG7 */
+#define CSR_SEQ0BDISABLEFLAG7_LSB			0
+#define CSR_SEQ0BDISABLEFLAG7_MASK			GENMASK_32(15, 0)
+/* CSR_STARTVECTOR0B0 */
+#define CSR_STARTVECTOR0B0_LSB				0
+#define CSR_STARTVECTOR0B0_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC0_LSB				0
+#define CSR_SEQ0BSTARTVEC0_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B1 */
+#define CSR_STARTVECTOR0B1_LSB				0
+#define CSR_STARTVECTOR0B1_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC1_LSB				0
+#define CSR_SEQ0BSTARTVEC1_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B2 */
+#define CSR_STARTVECTOR0B2_LSB				0
+#define CSR_STARTVECTOR0B2_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC2_LSB				0
+#define CSR_SEQ0BSTARTVEC2_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B3 */
+#define CSR_STARTVECTOR0B3_LSB				0
+#define CSR_STARTVECTOR0B3_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC3_LSB				0
+#define CSR_SEQ0BSTARTVEC3_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B4 */
+#define CSR_STARTVECTOR0B4_LSB				0
+#define CSR_STARTVECTOR0B4_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC4_LSB				0
+#define CSR_SEQ0BSTARTVEC4_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B5 */
+#define CSR_STARTVECTOR0B5_LSB				0
+#define CSR_STARTVECTOR0B5_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC5_LSB				0
+#define CSR_SEQ0BSTARTVEC5_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B6 */
+#define CSR_STARTVECTOR0B6_LSB				0
+#define CSR_STARTVECTOR0B6_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC6_LSB				0
+#define CSR_SEQ0BSTARTVEC6_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B7 */
+#define CSR_STARTVECTOR0B7_LSB				0
+#define CSR_STARTVECTOR0B7_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC7_LSB				0
+#define CSR_SEQ0BSTARTVEC7_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B8 */
+#define CSR_STARTVECTOR0B8_LSB				0
+#define CSR_STARTVECTOR0B8_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC8_LSB				0
+#define CSR_SEQ0BSTARTVEC8_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B9 */
+#define CSR_STARTVECTOR0B9_LSB				0
+#define CSR_STARTVECTOR0B9_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC9_LSB				0
+#define CSR_SEQ0BSTARTVEC9_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B10 */
+#define CSR_STARTVECTOR0B10_LSB				0
+#define CSR_STARTVECTOR0B10_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC10_LSB				0
+#define CSR_SEQ0BSTARTVEC10_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B11 */
+#define CSR_STARTVECTOR0B11_LSB				0
+#define CSR_STARTVECTOR0B11_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC11_LSB				0
+#define CSR_SEQ0BSTARTVEC11_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B12 */
+#define CSR_STARTVECTOR0B12_LSB				0
+#define CSR_STARTVECTOR0B12_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC12_LSB				0
+#define CSR_SEQ0BSTARTVEC12_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B13 */
+#define CSR_STARTVECTOR0B13_LSB				0
+#define CSR_STARTVECTOR0B13_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC13_LSB				0
+#define CSR_SEQ0BSTARTVEC13_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B14 */
+#define CSR_STARTVECTOR0B14_LSB				0
+#define CSR_STARTVECTOR0B14_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC14_LSB				0
+#define CSR_SEQ0BSTARTVEC14_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B15 */
+#define CSR_STARTVECTOR0B15_LSB				0
+#define CSR_STARTVECTOR0B15_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC15_LSB				0
+#define CSR_SEQ0BSTARTVEC15_MASK			GENMASK_32(6, 0)
+/* CSR_SEQ0BWAITCONDSEL */
+#define CSR_SEQ0BWAITCONDSEL_LSB			0
+#define CSR_SEQ0BWAITCONDSEL_MASK			GENMASK_32(2, 0)
+/* CSR_PHYINLP3 */
+#define CSR_PHYINLP3_LSB				0
+#define CSR_PHYINLP3_MASK				BIT(0)
+/* CSR_SEQUENCEREG0B0S0 */
+#define CSR_SEQUENCEREG0B0S0_LSB			0
+#define CSR_SEQUENCEREG0B0S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B0S1 */
+#define CSR_SEQUENCEREG0B0S1_LSB			0
+#define CSR_SEQUENCEREG0B0S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B0S2 */
+#define CSR_SEQUENCEREG0B0S2_LSB			0
+#define CSR_SEQUENCEREG0B0S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B1S0 */
+#define CSR_SEQUENCEREG0B1S0_LSB			0
+#define CSR_SEQUENCEREG0B1S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B1S1 */
+#define CSR_SEQUENCEREG0B1S1_LSB			0
+#define CSR_SEQUENCEREG0B1S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B1S2 */
+#define CSR_SEQUENCEREG0B1S2_LSB			0
+#define CSR_SEQUENCEREG0B1S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B2S0 */
+#define CSR_SEQUENCEREG0B2S0_LSB			0
+#define CSR_SEQUENCEREG0B2S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B2S1 */
+#define CSR_SEQUENCEREG0B2S1_LSB			0
+#define CSR_SEQUENCEREG0B2S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B2S2 */
+#define CSR_SEQUENCEREG0B2S2_LSB			0
+#define CSR_SEQUENCEREG0B2S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B3S0 */
+#define CSR_SEQUENCEREG0B3S0_LSB			0
+#define CSR_SEQUENCEREG0B3S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B3S1 */
+#define CSR_SEQUENCEREG0B3S1_LSB			0
+#define CSR_SEQUENCEREG0B3S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B3S2 */
+#define CSR_SEQUENCEREG0B3S2_LSB			0
+#define CSR_SEQUENCEREG0B3S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B4S0 */
+#define CSR_SEQUENCEREG0B4S0_LSB			0
+#define CSR_SEQUENCEREG0B4S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B4S1 */
+#define CSR_SEQUENCEREG0B4S1_LSB			0
+#define CSR_SEQUENCEREG0B4S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B4S2 */
+#define CSR_SEQUENCEREG0B4S2_LSB			0
+#define CSR_SEQUENCEREG0B4S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B5S0 */
+#define CSR_SEQUENCEREG0B5S0_LSB			0
+#define CSR_SEQUENCEREG0B5S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B5S1 */
+#define CSR_SEQUENCEREG0B5S1_LSB			0
+#define CSR_SEQUENCEREG0B5S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B5S2 */
+#define CSR_SEQUENCEREG0B5S2_LSB			0
+#define CSR_SEQUENCEREG0B5S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B6S0 */
+#define CSR_SEQUENCEREG0B6S0_LSB			0
+#define CSR_SEQUENCEREG0B6S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B6S1 */
+#define CSR_SEQUENCEREG0B6S1_LSB			0
+#define CSR_SEQUENCEREG0B6S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B6S2 */
+#define CSR_SEQUENCEREG0B6S2_LSB			0
+#define CSR_SEQUENCEREG0B6S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B7S0 */
+#define CSR_SEQUENCEREG0B7S0_LSB			0
+#define CSR_SEQUENCEREG0B7S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B7S1 */
+#define CSR_SEQUENCEREG0B7S1_LSB			0
+#define CSR_SEQUENCEREG0B7S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B7S2 */
+#define CSR_SEQUENCEREG0B7S2_LSB			0
+#define CSR_SEQUENCEREG0B7S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B8S0 */
+#define CSR_SEQUENCEREG0B8S0_LSB			0
+#define CSR_SEQUENCEREG0B8S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B8S1 */
+#define CSR_SEQUENCEREG0B8S1_LSB			0
+#define CSR_SEQUENCEREG0B8S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B8S2 */
+#define CSR_SEQUENCEREG0B8S2_LSB			0
+#define CSR_SEQUENCEREG0B8S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B9S0 */
+#define CSR_SEQUENCEREG0B9S0_LSB			0
+#define CSR_SEQUENCEREG0B9S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B9S1 */
+#define CSR_SEQUENCEREG0B9S1_LSB			0
+#define CSR_SEQUENCEREG0B9S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B9S2 */
+#define CSR_SEQUENCEREG0B9S2_LSB			0
+#define CSR_SEQUENCEREG0B9S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B10S0 */
+#define CSR_SEQUENCEREG0B10S0_LSB			0
+#define CSR_SEQUENCEREG0B10S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B10S1 */
+#define CSR_SEQUENCEREG0B10S1_LSB			0
+#define CSR_SEQUENCEREG0B10S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B10S2 */
+#define CSR_SEQUENCEREG0B10S2_LSB			0
+#define CSR_SEQUENCEREG0B10S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B11S0 */
+#define CSR_SEQUENCEREG0B11S0_LSB			0
+#define CSR_SEQUENCEREG0B11S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B11S1 */
+#define CSR_SEQUENCEREG0B11S1_LSB			0
+#define CSR_SEQUENCEREG0B11S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B11S2 */
+#define CSR_SEQUENCEREG0B11S2_LSB			0
+#define CSR_SEQUENCEREG0B11S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B12S0 */
+#define CSR_SEQUENCEREG0B12S0_LSB			0
+#define CSR_SEQUENCEREG0B12S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B12S1 */
+#define CSR_SEQUENCEREG0B12S1_LSB			0
+#define CSR_SEQUENCEREG0B12S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B12S2 */
+#define CSR_SEQUENCEREG0B12S2_LSB			0
+#define CSR_SEQUENCEREG0B12S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B13S0 */
+#define CSR_SEQUENCEREG0B13S0_LSB			0
+#define CSR_SEQUENCEREG0B13S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B13S1 */
+#define CSR_SEQUENCEREG0B13S1_LSB			0
+#define CSR_SEQUENCEREG0B13S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B13S2 */
+#define CSR_SEQUENCEREG0B13S2_LSB			0
+#define CSR_SEQUENCEREG0B13S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B14S0 */
+#define CSR_SEQUENCEREG0B14S0_LSB			0
+#define CSR_SEQUENCEREG0B14S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B14S1 */
+#define CSR_SEQUENCEREG0B14S1_LSB			0
+#define CSR_SEQUENCEREG0B14S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B14S2 */
+#define CSR_SEQUENCEREG0B14S2_LSB			0
+#define CSR_SEQUENCEREG0B14S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B15S0 */
+#define CSR_SEQUENCEREG0B15S0_LSB			0
+#define CSR_SEQUENCEREG0B15S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B15S1 */
+#define CSR_SEQUENCEREG0B15S1_LSB			0
+#define CSR_SEQUENCEREG0B15S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B15S2 */
+#define CSR_SEQUENCEREG0B15S2_LSB			0
+#define CSR_SEQUENCEREG0B15S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B16S0 */
+#define CSR_SEQUENCEREG0B16S0_LSB			0
+#define CSR_SEQUENCEREG0B16S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B16S1 */
+#define CSR_SEQUENCEREG0B16S1_LSB			0
+#define CSR_SEQUENCEREG0B16S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B16S2 */
+#define CSR_SEQUENCEREG0B16S2_LSB			0
+#define CSR_SEQUENCEREG0B16S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B17S0 */
+#define CSR_SEQUENCEREG0B17S0_LSB			0
+#define CSR_SEQUENCEREG0B17S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B17S1 */
+#define CSR_SEQUENCEREG0B17S1_LSB			0
+#define CSR_SEQUENCEREG0B17S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B17S2 */
+#define CSR_SEQUENCEREG0B17S2_LSB			0
+#define CSR_SEQUENCEREG0B17S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B18S0 */
+#define CSR_SEQUENCEREG0B18S0_LSB			0
+#define CSR_SEQUENCEREG0B18S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B18S1 */
+#define CSR_SEQUENCEREG0B18S1_LSB			0
+#define CSR_SEQUENCEREG0B18S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B18S2 */
+#define CSR_SEQUENCEREG0B18S2_LSB			0
+#define CSR_SEQUENCEREG0B18S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B19S0 */
+#define CSR_SEQUENCEREG0B19S0_LSB			0
+#define CSR_SEQUENCEREG0B19S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B19S1 */
+#define CSR_SEQUENCEREG0B19S1_LSB			0
+#define CSR_SEQUENCEREG0B19S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B19S2 */
+#define CSR_SEQUENCEREG0B19S2_LSB			0
+#define CSR_SEQUENCEREG0B19S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B20S0 */
+#define CSR_SEQUENCEREG0B20S0_LSB			0
+#define CSR_SEQUENCEREG0B20S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B20S1 */
+#define CSR_SEQUENCEREG0B20S1_LSB			0
+#define CSR_SEQUENCEREG0B20S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B20S2 */
+#define CSR_SEQUENCEREG0B20S2_LSB			0
+#define CSR_SEQUENCEREG0B20S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B21S0 */
+#define CSR_SEQUENCEREG0B21S0_LSB			0
+#define CSR_SEQUENCEREG0B21S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B21S1 */
+#define CSR_SEQUENCEREG0B21S1_LSB			0
+#define CSR_SEQUENCEREG0B21S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B21S2 */
+#define CSR_SEQUENCEREG0B21S2_LSB			0
+#define CSR_SEQUENCEREG0B21S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B22S0 */
+#define CSR_SEQUENCEREG0B22S0_LSB			0
+#define CSR_SEQUENCEREG0B22S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B22S1 */
+#define CSR_SEQUENCEREG0B22S1_LSB			0
+#define CSR_SEQUENCEREG0B22S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B22S2 */
+#define CSR_SEQUENCEREG0B22S2_LSB			0
+#define CSR_SEQUENCEREG0B22S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B23S0 */
+#define CSR_SEQUENCEREG0B23S0_LSB			0
+#define CSR_SEQUENCEREG0B23S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B23S1 */
+#define CSR_SEQUENCEREG0B23S1_LSB			0
+#define CSR_SEQUENCEREG0B23S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B23S2 */
+#define CSR_SEQUENCEREG0B23S2_LSB			0
+#define CSR_SEQUENCEREG0B23S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B24S0 */
+#define CSR_SEQUENCEREG0B24S0_LSB			0
+#define CSR_SEQUENCEREG0B24S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B24S1 */
+#define CSR_SEQUENCEREG0B24S1_LSB			0
+#define CSR_SEQUENCEREG0B24S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B24S2 */
+#define CSR_SEQUENCEREG0B24S2_LSB			0
+#define CSR_SEQUENCEREG0B24S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B25S0 */
+#define CSR_SEQUENCEREG0B25S0_LSB			0
+#define CSR_SEQUENCEREG0B25S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B25S1 */
+#define CSR_SEQUENCEREG0B25S1_LSB			0
+#define CSR_SEQUENCEREG0B25S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B25S2 */
+#define CSR_SEQUENCEREG0B25S2_LSB			0
+#define CSR_SEQUENCEREG0B25S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B26S0 */
+#define CSR_SEQUENCEREG0B26S0_LSB			0
+#define CSR_SEQUENCEREG0B26S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B26S1 */
+#define CSR_SEQUENCEREG0B26S1_LSB			0
+#define CSR_SEQUENCEREG0B26S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B26S2 */
+#define CSR_SEQUENCEREG0B26S2_LSB			0
+#define CSR_SEQUENCEREG0B26S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B27S0 */
+#define CSR_SEQUENCEREG0B27S0_LSB			0
+#define CSR_SEQUENCEREG0B27S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B27S1 */
+#define CSR_SEQUENCEREG0B27S1_LSB			0
+#define CSR_SEQUENCEREG0B27S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B27S2 */
+#define CSR_SEQUENCEREG0B27S2_LSB			0
+#define CSR_SEQUENCEREG0B27S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B28S0 */
+#define CSR_SEQUENCEREG0B28S0_LSB			0
+#define CSR_SEQUENCEREG0B28S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B28S1 */
+#define CSR_SEQUENCEREG0B28S1_LSB			0
+#define CSR_SEQUENCEREG0B28S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B28S2 */
+#define CSR_SEQUENCEREG0B28S2_LSB			0
+#define CSR_SEQUENCEREG0B28S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B29S0 */
+#define CSR_SEQUENCEREG0B29S0_LSB			0
+#define CSR_SEQUENCEREG0B29S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B29S1 */
+#define CSR_SEQUENCEREG0B29S1_LSB			0
+#define CSR_SEQUENCEREG0B29S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B29S2 */
+#define CSR_SEQUENCEREG0B29S2_LSB			0
+#define CSR_SEQUENCEREG0B29S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B30S0 */
+#define CSR_SEQUENCEREG0B30S0_LSB			0
+#define CSR_SEQUENCEREG0B30S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B30S1 */
+#define CSR_SEQUENCEREG0B30S1_LSB			0
+#define CSR_SEQUENCEREG0B30S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B30S2 */
+#define CSR_SEQUENCEREG0B30S2_LSB			0
+#define CSR_SEQUENCEREG0B30S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B31S0 */
+#define CSR_SEQUENCEREG0B31S0_LSB			0
+#define CSR_SEQUENCEREG0B31S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B31S1 */
+#define CSR_SEQUENCEREG0B31S1_LSB			0
+#define CSR_SEQUENCEREG0B31S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B31S2 */
+#define CSR_SEQUENCEREG0B31S2_LSB			0
+#define CSR_SEQUENCEREG0B31S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B32S0 */
+#define CSR_SEQUENCEREG0B32S0_LSB			0
+#define CSR_SEQUENCEREG0B32S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B32S1 */
+#define CSR_SEQUENCEREG0B32S1_LSB			0
+#define CSR_SEQUENCEREG0B32S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B32S2 */
+#define CSR_SEQUENCEREG0B32S2_LSB			0
+#define CSR_SEQUENCEREG0B32S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B33S0 */
+#define CSR_SEQUENCEREG0B33S0_LSB			0
+#define CSR_SEQUENCEREG0B33S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B33S1 */
+#define CSR_SEQUENCEREG0B33S1_LSB			0
+#define CSR_SEQUENCEREG0B33S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B33S2 */
+#define CSR_SEQUENCEREG0B33S2_LSB			0
+#define CSR_SEQUENCEREG0B33S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B34S0 */
+#define CSR_SEQUENCEREG0B34S0_LSB			0
+#define CSR_SEQUENCEREG0B34S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B34S1 */
+#define CSR_SEQUENCEREG0B34S1_LSB			0
+#define CSR_SEQUENCEREG0B34S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B34S2 */
+#define CSR_SEQUENCEREG0B34S2_LSB			0
+#define CSR_SEQUENCEREG0B34S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B35S0 */
+#define CSR_SEQUENCEREG0B35S0_LSB			0
+#define CSR_SEQUENCEREG0B35S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B35S1 */
+#define CSR_SEQUENCEREG0B35S1_LSB			0
+#define CSR_SEQUENCEREG0B35S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B35S2 */
+#define CSR_SEQUENCEREG0B35S2_LSB			0
+#define CSR_SEQUENCEREG0B35S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B36S0 */
+#define CSR_SEQUENCEREG0B36S0_LSB			0
+#define CSR_SEQUENCEREG0B36S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B36S1 */
+#define CSR_SEQUENCEREG0B36S1_LSB			0
+#define CSR_SEQUENCEREG0B36S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B36S2 */
+#define CSR_SEQUENCEREG0B36S2_LSB			0
+#define CSR_SEQUENCEREG0B36S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B37S0 */
+#define CSR_SEQUENCEREG0B37S0_LSB			0
+#define CSR_SEQUENCEREG0B37S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B37S1 */
+#define CSR_SEQUENCEREG0B37S1_LSB			0
+#define CSR_SEQUENCEREG0B37S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B37S2 */
+#define CSR_SEQUENCEREG0B37S2_LSB			0
+#define CSR_SEQUENCEREG0B37S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B38S0 */
+#define CSR_SEQUENCEREG0B38S0_LSB			0
+#define CSR_SEQUENCEREG0B38S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B38S1 */
+#define CSR_SEQUENCEREG0B38S1_LSB			0
+#define CSR_SEQUENCEREG0B38S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B38S2 */
+#define CSR_SEQUENCEREG0B38S2_LSB			0
+#define CSR_SEQUENCEREG0B38S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B39S0 */
+#define CSR_SEQUENCEREG0B39S0_LSB			0
+#define CSR_SEQUENCEREG0B39S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B39S1 */
+#define CSR_SEQUENCEREG0B39S1_LSB			0
+#define CSR_SEQUENCEREG0B39S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B39S2 */
+#define CSR_SEQUENCEREG0B39S2_LSB			0
+#define CSR_SEQUENCEREG0B39S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B40S0 */
+#define CSR_SEQUENCEREG0B40S0_LSB			0
+#define CSR_SEQUENCEREG0B40S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B40S1 */
+#define CSR_SEQUENCEREG0B40S1_LSB			0
+#define CSR_SEQUENCEREG0B40S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B40S2 */
+#define CSR_SEQUENCEREG0B40S2_LSB			0
+#define CSR_SEQUENCEREG0B40S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B41S0 */
+#define CSR_SEQUENCEREG0B41S0_LSB			0
+#define CSR_SEQUENCEREG0B41S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B41S1 */
+#define CSR_SEQUENCEREG0B41S1_LSB			0
+#define CSR_SEQUENCEREG0B41S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B41S2 */
+#define CSR_SEQUENCEREG0B41S2_LSB			0
+#define CSR_SEQUENCEREG0B41S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B42S0 */
+#define CSR_SEQUENCEREG0B42S0_LSB			0
+#define CSR_SEQUENCEREG0B42S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B42S1 */
+#define CSR_SEQUENCEREG0B42S1_LSB			0
+#define CSR_SEQUENCEREG0B42S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B42S2 */
+#define CSR_SEQUENCEREG0B42S2_LSB			0
+#define CSR_SEQUENCEREG0B42S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B43S0 */
+#define CSR_SEQUENCEREG0B43S0_LSB			0
+#define CSR_SEQUENCEREG0B43S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B43S1 */
+#define CSR_SEQUENCEREG0B43S1_LSB			0
+#define CSR_SEQUENCEREG0B43S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B43S2 */
+#define CSR_SEQUENCEREG0B43S2_LSB			0
+#define CSR_SEQUENCEREG0B43S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B44S0 */
+#define CSR_SEQUENCEREG0B44S0_LSB			0
+#define CSR_SEQUENCEREG0B44S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B44S1 */
+#define CSR_SEQUENCEREG0B44S1_LSB			0
+#define CSR_SEQUENCEREG0B44S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B44S2 */
+#define CSR_SEQUENCEREG0B44S2_LSB			0
+#define CSR_SEQUENCEREG0B44S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B45S0 */
+#define CSR_SEQUENCEREG0B45S0_LSB			0
+#define CSR_SEQUENCEREG0B45S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B45S1 */
+#define CSR_SEQUENCEREG0B45S1_LSB			0
+#define CSR_SEQUENCEREG0B45S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B45S2 */
+#define CSR_SEQUENCEREG0B45S2_LSB			0
+#define CSR_SEQUENCEREG0B45S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B46S0 */
+#define CSR_SEQUENCEREG0B46S0_LSB			0
+#define CSR_SEQUENCEREG0B46S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B46S1 */
+#define CSR_SEQUENCEREG0B46S1_LSB			0
+#define CSR_SEQUENCEREG0B46S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B46S2 */
+#define CSR_SEQUENCEREG0B46S2_LSB			0
+#define CSR_SEQUENCEREG0B46S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B47S0 */
+#define CSR_SEQUENCEREG0B47S0_LSB			0
+#define CSR_SEQUENCEREG0B47S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B47S1 */
+#define CSR_SEQUENCEREG0B47S1_LSB			0
+#define CSR_SEQUENCEREG0B47S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B47S2 */
+#define CSR_SEQUENCEREG0B47S2_LSB			0
+#define CSR_SEQUENCEREG0B47S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B48S0 */
+#define CSR_SEQUENCEREG0B48S0_LSB			0
+#define CSR_SEQUENCEREG0B48S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B48S1 */
+#define CSR_SEQUENCEREG0B48S1_LSB			0
+#define CSR_SEQUENCEREG0B48S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B48S2 */
+#define CSR_SEQUENCEREG0B48S2_LSB			0
+#define CSR_SEQUENCEREG0B48S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B49S0 */
+#define CSR_SEQUENCEREG0B49S0_LSB			0
+#define CSR_SEQUENCEREG0B49S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B49S1 */
+#define CSR_SEQUENCEREG0B49S1_LSB			0
+#define CSR_SEQUENCEREG0B49S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B49S2 */
+#define CSR_SEQUENCEREG0B49S2_LSB			0
+#define CSR_SEQUENCEREG0B49S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B50S0 */
+#define CSR_SEQUENCEREG0B50S0_LSB			0
+#define CSR_SEQUENCEREG0B50S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B50S1 */
+#define CSR_SEQUENCEREG0B50S1_LSB			0
+#define CSR_SEQUENCEREG0B50S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B50S2 */
+#define CSR_SEQUENCEREG0B50S2_LSB			0
+#define CSR_SEQUENCEREG0B50S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B51S0 */
+#define CSR_SEQUENCEREG0B51S0_LSB			0
+#define CSR_SEQUENCEREG0B51S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B51S1 */
+#define CSR_SEQUENCEREG0B51S1_LSB			0
+#define CSR_SEQUENCEREG0B51S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B51S2 */
+#define CSR_SEQUENCEREG0B51S2_LSB			0
+#define CSR_SEQUENCEREG0B51S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B52S0 */
+#define CSR_SEQUENCEREG0B52S0_LSB			0
+#define CSR_SEQUENCEREG0B52S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B52S1 */
+#define CSR_SEQUENCEREG0B52S1_LSB			0
+#define CSR_SEQUENCEREG0B52S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B52S2 */
+#define CSR_SEQUENCEREG0B52S2_LSB			0
+#define CSR_SEQUENCEREG0B52S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B53S0 */
+#define CSR_SEQUENCEREG0B53S0_LSB			0
+#define CSR_SEQUENCEREG0B53S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B53S1 */
+#define CSR_SEQUENCEREG0B53S1_LSB			0
+#define CSR_SEQUENCEREG0B53S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B53S2 */
+#define CSR_SEQUENCEREG0B53S2_LSB			0
+#define CSR_SEQUENCEREG0B53S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B54S0 */
+#define CSR_SEQUENCEREG0B54S0_LSB			0
+#define CSR_SEQUENCEREG0B54S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B54S1 */
+#define CSR_SEQUENCEREG0B54S1_LSB			0
+#define CSR_SEQUENCEREG0B54S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B54S2 */
+#define CSR_SEQUENCEREG0B54S2_LSB			0
+#define CSR_SEQUENCEREG0B54S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B55S0 */
+#define CSR_SEQUENCEREG0B55S0_LSB			0
+#define CSR_SEQUENCEREG0B55S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B55S1 */
+#define CSR_SEQUENCEREG0B55S1_LSB			0
+#define CSR_SEQUENCEREG0B55S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B55S2 */
+#define CSR_SEQUENCEREG0B55S2_LSB			0
+#define CSR_SEQUENCEREG0B55S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B56S0 */
+#define CSR_SEQUENCEREG0B56S0_LSB			0
+#define CSR_SEQUENCEREG0B56S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B56S1 */
+#define CSR_SEQUENCEREG0B56S1_LSB			0
+#define CSR_SEQUENCEREG0B56S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B56S2 */
+#define CSR_SEQUENCEREG0B56S2_LSB			0
+#define CSR_SEQUENCEREG0B56S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B57S0 */
+#define CSR_SEQUENCEREG0B57S0_LSB			0
+#define CSR_SEQUENCEREG0B57S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B57S1 */
+#define CSR_SEQUENCEREG0B57S1_LSB			0
+#define CSR_SEQUENCEREG0B57S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B57S2 */
+#define CSR_SEQUENCEREG0B57S2_LSB			0
+#define CSR_SEQUENCEREG0B57S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B58S0 */
+#define CSR_SEQUENCEREG0B58S0_LSB			0
+#define CSR_SEQUENCEREG0B58S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B58S1 */
+#define CSR_SEQUENCEREG0B58S1_LSB			0
+#define CSR_SEQUENCEREG0B58S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B58S2 */
+#define CSR_SEQUENCEREG0B58S2_LSB			0
+#define CSR_SEQUENCEREG0B58S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B59S0 */
+#define CSR_SEQUENCEREG0B59S0_LSB			0
+#define CSR_SEQUENCEREG0B59S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B59S1 */
+#define CSR_SEQUENCEREG0B59S1_LSB			0
+#define CSR_SEQUENCEREG0B59S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B59S2 */
+#define CSR_SEQUENCEREG0B59S2_LSB			0
+#define CSR_SEQUENCEREG0B59S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B60S0 */
+#define CSR_SEQUENCEREG0B60S0_LSB			0
+#define CSR_SEQUENCEREG0B60S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B60S1 */
+#define CSR_SEQUENCEREG0B60S1_LSB			0
+#define CSR_SEQUENCEREG0B60S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B60S2 */
+#define CSR_SEQUENCEREG0B60S2_LSB			0
+#define CSR_SEQUENCEREG0B60S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B61S0 */
+#define CSR_SEQUENCEREG0B61S0_LSB			0
+#define CSR_SEQUENCEREG0B61S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B61S1 */
+#define CSR_SEQUENCEREG0B61S1_LSB			0
+#define CSR_SEQUENCEREG0B61S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B61S2 */
+#define CSR_SEQUENCEREG0B61S2_LSB			0
+#define CSR_SEQUENCEREG0B61S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B62S0 */
+#define CSR_SEQUENCEREG0B62S0_LSB			0
+#define CSR_SEQUENCEREG0B62S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B62S1 */
+#define CSR_SEQUENCEREG0B62S1_LSB			0
+#define CSR_SEQUENCEREG0B62S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B62S2 */
+#define CSR_SEQUENCEREG0B62S2_LSB			0
+#define CSR_SEQUENCEREG0B62S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B63S0 */
+#define CSR_SEQUENCEREG0B63S0_LSB			0
+#define CSR_SEQUENCEREG0B63S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B63S1 */
+#define CSR_SEQUENCEREG0B63S1_LSB			0
+#define CSR_SEQUENCEREG0B63S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B63S2 */
+#define CSR_SEQUENCEREG0B63S2_LSB			0
+#define CSR_SEQUENCEREG0B63S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B64S0 */
+#define CSR_SEQUENCEREG0B64S0_LSB			0
+#define CSR_SEQUENCEREG0B64S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B64S1 */
+#define CSR_SEQUENCEREG0B64S1_LSB			0
+#define CSR_SEQUENCEREG0B64S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B64S2 */
+#define CSR_SEQUENCEREG0B64S2_LSB			0
+#define CSR_SEQUENCEREG0B64S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B65S0 */
+#define CSR_SEQUENCEREG0B65S0_LSB			0
+#define CSR_SEQUENCEREG0B65S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B65S1 */
+#define CSR_SEQUENCEREG0B65S1_LSB			0
+#define CSR_SEQUENCEREG0B65S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B65S2 */
+#define CSR_SEQUENCEREG0B65S2_LSB			0
+#define CSR_SEQUENCEREG0B65S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B66S0 */
+#define CSR_SEQUENCEREG0B66S0_LSB			0
+#define CSR_SEQUENCEREG0B66S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B66S1 */
+#define CSR_SEQUENCEREG0B66S1_LSB			0
+#define CSR_SEQUENCEREG0B66S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B66S2 */
+#define CSR_SEQUENCEREG0B66S2_LSB			0
+#define CSR_SEQUENCEREG0B66S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B67S0 */
+#define CSR_SEQUENCEREG0B67S0_LSB			0
+#define CSR_SEQUENCEREG0B67S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B67S1 */
+#define CSR_SEQUENCEREG0B67S1_LSB			0
+#define CSR_SEQUENCEREG0B67S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B67S2 */
+#define CSR_SEQUENCEREG0B67S2_LSB			0
+#define CSR_SEQUENCEREG0B67S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B68S0 */
+#define CSR_SEQUENCEREG0B68S0_LSB			0
+#define CSR_SEQUENCEREG0B68S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B68S1 */
+#define CSR_SEQUENCEREG0B68S1_LSB			0
+#define CSR_SEQUENCEREG0B68S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B68S2 */
+#define CSR_SEQUENCEREG0B68S2_LSB			0
+#define CSR_SEQUENCEREG0B68S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B69S0 */
+#define CSR_SEQUENCEREG0B69S0_LSB			0
+#define CSR_SEQUENCEREG0B69S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B69S1 */
+#define CSR_SEQUENCEREG0B69S1_LSB			0
+#define CSR_SEQUENCEREG0B69S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B69S2 */
+#define CSR_SEQUENCEREG0B69S2_LSB			0
+#define CSR_SEQUENCEREG0B69S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B70S0 */
+#define CSR_SEQUENCEREG0B70S0_LSB			0
+#define CSR_SEQUENCEREG0B70S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B70S1 */
+#define CSR_SEQUENCEREG0B70S1_LSB			0
+#define CSR_SEQUENCEREG0B70S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B70S2 */
+#define CSR_SEQUENCEREG0B70S2_LSB			0
+#define CSR_SEQUENCEREG0B70S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B71S0 */
+#define CSR_SEQUENCEREG0B71S0_LSB			0
+#define CSR_SEQUENCEREG0B71S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B71S1 */
+#define CSR_SEQUENCEREG0B71S1_LSB			0
+#define CSR_SEQUENCEREG0B71S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B71S2 */
+#define CSR_SEQUENCEREG0B71S2_LSB			0
+#define CSR_SEQUENCEREG0B71S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B72S0 */
+#define CSR_SEQUENCEREG0B72S0_LSB			0
+#define CSR_SEQUENCEREG0B72S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B72S1 */
+#define CSR_SEQUENCEREG0B72S1_LSB			0
+#define CSR_SEQUENCEREG0B72S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B72S2 */
+#define CSR_SEQUENCEREG0B72S2_LSB			0
+#define CSR_SEQUENCEREG0B72S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B73S0 */
+#define CSR_SEQUENCEREG0B73S0_LSB			0
+#define CSR_SEQUENCEREG0B73S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B73S1 */
+#define CSR_SEQUENCEREG0B73S1_LSB			0
+#define CSR_SEQUENCEREG0B73S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B73S2 */
+#define CSR_SEQUENCEREG0B73S2_LSB			0
+#define CSR_SEQUENCEREG0B73S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B74S0 */
+#define CSR_SEQUENCEREG0B74S0_LSB			0
+#define CSR_SEQUENCEREG0B74S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B74S1 */
+#define CSR_SEQUENCEREG0B74S1_LSB			0
+#define CSR_SEQUENCEREG0B74S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B74S2 */
+#define CSR_SEQUENCEREG0B74S2_LSB			0
+#define CSR_SEQUENCEREG0B74S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B75S0 */
+#define CSR_SEQUENCEREG0B75S0_LSB			0
+#define CSR_SEQUENCEREG0B75S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B75S1 */
+#define CSR_SEQUENCEREG0B75S1_LSB			0
+#define CSR_SEQUENCEREG0B75S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B75S2 */
+#define CSR_SEQUENCEREG0B75S2_LSB			0
+#define CSR_SEQUENCEREG0B75S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B76S0 */
+#define CSR_SEQUENCEREG0B76S0_LSB			0
+#define CSR_SEQUENCEREG0B76S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B76S1 */
+#define CSR_SEQUENCEREG0B76S1_LSB			0
+#define CSR_SEQUENCEREG0B76S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B76S2 */
+#define CSR_SEQUENCEREG0B76S2_LSB			0
+#define CSR_SEQUENCEREG0B76S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B77S0 */
+#define CSR_SEQUENCEREG0B77S0_LSB			0
+#define CSR_SEQUENCEREG0B77S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B77S1 */
+#define CSR_SEQUENCEREG0B77S1_LSB			0
+#define CSR_SEQUENCEREG0B77S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B77S2 */
+#define CSR_SEQUENCEREG0B77S2_LSB			0
+#define CSR_SEQUENCEREG0B77S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B78S0 */
+#define CSR_SEQUENCEREG0B78S0_LSB			0
+#define CSR_SEQUENCEREG0B78S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B78S1 */
+#define CSR_SEQUENCEREG0B78S1_LSB			0
+#define CSR_SEQUENCEREG0B78S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B78S2 */
+#define CSR_SEQUENCEREG0B78S2_LSB			0
+#define CSR_SEQUENCEREG0B78S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B79S0 */
+#define CSR_SEQUENCEREG0B79S0_LSB			0
+#define CSR_SEQUENCEREG0B79S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B79S1 */
+#define CSR_SEQUENCEREG0B79S1_LSB			0
+#define CSR_SEQUENCEREG0B79S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B79S2 */
+#define CSR_SEQUENCEREG0B79S2_LSB			0
+#define CSR_SEQUENCEREG0B79S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B80S0 */
+#define CSR_SEQUENCEREG0B80S0_LSB			0
+#define CSR_SEQUENCEREG0B80S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B80S1 */
+#define CSR_SEQUENCEREG0B80S1_LSB			0
+#define CSR_SEQUENCEREG0B80S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B80S2 */
+#define CSR_SEQUENCEREG0B80S2_LSB			0
+#define CSR_SEQUENCEREG0B80S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B81S0 */
+#define CSR_SEQUENCEREG0B81S0_LSB			0
+#define CSR_SEQUENCEREG0B81S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B81S1 */
+#define CSR_SEQUENCEREG0B81S1_LSB			0
+#define CSR_SEQUENCEREG0B81S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B81S2 */
+#define CSR_SEQUENCEREG0B81S2_LSB			0
+#define CSR_SEQUENCEREG0B81S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B82S0 */
+#define CSR_SEQUENCEREG0B82S0_LSB			0
+#define CSR_SEQUENCEREG0B82S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B82S1 */
+#define CSR_SEQUENCEREG0B82S1_LSB			0
+#define CSR_SEQUENCEREG0B82S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B82S2 */
+#define CSR_SEQUENCEREG0B82S2_LSB			0
+#define CSR_SEQUENCEREG0B82S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B83S0 */
+#define CSR_SEQUENCEREG0B83S0_LSB			0
+#define CSR_SEQUENCEREG0B83S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B83S1 */
+#define CSR_SEQUENCEREG0B83S1_LSB			0
+#define CSR_SEQUENCEREG0B83S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B83S2 */
+#define CSR_SEQUENCEREG0B83S2_LSB			0
+#define CSR_SEQUENCEREG0B83S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B84S0 */
+#define CSR_SEQUENCEREG0B84S0_LSB			0
+#define CSR_SEQUENCEREG0B84S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B84S1 */
+#define CSR_SEQUENCEREG0B84S1_LSB			0
+#define CSR_SEQUENCEREG0B84S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B84S2 */
+#define CSR_SEQUENCEREG0B84S2_LSB			0
+#define CSR_SEQUENCEREG0B84S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B85S0 */
+#define CSR_SEQUENCEREG0B85S0_LSB			0
+#define CSR_SEQUENCEREG0B85S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B85S1 */
+#define CSR_SEQUENCEREG0B85S1_LSB			0
+#define CSR_SEQUENCEREG0B85S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B85S2 */
+#define CSR_SEQUENCEREG0B85S2_LSB			0
+#define CSR_SEQUENCEREG0B85S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B86S0 */
+#define CSR_SEQUENCEREG0B86S0_LSB			0
+#define CSR_SEQUENCEREG0B86S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B86S1 */
+#define CSR_SEQUENCEREG0B86S1_LSB			0
+#define CSR_SEQUENCEREG0B86S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B86S2 */
+#define CSR_SEQUENCEREG0B86S2_LSB			0
+#define CSR_SEQUENCEREG0B86S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B87S0 */
+#define CSR_SEQUENCEREG0B87S0_LSB			0
+#define CSR_SEQUENCEREG0B87S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B87S1 */
+#define CSR_SEQUENCEREG0B87S1_LSB			0
+#define CSR_SEQUENCEREG0B87S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B87S2 */
+#define CSR_SEQUENCEREG0B87S2_LSB			0
+#define CSR_SEQUENCEREG0B87S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B88S0 */
+#define CSR_SEQUENCEREG0B88S0_LSB			0
+#define CSR_SEQUENCEREG0B88S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B88S1 */
+#define CSR_SEQUENCEREG0B88S1_LSB			0
+#define CSR_SEQUENCEREG0B88S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B88S2 */
+#define CSR_SEQUENCEREG0B88S2_LSB			0
+#define CSR_SEQUENCEREG0B88S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B89S0 */
+#define CSR_SEQUENCEREG0B89S0_LSB			0
+#define CSR_SEQUENCEREG0B89S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B89S1 */
+#define CSR_SEQUENCEREG0B89S1_LSB			0
+#define CSR_SEQUENCEREG0B89S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B89S2 */
+#define CSR_SEQUENCEREG0B89S2_LSB			0
+#define CSR_SEQUENCEREG0B89S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B90S0 */
+#define CSR_SEQUENCEREG0B90S0_LSB			0
+#define CSR_SEQUENCEREG0B90S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B90S1 */
+#define CSR_SEQUENCEREG0B90S1_LSB			0
+#define CSR_SEQUENCEREG0B90S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B90S2 */
+#define CSR_SEQUENCEREG0B90S2_LSB			0
+#define CSR_SEQUENCEREG0B90S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B91S0 */
+#define CSR_SEQUENCEREG0B91S0_LSB			0
+#define CSR_SEQUENCEREG0B91S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B91S1 */
+#define CSR_SEQUENCEREG0B91S1_LSB			0
+#define CSR_SEQUENCEREG0B91S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B91S2 */
+#define CSR_SEQUENCEREG0B91S2_LSB			0
+#define CSR_SEQUENCEREG0B91S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B92S0 */
+#define CSR_SEQUENCEREG0B92S0_LSB			0
+#define CSR_SEQUENCEREG0B92S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B92S1 */
+#define CSR_SEQUENCEREG0B92S1_LSB			0
+#define CSR_SEQUENCEREG0B92S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B92S2 */
+#define CSR_SEQUENCEREG0B92S2_LSB			0
+#define CSR_SEQUENCEREG0B92S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B93S0 */
+#define CSR_SEQUENCEREG0B93S0_LSB			0
+#define CSR_SEQUENCEREG0B93S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B93S1 */
+#define CSR_SEQUENCEREG0B93S1_LSB			0
+#define CSR_SEQUENCEREG0B93S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B93S2 */
+#define CSR_SEQUENCEREG0B93S2_LSB			0
+#define CSR_SEQUENCEREG0B93S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B94S0 */
+#define CSR_SEQUENCEREG0B94S0_LSB			0
+#define CSR_SEQUENCEREG0B94S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B94S1 */
+#define CSR_SEQUENCEREG0B94S1_LSB			0
+#define CSR_SEQUENCEREG0B94S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B94S2 */
+#define CSR_SEQUENCEREG0B94S2_LSB			0
+#define CSR_SEQUENCEREG0B94S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B95S0 */
+#define CSR_SEQUENCEREG0B95S0_LSB			0
+#define CSR_SEQUENCEREG0B95S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B95S1 */
+#define CSR_SEQUENCEREG0B95S1_LSB			0
+#define CSR_SEQUENCEREG0B95S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B95S2 */
+#define CSR_SEQUENCEREG0B95S2_LSB			0
+#define CSR_SEQUENCEREG0B95S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B96S0 */
+#define CSR_SEQUENCEREG0B96S0_LSB			0
+#define CSR_SEQUENCEREG0B96S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B96S1 */
+#define CSR_SEQUENCEREG0B96S1_LSB			0
+#define CSR_SEQUENCEREG0B96S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B96S2 */
+#define CSR_SEQUENCEREG0B96S2_LSB			0
+#define CSR_SEQUENCEREG0B96S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B97S0 */
+#define CSR_SEQUENCEREG0B97S0_LSB			0
+#define CSR_SEQUENCEREG0B97S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B97S1 */
+#define CSR_SEQUENCEREG0B97S1_LSB			0
+#define CSR_SEQUENCEREG0B97S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B97S2 */
+#define CSR_SEQUENCEREG0B97S2_LSB			0
+#define CSR_SEQUENCEREG0B97S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B98S0 */
+#define CSR_SEQUENCEREG0B98S0_LSB			0
+#define CSR_SEQUENCEREG0B98S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B98S1 */
+#define CSR_SEQUENCEREG0B98S1_LSB			0
+#define CSR_SEQUENCEREG0B98S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B98S2 */
+#define CSR_SEQUENCEREG0B98S2_LSB			0
+#define CSR_SEQUENCEREG0B98S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B99S0 */
+#define CSR_SEQUENCEREG0B99S0_LSB			0
+#define CSR_SEQUENCEREG0B99S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B99S1 */
+#define CSR_SEQUENCEREG0B99S1_LSB			0
+#define CSR_SEQUENCEREG0B99S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B99S2 */
+#define CSR_SEQUENCEREG0B99S2_LSB			0
+#define CSR_SEQUENCEREG0B99S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B100S0 */
+#define CSR_SEQUENCEREG0B100S0_LSB			0
+#define CSR_SEQUENCEREG0B100S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B100S1 */
+#define CSR_SEQUENCEREG0B100S1_LSB			0
+#define CSR_SEQUENCEREG0B100S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B100S2 */
+#define CSR_SEQUENCEREG0B100S2_LSB			0
+#define CSR_SEQUENCEREG0B100S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B101S0 */
+#define CSR_SEQUENCEREG0B101S0_LSB			0
+#define CSR_SEQUENCEREG0B101S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B101S1 */
+#define CSR_SEQUENCEREG0B101S1_LSB			0
+#define CSR_SEQUENCEREG0B101S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B101S2 */
+#define CSR_SEQUENCEREG0B101S2_LSB			0
+#define CSR_SEQUENCEREG0B101S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B102S0 */
+#define CSR_SEQUENCEREG0B102S0_LSB			0
+#define CSR_SEQUENCEREG0B102S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B102S1 */
+#define CSR_SEQUENCEREG0B102S1_LSB			0
+#define CSR_SEQUENCEREG0B102S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B102S2 */
+#define CSR_SEQUENCEREG0B102S2_LSB			0
+#define CSR_SEQUENCEREG0B102S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B103S0 */
+#define CSR_SEQUENCEREG0B103S0_LSB			0
+#define CSR_SEQUENCEREG0B103S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B103S1 */
+#define CSR_SEQUENCEREG0B103S1_LSB			0
+#define CSR_SEQUENCEREG0B103S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B103S2 */
+#define CSR_SEQUENCEREG0B103S2_LSB			0
+#define CSR_SEQUENCEREG0B103S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B104S0 */
+#define CSR_SEQUENCEREG0B104S0_LSB			0
+#define CSR_SEQUENCEREG0B104S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B104S1 */
+#define CSR_SEQUENCEREG0B104S1_LSB			0
+#define CSR_SEQUENCEREG0B104S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B104S2 */
+#define CSR_SEQUENCEREG0B104S2_LSB			0
+#define CSR_SEQUENCEREG0B104S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B105S0 */
+#define CSR_SEQUENCEREG0B105S0_LSB			0
+#define CSR_SEQUENCEREG0B105S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B105S1 */
+#define CSR_SEQUENCEREG0B105S1_LSB			0
+#define CSR_SEQUENCEREG0B105S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B105S2 */
+#define CSR_SEQUENCEREG0B105S2_LSB			0
+#define CSR_SEQUENCEREG0B105S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B106S0 */
+#define CSR_SEQUENCEREG0B106S0_LSB			0
+#define CSR_SEQUENCEREG0B106S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B106S1 */
+#define CSR_SEQUENCEREG0B106S1_LSB			0
+#define CSR_SEQUENCEREG0B106S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B106S2 */
+#define CSR_SEQUENCEREG0B106S2_LSB			0
+#define CSR_SEQUENCEREG0B106S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B107S0 */
+#define CSR_SEQUENCEREG0B107S0_LSB			0
+#define CSR_SEQUENCEREG0B107S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B107S1 */
+#define CSR_SEQUENCEREG0B107S1_LSB			0
+#define CSR_SEQUENCEREG0B107S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B107S2 */
+#define CSR_SEQUENCEREG0B107S2_LSB			0
+#define CSR_SEQUENCEREG0B107S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B108S0 */
+#define CSR_SEQUENCEREG0B108S0_LSB			0
+#define CSR_SEQUENCEREG0B108S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B108S1 */
+#define CSR_SEQUENCEREG0B108S1_LSB			0
+#define CSR_SEQUENCEREG0B108S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B108S2 */
+#define CSR_SEQUENCEREG0B108S2_LSB			0
+#define CSR_SEQUENCEREG0B108S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B109S0 */
+#define CSR_SEQUENCEREG0B109S0_LSB			0
+#define CSR_SEQUENCEREG0B109S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B109S1 */
+#define CSR_SEQUENCEREG0B109S1_LSB			0
+#define CSR_SEQUENCEREG0B109S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B109S2 */
+#define CSR_SEQUENCEREG0B109S2_LSB			0
+#define CSR_SEQUENCEREG0B109S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B110S0 */
+#define CSR_SEQUENCEREG0B110S0_LSB			0
+#define CSR_SEQUENCEREG0B110S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B110S1 */
+#define CSR_SEQUENCEREG0B110S1_LSB			0
+#define CSR_SEQUENCEREG0B110S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B110S2 */
+#define CSR_SEQUENCEREG0B110S2_LSB			0
+#define CSR_SEQUENCEREG0B110S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B111S0 */
+#define CSR_SEQUENCEREG0B111S0_LSB			0
+#define CSR_SEQUENCEREG0B111S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B111S1 */
+#define CSR_SEQUENCEREG0B111S1_LSB			0
+#define CSR_SEQUENCEREG0B111S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B111S2 */
+#define CSR_SEQUENCEREG0B111S2_LSB			0
+#define CSR_SEQUENCEREG0B111S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B112S0 */
+#define CSR_SEQUENCEREG0B112S0_LSB			0
+#define CSR_SEQUENCEREG0B112S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B112S1 */
+#define CSR_SEQUENCEREG0B112S1_LSB			0
+#define CSR_SEQUENCEREG0B112S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B112S2 */
+#define CSR_SEQUENCEREG0B112S2_LSB			0
+#define CSR_SEQUENCEREG0B112S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B113S0 */
+#define CSR_SEQUENCEREG0B113S0_LSB			0
+#define CSR_SEQUENCEREG0B113S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B113S1 */
+#define CSR_SEQUENCEREG0B113S1_LSB			0
+#define CSR_SEQUENCEREG0B113S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B113S2 */
+#define CSR_SEQUENCEREG0B113S2_LSB			0
+#define CSR_SEQUENCEREG0B113S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B114S0 */
+#define CSR_SEQUENCEREG0B114S0_LSB			0
+#define CSR_SEQUENCEREG0B114S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B114S1 */
+#define CSR_SEQUENCEREG0B114S1_LSB			0
+#define CSR_SEQUENCEREG0B114S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B114S2 */
+#define CSR_SEQUENCEREG0B114S2_LSB			0
+#define CSR_SEQUENCEREG0B114S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B115S0 */
+#define CSR_SEQUENCEREG0B115S0_LSB			0
+#define CSR_SEQUENCEREG0B115S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B115S1 */
+#define CSR_SEQUENCEREG0B115S1_LSB			0
+#define CSR_SEQUENCEREG0B115S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B115S2 */
+#define CSR_SEQUENCEREG0B115S2_LSB			0
+#define CSR_SEQUENCEREG0B115S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B116S0 */
+#define CSR_SEQUENCEREG0B116S0_LSB			0
+#define CSR_SEQUENCEREG0B116S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B116S1 */
+#define CSR_SEQUENCEREG0B116S1_LSB			0
+#define CSR_SEQUENCEREG0B116S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B116S2 */
+#define CSR_SEQUENCEREG0B116S2_LSB			0
+#define CSR_SEQUENCEREG0B116S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B117S0 */
+#define CSR_SEQUENCEREG0B117S0_LSB			0
+#define CSR_SEQUENCEREG0B117S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B117S1 */
+#define CSR_SEQUENCEREG0B117S1_LSB			0
+#define CSR_SEQUENCEREG0B117S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B117S2 */
+#define CSR_SEQUENCEREG0B117S2_LSB			0
+#define CSR_SEQUENCEREG0B117S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B118S0 */
+#define CSR_SEQUENCEREG0B118S0_LSB			0
+#define CSR_SEQUENCEREG0B118S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B118S1 */
+#define CSR_SEQUENCEREG0B118S1_LSB			0
+#define CSR_SEQUENCEREG0B118S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B118S2 */
+#define CSR_SEQUENCEREG0B118S2_LSB			0
+#define CSR_SEQUENCEREG0B118S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B119S0 */
+#define CSR_SEQUENCEREG0B119S0_LSB			0
+#define CSR_SEQUENCEREG0B119S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B119S1 */
+#define CSR_SEQUENCEREG0B119S1_LSB			0
+#define CSR_SEQUENCEREG0B119S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B119S2 */
+#define CSR_SEQUENCEREG0B119S2_LSB			0
+#define CSR_SEQUENCEREG0B119S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B120S0 */
+#define CSR_SEQUENCEREG0B120S0_LSB			0
+#define CSR_SEQUENCEREG0B120S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B120S1 */
+#define CSR_SEQUENCEREG0B120S1_LSB			0
+#define CSR_SEQUENCEREG0B120S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B120S2 */
+#define CSR_SEQUENCEREG0B120S2_LSB			0
+#define CSR_SEQUENCEREG0B120S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B121S0 */
+#define CSR_SEQUENCEREG0B121S0_LSB			0
+#define CSR_SEQUENCEREG0B121S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B121S1 */
+#define CSR_SEQUENCEREG0B121S1_LSB			0
+#define CSR_SEQUENCEREG0B121S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B121S2 */
+#define CSR_SEQUENCEREG0B121S2_LSB			0
+#define CSR_SEQUENCEREG0B121S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQ0BGPR1 */
+#define CSR_SEQ0BGPR1_LSB				0
+#define CSR_SEQ0BGPR1_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR2 */
+#define CSR_SEQ0BGPR2_LSB				0
+#define CSR_SEQ0BGPR2_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR3 */
+#define CSR_SEQ0BGPR3_LSB				0
+#define CSR_SEQ0BGPR3_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR4 */
+#define CSR_SEQ0BGPR4_LSB				0
+#define CSR_SEQ0BGPR4_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR5 */
+#define CSR_SEQ0BGPR5_LSB				0
+#define CSR_SEQ0BGPR5_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR6 */
+#define CSR_SEQ0BGPR6_LSB				0
+#define CSR_SEQ0BGPR6_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR7 */
+#define CSR_SEQ0BGPR7_LSB				0
+#define CSR_SEQ0BGPR7_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR8 */
+#define CSR_SEQ0BGPR8_LSB				0
+#define CSR_SEQ0BGPR8_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BFIXEDADDRBITS */
+#define CSR_SEQ0BFIXEDADDRBITS_LSB			0
+#define CSR_SEQ0BFIXEDADDRBITS_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BCHIPLETBITS_LSB			0
+#define CSR_SEQ0BCHIPLETBITS_MASK			GENMASK_32(3, 0)
+#define CSR_SEQ0BPSTATEBITS_LSB				4
+#define CSR_SEQ0BPSTATEBITS_MASK			GENMASK_32(6, 4)
+
+/* DRTUB0 register offsets */
+/* CSR_DCTSHADOWREGS */
+#define CSR_DCTSHADOWREGS_LSB				0
+#define CSR_DCTSHADOWREGS_MASK				BIT(0)
+#define CSR_DCTWRITEPROTSHADOW_LSB			0
+#define CSR_DCTWRITEPROTSHADOW_MASK			BIT(0)
+/* CSR_DCTWRITEONLYSHADOW */
+#define CSR_DCTWRITEONLYSHADOW_LSB			0
+#define CSR_DCTWRITEONLYSHADOW_MASK			GENMASK_32(15, 0)
+/* CSR_UCTWRITEONLY */
+#define CSR_UCTWRITEONLY_LSB				0
+#define CSR_UCTWRITEONLY_MASK				GENMASK_32(15, 0)
+/* CSR_UCTWRITEPROT */
+#define CSR_UCTWRITEPROT_LSB				0
+#define CSR_UCTWRITEPROT_MASK				BIT(0)
+/* CSR_UCTDATWRITEONLY */
+#define CSR_UCTDATWRITEONLY_LSB				0
+#define CSR_UCTDATWRITEONLY_MASK			GENMASK_32(15, 0)
+/* CSR_UCTDATWRITEPROT */
+#define CSR_UCTDATWRITEPROT_LSB				0
+#define CSR_UCTDATWRITEPROT_MASK			BIT(0)
+/* CSR_UCTLERR */
+#define CSR_UCTLERR_LSB					0
+#define CSR_UCTLERR_MASK				BIT(0)
+/* CSR_UCCLKHCLKENABLES */
+#define CSR_UCCLKHCLKENABLES_LSB			0
+#define CSR_UCCLKHCLKENABLES_MASK			GENMASK_32(1, 0)
+#define CSR_UCCLKEN_LSB					0
+#define CSR_UCCLKEN_MASK				BIT(0)
+#define CSR_HCLKEN_LSB					1
+#define CSR_HCLKEN_MASK					BIT(1)
+/* CSR_CURPSTATE0B */
+#define CSR_CURPSTATE0B_LSB				0
+#define CSR_CURPSTATE0B_MASK				GENMASK_32(3, 0)
+/* CSR_CLRWAKEUPSTICKY */
+#define CSR_CLRWAKEUPSTICKY_LSB				0
+#define CSR_CLRWAKEUPSTICKY_MASK			GENMASK_32(3, 0)
+/* CSR_WAKEUPMASK */
+#define CSR_WAKEUPMASK_LSB				0
+#define CSR_WAKEUPMASK_MASK				GENMASK_32(3, 0)
+/* CSR_CUSTPUBREV */
+#define CSR_CUSTPUBREV_LSB				0
+#define CSR_CUSTPUBREV_MASK				GENMASK_32(5, 0)
+/* CSR_PUBREV */
+#define CSR_PUBREV_LSB					0
+#define CSR_PUBREV_MASK					GENMASK_32(15, 0)
+#define CSR_RESERVEDPUBREV_LSB				0
+#define CSR_RESERVEDPUBREV_MASK				GENMASK_32(3, 0)
+#define CSR_PUBMNR_LSB					4
+#define CSR_PUBMNR_MASK					GENMASK_32(7, 4)
+#define CSR_PUBMDR_LSB					8
+#define CSR_PUBMDR_MASK					GENMASK_32(11, 8)
+#define CSR_PUBMJR_LSB					12
+#define CSR_PUBMJR_MASK					GENMASK_32(15, 12)
+
+/* APBONLY0 register offsets */
+/* CSR_MICROCONTMUXSEL */
+#define CSR_MICROCONTMUXSEL_LSB				0
+#define CSR_MICROCONTMUXSEL_MASK			BIT(0)
+/* CSR_UCTSHADOWREGS */
+#define CSR_UCTSHADOWREGS_LSB				0
+#define CSR_UCTSHADOWREGS_MASK				GENMASK_32(1, 0)
+#define CSR_UCTWRITEPROTSHADOW_LSB			0
+#define CSR_UCTWRITEPROTSHADOW_MASK			BIT(0)
+#define CSR_UCTDATWRITEPROTSHADOW_LSB			1
+#define CSR_UCTDATWRITEPROTSHADOW_MASK			BIT(1)
+/* CSR_DCTWRITEONLY */
+#define CSR_DCTWRITEONLY_LSB				0
+#define CSR_DCTWRITEONLY_MASK				GENMASK_32(15, 0)
+/* CSR_DCTWRITEPROT */
+#define CSR_DCTWRITEPROT_LSB				0
+#define CSR_DCTWRITEPROT_MASK				BIT(0)
+/* CSR_UCTWRITEONLYSHADOW */
+#define CSR_UCTWRITEONLYSHADOW_LSB			0
+#define CSR_UCTWRITEONLYSHADOW_MASK			GENMASK_32(15, 0)
+/* CSR_UCTDATWRITEONLYSHADOW */
+#define CSR_UCTDATWRITEONLYSHADOW_LSB			0
+#define CSR_UCTDATWRITEONLYSHADOW_MASK			GENMASK_32(15, 0)
+/* CSR_NEVERGATECSRCLOCK */
+#define CSR_NEVERGATECSRCLOCK_LSB			0
+#define CSR_NEVERGATECSRCLOCK_MASK			BIT(0)
+/* CSR_DFICFGRDDATAVALIDTICKS */
+#define CSR_DFICFGRDDATAVALIDTICKS_LSB			0
+#define CSR_DFICFGRDDATAVALIDTICKS_MASK			GENMASK_32(5, 0)
+/* CSR_MICRORESET */
+#define CSR_MICRORESET_LSB				0
+#define CSR_MICRORESET_MASK				GENMASK_32(3, 0)
+#define CSR_STALLTOMICRO_LSB				0
+#define CSR_STALLTOMICRO_MASK				BIT(0)
+#define CSR_TESTWAKEUP_LSB				1
+#define CSR_TESTWAKEUP_MASK				BIT(1)
+#define CSR_RSVDMICRO_LSB				2
+#define CSR_RSVDMICRO_MASK				BIT(2)
+#define CSR_RESETTOMICRO_LSB				3
+#define CSR_RESETTOMICRO_MASK				BIT(3)
+/* CSR_SEQUENCEROVERRIDE */
+#define CSR_SEQUENCEROVERRIDE_LSB			0
+#define CSR_SEQUENCEROVERRIDE_MASK			GENMASK_32(10, 0)
+#define CSR_FORCESEQ0BDFIFREQ_LSB			0
+#define CSR_FORCESEQ0BDFIFREQ_MASK			GENMASK_32(4, 0)
+#define CSR_FORCESEQ0BSTART_LSB				5
+#define CSR_FORCESEQ0BSTART_MASK			BIT(5)
+#define CSR_FORCESEQ0BSTOP_LSB				6
+#define CSR_FORCESEQ0BSTOP_MASK				BIT(6)
+#define CSR_BLOCKSEQ0BREQUESTS_LSB			7
+#define CSR_BLOCKSEQ0BREQUESTS_MASK			BIT(7)
+#define CSR_BLOCKSEQ0BACK_LSB				8
+#define CSR_BLOCKSEQ0BACK_MASK				BIT(8)
+#define CSR_DISABLETERMINATEFLAG_LSB			9
+#define CSR_DISABLETERMINATEFLAG_MASK			BIT(9)
+#define CSR_SELECTDFIFREQTOGPRMUX_LSB			10
+#define CSR_SELECTDFIFREQTOGPRMUX_MASK			BIT(10)
+/* CSR_DFIINITCOMPLETESHADOW */
+#define CSR_DFIINITCOMPLETESHADOW_LSB			0
+#define CSR_DFIINITCOMPLETESHADOW_MASK			BIT(0)
+
+/* Fields brought to you by the letter B */
+#define B_MIN						0U
+#define B_MAX						1U
+#define B0						0x0U
+#define B1						0x100U
+#define BBRD						0xF00U
+#define BB_MIN						0U
+#define BB_MAX						15U
+#define BB0						0x0U
+#define BB1						0x1000U
+#define BB2						0x2000U
+#define BB3						0x3000U
+#define BB4						0x4000U
+#define BB5						0x5000U
+#define BB6						0x6000U
+#define BB7						0x7000U
+#define BB8						0x8000U
+#define BB9						0x9000U
+#define BB10						0xA000U
+#define BB11						0xB000U
+#define BB12						0xC000U
+#define BB13						0xD000U
+#define BB14						0xE000U
+#define BB15						0xF000U
+#define BBBRD						0xF000U
+/* Fields brought to you by the letter C */
+#define C_MIN						0U
+#define C_MAX						15U
+#define C0						0x0U
+#define C1						0x1000U
+#define C2						0x2000U
+#define C3						0x3000U
+#define C4						0x4000U
+#define C5						0x5000U
+#define C6						0x6000U
+#define C7						0x7000U
+#define C8						0x8000U
+#define C9						0x9000U
+#define C10						0xA000U
+#define C11						0xB000U
+#define C12						0xC000U
+#define C13						0xD000U
+#define C14						0xE000U
+#define C15						0xF000U
+#define CBRD						0xF000U
+/* Fields brought to you by the letter D */
+#define D_MIN						0U
+#define D_MAX						3U
+#define D0						0x0U
+#define D1						0x100U
+#define D2						0x200U
+#define D3						0x300U
+#define DBRD						0xF00U
+/* Fields brought to you by the letter I */
+#define I_MIN						0U
+#define I_MAX						8U
+#define I0						0x0U
+#define I1						0x100U
+#define I2						0x200U
+#define I3						0x300U
+#define I4						0x400U
+#define I5						0x500U
+#define I6						0x600U
+#define I7						0x700U
+#define I8						0x800U
+#define IBRD						0xF00U
+/* Fields brought to you by the letter J */
+#define J_MIN						0U
+#define J_MAX						0U
+#define J0						0x0U
+#define JBRD						0xF00U
+/* Fields brought to you by the letter L */
+#define L_MIN						0U
+#define L_MAX						13U
+#define L0						0x0U
+#define L1						0x100U
+#define L2						0x200U
+#define L3						0x300U
+#define L4						0x400U
+#define L5						0x500U
+#define L6						0x600U
+#define L7						0x700U
+#define L8						0x800U
+#define L9						0x900U
+#define L10						0xA00U
+#define L11						0xB00U
+#define L12						0xC00U
+#define L13						0xD00U
+#define LBRD						0xF00U
+/* Fields brought to you by the letter M */
+#define M_MIN						0U
+#define M_MAX						8U
+#define M0						0x0U
+#define M1						0x100U
+#define M2						0x200U
+#define M3						0x300U
+#define M4						0x400U
+#define M5						0x500U
+#define M6						0x600U
+#define M7						0x700U
+#define M8						0x800U
+#define MBRD						0xF00U
+/* Fields brought to you by the letter N */
+#define N_MIN						0U
+#define N_MAX						15U
+#define N0						0x0U
+#define N1						0x100U
+#define N2						0x200U
+#define N3						0x300U
+#define N4						0x400U
+#define N5						0x500U
+#define N6						0x600U
+#define N7						0x700U
+#define N8						0x800U
+#define N9						0x900U
+#define N10						0xA00U
+#define N11						0xB00U
+#define N12						0xC00U
+#define N13						0xD00U
+#define N14						0xE00U
+#define N15						0xF00U
+#define NBRD						0xF00U
+/* Fields brought to you by the letter P */
+#define P_MIN						0U
+#define P_MAX						3U
+#define P0						0x0U
+#define P1						0x100000U
+#define P2						0x200000U
+#define P3						0x300000U
+#define PBRD						0x700000U
+#define PP_MIN						0U
+#define PP_MAX						3U
+#define PP0						0x0U
+#define PP1						0x100000U
+#define PP2						0x200000U
+#define PP3						0x300000U
+#define PPBRD						0x700000U
+/* Fields brought to you by the letter Q */
+#define Q_MIN						0U
+#define Q_MAX						3U
+#define Q0						0x0U
+#define Q1						0x100000U
+#define Q2						0x200000U
+#define Q3						0x300000U
+#define QBRD						0x700000U
+/* Fields brought to you by the letter R */
+#define R_MIN						0U
+#define R_MAX						8U
+#define R0						0x0U
+#define R1						0x100U
+#define R2						0x200U
+#define R3						0x300U
+#define R4						0x400U
+#define R5						0x500U
+#define R6						0x600U
+#define R7						0x700U
+#define R8						0x800U
+#define RBRD						0xF00U
+/* Fields brought to you by the letter T */
+#define T_MIN						0U
+#define T_MAX						15U
+#define T0						0x0U
+#define T1						0x10000U
+#define T2						0x20000U
+#define T3						0x30000U
+#define T4						0x40000U
+#define T5						0x50000U
+#define T6						0x60000U
+#define T7						0x70000U
+#define T8						0x80000U
+#define T9						0x90000U
+#define T10						0xA0000U
+#define T11						0xB0000U
+#define T12						0xC0000U
+#define T13						0xD0000U
+#define T14						0xE0000U
+#define T15						0xF0000U
+#define TBRD						0xF0000U
+/* Fields brought to you by the letter U */
+#define U_MIN						0U
+#define U_MAX						1U
+#define U0						0x0U
+#define U1						0x100U
+#define UBRD						0xF00U
+/* Fields brought to you by the letter Y */
+#define Y_MIN						0U
+#define Y_MAX						0U
+#define Y0						0x0U
+#define YBRD						0xF000000U
+
+#define TACSM						0x40000U
+#define TACSMBRD					0x4F000U
+#define TALL						0xF0000U
+#define TALLBRD						0xFF000U
+#define TANIB						0x0U
+#define TANIBBRD					0xF000U
+#define TAPBONLY					0xD0000U
+#define TAPBONLYBRD					0xDF000U
+#define TDBYTE						0x10000U
+#define TDBYTEBRD					0x1F000U
+#define TDRTUB						0xC0000U
+#define TDRTUBBRD					0xCF000U
+#define TINITENG					0x90000U
+#define TINITENGBRD					0x9F000U
+#define TMASTER						0x20000U
+#define TMASTERBRD					0x2F000U
+#define TPPGC						0x70000U
+#define TPPGCBRD					0x7F000U
+#define TUCTL_MEM					0x50000U
+#define TUCTL_MEMBRD					0x5F000U
+
+#define DBYTE_NUM					9U
+#define ANIB_NUM					12U
+
+#endif /* DDRPHY_PHYINIT_CSR_ALL_DEFINES_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit.h
new file mode 100644
index 0000000..acd7072
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_PHYINIT_H
+#define DDRPHY_PHYINIT_H
+
+#include <stdbool.h>
+
+#include <ddrphy_phyinit_usercustom.h>
+
+enum message_block_field {
+	MB_FIELD_PSTATE,
+	MB_FIELD_PLLBYPASSEN,
+	MB_FIELD_DRAMFREQ,
+	MB_FIELD_DFIFREQRATIO,
+	MB_FIELD_BPZNRESVAL,
+	MB_FIELD_PHYODTIMPEDANCE,
+	MB_FIELD_PHYDRVIMPEDANCE,
+	MB_FIELD_DRAMTYPE,
+	MB_FIELD_DISABLEDDBYTE,
+	MB_FIELD_ENABLEDDQS,
+	MB_FIELD_PHYCFG,
+	MB_FIELD_X16PRESENT,
+	MB_FIELD_ENABLEDDQSCHA,
+	MB_FIELD_CSPRESENTCHA,
+	MB_FIELD_ENABLEDDQSCHB,
+	MB_FIELD_CSPRESENTCHB,
+};
+
+/* Function definitions */
+int ddrphy_phyinit_softsetmb(struct pmu_smb_ddr_1d *mb_ddr_1d, enum message_block_field field,
+			     uint32_t value);
+void ddrphy_phyinit_initstruct(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d);
+#endif /* DDRPHY_PHYINIT_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_struct.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_struct.h
new file mode 100644
index 0000000..ae34c0c
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_struct.h
@@ -0,0 +1,786 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_PHYINIT_STRUCT_H
+#define DDRPHY_PHYINIT_STRUCT_H
+
+/* This file defines the internal data structures used in PhyInit to store user configuration */
+
+/* DIMM Type definitions */
+#define DDR_DIMMTYPE_NODIMM 4U /* No DIMM (Soldered-on) */
+
+/*
+ * Structure for basic user inputs
+ *
+ * The following basic data structure must be set and completed correctly so
+ * that the PhyInit software package can accurate program PHY registers.
+ */
+struct user_input_basic {
+	uint32_t dramtype;		/*
+					 * DRAM module type.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | DDR4
+					 *   0x1 | DDR3
+					 *   0x2 | LPDDR4
+					 */
+
+	uint32_t dimmtype;		/*
+					 * DIMM type.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x4 | No DIMM (Soldered-on) (DDR_DIMMTYPE_NODIMM)
+					 */
+
+	uint32_t lp4xmode;		/*
+					 * LPDDR4X mode support.
+					 * Only used for LPDDR4, but not valid here.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | LPDDR4 mode, when dramtype is LPDDR4
+					 */
+
+	uint32_t numdbyte;		/* Number of dbytes physically instantiated */
+
+	uint32_t numactivedbytedfi0;	/* Number of active dbytes to be controlled by dfi0 */
+
+	uint32_t numactivedbytedfi1;	/*
+					 * Number of active dbytes to be controlled by dfi1.
+					 * Only used for LPDDR4.
+					 */
+
+	uint32_t numanib;		/* Number of ANIBs physically instantiated */
+
+	uint32_t numrank_dfi0;		/* Number of ranks in DFI0 channel */
+
+	uint32_t numrank_dfi1;		/* Number of ranks in DFI1 channel (if DFI1 exists) */
+
+	uint32_t dramdatawidth;		/*
+					 * Width of the DRAM device.
+					 *
+					 * Enter 4,8,16 or 32 depending on protocol and dram type
+					 * according below table.
+					 *
+					 * Protocol | Valid Options | Default
+					 * -------- | ------------- | ---
+					 * DDR3     | 4,8,16        | 8
+					 * DDR4     | 4,8,16        | 8
+					 * LPDDR4   | 8,16          | 16
+					 *
+					 * For mixed x8 and x16 width devices, set variable to x8.
+					 */
+
+	uint32_t numpstates;		/* Number of p-states used. Must be set to 1 */
+
+	uint32_t frequency;		/*
+					 * Memclk frequency for each PState.
+					 * Memclk frequency in MHz round up to next highest integer.
+					 * Enter 334 for 333.333, etc.
+					 */
+
+	uint32_t pllbypass;		/*
+					 * Indicates if PLL should be in Bypass mode.
+					 * If DDR datarate < 333, PLL must be in Bypass Mode.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x1 | Enabled
+					 *   0x0 | Disabled
+					 */
+
+	uint32_t dfifreqratio;		/*
+					 * Selected Dfi Frequency ratio.
+					 * Used to program the dfifreqratio register. This register
+					 * controls how dfi_freq_ratio input pin should be driven
+					 * inaccordance with DFI Spec.
+					 *
+					 * Binary Value | Description
+					 *        ----- | ------
+					 *        2'b01 | 1:2 DFI Frequency Ratio (default)
+					 */
+
+	uint32_t dfi1exists;		/* Indicates if the PHY configuration has Dfi1 channel */
+
+	uint32_t train2d;		/* Obsolete. Not used. */
+
+	uint32_t hardmacrover;		/*
+					 * Hard Macro Family version in use.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   3   | hardmacro family D
+					 */
+
+	uint32_t readdbienable;		/* Obsolete. Not Used. */
+
+	uint32_t dfimode;		/* Obsolete. Not Used. */
+};
+
+/*
+ * Structure for advanced user inputs
+ */
+struct user_input_advanced {
+	uint32_t lp4rxpreamblemode;	/*
+					 * Selects between DRAM read static vs toggle preamble.
+					 * Determine desired DRAM Read Preamble Mode based on SI
+					 * Analysis and DRAM Part in use.
+					 * The PHY training firmware will program DRAM mr1-OP[3]
+					 * after training based on setting.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x1 | toggling preamble
+					 *   0x0 | static preamble
+					 */
+
+	uint32_t lp4postambleext;	/*
+					 * Extend write postamble in LPDDR4.
+					 * Only used for LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr3-OP[1] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Set value according to your SI analysis and DRAM
+					 * requirement.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | half Memclk postamble
+					 *   0x1 | 1.5 Memclk postabmle (default)
+					 */
+
+	uint32_t d4rxpreamblelength;	/*
+					 * Length of read preamble in DDR4 mode.
+					 * Only used for DDR4.
+					 * This variable is used to calculate DDR4 mr4-OP[11] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Set value according to your SI analysis and DRAM
+					 * requirement.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 |  1 Tck
+					 *   0x1 |  2 Tck (default)
+					 */
+
+	uint32_t d4txpreamblelength;	/*
+					 * Length of write preamble in DDR4 mode.
+					 * Only used for DDR4.
+					 * This variable is used to calculate DDR4 mr4-OP[12] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Set value according to your SI analysis and DRAM
+					 * requirement.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | 1 Tck (default)
+					 *   0x1 | 2 Tck
+					 */
+
+	uint32_t extcalresval;		/*
+					 * External Impedance calibration pull-down resistor value
+					 * select.
+					 * Indicates value of impedance calibration pull-down
+					 * resistor connected to BP_ZN pin of the PHY.
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | 240 ohm (default)
+					 */
+
+	uint32_t is2ttiming;		/*
+					 * Set to 1 to use 2T timing for address/command, otherwise
+					 * 1T timing will be used.
+					 * Determine 1T or 2T Timing operation mode based on SI
+					 * Analysis and DRAM Timing.
+					 *   - In 1T mode, CK, CS, CA all have the same nominal
+					 *     timing, ie. ATxDly[6:0] will have same value for all
+					 *     ANIBs.
+					 *   - In 2T mode, CK, CS,have the same nominal timing
+					 *     (e.g. AtxDly[6:0]=0x00), while CA is delayed by 1UI
+					 *     (e.g. ATxDly[6:0]=0x40)
+					 * Used to program phycfg setting in messageBlock.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | 1T Timing (default)
+					 *   0x1 | 2T Timing
+					 */
+
+	uint32_t odtimpedance;		/*
+					 * ODT impedance in ohm.
+					 * Used for programming TxOdtDrvStren registers.
+					 * Enter 0 for open/high-impedance.
+					 * Default value: 60
+					 */
+
+	uint32_t tximpedance;		/*
+					 * Tx Drive Impedance for DQ/DQS in ohm.
+					 * Used for programming TxImpedanceCtrl1 registers.
+					 * Enter 0 for open/high-impedance.
+					 * Default value: 60
+					 */
+
+	uint32_t atximpedance;		/*
+					 * Tx Drive Impedance for AC in ohm.
+					 * Used for programming ATxImpedance register.
+					 * Enter 0 for open/high-impedance
+					 * Default value: 20 (HMA,HMB,HMC,HMD), 40 (HME)
+					 */
+
+	uint32_t memalerten;		/*
+					 * Enables BP_ALERT programming of PHY registers.
+					 * Only used for DDR3 and DDR4.
+					 * Used for programming MemAlertControl and MemAlertControl2
+					 * registers.
+					 * Program if you require using BP_ALERT pin (to receive or
+					 * terminate signal) of the PHY otherwise leave at default
+					 * value to save power.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 * 0x0 | Disable BP_ALERT (default)
+					 */
+
+	uint32_t memalertpuimp;		/*
+					 * Specify MemAlert Pull-up Termination Impedance.
+					 * Programs the pull-up termination on BP_ALERT.
+					 * Not valid here (fixed 0 value).
+					 */
+
+	uint32_t memalertvreflevel;	/*
+					 * Specify the Vref level for BP_ALERT(MemAlert) Receiver.
+					 * Not valid here (fixed 0 value).
+					 */
+
+	uint32_t memalertsyncbypass;	/*
+					 * When set, this bit bypasses the DfiClk synchronizer on
+					 * dfi_alert_n.
+					 * Not valid here (fixed 0 value).
+					 */
+
+	uint32_t disdynadrtri;		/*
+					 * Disable Dynamic Per-MEMCLK Address Tristate feature.
+					 * Program this variable if you require to disable this
+					 * feature.
+					 *   - In DDR3/2T and DDR4/2T/2N modes, the dynamic tristate
+					 *     feature should be disabled if the controller cannot
+					 *     follow the 2T PHY tristate protocol.
+					 *   - In LPDDR4 mode, the dynamic tristate feature should
+					 *     be disabled.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *  0x1  | Disable Dynamic Tristate
+					 */
+
+	uint32_t phymstrtraininterval;	/*
+					 * Specifies the how frequent dfi_phymstr_req is issued by
+					 * PHY.
+					 * Only required in LPDDR4.
+					 * Based on SI analysis determine how frequent DRAM drift
+					 * compensation and re-training is required.
+					 * Determine if Memory controller supports DFI PHY Master
+					 * Interface.
+					 * Program based on desired setting for
+					 * PPTTrainSetup.PhyMstrTrainInterval register.
+					 * Default value: 0xa
+					 *
+					 * Example:
+					 * Value | Description
+					 * ----- | ------
+					 *   0xa | PPT Train Interval = 268435456 MEMCLKs (default)
+					 */
+
+	uint32_t phymstrmaxreqtoack;	/*
+					 * Max time from dfi_phymstr_req asserted to dfi_phymstr_ack
+					 * asserted.
+					 * Only required in LPDDR4.
+					 * Based on your Memory controller's(MC) specification
+					 * determine how long the PHY should wait for the assertion
+					 * of dfi_phymstr_ack once dfi_phymstr_req has been issued
+					 * by the PHY. If the MC does not ack the PHY's request, PHY
+					 * may issue dfi_error.
+					 * This value will be used to program
+					 * PPTTrainSetup.PhyMstrMaxReqToAck register.
+					 * Default value: 0x5
+					 *
+					 * Example:
+					 * Value | Description
+					 * ----- | ------
+					 *   0x5 | PPT Max. Req to Ack. = 8192 MEMCLKs (default)
+					 */
+
+	uint32_t wdqsext;		/*
+					 * Enable Write DQS Extension feature of PHY.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | Disable Write DQS Extension feature. (default)
+					 *   0x1 | Enable Write DQS Extension feature.
+					 */
+
+	uint32_t calinterval;		/*
+					 * Specifies the interval between successive calibrations,
+					 * in mS.
+					 * Program variable based on desired setting for
+					 * CalRate.CalInterval register.
+					 * - Fixed 0x9 value (20mS interval)
+					 */
+
+	uint32_t calonce;		/*
+					 * This setting changes the behaviour of CalRun register.
+					 * If you desire to manually trigger impedance calibration
+					 * in mission mode set this variable to 1, and toggle CalRun
+					 * in mission mode.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 * 0x0   | Calibration will proceed at the rate determined
+					 *       | by CalInterval. This field should only be changed
+					 *       | while the calibrator is idle. ie before csr
+					 *       | CalRun is set.
+					 */
+
+	uint32_t lp4rl;			/*
+					 * LPDDR4 Dram Read Latency.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr2-OP[2:0]
+					 * set in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 * Determine values based on your DRAM part's supported
+					 * speed and latency bin.
+					 * Default: calculated based on user_input_basic.frequency
+					 * and "JEDEC JESD209-4A (LPDDR4)" Table 28 "Read and Write
+					 * Latencies".
+					 * Lowest latency selected when more than one latency can be
+					 * used. For example given configuration for LPDDR4, x16,
+					 * NoDbi and DDR533, RL=10 is selected rather than 14.
+					 */
+
+	uint32_t lp4wl;			/*
+					 * LPDDR4 Dram Write Latency.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr2-OP[5:3]
+					 * set in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 * Determine values based on your DRAM part's supported
+					 * speed and latency bin.
+					 * Default: calculated based on user_input_basic.frequency
+					 * and "JEDEC JESD209-4A (LPDDR4)" Table 28 "Read and Write
+					 * Latencies".
+					 * Lowest latency selected when more than one latency can be
+					 * used.
+					 */
+
+	uint32_t lp4wls;		/*
+					 * LPDDR4 Dram WL Set.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr2-OP[6] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 * Determine value based on Memory controllers requirement
+					 * of DRAM State after PHY training.
+					 *
+					 * Value | Description
+					 *   --- | ---
+					 *   0x0 | WL Set "A" (default)
+					 */
+
+	uint32_t lp4dbird;		/*
+					 * LPDDR4 Dram DBI-Read Enable.
+					 * Applicable only if dramtype == LPDDR4.
+					 * Determine if you require to using DBI for the given
+					 * PState.
+					 * If Read DBI is not used PHY receivers are turned off to
+					 * save power.
+					 * This variable is used to calculate LPDDR4 mr3-OP[6] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * PHY register DMIPinPresent is programmed based on this
+					 * parameter.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 *
+					 * Value | Description
+					 *   --- | ---
+					 *   0x0 | Disabled (default)
+					 *   0x1 | Enabled
+					 */
+
+	uint32_t lp4dbiwr;		/*
+					 * LPDDR4 Dram DBI-Write Enable.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr3-OP[7] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 *
+					 * Value | Description
+					 *   --- | ---
+					 *   0x0 | Disabled (default)
+					 *   0x1 | Enabled
+					 */
+
+	uint32_t lp4nwr;		/*
+					 * LPDDR4 Write-Recovery for Auto- Pre-charge commands.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr1-OP[6:4] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 * Determine values based on your DRAM part's supported
+					 * speed and latency bin.
+					 * Default: calculated based on user_input_basic.frequency
+					 * and "JEDEC JESD209-4A (LPDDR4)" Table 28 "Read and Write
+					 * Latencies".
+					 * Lowest latency selected when more than one latency can be
+					 * used.
+					 *
+					 * Binary Value | Description
+					 * --- | ---
+					 * 000 | nWR = 6 (default)
+					 * 001 | nWR = 10
+					 * 010 | nWR = 16
+					 * 011 | nWR = 20
+					 * 100 | nWR = 24
+					 * 101 | nWR = 30
+					 * 110 | nWR = 34
+					 * 111 | nWR = 40
+					 */
+
+	uint32_t lp4lowpowerdrv;	/*
+					 * Configure output Driver in Low power mode.
+					 * Feature only supported for Hard Macro Family E (HME).
+					 * Use NMOS Pull-up for Low-Power IO.
+					 * Not valid here
+					 */
+
+	uint32_t drambyteswap;		/*
+					 * DRAM Oscillator count source mapping for skip_training.
+					 * The PHY supports swapping of DRAM oscillator count values
+					 * between paired DBytes for the purpose of tDQSDQ DRAM
+					 * Drift Compensation(DDC).
+					 * Each DByte has a register bit to control the source of
+					 * the oscillator count value used to perform tDQSDQ Drift
+					 * compensation.
+					 * On silicon the training firmware will determine the DByte
+					 * swap and program PptCtlStatic register to select
+					 * oscillator count source. When skip_train is used,
+					 * training firmware is skipped thus manual programming may
+					 * be required depending on configuration.
+					 * The default hardware configuration is for odd Dbyte
+					 * instance n to use oscillator count values from its paired
+					 * Dbyte instance n-1. So Dbyte1 will use the oscillator
+					 * count values from Dbyte0, Dbyte3 will use Dbyte2 and so
+					 * on. This is required for DRAM Data width =16.
+					 * Each bit of this field corresponds to a DBYTE:
+					 *   - bit-0 = setting for DBYTE0
+					 *   - bit-1 = setting for DBYTE1
+					 *   - bit-2 = setting for DBYTE2
+					 *   - . . .
+					 *   - bit-n = setting for DBYTEn
+					 * By setting the associated bit for each DByte to 1, PHY
+					 * will use non-default source for count value.
+					 *   - for even Dbytes, non-default source is to use the odd
+					 *     pair count value.
+					 *   - for odd Dbytes, no-default source to use data
+					 *     received directly from the DRAM.
+					 * Byte swapping must be the same across different ranks.
+					 * Default value: 0x0
+					 * If Byte mode devices are indicated via the x8mode
+					 * messageBlock parameter, this variable is ignored as PHY
+					 * only supports a limited configuration set based on Byte
+					 * mode configuration.
+					 *
+					 * Example:
+					 * DramByteSwap = 0x03 - Dbyte0: use count values from
+					 * Dbyte1, Dbyte1 uses count values received directly
+					 * received from DRAM.
+					 * Rest of Dbytes have default source for DRAM oscilator
+					 * count.
+					 */
+
+	uint32_t rxenbackoff;		/*
+					 * Determines the Placement of PHY Read Gate signal.
+					 * Only used in LPDDR4 when lp4rxpreamblemode==0 (static
+					 * preamble) for skip_train==true.
+					 * For other dramtypes or LPDDR4-toggling-preamble no
+					 * options are available and PhyInit will set position as
+					 * required. See source code in
+					 * ddrphy_phyinit_c_initphyconfig() to see how the
+					 * RxEnBackOff register is set.
+					 * For skip_train==false, FW will set the position based on
+					 * Preamble.
+					 * We recommend keeping this setting at default value.
+					 * SI analysis is required to determine if default value
+					 * needs to be changed.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x1 | Position read gate 1UI from the first valid edge
+					 *       | of DQS_t (LPDDR4 Static preamble only) (default)
+					 */
+
+	uint32_t trainsequencectrl;	/*
+					 * Firmware Training Sequence Control.
+					 * This input is used to program sequencectrl in
+					 * messageBlock.
+					 * It controls the training stages executed by firmware.
+					 * For production silicon we recommend to use default value
+					 * programmed by PhyInit.
+					 */
+
+	uint32_t snpsumctlopt;		/*
+					 * Enable Fast Frequency Change (FFC) Optimizations
+					 * specific to UMCTL2 (DDRCTRL).
+					 * Not valid for dimmtype=NODIMM.
+					 * Consult DDRCTRL documentation in Reference Manual to
+					 * ensure when optimizations can be enabled.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 * 0 | Disable FFC MRW optimization (default)
+					 */
+
+	uint32_t snpsumctlf0rc5x;	/*
+					 * F0RX5x RCD Control Word when using Fast Frequency
+					 * Change(FFC) optimizations specific to UMCTL2
+					 * Not valid for dimmtype=NODIMM.
+					 * Only valid for when SnpsUmctlOpt=1.
+					 * When UMCTL2 optimizations are enabled PHY will perform
+					 * RCD MRW during fast frequency change request.
+					 * The correct RCD control word value for each PState must
+					 * be programmed in this field.
+					 * Consult the RCD spec and UMCTL documentation to
+					 * determine the correct value based on DRAM configuration
+					 * and operating speed.
+					 */
+
+	uint32_t txslewrisedq;		/*
+					 * Pull-up slew rate control for DBYTE Tx.
+					 * Value specified here will be written to register
+					 * TxSlewRate.TxPreP by PhyInit.
+					 * See register description for more information.
+					 */
+
+	uint32_t txslewfalldq;		/*
+					 * Pull-down slew rate control for DBYTE Tx.
+					 * Value specified here will be written to
+					 * TxSlewRate.TxPreN by PhyInit.
+					 * See register description for more information.
+					 */
+
+	uint32_t txslewriseac;		/*
+					 * Pull-up slew rate control for ANIB Tx.
+					 * Value specified here will be written to
+					 * ATxSlewRate.ATxPreP.
+					 * See register description for more information.
+					 */
+
+	uint32_t txslewfallac;		/*
+					 * Pull-down slew rate control for ANIB Tx.
+					 * Value specified here will be written to
+					 * ATxSlewRate.ATxPreN.
+					 * See register description for more information.
+					 */
+
+	uint32_t disableretraining;	/*
+					 * Disable PHY DRAM Drift compensation re-training.
+					 * Only applied to LPDDR4. No retraining is required in
+					 * DDR4/3.
+					 * Disable PHY re-training during DFI frequency change
+					 * requests in LPDDR4.
+					 * The purpose of retraining is to compensate for drift in
+					 * the DRAM.
+					 * Determine based on SI analysis and DRAM datasheet if
+					 * retraining can be disabled.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x1 | Disable retraining
+					 *   0x0 | Enable retraining
+					 */
+
+	uint32_t disablephyupdate;	/*
+					 * Disable DFI PHY Update feature.
+					 * Only effects LPDDR4.
+					 * Disable DFI PHY Update feature. When set PHY will not
+					 * assert dfi0/1_phyupd_req.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x1 | Disable DFI PHY Update
+					 *   0x0 | Enable DFI PHY Update
+					 */
+
+	uint32_t enablehighclkskewfix;	/*
+					 * Enable alternative PIE program.
+					 * If enabled the PIE reinitializes the FIFO pointers a
+					 * second time due for designs with large skew between
+					 * chiplet DfiClk branches. If enabled PIE latencies in all
+					 * protocols are increased by 60 DfiClks.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x0 | Disable (default)
+					 */
+
+	uint32_t disableunusedaddrlns;  /*
+					 * Turn off or tristate Address Lanes when possible.
+					 *
+					 * When enabled, PHY will tristate unused address lanes to
+					 * save power when possible by using Acx4AnibDis and
+					 * AForceTriCont registers.
+					 * This feature is only implemented for the default PHY
+					 * Address bump mapping and Ranks must be populated in
+					 * order. ie Rank1 cannot be used if Rank0 is unpopulated.
+					 * For alternative bump mapping follow the following
+					 * guideline to achieve maximum power savings:
+					 *   - For each unused BP_A bump program AForceTriCont[4:0]
+					 *     bits based on register description.
+					 *   - if all lanes of an Anib are unused _AND_ ANIB is not
+					 *     the first or last instance set bit associated with
+					 *     the instance in Acs4AnibDis registers. see register
+					 *     description for details.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x1 | Enable
+					 */
+
+	uint32_t phyinitsequencenum;	/*
+					 * Switches between supported phyinit training sequences.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x0 | Minimizes number of Imem/Dmem loads (default)
+					 */
+
+	uint32_t enabledficspolarityfix;/*
+					 * Enable alternative PIE program.
+					 * Set to 1 if PUB_VERSION <2.43a, otherwise set to 0. If
+					 * enabled the PIE programs Dfi{Rd,Wr}DataCsDestMap CSR's
+					 * to default values 0x00E4 before running PPT.
+					 * Before exiting PPT, PIE will restore
+					 * Dfi{Rd,Wr}DataCsDestMap CSR's to 0x00E1.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x0 | Disable (default)
+					 */
+
+	uint32_t phyvref;		/*
+					 * Must be programmed with the Vref level to be used by the
+					 * PHY during reads.
+					 * The units of this field are a percentage of VDDQ
+					 * according to the following equation:
+					 * Receiver Vref = VDDQ*phyvref[6:0]/128
+					 * For example to set Vref at 0.75*VDDQ, set this field to
+					 * 0x60.
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must calculate the analytical Vref by
+					 * using the impedances, terminations, and series resistance
+					 * present in the system.
+					 */
+
+	uint32_t sequencectrl;		/*
+					 * Controls the training steps to be run. Each bit
+					 * corresponds to a training step.
+					 * If the bit is set to 1, the training step will run.
+					 * If the bit is set to 0, the training step will be
+					 * skipped.
+					 * Training step to bit mapping:
+					 * sequencectrl[0] = Run DevInit - Device/phy
+					 *		     initialization. Should always be set.
+					 * sequencectrl[1] = Run WrLvl - Write leveling
+					 * sequencectrl[2] = Run RxEn - Read gate training
+					 * sequencectrl[3] = Run RdDQS1D - 1d read dqs training
+					 * sequencectrl[4] = Run WrDQ1D - 1d write dq training
+					 * sequencectrl[5] = RFU, must be zero
+					 * sequencectrl[6] = RFU, must be zero
+					 * sequencectrl[7] = RFU, must be zero
+					 * sequencectrl[8] = Run RdDeskew - Per lane read dq deskew
+					 *		     training
+					 * sequencectrl[9] = Run MxRdLat - Max read latency training
+					 * sequencectrl[10] = RFU, must be zero
+					 * sequencectrl[11] = RFU, must be zero
+					 * sequencectrl[12] = RFU, must be zero
+					 * sequencectrl[13] = RFU, must be zero
+					 * sequencectrl[15-14] = RFU, must be zero
+					 */
+};
+
+/*
+ * Structure for mode register user inputs
+ *
+ * The following data structure must be set and completed correctly so that the PhyInit software
+ * package can accurate fill message block structure.
+ * Only some mrx are used per DDR type, on related width:
+ * - DDR3: mr0..2 are used (16-bits values)
+ * - DDR4: mr0..6 are used (16-bits values)
+ * - LPDDR4: mr1..4 and mr11..22 are used (8-bits values)
+ */
+struct user_input_mode_register {
+	uint32_t mr0;
+	uint32_t mr1;
+	uint32_t mr2;
+	uint32_t mr3;
+	uint32_t mr4;
+	uint32_t mr5;
+	uint32_t mr6;
+	uint32_t mr11;
+	uint32_t mr12;
+	uint32_t mr13;
+	uint32_t mr14;
+	uint32_t mr22;
+};
+
+/*
+ * Structure for swizzle user inputs
+ *
+ * The following data structure must be set and completed correctly sothat the PhyInit software
+ * package can accurate set swizzle (IO muxing) config.
+ * Only some swizzles are used per DDR type:
+ * - DDR3/DDR4: swizzle 0..32 are used
+ *   - 26 for hwtswizzle
+ *   - 7 for acswizzle
+ * - LPDDR4:  swizzle 0..43 are used
+ *   - 8 per byte for dqlnsel (total 32)
+ *   - 6 for mapcaatodfi
+ *   - 6 for mapcabtodfi
+ */
+#define NB_HWT_SWIZZLE			26U
+#define NB_AC_SWIZZLE			7U
+#define NB_DQLNSEL_SWIZZLE_PER_BYTE	8U
+#define NB_MAPCAATODFI_SWIZZLE		6U
+#define NB_MAPCABTODFI_SWIZZLE		6U
+#define NB_SWIZZLE	44
+struct user_input_swizzle {
+	uint32_t swizzle[NB_SWIZZLE];
+};
+
+#endif /* DDRPHY_PHYINIT_STRUCT_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_usercustom.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_usercustom.h
new file mode 100644
index 0000000..b248f59
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_usercustom.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_PHYINIT_USERCUSTOM_H
+#define DDRPHY_PHYINIT_USERCUSTOM_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <ddrphy_csr_all_cdefines.h>
+
+#include <drivers/st/stm32mp2_ddr.h>
+
+/* Message Block Structure Definitions */
+#if STM32MP_DDR3_TYPE
+#include <mnpmusrammsgblock_ddr3.h>
+#elif STM32MP_DDR4_TYPE
+#include <mnpmusrammsgblock_ddr4.h>
+#else /* STM32MP_LPDDR4_TYPE */
+#include <mnpmusrammsgblock_lpddr4.h>
+#endif /* STM32MP_DDR3_TYPE */
+
+/*
+ * -------------------------------------------------------------
+ * Defines for Firmware Images
+ * - indicate IMEM/DMEM address, size (bytes) and offsets.
+ * -------------------------------------------------------------
+ *
+ * IMEM_SIZE max size of instruction memory.
+ * DMEM_SIZE max size of data memory.
+ *
+ * IMEM_ST_ADDR start of IMEM address in memory.
+ * DMEM_ST_ADDR start of DMEM address in memory.
+ * DMEM_BIN_OFFSET start offset in DMEM memory (message block).
+ */
+#if STM32MP_DDR3_TYPE
+#define IMEM_SIZE			0x4C28U
+#define DMEM_SIZE			0x6C8U
+#elif STM32MP_DDR4_TYPE
+#define IMEM_SIZE			0x6D24U
+#define DMEM_SIZE			0x6CCU
+#else /* STM32MP_LPDDR4_TYPE */
+#define IMEM_SIZE			0x7E50U
+#define DMEM_SIZE			0x67CU
+#endif /* STM32MP_DDR3_TYPE */
+#define IMEM_ST_ADDR			0x50000U
+#define DMEM_ST_ADDR			0x54000U
+#define DMEM_BIN_OFFSET			0x200U
+
+/*
+ * ------------------
+ * Type definitions
+ * ------------------
+ */
+
+/* A structure used to SRAM memory address space */
+enum return_offset_lastaddr {
+	RETURN_OFFSET,
+	RETURN_LASTADDR
+};
+
+/* Enumeration of instructions for PhyInit Register Interface */
+enum reginstr {
+	STARTTRACK,	/* Start register tracking */
+	STOPTRACK,	/* Stop register tracking */
+	SAVEREGS,	/* Save(read) tracked register values */
+	RESTOREREGS,	/* Restore (write) saved register values */
+};
+
+/* Data structure to store register address/value pairs */
+struct reg_addr_val {
+	uint32_t	address;	/* Register address */
+	uint16_t	value;		/* Register value */
+};
+
+/* Target CSR for the impedance value for ddrphy_phyinit_mapdrvstren() */
+enum drvtype {
+	DRVSTRENFSDQP,
+	DRVSTRENFSDQN,
+	ODTSTRENP,
+	ODTSTRENN,
+	ADRVSTRENP,
+	ADRVSTRENN
+};
+
+/*
+ * -------------------------------------------------------------
+ * Fixed Function prototypes
+ * -------------------------------------------------------------
+ */
+int ddrphy_phyinit_sequence(struct stm32mp_ddr_config *config, bool skip_training, bool reten);
+int ddrphy_phyinit_restore_sequence(void);
+int ddrphy_phyinit_c_initphyconfig(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t *ardptrinitval);
+void ddrphy_phyinit_d_loadimem(void);
+void ddrphy_phyinit_progcsrskiptrain(struct stm32mp_ddr_config *config,
+				     struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t ardptrinitval);
+int ddrphy_phyinit_f_loaddmem(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d);
+int ddrphy_phyinit_g_execfw(void);
+void ddrphy_phyinit_i_loadpieimage(struct stm32mp_ddr_config *config, bool skip_training);
+void ddrphy_phyinit_loadpieprodcode(void);
+int ddrphy_phyinit_mapdrvstren(uint32_t drvstren_ohm, enum drvtype targetcsr);
+int ddrphy_phyinit_calcmb(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d);
+void ddrphy_phyinit_writeoutmem(uint32_t *mem, uint32_t mem_offset, uint32_t mem_size);
+void ddrphy_phyinit_writeoutmsgblk(uint16_t *mem, uint32_t mem_offset, uint32_t mem_size);
+int ddrphy_phyinit_isdbytedisabled(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t dbytenumber);
+int ddrphy_phyinit_trackreg(uint32_t adr);
+int ddrphy_phyinit_reginterface(enum reginstr myreginstr, uint32_t adr, uint16_t dat);
+
+void ddrphy_phyinit_usercustom_custompretrain(struct stm32mp_ddr_config *config);
+int ddrphy_phyinit_usercustom_g_waitfwdone(void);
+int ddrphy_phyinit_usercustom_saveretregs(struct stm32mp_ddr_config *config);
+
+#endif /* DDRPHY_PHYINIT_USERCUSTOM_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_wrapper.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_wrapper.h
new file mode 100644
index 0000000..ed4be1c
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_wrapper.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_WRAPPER_H
+#define DDRPHY_WRAPPER_H
+
+static inline long long fmodll(long long x, long long y)
+{
+	return x - ((x / y) * y);
+}
+
+static inline int fmodi(int x, int y)
+{
+	return (int)fmodll((long long)x, (long long)y);
+}
+
+#endif /* DDRPHY_WRAPPER_H */
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
new file mode 100644
index 0000000..a0712b5
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
@@ -0,0 +1,1140 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+#include <ddrphy_wrapper.h>
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+
+/*
+ * Program txslewrate:
+ * - txslewrate::txpredrvmode is dependent on dramtype.
+ * - txslewrate::txprep and txslewrate::txpren are technology-specific.
+ */
+static void txslewrate_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t txpredrvmode;
+	uint32_t byte;
+	uint32_t txpren; /* Default to 0xf (max). Optimal setting is technology specific */
+	uint32_t txprep; /* Default to 0xf (max). Optimal setting is technology specific */
+	uint16_t txslewrate;
+
+#if STM32MP_DDR3_TYPE
+	txpredrvmode = 0x3U;
+#elif STM32MP_DDR4_TYPE
+	txpredrvmode = 0x2U;
+#else /* STM32MP_LPDDR4_TYPE */
+	txpredrvmode = 0x1U;
+#endif /* STM32MP_DDR3_TYPE */
+
+	txprep = config->uia.txslewrisedq;
+	txpren = config->uia.txslewfalldq;
+
+	txslewrate = (uint16_t)((txpredrvmode << CSR_TXPREDRVMODE_LSB) |
+				(txpren << CSR_TXPREN_LSB) |
+				(txprep << CSR_TXPREP_LSB));
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane <= B_MAX; lane++) {
+			uint32_t b_addr;
+
+			b_addr = lane << 8;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | c_addr | b_addr |
+									CSR_TXSLEWRATE_ADDR))),
+				      txslewrate);
+		}
+	}
+}
+
+/*
+ * Program atxslewrate:
+ * - atxslewrate::atxpredrvmode is dependent on dramtype and whether
+ *   the ACX4 instance is used for AC or CK.
+ * - atxslewrate::atxprep and atxslewrate::atxpren are technology-specific.
+ */
+static void atxslewrate_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t anib;
+	uint32_t atxpren; /* Default to 0xf (max). Optimal setting is technology specific */
+	uint32_t atxprep; /* Default to 0xf (max). Optimal setting is technology specific */
+	uint32_t ck_anib_inst[2] = {0};
+
+	atxprep = config->uia.txslewriseac;
+	atxpren = config->uia.txslewfallac;
+
+	/*
+	 * # of ANIBs      CK ANIB Instance
+	 * ACX8            ANIB 1
+	 */
+	if (config->uib.numanib == 8U) {
+		ck_anib_inst[0] = 1U;
+		ck_anib_inst[1] = 1U;
+	}
+
+	for (anib = 0U; anib < config->uib.numanib; anib++) {
+		uint32_t atxpredrvmode;
+		uint32_t c_addr;
+		uint16_t atxslewrate;
+
+		c_addr = anib << 12;
+
+		if ((anib == ck_anib_inst[0]) || (anib == ck_anib_inst[1])) {
+			/* CK ANIB instance */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			atxpredrvmode = 0x0U;
+#else /* STM32MP_LPDDR4_TYPE */
+			atxpredrvmode = 0x1U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+		} else {
+			/* non-CK ANIB instance */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			atxpredrvmode = 0x3U;
+#else /* STM32MP_LPDDR4_TYPE */
+			atxpredrvmode = 0x1U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+		}
+
+		atxslewrate = (uint16_t)((atxpredrvmode << CSR_ATXPREDRVMODE_LSB) |
+					 (atxpren << CSR_ATXPREN_LSB) |
+					 (atxprep << CSR_ATXPREP_LSB));
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TANIB | c_addr |
+								CSR_ATXSLEWRATE_ADDR))),
+			      atxslewrate);
+	}
+}
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+/*
+ * Program dfirddatacsdestmap and dfiwrdatacsdestmap:
+ * - Dependencies: mb_ddr_1d->msgmisc[6] Determine Partial Rank Support.
+ */
+static void dfidatacsdestmap_program(struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	if ((mb_ddr_1d->msgmisc & 0x40U) != 0U) {
+		uint16_t dfirddatacsdestmap = 0xA0U;
+		uint16_t dfiwrdatacsdestmap = 0xA0U;
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER |
+								CSR_DFIRDDATACSDESTMAP_ADDR))),
+			      dfirddatacsdestmap);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER |
+								CSR_DFIWRDATACSDESTMAP_ADDR))),
+			      dfiwrdatacsdestmap);
+	}
+}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+/*
+ * Program pllctrl2:
+ * - Calculate PLL controls from frequency.
+ */
+static void pllctrl2_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t pllctrl2;
+	uint32_t halffreq = config->uib.frequency / 2U;
+
+	if (halffreq < 235U) {
+		pllctrl2 = 0x7U;
+	} else if (halffreq < 313U) {
+		pllctrl2 = 0x6U;
+	} else if (halffreq < 469U) {
+		pllctrl2 = 0xBU;
+	} else if (halffreq < 625U) {
+		pllctrl2 = 0xAU;
+	} else if (halffreq < 938U) {
+		pllctrl2 = 0x19U;
+	} else if (halffreq < 1067U) {
+		pllctrl2 = 0x18U;
+	} else {
+		pllctrl2 = 0x19U;
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_PLLCTRL2_ADDR))), pllctrl2);
+}
+
+/*
+ * Program ardptrinitval:
+ * - The values programmed here assume ideal properties of DfiClk and Pclk including:
+ *   - DfiClk skew
+ *   - DfiClk jitter
+ *   - DfiClk PVT variations
+ *   - Pclk skew
+ *   - Pclk jitter
+ *
+ * ardptrinitval Programmed differently based on PLL Bypass mode and frequency:
+ * - PLL Bypassed mode:
+ *   - For MemClk frequency > 933MHz, the valid range of ardptrinitval[3:0] is: 2-5
+ *   - For MemClk frequency < 933MHz, the valid range of ardptrinitval[3:0] is: 1-5
+ * - PLL Enabled mode:
+ *   - For MemClk frequency > 933MHz, the valid range of ardptrinitval[3:0] is: 1-5
+ *   - For MemClk frequency < 933MHz, the valid range of ardptrinitval[3:0] is: 0-5
+ */
+static void ardptrinitval_program(struct stm32mp_ddr_config *config, uint32_t *ardptrinitval)
+{
+	uint16_t regdata;
+
+	if (config->uib.frequency >= 933U) {
+		regdata = 0x2U;
+	} else {
+		regdata = 0x1U;
+	}
+
+	/* Add one UI for synchronizer on SyncBus when PLL is bypassed */
+	if (config->uib.pllbypass == 1U) {
+		regdata++;
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_ARDPTRINITVAL_ADDR))),
+		      regdata);
+
+	*ardptrinitval = (uint32_t)regdata;
+}
+
+#if STM32MP_LPDDR4_TYPE
+/*
+ * Program ProcOdtCtl:
+ * - Sets procodtalwayson/procodtalwaysoff for LPDDR4 using the PIE register seq0bgpr4.
+ */
+static void procodtctl_program(void)
+{
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | C0 | CSR_SEQ0BGPR4_ADDR))), 0U);
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+/*
+ * Program dbytedllmodecntrl:
+ * - dllrxpreamblemode
+ * Program dqspreamblecontrol:
+ * - Fields:
+ *   - twotckrxdqspre
+ *   - twotcktxdqspre
+ *   - positiondfeinit
+ *   - lp4tgltwotcktxdqspre
+ *   - lp4postambleext
+ *   - lp4sttcprebridgerxen
+ * - Dependencies:
+ *   - user_input_advanced.lp4rxpreamblemode (LPDDR4)
+ *   - user_input_advanced.lp4postambleext (LPDDR4)
+ *   - user_input_advanced.wdqsext (LPDDR4)
+ *   - user_input_advanced.d4rxpreamblelength (DDR4)
+ *   - user_input_advanced.d4txpreamblelength (DDR4)
+ */
+static void dbytedllmodecntrl_program(struct stm32mp_ddr_config *config, uint32_t *twotckrxdqspre)
+{
+	uint32_t disdllgainivseed = 1U;
+	uint32_t disdllseedsel = 0U;
+	uint32_t dllgainiv = 0x1U;
+	uint32_t dllgaintv = 0x6U;
+	uint32_t dllrxpreamblemode = 0U;
+	uint32_t lcdlseed0 = 0x21U;
+	uint32_t lp4postambleext = 0U;
+	uint32_t lp4sttcprebridgerxen = 0U;
+	uint32_t lp4tgltwotcktxdqspre = 0U;
+	uint32_t positiondfeinit;
+	uint32_t twotcktxdqspre = 0U;
+	uint32_t wdqsextension = 0U;
+	uint16_t dbytedllmodecntrl;
+	uint16_t dllgainctl;
+	uint16_t dlllockparam;
+	uint16_t dqspreamblecontrol;
+
+#if STM32MP_DDR3_TYPE
+	/* Same as default */
+	*twotckrxdqspre		= 0x0U;
+	lp4sttcprebridgerxen	= 0x0U;
+	dllrxpreamblemode	= 0x0U;
+	twotcktxdqspre		= 0x0U;
+	lp4tgltwotcktxdqspre	= 0x0U;
+	positiondfeinit		= 0x0U;
+	lp4postambleext		= 0x0U;
+#elif STM32MP_DDR4_TYPE
+	*twotckrxdqspre		= config->uia.d4rxpreamblelength;
+	lp4sttcprebridgerxen	= 0x0U;
+	dllrxpreamblemode	= 0x1U;
+	twotcktxdqspre		= config->uia.d4txpreamblelength;
+	lp4tgltwotcktxdqspre	= 0x0U;
+	positiondfeinit		= 0x2U;
+	lp4postambleext		= 0x0U;
+#else /* STM32MP_LPDDR4_TYPE */
+	/* Set to 1 if static Rx preamble */
+	*twotckrxdqspre		= (config->uia.lp4rxpreamblemode == 0U) ? 1U : 0U;
+	/* Set to 1 if static Rx preamble */
+	lp4sttcprebridgerxen	= (config->uia.lp4rxpreamblemode == 0U) ? 1U : 0U;
+	dllrxpreamblemode	= 0x1U;
+	/* Must be 2*Tck Tx preamble according to JEDEC (mr1.OP[2] = 1) */
+	twotcktxdqspre		= 0x1U;
+	/* Must be toggling Tx preamble */
+	lp4tgltwotcktxdqspre	= 0x1U;
+	positiondfeinit		= 0x0U;
+	lp4postambleext		= config->uia.lp4postambleext;
+	wdqsextension		= config->uia.wdqsext;
+#endif /* STM32MP_DDR3_TYPE */
+
+	dqspreamblecontrol = (uint16_t)((wdqsextension << CSR_WDQSEXTENSION_LSB) |
+					(lp4sttcprebridgerxen << CSR_LP4STTCPREBRIDGERXEN_LSB) |
+					(lp4postambleext << CSR_LP4POSTAMBLEEXT_LSB) |
+					(lp4tgltwotcktxdqspre << CSR_LP4TGLTWOTCKTXDQSPRE_LSB) |
+					(positiondfeinit << CSR_POSITIONDFEINIT_LSB) |
+					(twotcktxdqspre << CSR_TWOTCKTXDQSPRE_LSB) |
+					(*twotckrxdqspre << CSR_TWOTCKRXDQSPRE_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DQSPREAMBLECONTROL_ADDR))),
+		      dqspreamblecontrol);
+
+	dbytedllmodecntrl = (uint16_t)(dllrxpreamblemode << CSR_DLLRXPREAMBLEMODE_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DBYTEDLLMODECNTRL_ADDR))),
+		      dbytedllmodecntrl);
+
+	dllgainctl = (uint16_t)(dllgainiv | (dllgaintv << CSR_DLLGAINTV_LSB));
+	dlllockparam = (uint16_t)(disdllseedsel | (disdllgainivseed << CSR_DISDLLGAINIVSEED_LSB) |
+				  (lcdlseed0 << CSR_LCDLSEED0_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DLLLOCKPARAM_ADDR))),
+		      dlllockparam);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DLLGAINCTL_ADDR))),
+		      dllgainctl);
+}
+
+/*
+ * Program procodttimectl:
+ * - Fields:
+ *   - POdtStartDelay[3:2]
+ *   - POdtTailWidth[1:0]
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ *   - user_input_advanced.wdqsext
+ */
+static void procodttimectl_program(struct stm32mp_ddr_config *config, uint32_t twotckrxdqspre)
+{
+	uint16_t procodttimectl;
+
+	if (config->uia.wdqsext != 0U) {
+		/* POdtStartDelay = 0x0 and  POdtTailWidth  = 0x3 */
+		procodttimectl = 0x3U;
+	} else if (config->uib.frequency <= 933U) {
+		/* Memclk Freq <= 933MHz: POdtStartDelay = 0x2 and POdtTailWidth  = 0x2 */
+		procodttimectl = 0xAU;
+	} else if (config->uib.frequency <= 1200U) {
+		/* 933MHz < Memclk Freq <= 1200MHz */
+		if (twotckrxdqspre == 1U) {
+			/* POdtStartDelay = 0x0 and  POdtTailWidth  = 0x2 */
+			procodttimectl = 0x2U;
+		} else {
+			/* POdtStartDelay = 0x1 and POdtTailWidth  = 0x2 */
+			procodttimectl = 0x6U;
+		}
+	} else {
+		/* Memclk Freq > 1200MHz */
+		if (twotckrxdqspre == 1U) {
+			/* POdtStartDelay = 0x0 and POdtTailWidth  = 0x3 */
+			procodttimectl = 0x3U;
+		} else {
+			/* POdtStartDelay = 0x1 and POdtTailWidth  = 0x3 */
+			procodttimectl = 0x7U;
+		}
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_PROCODTTIMECTL_ADDR))),
+		      procodttimectl);
+}
+
+/*
+ * Program txodtdrvstren:
+ * - Fields:
+ *   - ODTStrenP_px[5:0]
+ *   - ODTStrenN_px[11:6]
+ * - Dependencies:
+ *   - user_input_basic.numdbyte
+ *   - user_input_advanced.odtimpedance
+ * \return 0 on success.
+ */
+static int txodtdrvstren_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte;
+	int odtstrenn_state;
+	int odtstrenp_state;
+	uint16_t txodtdrvstren;
+
+	odtstrenp_state = ddrphy_phyinit_mapdrvstren(config->uia.odtimpedance, ODTSTRENP);
+	if (odtstrenp_state < 0) {
+		return odtstrenp_state;
+	}
+
+	odtstrenn_state = ddrphy_phyinit_mapdrvstren(config->uia.odtimpedance, ODTSTRENN);
+	if (odtstrenn_state < 0) {
+		return odtstrenn_state;
+	}
+
+	txodtdrvstren = (uint16_t)((odtstrenn_state << CSR_ODTSTRENN_LSB) | odtstrenp_state);
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane <= B_MAX; lane++) {
+			uint32_t b_addr;
+
+			b_addr = lane << 8;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | c_addr | b_addr |
+									CSR_TXODTDRVSTREN_ADDR))),
+				      txodtdrvstren);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Program tximpedancectrl1:
+ * - Fields:
+ *   - DrvStrenFSDqP[5:0]
+ *   - DrvStrenFSDqN[11:6]
+ * - Dependencies:
+ *   - user_input_basic.numdbyte
+ *   - user_input_advanced.tximpedance
+ * \return 0 on success.
+ */
+static int tximpedancectrl1_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte;
+	int drvstrenfsdqn_state;
+	int drvstrenfsdqp_state;
+	uint16_t tximpedancectrl1;
+
+	drvstrenfsdqp_state = ddrphy_phyinit_mapdrvstren(config->uia.tximpedance,
+							 DRVSTRENFSDQP);
+	if (drvstrenfsdqp_state < 0) {
+		return drvstrenfsdqp_state;
+	}
+
+	drvstrenfsdqn_state = ddrphy_phyinit_mapdrvstren(config->uia.tximpedance,
+							 DRVSTRENFSDQN);
+	if (drvstrenfsdqn_state < 0) {
+		return drvstrenfsdqn_state;
+	}
+
+	tximpedancectrl1 = (uint16_t)((drvstrenfsdqn_state << CSR_DRVSTRENFSDQN_LSB) |
+				      (drvstrenfsdqp_state << CSR_DRVSTRENFSDQP_LSB));
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane <= B_MAX; lane++) {
+			uint32_t b_addr;
+
+			b_addr = lane << 8;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U *
+								  (TDBYTE | c_addr | b_addr |
+								   CSR_TXIMPEDANCECTRL1_ADDR))),
+				      tximpedancectrl1);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Program atximpedance:
+ * - Fields:
+ *   - ADrvStrenP[4:0]
+ *   - ADrvStrenN[9:5]
+ * - Dependencies:
+ *   - user_input_basic.numanib
+ *   - user_input_advanced.atximpedance
+ * \return 0 on success.
+ */
+static int atximpedance_program(struct stm32mp_ddr_config *config)
+{
+	int adrvstrenn_state;
+	int adrvstrenp_state;
+	uint32_t anib;
+	uint16_t atximpedance;
+
+	adrvstrenp_state = ddrphy_phyinit_mapdrvstren(config->uia.atximpedance,
+						      ADRVSTRENP);
+	if (adrvstrenp_state < 0) {
+		return adrvstrenp_state;
+	}
+
+	adrvstrenn_state = ddrphy_phyinit_mapdrvstren(config->uia.atximpedance,
+						      ADRVSTRENN);
+	if (adrvstrenn_state < 0) {
+		return adrvstrenn_state;
+	}
+
+	atximpedance = (uint16_t)((adrvstrenn_state << CSR_ADRVSTRENN_LSB) |
+				  (adrvstrenp_state << CSR_ADRVSTRENP_LSB));
+
+	for (anib = 0U; anib < config->uib.numanib; anib++) {
+		uint32_t c_addr;
+
+		c_addr = anib << 12;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TANIB | c_addr |
+								CSR_ATXIMPEDANCE_ADDR))),
+			      atximpedance);
+	}
+
+	return 0;
+}
+
+/*
+ * Program dfimode:
+ * - Dependencies:
+ *   - user_input_basic.dfi1exists
+ */
+static void dfimode_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t dfimode = 0x5U;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	if (config->uib.dfi1exists == 0U) {
+		dfimode = 0x1U; /* DFI1 does not physically exists */
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DFIMODE_ADDR))), dfimode);
+}
+
+/*
+ * Program dficamode:
+ * - Fields:
+ *   - DfiLp3CAMode
+ *   - DfiD4CAMode
+ *   - DfiLp4CAMode
+ *   - DfiD4AltCAMode
+ */
+static void dficamode_program(void)
+{
+	uint16_t dficamode;
+
+#if STM32MP_DDR3_TYPE
+	dficamode = 0U;
+#elif STM32MP_DDR4_TYPE
+	dficamode = 2U;
+#else /* STM32MP_LPDDR4_TYPE */
+	dficamode = 4U;
+#endif /* STM32MP_DDR3_TYPE */
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DFICAMODE_ADDR))), dficamode);
+}
+
+/*
+ * Program caldrvstr0:
+ * - Fields:
+ *   - caldrvstrpd50[3:0]
+ *   - caldrvstrpu50[7:4]
+ * - Dependencies:
+ *   - user_input_advanced.extcalresval
+ */
+static void caldrvstr0_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t caldrvstr0;
+	uint16_t caldrvstrp50 = (uint16_t)config->uia.extcalresval;
+
+	caldrvstr0 = (caldrvstrp50 << CSR_CALDRVSTRPU50_LSB) | caldrvstrp50;
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALDRVSTR0_ADDR))),
+		      caldrvstr0);
+}
+
+/*
+ * Program CalUclkInfo:
+ * - Impedance calibration CLK Counter.
+ * - Fields:
+ *   - caluclkticksper1us
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ */
+static void caluclkinfo_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t caluclkticksper1us_x10;
+	uint16_t caluclkticksper1us;
+
+	/* Number of DfiClk cycles per 1us */
+	caluclkticksper1us_x10 = (10U * config->uib.frequency) / 2U;
+	caluclkticksper1us = (uint16_t)(caluclkticksper1us_x10 / 10U);
+
+	if ((config->uib.frequency % 2U) != 0U) {
+		caluclkticksper1us++;
+	}
+
+	if (caluclkticksper1us < 24U) {
+		/* Minimum value of caluclkticksper1us = 24 */
+		caluclkticksper1us = 24U;
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALUCLKINFO_ADDR))),
+		      caluclkticksper1us);
+}
+
+/*
+ * Program Calibration CSRs based on user input
+ * - Fields:
+ *   - calinterval
+ *   - calonce
+ * - Dependencies:
+ *   - user_input_advanced.calinterval
+ *   - user_input_advanced.calonce
+ */
+static void calibration_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t calinterval;
+	uint32_t calonce;
+	uint16_t calrate;
+
+	calinterval = config->uia.calinterval;
+	calonce = config->uia.calonce;
+
+	calrate = (uint16_t)((calonce << CSR_CALONCE_LSB) | (calinterval << CSR_CALINTERVAL_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALRATE_ADDR))), calrate);
+}
+
+/*
+ * Program vrefinglobal:
+ * - dqdqsrcvcntrl and csrvrefinglobal to select Global VREF
+ *   from Master to be used in each DQ.
+ * - Fields:
+ *   - globalvrefinsel: Select Range of GlobalVref DAC. Default: set to 1.
+ *   - globalvrefindac: Vref level is set based on mb_ddr_1d->phyvref value.
+ *     The following formula is used to convert the phyvref into the register setting.
+ *       \f{eqnarray*}{
+ *           PhyVrefPrcnt &=& \frac{mb_ddr_1d->phyvref}{128} \\
+ *        if globalvrefinsel = 1 :
+ *           globalvrefindac &=& 1+\frac{PhyVrefPrcnt}{0.005} \\
+ *        if globalvrefinsel = 0 :
+ *           globalvrefindac &=& \frac{(PhyVrefPrcnt-0.345)}{0.005} \\
+ *           RxVref &=& (globalvrefindac == 0) ? Hi-Z : (PhyVrefPrcnt \times VDDQ)
+ *        \f}
+ *
+ * Program dqdqsrcvcntrl:
+ * - dqdqsrcvcntrl and csrvrefinglobal to select Global VREF
+ *   from Master to be used in each DQ
+ * - Fields:
+ *  - selanalogvref
+ *  - majormodedbyte
+ *  - ExtVrefRange
+ *  - DfeCtrl
+ *  - GainCurrAdj
+ * - Dependencies:
+ *   - user_input_basic.numdbyte
+ */
+static void vrefinglobal_program(struct stm32mp_ddr_config *config,
+				 struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint32_t majormodedbyte;
+	int32_t vref_percentvddq = (int32_t)mb_ddr_1d->phyvref * 1000 * 100 / 128;
+	uint8_t globalvrefindac = 0x0U;
+	uint8_t globalvrefinsel = 0x4U;
+	uint32_t byte;
+	uint32_t dfectrl_defval = 0U;
+	uint32_t extvrefrange_defval = 0U;
+	uint32_t gaincurradj_defval = 0xBU;
+	uint32_t selanalogvref = 1U; /* Use Global VREF from Master */
+	uint16_t dqdqsrcvcntrl;
+	uint16_t vrefinglobal;
+
+#if STM32MP_DDR3_TYPE
+	majormodedbyte = 0U;
+#elif STM32MP_DDR4_TYPE
+	majormodedbyte = 3U;
+#else /* STM32MP_LPDDR4_TYPE */
+	majormodedbyte = 2U;
+#endif /* STM32MP_DDR3_TYPE */
+
+	/* Check range1 first. Only use range0 if customer input maxes out range1. */
+	globalvrefindac = (uint8_t)((vref_percentvddq / 500) + 1);
+	if (globalvrefindac > 127U) {
+		/* Min value is 1 */
+		globalvrefindac = (uint8_t)(MAX((vref_percentvddq - 34500), 500) / 500);
+		globalvrefinsel = 0x0U;
+	}
+	globalvrefindac = MIN(globalvrefindac, (uint8_t)127);
+
+	vrefinglobal = (uint16_t)((globalvrefindac << CSR_GLOBALVREFINDAC_LSB) | globalvrefinsel);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_VREFINGLOBAL_ADDR))),
+		      vrefinglobal);
+
+	dqdqsrcvcntrl = (uint16_t)((gaincurradj_defval << CSR_GAINCURRADJ_LSB) |
+				   (majormodedbyte << CSR_MAJORMODEDBYTE_LSB) |
+				   (dfectrl_defval << CSR_DFECTRL_LSB) |
+				   (extvrefrange_defval << CSR_EXTVREFRANGE_LSB) |
+				   (selanalogvref << CSR_SELANALOGVREF_LSB));
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane <= B_MAX; lane++) {
+			uint32_t b_addr;
+
+			b_addr = lane << 8;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | c_addr | b_addr |
+									CSR_DQDQSRCVCNTRL_ADDR))),
+				      dqdqsrcvcntrl);
+		}
+	}
+}
+
+/*
+ * Program dfifreqratio :
+ * - Dependencies:
+ *   - user_input_basic.dfifreqratio
+ */
+static void dfifreqratio_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t dfifreqratio;
+
+	dfifreqratio = (uint16_t)config->uib.dfifreqratio;
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DFIFREQRATIO_ADDR))),
+		      dfifreqratio);
+}
+
+/*
+ * Program tristatemodeca based on dramtype and 2T Timing
+ * - Fields:
+ *   - CkDisVal
+ *   - disdynadrtri
+ *   - ddr2tmode
+ * - Dependencies:
+ *   - user_input_advanced.is2ttiming
+ *   - user_input_advanced.disdynadrtri
+ */
+static void tristatemodeca_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t ckdisval_def;
+	uint32_t ddr2tmode;
+	uint32_t disdynadrtri;
+	uint16_t tristatemodeca;
+
+	/* CkDisVal depends on dramtype */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	ckdisval_def = 1U; /* {CLK_t,CLK_c} = 2'b00; */
+#else /* STM32MP_LPDDR4_TYPE */
+	ckdisval_def = 0U; /* {CLK_t,CLK_c} = 2'b01; */
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	disdynadrtri = config->uia.disdynadrtri;
+#else /* STM32MP_LPDDR4_TYPE */
+	disdynadrtri = 1U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	ddr2tmode = config->uia.is2ttiming;
+
+	tristatemodeca = (uint16_t)((ckdisval_def << CSR_CKDISVAL_LSB) |
+				    (ddr2tmode << CSR_DDR2TMODE_LSB) |
+				    (disdynadrtri << CSR_DISDYNADRTRI_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_TRISTATEMODECA_ADDR))),
+		      tristatemodeca);
+}
+
+/*
+ * Program DfiXlat based on Pll Bypass Input
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ *   - user_input_basic.pllbypass
+ */
+static void dfixlat_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t loopvector;
+	uint16_t pllbypass_dat = 0U;
+	uint16_t skipddc_dat = 0U;	/*
+					 * Set to vector offset based on frequency to disable dram
+					 * drift compensation.
+					 */
+
+	pllbypass_dat |= (uint16_t)config->uib.pllbypass;
+
+	if (config->uib.frequency < 333U) {
+		skipddc_dat |= 0x5U;
+	}
+
+	for (loopvector = 0U; loopvector < 8U; loopvector++) {
+		uint16_t dfifreqxlat_dat;
+		uintptr_t reg = (uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER |
+								  (CSR_DFIFREQXLAT0_ADDR +
+								   loopvector))));
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+		if (loopvector == 0U) {
+			/*
+			 * Relock DfiFreq = 00,01,02,03)  Use StartVec 5 (pll_enabled) or
+			 * StartVec 6 (pll_bypassed).
+			 */
+			dfifreqxlat_dat = pllbypass_dat + 0x5555U;
+
+			mmio_write_16(reg, dfifreqxlat_dat);
+		} else if (loopvector == 7U) {
+			/* LP3-entry DfiFreq = 1F */
+			mmio_write_16(reg, 0xF000U);
+		} else {
+			/*
+			 * Everything else = skip retrain  (could also map to 0000 since retrain
+			 * code is excluded, but this is cleaner).
+			 */
+			mmio_write_16(reg, 0x5555U);
+		}
+#else /* STM32MP_LPDDR4_TYPE */
+		if (loopvector == 0U) {
+			/*
+			 * Retrain & Relock DfiFreq = 00,01,02,03)  Use StartVec 0 (pll_enabled) or
+			 * StartVec 1 (pll_bypassed).
+			 */
+			dfifreqxlat_dat = pllbypass_dat + skipddc_dat;
+			mmio_write_16(reg, dfifreqxlat_dat);
+		} else if (loopvector == 2U) {
+			/*
+			 * Retrain only DfiFreq = 08,09,0A,0B)  Use StartVec 4 (1, and maybe 2,3,
+			 * used by verif).
+			 */
+			mmio_write_16(reg, 0x4444U);
+		} else if (loopvector == 3U) {
+			/* Phymstr type state change, StartVec 8 */
+			mmio_write_16(reg, 0x8888U);
+		} else if (loopvector == 4U) {
+			/*
+			 * Relock only DfiFreq = 10,11,12,13   Use StartVec 5 (pll_enabled) or
+			 * StartVec 6 (pll_bypassed).
+			 */
+			dfifreqxlat_dat = pllbypass_dat + 0x5555U;
+			mmio_write_16(reg, dfifreqxlat_dat);
+		} else if (loopvector == 7U) {
+			/* LP3-entry DfiFreq = 1F */
+			mmio_write_16(reg, 0xF000U);
+		} else {
+			/* Everything else */
+			mmio_write_16(reg, 0x0000U);
+		}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+	}
+}
+
+/*
+ * Program dqdqsrcvcntrl1 (Receiver Powerdown) and DbyteMiscMode
+ * - see function ddrphy_phyinit_isdbytedisabled() to determine
+ *   which DBytes are turned off completely based on PHY configuration.
+ * - Fields:
+ *   - DByteDisable
+ *   - PowerDownRcvr
+ *   - PowerDownRcvrDqs
+ *   - RxPadStandbyEn
+ * - Dependencies:
+ *   - user_input_basic.numdbyte
+ *   - user_input_basic.dramdatawidth (DDR3/DDR4)
+ *   - mb_ddr_1d->mr5 (DDR4)
+ *   - user_input_advanced.lp4dbird (LPDDR4)
+ */
+static void dqdqsrcvcntrl1_program(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint32_t d;
+	uint16_t mr5 __maybe_unused;
+	uint16_t regdata;
+	uint16_t regdata1;
+	uint16_t regdata2; /* Turn off Rx of DBI lane */
+
+	regdata = 0x1U << CSR_DBYTEDISABLE_LSB;
+
+	regdata1 = (0x1FFU << CSR_POWERDOWNRCVR_LSB) |
+		   (0x1U << CSR_POWERDOWNRCVRDQS_LSB) |
+		   (0x1U << CSR_RXPADSTANDBYEN_LSB);
+
+	regdata2 = (0x100U << CSR_POWERDOWNRCVR_LSB) | CSR_RXPADSTANDBYEN_MASK;
+
+#if STM32MP_DDR4_TYPE
+	/* OR all mr4 masked values, to help check in next loop */
+	mr5 = (mb_ddr_1d->mr5 >> 12) & 0x1U;
+#endif /* STM32MP_DDR4_TYPE */
+
+	for (d = 0U; d < config->uib.numdbyte; d++) {
+		uint32_t c_addr;
+
+		c_addr = d * C1;
+		if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, d) != 0) {
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+									CSR_DBYTEMISCMODE_ADDR))),
+				      regdata);
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+									CSR_DQDQSRCVCNTRL1_ADDR))),
+				      regdata1);
+		} else {
+			/* Disable RDBI lane if not used. */
+#if STM32MP_DDR3_TYPE
+			if (config->uib.dramdatawidth != 4U) {
+#elif STM32MP_DDR4_TYPE
+			if ((config->uib.dramdatawidth != 4U) && (mr5 == 0U)) {
+#else /* STM32MP_LPDDR4_TYPE */
+			if (config->uia.lp4dbird == 0U) {
+#endif /* STM32MP_DDR3_TYPE */
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								     CSR_DQDQSRCVCNTRL1_ADDR))),
+					      regdata2);
+			}
+		}
+	}
+}
+
+/*
+ * Program masterx4config
+ * - Fields:
+ *   - x4tg
+ *   - masterx4config
+ * - Dependencies:
+ *   - user_input_basic.dramdatawidth
+ *
+ * \note PHY does not support mixed dram device data width
+ */
+static void masterx4config_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t x4tg = 0U;
+	uint16_t masterx4config;
+
+	if (config->uib.dramdatawidth == 4U) {
+		x4tg = 0xFU;
+	}
+
+	masterx4config = (uint16_t)(x4tg << CSR_X4TG_LSB);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MASTERX4CONFIG_ADDR))),
+		      masterx4config);
+}
+
+#if !STM32MP_DDR3_TYPE
+/*
+ * Program dmipinpresent based on dramtype and Read-DBI enable
+ * - Fields:
+ *   - RdDbiEnabled
+ * - Dependencies:
+ *   - mb_ddr_1d->mr5 (DDR4)
+ *   - user_input_advanced.lp4dbird (LPDDR4)
+ */
+static void dmipinpresent_program(struct stm32mp_ddr_config *config,
+				  struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint16_t dmipinpresent;
+
+#if STM32MP_DDR4_TYPE
+	/* For DDR4, Read DBI is enabled in mr5-A12 */
+	dmipinpresent = (mb_ddr_1d->mr5 >> 12) & 0x1U;
+#else /* STM32MP_LPDDR4_TYPE */
+	dmipinpresent = (uint16_t)config->uia.lp4dbird;
+#endif /* STM32MP_DDR4_TYPE */
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DMIPINPRESENT_ADDR))),
+		      dmipinpresent);
+}
+#endif /* !STM32MP_DDR3_TYPE */
+
+/*
+ * Program aforcetricont and acx4anibdis
+ * - Fields:
+ *   - aforcetricont
+ *   - acx4anibdis
+ * - Dependencies:
+ *   - user_input_basic.numrank_dfi0
+ *   - user_input_basic.numrank_dfi1
+ *   - user_input_basic.numanib
+ *   - user_input_advanced.disableunusedaddrlns
+ */
+static void aforcetricont_acx4anibdis_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t anib;
+	uint16_t acx4anibdis = 0x0U;
+
+	for (anib = 0U; (anib < config->uib.numanib) && (config->uia.disableunusedaddrlns != 0U);
+	     anib++) {
+		uint32_t c_addr;
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+		uint32_t numrank = config->uib.numrank_dfi0 + config->uib.numrank_dfi1;
+#else /* STM32MP_LPDDR4_TYPE */
+		uint32_t numrank0 = config->uib.numrank_dfi0;
+		uint32_t numrank1 = config->uib.numrank_dfi1;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+		uint16_t aforcetricont = 0x0U;
+
+		c_addr = anib << 12;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+		if ((anib == 0U) && (numrank == 1U)) {
+			aforcetricont = 0x2U;
+		} else if ((anib == 1U) && (numrank == 1U)) {
+			aforcetricont = 0xCU;
+		} else if (anib == 6U) {
+			aforcetricont = 0x1U;
+		}
+#else /* STM32MP_LPDDR4_TYPE */
+		if ((anib == 0U) && (numrank0 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 0U) && (numrank0 == 1U)) {
+			aforcetricont = 0x2U;
+		} else if ((anib == 1U) && (numrank0 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 1U) && (numrank0 == 1U)) {
+			aforcetricont = 0x8U;
+		} else if ((anib == 2U) && (numrank0 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 3U) && (numrank1 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 3U) && (numrank1 == 1U)) {
+			aforcetricont = 0x2U;
+		} else if ((anib == 4U) && (numrank1 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 4U) && (numrank1 == 1U)) {
+			aforcetricont = 0x8U;
+		} else if ((anib == 5U) && (numrank1 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if (anib == 6U) {
+			aforcetricont = 0xFU;
+		} else if (anib == 7U) {
+			aforcetricont = 0xFU;
+		}
+
+		/*
+		 * If all the lanes can be disabled, and Anib is not the first or last disable
+		 * entire chiplet
+		 */
+		if ((aforcetricont == 0xFU) && (anib != 0U) &&
+		    (anib != (config->uib.numanib - 1U))) {
+			acx4anibdis = acx4anibdis | (0x1U << anib);
+		}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TANIB | c_addr |
+								CSR_AFORCETRICONT_ADDR))),
+			      aforcetricont);
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_ACX4ANIBDIS_ADDR))),
+		      acx4anibdis);
+}
+
+/*
+ * Implements Step C of initialization sequence
+ *
+ * This function programs majority of PHY configuration registers based
+ * on data input into PhyInit data structures.
+ *
+ * This function programs PHY configuration registers based on information
+ * provided in the PhyInit data structures (config->uib, config->uia).
+ * The user can overwrite the programming of this function by modifying
+ * ddrphy_phyinit_usercustom_custompretrain().  Please see
+ * ddrphy_phyinit_struct.h for PhyInit data structure definition.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_c_initphyconfig(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t *ardptrinitval)
+{
+	uint32_t twotckrxdqspre;
+	int ret;
+
+	/*
+	 * Step (C) Initialize PHY Configuration
+	 * Load the required PHY configuration registers for the appropriate mode and memory
+	 * configuration.
+	 */
+
+	txslewrate_program(config);
+
+	atxslewrate_program(config);
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	dfidatacsdestmap_program(mb_ddr_1d);
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	pllctrl2_program(config);
+
+	ardptrinitval_program(config, ardptrinitval);
+
+#if STM32MP_LPDDR4_TYPE
+	procodtctl_program();
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	dbytedllmodecntrl_program(config, &twotckrxdqspre);
+
+	procodttimectl_program(config, twotckrxdqspre);
+
+	ret = txodtdrvstren_program(config);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = tximpedancectrl1_program(config);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = atximpedance_program(config);
+	if (ret != 0) {
+		return ret;
+	}
+
+	dfimode_program(config);
+
+	dficamode_program();
+
+	caldrvstr0_program(config);
+
+	caluclkinfo_program(config);
+
+	calibration_program(config);
+
+	vrefinglobal_program(config, mb_ddr_1d);
+
+	dfifreqratio_program(config);
+
+	tristatemodeca_program(config);
+
+	dfixlat_program(config);
+
+	dqdqsrcvcntrl1_program(config, mb_ddr_1d);
+
+	masterx4config_program(config);
+
+#if !STM32MP_DDR3_TYPE
+	dmipinpresent_program(config, mb_ddr_1d);
+
+#if STM32MP_LPDDR4_TYPE
+	/*
+	 * Program DFIPHYUPD
+	 * - Fields:
+	 *   - DFIPHYUPDMODE
+	 *   - DFIPHYUPDCNT
+	 * - Dependencies:
+	 *   - user_input_advanced.disablephyupdate
+	 */
+	if (config->uia.disablephyupdate != 0U) {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DFIPHYUPD_ADDR))),
+			      0x0U);
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+#endif /* !STM32MP_DDR3_TYPE */
+
+	aforcetricont_acx4anibdis_program(config);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_calcmb.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_calcmb.c
new file mode 100644
index 0000000..c5fa5f1
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_calcmb.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * Reads PhyInit inputs structures and sets relevant message block
+ * parameters.
+ *
+ * This function sets Message Block parameters based on user_input_basic and
+ * user_input_advanced. user changes in these files takes precedence
+ * over this function call.
+ *
+ * MessageBlock fields set :
+ *  - dramtype
+ *  - pstate
+ *  - dramfreq
+ *  - pllbypassen
+ *  - dfifreqratio
+ *  - phyodtimpedance
+ *  - phydrvimpedance
+ *  - bpznresval
+ *  - enableddqscha (LPDDR4)
+ *  - cspresentcha (LPDDR4)
+ *  - enableddqsChb (LPDDR4)
+ *  - cspresentchb (LPDDR4)
+ *  - enableddqs (DDR3/DDR4)
+ *  - phycfg (DDR3/DDR4)
+ *  - x16present (DDR4)
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_calcmb(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint32_t nad0 = config->uib.numactivedbytedfi0;
+	uint32_t nad1 = 0;
+	uint16_t mr4 __maybe_unused;
+	uint16_t disableddbyte __maybe_unused;
+	uint32_t dbyte __maybe_unused;
+	int ret;
+
+#if STM32MP_LPDDR4_TYPE
+	nad1 = config->uib.numactivedbytedfi1;
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	/* A few checks to make sure valid programming */
+	if ((nad0 == 0U) || (config->uib.numdbyte == 0U)) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s numactivedbytedfi0, numactivedbytedfi0, NumByte out of range.\n",
+			__func__);
+		return -1;
+	}
+
+	if ((nad0 + nad1) > config->uib.numdbyte) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s numactivedbytedfi0+numactivedbytedfi1 is larger than numdbyteDfi0\n",
+			__func__);
+		return -1;
+	}
+
+	if ((config->uib.dfi1exists == 0U) && (nad1 != 0U)) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s dfi1exists==0 but numdbyteDfi0 != 0\n", __func__);
+		return -1;
+	}
+
+#if STM32MP_DDR4_TYPE
+	/* OR all mr4 masked values, to help check in next loop */
+	mr4 = mb_ddr_1d->mr4 & 0x1C0U;
+
+	/* 1D message block defaults */
+	if (mr4 != 0x0U) {
+		ERROR("mr4 != 0x0\n");
+		VERBOSE("%s Setting DRAM CAL mode is not supported by the PHY.\n", __func__);
+		VERBOSE("Memory controller may set CAL mode after PHY has entered mission\n");
+		VERBOSE("mode. Please check value programmed in mb_ddr_1d[*].mr4\n");
+		VERBOSE("and unset A8:6\n");
+		return -1;
+	}
+#endif /* STM32MP_DDR4_TYPE */
+
+#if STM32MP_DDR3_TYPE
+	if (config->uib.dimmtype == DDR_DIMMTYPE_NODIMM) {
+		ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DRAMTYPE, 0x1U);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+#elif STM32MP_DDR4_TYPE
+	if (config->uib.dimmtype == DDR_DIMMTYPE_NODIMM) {
+		ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DRAMTYPE, 0x2U);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+#else /* STM32MP_LPDDR4_TYPE */
+	/* Nothing to do */
+#endif /* STM32MP_DDR3_TYPE */
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PSTATE, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DRAMFREQ, config->uib.frequency * 2U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PLLBYPASSEN, config->uib.pllbypass);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (config->uib.dfifreqratio == 1U) {
+		ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DFIFREQRATIO, 0x2U);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PHYODTIMPEDANCE, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PHYDRVIMPEDANCE, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_BPZNRESVAL, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_ENABLEDDQS, nad0 * 8U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	disableddbyte = 0x0U;
+
+	for (dbyte = 0U; (dbyte < config->uib.numdbyte) && (dbyte < 8U); dbyte++) {
+		if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, dbyte) != 0) {
+			disableddbyte |= 0x1U << dbyte;
+		}
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DISABLEDDBYTE, disableddbyte);
+	if (ret != 0) {
+		return ret;
+	}
+
+#if STM32MP_DDR3_TYPE
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PHYCFG, config->uia.is2ttiming);
+	if (ret != 0) {
+		return ret;
+	}
+#else /* STM32MP_DDR4_TYPE */
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PHYCFG,
+				       ((mb_ddr_1d->mr3 & 0x8U) != 0U) ?
+				       0U : config->uia.is2ttiming);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_X16PRESENT,
+				       (config->uib.dramdatawidth == 0x10U) ?
+				       mb_ddr_1d->cspresent : 0x0U);
+	if (ret != 0) {
+		return ret;
+	}
+#endif /* STM32MP_DDR3_TYPE */
+#else /* STM32MP_LPDDR4_TYPE */
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_ENABLEDDQSCHA, nad0 * 8U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_CSPRESENTCHA,
+				       (config->uib.numrank_dfi0 == 2U) ?
+				       0x3U : config->uib.numrank_dfi0);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_ENABLEDDQSCHB, nad1 * 8U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_CSPRESENTCHB,
+				       (config->uib.numrank_dfi1 == 2U) ?
+				       0x3U : config->uib.numrank_dfi1);
+	if (ret != 0) {
+		return ret;
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_d_loadimem.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_d_loadimem.c
new file mode 100644
index 0000000..8bec30b
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_d_loadimem.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * This function loads the training firmware IMEM image into the PHY.
+ *
+ * This function reads the DDR firmware source memory area to generate a
+ * set of apb writes to load IMEM image into the PHY. The exact steps in this
+ * function are as follows:
+ *
+ * -# Ensure DRAM is in reset.
+ * -# Load the microcontroller memory with the provided training firmware
+ * -# Initialize the firmware mailbox structures to be able to communicate with
+ * the firmware.
+ *
+ * \return void
+ */
+void ddrphy_phyinit_d_loadimem(void)
+{
+	uint16_t memresetl;
+	uint32_t *ptr32;
+
+	/* Set memresetl to avoid glitch on BP_MemReset_L during training */
+	memresetl = CSR_PROTECTMEMRESET_MASK;
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MEMRESETL_ADDR))), memresetl);
+
+	ptr32 = (uint32_t *)(STM32MP_DDR_FW_BASE + STM32MP_DDR_FW_IMEM_OFFSET);
+	ddrphy_phyinit_writeoutmem(ptr32, IMEM_ST_ADDR, IMEM_SIZE);
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_f_loaddmem.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_f_loaddmem.c
new file mode 100644
index 0000000..3c6c87f
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_f_loaddmem.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <platform_def.h>
+
+/*
+ * This function loads the training firmware DMEM image and write the
+ * Message Block parameters for the training firmware into the PHY.
+ *
+ * This function performs the following tasks:
+ *
+ * -# Load the firmware DMEM segment to initialize the data structures from the
+ * DDR firmware source memory area.
+ * -# Write the Firmware Message Block with the required contents detailing the training parameters.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_f_loaddmem(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint32_t sizeofmsgblk;
+	uint16_t *ptr16;
+	uint32_t *ptr32;
+
+	/* Some basic checks on MessageBlock */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	if ((mb_ddr_1d->enableddqs > (8U * (uint8_t)config->uib.numactivedbytedfi0)) ||
+	    (mb_ddr_1d->enableddqs <= 0U)) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s enableddqs is Zero or greater than NumActiveDbytes for Dfi0\n",
+			__func__);
+		return -1;
+	}
+#else /* STM32MP_LPDDR4_TYPE */
+	if (((mb_ddr_1d->enableddqscha % 16U) != 0U) || ((mb_ddr_1d->enableddqschb % 16U) != 0U)) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s Lp3/Lp4 - Number of Dq's Enabled per Channel much be multipe of 16\n",
+			__func__);
+		return -1;
+	}
+
+	if ((mb_ddr_1d->enableddqscha > (uint8_t)(8U * config->uib.numactivedbytedfi0)) ||
+	    (mb_ddr_1d->enableddqschb > (uint8_t)(8U * config->uib.numactivedbytedfi1)) ||
+	    ((mb_ddr_1d->enableddqscha == 0U) && (mb_ddr_1d->enableddqschb == 0U))) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s EnabledDqsChA/B are not set correctly./1\n", __func__);
+		return -1;
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	sizeofmsgblk = sizeof(struct pmu_smb_ddr_1d);
+
+	ptr16 = (uint16_t *)mb_ddr_1d;
+	ddrphy_phyinit_writeoutmsgblk(ptr16, DMEM_ST_ADDR, sizeofmsgblk);
+
+	ptr32 = (uint32_t *)(STM32MP_DDR_FW_BASE + STM32MP_DDR_FW_DMEM_OFFSET);
+	ddrphy_phyinit_writeoutmem(ptr32, DMEM_ST_ADDR + DMEM_BIN_OFFSET,
+				   DMEM_SIZE - STM32MP_DDR_FW_DMEM_OFFSET);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_g_execfw.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_g_execfw.c
new file mode 100644
index 0000000..0c11594
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_g_execfw.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * Execute the Training Firmware
+ *
+ * The training firmware is executed with the procedure:
+ *
+ * -# Reset the firmware microcontroller by writing the MicroReset register to
+ * set the StallToMicro and ResetToMicro fields to 1 (all other fields should be
+ * zero). Then rewrite the registers so that only the StallToMicro remains set
+ * (all other fields should be zero).
+ * -# Begin execution of the training firmware by setting the MicroReset
+ * register to 0.
+ * -# Wait for the training firmware to complete by following the procedure implemented in
+ * ddrphy_phyinit_usercustom_g_waitfwdone() function.
+ * -# Halt the microcontroller.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_g_execfw(void)
+{
+	int ret;
+
+	/*
+	 * 1. Reset the firmware microcontroller by writing the MicroReset CSR to set the
+	 * StallToMicro and ResetToMicro fields to 1 (all other fields should be zero).
+	 * Then rewrite the CSR so that only the StallToMicro remains set (all other fields should
+	 * be zero).
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      CSR_STALLTOMICRO_MASK);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICRORESET_ADDR))),
+		      CSR_RESETTOMICRO_MASK | CSR_STALLTOMICRO_MASK);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICRORESET_ADDR))),
+		      CSR_STALLTOMICRO_MASK);
+
+	/* 2. Begin execution of the training firmware by setting the MicroReset CSR to 0 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICRORESET_ADDR))), 0x0U);
+
+	/*
+	 * 3. Wait for the training firmware to complete by following the procedure
+	 * implemented in ddrphy_phyinit_usercustom_g_waitfwdone() function.
+	 */
+	ret = ddrphy_phyinit_usercustom_g_waitfwdone();
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* 4. Halt the microcontroller */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICRORESET_ADDR))),
+		      CSR_STALLTOMICRO_MASK);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_i_loadpieimage.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_i_loadpieimage.c
new file mode 100644
index 0000000..6ca0ddc
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_i_loadpieimage.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#if STM32MP_LPDDR4_TYPE
+/*
+ * Program DfiWrRdDataCsConfig
+ * - Fields:
+ *   - dfiwrdatacspolarity
+ *   - dfirddatacspolarity
+ */
+static void dfiwrrddatacsconfig_program(void)
+{
+	uint16_t dfiwrdatacspolarity;
+	uint16_t dfirddatacspolarity;
+
+	/*
+	 * DfiWrRdDataCsConfig : dfiwrdatacspolarity=0x1 and dfirddatacspolarity=0x1.
+	 * Set DataCsPolarity bits to enable active high
+	 */
+	dfiwrdatacspolarity = 0x1U;
+	dfirddatacspolarity = 0x1U;
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | C0 |
+							CSR_DFIWRRDDATACSCONFIG_ADDR))),
+		      (dfiwrdatacspolarity << CSR_DFIWRDATACSPOLARITY_LSB) |
+		      (dfirddatacspolarity << CSR_DFIRDDATACSPOLARITY_LSB));
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+/*
+ * Registers: Seq0BDLY0, Seq0BDLY1, Seq0BDLY2, Seq0BDLY3
+ * - Program PIE instruction delays
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ */
+static void seq0bdly_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t lowfreqopt __unused;
+	uint16_t dfifrq_x10;
+	uint16_t pscount_ref;
+	uint16_t pscount[4]; /* Need delays for 0.5us, 1us, 10us, and 25us */
+
+	/*
+	 * Calculate the counts to obtain the correct delay for each frequency
+	 * Need to divide by 4 since the delay value are specified in units of
+	 * 4 clocks.
+	 */
+	dfifrq_x10 = (10U * (uint16_t)config->uib.frequency) / 2U;
+	pscount_ref = dfifrq_x10 / 4U;
+	pscount[0] = pscount_ref / (2U * 10U);
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	if (config->uib.frequency < 400U) {
+		lowfreqopt = 3U;
+	} else if (config->uib.frequency < 533U) {
+		lowfreqopt = 11U;
+	} else {
+		lowfreqopt = 0U;
+	}
+
+	pscount[1] = (pscount_ref / 10U) - lowfreqopt;
+#else /* STM32MP_LPDDR4_TYPE */
+	pscount[1] = pscount_ref / 10U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+	pscount[2] = pscount_ref;
+
+	if (dfifrq_x10 > 2665U) {
+		pscount[3] = 44U;
+	} else if ((dfifrq_x10 <= 2665U) && (dfifrq_x10 > 2000U)) {
+		pscount[3] = 33U;
+	} else {
+		pscount[3] = 16U;
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER | CSR_SEQ0BDLY0_ADDR))),
+		      pscount[0]);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER | CSR_SEQ0BDLY1_ADDR))),
+		      pscount[1]);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER | CSR_SEQ0BDLY2_ADDR))),
+		      pscount[2]);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER | CSR_SEQ0BDLY3_ADDR))),
+		      pscount[3]);
+}
+
+/*
+ * Registers: Seq0BDisableFlag0..7
+ * - Program PIE Instruction Disable Flags
+ * - Dependencies:
+ *   - user_input_advanced.DisableRetraining (LPDDR4)
+ *   - skip_training (LPDDR4)
+ *   - user_input_basic.frequency (LPDDR4)
+ */
+static void seq0bdisableflag_program(struct stm32mp_ddr_config *config, bool skip_training)
+{
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG0_ADDR))),
+		      0x0000U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG1_ADDR))),
+		      0x0173U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG2_ADDR))),
+		      0x0060U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG3_ADDR))),
+		      0x6110U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG4_ADDR))),
+		      0x2152U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG5_ADDR))),
+		      0xDFBDU);
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG6_ADDR))),
+		      0xFFFFU);
+#else /* STM32MP_LPDDR4_TYPE */
+	if (skip_training || (config->uia.disableretraining != 0U) ||
+	    (config->uib.frequency < 333U)) {
+		/* Disabling DRAM drift compensation */
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG |
+								CSR_SEQ0BDISABLEFLAG6_ADDR))),
+			      0xFFFFU);
+	} else {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG |
+								CSR_SEQ0BDISABLEFLAG6_ADDR))),
+			      0x2060U);
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	/*
+	 * - Register: Seq0BGPR7
+	 *   - Program active CSx for MRS7 during D4 RDIMM frequency change
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG7_ADDR))),
+		      0x6152U);
+}
+
+#if STM32MP_LPDDR4_TYPE
+/*
+ * Registers: ppttrainsetup and ppttrainsetup2
+ * - Related to DFI PHY Master Interface (PMI).
+ * - Enable DFI PMI if training firmware was run
+ * - Fields:
+ *   - PhyMstrTrainInterval
+ *   - PhyMstrMaxReqToAck
+ *   - PhyMstrFreqOverride
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ *   - user_input_advanced.PhyMstrTrainInterval
+ *   - user_input_advanced.PhyMstrMaxReqToAck
+ */
+static void ppttrainsetup_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t ppttrainsetup;
+
+	/* Enabling Phy Master Interface for DRAM drift compensation */
+	if (config->uib.frequency >= 333U) {
+		ppttrainsetup =	(uint16_t)((config->uia.phymstrtraininterval <<
+					    CSR_PHYMSTRTRAININTERVAL_LSB) |
+					   (config->uia.phymstrmaxreqtoack <<
+					    CSR_PHYMSTRMAXREQTOACK_LSB));
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_PPTTRAINSETUP_ADDR))),
+			      ppttrainsetup);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER |
+								CSR_PPTTRAINSETUP2_ADDR))),
+			      0x0003U);
+	}
+}
+
+/*
+ * Registers AcsmPlayback*x*
+ * - Program Address/Command Sequence Engine (ACSM) registers with
+ *   required instructions for retraining algorithm.
+ */
+static void acsmplayback_program(void)
+{
+	uint32_t vec;
+
+	for (vec = 0U; vec < 3U; vec++) {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TACSM | (CSR_ACSMPLAYBACK0X0_ADDR +
+									 (vec * 2U))))),
+			      0xE0U);
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TACSM | (CSR_ACSMPLAYBACK1X0_ADDR +
+									 (vec * 2U))))),
+			      0x12U);
+	}
+}
+
+/*
+ * Program Training Hardware Registers for mission mode retraining
+ * and DRAM drift compensation algorithm.
+ */
+static void traininghwreg_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte;
+
+	/* Programing Training Hardware Registers for mission mode retraining */
+
+	/*
+	 * - Register: AcsmCtrl13
+	 *   - Fields: AcsmCkeEnb
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TACSM | CSR_ACSMCTRL13_ADDR))),
+		      0xFU << CSR_ACSMCKEENB_LSB);
+
+	/*
+	 * - Register: AcsmCtrl1
+	 *   - Fields: AcsmRepCnt
+	 *             Need 19 iterations @ 0.25ui increments to cover 4.5UI
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TACSM | CSR_ACSMCTRL1_ADDR))),
+		      0xEU << CSR_ACSMREPCNT_LSB);
+
+	/*
+	 * - Register: TsmByte1, TsmByte2
+	 *   - Dependencies: config->uib.numdbyte
+	 */
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t i_addr;
+		uint16_t regdata;
+		uint32_t vec;
+
+		c_addr = byte * C1;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TSMBYTE1_ADDR))),
+			      0x1U);   /* [15:8] gstep; [7:0]bstep; */
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TSMBYTE2_ADDR))),
+			      0x1U);   /* [15:0] good_bar; */
+
+		regdata = (CSR_DTSMSTATICCMPR_MASK | CSR_DTSMSTATICCMPRVAL_MASK);
+
+		/*
+		 * - Register: TsmByte3, TsmByte5
+		 *   - Fields:
+		 *     - DtsmStaticCmpr
+		 *     - DtsmStaticCmprVal
+		 */
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TSMBYTE3_ADDR))),
+			      regdata);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TSMBYTE5_ADDR))),
+			      0x1U); /* [15:0] bad_bar; */
+
+		/*
+		 * - Register: TrainingParam
+		 *   - Fields:
+		 *     - EnDynRateReduction
+		 *     - RollIntoCoarse
+		 *     - IncDecRate
+		 *     - TrainEnRxEn
+		 *   - Dependencies:
+		 *     - user_input_advanced.DisableRetraining
+		 */
+		regdata = (CSR_ENDYNRATEREDUCTION_MASK | CSR_ROLLINTOCOARSE_MASK |
+			   (0x3U << CSR_INCDECRATE_LSB));
+		regdata = config->uia.disableretraining ?
+			  regdata : (regdata | CSR_TRAINENRXEN_MASK);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TRAININGPARAM_ADDR))),
+			      regdata);
+
+		/*
+		 * - Register: Tsm0
+		 *   - Fields:
+		 *     - DtsmEnb
+		 */
+		regdata = (0x1U << CSR_DTSMENB_LSB);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | I0 | TDBYTE |
+								CSR_TSM0_ADDR))),
+			      regdata);
+
+		/*
+		 * - Register: Tsm2
+		 *   - Fields:
+		 *     - DtsmDisErrChk
+		 */
+		regdata = (0x1U << CSR_DTSMDISERRCHK_LSB);
+		for (vec = 1U; vec <= I_MAX; vec++) {
+			i_addr = vec * I1;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | i_addr | TDBYTE |
+									CSR_TSM2_ADDR))),
+				      regdata);
+		}
+	}
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+/*
+ * - Register: calrate
+ *   - Fields:
+ *     - calOnce
+ *     - calinterval
+ *   - Dependencies
+ *     - user_input_advanced.calinterval
+ *     - user_input_advanced.calonce
+ */
+static void calrate_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t calinterval;
+	uint32_t calonce;
+	uint16_t calrate;
+
+	calinterval = config->uia.calinterval;
+	calonce = config->uia.calonce;
+
+	calrate = (uint16_t)((0x1U << CSR_CALRUN_LSB) | (calonce << CSR_CALONCE_LSB) |
+			     (calinterval << CSR_CALINTERVAL_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALRATE_ADDR))), calrate);
+}
+
+/*
+ * Loads registers after training
+ *
+ * This function programs the PHY Initialization Engine (PIE) instructions and
+ * the associated registers.
+ * Training hardware registers are also programmed to for mission mode
+ * retraining. (LPDDR4)
+ *
+ * \return void
+ */
+void ddrphy_phyinit_i_loadpieimage(struct stm32mp_ddr_config *config, bool skip_training)
+{
+	/*
+	 * Enable access to the internal CSRs by setting the MicroContMuxSel CSR to 0.
+	 * This allows the memory controller unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+
+	ddrphy_phyinit_loadpieprodcode();
+
+#if STM32MP_LPDDR4_TYPE
+	/*
+	 * No user specified EnableDfiCsPolarityFix, running with new PUB with DFI CS polarity fix
+	 * so program the data polarity CSR.
+	 */
+	dfiwrrddatacsconfig_program();
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	seq0bdly_program(config);
+
+	seq0bdisableflag_program(config, skip_training);
+
+#if STM32MP_LPDDR4_TYPE
+	if (!skip_training) {
+		ppttrainsetup_program(config);
+	}
+
+	acsmplayback_program();
+
+	traininghwreg_program(config);
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	/*
+	 * - Register: CalZap
+	 *   - Prepare the calibration controller for mission mode.
+	 *     Turn on calibration and hold idle until dfi_init_start is asserted sequence is
+	 *     triggered.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALZAP_ADDR))), 0x1U);
+
+	calrate_program(config);
+
+	/*
+	 * At the end of this function, PHY Clk gating register UcclkHclkEnables is
+	 * set for mission mode.  Additionally APB access is Isolated by setting
+	 * MicroContMuxSel.
+	 */
+	/* Disabling Ucclk (PMU) and Hclk (training hardware) */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x0U);
+
+	/* Isolate the APB access from the internal CSRs by setting the MicroContMuxSel CSR to 1 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_initstruct.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_initstruct.c
new file mode 100644
index 0000000..50a88be
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_initstruct.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * This is used to initialize the PhyInit structures before user defaults and overrides are applied.
+ *
+ * @return Void
+ */
+void ddrphy_phyinit_initstruct(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	/*
+	 * ##############################################################
+	 * Basic Message Block Variables
+	 * ##############################################################
+	 */
+
+	uint8_t msgmisc = 0x00U;	/* For fast simulation */
+	uint8_t reserved00 = 0x0U;	/*
+					 * Set reserved00[7] = 1 (If using T28 attenuated receivers)
+					 * Set reserved00[6:0] = 0 (Reserved; must be set to 0)
+					 */
+
+	uint8_t hdtctrl = 0xFFU;
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	uint8_t cspresent = 0x01U;	/*
+					 * Indicates presence of DRAM at each chip select for PHY.
+					 *
+					 * If the bit is set to 1, the CS is connected to DRAM.
+					 * If the bit is set to 0, the CS is not connected to DRAM.
+					 *
+					 * Set cspresent[0]   = 1 (if CS0 is populated with DRAM)
+					 * Set cspresent[1]   = 1 (if CS1 is populated with DRAM)
+					 * Set cspresent[2]   = 1 (if CS2 is populated with DRAM)
+					 * Set cspresent[3]   = 1 (if CS3 is populated with DRAM)
+					 * Set cspresent[7:4] = 0 (Reserved; must be set to 0)
+					 */
+	uint8_t dfimrlmargin = 0x01U;	/* 1 is typically good in DDR3 */
+#if STM32MP_DDR3_TYPE
+	uint8_t addrmirror = 0x00U;	/*
+					 * Set addrmirror if CS is mirrored.
+					 * (typically odd CS are mirroed in DIMMs)
+					 */
+#else /* STM32MP_DDR4_TYPE */
+	uint8_t addrmirror = 0xAAU;
+#endif /* STM32MP_DDR3_TYPE */
+	uint8_t wrodtpat_rank0 = 0x01U;	/*
+					 * When Writing Rank0 : Bits[3:0] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+	uint8_t wrodtpat_rank1 = 0x02U;	/*
+					 * When Writing Rank1 : Bits[3:0] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+#if STM32MP_DDR3_TYPE
+	uint8_t wrodtpat_rank2 = 0x04U;	/*
+					 * When Writing Rank2 : Bits[3:0] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+	uint8_t wrodtpat_rank3 = 0x08U;	/*
+					 * When Writing Rank3 : Bits[3:0] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+#else /* STM32MP_DDR4_TYPE */
+	uint8_t wrodtpat_rank2 = 0x00U;
+	uint8_t wrodtpat_rank3 = 0x00U;
+#endif /* STM32MP_DDR3_TYPE */
+	uint8_t rdodtpat_rank0 = 0x20U;	/*
+					 * When Reading Rank0 : Bits[7:4] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+	uint8_t rdodtpat_rank1 = 0x10U;	/*
+					 * When Reading Rank1 : Bits[7:4] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+#if STM32MP_DDR3_TYPE
+	uint8_t rdodtpat_rank2 = 0x80U;	/*
+					 * When Reading Rank2 : Bits[7:4] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+	uint8_t rdodtpat_rank3 = 0x40U;	/*
+					 * When Reading Rank3 : Bits[7:4] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+#else /* STM32MP_DDR4_TYPE */
+	uint8_t rdodtpat_rank2 = 0x00U;
+	uint8_t rdodtpat_rank3 = 0x00U;
+
+	uint8_t d4misc = 0x1U;		/*
+					 * Protect memory reset:
+					 * 0x1 = dfi_reset_n cannot control BP_MEMRESERT_L to
+					 *       devices after training.
+					 * 0x0 = dfi_resert_n can control BP_MEMRESERT_L to
+					 *       devices after training.
+					 */
+#endif /* STM32MP_DDR3_TYPE */
+#else /* STM32MP_LPDDR4_TYPE */
+	uint8_t caterminatingrankcha = 0x00U; /* Usually Rank0 is terminating rank */
+	uint8_t caterminatingrankchb = 0x00U; /* Usually Rank0 is terminating rank */
+	uint8_t dfimrlmargin = 0x02U; /* This needs to be large enough for max tDQSCK variation */
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+#if STM32MP_DDR3_TYPE
+	uint8_t share2dvrefresult = 0x0U;	/*
+						 * Bitmap that controls which vref generator the
+						 * phy will use per pstate
+						 *     If share2dvrefresult[x] = 1, pstate x will
+						 *     use the per-lane VrefDAC0/1 CSRs which can be
+						 *     trained by 2d training. If 2D has not run
+						 *     yet, VrefDAC0/1 will default to pstate 0's
+						 *     1D phyVref messageBlock setting.
+						 *     If share2dvrefresult[x] = 0, pstate x will
+						 *     use the per-phy VrefInGlobal CSR, which are
+						 *     set to pstate x's 1D phyVref messageBlock
+						 *     setting.
+						 */
+#elif STM32MP_DDR4_TYPE
+	uint8_t share2dvrefresult = 0x1U;
+#else /* STM32MP_LPDDR4_TYPE */
+	uint8_t share2dvrefresult = 0x1U;
+	uint8_t usebroadcastmr = 0x00U;
+#endif /* STM32MP_DDR3_TYPE */
+
+	/* 1D message block defaults */
+	memset((void *)mb_ddr_1d, 0, sizeof(struct pmu_smb_ddr_1d));
+
+	mb_ddr_1d->pstate = 0U;
+	mb_ddr_1d->sequencectrl = (uint16_t)config->uia.sequencectrl;
+	mb_ddr_1d->phyconfigoverride = 0x0U;
+	mb_ddr_1d->hdtctrl = hdtctrl;
+	mb_ddr_1d->msgmisc = msgmisc;
+	mb_ddr_1d->reserved00 = reserved00;
+	mb_ddr_1d->dfimrlmargin = dfimrlmargin;
+	mb_ddr_1d->phyvref = (uint8_t)config->uia.phyvref;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	mb_ddr_1d->cspresent = cspresent;
+	mb_ddr_1d->cspresentd0 = cspresent;
+	/* mb_ddr_1d->cspresentd1 = 0x0U; Unused */
+	mb_ddr_1d->addrmirror = addrmirror;
+
+	mb_ddr_1d->acsmodtctrl0 = wrodtpat_rank0 | rdodtpat_rank0;
+	mb_ddr_1d->acsmodtctrl1 = wrodtpat_rank1 | rdodtpat_rank1;
+	mb_ddr_1d->acsmodtctrl2 = wrodtpat_rank2 | rdodtpat_rank2;
+	mb_ddr_1d->acsmodtctrl3 = wrodtpat_rank3 | rdodtpat_rank3;
+
+	/* mb_ddr_1d->acsmodtctrl4 = 0x0U; Unused */
+	/* mb_ddr_1d->acsmodtctrl5 = 0x0U; Unused */
+	/* mb_ddr_1d->acsmodtctrl6 = 0x0U; Unused */
+	/* mb_ddr_1d->acsmodtctrl7 = 0x0U; Unused */
+	mb_ddr_1d->enableddqs = (uint8_t)((config->uib.numactivedbytedfi0 +
+					   config->uib.numactivedbytedfi1) * 8U);
+#if STM32MP_DDR3_TYPE
+	mb_ddr_1d->phycfg = (uint8_t)config->uia.is2ttiming;
+#else /* STM32MP_DDR4_TYPE */
+	mb_ddr_1d->phycfg = ((config->uim.mr3 & 0x8U) == 0x8U) ?
+			      0U : (uint8_t)config->uia.is2ttiming;
+	mb_ddr_1d->x16present = (config->uib.dramdatawidth == 0x10) ?
+				mb_ddr_1d->cspresent : 0x0U;
+	mb_ddr_1d->d4misc = d4misc;
+	mb_ddr_1d->cssetupgddec = 0x1U;	/* If Geardown is chosen, dynamically modify CS timing */
+
+	/*
+	 * Outputs - just initialize these to zero
+	 * mb_ddr_1d->rtt_nom_wr_park<0..7>
+	 */
+#endif /* STM32MP_DDR3_TYPE */
+
+	mb_ddr_1d->mr0 = (uint16_t)config->uim.mr0;
+	mb_ddr_1d->mr1 = (uint16_t)config->uim.mr1;
+	mb_ddr_1d->mr2 = (uint16_t)config->uim.mr2;
+#if STM32MP_DDR4_TYPE
+	mb_ddr_1d->mr3 = (uint16_t)config->uim.mr3;
+	mb_ddr_1d->mr4 = (uint16_t)config->uim.mr4;
+	mb_ddr_1d->mr5 = (uint16_t)config->uim.mr5;
+	mb_ddr_1d->mr6 = (uint16_t)config->uim.mr6;
+
+	mb_ddr_1d->alt_cas_l = 0x0U;
+	mb_ddr_1d->alt_wcas_l = 0x0U;
+
+	/*
+	 * Outputs - just initialize these to zero
+	 * mb_ddr_1d->vrefdqr<0..3>nib<0..19>
+	 */
+#endif /* STM32MP_DDR4_TYPE */
+#else /* STM32MP_LPDDR4_TYPE */
+	mb_ddr_1d->enableddqscha = (uint8_t)(config->uib.numactivedbytedfi0 * 8U);
+	mb_ddr_1d->cspresentcha = (config->uib.numrank_dfi0 == 2U) ?
+				  0x3U : (uint8_t)config->uib.numrank_dfi0;
+	mb_ddr_1d->enableddqschb = (uint8_t)(config->uib.numactivedbytedfi1 * 8U);
+	mb_ddr_1d->cspresentchb = (config->uib.numrank_dfi1 == 2U) ?
+				  0x3U : (uint8_t)config->uib.numrank_dfi1;
+	mb_ddr_1d->usebroadcastmr = usebroadcastmr;
+
+	mb_ddr_1d->lp4misc = 0x00U;
+	mb_ddr_1d->caterminatingrankcha = caterminatingrankcha;
+	mb_ddr_1d->caterminatingrankchb = caterminatingrankchb;
+	mb_ddr_1d->lp4quickboot = 0x00U;
+	mb_ddr_1d->catrainopt = 0x00U;
+	mb_ddr_1d->x8mode = 0x00U;
+
+	mb_ddr_1d->mr1_a0 = (uint8_t)config->uim.mr1;
+	mb_ddr_1d->mr2_a0 = (uint8_t)config->uim.mr2;
+	mb_ddr_1d->mr3_a0 = (uint8_t)config->uim.mr3;
+	mb_ddr_1d->mr4_a0 = (uint8_t)config->uim.mr4;
+	mb_ddr_1d->mr11_a0 = (uint8_t)config->uim.mr11;
+	mb_ddr_1d->mr12_a0 = (uint8_t)config->uim.mr12;
+	mb_ddr_1d->mr13_a0 = (uint8_t)config->uim.mr13;
+	mb_ddr_1d->mr14_a0 = (uint8_t)config->uim.mr14;
+	mb_ddr_1d->mr16_a0 = 0x00U;
+	mb_ddr_1d->mr17_a0 = 0x00U;
+	mb_ddr_1d->mr22_a0 = (uint8_t)config->uim.mr22;
+	mb_ddr_1d->mr24_a0 = 0x00U;
+	mb_ddr_1d->mr1_a1 = (uint8_t)config->uim.mr1;
+	mb_ddr_1d->mr2_a1 = (uint8_t)config->uim.mr2;
+	mb_ddr_1d->mr3_a1 = (uint8_t)config->uim.mr3;
+	mb_ddr_1d->mr4_a1 = (uint8_t)config->uim.mr4;
+	mb_ddr_1d->mr11_a1 = (uint8_t)config->uim.mr11;
+	mb_ddr_1d->mr12_a1 = (uint8_t)config->uim.mr12;
+	mb_ddr_1d->mr13_a1 = (uint8_t)config->uim.mr13;
+	mb_ddr_1d->mr14_a1 = (uint8_t)config->uim.mr14;
+	mb_ddr_1d->mr16_a1 = 0x00U;
+	mb_ddr_1d->mr17_a1 = 0x00U;
+	mb_ddr_1d->mr22_a1 = (uint8_t)config->uim.mr22;
+	mb_ddr_1d->mr24_a1 = 0x00U;
+
+	mb_ddr_1d->mr1_b0 = (uint8_t)config->uim.mr1;
+	mb_ddr_1d->mr2_b0 = (uint8_t)config->uim.mr2;
+	mb_ddr_1d->mr3_b0 = (uint8_t)config->uim.mr3;
+	mb_ddr_1d->mr4_b0 = (uint8_t)config->uim.mr4;
+	mb_ddr_1d->mr11_b0 = (uint8_t)config->uim.mr11;
+	mb_ddr_1d->mr12_b0 = (uint8_t)config->uim.mr12;
+	mb_ddr_1d->mr13_b0 = (uint8_t)config->uim.mr13;
+	mb_ddr_1d->mr14_b0 = (uint8_t)config->uim.mr14;
+	mb_ddr_1d->mr16_b0 = 0x00U;
+	mb_ddr_1d->mr17_b0 = 0x00U;
+	mb_ddr_1d->mr22_b0 = (uint8_t)config->uim.mr22;
+	mb_ddr_1d->mr24_b0 = 0x00U;
+	mb_ddr_1d->mr1_b1 = (uint8_t)config->uim.mr1;
+	mb_ddr_1d->mr2_b1 = (uint8_t)config->uim.mr2;
+	mb_ddr_1d->mr3_b1 = (uint8_t)config->uim.mr3;
+	mb_ddr_1d->mr4_b1 = (uint8_t)config->uim.mr4;
+	mb_ddr_1d->mr11_b1 = (uint8_t)config->uim.mr11;
+	mb_ddr_1d->mr12_b1 = (uint8_t)config->uim.mr12;
+	mb_ddr_1d->mr13_b1 = (uint8_t)config->uim.mr13;
+	mb_ddr_1d->mr14_b1 = (uint8_t)config->uim.mr14;
+	mb_ddr_1d->mr16_b1 = 0x00U;
+	mb_ddr_1d->mr17_b1 = 0x00U;
+	mb_ddr_1d->mr22_b1 = (uint8_t)config->uim.mr22;
+	mb_ddr_1d->mr24_b1 = 0x00U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	mb_ddr_1d->share2dvrefresult = share2dvrefresult;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_isdbytedisabled.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_isdbytedisabled.c
new file mode 100644
index 0000000..4daf2bb
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_isdbytedisabled.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+#include <ddrphy_wrapper.h>
+
+/*
+ * Helper function to determine if a given DByte is Disabled given PhyInit inputs.
+ * @return 1 if disabled, 0 if enabled.
+ */
+int ddrphy_phyinit_isdbytedisabled(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t dbytenumber)
+{
+	int disabledbyte;
+	uint32_t nad0 __maybe_unused;
+	uint32_t nad1 __maybe_unused;
+
+	disabledbyte = 0; /* Default assume Dbyte is Enabled */
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	disabledbyte = (dbytenumber > (config->uib.numactivedbytedfi0 - 1U)) ? 1 : 0;
+#else /* STM32MP_LPDDR4_TYPE */
+	nad0 = config->uib.numactivedbytedfi0;
+	nad1 = config->uib.numactivedbytedfi1;
+
+	if ((nad0 + nad1) > config->uib.numdbyte) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s invalid PHY configuration:\n", __func__);
+		VERBOSE("numactivedbytedfi0(%u)+numactivedbytedfi1(%u)>numdbytes(%u).\n",
+			nad0, nad1, config->uib.numdbyte);
+	}
+
+	if (config->uib.dfi1exists != 0U) {
+		if (config->uib.numactivedbytedfi1 == 0U) {
+			/* Only dfi0 (ChA) is enabled, dfi1 (ChB) disabled */
+			disabledbyte = (dbytenumber > (config->uib.numactivedbytedfi0 - 1U)) ?
+				       1 : 0;
+		} else {
+			/* DFI1 enabled */
+			disabledbyte = (((config->uib.numactivedbytedfi0 - 1U) < dbytenumber) &&
+					(dbytenumber < (config->uib.numdbyte / 2U))) ?
+				       1 : (dbytenumber >
+					    ((config->uib.numdbyte / 2U) +
+					     config->uib.numactivedbytedfi1 - 1U)) ? 1 : 0;
+		}
+	} else {
+		disabledbyte = (dbytenumber > (config->uib.numactivedbytedfi0 - 1U)) ? 1 : 0;
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	/* Qualify results against MessageBlock */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	if ((mb_ddr_1d->enableddqs < 1U) ||
+	    (mb_ddr_1d->enableddqs > (uint8_t)(8U * config->uib.numactivedbytedfi0))) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s enableddqs(%u)\n", __func__, mb_ddr_1d->enableddqs);
+		VERBOSE("Value must be 0 < enableddqs < config->uib.numactivedbytedfi0 * 8.\n");
+	}
+
+	if (dbytenumber < 8) {
+		disabledbyte |= (int)mb_ddr_1d->disableddbyte & (0x1 << dbytenumber);
+	}
+#else /* STM32MP_LPDDR4_TYPE */
+	if ((mb_ddr_1d->enableddqscha < 1U) ||
+	    (mb_ddr_1d->enableddqscha > (uint8_t)(8U * config->uib.numactivedbytedfi0))) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s enableddqscha(%u)\n", __func__, mb_ddr_1d->enableddqscha);
+		VERBOSE("Value must be 0 < enableddqscha < config->uib.numactivedbytedfi0*8\n");
+	}
+
+	if ((config->uib.dfi1exists != 0U) && (config->uib.numactivedbytedfi1 > 0U) &&
+	    ((mb_ddr_1d->enableddqschb < 1U) ||
+	     (mb_ddr_1d->enableddqschb > (uint8_t)(8U * config->uib.numactivedbytedfi1)))) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s enableddqschb(%u)\n", __func__, mb_ddr_1d->enableddqschb);
+		VERBOSE("Value must be 0 < enableddqschb < config->uib.numactivedbytedfi1*8\n");
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	return disabledbyte;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_loadpieprodcode.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_loadpieprodcode.c
new file mode 100644
index 0000000..2843b10
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_loadpieprodcode.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+#define PRODCODE_SIZE	177
+
+static const uint32_t prodcode_addr[PRODCODE_SIZE] = {
+	0x90000U, 0x90001U, 0x90002U, 0x90003U, 0x90004U, 0x90005U, 0x90029U, 0x9002AU, 0x9002BU,
+	0x9002CU, 0x9002DU, 0x9002EU, 0x9002FU, 0x90030U, 0x90031U, 0x90032U, 0x90033U, 0x90034U,
+	0x90035U, 0x90036U, 0x90037U, 0x90038U, 0x90039U, 0x9003AU, 0x9003BU, 0x9003CU, 0x9003DU,
+	0x9003EU, 0x9003FU, 0x90040U, 0x90041U, 0x90042U, 0x90043U, 0x90044U, 0x90045U, 0x90046U,
+	0x90047U, 0x90048U, 0x90049U, 0x9004AU, 0x9004BU, 0x9004CU, 0x9004DU, 0x9004EU, 0x9004FU,
+	0x90050U, 0x90051U, 0x90052U, 0x90053U, 0x90054U, 0x90055U, 0x90056U, 0x90057U, 0x90058U,
+	0x90059U, 0x9005AU, 0x9005BU, 0x9005CU, 0x9005DU, 0x9005EU, 0x9005FU, 0x90060U, 0x90061U,
+	0x90062U, 0x90063U, 0x90064U, 0x90065U, 0x90066U, 0x90067U, 0x90068U, 0x90069U, 0x9006AU,
+	0x9006BU, 0x9006CU, 0x9006DU, 0x9006EU, 0x9006FU, 0x90070U, 0x90071U, 0x90072U, 0x90073U,
+	0x90074U, 0x90075U, 0x90076U, 0x90077U, 0x90078U, 0x90079U, 0x9007AU, 0x9007BU, 0x9007CU,
+	0x9007DU, 0x9007EU, 0x9007FU, 0x90080U, 0x90081U, 0x90082U, 0x90083U, 0x90084U, 0x90085U,
+	0x90086U, 0x90087U, 0x90088U, 0x90089U, 0x9008AU, 0x9008BU, 0x9008CU, 0x9008DU, 0x9008EU,
+	0x9008FU, 0x90090U, 0x90091U, 0x90092U, 0x90093U, 0x90094U, 0x90095U, 0x90096U, 0x90097U,
+	0x90098U, 0x90099U, 0x9009AU, 0x9009BU, 0x9009CU, 0x9009DU, 0x9009EU, 0x9009FU, 0x900A0U,
+	0x900A1U, 0x900A2U, 0x900A3U, 0x900A4U, 0x900A5U, 0x900A6U, 0x900A7U, 0x900A8U, 0x900A9U,
+	0x900AAU, 0x900ABU, 0x900ACU, 0x900ADU, 0x900AEU, 0x900AFU, 0x900B0U, 0x900B1U, 0x900B2U,
+	0x900B3U, 0x900B4U, 0x900B5U, 0x900B6U, 0x900B7U, 0x900B8U, 0x900B9U, 0x900BAU, 0x900BBU,
+	0x900BCU, 0x900BDU, 0x900BEU, 0x900BFU, 0x900C0U, 0x900C1U, 0x900C2U, 0x900C3U, 0x900C4U,
+	0x900C5U, 0x900C6U, 0x900C7U, 0x900C8U, 0x900C9U, 0x900CAU, 0x90006U, 0x90007U, 0x90008U,
+	0x90009U, 0x9000AU, 0x9000BU, 0xD00E7U, 0x90017U, 0x90026U,
+};
+
+static const uint16_t prodcode_data[PRODCODE_SIZE] = {
+	0x0010U, 0x0400U, 0x010EU, 0x0000U, 0x0000U, 0x0008U, 0x000BU, 0x0480U, 0x0109U, 0x0008U,
+	0x0448U, 0x0139U, 0x0008U, 0x0478U, 0x0109U, 0x0002U, 0x0010U, 0x0139U, 0x000BU, 0x07C0U,
+	0x0139U, 0x0044U, 0x0633U, 0x0159U, 0x014FU, 0x0630U, 0x0159U, 0x0047U, 0x0633U, 0x0149U,
+	0x004FU, 0x0633U, 0x0179U, 0x0008U, 0x00E0U, 0x0109U, 0x0000U, 0x07C8U, 0x0109U, 0x0000U,
+	0x0001U, 0x0008U, 0x0030U, 0x065AU, 0x0009U, 0x0000U, 0x045AU, 0x0009U, 0x0000U, 0x0448U,
+	0x0109U, 0x0040U, 0x0633U, 0x0179U, 0x0001U, 0x0618U, 0x0109U, 0x40C0U, 0x0633U, 0x0149U,
+	0x0008U, 0x0004U, 0x0048U, 0x4040U, 0x0633U, 0x0149U, 0x0000U, 0x0004U, 0x0048U, 0x0040U,
+	0x0633U, 0x0149U, 0x0000U, 0x0658U, 0x0109U, 0x0010U, 0x0004U, 0x0018U, 0x0000U, 0x0004U,
+	0x0078U, 0x0549U, 0x0633U, 0x0159U, 0x0D49U, 0x0633U, 0x0159U, 0x094AU, 0x0633U, 0x0159U,
+	0x0441U, 0x0633U, 0x0149U, 0x0042U, 0x0633U, 0x0149U, 0x0001U, 0x0633U, 0x0149U, 0x0000U,
+	0x00E0U, 0x0109U, 0x000AU, 0x0010U, 0x0109U, 0x0009U, 0x03C0U, 0x0149U, 0x0009U, 0x03C0U,
+	0x0159U, 0x0018U, 0x0010U, 0x0109U, 0x0000U, 0x03C0U, 0x0109U, 0x0018U, 0x0004U, 0x0048U,
+	0x0018U, 0x0004U, 0x0058U, 0x000BU, 0x0010U, 0x0109U, 0x0001U, 0x0010U, 0x0109U, 0x0005U,
+	0x07C0U, 0x0109U, 0x0000U, 0x8140U, 0x010CU, 0x0010U, 0x8138U, 0x0104U, 0x0008U, 0x0448U,
+	0x0109U, 0x000FU, 0x07C0U, 0x0109U, 0x0047U, 0x0630U, 0x0109U, 0x0008U, 0x0618U, 0x0109U,
+	0x0008U, 0x00E0U, 0x0109U, 0x0000U, 0x07C8U, 0x0109U, 0x0008U, 0x8140U, 0x010CU, 0x0000U,
+	0x0478U, 0x0109U, 0x0000U, 0x0001U, 0x0008U, 0x0008U, 0x0004U, 0x0000U, 0x0008U, 0x07C8U,
+	0x0109U, 0x0000U, 0x0400U, 0x0106U, 0x0400U, 0x0000U, 0x002CU,
+	};
+
+#else /* STM32MP_LPDDR4_TYPE */
+#define PRODCODE_SIZE		481
+
+static const uint32_t prodcode_addr[PRODCODE_SIZE] = {
+	0x90000U, 0x90001U, 0x90002U, 0x90003U, 0x90004U, 0x90005U, 0x90029U, 0x9002AU, 0x9002BU,
+	0x9002CU, 0x9002DU, 0x9002EU, 0x9002FU, 0x90030U, 0x90031U, 0x90032U, 0x90033U, 0x90034U,
+	0x90035U, 0x90036U, 0x90037U, 0x90038U, 0x90039U, 0x9003AU, 0x9003BU, 0x9003CU, 0x9003DU,
+	0x9003EU, 0x9003FU, 0x90040U, 0x90041U, 0x90042U, 0x90043U, 0x90044U, 0x90045U, 0x90046U,
+	0x90047U, 0x90048U, 0x90049U, 0x9004AU, 0x9004BU, 0x9004CU, 0x9004DU, 0x9004EU, 0x9004FU,
+	0x90050U, 0x90051U, 0x90052U, 0x90053U, 0x90054U, 0x90055U, 0x90056U, 0x90057U, 0x90058U,
+	0x90059U, 0x9005AU, 0x9005BU, 0x9005CU, 0x9005DU, 0x9005EU, 0x9005FU, 0x90060U, 0x90061U,
+	0x90062U, 0x90063U, 0x90064U, 0x90065U, 0x90066U, 0x90067U, 0x90068U, 0x90069U, 0x9006AU,
+	0x9006BU, 0x9006CU, 0x9006DU, 0x9006EU, 0x9006FU, 0x90070U, 0x90071U, 0x90072U, 0x90073U,
+	0x90074U, 0x90075U, 0x90076U, 0x90077U, 0x90078U, 0x90079U, 0x9007AU, 0x9007BU, 0x9007CU,
+	0x9007DU, 0x9007EU, 0x9007FU, 0x90080U, 0x90081U, 0x90082U, 0x90083U, 0x90084U, 0x90085U,
+	0x90086U, 0x90087U, 0x90088U, 0x90089U, 0x9008AU, 0x9008BU, 0x9008CU, 0x9008DU, 0x9008EU,
+	0x9008FU, 0x90090U, 0x90091U, 0x90092U, 0x90093U, 0x90094U, 0x90095U, 0x90096U, 0x90097U,
+	0x90098U, 0x90099U, 0x9009AU, 0x9009BU, 0x9009CU, 0x9009DU, 0x9009EU, 0x9009FU, 0x900A0U,
+	0x900A1U, 0x900A2U, 0x900A3U, 0x900A4U, 0x900A5U, 0x900A6U, 0x900A7U, 0x900A8U, 0x900A9U,
+	0x40000U, 0x40020U, 0x40040U, 0x40060U, 0x40001U, 0x40021U, 0x40041U, 0x40061U, 0x40002U,
+	0x40022U, 0x40042U, 0x40062U, 0x40003U, 0x40023U, 0x40043U, 0x40063U, 0x40004U, 0x40024U,
+	0x40044U, 0x40064U, 0x40005U, 0x40025U, 0x40045U, 0x40065U, 0x40006U, 0x40026U, 0x40046U,
+	0x40066U, 0x40007U, 0x40027U, 0x40047U, 0x40067U, 0x40008U, 0x40028U, 0x40048U, 0x40068U,
+	0x40009U, 0x40029U, 0x40049U, 0x40069U, 0x4000AU, 0x4002AU, 0x4004AU, 0x4006AU, 0x4000BU,
+	0x4002BU, 0x4004BU, 0x4006BU, 0x4000CU, 0x4002CU, 0x4004CU, 0x4006CU, 0x4000DU, 0x4002DU,
+	0x4004DU, 0x4006DU, 0x4000EU, 0x4002EU, 0x4004EU, 0x4006EU, 0x4000FU, 0x4002FU, 0x4004FU,
+	0x4006FU, 0x40010U, 0x40030U, 0x40050U, 0x40070U, 0x40011U, 0x40031U, 0x40051U, 0x40071U,
+	0x40012U, 0x40032U, 0x40052U, 0x40072U, 0x40013U, 0x40033U, 0x40053U, 0x40073U, 0x40014U,
+	0x40034U, 0x40054U, 0x40074U, 0x40015U, 0x40035U, 0x40055U, 0x40075U, 0x40016U, 0x40036U,
+	0x40056U, 0x40076U, 0x40017U, 0x40037U, 0x40057U, 0x40077U, 0x40018U, 0x40038U, 0x40058U,
+	0x40078U, 0x40019U, 0x40039U, 0x40059U, 0x40079U, 0x4001AU, 0x4003AU, 0x4005AU, 0x4007AU,
+	0x900AAU, 0x900ABU, 0x900ACU, 0x900ADU, 0x900AEU, 0x900AFU, 0x900B0U, 0x900B1U, 0x900B2U,
+	0x900B3U, 0x900B4U, 0x900B5U, 0x900B6U, 0x900B7U, 0x900B8U, 0x900B9U, 0x900BAU, 0x900BBU,
+	0x900BCU, 0x900BDU, 0x900BEU, 0x900BFU, 0x900C0U, 0x900C1U, 0x900C2U, 0x900C3U, 0x900C4U,
+	0x900C5U, 0x900C6U, 0x900C7U, 0x900C8U, 0x900C9U, 0x900CAU, 0x900CBU, 0x900CCU, 0x900CDU,
+	0x900CEU, 0x900CFU, 0x900D0U, 0x900D1U, 0x900D2U, 0x900D3U, 0x900D4U, 0x900D5U, 0x900D6U,
+	0x900D7U, 0x900D8U, 0x900D9U, 0x900DAU, 0x900DBU, 0x900DCU, 0x900DDU, 0x900DEU, 0x900DFU,
+	0x900E0U, 0x900E1U, 0x900E2U, 0x900E3U, 0x900E4U, 0x900E5U, 0x900E6U, 0x900E7U, 0x900E8U,
+	0x900E9U, 0x900EAU, 0x900EBU, 0x900ECU, 0x900EDU, 0x900EEU, 0x900EFU, 0x900F0U, 0x900F1U,
+	0x900F2U, 0x900F3U, 0x900F4U, 0x900F5U, 0x900F6U, 0x900F7U, 0x900F8U, 0x900F9U, 0x900FAU,
+	0x900FBU, 0x900FCU, 0x900FDU, 0x900FEU, 0x900FFU, 0x90100U, 0x90101U, 0x90102U, 0x90103U,
+	0x90104U, 0x90105U, 0x90106U, 0x90107U, 0x90108U, 0x90109U, 0x9010AU, 0x9010BU, 0x9010CU,
+	0x9010DU, 0x9010EU, 0x9010FU, 0x90110U, 0x90111U, 0x90112U, 0x90113U, 0x90114U, 0x90115U,
+	0x90116U, 0x90117U, 0x90118U, 0x90119U, 0x9011AU, 0x9011BU, 0x9011CU, 0x9011DU, 0x9011EU,
+	0x9011FU, 0x90120U, 0x90121U, 0x90122U, 0x90123U, 0x90124U, 0x90125U, 0x90126U, 0x90127U,
+	0x90128U, 0x90129U, 0x9012AU, 0x9012BU, 0x9012CU, 0x9012DU, 0x9012EU, 0x9012FU, 0x90130U,
+	0x90131U, 0x90132U, 0x90133U, 0x90134U, 0x90135U, 0x90136U, 0x90137U, 0x90138U, 0x90139U,
+	0x9013AU, 0x9013BU, 0x9013CU, 0x9013DU, 0x9013EU, 0x9013FU, 0x90140U, 0x90141U, 0x90142U,
+	0x90143U, 0x90144U, 0x90145U, 0x90146U, 0x90147U, 0x90148U, 0x90149U, 0x9014AU, 0x9014BU,
+	0x9014CU, 0x9014DU, 0x9014EU, 0x9014FU, 0x90150U, 0x90151U, 0x90152U, 0x90153U, 0x90154U,
+	0x90155U, 0x90156U, 0x90157U, 0x90158U, 0x90159U, 0x9015AU, 0x9015BU, 0x9015CU, 0x9015DU,
+	0x9015EU, 0x9015FU, 0x90160U, 0x90161U, 0x90162U, 0x90163U, 0x90164U, 0x90165U, 0x90166U,
+	0x90167U, 0x90168U, 0x90169U, 0x9016AU, 0x9016BU, 0x9016CU, 0x9016DU, 0x9016EU, 0x9016FU,
+	0x90170U, 0x90171U, 0x90172U, 0x90173U, 0x90174U, 0x90175U, 0x90176U, 0x90177U, 0x90178U,
+	0x90179U, 0x9017AU, 0x9017BU, 0x9017CU, 0x9017DU, 0x9017EU, 0x9017FU, 0x90180U, 0x90181U,
+	0x90182U, 0x90183U, 0x90184U, 0x90006U, 0x90007U, 0x90008U, 0x90009U, 0x9000AU, 0x9000BU,
+	0xD00E7U, 0x90017U, 0x9001FU, 0x90026U, 0x400D0U, 0x400D1U, 0x400D2U, 0x400D3U, 0x400D4U,
+	0x400D5U, 0x400D6U, 0x400D7U, 0x2003AU,
+	};
+
+static const uint16_t prodcode_data[PRODCODE_SIZE] = {
+	0x0010U, 0x0400U, 0x010EU, 0x0000U, 0x0000U, 0x0008U, 0x000BU, 0x0480U, 0x0109U, 0x0008U,
+	0x0448U, 0x0139U, 0x0008U, 0x0478U, 0x0109U, 0x0000U, 0x00E8U, 0x0109U, 0x0002U, 0x0010U,
+	0x0139U, 0x000BU, 0x07C0U, 0x0139U, 0x0044U, 0x0633U, 0x0159U, 0x014FU, 0x0630U, 0x0159U,
+	0x0047U, 0x0633U, 0x0149U, 0x004FU, 0x0633U, 0x0179U, 0x0008U, 0x00E0U, 0x0109U, 0x0000U,
+	0x07C8U, 0x0109U, 0x0000U, 0x0001U, 0x0008U, 0x0030U, 0x065AU, 0x0009U, 0x0000U, 0x045AU,
+	0x0009U, 0x0000U, 0x0448U, 0x0109U, 0x0040U, 0x0633U, 0x0179U, 0x0001U, 0x0618U, 0x0109U,
+	0x40C0U, 0x0633U, 0x0149U, 0x0008U, 0x0004U, 0x0048U, 0x4040U, 0x0633U, 0x0149U, 0x0000U,
+	0x0004U, 0x0048U, 0x0040U, 0x0633U, 0x0149U, 0x0000U, 0x0658U, 0x0109U, 0x0010U, 0x0004U,
+	0x0018U, 0x0000U, 0x0004U, 0x0078U, 0x0549U, 0x0633U, 0x0159U, 0x0D49U, 0x0633U, 0x0159U,
+	0x094AU, 0x0633U, 0x0159U, 0x0441U, 0x0633U, 0x0149U, 0x0042U, 0x0633U, 0x0149U, 0x0001U,
+	0x0633U, 0x0149U, 0x0000U, 0x00E0U, 0x0109U, 0x000AU, 0x0010U, 0x0109U, 0x0009U, 0x03C0U,
+	0x0149U, 0x0009U, 0x03C0U, 0x0159U, 0x0018U, 0x0010U, 0x0109U, 0x0000U, 0x03C0U, 0x0109U,
+	0x0018U, 0x0004U, 0x0048U, 0x0018U, 0x0004U, 0x0058U, 0x000BU, 0x0010U, 0x0109U, 0x0001U,
+	0x0010U, 0x0109U, 0x0005U, 0x07C0U, 0x0109U, 0x0811U, 0x0880U, 0x0000U, 0x0000U, 0x4008U,
+	0x0083U, 0x004FU, 0x0000U, 0x4040U, 0x0083U, 0x0051U, 0x0000U, 0x0811U, 0x0880U, 0x0000U,
+	0x0000U, 0x0720U, 0x000FU, 0x1740U, 0x0000U, 0x0016U, 0x0083U, 0x004BU, 0x0000U, 0x0716U,
+	0x000FU, 0x2001U, 0x0000U, 0x0716U, 0x000FU, 0x2800U, 0x0000U, 0x0716U, 0x000FU, 0x0F00U,
+	0x0000U, 0x0720U, 0x000FU, 0x1400U, 0x0000U, 0x0E08U, 0x0C15U, 0x0000U, 0x0000U, 0x0625U,
+	0x0015U, 0x0000U, 0x0000U, 0x4028U, 0x0080U, 0x0000U, 0x0000U, 0x0E08U, 0x0C1AU, 0x0000U,
+	0x0000U, 0x0625U, 0x001AU, 0x0000U, 0x0000U, 0x4040U, 0x0080U, 0x0000U, 0x0000U, 0x2604U,
+	0x0015U, 0x0000U, 0x0000U, 0x0708U, 0x0005U, 0x0000U, 0x2002U, 0x0008U, 0x0080U, 0x0000U,
+	0x0000U, 0x2604U, 0x001AU, 0x0000U, 0x0000U, 0x0708U, 0x000AU, 0x0000U, 0x2002U, 0x4040U,
+	0x0080U, 0x0000U, 0x0000U, 0x060AU, 0x0015U, 0x1200U, 0x0000U, 0x061AU, 0x0015U, 0x1300U,
+	0x0000U, 0x060AU, 0x001AU, 0x1200U, 0x0000U, 0x0642U, 0x001AU, 0x1300U, 0x0000U, 0x4808U,
+	0x0880U, 0x0000U, 0x0000U, 0x0000U, 0x0790U, 0x011AU, 0x0008U, 0x07AAU, 0x002AU, 0x0010U,
+	0x07B2U, 0x002AU, 0x0000U, 0x07C8U, 0x0109U, 0x0010U, 0x0010U, 0x0109U, 0x0010U, 0x02A8U,
+	0x0129U, 0x0008U, 0x0370U, 0x0129U, 0x000AU, 0x03C8U, 0x01A9U, 0x000CU, 0x0408U, 0x0199U,
+	0x0014U, 0x0790U, 0x011AU, 0x0008U, 0x0004U, 0x0018U, 0x000EU, 0x0408U, 0x0199U, 0x0008U,
+	0x8568U, 0x0108U, 0x0018U, 0x0790U, 0x016AU, 0x0008U, 0x01D8U, 0x0169U, 0x0010U, 0x8558U,
+	0x0168U, 0x1FF8U, 0x85A8U, 0x01E8U, 0x0050U, 0x0798U, 0x016AU, 0x0060U, 0x07A0U, 0x016AU,
+	0x0008U, 0x8310U, 0x0168U, 0x0008U, 0xA310U, 0x0168U, 0x000AU, 0x0408U, 0x0169U, 0x006EU,
+	0x0000U, 0x0068U, 0x0000U, 0x0408U, 0x0169U, 0x0000U, 0x8310U, 0x0168U, 0x0000U, 0xA310U,
+	0x0168U, 0x1FF8U, 0x85A8U, 0x01E8U, 0x0068U, 0x0798U, 0x016AU, 0x0078U, 0x07A0U, 0x016AU,
+	0x0068U, 0x0790U, 0x016AU, 0x0008U, 0x8B10U, 0x0168U, 0x0008U, 0xAB10U, 0x0168U, 0x000AU,
+	0x0408U, 0x0169U, 0x0058U, 0x0000U, 0x0068U, 0x0000U, 0x0408U, 0x0169U, 0x0000U, 0x8B10U,
+	0x0168U, 0x0001U, 0xAB10U, 0x0168U, 0x0000U, 0x01D8U, 0x0169U, 0x0080U, 0x0790U, 0x016AU,
+	0x0018U, 0x07AAU, 0x006AU, 0x000AU, 0x0000U, 0x01E9U, 0x0008U, 0x8080U, 0x0108U, 0x000FU,
+	0x0408U, 0x0169U, 0x000CU, 0x0000U, 0x0068U, 0x0009U, 0x0000U, 0x01A9U, 0x0000U, 0x0408U,
+	0x0169U, 0x0000U, 0x8080U, 0x0108U, 0x0008U, 0x07AAU, 0x006AU, 0x0000U, 0x8568U, 0x0108U,
+	0x00B7U, 0x0790U, 0x016AU, 0x001FU, 0x0000U, 0x0068U, 0x0008U, 0x8558U, 0x0168U, 0x000FU,
+	0x0408U, 0x0169U, 0x000DU, 0x0000U, 0x0068U, 0x0000U, 0x0408U, 0x0169U, 0x0000U, 0x8558U,
+	0x0168U, 0x0008U, 0x03C8U, 0x01A9U, 0x0003U, 0x0370U, 0x0129U, 0x0020U, 0x02AAU, 0x0009U,
+	0x0008U, 0x00E8U, 0x0109U, 0x0000U, 0x8140U, 0x010CU, 0x0010U, 0x8138U, 0x0104U, 0x0008U,
+	0x0448U, 0x0109U, 0x000FU, 0x07C0U, 0x0109U, 0x0000U, 0x00E8U, 0x0109U, 0x0047U, 0x0630U,
+	0x0109U, 0x0008U, 0x0618U, 0x0109U, 0x0008U, 0x00E0U, 0x0109U, 0x0000U, 0x07C8U, 0x0109U,
+	0x0008U, 0x8140U, 0x010CU, 0x0000U, 0x0478U, 0x0109U, 0x0000U, 0x0001U, 0x0008U, 0x0008U,
+	0x0004U, 0x0000U, 0x0008U, 0x07C8U, 0x0109U, 0x0000U, 0x0400U, 0x0106U, 0x0400U, 0x0000U,
+	0x002BU, 0x0069U, 0x0000U, 0x0101U, 0x0105U, 0x0107U, 0x010FU, 0x0202U, 0x020AU, 0x020BU,
+	0x0002U,
+	};
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+/*
+ * Loads PIE instruction sequence PHY registers
+ * @returns void
+ */
+void ddrphy_phyinit_loadpieprodcode(void)
+{
+	int i;
+
+	for (i = 0; i < PRODCODE_SIZE; i++) {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * prodcode_addr[i])),
+			      prodcode_data[i]);
+	}
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c
new file mode 100644
index 0000000..f1eeb82
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * Maps impedance values to register settings
+ *
+ * Reads the pull-up/pull-down driver impedance from drvstren_ohm input
+ * and encodes that value for the CSR field specified in targetcsr input,
+ * based on DDR protocol.
+ *
+ * @param[in] drvstren_ohm drive strenght / ODT impedance in Ohms
+ *
+ * @param[in] targetcsr Target CSR for the impedance value. on of following
+ * enum drvtype:
+ *   - DRVSTRENFSDQP
+ *   - DRVSTRENFSDQN
+ *   - ODTSTRENP
+ *   - ODTSTRENN
+ *   - ADRVSTRENP
+ *   - ADRVSTRENN
+ *
+ * \return >=0 value on success, else negative.
+ */
+int ddrphy_phyinit_mapdrvstren(uint32_t drvstren_ohm, enum drvtype targetcsr)
+{
+	int stren_setting = -1;
+
+	if ((targetcsr == DRVSTRENFSDQP) || (targetcsr == DRVSTRENFSDQN)) {
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 31U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 35U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 41U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 50U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 56U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 64U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 74U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 88U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 108U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 140U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 200U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 360U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 481U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+	} else if (targetcsr == ODTSTRENP) {
+#if STM32MP_DDR3_TYPE
+		/*
+		 * DDR3 - P and N has the same impedance and non-zero.
+		 * user input is half the individual pull-up and pull-down impedances values
+		 * because of parallel between them.
+		 */
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 15U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 16U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 17U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 18U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 20U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 21U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 23U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 26U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 55U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 71U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 101U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 181U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 241U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+#elif STM32MP_DDR4_TYPE
+		/* DDR4 - P is non-zero */
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 31U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 35U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 41U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 50U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 56U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 64U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 74U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 88U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 108U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 140U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 200U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 360U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 481U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+#else /* STM32MP_LPDDR4_TYPE */
+		/* LPDDR4 - P is high-Z */
+		stren_setting = 0x00; /* High-impedance */
+#endif /* STM32MP_DDR3_TYPE */
+	} else if (targetcsr == ODTSTRENN) {
+#if STM32MP_DDR3_TYPE
+		/*
+		 * DDR3 - P and N has the same impedance and non-zero.
+		 * Times 2 of user input because of parallel pull-up and pull-down termination.
+		 */
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 15U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 16U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 17U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 18U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 20U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 21U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 23U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 26U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 55U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 71U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 101U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 181U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 241U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+#elif STM32MP_DDR4_TYPE
+		/* DDR4 - N is high-Z */
+		stren_setting = 0x00; /* High-impedance */
+#else /* STM32MP_LPDDR4_TYPE */
+		/* LPDDR4 - N is non-zero */
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 31U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 35U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 41U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 50U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 56U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 64U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 74U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 88U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 108U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 140U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 200U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 360U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 481U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+#endif /* STM32MP_DDR3_TYPE */
+	} else {
+		/* if ((targetcsr == ADRVSTRENP) || (targetcsr == ADRVSTRENN)) */
+		if (drvstren_ohm == 120U) {
+			stren_setting = 0x00;
+		} else if (drvstren_ohm == 60U) {
+			stren_setting = 0x01;
+		} else if (drvstren_ohm == 40U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm == 30U) {
+			stren_setting = 0x07;
+		} else if (drvstren_ohm == 24U) {
+			stren_setting = 0x0F;
+		} else if (drvstren_ohm == 20U) {
+			stren_setting = 0x1F;
+		} else {
+			ERROR("%s %d\n", __func__, __LINE__);
+			VERBOSE("%s userinputadvanced.atximpedance %u Ohms value is not valid.\n",
+				__func__, drvstren_ohm);
+			VERBOSE("Valid values are: 20, 24, 30, 40, 60 and 120 Ohms.\n");
+		}
+	}
+
+	return stren_setting;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_progcsrskiptrain.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_progcsrskiptrain.c
new file mode 100644
index 0000000..c9a71f4
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_progcsrskiptrain.c
@@ -0,0 +1,893 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+#include <ddrphy_wrapper.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+struct phyinit_timings {
+	int tstaoff;
+	int tpdm;
+	int tcasl_add;
+};
+
+static struct phyinit_timings timings;
+
+/*
+ * Program dfimrl according to this formula:
+ *
+ *         dfimrl = ceiling( (ARdPtrinitval*UI + phy_tx_insertion_dly +
+ *                            phy_rx_insertion_dly + PHY_Rx_Fifo_dly + tDQSCK + tstaoff) /
+ *                           dficlk_period)
+ *
+ * All terms in above equation specified in ps
+ * tDQSCK - determine from memory model
+ * tstaoff - determine from memory model
+ * phy_tx_insertion_dly = 200ps
+ * phy_rx_insertion_dly = 200ps
+ * phy_rx_fifo_dly      = 200ps + 4UI
+ */
+static void dfimrl_program(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d,
+			   int ardptrinitval)
+{
+	uint32_t byte;
+	int dfimrl_in_dficlk;
+	int phy_rx_fifo_dly;
+	int phy_rx_insertion_dly = 200;
+	int phy_tx_insertion_dly = 200;
+	long long dficlk_period_x1000;
+	long long dfimrl_in_fs;
+	long long uifs;
+	uint16_t dfimrl;
+
+	uifs = (1000 * 1000000) / ((int)config->uib.frequency * 2);
+	dficlk_period_x1000 = 4 * uifs;
+
+	phy_rx_fifo_dly = (int)(((200 * 1000) + (4 * uifs)) / 1000);
+
+	dfimrl_in_fs = (ardptrinitval * uifs) +
+		       ((phy_tx_insertion_dly + phy_rx_insertion_dly + phy_rx_fifo_dly +
+			 timings.tstaoff + timings.tcasl_add + timings.tpdm) * 1000);
+
+	dfimrl_in_dficlk = (int)(dfimrl_in_fs / dficlk_period_x1000);
+	if ((dfimrl_in_fs % dficlk_period_x1000) != 0) {
+		dfimrl_in_dficlk++;
+	}
+	dfimrl = (uint16_t)(dfimrl_in_dficlk + mb_ddr_1d->dfimrlmargin);
+
+	/*
+	 * mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | CBRD | CSR_DFIMRL_ADDR))),
+	 *               dfimrl);
+	 */
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+
+		c_addr = byte << 12;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | c_addr |
+								CSR_DFIMRL_ADDR))),
+			      dfimrl);
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTMRL_ADDR))), dfimrl);
+}
+
+/*
+ * Program txdqsdlytg0/1[9:0]:
+ *
+ *         txdqsdlytg*[9:6] = floor( (4*UI + tstaoff) / UI)
+ *         txdqsdlytg*[5:0] = ceiling( (tstaoff%UI / UI) * 32)
+ *
+ * tstaoff and UI expressed in ps
+ *
+ * For HMD and LPDDR4X and MEMCLK <= 533 mhz:
+ *    txdqsdlytg*[9:6] = 0x5
+ *
+ * For other dimm types, leave TDqsDlyTg*[9:0] at default 0x100
+ *
+ * ppp_0001_cccc_uuuu_1101_0000
+ *
+ * if DDR3 or DDR4
+ *      num_timingroup = numrank_dfi0;
+ * else
+ *      num_timingroup = numrank_dfi0 + numrank_dfi1 * dfi1exists;
+ */
+static void txdqsdlytg_program(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d,
+			       uint16_t *txdqsdly)
+{
+	uint32_t byte;
+	int txdqsdlytg_5to0; /* Fine delay - 1/32UI per increment */
+	int txdqsdlytg_9to6; /* Coarse delay - 1UI per increment */
+	int txdqsdlytg_fine_default = 0;
+	int txdqsdlytg_coarse_default = 4;
+	long long tmp_value;
+	long long uifs;
+
+	uifs = (1000 * 1000000) / ((int)config->uib.frequency * 2);
+
+	txdqsdlytg_9to6 = (int)(((int)((txdqsdlytg_coarse_default * uifs) / 1000) +
+				 timings.tstaoff + timings.tcasl_add
+				 - timings.tpdm) / (int)(uifs / 1000));
+
+	tmp_value = fmodll(((txdqsdlytg_fine_default * uifs / 32) +
+			    ((timings.tstaoff + timings.tcasl_add) * 1000) -
+			    (timings.tpdm * 1000)),
+			   uifs);
+	txdqsdlytg_5to0 = (int)(tmp_value / uifs * 32);
+	if ((tmp_value % uifs) != 0) {
+		txdqsdlytg_5to0++;
+	}
+
+	/* Bit-5 of LCDL is no longer used, so bumping bit-5 of fine_dly up to coarse_dly */
+	if (txdqsdlytg_5to0 >= 32) {
+		txdqsdlytg_9to6 = txdqsdlytg_9to6 + 1;
+		txdqsdlytg_5to0 = txdqsdlytg_5to0 - 32;
+	}
+
+	*txdqsdly = (uint16_t)((txdqsdlytg_9to6 << 6) | txdqsdlytg_5to0);
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t nibble;
+
+		c_addr = byte << 12;
+		for (nibble = 0U; nibble < 2U; nibble++) {
+			uint32_t u_addr;
+
+			if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, byte) != 0) {
+				continue;
+			}
+
+			u_addr = nibble << 8;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			if ((mb_ddr_1d->cspresent & 0x1U) != 0U) {
+#else /* STM32MP_LPDDR4_TYPE */
+			if (((mb_ddr_1d->cspresentcha & 0x1U) |
+			     (mb_ddr_1d->cspresentchb & 0x1U)) != 0U) {
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | u_addr |
+								     CSR_TXDQSDLYTG0_ADDR))),
+					      *txdqsdly);
+			}
+
+#if STM32MP_LPDDR4_TYPE
+			if ((((mb_ddr_1d->cspresentcha & 0x2U) >> 1) |
+			     ((mb_ddr_1d->cspresentchb & 0x2U) >> 1)) != 0U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | u_addr |
+								     CSR_TXDQSDLYTG1_ADDR))),
+					      *txdqsdly);
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+	}
+}
+
+/*
+ * ##############################################################
+ *
+ * Program txdqdlyTg0/1[8:0]:
+ *
+ *     txdqdlyTg*[8:6] = floor( (txdqsdlytg*[5:0]*UI/32 + tDQS2DQ + 0.5UI) / UI)
+ *     txdqdlyTg*[5:0] = ceil( ((txdqsdlytg*[5:0]*UI/32 + tDQS2DQ + 0.5UI)%UI / UI) * 32)
+ *
+ * ##############################################################
+ */
+static void txdqdlytg_program(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d,
+			      uint16_t txdqsdly)
+{
+	uint32_t byte;
+	int txdqdly_5to0; /* Fine delay - 1/32UI per increment */
+	int txdqdly_8to6; /* Coarse delay - 1UI per increment */
+	int txdqsdlytg_5to0; /* Fine delay - 1/32UI per increment */
+	long long tmp_value;
+	long long uifs;
+	uint16_t txdqdly;
+
+	uifs = (1000 * 1000000) / ((int)config->uib.frequency * 2);
+
+	txdqsdlytg_5to0 = (int)txdqsdly & 0x3F;
+
+	txdqdly_8to6 = (int)(((txdqsdlytg_5to0 * uifs / 32) + (uifs / 2)) / uifs);
+	tmp_value = fmodll(((txdqsdlytg_5to0 * uifs / 32) + (uifs / 2)), uifs);
+	txdqdly_5to0 = (int)(((tmp_value * 32) / uifs));
+	if ((tmp_value % uifs) != 0) {
+		txdqdly_5to0++;
+	}
+
+	/* Bit-5 of LCDL is no longer used, so bumping bit-5 of fine_dly up to coarse_dly */
+	if (txdqdly_5to0 >= 32) {
+		txdqdly_8to6 = txdqdly_8to6 + 1;
+		txdqdly_5to0 = txdqdly_5to0 - 32;
+	}
+
+	txdqdly = (uint16_t)((txdqdly_8to6 << 6) | txdqdly_5to0);
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane < 9U; lane++) {
+			uint32_t r_addr;
+
+			if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, byte) != 0) {
+				continue;
+			}
+
+			r_addr = lane << 8;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			if ((mb_ddr_1d->cspresent & 0x1U) != 0U) {
+#else /* STM32MP_LPDDR4_TYPE */
+			if (((mb_ddr_1d->cspresentcha & 0x1U) |
+			     (mb_ddr_1d->cspresentchb & 0x1U)) != 0U) {
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | r_addr |
+								     CSR_TXDQDLYTG0_ADDR))),
+					      txdqdly);
+			}
+
+#if STM32MP_LPDDR4_TYPE
+			if ((((mb_ddr_1d->cspresentcha & 0x2U) >> 1) |
+			     ((mb_ddr_1d->cspresentchb & 0x2U) >> 1)) != 0U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | r_addr |
+								     CSR_TXDQDLYTG1_ADDR))),
+					      txdqdly);
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+	}
+}
+
+/*
+ * Program rxendly0/1[10:0]:
+ *
+ *         rxendly[10:6] = floor( (4*UI + tDQSCK + tstaoff) / UI)
+ *         rxendly[5:0]  = ceil( ((tDQSCK + tstaoff) % UI) * 32)
+ *
+ * tDQSCK, tstaoff and UI expressed in ps
+ */
+static void rxendly_program(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	int rxendly_coarse_default = 4;
+	int rxendly_fine_default = 0;
+
+	int backoff_x1000 __maybe_unused;
+	int zerobackoff_x1000 __maybe_unused;
+	uint32_t byte;
+	int rxendly_10to6; /* Coarse delay - 1UI per increment */
+	int rxendly_5to0; /* Fine delay - 1/32UI per increment */
+	int totfinestep;
+	long long finestepfs; /* Fine steps in fs */
+	long long rxendly_offset_x1000000 = 0; /* 0 Offset is 1UI before the first DQS. */
+	long long totfs;
+	long long uifs;
+	uint16_t rxendly;
+
+	uifs = (1000 * 1000000) / ((int)config->uib.frequency * 2);
+
+#if STM32MP_LPDDR4_TYPE
+	/* Compensate for pptenrxenbackoff */
+	zerobackoff_x1000 = (1000 * 24) / 32;
+	if (config->uia.lp4rxpreamblemode == 1U) {
+		backoff_x1000 = 1000 - ((1000 * 2) / 32);
+	} else {
+		backoff_x1000 = (1000 * (int)config->uia.rxenbackoff) - ((1000 * 2) / 32);
+	}
+
+	if (config->uia.disableretraining == 0U) {
+		rxendly_offset_x1000000 = config->uib.frequency < 333U ?
+					  backoff_x1000 * uifs : zerobackoff_x1000 * uifs;
+	} else {
+		rxendly_offset_x1000000 = zerobackoff_x1000 * uifs;
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	finestepfs = uifs / 32;
+	totfs = ((32 * rxendly_coarse_default * finestepfs) +
+		 (rxendly_fine_default * finestepfs) +
+		 ((timings.tstaoff + timings.tcasl_add +
+		   timings.tpdm) * 1000) + (rxendly_offset_x1000000 / 1000));
+	totfinestep = totfs / finestepfs;
+
+	rxendly_10to6 = totfinestep / 32;
+	rxendly_5to0  = fmodi(totfinestep, 32);
+
+	/* Bit-5 of LCDL is no longer used, so bumping bit-5 of fine_dly up to coarse_dly */
+	if (rxendly_5to0 >= 32) {
+		rxendly_10to6 = rxendly_10to6 + 1;
+		rxendly_5to0 = rxendly_5to0 - 32;
+	}
+
+	rxendly = (uint16_t)((rxendly_10to6 << 6) | rxendly_5to0);
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t nibble;
+
+		c_addr = byte << 12;
+		for (nibble = 0U; nibble < 2U; nibble++) {
+			uint32_t u_addr;
+
+			if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, byte) != 0) {
+				continue;
+			}
+
+			u_addr = nibble << 8;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			if ((mb_ddr_1d->cspresent & 0x1U) != 0) {
+#else /* STM32MP_LPDDR4_TYPE */
+			if (((mb_ddr_1d->cspresentcha & 0x1U) |
+			     (mb_ddr_1d->cspresentchb & 0x1U)) != 0U) {
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | u_addr |
+								     CSR_RXENDLYTG0_ADDR))),
+					      rxendly);
+			}
+
+#if STM32MP_LPDDR4_TYPE
+			if ((((mb_ddr_1d->cspresentcha & 0x2U) >> 1) |
+			     ((mb_ddr_1d->cspresentchb & 0x2U) >> 1)) != 0U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | u_addr |
+								     CSR_RXENDLYTG1_ADDR))),
+					      rxendly);
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+	}
+}
+
+#if STM32MP_LPDDR4_TYPE
+/*
+ * Programming Seq0BGPR1/2/3 for LPDDR4
+ */
+static void seq0bgpr_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t extradly = 3U;
+	uint32_t rl = 0U; /* Computed read latency */
+	uint32_t wl = 0U; /* Computed write latency */
+	uint16_t mr_dbi_rd; /* Extracted field from MR */
+	uint16_t mr_rl;
+	uint16_t mr_wl;
+	uint16_t mr_wls;
+	uint16_t regdata;
+
+	mr_rl = (uint16_t)config->uia.lp4rl;	/* RL[2:0] */
+	mr_wl = (uint16_t)config->uia.lp4wl;	/* WL[5:3] */
+	mr_wls = (uint16_t)config->uia.lp4wls;	/* WLS */
+	mr_dbi_rd = (uint16_t)config->uia.lp4dbird; /* DBI-RD */
+
+	switch ((mr_dbi_rd << 3) | mr_rl) {
+		/* DBI-RD Disabled */
+	case  0U:
+		rl = 6U;
+		break;
+	case  1U:
+		rl = 10U;
+		break;
+	case  2U:
+		rl = 14U;
+		break;
+	case  3U:
+		rl = 20U;
+		break;
+	case  4U:
+		rl = 24U;
+		break;
+	case  5U:
+		rl = 28U;
+		break;
+	case  6U:
+		rl = 32U;
+		break;
+	case  7U:
+		rl = 36U;
+		break;
+		/* DBI-RD Enabled */
+	case  8U:
+		rl = 6U;
+		break;
+	case  9U:
+		rl = 12U;
+		break;
+	case 10U:
+		rl = 16U;
+		break;
+	case 11U:
+		rl = 22U;
+		break;
+	case 12U:
+		rl = 28U;
+		break;
+	case 13U:
+		rl = 32U;
+		break;
+	case 14U:
+		rl = 36U;
+		break;
+	case 15U:
+		rl = 40U;
+		break;
+	default:
+		rl = 6U;
+		break;
+	}
+
+	switch ((mr_wls << 3) | mr_wl) {
+		/* DBI-RD Disabled */
+	case  0U:
+		wl = 4U;
+		break;
+	case  1U:
+		wl = 6U;
+		break;
+	case  2U:
+		wl = 8U;
+		break;
+	case  3U:
+		wl = 10U;
+		break;
+	case  4U:
+		wl = 12U;
+		break;
+	case  5U:
+		wl = 14U;
+		break;
+	case  6U:
+		wl = 16U;
+		break;
+	case  7U:
+		wl = 18U;
+		break;
+		/* DBI-RD Enabled */
+	case  8U:
+		wl = 4U;
+		break;
+	case  9U:
+		wl = 8U;
+		break;
+	case 10U:
+		wl = 12U;
+		break;
+	case 11U:
+		wl = 18U;
+		break;
+	case 12U:
+		wl = 22U;
+		break;
+	case 13U:
+		wl = 26U;
+		break;
+	case 14U:
+		wl = 30U;
+		break;
+	case 15U:
+		wl = 34U;
+		break;
+	default:
+		wl = 4U;
+		break;
+	}
+
+	/* Program Seq0b_GPRx */
+	regdata = (uint16_t)((rl - 5U + extradly) << CSR_ACSMRCASLAT_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (P0 | C0 | TINITENG | R2 |
+							CSR_SEQ0BGPR1_ADDR))),
+		      regdata);
+
+	regdata = (uint16_t)((wl - 5U + extradly) << CSR_ACSMWCASLAT_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (P0 | C0 | TINITENG | R2 |
+							CSR_SEQ0BGPR2_ADDR))),
+		      regdata);
+
+	regdata = (uint16_t)((rl - 5U + extradly + 4U + 8U) << CSR_ACSMRCASLAT_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (P0 | C0 | TINITENG | R2 |
+							CSR_SEQ0BGPR3_ADDR))),
+		      regdata);
+}
+
+/*
+ * Program hwtlpcsena and hwtlpcsenb based on number of ranks per channel
+ * Applicable only for LPDDR4.  These CSRs have no effect for DDR3/4.
+ *
+ * CSRs to program:
+ *      hwtlpcsena
+ *      hwtlpcsenb
+ *
+ * User input dependencies:
+ *      config->uib.numrank_dfi0
+ *      config->uib.numrank_dfi1
+ *      config->uib.dfi1exists
+ *      config->uib.numactivedbytedfi1
+ */
+static void hwtlpcsen_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t hwtlpcsena;
+	uint16_t hwtlpcsenb;
+
+	/* Channel A - 1'b01 if signal-rank, 2'b11 if dual-rank */
+	hwtlpcsena = (uint16_t)config->uib.numrank_dfi0 | 0x1U;
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTLPCSENA_ADDR))),
+		      hwtlpcsena);
+
+	/*
+	 * Channel B - 1'b01 if signal-rank, 2'b11 if dual-rank
+	 * If DFI1 exists but disabled, numrank_dfi0 is used to program CsEnB
+	 */
+	if ((config->uib.dfi1exists != 0U) && (config->uib.numactivedbytedfi1 == 0U)) {
+		hwtlpcsenb = (uint16_t)config->uib.numrank_dfi0 | 0x1U;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTLPCSENB_ADDR))),
+			      hwtlpcsenb);
+	} else if ((config->uib.dfi1exists != 0U) && (config->uib.numactivedbytedfi1 > 0U)) {
+		hwtlpcsenb = (uint16_t)config->uib.numrank_dfi1 | 0x1U;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTLPCSENB_ADDR))),
+			      hwtlpcsenb);
+	} else {
+		/* Disable Channel B */
+		hwtlpcsenb = 0x0U;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTLPCSENB_ADDR))),
+			      hwtlpcsenb);
+	}
+}
+
+/*
+ * Program pptdqscntinvtrntg0 and pptdqscntinvtrntg1
+ * Calculated based on tDQS2DQ and Frequencey
+ * Applicable to LPDDR4 only
+ *
+ * 65536*(tdqs2dq_value_rank<rank>_chan<chan>*2)/(2*2048*UI(ps)_int)
+ *
+ * CSRs to program:
+ *      pptdqscntinvtrntg0
+ *      pptdqscntinvtrntg1
+ *
+ * User input dependencies:
+ *      config->uib.numrank_dfi0
+ *      config->uib.numrank_dfi1
+ *      config->uib.dfi1exists
+ *      config->uib.numdbyte
+ */
+static void pptdqscntinvtrntg_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t numrank_total = config->uib.numrank_dfi0;
+	uint32_t rank;
+
+	/* Calculate total number of timing groups (ranks) */
+	if (config->uib.dfi1exists != 0U) {
+		numrank_total += config->uib.numrank_dfi1;
+	}
+
+	/* Set per timing group */
+	for (rank = 0U; rank < numrank_total; rank++) {
+		uint32_t byte;
+
+		for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+			uint32_t c_addr;
+
+			c_addr = byte << 12;
+			if (rank == 0U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr |
+							       CSR_PPTDQSCNTINVTRNTG0_ADDR))),
+					      0U);
+			} else if (rank == 1U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr |
+							       CSR_PPTDQSCNTINVTRNTG1_ADDR))),
+					      0U);
+			}
+		}
+	}
+}
+
+/*
+ * CSRs to program:
+ *      PptCtlStatic:: DOCByteSelTg0/1
+ *                   :: pptenrxenbackoff
+ *
+ * User input dependencies::
+ *      config->uib.numdbyte
+ *      config->uib.numrank_dfi0
+ *      config->uib.numrank_dfi1
+ *      config->uia.lp4rxpreamblemode
+ *      config->uia.rxenbackoff
+ *      config->uia.drambyteswap
+ */
+static void pptctlstatic_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte;
+	uint32_t pptenrxenbackoff;
+
+	/*
+	 * The customer will setup some fields in this csr so the fw needs to do a
+	 * read-modify-write here.
+	 */
+
+	if (config->uia.lp4rxpreamblemode == 1U) {
+		/* Rx-preamble mode for PS0 */
+		/* Programming PptCtlStatic detected toggling preamble */
+		pptenrxenbackoff = 0x1U; /* Toggling RD_PRE */
+	} else {
+		pptenrxenbackoff = config->uia.rxenbackoff; /* Static RD_PRE */
+	}
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint16_t regdata;
+		uint8_t pptentg1;
+		uint32_t docbytetg0;
+		uint32_t docbytetg1;
+
+		/* Each Dbyte could have a different configuration */
+		c_addr = byte * C1;
+		if ((byte % 2) == 0) {
+			docbytetg0 = 0x1U & (config->uia.drambyteswap >> byte);
+			docbytetg1 = 0x1U & (config->uia.drambyteswap >> byte);
+		} else {
+			docbytetg0 = 0x1U & (~(config->uia.drambyteswap >> byte));
+			docbytetg1 = 0x1U & (~(config->uia.drambyteswap >> byte));
+		}
+
+		pptentg1 = ((config->uib.numrank_dfi0 == 2U) || (config->uib.numrank_dfi1 == 2U)) ?
+			   0x1U : 0x0U;
+		regdata = (uint16_t)((0x1U << CSR_PPTENDQS2DQTG0_LSB) |
+				     (pptentg1 << CSR_PPTENDQS2DQTG1_LSB) |
+				     (0x1U << CSR_PPTENRXENDLYTG0_LSB) |
+				     (pptentg1 << CSR_PPTENRXENDLYTG1_LSB) |
+				     (pptenrxenbackoff << CSR_PPTENRXENBACKOFF_LSB) |
+				     (docbytetg0 << CSR_DOCBYTESELTG0_LSB) |
+				     (docbytetg1 << CSR_DOCBYTESELTG1_LSB));
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_PPTCTLSTATIC_ADDR))),
+			      regdata);
+	}
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+/*
+ * Program hwtcamode based on dram type
+ *
+ * CSRs to program:
+ *      hwtcamode::hwtlp3camode
+ *               ::hwtd4camode
+ *               ::hwtlp4camode
+ *               ::hwtd4altcamode
+ *               ::hwtcsinvert
+ *               ::hwtdbiinvert
+ */
+static void hwtcamode_program(void)
+{
+	uint32_t hwtlp3camode = 0U;
+	uint32_t hwtd4camode = 0U;
+	uint32_t hwtlp4camode = 0U;
+	uint32_t hwtd4altcamode = 0U;
+	uint32_t hwtcsinvert = 0U;
+	uint32_t hwtdbiinvert = 0U;
+	uint16_t hwtcamode;
+
+#if STM32MP_DDR4_TYPE
+	hwtd4camode = 1U;
+#elif STM32MP_LPDDR4_TYPE
+	hwtlp4camode = 1U;
+	hwtcsinvert = 1U;
+	hwtdbiinvert = 1U;
+#else /* STM32MP_DDR3_TYPE */
+	/* Nothing to declare */
+#endif /* STM32MP_DDR4_TYPE */
+
+	hwtcamode = (uint16_t)((hwtdbiinvert << CSR_HWTDBIINVERT_LSB) |
+			       (hwtcsinvert << CSR_HWTCSINVERT_LSB) |
+			       (hwtd4altcamode << CSR_HWTD4ALTCAMODE_LSB) |
+			       (hwtlp4camode << CSR_HWTLP4CAMODE_LSB) |
+			       (hwtd4camode << CSR_HWTD4CAMODE_LSB) |
+			       (hwtlp3camode << CSR_HWTLP3CAMODE_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTCAMODE_ADDR))), hwtcamode);
+}
+
+/*
+ * Program DllGainCtl and DllLockParam based on frequency
+ */
+static void dllgainctl_dlllockparam_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t dllgainiv;
+	uint32_t dllgaintv;
+	uint32_t lcdlseed;
+	uint32_t memck_freq;
+	uint32_t stepsize_x10 = 47U;	/*
+					 * Nominal stepsize, in units of tenths of a ps,
+					 * if nominal=4.7ps use 47
+					 */
+	uint16_t wddllgainctl;
+	uint16_t wddlllockparam;
+
+	memck_freq = config->uib.frequency;
+
+	/*
+	 * lcdlseed = ((1000000/memck_freq)/2)/lcdl_stepsize  ...
+	 * where default lcdl_stepsize=4.7 in simulation.
+	 */
+	if (memck_freq >= 1200U) {
+		dllgainiv = 0x04U;
+		dllgaintv = 0x05U;
+	} else if (memck_freq >= 800U) {
+		dllgainiv = 0x03U;
+		dllgaintv = 0x05U;
+	} else if (memck_freq >= 532U) {
+		dllgainiv = 0x02U;
+		dllgaintv = 0x04U;
+	} else if (memck_freq >= 332U) {
+		dllgainiv = 0x01U;
+		dllgaintv = 0x03U;
+	} else {
+		dllgainiv = 0x00U;
+		dllgaintv = 0x02U;
+	}
+
+	/*
+	 * lcdlseed= (1000000/(2*memck_freq)) * (100/(120*(stepsize_nominal)));
+	 * *100/105 is to bias the seed low.
+	 */
+	lcdlseed = (1000000U * 10U * 100U) / (2U * memck_freq * stepsize_x10 * 105U);
+
+	if (lcdlseed > (511U - 32U)) {
+		lcdlseed = 511U - 32U;
+	}
+
+	if (lcdlseed < 32U) {
+		lcdlseed = 32U;
+	}
+
+	wddllgainctl = (uint16_t)((CSR_DLLGAINTV_MASK & (dllgaintv << CSR_DLLGAINTV_LSB)) |
+				  (CSR_DLLGAINIV_MASK & (dllgainiv << CSR_DLLGAINIV_LSB)));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DLLGAINCTL_ADDR))),
+		      wddllgainctl);
+
+	wddlllockparam = (uint16_t)((CSR_LCDLSEED0_MASK & (lcdlseed << CSR_LCDLSEED0_LSB)) |
+				    (CSR_DISDLLGAINIVSEED_MASK & 0xFFFFU));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DLLLOCKPARAM_ADDR))),
+		      wddlllockparam);
+}
+
+/*
+ * Program AcsmCtrl23 for Fw and Ppt.
+ *
+ * CSRs to program:
+ *   AcsmCtrl23::AcsmCsMask
+ *               AcsmCsMode
+ */
+static void acsmctrl23_program(void)
+{
+	uint16_t regdata;
+
+	regdata = (0x0FU << CSR_ACSMCSMASK_LSB) | (0x1U << CSR_ACSMCSMODE_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TACSM | CSR_ACSMCTRL23_ADDR))),
+		      regdata);
+}
+
+/*
+ * Set PllForceCal to 1 and PllDacValIn to some arbitrary value
+ */
+static void pllforcecal_plldacvalin_program(void)
+{
+	uint32_t dacval_in = 0x10U;
+	uint32_t force_cal = 0x1U;
+	uint32_t pllencal = 0x1U;
+	uint32_t maxrange = 0x1FU;
+	uint16_t pllctrl3_gpr;
+	uint16_t pllctrl3_startup;
+
+	pllctrl3_startup = (uint16_t)((dacval_in << CSR_PLLDACVALIN_LSB) |
+				      (maxrange << CSR_PLLMAXRANGE_LSB));
+	pllctrl3_gpr = pllctrl3_startup | (uint16_t)((force_cal << CSR_PLLFORCECAL_LSB) |
+						     (pllencal << CSR_PLLENCAL_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_PLLCTRL3_ADDR))),
+		      pllctrl3_startup);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BGPR6_ADDR))),
+		      pllctrl3_gpr);
+}
+
+/*
+ * This function programs registers that are normally set by training
+ * firmware.
+ *
+ * This function is used in place of running 1D or 1D training steps. PhyInit
+ * calls this function when skip_train = true. In that case, PhyInit does not
+ * execute training firmware and this function is called instead to program
+ * PHY registers according to DRAM timing parameters specified in userInput
+ * data structure. See documentation of ddrphy_phyinit_struct.h file
+ * details of timing parameters available in skip training.
+ *
+ * \warning ddrphy_phyinit_progcsrskiptrain() only supports zero board
+ * delay model. If system board delays are set or randomized, full 1D or 1D
+ * initialization flow must be executed.
+ *
+ * This function replaces these steps in the PHY Initialization sequence:
+ *  - (E) Set the PHY input clocks to the desired frequency
+ *  - (F) Write the Message Block parameters for the training firmware
+ *  - (G) Execute the Training Firmware
+ *  - (H) Read the Message Block results
+ *
+ * \returns \c void
+ */
+void ddrphy_phyinit_progcsrskiptrain(struct stm32mp_ddr_config *config,
+				     struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t ardptrinitval)
+{
+	uint16_t txdqsdly;
+
+	/*
+	 * Program ATxDlY
+	 * For DDR4, DDR3 and LPDDR4, leave AtxDly[6:0] at default (0x0)
+	 */
+
+	dfimrl_program(config, mb_ddr_1d, ardptrinitval);
+
+	txdqsdlytg_program(config, mb_ddr_1d, &txdqsdly);
+
+	txdqdlytg_program(config, mb_ddr_1d, txdqsdly);
+
+	rxendly_program(config, mb_ddr_1d);
+
+#if STM32MP_LPDDR4_TYPE
+	seq0bgpr_program(config);
+
+	hwtlpcsen_program(config);
+
+	pptdqscntinvtrntg_program(config);
+
+	pptctlstatic_program(config);
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	hwtcamode_program();
+
+	dllgainctl_dlllockparam_program(config);
+
+	acsmctrl23_program();
+
+	pllforcecal_plldacvalin_program();
+
+	/*
+	 * ##############################################################
+	 *
+	 * Setting PhyInLP3 to 0 to cause PIE to execute LP2 sequence instead of INIT on first
+	 * dfi_init_start.
+	 * This prevents any DRAM commands before DRAM is initialized, which is the case for
+	 * skip_train.
+	 *
+	 * Moved to here from dddrphy_phyinit_I_loadPIEImage()
+	 * These should not be needed on S3-exit
+	 *
+	 * Note this executes for SkipTrain only, *not* DevInit+SkipTrain
+	 * DevInit+SkipTrain already initializes DRAM and thus don't need to avoid DRAM commands
+	 *
+	 * ##############################################################
+	 */
+
+	/*
+	 * Special skipTraining configuration to Prevent DRAM Commands on the first dfi
+	 * status interface handshake. In order to see this behavior, the first dfi_freq
+	 * should be in the range of 0x0f < dfi_freq_sel[4:0] < 0x14.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_PHYINLP3_ADDR))), 0x0U);
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_reginterface.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_reginterface.c
new file mode 100644
index 0000000..21400f7
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_reginterface.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * This file provides a group of functions that are used to track PHY register
+ * writes by intercepting io_write16 function calls.  Once the registers are
+ * tracked, their value can be saved at a given time spot, and restored later
+ * as required. This implementation is useful to capture any PHY register
+ * programing in any function during PHY initialization.
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * MAX_NUM_RET_REGS default Max number of retention registers.
+ *
+ * This define is only used by the PhyInit Register interface to define the max
+ * amount of registered that can be saved. The user may increase this variable
+ * as desired if a larger number of registers need to be restored.
+ */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+#define MAX_NUM_RET_REGS	129
+#else /* STM32MP_LPDDR4_TYPE */
+#define MAX_NUM_RET_REGS	283
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+/*
+ * Array of Address/value pairs used to store register values for the purpose
+ * of retention restore.
+ */
+#define RETREG_AREA	(MAX_NUM_RET_REGS + 1) * sizeof(struct reg_addr_val)
+#define RETREG_BASE	RETRAM_BASE + RETRAM_SIZE - RETREG_AREA
+
+static int *retregsize = (int *)(RETREG_BASE);
+static struct reg_addr_val *retreglist = (struct reg_addr_val *)(RETREG_BASE + sizeof(int));
+
+static int numregsaved; /* Current Number of registers saved. */
+static int tracken = 1; /* Enabled tracking of registers */
+
+/*
+ * Tags a register if tracking is enabled in the register
+ * interface.
+ *
+ * During PhyInit registers writes, keeps track of address
+ * for the purpose of restoring the PHY register state during PHY
+ * retention exit process. Tracking can be turned on/off via the
+ * ddrphy_phyinit_reginterface STARTTRACK, STOPTRACK instructions. By
+ * default tracking is always turned on.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_trackreg(uint32_t adr)
+{
+	int regindx = 0;
+
+	/* Return if tracking is disabled */
+	if (tracken == 0) {
+		return 0;
+	}
+
+	/* Search register address within the array */
+	for (regindx = 0; regindx < numregsaved; regindx++) {
+		if (retreglist[regindx].address == adr) {
+			/* Register found */
+			return 0;
+		}
+	}
+
+	/* Register not found, so add it */
+	if (numregsaved > MAX_NUM_RET_REGS) {
+		ERROR("numregsaved > MAX_NUM_RET_REGS\n");
+		VERBOSE("[ddrphy_phyinit_reginterface:%s]\n", __func__);
+		VERBOSE("Max Number of Restore Registers reached: %d.\n", numregsaved);
+		VERBOSE("Please recompile PhyInit with larger MAX_NUM_RET_REG value.\n");
+		return -1;
+	}
+
+	retreglist[regindx].address = adr;
+	numregsaved++;
+
+	return 0;
+}
+
+/*
+ * Register interface function used to track, save and restore retention registers.
+ *
+ * ### Usage
+ * Register tracking is enabled by calling:
+ *
+ *  \code
+ *  ddrphy_phyinit_reginterface(STARTTRACK,0,0);
+ *  \endcode
+ *
+ * from this point on any call to mmio_write_16() in
+ * return will be capture by the register interface via a call to
+ * ddrphy_phyinit_trackreg(). Tracking is disabled by calling:
+ *
+ *  \code
+ *  ddrphy_phyinit_reginterface(STOPTRACK,0,0);
+ *  \endcode
+ *
+ * On calling this function, register write via mmio_write_16 are no longer tracked until a
+ * STARTTRACK call is made. Once all the register write are complete, SAVEREGS
+ * command can be issue to save register values into the internal data array of
+ * the register interface. Upon retention exit RESTOREREGS are command can be
+ * used to issue register write commands to the PHY based on values stored in
+ * the array.
+ *  \code
+ *   ddrphy_phyinit_reginterface(SAVEREGS,0,0);
+ *   ddrphy_phyinit_reginterface(RESTOREREGS,0,0);
+ *  \endcode
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_reginterface(enum reginstr myreginstr, uint32_t adr, uint16_t dat)
+{
+	if (myreginstr == SAVEREGS) {
+		int regindx;
+
+		/*
+		 * Go through all the tracked registers, issue a register read and place
+		 * the result in the data structure for future recovery.
+		 */
+		for (regindx = 0; regindx < numregsaved; regindx++) {
+			uint16_t data;
+
+			data = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+							(4U * retreglist[regindx].address)));
+			retreglist[regindx].value = data;
+		}
+
+		*retregsize = numregsaved;
+
+		return 0;
+	} else if (myreginstr == RESTOREREGS) {
+		int regindx;
+
+		/*
+		 * Write PHY registers based on Address, Data value pairs stores in
+		 * retreglist.
+		 */
+		for (regindx = 0; regindx < *retregsize; regindx++) {
+			mmio_write_16((uintptr_t)
+				      (DDRPHYC_BASE + (4U * retreglist[regindx].address)),
+				      retreglist[regindx].value);
+		}
+
+		return 0;
+	} else if (myreginstr == STARTTRACK) {
+		/* Enable tracking */
+		tracken = 1;
+		return 0;
+	} else if (myreginstr == STOPTRACK) {
+		/* Disable tracking */
+		tracken = 0;
+		return 0;
+	} else {
+		return -1;
+	}
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_restore_sequence.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_restore_sequence.c
new file mode 100644
index 0000000..cddb955
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_restore_sequence.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * This function implements the register restore portion of S3/IO
+ * retention sequence.
+ *
+ * \note This function requiers the runtime_config.reten=1 to enable PhyInit exit retention feature.
+ * This variable can be set as in
+ * \return 0 on completion of the sequence, EXIT_FAILURE on error.
+ */
+int ddrphy_phyinit_restore_sequence(void)
+{
+	int ret;
+
+	/*
+	 * Before you call this functions perform the following:
+	 * --------------------------------------------------------------------------
+	 * -# Bring up VDD, VDDQ should already be up
+	 * -# Since the CKE* and MEMRESET pin state must be protected, special care
+	 *    must be taken to ensure that the following signals
+	 *    - atpg_mode = 1'b0
+	 *    - PwrOkIn = 1'b0
+	 *
+	 * -# The {BypassModeEn*, WRSTN} signals may be defined at VDD power-on, but
+	 *    must be driven to ZERO at least 10ns prior to the asserting edge of PwrOkIn.
+	 *
+	 * -# Start Clocks and Reset the PHY
+	 *    This step is identical to ddrphy_phyinit_usercustom_b_startclockresetphy()
+	 */
+
+	/* Write the MicroContMuxSel CSR to 0x0 to allow access to the internal CSRs */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+
+	/*
+	 * Write the UcclkHclkEnables CSR to 0x3 to enable all the clocks so the reads can
+	 * complete.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x3U);
+
+	/*
+	 * Assert CalZap to force impedance calibration FSM to idle.
+	 * De-asserted as part of dfi_init_start/complete handshake by the PIE when DfiClk is valid.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALZAP_ADDR))), 0x1U);
+
+	/* Issue register writes to restore registers values */
+	ret = ddrphy_phyinit_reginterface(RESTOREREGS, 0U, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/*
+	 * Write the UcclkHclkEnables CSR to disable the appropriate clocks after all reads done.
+	 * Disabling Ucclk (PMU) and Hclk (training hardware).
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x0U);
+
+	/* Write the MicroContMuxSel CSR to 0x1 to isolate the internal CSRs during mission mode */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_sequence.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_sequence.c
new file mode 100644
index 0000000..adc4377
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_sequence.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * This function implements the flow of PhyInit software to initialize the PHY.
+ *
+ * The execution sequence follows the overview figure provided in the Reference Manual.
+ *
+ * \returns 0 on completion of the sequence, EXIT_FAILURE on error.
+ */
+int ddrphy_phyinit_sequence(struct stm32mp_ddr_config *config, bool skip_training, bool reten)
+{
+	int ret;
+	uint32_t ardptrinitval;	/*
+				 * Represents the value stored in Step C into the register with the
+				 * same name. Defined as a global variable so that implementation
+				 * of ddrphy_phyinit_progcsrskiptrain() function does not require
+				 * a PHY read register implementation.
+				 */
+	struct pmu_smb_ddr_1d mb_ddr_1d; /* Firmware 1D Message Block structure */
+
+	/* Check user input pstate number consistency vs. SW capabilities */
+	if (config->uib.numpstates > 1U) {
+		return -1;
+	}
+
+	/* Initialize structures */
+	ddrphy_phyinit_initstruct(config, &mb_ddr_1d);
+
+	/* Re-calculate Firmware Message Block input based on final user input */
+	ret = ddrphy_phyinit_calcmb(config, &mb_ddr_1d);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* (A) Bring up VDD, VDDQ, and VAA */
+	/* ddrphy_phyinit_usercustom_a_bringuppower(); */
+
+	/* (B) Start Clocks and Reset the PHY */
+	/* ddrphy_phyinit_usercustom_b_startclockresetphy(); */
+
+	/* (C) Initialize PHY Configuration */
+	ret = ddrphy_phyinit_c_initphyconfig(config, &mb_ddr_1d, &ardptrinitval);
+	if (ret != 0) {
+		return ret;
+	}
+	/*
+	 * Customize any register write desired; This can include any CSR not covered by PhyInit
+	 * or user wish to override values calculated in step_C.
+	 */
+	ddrphy_phyinit_usercustom_custompretrain(config);
+
+	/* Stop retention register tracking for training firmware related registers */
+	ret = ddrphy_phyinit_reginterface(STOPTRACK, 0U, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (skip_training) {
+		/* Skip running training firmware entirely */
+		ddrphy_phyinit_progcsrskiptrain(config, &mb_ddr_1d, ardptrinitval);
+	} else {
+		/* (D) Load the IMEM Memory for 1D training */
+		ddrphy_phyinit_d_loadimem();
+
+		/* (E) Set the PHY input clocks to the desired frequency */
+		/* ddrphy_phyinit_usercustom_e_setdficlk(pstate); */
+
+		/* (F) Write the Message Block parameters for the training firmware */
+		ret = ddrphy_phyinit_f_loaddmem(config, &mb_ddr_1d);
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* (G) Execute the Training Firmware */
+		ret = ddrphy_phyinit_g_execfw();
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* (H) Read the Message Block results */
+		/* ddrphy_phyinit_h_readmsgblock(); */
+	}
+
+	/* Start retention register tracking for training firmware related registers */
+	ret = ddrphy_phyinit_reginterface(STARTTRACK, 0U, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* (I) Load PHY Init Engine Image */
+	ddrphy_phyinit_i_loadpieimage(config, skip_training);
+
+	/*
+	 * Customize any CSR write desired to override values programmed by firmware or
+	 * ddrphy_phyinit_i_loadpieimage()
+	 */
+	/* ddrphy_phyinit_usercustom_customposttrain(); */
+
+	if (reten) {
+		/* Save value of tracked registers for retention restore sequence. */
+		ret = ddrphy_phyinit_usercustom_saveretregs(config);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	/* (J) Initialize the PHY to Mission Mode through DFI Initialization */
+	/* ddrphy_phyinit_usercustom_j_entermissionmode(); */
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_softsetmb.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_softsetmb.c
new file mode 100644
index 0000000..86b084d
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_softsetmb.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * Set messageBlock variable only if not set by user
+ *
+ * This function is used by ddrphy_phyinit_calcmb() to set calculated
+ * messageBlock variables only when the user has not directly programmed them.
+ *
+ * @param[in]   field   A string representing the messageBlock field to be programed.
+ * @param[in]   value   filed value
+ *
+ * @return 0 on success.
+ * On error  returns the following values based on error:
+ * - -1 : message block field specified by the input \c field string is not
+ * found in the message block data structure.
+ */
+int ddrphy_phyinit_softsetmb(struct pmu_smb_ddr_1d *mb_ddr_1d, enum message_block_field field,
+			     uint32_t value)
+{
+	int ret = 0;
+
+	if (field == MB_FIELD_DRAMFREQ) {
+		assert(value <= UINT16_MAX);
+	} else {
+		assert(value <= UINT8_MAX);
+	}
+
+	switch (field) {
+	case MB_FIELD_PSTATE:
+		mb_ddr_1d->pstate = (uint8_t)value;
+		break;
+	case MB_FIELD_PLLBYPASSEN:
+		mb_ddr_1d->pllbypassen = (uint8_t)value;
+		break;
+	case MB_FIELD_DRAMFREQ:
+		mb_ddr_1d->dramfreq = (uint16_t)value;
+		break;
+	case MB_FIELD_DFIFREQRATIO:
+		mb_ddr_1d->dfifreqratio = (uint8_t)value;
+		break;
+	case MB_FIELD_BPZNRESVAL:
+		mb_ddr_1d->bpznresval = (uint8_t)value;
+		break;
+	case MB_FIELD_PHYODTIMPEDANCE:
+		mb_ddr_1d->phyodtimpedance = (uint8_t)value;
+		break;
+	case MB_FIELD_PHYDRVIMPEDANCE:
+		mb_ddr_1d->phydrvimpedance = (uint8_t)value;
+		break;
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	case MB_FIELD_DRAMTYPE:
+		mb_ddr_1d->dramtype = (uint8_t)value;
+		break;
+	case MB_FIELD_DISABLEDDBYTE:
+		mb_ddr_1d->disableddbyte = (uint8_t)value;
+		break;
+	case MB_FIELD_ENABLEDDQS:
+		mb_ddr_1d->enableddqs = (uint8_t)value;
+		break;
+	case MB_FIELD_PHYCFG:
+		mb_ddr_1d->phycfg = (uint8_t)value;
+		break;
+#if STM32MP_DDR4_TYPE
+	case MB_FIELD_X16PRESENT:
+		mb_ddr_1d->x16present = (uint8_t)value;
+		break;
+#endif /* STM32MP_DDR4_TYPE */
+#else /* STM32MP_LPDDR4_TYPE */
+	case MB_FIELD_ENABLEDDQSCHA:
+		mb_ddr_1d->enableddqscha = (uint8_t)value;
+		break;
+	case MB_FIELD_CSPRESENTCHA:
+		mb_ddr_1d->cspresentcha = (uint8_t)value;
+		break;
+	case MB_FIELD_ENABLEDDQSCHB:
+		mb_ddr_1d->enableddqschb = (uint8_t)value;
+		break;
+	case MB_FIELD_CSPRESENTCHB:
+		mb_ddr_1d->cspresentchb = (uint8_t)value;
+		break;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+	default:
+		ERROR("unknown message block field %u\n", field);
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_writeoutmem.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_writeoutmem.c
new file mode 100644
index 0000000..868800e
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_writeoutmem.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * Writes local memory content into the SRAM via APB interface.
+ *
+ * This function issued APB writes commands to SRAM address based on values
+ * stored in a local PhyInit array that contains consolidated IMEM and DMEM
+ * data.
+ * @param[in] mem[] Local memory array.
+ * @param[in] mem_offset offset index. if provided, skips to the offset index
+ * from the local array and issues APB commands from mem_offset to mem_size.
+ * @param[in] mem_size size of the memroy (in mem array index)
+ * @returns void
+ */
+void ddrphy_phyinit_writeoutmem(uint32_t *mem, uint32_t mem_offset, uint32_t mem_size)
+{
+	uint32_t index;
+
+	/*
+	 * 1. Enable access to the internal CSRs by setting the MicroContMuxSel CSR to 0.
+	 *    This allows the memory controller unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+
+	for (index = 0U; index < mem_size / sizeof(uint32_t); index++) {
+		uint32_t data = mem[index];
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * ((index * 2) + mem_offset))),
+			      data & 0xFFFFU);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * ((index * 2) + 1 + mem_offset))),
+			      (data >> 16) & 0xFFFFU);
+	}
+
+	/*
+	 * 2. Isolate the APB access from the internal CSRs by setting the MicroContMuxSel CSR to 1.
+	 *    This allows the firmware unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+}
+
+/* Similar function for message block */
+void ddrphy_phyinit_writeoutmsgblk(uint16_t *mem, uint32_t mem_offset, uint32_t mem_size)
+{
+	uint32_t index;
+
+	/*
+	 * 1. Enable access to the internal CSRs by setting the MicroContMuxSel CSR to 0.
+	 *    This allows the memory controller unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+
+	for (index = 0U; index < mem_size / sizeof(uint16_t); index++) {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (index + mem_offset))), mem[index]);
+	}
+
+	/*
+	 * 2. Isolate the APB access from the internal CSRs by setting the MicroContMuxSel CSR to 1.
+	 *    This allows the firmware unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+}
diff --git a/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_custompretrain.c b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_custompretrain.c
new file mode 100644
index 0000000..6a20013
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_custompretrain.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/* DDRDBG registers */
+#define DDRDBG_DDR34_AC_SWIZZLE_ADD3_0		U(0x100)
+
+/*
+ * This function is called before training firmware is executed. Any
+ * register override in this function might affect the firmware training
+ * results.
+ *
+ * This function is executed before firmware execution loop. Thus this function
+ * should be used only for the following:
+ *
+ *  - Override PHY register values written by
+ *  ddrphy_phyinit_c_initphyconfig. An example use case is when this
+ *  function does not perform the exact programing desired by the user.
+ *  - Write custom PHY registers that need to take effect before training
+ *  firmware execution.
+ *
+ * User shall use mmio_write_16 to write PHY registers in order for the register
+ * to be tracked by PhyInit for retention restore.
+ *
+ * To override settings in the message block, users can assign values to the
+ * fields in the message block data structure directly.
+ *
+ * \ref examples/simple/ddrphy_phyinit_usercustom_custompretrain.c example of this function.
+ *
+ * @return Void
+ */
+void ddrphy_phyinit_usercustom_custompretrain(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte __unused;
+	uint32_t i = 0U;
+	uint32_t j;
+	uintptr_t base;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	base = (uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTSWIZZLEHWTADDRESS0_ADDR)));
+
+	for (i = 0U; i < NB_HWT_SWIZZLE; i++) {
+		mmio_write_16(base + (i * sizeof(uint32_t)),
+			      (uint16_t)config->uis.swizzle[i]);
+	}
+
+	base = (uintptr_t)(stm32_ddrdbg_get_base() + DDRDBG_DDR34_AC_SWIZZLE_ADD3_0);
+
+	for (j = 0U; j < NB_AC_SWIZZLE; j++, i++) {
+		mmio_write_32(base + (j * sizeof(uint32_t)), config->uis.swizzle[i]);
+	}
+#else /* STM32MP_LPDDR4_TYPE */
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		base = (uintptr_t)(DDRPHYC_BASE + (4U *
+						   ((byte << 12) | TDBYTE | CSR_DQ0LNSEL_ADDR)));
+
+		for (j = 0U; j < NB_DQLNSEL_SWIZZLE_PER_BYTE; j++, i++) {
+			mmio_write_16(base + (j * sizeof(uint32_t)),
+				      (uint16_t)config->uis.swizzle[i]);
+		}
+	}
+
+	base = (uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MAPCAA0TODFI_ADDR)));
+
+	for (j = 0U; j < NB_MAPCAATODFI_SWIZZLE; j++, i++) {
+		mmio_write_16(base + (j * sizeof(uint32_t)),
+			      (uint16_t)config->uis.swizzle[i]);
+	}
+
+	base = (uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MAPCAB0TODFI_ADDR)));
+
+	for (j = 0U; j < NB_MAPCABTODFI_SWIZZLE; j++, i++) {
+		mmio_write_16(base + (j * sizeof(uint32_t)),
+			      (uint16_t)config->uis.swizzle[i]);
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+}
diff --git a/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_g_waitfwdone.c b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_g_waitfwdone.c
new file mode 100644
index 0000000..3d00d3d
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_g_waitfwdone.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <drivers/delay_timer.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/* Firmware major messages */
+#define FW_MAJ_MSG_TRAINING_SUCCESS	0x0000007U
+#define FW_MAJ_MSG_START_STREAMING	0x0000008U
+#define FW_MAJ_MSG_TRAINING_FAILED	0x00000FFU
+
+#define PHYINIT_DELAY_1US		1U
+#define PHYINIT_DELAY_10US		10U
+#define PHYINIT_TIMEOUT_US_1S		1000000U
+
+static int wait_uctwriteprotshadow(bool state)
+{
+	uint64_t timeout;
+	uint16_t read_data;
+	uint16_t value = state ? BIT(0) : 0U;
+
+	timeout = timeout_init_us(PHYINIT_TIMEOUT_US_1S);
+
+	do {
+		read_data = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+						     (4U * (TAPBONLY | CSR_UCTSHADOWREGS_ADDR))));
+		udelay(PHYINIT_DELAY_1US);
+		if (timeout_elapsed(timeout)) {
+			return -1;
+		}
+	} while ((read_data & BIT(0)) != value);
+
+	return 0;
+}
+
+static int ack_message_receipt(void)
+{
+	int ret;
+
+	/* Acknowledge the receipt of the message */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_DCTWRITEPROT_ADDR))), 0U);
+
+	udelay(PHYINIT_DELAY_1US);
+
+	ret = wait_uctwriteprotshadow(true);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Complete the 4-phase protocol */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_DCTWRITEPROT_ADDR))), 1U);
+
+	udelay(PHYINIT_DELAY_1US);
+
+	return 0;
+}
+
+static int get_major_message(uint32_t *msg)
+{
+	uint16_t message_number;
+	int ret;
+
+	ret = wait_uctwriteprotshadow(false);
+	if (ret != 0) {
+		return ret;
+	}
+
+	message_number = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+							    (4U * (TAPBONLY |
+								   CSR_UCTWRITEONLYSHADOW_ADDR))));
+
+	ret = ack_message_receipt();
+	if (ret != 0) {
+		return ret;
+	}
+
+	*msg = (uint32_t)message_number;
+
+	return 0;
+}
+
+static int get_streaming_message(uint32_t *msg)
+{
+	uint16_t stream_word_lower_part;
+	uint16_t stream_word_upper_part;
+	int ret;
+
+	ret = wait_uctwriteprotshadow(false);
+	if (ret != 0) {
+		return ret;
+	}
+
+	stream_word_lower_part = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+							  (4U * (TAPBONLY |
+								 CSR_UCTWRITEONLYSHADOW_ADDR))));
+
+	stream_word_upper_part = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+							  (4U * (TAPBONLY |
+								 CSR_UCTDATWRITEONLYSHADOW_ADDR))));
+
+	ret = ack_message_receipt();
+	if (ret != 0) {
+		return ret;
+	}
+
+	*msg = (uint32_t)stream_word_lower_part | ((uint32_t)stream_word_upper_part << 16);
+
+	return 0;
+}
+
+/*
+ * Implements the mechanism to wait for completion of training firmware execution.
+ *
+ * The purpose of user this function is to wait for firmware to finish training.
+ * The user can either implement a counter to wait or implement the polling
+ * mechanism (our choice here). The wait time is highly dependent on the training features
+ * enabled via sequencectrl input to the message block.
+ *
+ * The default behavior of this function is to print comments relating to this
+ * process. A function call of the same name will be printed in the output text
+ * file.
+ *
+ * The user can choose to leave this function as is, or implement mechanism to
+ * trigger mailbox poling event in simulation.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_usercustom_g_waitfwdone(void)
+{
+	uint32_t fw_major_message;
+	int ret;
+
+	do {
+		ret = get_major_message(&fw_major_message);
+		if (ret != 0) {
+			return ret;
+		}
+
+		VERBOSE("fw_major_message = %x\n", (unsigned int)fw_major_message);
+
+		if (fw_major_message == FW_MAJ_MSG_START_STREAMING) {
+			uint32_t i;
+			uint32_t read_data;
+			uint32_t stream_len;
+
+			ret = get_streaming_message(&read_data);
+			if (ret != 0) {
+				return ret;
+			}
+
+			stream_len = read_data & 0xFFFFU;
+
+			for (i = 0U; i < stream_len; i++) {
+				ret = get_streaming_message(&read_data);
+				if (ret != 0) {
+					return ret;
+				}
+
+				VERBOSE("streaming message = %x\n", (unsigned int)read_data);
+			}
+		}
+	} while ((fw_major_message != FW_MAJ_MSG_TRAINING_SUCCESS) &&
+		 (fw_major_message != FW_MAJ_MSG_TRAINING_FAILED));
+
+	udelay(PHYINIT_DELAY_10US);
+
+	if (fw_major_message == FW_MAJ_MSG_TRAINING_FAILED) {
+		ERROR("%s Training has failed.\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_saveretregs.c b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_saveretregs.c
new file mode 100644
index 0000000..b573de3
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_saveretregs.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * This function can be used to implement saving of PHY registers to be
+ * restored on retention exit.
+ *
+ * The requirement of this function is to issue register reads and store the
+ * value to be recovered on retention exit. The following is an example
+ * implementation and the user may implement alternate methods that suit their
+ * specific SoC system needs.
+ *
+ * In this implementation PhyInit saves register values in an internal C array.
+ * During retention exit it restores register values from the array. The exact
+ * list of registers to save and later restore can be seen in the output txt
+ * file with an associated calls to mmio_read_16().
+ *
+ * PhyInit provides a register interface and a tracking mechanism to minimize
+ * the number registers needing restore. Refer to source code for
+ * ddrphy_phyinit_reginterface() for detailed implementation of tracking
+ * mechanism. Tracking is disabled from step D to Step H as these involve
+ * loading, executing and checking the state of training firmware execution
+ * which are not required to implement the retention exit sequence. The registers
+ * specified representing training results are also saved in addition to registers
+ * written by PhyInit during PHY initialization.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_usercustom_saveretregs(struct stm32mp_ddr_config *config)
+{
+	uint32_t anib;
+	uint32_t byte;
+	uint32_t nibble;
+	uint32_t lane;
+	uint32_t c_addr;
+	uint32_t u_addr;
+	uint32_t b_addr;
+	uint32_t r_addr;
+	int ret;
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * 1. Enable tracking of training firmware result registers
+	 *
+	 *    \note  The tagged registers in this step are in
+	 *    addition to what is automatically tagged during Steps C to I.
+	 *
+	 * --------------------------------------------------------------------------
+	 */
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_PLLCTRL3_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Non-PState Dbyte Registers */
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		c_addr = byte << 12;
+
+		for (lane = 0U; lane <= R_MAX; lane++) {
+			r_addr = lane << 8;
+
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | r_addr |
+						      CSR_RXPBDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | r_addr |
+						      CSR_RXPBDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+
+#if STM32MP_LPDDR4_TYPE
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_PPTCTLSTATIC_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_TRAININGINCDECDTSMEN_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_TSMBYTE0_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ0LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ1LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ2LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ3LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ4LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ5LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ6LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ7LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+#endif /* STM32MP_LPDDR4_TYPE */
+	}
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_VREFINGLOBAL_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Anib Registers */
+	for (anib = 0U; anib < config->uib.numanib; anib++) {
+		c_addr = anib << 12;
+
+		ret = ddrphy_phyinit_trackreg(TANIB | c_addr | CSR_ATXDLY_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	/* Dbyte Registers */
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		c_addr = byte << 12;
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DFIMRL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		for (nibble = 0U; nibble <= B_MAX; nibble++) {
+			b_addr = nibble << 8;
+
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | b_addr |
+						      CSR_DQDQSRCVCNTRL_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+		}
+
+		for (nibble = 0U; nibble < 2U; nibble++) {
+			u_addr = nibble << 8;
+
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_RXENDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_RXENDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_TXDQSDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_TXDQSDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_RXCLKDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_RXCLKDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+
+		for (lane = R_MIN; lane <= R_MAX; lane++) {
+			r_addr = lane << 8;
+
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | r_addr |
+						      CSR_TXDQDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | r_addr |
+						      CSR_TXDQDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+
+#if STM32MP_LPDDR4_TYPE
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_PPTDQSCNTINVTRNTG0_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_PPTDQSCNTINVTRNTG1_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+#endif /* STM32MP_LPDDR4_TYPE */
+	}
+
+	/* PIE Registers */
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR1_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR2_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR3_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR4_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR5_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR6_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR7_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR8_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Master Registers */
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_DLLGAINCTL_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_DLLLOCKPARAM_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+#if STM32MP_LPDDR4_TYPE
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_HWTMRL_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* INITENG Registers */
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BDISABLEFLAG6_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_HWTCAMODE_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+#if STM32MP_LPDDR4_TYPE
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_HWTLPCSENA_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_HWTLPCSENB_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* ACSM registers */
+	ret = ddrphy_phyinit_trackreg(TACSM | CSR_ACSMCTRL13_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TACSM | CSR_ACSMCTRL23_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * 2. Track any additional registers
+	 *    Register writes made using the any of the PhyInit functions are
+	 *    automatically tracked using the call to ddrphy_phyinit_trackreg() in
+	 *    mmio_write_16(). Use this section to track additional registers.
+	 * --------------------------------------------------------------------------
+	 */
+
+	/*
+	 * Example:
+	 * ddrphy_phyinit_trackreg(<addr>);
+	 */
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * 3. Prepare for register reads
+	 *    - Write the MicroContMuxSel CSR to 0x0 to allow access to the internal CSRs
+	 *    - Write the UcclkHclkEnables CSR to 0x3 to enable all the clocks so the reads
+	 *      can complete.
+	 * --------------------------------------------------------------------------
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x3U);
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * / 4. Read and save all the registers
+	 * /    - The list of registers differ depending on protocol and 1D training.
+	 * --------------------------------------------------------------------------
+	 */
+
+	ret = ddrphy_phyinit_reginterface(SAVEREGS, 0U, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * 5. Prepare for mission mode
+	 *  - Write the UcclkHclkEnables CSR to disable the appropriate clocks after all reads done.
+	 *  - Write the MicroContMuxSel CSR to 0x1 to isolate the internal CSRs during mission mode.
+	 * --------------------------------------------------------------------------
+	 */
+
+	/* Disabling Ucclk (PMU) and Hclk (training hardware) */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x0U);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c
index 27d8b2c..415d9e4 100644
--- a/drivers/st/ddr/stm32mp1_ddr.c
+++ b/drivers/st/ddr/stm32mp1_ddr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -24,14 +24,12 @@
 
 #define DDRCTL_REG(x, y)					\
 	{							\
-		.name = #x,					\
 		.offset = offsetof(struct stm32mp_ddrctl, x),	\
 		.par_offset = offsetof(struct y, x)		\
 	}
 
 #define DDRPHY_REG(x, y)					\
 	{							\
-		.name = #x,					\
 		.offset = offsetof(struct stm32mp_ddrphy, x),	\
 		.par_offset = offsetof(struct y, x)		\
 	}
@@ -215,7 +213,7 @@
 {
 	uint32_t pgsr;
 	int error = 0;
-	uint64_t timeout = timeout_init_us(TIMEOUT_US_1S);
+	uint64_t timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
 
 	do {
 		pgsr = mmio_read_32((uintptr_t)&phy->pgsr);
@@ -266,7 +264,7 @@
 		mmio_read_32((uintptr_t)&phy->pir));
 
 	/* Need to wait 10 configuration clock before start polling */
-	udelay(10);
+	udelay(DDR_DELAY_10US);
 
 	/* Wait DRAM initialization and Gate Training Evaluation complete */
 	stm32mp1_ddrphy_idone_wait(phy);
@@ -279,7 +277,7 @@
 	uint32_t stat;
 	int break_loop = 0;
 
-	timeout = timeout_init_us(TIMEOUT_US_1S);
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
 	for ( ; ; ) {
 		uint32_t operating_mode;
 		uint32_t selref_type;
@@ -508,8 +506,7 @@
 #endif
 
 	/* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
-	mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl,
-			DDRCTRL_PWRCTL_SELFREF_SW);
+	stm32mp_ddr_sw_selfref_exit(priv->ctl);
 	stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
 
 	/*
@@ -524,10 +521,7 @@
 	 */
 
 	/* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */
-	mmio_clrbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
-	VERBOSE("[0x%lx] dbg1 = 0x%x\n",
-		(uintptr_t)&priv->ctl->dbg1,
-		mmio_read_32((uintptr_t)&priv->ctl->dbg1));
+	stm32mp_ddr_enable_host_interface(priv->ctl);
 }
 
 static void stm32mp1_refresh_disable(struct stm32mp_ddrctl *ctl)
@@ -614,7 +608,7 @@
 	mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
 
 	/* 1.4. wait 128 cycles to permit initialization of end logic */
-	udelay(2);
+	udelay(DDR_DELAY_2US);
 	/* For PCLK = 133MHz => 1 us is enough, 2 to allow lower frequency */
 
 	/* 1.5. initialize registers ddr_umctl2 */
diff --git a/drivers/st/ddr/stm32mp2_ddr.c b/drivers/st/ddr/stm32mp2_ddr.c
new file mode 100644
index 0000000..5193d11
--- /dev/null
+++ b/drivers/st/ddr/stm32mp2_ddr.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp2_ddr_regs.h>
+#include <drivers/st/stm32mp_ddr.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#define DDRDBG_FRAC_PLL_LOCK	U(0x10)
+
+#define DDRCTL_REG(x, y, z)					\
+	{							\
+		.offset = offsetof(struct stm32mp_ddrctl, x),	\
+		.par_offset = offsetof(struct y, x),		\
+		.qd = z						\
+	}
+
+/*
+ * PARAMETERS: value get from device tree :
+ *             size / order need to be aligned with binding
+ *             modification NOT ALLOWED !!!
+ */
+#define DDRCTL_REG_REG_SIZE	48	/* st,ctl-reg */
+#define DDRCTL_REG_TIMING_SIZE	20	/* st,ctl-timing */
+#define DDRCTL_REG_MAP_SIZE	12	/* st,ctl-map */
+#if STM32MP_DDR_DUAL_AXI_PORT
+#define DDRCTL_REG_PERF_SIZE	21	/* st,ctl-perf */
+#else /* !STM32MP_DDR_DUAL_AXI_PORT */
+#define DDRCTL_REG_PERF_SIZE	14	/* st,ctl-perf */
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
+
+#define DDRPHY_REG_REG_SIZE	0	/* st,phy-reg */
+#define	DDRPHY_REG_TIMING_SIZE	0	/* st,phy-timing */
+
+#define DDRCTL_REG_REG(x, z)	DDRCTL_REG(x, stm32mp2_ddrctrl_reg, z)
+static const struct stm32mp_ddr_reg_desc ddr_reg[DDRCTL_REG_REG_SIZE] = {
+	DDRCTL_REG_REG(mstr, true),
+	DDRCTL_REG_REG(mrctrl0, false),
+	DDRCTL_REG_REG(mrctrl1, false),
+	DDRCTL_REG_REG(mrctrl2, false),
+	DDRCTL_REG_REG(derateen, true),
+	DDRCTL_REG_REG(derateint, false),
+	DDRCTL_REG_REG(deratectl, false),
+	DDRCTL_REG_REG(pwrctl, false),
+	DDRCTL_REG_REG(pwrtmg, true),
+	DDRCTL_REG_REG(hwlpctl, true),
+	DDRCTL_REG_REG(rfshctl0, false),
+	DDRCTL_REG_REG(rfshctl1, false),
+	DDRCTL_REG_REG(rfshctl3, true),
+	DDRCTL_REG_REG(crcparctl0, false),
+	DDRCTL_REG_REG(crcparctl1, false),
+	DDRCTL_REG_REG(init0, true),
+	DDRCTL_REG_REG(init1, false),
+	DDRCTL_REG_REG(init2, false),
+	DDRCTL_REG_REG(init3, true),
+	DDRCTL_REG_REG(init4, true),
+	DDRCTL_REG_REG(init5, false),
+	DDRCTL_REG_REG(init6, true),
+	DDRCTL_REG_REG(init7, true),
+	DDRCTL_REG_REG(dimmctl, false),
+	DDRCTL_REG_REG(rankctl, true),
+	DDRCTL_REG_REG(rankctl1, true),
+	DDRCTL_REG_REG(zqctl0, true),
+	DDRCTL_REG_REG(zqctl1, false),
+	DDRCTL_REG_REG(zqctl2, false),
+	DDRCTL_REG_REG(dfitmg0, true),
+	DDRCTL_REG_REG(dfitmg1, true),
+	DDRCTL_REG_REG(dfilpcfg0, false),
+	DDRCTL_REG_REG(dfilpcfg1, false),
+	DDRCTL_REG_REG(dfiupd0, true),
+	DDRCTL_REG_REG(dfiupd1, false),
+	DDRCTL_REG_REG(dfiupd2, false),
+	DDRCTL_REG_REG(dfimisc, true),
+	DDRCTL_REG_REG(dfitmg2, true),
+	DDRCTL_REG_REG(dfitmg3, false),
+	DDRCTL_REG_REG(dbictl, true),
+	DDRCTL_REG_REG(dfiphymstr, false),
+	DDRCTL_REG_REG(dbg0, false),
+	DDRCTL_REG_REG(dbg1, false),
+	DDRCTL_REG_REG(dbgcmd, false),
+	DDRCTL_REG_REG(swctl, false), /* forced qd value */
+	DDRCTL_REG_REG(swctlstatic, false),
+	DDRCTL_REG_REG(poisoncfg, false),
+	DDRCTL_REG_REG(pccfg, false),
+};
+
+#define DDRCTL_REG_TIMING(x, z)	DDRCTL_REG(x, stm32mp2_ddrctrl_timing, z)
+static const struct stm32mp_ddr_reg_desc ddr_timing[DDRCTL_REG_TIMING_SIZE] = {
+	DDRCTL_REG_TIMING(rfshtmg, false),
+	DDRCTL_REG_TIMING(rfshtmg1, false),
+	DDRCTL_REG_TIMING(dramtmg0, true),
+	DDRCTL_REG_TIMING(dramtmg1, true),
+	DDRCTL_REG_TIMING(dramtmg2, true),
+	DDRCTL_REG_TIMING(dramtmg3, true),
+	DDRCTL_REG_TIMING(dramtmg4, true),
+	DDRCTL_REG_TIMING(dramtmg5, true),
+	DDRCTL_REG_TIMING(dramtmg6, true),
+	DDRCTL_REG_TIMING(dramtmg7, true),
+	DDRCTL_REG_TIMING(dramtmg8, true),
+	DDRCTL_REG_TIMING(dramtmg9, true),
+	DDRCTL_REG_TIMING(dramtmg10, true),
+	DDRCTL_REG_TIMING(dramtmg11, true),
+	DDRCTL_REG_TIMING(dramtmg12, true),
+	DDRCTL_REG_TIMING(dramtmg13, true),
+	DDRCTL_REG_TIMING(dramtmg14, true),
+	DDRCTL_REG_TIMING(dramtmg15, true),
+	DDRCTL_REG_TIMING(odtcfg, true),
+	DDRCTL_REG_TIMING(odtmap, false),
+};
+
+#define DDRCTL_REG_MAP(x)	DDRCTL_REG(x, stm32mp2_ddrctrl_map, false)
+static const struct stm32mp_ddr_reg_desc ddr_map[DDRCTL_REG_MAP_SIZE] = {
+	DDRCTL_REG_MAP(addrmap0),
+	DDRCTL_REG_MAP(addrmap1),
+	DDRCTL_REG_MAP(addrmap2),
+	DDRCTL_REG_MAP(addrmap3),
+	DDRCTL_REG_MAP(addrmap4),
+	DDRCTL_REG_MAP(addrmap5),
+	DDRCTL_REG_MAP(addrmap6),
+	DDRCTL_REG_MAP(addrmap7),
+	DDRCTL_REG_MAP(addrmap8),
+	DDRCTL_REG_MAP(addrmap9),
+	DDRCTL_REG_MAP(addrmap10),
+	DDRCTL_REG_MAP(addrmap11),
+};
+
+#define DDRCTL_REG_PERF(x, z)	DDRCTL_REG(x, stm32mp2_ddrctrl_perf, z)
+static const struct stm32mp_ddr_reg_desc ddr_perf[DDRCTL_REG_PERF_SIZE] = {
+	DDRCTL_REG_PERF(sched, true),
+	DDRCTL_REG_PERF(sched1, false),
+	DDRCTL_REG_PERF(perfhpr1, true),
+	DDRCTL_REG_PERF(perflpr1, true),
+	DDRCTL_REG_PERF(perfwr1, true),
+	DDRCTL_REG_PERF(sched3, false),
+	DDRCTL_REG_PERF(sched4, false),
+	DDRCTL_REG_PERF(pcfgr_0, false),
+	DDRCTL_REG_PERF(pcfgw_0, false),
+	DDRCTL_REG_PERF(pctrl_0, false),
+	DDRCTL_REG_PERF(pcfgqos0_0, true),
+	DDRCTL_REG_PERF(pcfgqos1_0, true),
+	DDRCTL_REG_PERF(pcfgwqos0_0, true),
+	DDRCTL_REG_PERF(pcfgwqos1_0, true),
+#if STM32MP_DDR_DUAL_AXI_PORT
+	DDRCTL_REG_PERF(pcfgr_1, false),
+	DDRCTL_REG_PERF(pcfgw_1, false),
+	DDRCTL_REG_PERF(pctrl_1, false),
+	DDRCTL_REG_PERF(pcfgqos0_1, true),
+	DDRCTL_REG_PERF(pcfgqos1_1, true),
+	DDRCTL_REG_PERF(pcfgwqos0_1, true),
+	DDRCTL_REG_PERF(pcfgwqos1_1, true),
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
+};
+
+static const struct stm32mp_ddr_reg_desc ddrphy_reg[DDRPHY_REG_REG_SIZE] = {};
+
+static const struct stm32mp_ddr_reg_desc ddrphy_timing[DDRPHY_REG_TIMING_SIZE] = {};
+
+/*
+ * REGISTERS ARRAY: used to parse device tree and interactive mode
+ */
+static const struct stm32mp_ddr_reg_info ddr_registers[REG_TYPE_NB] __unused = {
+	[REG_REG] = {
+		.name = "static",
+		.desc = ddr_reg,
+		.size = DDRCTL_REG_REG_SIZE,
+		.base = DDR_BASE
+	},
+	[REG_TIMING] = {
+		.name = "timing",
+		.desc = ddr_timing,
+		.size = DDRCTL_REG_TIMING_SIZE,
+		.base = DDR_BASE
+	},
+	[REG_PERF] = {
+		.name = "perf",
+		.desc = ddr_perf,
+		.size = DDRCTL_REG_PERF_SIZE,
+		.base = DDR_BASE
+	},
+	[REG_MAP] = {
+		.name = "map",
+		.desc = ddr_map,
+		.size = DDRCTL_REG_MAP_SIZE,
+		.base = DDR_BASE
+	},
+	[REGPHY_REG] = {
+		.name = "static",
+		.desc = ddrphy_reg,
+		.size = DDRPHY_REG_REG_SIZE,
+		.base = DDRPHY_BASE
+	},
+	[REGPHY_TIMING] = {
+		.name = "timing",
+		.desc = ddrphy_timing,
+		.size = DDRPHY_REG_TIMING_SIZE,
+		.base = DDRPHY_BASE
+	},
+};
+
+static void ddr_reset(struct stm32mp_ddr_priv *priv)
+{
+	udelay(DDR_DELAY_1US);
+
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_write_32(priv->rcc + RCC_DDRPHYCAPBCFGR,
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBEN | RCC_DDRPHYCAPBCFGR_DDRPHYCAPBLPEN |
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBRST);
+	mmio_write_32(priv->rcc + RCC_DDRCAPBCFGR,
+		      RCC_DDRCAPBCFGR_DDRCAPBEN | RCC_DDRCAPBCFGR_DDRCAPBLPEN |
+		      RCC_DDRCAPBCFGR_DDRCAPBRST);
+	mmio_write_32(priv->rcc + RCC_DDRCFGR,
+		      RCC_DDRCFGR_DDRCFGEN | RCC_DDRCFGR_DDRCFGLPEN | RCC_DDRCFGR_DDRCFGRST);
+
+	udelay(DDR_DELAY_1US);
+
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_write_32(priv->rcc + RCC_DDRPHYCAPBCFGR,
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBEN | RCC_DDRPHYCAPBCFGR_DDRPHYCAPBLPEN);
+	mmio_write_32(priv->rcc + RCC_DDRCAPBCFGR,
+		      RCC_DDRCAPBCFGR_DDRCAPBEN | RCC_DDRCAPBCFGR_DDRCAPBLPEN);
+	mmio_write_32(priv->rcc + RCC_DDRCFGR, RCC_DDRCFGR_DDRCFGEN | RCC_DDRCFGR_DDRCFGLPEN);
+
+	udelay(DDR_DELAY_1US);
+}
+
+static void ddr_standby_reset(struct stm32mp_ddr_priv *priv)
+{
+	udelay(DDR_DELAY_1US);
+
+	mmio_write_32(priv->rcc + RCC_DDRCPCFGR,
+		      RCC_DDRCPCFGR_DDRCPEN | RCC_DDRCPCFGR_DDRCPLPEN | RCC_DDRCPCFGR_DDRCPRST);
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_write_32(priv->rcc + RCC_DDRPHYCAPBCFGR,
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBEN | RCC_DDRPHYCAPBCFGR_DDRPHYCAPBLPEN |
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBRST);
+	mmio_write_32(priv->rcc + RCC_DDRCAPBCFGR,
+		      RCC_DDRCAPBCFGR_DDRCAPBEN | RCC_DDRCAPBCFGR_DDRCAPBLPEN |
+		      RCC_DDRCAPBCFGR_DDRCAPBRST);
+
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRPHYDLP);
+	mmio_setbits_32(priv->rcc + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+
+	udelay(DDR_DELAY_1US);
+}
+
+static void ddr_standby_reset_release(struct stm32mp_ddr_priv *priv)
+{
+	udelay(DDR_DELAY_1US);
+
+	mmio_write_32(priv->rcc + RCC_DDRCPCFGR, RCC_DDRCPCFGR_DDRCPEN | RCC_DDRCPCFGR_DDRCPLPEN);
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_clrbits_32(priv->rcc + RCC_DDRPHYCAPBCFGR, RCC_DDRPHYCAPBCFGR_DDRPHYCAPBRST);
+	mmio_write_32(priv->rcc + RCC_DDRCFGR, RCC_DDRCFGR_DDRCFGEN | RCC_DDRCFGR_DDRCFGLPEN);
+
+	udelay(DDR_DELAY_1US);
+}
+
+static void ddr_sysconf_configuration(struct stm32mp_ddr_priv *priv,
+				      struct stm32mp_ddr_config *config)
+{
+	mmio_write_32(stm32_ddrdbg_get_base() + DDRDBG_LP_DISABLE,
+		      DDRDBG_LP_DISABLE_LPI_XPI_DISABLE | DDRDBG_LP_DISABLE_LPI_DDRC_DISABLE);
+
+	mmio_write_32(stm32_ddrdbg_get_base() + DDRDBG_BYPASS_PCLKEN,
+		      (uint32_t)config->uib.pllbypass);
+
+	mmio_write_32(priv->rcc + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+
+	udelay(DDR_DELAY_1US);
+}
+
+static void set_dfi_init_complete_en(struct stm32mp_ddrctl *ctl, bool phy_init_done)
+{
+	/*
+	 * Manage quasi-dynamic registers modification
+	 * dfimisc.dfi_init_complete_en : Group 3
+	 */
+	stm32mp_ddr_set_qd3_update_conditions(ctl);
+
+	udelay(DDR_DELAY_1US);
+
+	if (phy_init_done) {
+		/* Indicates to controller that PHY has completed initialization */
+		mmio_setbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	} else {
+		/* PHY not initialized yet, wait for completion */
+		mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	}
+
+	udelay(DDR_DELAY_1US);
+
+	stm32mp_ddr_unset_qd3_update_conditions(ctl);
+
+}
+
+static void disable_refresh(struct stm32mp_ddrctl *ctl)
+{
+	mmio_setbits_32((uintptr_t)&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
+
+	stm32mp_ddr_wait_refresh_update_done_ack(ctl);
+
+	udelay(DDR_DELAY_1US);
+
+	mmio_clrbits_32((uintptr_t)&ctl->pwrctl,
+			DDRCTRL_PWRCTL_POWERDOWN_EN | DDRCTRL_PWRCTL_SELFREF_EN);
+
+	udelay(DDR_DELAY_1US);
+
+	set_dfi_init_complete_en(ctl, false);
+}
+
+static void restore_refresh(struct stm32mp_ddrctl *ctl, uint32_t rfshctl3, uint32_t pwrctl)
+{
+	if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) {
+		mmio_clrbits_32((uintptr_t)&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
+
+		stm32mp_ddr_wait_refresh_update_done_ack(ctl);
+
+		udelay(DDR_DELAY_1US);
+	}
+
+	if ((pwrctl & DDRCTRL_PWRCTL_SELFREF_SW) != 0U) {
+		mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_SW);
+
+		udelay(DDR_DELAY_1US);
+	}
+
+	if ((pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) != 0U) {
+		mmio_setbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+
+		udelay(DDR_DELAY_1US);
+	}
+
+	if ((pwrctl & DDRCTRL_PWRCTL_SELFREF_EN) != 0U) {
+		mmio_setbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_EN);
+
+		udelay(DDR_DELAY_1US);
+	}
+
+	set_dfi_init_complete_en(ctl, true);
+}
+
+void stm32mp2_ddr_init(struct stm32mp_ddr_priv *priv,
+		       struct stm32mp_ddr_config *config)
+{
+	int ret = -EINVAL;
+	uint32_t ddr_retdis;
+	enum ddr_type ddr_type;
+
+	if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
+		ddr_type = STM32MP_DDR3;
+	} else if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR4) != 0U) {
+		ddr_type = STM32MP_DDR4;
+	} else if ((config->c_reg.mstr & DDRCTRL_MSTR_LPDDR4) != 0U) {
+		ddr_type = STM32MP_LPDDR4;
+	} else {
+		ERROR("DDR type not supported\n");
+		panic();
+	}
+
+	VERBOSE("name = %s\n", config->info.name);
+	VERBOSE("speed = %u kHz\n", config->info.speed);
+	VERBOSE("size  = 0x%zx\n", config->info.size);
+	if (config->self_refresh) {
+		VERBOSE("sel-refresh exit (zdata = 0x%x)\n", config->zdata);
+	}
+
+	/* Check DDR PHY pads retention */
+	ddr_retdis = mmio_read_32(priv->pwr + PWR_CR11) & PWR_CR11_DDRRETDIS;
+	if (config->self_refresh) {
+		if (ddr_retdis == PWR_CR11_DDRRETDIS) {
+			VERBOSE("self-refresh aborted: no retention\n");
+			config->self_refresh = false;
+		}
+	}
+
+	if (config->self_refresh) {
+		ddr_standby_reset(priv);
+
+		VERBOSE("disable DDR PHY retention\n");
+		mmio_setbits_32(priv->pwr + PWR_CR11, PWR_CR11_DDRRETDIS);
+
+		udelay(DDR_DELAY_1US);
+
+		mmio_clrbits_32(priv->rcc + RCC_DDRCAPBCFGR, RCC_DDRCAPBCFGR_DDRCAPBRST);
+
+		udelay(DDR_DELAY_1US);
+
+	} else {
+		if (stm32mp_board_ddr_power_init(ddr_type) != 0) {
+			ERROR("DDR power init failed\n");
+			panic();
+		}
+
+		VERBOSE("disable DDR PHY retention\n");
+		mmio_setbits_32(priv->pwr + PWR_CR11, PWR_CR11_DDRRETDIS);
+
+		ddr_reset(priv);
+
+		ddr_sysconf_configuration(priv, config);
+	}
+
+#if STM32MP_LPDDR4_TYPE
+	/*
+	 * Enable PWRCTL.SELFREF_SW to ensure correct setting of PWRCTL.LPDDR4_SR_ALLOWED.
+	 * Later disabled in restore_refresh().
+	 */
+	config->c_reg.pwrctl |= DDRCTRL_PWRCTL_SELFREF_SW;
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	stm32mp_ddr_set_reg(priv, REG_REG, &config->c_reg, ddr_registers);
+	stm32mp_ddr_set_reg(priv, REG_TIMING, &config->c_timing, ddr_registers);
+	stm32mp_ddr_set_reg(priv, REG_MAP, &config->c_map, ddr_registers);
+	stm32mp_ddr_set_reg(priv, REG_PERF, &config->c_perf, ddr_registers);
+
+	if (!config->self_refresh) {
+		/*  DDR core and PHY reset de-assert */
+		mmio_clrbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+
+		disable_refresh(priv->ctl);
+	}
+
+	if (config->self_refresh) {
+		ddr_standby_reset_release(priv);
+
+		/* Initialize DDR by skipping training and disabling result saving */
+		ret = ddrphy_phyinit_sequence(config, true, false);
+
+		if (ret == 0) {
+			ret = ddrphy_phyinit_restore_sequence();
+		}
+
+		/* Poll on ddrphy_initeng0_phyinlpx.phyinlp3 = 0 */
+		ddr_wait_lp3_mode(false);
+	} else {
+		/* Initialize DDR including training and result saving */
+		ret = ddrphy_phyinit_sequence(config, false, true);
+	}
+
+	if (ret != 0) {
+		ERROR("DDR PHY init: Error %d\n", ret);
+		panic();
+	}
+
+	ddr_activate_controller(priv->ctl, false);
+
+	if (config->self_refresh) {
+		struct stm32mp_ddrctl *ctl = priv->ctl;
+
+		/* SW self refresh exit prequested */
+		mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_SW);
+
+		if (ddr_sr_exit_loop() != 0) {
+			ERROR("DDR Standby exit error\n");
+			panic();
+		}
+
+		/* Re-enable DFI low-power interface */
+		mmio_clrbits_32((uintptr_t)&ctl->dfilpcfg0, DDRCTRL_DFILPCFG0_DFI_LP_EN_SR);
+	} else {
+		restore_refresh(priv->ctl, config->c_reg.rfshctl3, config->c_reg.pwrctl);
+	}
+
+	stm32mp_ddr_enable_axi_port(priv->ctl);
+}
diff --git a/drivers/st/ddr/stm32mp2_ddr_helpers.c b/drivers/st/ddr/stm32mp2_ddr_helpers.c
new file mode 100644
index 0000000..a2a4082
--- /dev/null
+++ b/drivers/st/ddr/stm32mp2_ddr_helpers.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp2_ddr.h>
+#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp2_ddr_regs.h>
+#include <drivers/st/stm32mp_ddr.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/* HW idle period (unit: Multiples of 32 DFI clock cycles) */
+#define HW_IDLE_PERIOD			0x3U
+
+static enum stm32mp2_ddr_sr_mode saved_ddr_sr_mode;
+
+#pragma weak stm32_ddrdbg_get_base
+uintptr_t stm32_ddrdbg_get_base(void)
+{
+	return 0U;
+}
+
+static void set_qd1_qd3_update_conditions(struct stm32mp_ddrctl *ctl)
+{
+	mmio_setbits_32((uintptr_t)&ctl->dbg1, DDRCTRL_DBG1_DIS_DQ);
+
+	stm32mp_ddr_set_qd3_update_conditions(ctl);
+}
+
+static void unset_qd1_qd3_update_conditions(struct stm32mp_ddrctl *ctl)
+{
+	stm32mp_ddr_unset_qd3_update_conditions(ctl);
+
+	mmio_clrbits_32((uintptr_t)&ctl->dbg1, DDRCTRL_DBG1_DIS_DQ);
+}
+
+static void wait_dfi_init_complete(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t dfistat;
+
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		dfistat = mmio_read_32((uintptr_t)&ctl->dfistat);
+		VERBOSE("[0x%lx] dfistat = 0x%x ", (uintptr_t)&ctl->dfistat, dfistat);
+
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+	} while ((dfistat & DDRCTRL_DFISTAT_DFI_INIT_COMPLETE) == 0U);
+
+	VERBOSE("[0x%lx] dfistat = 0x%x\n", (uintptr_t)&ctl->dfistat, dfistat);
+}
+
+static void disable_dfi_low_power_interface(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t dfistat;
+	uint32_t stat;
+
+	mmio_clrbits_32((uintptr_t)&ctl->dfilpcfg0, DDRCTRL_DFILPCFG0_DFI_LP_EN_SR);
+
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		dfistat = mmio_read_32((uintptr_t)&ctl->dfistat);
+		stat = mmio_read_32((uintptr_t)&ctl->stat);
+		VERBOSE("[0x%lx] dfistat = 0x%x ", (uintptr_t)&ctl->dfistat, dfistat);
+		VERBOSE("[0x%lx] stat = 0x%x ", (uintptr_t)&ctl->stat, stat);
+
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+	} while (((dfistat & DDRCTRL_DFISTAT_DFI_LP_ACK) != 0U) ||
+		 ((stat & DDRCTRL_STAT_OPERATING_MODE_MASK) == DDRCTRL_STAT_OPERATING_MODE_SR));
+
+	VERBOSE("[0x%lx] dfistat = 0x%x\n", (uintptr_t)&ctl->dfistat, dfistat);
+	VERBOSE("[0x%lx] stat = 0x%x\n", (uintptr_t)&ctl->stat, stat);
+}
+
+void ddr_activate_controller(struct stm32mp_ddrctl *ctl, bool sr_entry)
+{
+	/*
+	 * Manage quasi-dynamic registers modification
+	 * dfimisc.dfi_frequency : Group 1
+	 * dfimisc.dfi_init_complete_en and dfimisc.dfi_init_start : Group 3
+	 */
+	set_qd1_qd3_update_conditions(ctl);
+
+	if (sr_entry) {
+		mmio_setbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_FREQUENCY);
+	} else {
+		mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_FREQUENCY);
+	}
+
+	mmio_setbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_START);
+	mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_START);
+
+	wait_dfi_init_complete(ctl);
+
+	udelay(DDR_DELAY_1US);
+
+	if (sr_entry) {
+		mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	} else {
+		mmio_setbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	}
+
+	udelay(DDR_DELAY_1US);
+
+	unset_qd1_qd3_update_conditions(ctl);
+}
+
+#if STM32MP_LPDDR4_TYPE
+static void disable_phy_ddc(void)
+{
+	/* Enable APB access to internal CSR registers */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_APBONLY0_MICROCONTMUXSEL, 0U);
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES,
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_UCCLKEN |
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN);
+
+	/* Disable DRAM drift compensation */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_INITENG0_P0_SEQ0BDISABLEFLAG6, 0xFFFFU);
+
+	/* Disable APB access to internal CSR registers */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES,
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN);
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_APBONLY0_MICROCONTMUXSEL,
+		      DDRPHY_APBONLY0_MICROCONTMUXSEL_MICROCONTMUXSEL);
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+void ddr_wait_lp3_mode(bool sr_entry)
+{
+	uint64_t timeout;
+	bool repeat_loop = false;
+
+	/* Enable APB access to internal CSR registers */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_APBONLY0_MICROCONTMUXSEL, 0U);
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES,
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_UCCLKEN |
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN);
+
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		uint16_t phyinlpx = mmio_read_32(stm32mp_ddrphyc_base() +
+						 DDRPHY_INITENG0_P0_PHYINLPX);
+
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+
+		if (sr_entry) {
+			repeat_loop = (phyinlpx & DDRPHY_INITENG0_P0_PHYINLPX_PHYINLP3) == 0U;
+		} else {
+			repeat_loop = (phyinlpx & DDRPHY_INITENG0_P0_PHYINLPX_PHYINLP3) != 0U;
+		}
+	} while (repeat_loop);
+
+	/* Disable APB access to internal CSR registers */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES, 0U);
+#else /* STM32MP_LPDDR4_TYPE */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES,
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN);
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_APBONLY0_MICROCONTMUXSEL,
+		      DDRPHY_APBONLY0_MICROCONTMUXSEL_MICROCONTMUXSEL);
+}
+
+static int sr_loop(bool is_entry)
+{
+	uint32_t type;
+	uint32_t state __maybe_unused;
+	uint64_t timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	bool repeat_loop = false;
+
+	/*
+	 * Wait for DDRCTRL to be out of or back to "normal/mission mode".
+	 * Consider also SRPD mode for LPDDR4 only.
+	 */
+	do {
+		type = mmio_read_32(stm32mp_ddrctrl_base() + DDRCTRL_STAT) &
+		       DDRCTRL_STAT_SELFREF_TYPE_MASK;
+#if STM32MP_LPDDR4_TYPE
+		state = mmio_read_32(stm32mp_ddrctrl_base() + DDRCTRL_STAT) &
+		       DDRCTRL_STAT_SELFREF_STATE_MASK;
+#endif /* STM32MP_LPDDR4_TYPE */
+
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+
+		if (is_entry) {
+#if STM32MP_LPDDR4_TYPE
+			repeat_loop = (type == 0x0U) || (state != DDRCTRL_STAT_SELFREF_STATE_SRPD);
+#else /* !STM32MP_LPDDR4_TYPE */
+			repeat_loop = (type == 0x0U);
+#endif /* STM32MP_LPDDR4_TYPE */
+		} else {
+#if STM32MP_LPDDR4_TYPE
+			repeat_loop = (type != 0x0U) || (state != 0x0U);
+#else /* !STM32MP_LPDDR4_TYPE */
+			repeat_loop = (type != 0x0U);
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+	} while (repeat_loop);
+
+	return 0;
+}
+
+static int sr_entry_loop(void)
+{
+	return sr_loop(true);
+}
+
+int ddr_sr_exit_loop(void)
+{
+	return sr_loop(false);
+}
+
+static int sr_ssr_set(void)
+{
+	uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
+
+	/*
+	 * Disable Clock disable with LP modes
+	 * (used in RUN mode for LPDDR2 with specific timing).
+	 */
+	mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE);
+
+	/* Disable automatic Self-Refresh mode */
+	mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_EN);
+
+	mmio_write_32(stm32_ddrdbg_get_base() + DDRDBG_LP_DISABLE,
+		      DDRDBG_LP_DISABLE_LPI_XPI_DISABLE | DDRDBG_LP_DISABLE_LPI_DDRC_DISABLE);
+
+	return 0;
+}
+
+static int sr_ssr_entry(bool standby)
+{
+	uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	if (stm32mp_ddr_disable_axi_port((struct stm32mp_ddrctl *)ddrctrl_base) != 0) {
+		panic();
+	}
+
+#if STM32MP_LPDDR4_TYPE
+	if (standby) {
+		/* Disable DRAM drift compensation */
+		disable_phy_ddc();
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	disable_dfi_low_power_interface((struct stm32mp_ddrctl *)ddrctrl_base);
+
+	/* SW self refresh entry prequested */
+	mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_SW);
+#if STM32MP_LPDDR4_TYPE
+	mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_STAY_IN_SELFREF);
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	if (sr_entry_loop() != 0) {
+		return -1;
+	}
+
+	ddr_activate_controller((struct stm32mp_ddrctl *)ddrctrl_base, true);
+
+	/* Poll on ddrphy_initeng0_phyinlpx.phyinlp3 = 1 */
+	ddr_wait_lp3_mode(true);
+
+	if (standby) {
+		mmio_clrbits_32(stm32mp_pwr_base() + PWR_CR11, PWR_CR11_DDRRETDIS);
+	}
+
+	mmio_clrsetbits_32(rcc_base + RCC_DDRCPCFGR, RCC_DDRCPCFGR_DDRCPLPEN,
+			   RCC_DDRCPCFGR_DDRCPEN);
+	mmio_setbits_32(rcc_base + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+	mmio_setbits_32(rcc_base + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRPHYDLP);
+
+	return 0;
+}
+
+static int sr_ssr_exit(void)
+{
+	uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	mmio_setbits_32(rcc_base + RCC_DDRCPCFGR,
+			RCC_DDRCPCFGR_DDRCPLPEN | RCC_DDRCPCFGR_DDRCPEN);
+	mmio_clrbits_32(rcc_base + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRPHYDLP);
+	mmio_setbits_32(rcc_base + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+
+	udelay(DDR_DELAY_1US);
+
+	ddr_activate_controller((struct stm32mp_ddrctl *)ddrctrl_base, false);
+
+	/* Poll on ddrphy_initeng0_phyinlpx.phyinlp3 = 0 */
+	ddr_wait_lp3_mode(false);
+
+	/* SW self refresh exit prequested */
+	mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_SW);
+
+	if (ddr_sr_exit_loop() != 0) {
+		return -1;
+	}
+
+	/* Re-enable DFI low-power interface */
+	mmio_setbits_32(ddrctrl_base + DDRCTRL_DFILPCFG0, DDRCTRL_DFILPCFG0_DFI_LP_EN_SR);
+
+	stm32mp_ddr_enable_axi_port((struct stm32mp_ddrctl *)ddrctrl_base);
+
+	return 0;
+}
+
+static int sr_hsr_set(void)
+{
+	uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
+
+	mmio_clrsetbits_32(stm32mp_rcc_base() + RCC_DDRITFCFGR,
+			   RCC_DDRITFCFGR_DDRCKMOD_MASK, RCC_DDRITFCFGR_DDRCKMOD_HSR);
+
+	/*
+	 * manage quasi-dynamic registers modification
+	 * hwlpctl.hw_lp_en : Group 2
+	 */
+	if (stm32mp_ddr_sw_selfref_entry((struct stm32mp_ddrctl *)ddrctrl_base) != 0) {
+		panic();
+	}
+	stm32mp_ddr_start_sw_done((struct stm32mp_ddrctl *)ddrctrl_base);
+
+	mmio_write_32(ddrctrl_base + DDRCTRL_HWLPCTL,
+		      DDRCTRL_HWLPCTL_HW_LP_EN | DDRCTRL_HWLPCTL_HW_LP_EXIT_IDLE_EN |
+		      (HW_IDLE_PERIOD << DDRCTRL_HWLPCTL_HW_LP_IDLE_X32_SHIFT));
+
+	stm32mp_ddr_wait_sw_done_ack((struct stm32mp_ddrctl *)ddrctrl_base);
+	stm32mp_ddr_sw_selfref_exit((struct stm32mp_ddrctl *)ddrctrl_base);
+
+	return 0;
+}
+
+static int sr_hsr_entry(void)
+{
+	mmio_write_32(stm32mp_rcc_base() + RCC_DDRCPCFGR, RCC_DDRCPCFGR_DDRCPLPEN);
+
+	return sr_entry_loop(); /* read_data should be equal to 0x223 */
+}
+
+static int sr_hsr_exit(void)
+{
+	mmio_write_32(stm32mp_rcc_base() + RCC_DDRCPCFGR,
+		      RCC_DDRCPCFGR_DDRCPLPEN | RCC_DDRCPCFGR_DDRCPEN);
+
+	/* TODO: check if ddr_sr_exit_loop() is needed here */
+
+	return 0;
+}
+
+static int sr_asr_set(void)
+{
+	mmio_write_32(stm32_ddrdbg_get_base() + DDRDBG_LP_DISABLE, 0U);
+
+	return 0;
+}
+
+static int sr_asr_entry(void)
+{
+	/*
+	 * Automatically enter into self refresh when there is no ddr traffic
+	 * for the delay programmed into SYSCONF_DDRC_AUTO_SR_DELAY register.
+	 * Default value is 0x20 (unit: Multiples of 32 DFI clock cycles).
+	 */
+	return sr_entry_loop();
+}
+
+static int sr_asr_exit(void)
+{
+	return ddr_sr_exit_loop();
+}
+
+uint32_t ddr_get_io_calibration_val(void)
+{
+	/* TODO create related service */
+
+	return 0U;
+}
+
+int ddr_sr_entry(bool standby)
+{
+	int ret = -EINVAL;
+
+	switch (saved_ddr_sr_mode) {
+	case DDR_SSR_MODE:
+		ret = sr_ssr_entry(standby);
+		break;
+	case DDR_HSR_MODE:
+		ret = sr_hsr_entry();
+		break;
+	case DDR_ASR_MODE:
+		ret = sr_asr_entry();
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+int ddr_sr_exit(void)
+{
+	int ret = -EINVAL;
+
+	switch (saved_ddr_sr_mode) {
+	case DDR_SSR_MODE:
+		ret = sr_ssr_exit();
+		break;
+	case DDR_HSR_MODE:
+		ret = sr_hsr_exit();
+		break;
+	case DDR_ASR_MODE:
+		ret = sr_asr_exit();
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+enum stm32mp2_ddr_sr_mode ddr_read_sr_mode(void)
+{
+	uint32_t pwrctl = mmio_read_32(stm32mp_ddrctrl_base() + DDRCTRL_PWRCTL);
+	enum stm32mp2_ddr_sr_mode mode = DDR_SR_MODE_INVALID;
+
+	switch (pwrctl & (DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE |
+			  DDRCTRL_PWRCTL_SELFREF_EN)) {
+	case 0U:
+		mode = DDR_SSR_MODE;
+		break;
+	case DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE:
+		mode = DDR_HSR_MODE;
+		break;
+	case DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE | DDRCTRL_PWRCTL_SELFREF_EN:
+		mode = DDR_ASR_MODE;
+		break;
+	default:
+		break;
+	}
+
+	return mode;
+}
+
+void ddr_set_sr_mode(enum stm32mp2_ddr_sr_mode mode)
+{
+	int ret = -EINVAL;
+
+	if (mode == saved_ddr_sr_mode) {
+		return;
+	}
+
+	switch (mode) {
+	case DDR_SSR_MODE:
+		ret = sr_ssr_set();
+		break;
+	case DDR_HSR_MODE:
+		ret = sr_hsr_set();
+		break;
+	case DDR_ASR_MODE:
+		ret = sr_asr_set();
+		break;
+	default:
+		break;
+	}
+
+	if (ret != 0) {
+		ERROR("Unknown Self Refresh mode\n");
+		panic();
+	}
+
+	saved_ddr_sr_mode = mode;
+}
+
+void ddr_save_sr_mode(void)
+{
+	saved_ddr_sr_mode = ddr_read_sr_mode();
+}
+
+void ddr_restore_sr_mode(void)
+{
+	ddr_set_sr_mode(saved_ddr_sr_mode);
+}
+
+void ddr_sub_system_clk_init(void)
+{
+	mmio_write_32(stm32mp_rcc_base() + RCC_DDRCPCFGR,
+		      RCC_DDRCPCFGR_DDRCPEN | RCC_DDRCPCFGR_DDRCPLPEN);
+}
+
+void ddr_sub_system_clk_off(void)
+{
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	/* Clear DDR IO retention */
+	mmio_clrbits_32(stm32mp_pwr_base() + PWR_CR11, PWR_CR11_DDRRETDIS);
+
+	/* Reset DDR sub system */
+	mmio_write_32(rcc_base + RCC_DDRCPCFGR, RCC_DDRCPCFGR_DDRCPRST);
+	mmio_write_32(rcc_base + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_write_32(rcc_base + RCC_DDRPHYCAPBCFGR, RCC_DDRPHYCAPBCFGR_DDRPHYCAPBRST);
+	mmio_write_32(rcc_base + RCC_DDRCAPBCFGR, RCC_DDRCAPBCFGR_DDRCAPBRST);
+
+	/* Deactivate clocks and PLL2 */
+	mmio_clrbits_32(rcc_base + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+	mmio_clrbits_32(rcc_base + RCC_PLL2CFGR1, RCC_PLL2CFGR1_PLLEN);
+}
diff --git a/drivers/st/ddr/stm32mp2_ram.c b/drivers/st/ddr/stm32mp2_ram.c
new file mode 100644
index 0000000..95f05e7
--- /dev/null
+++ b/drivers/st/ddr/stm32mp2_ram.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/clk.h>
+#include <drivers/st/stm32mp2_ddr.h>
+#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp2_ram.h>
+#include <drivers/st/stm32mp_ddr.h>
+#include <drivers/st/stm32mp_ddr_test.h>
+#include <drivers/st/stm32mp_ram.h>
+
+#include <lib/mmio.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+static struct stm32mp_ddr_priv ddr_priv_data;
+static bool ddr_self_refresh;
+
+static int ddr_dt_get_ui_param(void *fdt, int node, struct stm32mp_ddr_config *config)
+{
+	int ret;
+	uint32_t size;
+
+	size = sizeof(struct user_input_basic) / sizeof(int);
+	ret = fdt_read_uint32_array(fdt, node, "st,phy-basic", size, (uint32_t *)&config->uib);
+
+	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-basic", size, ret);
+	if (ret != 0) {
+		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-basic", ret);
+		return -EINVAL;
+	}
+
+	size = sizeof(struct user_input_advanced) / sizeof(int);
+	ret = fdt_read_uint32_array(fdt, node, "st,phy-advanced", size, (uint32_t *)&config->uia);
+
+	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-advanced", size, ret);
+	if (ret != 0) {
+		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-advanced", ret);
+		return -EINVAL;
+	}
+
+	size = sizeof(struct user_input_mode_register) / sizeof(int);
+	ret = fdt_read_uint32_array(fdt, node, "st,phy-mr", size, (uint32_t *)&config->uim);
+
+	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-mr", size, ret);
+	if (ret != 0) {
+		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-mr", ret);
+		return -EINVAL;
+	}
+
+	size = sizeof(struct user_input_swizzle) / sizeof(int);
+	ret = fdt_read_uint32_array(fdt, node, "st,phy-swizzle", size, (uint32_t *)&config->uis);
+
+	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-swizzle", size, ret);
+	if (ret != 0) {
+		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-swizzle", ret);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int stm32mp2_ddr_setup(void)
+{
+	struct stm32mp_ddr_priv *priv = &ddr_priv_data;
+	int ret;
+	struct stm32mp_ddr_config config;
+	int node;
+	uintptr_t uret;
+	void *fdt;
+
+	const struct stm32mp_ddr_param param[] = {
+		CTL_PARAM(reg),
+		CTL_PARAM(timing),
+		CTL_PARAM(map),
+		CTL_PARAM(perf)
+	};
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
+	if (node < 0) {
+		ERROR("%s: can't read DDR node in DT\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = stm32mp_ddr_dt_get_info(fdt, node, &config.info);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = stm32mp_ddr_dt_get_param(fdt, node, param, ARRAY_SIZE(param), (uintptr_t)&config);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = ddr_dt_get_ui_param(fdt, node, &config);
+	if (ret < 0) {
+		return ret;
+	}
+
+	config.self_refresh = false;
+
+	if (stm32mp_is_wakeup_from_standby()) {
+		config.self_refresh = true;
+	}
+
+	/*  Map dynamically RETRAM area to save or restore PHY retention registers */
+	if (stm32mp_map_retram() != 0) {
+		panic();
+	}
+
+	stm32mp2_ddr_init(priv, &config);
+
+	/*  Unmap RETRAM, no more used until next DDR initialization call */
+	if (stm32mp_unmap_retram() != 0) {
+		panic();
+	}
+
+	priv->info.size = config.info.size;
+
+	VERBOSE("%s : ram size(%lx, %lx)\n", __func__, priv->info.base, priv->info.size);
+
+	if (stm32mp_map_ddr_non_cacheable() != 0) {
+		panic();
+	}
+
+	if (config.self_refresh) {
+		uret = stm32mp_ddr_test_rw_access();
+		if (uret != 0UL) {
+			ERROR("DDR rw test: can't access memory @ 0x%lx\n", uret);
+			panic();
+		}
+
+		/* TODO Restore area overwritten by training */
+		//stm32_restore_ddr_training_area();
+	} else {
+		size_t retsize;
+
+		uret = stm32mp_ddr_test_data_bus();
+		if (uret != 0UL) {
+			ERROR("DDR data bus test: can't access memory @ 0x%lx\n", uret);
+			panic();
+		}
+
+		uret = stm32mp_ddr_test_addr_bus(config.info.size);
+		if (uret != 0UL) {
+			ERROR("DDR addr bus test: can't access memory @ 0x%lx\n", uret);
+			panic();
+		}
+
+		retsize = stm32mp_ddr_check_size();
+		if (retsize < config.info.size) {
+			ERROR("DDR size: 0x%zx does not match DT config: 0x%zx\n",
+			      retsize, config.info.size);
+			panic();
+		}
+
+		INFO("Memory size = 0x%zx (%zu MB)\n", retsize, retsize / (1024U * 1024U));
+	}
+
+	/*
+	 * Initialization sequence has configured DDR registers with settings.
+	 * The Self Refresh (SR) mode corresponding to these settings has now
+	 * to be set.
+	 */
+	ddr_set_sr_mode(ddr_read_sr_mode());
+
+	if (stm32mp_unmap_ddr() != 0) {
+		panic();
+	}
+
+	/* Save DDR self_refresh state */
+	ddr_self_refresh = config.self_refresh;
+
+	return 0;
+}
+
+bool stm32mp2_ddr_is_restored(void)
+{
+	return ddr_self_refresh;
+}
+
+int stm32mp2_ddr_probe(void)
+{
+	struct stm32mp_ddr_priv *priv = &ddr_priv_data;
+
+	VERBOSE("STM32MP DDR probe\n");
+
+	priv->ctl = (struct stm32mp_ddrctl *)stm32mp_ddrctrl_base();
+	priv->phy = (struct stm32mp_ddrphy *)stm32mp_ddrphyc_base();
+	priv->pwr = stm32mp_pwr_base();
+	priv->rcc = stm32mp_rcc_base();
+
+	priv->info.base = STM32MP_DDR_BASE;
+	priv->info.size = 0;
+
+	return stm32mp2_ddr_setup();
+}
diff --git a/drivers/st/ddr/stm32mp_ddr.c b/drivers/st/ddr/stm32mp_ddr.c
index 6776e3b..98968d5 100644
--- a/drivers/st/ddr/stm32mp_ddr.c
+++ b/drivers/st/ddr/stm32mp_ddr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,13 +8,15 @@
 #include <drivers/delay_timer.h>
 #include <drivers/st/stm32mp_ddr.h>
 #include <drivers/st/stm32mp_ddrctrl_regs.h>
-#include <drivers/st/stm32mp_pmic.h>
 #include <lib/mmio.h>
 
 #include <platform_def.h>
 
 #define INVALID_OFFSET	0xFFU
 
+static bool axi_port_reenable_request;
+static bool host_interface_reenable_request;
+
 static uintptr_t get_base_addr(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_base_type base)
 {
 	if (base == DDRPHY_BASE) {
@@ -38,12 +40,23 @@
 		uintptr_t ptr = base_addr + desc[i].offset;
 
 		if (desc[i].par_offset == INVALID_OFFSET) {
-			ERROR("invalid parameter offset for %s", desc[i].name);
+			ERROR("invalid parameter offset for %s - index %u",
+			      ddr_registers[type].name, i);
 			panic();
 		} else {
+#if !STM32MP13 && !STM32MP15
+			if (desc[i].qd) {
+				stm32mp_ddr_start_sw_done(priv->ctl);
+			}
+#endif
 			value = *((uint32_t *)((uintptr_t)param +
 					       desc[i].par_offset));
 			mmio_write_32(ptr, value);
+#if !STM32MP13 && !STM32MP15
+			if (desc[i].qd) {
+				stm32mp_ddr_wait_sw_done_ack(priv->ctl);
+			}
+#endif
 		}
 	}
 }
@@ -66,7 +79,7 @@
 	VERBOSE("[0x%lx] swctl = 0x%x\n",
 		(uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl));
 
-	timeout = timeout_init_us(TIMEOUT_US_1S);
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
 	do {
 		swstat = mmio_read_32((uintptr_t)&ctl->swstat);
 		VERBOSE("[0x%lx] swstat = 0x%x ",
@@ -93,14 +106,194 @@
 	VERBOSE("[0x%lx] pctrl_1 = 0x%x\n", (uintptr_t)&ctl->pctrl_1,
 		mmio_read_32((uintptr_t)&ctl->pctrl_1));
 #endif
+}
+
+int stm32mp_ddr_disable_axi_port(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t pstat;
+
+	/* Disable uMCTL2 AXI port 0 */
+	mmio_clrbits_32((uintptr_t)&ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
+	VERBOSE("[0x%lx] pctrl_0 = 0x%x\n", (uintptr_t)&ctl->pctrl_0,
+		mmio_read_32((uintptr_t)&ctl->pctrl_0));
+
+#if STM32MP_DDR_DUAL_AXI_PORT
+	/* Disable uMCTL2 AXI port 1 */
+	mmio_clrbits_32((uintptr_t)&ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
+	VERBOSE("[0x%lx] pctrl_1 = 0x%x\n", (uintptr_t)&ctl->pctrl_1,
+		mmio_read_32((uintptr_t)&ctl->pctrl_1));
+#endif
 
+	/*
+	 * Waits until all AXI ports are idle
+	 * Poll PSTAT.rd_port_busy_n = 0
+	 * Poll PSTAT.wr_port_busy_n = 0
+	 */
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		pstat = mmio_read_32((uintptr_t)&ctl->pstat);
+		VERBOSE("[0x%lx] pstat = 0x%x ",
+			(uintptr_t)&ctl->pstat, pstat);
+		if (timeout_elapsed(timeout)) {
+			return -1;
+		}
+	} while (pstat != 0U);
+
+	return 0;
+}
+
+static bool ddr_is_axi_port_enabled(struct stm32mp_ddrctl *ctl)
+{
+	return (mmio_read_32((uintptr_t)&ctl->pctrl_0) & DDRCTRL_PCTRL_N_PORT_EN) != 0U;
+}
+
+void stm32mp_ddr_enable_host_interface(struct stm32mp_ddrctl *ctl)
+{
+	mmio_clrbits_32((uintptr_t)&ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+	VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+		(uintptr_t)&ctl->dbg1,
+		mmio_read_32((uintptr_t)&ctl->dbg1));
+}
+
+void stm32mp_ddr_disable_host_interface(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t dbgcam;
+	int count = 0;
+
+	mmio_setbits_32((uintptr_t)&ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+	VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+		(uintptr_t)&ctl->dbg1,
+		mmio_read_32((uintptr_t)&ctl->dbg1));
+
+	/*
+	 * Waits until all queues and pipelines are empty
+	 * Poll DBGCAM.dbg_wr_q_empty = 1
+	 * Poll DBGCAM.dbg_rd_q_empty = 1
+	 * Poll DBGCAM.dbg_wr_data_pipeline_empty = 1
+	 * Poll DBGCAM.dbg_rd_data_pipeline_empty = 1
+	 *
+	 * data_pipeline fields must be polled twice to ensure
+	 * value propoagation, so count is added to loop condition.
+	 */
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		dbgcam = mmio_read_32((uintptr_t)&ctl->dbgcam);
+		VERBOSE("[0x%lx] dbgcam = 0x%x ",
+			(uintptr_t)&ctl->dbgcam, dbgcam);
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+		count++;
+	} while (((dbgcam & DDRCTRL_DBG_Q_AND_DATA_PIPELINE_EMPTY) !=
+		  DDRCTRL_DBG_Q_AND_DATA_PIPELINE_EMPTY) || (count < 2));
+}
+
+static bool ddr_is_host_interface_enabled(struct stm32mp_ddrctl *ctl)
+{
+	return (mmio_read_32((uintptr_t)&ctl->dbg1) & DDRCTRL_DBG1_DIS_HIF) == 0U;
+}
+
+int stm32mp_ddr_sw_selfref_entry(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t stat;
+	uint32_t operating_mode;
+	uint32_t selref_type;
+
+	mmio_setbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_SW);
+	VERBOSE("[0x%lx] pwrctl = 0x%x\n",
+		(uintptr_t)&ctl->pwrctl,
+		mmio_read_32((uintptr_t)&ctl->pwrctl));
+
+	/*
+	 * Wait operating mode change in self-refresh mode
+	 * with STAT.operating_mode[1:0]==11.
+	 * Ensure transition to self-refresh was due to software
+	 * by checking also that STAT.selfref_type[1:0]=2.
+	 */
+	timeout = timeout_init_us(DDR_TIMEOUT_500US);
+	while (!timeout_elapsed(timeout)) {
+		stat = mmio_read_32((uintptr_t)&ctl->stat);
+		operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK;
+		selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK;
+
+		if ((operating_mode == DDRCTRL_STAT_OPERATING_MODE_SR) &&
+		    (selref_type == DDRCTRL_STAT_SELFREF_TYPE_SR)) {
+			return 0;
+		}
+	}
+
+	return -1;
 }
 
-int stm32mp_board_ddr_power_init(enum ddr_type ddr_type)
+void stm32mp_ddr_sw_selfref_exit(struct stm32mp_ddrctl *ctl)
 {
-	if (dt_pmic_status() > 0) {
-		return pmic_ddr_power_init(ddr_type);
+	mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_SW);
+	VERBOSE("[0x%lx] pwrctl = 0x%x\n",
+		(uintptr_t)&ctl->pwrctl,
+		mmio_read_32((uintptr_t)&ctl->pwrctl));
+}
+
+void stm32mp_ddr_set_qd3_update_conditions(struct stm32mp_ddrctl *ctl)
+{
+	if (ddr_is_axi_port_enabled(ctl)) {
+		if (stm32mp_ddr_disable_axi_port(ctl) != 0) {
+			panic();
+		}
+		axi_port_reenable_request = true;
 	}
 
-	return 0;
+	if (ddr_is_host_interface_enabled(ctl)) {
+		stm32mp_ddr_disable_host_interface(ctl);
+		host_interface_reenable_request = true;
+	}
+
+	stm32mp_ddr_start_sw_done(ctl);
+}
+
+void stm32mp_ddr_unset_qd3_update_conditions(struct stm32mp_ddrctl *ctl)
+{
+	stm32mp_ddr_wait_sw_done_ack(ctl);
+
+	if (host_interface_reenable_request) {
+		stm32mp_ddr_enable_host_interface(ctl);
+		host_interface_reenable_request = false;
+	}
+
+	if (axi_port_reenable_request) {
+		stm32mp_ddr_enable_axi_port(ctl);
+		axi_port_reenable_request = false;
+	}
+}
+
+void stm32mp_ddr_wait_refresh_update_done_ack(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t rfshctl3;
+	uint32_t refresh_update_level = DDRCTRL_RFSHCTL3_REFRESH_UPDATE_LEVEL;
+
+	/* Toggle rfshctl3.refresh_update_level */
+	rfshctl3 = mmio_read_32((uintptr_t)&ctl->rfshctl3);
+	if ((rfshctl3 & refresh_update_level) == refresh_update_level) {
+		mmio_setbits_32((uintptr_t)&ctl->rfshctl3, refresh_update_level);
+	} else {
+		mmio_clrbits_32((uintptr_t)&ctl->rfshctl3, refresh_update_level);
+		refresh_update_level = 0U;
+	}
+
+	VERBOSE("[0x%lx] rfshctl3 = 0x%x\n",
+		(uintptr_t)&ctl->rfshctl3, mmio_read_32((uintptr_t)&ctl->rfshctl3));
+
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		rfshctl3 = mmio_read_32((uintptr_t)&ctl->rfshctl3);
+		VERBOSE("[0x%lx] rfshctl3 = 0x%x ", (uintptr_t)&ctl->rfshctl3, rfshctl3);
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+	} while ((rfshctl3 & DDRCTRL_RFSHCTL3_REFRESH_UPDATE_LEVEL) != refresh_update_level);
+
+	VERBOSE("[0x%lx] rfshctl3 = 0x%x\n", (uintptr_t)&ctl->rfshctl3, rfshctl3);
 }
diff --git a/drivers/st/ddr/stm32mp_ddr_test.c b/drivers/st/ddr/stm32mp_ddr_test.c
index 0f6aff1..707a6ff 100644
--- a/drivers/st/ddr/stm32mp_ddr_test.c
+++ b/drivers/st/ddr/stm32mp_ddr_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,8 +10,31 @@
 
 #include <platform_def.h>
 
+#ifdef __aarch64__
+#define DDR_PATTERN	0xAAAAAAAAAAAAAAAAUL
+#define DDR_ANTIPATTERN	0x5555555555555555UL
+#else /* !__aarch64__ */
 #define DDR_PATTERN	0xAAAAAAAAU
 #define DDR_ANTIPATTERN	0x55555555U
+#endif /* __aarch64__ */
+
+static void mmio_write_pattern(uintptr_t addr, u_register_t value)
+{
+#ifdef __aarch64__
+	mmio_write_64(addr, (uint64_t)value);
+#else /* !__aarch64__ */
+	mmio_write_32(addr, (uint32_t)value);
+#endif /* __aarch64__ */
+}
+
+static u_register_t mmio_read_pattern(uintptr_t addr)
+{
+#ifdef __aarch64__
+	return (u_register_t)mmio_read_64(addr);
+#else /* !__aarch64__ */
+	return (u_register_t)mmio_read_32(addr);
+#endif /* __aarch64__ */
+}
 
 /*******************************************************************************
  * This function tests a simple read/write access to the DDR.
@@ -20,15 +43,15 @@
  ******************************************************************************/
 uintptr_t stm32mp_ddr_test_rw_access(void)
 {
-	uint32_t saved_value = mmio_read_32(STM32MP_DDR_BASE);
+	u_register_t saved_value = mmio_read_pattern(STM32MP_DDR_BASE);
 
-	mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN);
+	mmio_write_pattern(STM32MP_DDR_BASE, DDR_PATTERN);
 
-	if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) {
+	if (mmio_read_pattern(STM32MP_DDR_BASE) != DDR_PATTERN) {
 		return STM32MP_DDR_BASE;
 	}
 
-	mmio_write_32(STM32MP_DDR_BASE, saved_value);
+	mmio_write_pattern(STM32MP_DDR_BASE, saved_value);
 
 	return 0UL;
 }
@@ -43,12 +66,12 @@
  ******************************************************************************/
 uintptr_t stm32mp_ddr_test_data_bus(void)
 {
-	uint32_t pattern;
+	u_register_t pattern;
 
 	for (pattern = 1U; pattern != 0U; pattern <<= 1U) {
-		mmio_write_32(STM32MP_DDR_BASE, pattern);
+		mmio_write_pattern(STM32MP_DDR_BASE, pattern);
 
-		if (mmio_read_32(STM32MP_DDR_BASE) != pattern) {
+		if (mmio_read_pattern(STM32MP_DDR_BASE) != pattern) {
 			return STM32MP_DDR_BASE;
 		}
 	}
@@ -72,41 +95,41 @@
 	size_t testoffset = 0U;
 
 	/* Write the default pattern at each of the power-of-two offsets. */
-	for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+	for (offset = sizeof(u_register_t); (offset & addressmask) != 0U;
 	     offset <<= 1U) {
-		mmio_write_32(STM32MP_DDR_BASE + offset, DDR_PATTERN);
+		mmio_write_pattern(STM32MP_DDR_BASE + offset, DDR_PATTERN);
 	}
 
 	/* Check for address bits stuck high. */
-	mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
+	mmio_write_pattern(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
 
-	for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+	for (offset = sizeof(u_register_t); (offset & addressmask) != 0U;
 	     offset <<= 1U) {
-		if (mmio_read_32(STM32MP_DDR_BASE + offset) != DDR_PATTERN) {
+		if (mmio_read_pattern(STM32MP_DDR_BASE + offset) != DDR_PATTERN) {
 			return STM32MP_DDR_BASE + offset;
 		}
 	}
 
-	mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
+	mmio_write_pattern(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
 
 	/* Check for address bits stuck low or shorted. */
-	for (testoffset = sizeof(uint32_t); (testoffset & addressmask) != 0U;
+	for (testoffset = sizeof(u_register_t); (testoffset & addressmask) != 0U;
 	     testoffset <<= 1U) {
-		mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
+		mmio_write_pattern(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
 
-		if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) {
+		if (mmio_read_pattern(STM32MP_DDR_BASE) != DDR_PATTERN) {
 			return STM32MP_DDR_BASE;
 		}
 
-		for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
-		     offset <<= 1) {
-			if ((mmio_read_32(STM32MP_DDR_BASE + offset) != DDR_PATTERN) &&
+		for (offset = sizeof(u_register_t); (offset & addressmask) != 0U;
+		     offset <<= 1U) {
+			if ((mmio_read_pattern(STM32MP_DDR_BASE + offset) != DDR_PATTERN) &&
 			    (offset != testoffset)) {
 				return STM32MP_DDR_BASE + offset;
 			}
 		}
 
-		mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
+		mmio_write_pattern(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
 	}
 
 	return 0UL;
@@ -121,15 +144,15 @@
  ******************************************************************************/
 size_t stm32mp_ddr_check_size(void)
 {
-	size_t offset = sizeof(uint32_t);
+	size_t offset = sizeof(u_register_t);
 
-	mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN);
+	mmio_write_pattern(STM32MP_DDR_BASE, DDR_PATTERN);
 
 	while (offset < STM32MP_DDR_MAX_SIZE) {
-		mmio_write_32(STM32MP_DDR_BASE + offset, DDR_ANTIPATTERN);
+		mmio_write_pattern(STM32MP_DDR_BASE + offset, DDR_ANTIPATTERN);
 		dsb();
 
-		if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) {
+		if (mmio_read_pattern(STM32MP_DDR_BASE) != DDR_PATTERN) {
 			break;
 		}
 
diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
index 1e16287..58f97b3 100644
--- a/drivers/st/pmic/stm32mp_pmic.c
+++ b/drivers/st/pmic/stm32mp_pmic.c
@@ -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
  */
@@ -216,120 +216,6 @@
 }
 #endif
 
-int pmic_ddr_power_init(enum ddr_type ddr_type)
-{
-	int status;
-	uint16_t buck3_min_mv;
-	struct rdev *buck2, *buck3, *vref;
-	struct rdev *ldo3 __unused;
-
-	buck2 = regulator_get_by_name("buck2");
-	if (buck2 == NULL) {
-		return -ENOENT;
-	}
-
-#if STM32MP15
-	ldo3 = regulator_get_by_name("ldo3");
-	if (ldo3 == NULL) {
-		return -ENOENT;
-	}
-#endif
-
-	vref = regulator_get_by_name("vref_ddr");
-	if (vref == NULL) {
-		return -ENOENT;
-	}
-
-	switch (ddr_type) {
-	case STM32MP_DDR3:
-#if STM32MP15
-		status = regulator_set_flag(ldo3, REGUL_SINK_SOURCE);
-		if (status != 0) {
-			return status;
-		}
-#endif
-
-		status = regulator_set_min_voltage(buck2);
-		if (status != 0) {
-			return status;
-		}
-
-		status = regulator_enable(buck2);
-		if (status != 0) {
-			return status;
-		}
-
-		status = regulator_enable(vref);
-		if (status != 0) {
-			return status;
-		}
-
-#if STM32MP15
-		status = regulator_enable(ldo3);
-		if (status != 0) {
-			return status;
-		}
-#endif
-		break;
-
-	case STM32MP_LPDDR2:
-	case STM32MP_LPDDR3:
-		/*
-		 * Set LDO3 to 1.8V
-		 * Set LDO3 to bypass mode if BUCK3 = 1.8V
-		 * Set LDO3 to normal mode if BUCK3 != 1.8V
-		 */
-		buck3 = regulator_get_by_name("buck3");
-		if (buck3 == NULL) {
-			return -ENOENT;
-		}
-
-		regulator_get_range(buck3, &buck3_min_mv, NULL);
-
-#if STM32MP15
-		if (buck3_min_mv != 1800) {
-			status = regulator_set_min_voltage(ldo3);
-			if (status != 0) {
-				return status;
-			}
-		} else {
-			status = regulator_set_flag(ldo3, REGUL_ENABLE_BYPASS);
-			if (status != 0) {
-				return status;
-			}
-		}
-#endif
-
-		status = regulator_set_min_voltage(buck2);
-		if (status != 0) {
-			return status;
-		}
-
-#if STM32MP15
-		status = regulator_enable(ldo3);
-		if (status != 0) {
-			return status;
-		}
-#endif
-
-		status = regulator_enable(buck2);
-		if (status != 0) {
-			return status;
-		}
-
-		status = regulator_enable(vref);
-		if (status != 0) {
-			return status;
-		}
-		break;
-
-	default:
-		break;
-	};
-
-	return 0;
-}
-
 int pmic_voltages_init(void)
 {
 #if STM32MP13
diff --git a/drivers/st/pmic/stm32mp_pmic2.c b/drivers/st/pmic/stm32mp_pmic2.c
new file mode 100644
index 0000000..c19d36a
--- /dev/null
+++ b/drivers/st/pmic/stm32mp_pmic2.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/regulator.h>
+#include <drivers/st/stm32_i2c.h>
+#include <drivers/st/stm32mp_pmic2.h>
+#include <drivers/st/stpmic2.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#define PMIC_NODE_NOT_FOUND	1
+
+struct regul_handle_s {
+	const uint32_t id;
+	uint16_t bypass_mv;
+};
+
+static struct pmic_handle_s pmic2_handle;
+static struct i2c_handle_s i2c_handle;
+
+/* This driver is monoinstance */
+static struct pmic_handle_s *pmic2;
+
+static int dt_get_pmic_node(void *fdt)
+{
+	static int node = -FDT_ERR_BADOFFSET;
+
+	if (node == -FDT_ERR_BADOFFSET) {
+		node = fdt_node_offset_by_compatible(fdt, -1, "st,stpmic2");
+	}
+
+	return node;
+}
+
+int dt_pmic_status(void)
+{
+	static int status = -FDT_ERR_BADVALUE;
+	int node;
+	void *fdt;
+
+	if (status != -FDT_ERR_BADVALUE) {
+		return status;
+	}
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = dt_get_pmic_node(fdt);
+	if (node <= 0) {
+		status = -FDT_ERR_NOTFOUND;
+
+		return status;
+	}
+
+	status = DT_SECURE;
+
+	return status;
+}
+
+/*
+ * Get PMIC and its I2C bus configuration from the device tree.
+ * Return 0 on success, negative on error, 1 if no PMIC node is defined.
+ */
+static int dt_pmic2_i2c_config(struct dt_node_info *i2c_info,
+			       struct stm32_i2c_init_s *init,
+			       uint32_t *i2c_addr)
+{
+	static int i2c_node = -FDT_ERR_NOTFOUND;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if (i2c_node == -FDT_ERR_NOTFOUND) {
+		int pmic_node;
+		const fdt32_t *cuint;
+
+		pmic_node = dt_get_pmic_node(fdt);
+		if (pmic_node < 0) {
+			return PMIC_NODE_NOT_FOUND;
+		}
+
+		cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
+		if (cuint == NULL) {
+			return -FDT_ERR_NOTFOUND;
+		}
+
+		*i2c_addr = fdt32_to_cpu(*cuint) << 1;
+		if (*i2c_addr > UINT16_MAX) {
+			return -FDT_ERR_BADVALUE;
+		}
+
+		i2c_node = fdt_parent_offset(fdt, pmic_node);
+		if (i2c_node < 0) {
+			return -FDT_ERR_NOTFOUND;
+		}
+	}
+
+	dt_fill_device_info(i2c_info, i2c_node);
+	if (i2c_info->base == 0U) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	i2c_info->status = DT_SECURE;
+
+	return stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init);
+}
+
+bool initialize_pmic_i2c(void)
+{
+	int ret;
+	struct dt_node_info i2c_info;
+	struct i2c_handle_s *i2c = &i2c_handle;
+	uint32_t i2c_addr = 0U;
+	struct stm32_i2c_init_s i2c_init;
+
+	ret = dt_pmic2_i2c_config(&i2c_info, &i2c_init, &i2c_addr);
+	if (ret < 0) {
+		ERROR("I2C configuration failed %d\n", ret);
+		panic();
+	}
+
+	if (ret != 0) {
+		return false;
+	}
+
+	/* Initialize PMIC I2C */
+	i2c->i2c_base_addr		= i2c_info.base;
+	i2c->dt_status			= i2c_info.status;
+	i2c->clock			= i2c_info.clock;
+	i2c->i2c_state			= I2C_STATE_RESET;
+	i2c_init.own_address1		= i2c_addr;
+	i2c_init.addressing_mode	= I2C_ADDRESSINGMODE_7BIT;
+	i2c_init.dual_address_mode	= I2C_DUALADDRESS_DISABLE;
+	i2c_init.own_address2		= 0;
+	i2c_init.own_address2_masks	= I2C_OAR2_OA2NOMASK;
+	i2c_init.general_call_mode	= I2C_GENERALCALL_DISABLE;
+	i2c_init.no_stretch_mode	= I2C_NOSTRETCH_DISABLE;
+	i2c_init.analog_filter		= 1;
+	i2c_init.digital_filter_coef	= 0;
+
+	ret = stm32_i2c_init(i2c, &i2c_init);
+	if (ret != 0) {
+		ERROR("Cannot initialize I2C %x (%d)\n",
+		      i2c->i2c_base_addr, ret);
+		panic();
+	}
+
+	if (!stm32_i2c_is_device_ready(i2c, i2c_addr, 1,
+				       I2C_TIMEOUT_BUSY_MS)) {
+		ERROR("I2C device not ready\n");
+		panic();
+	}
+
+	pmic2 = &pmic2_handle;
+	pmic2->i2c_handle = &i2c_handle;
+	pmic2->i2c_addr = i2c_addr;
+
+	return true;
+}
+
+static int pmic2_set_state(const struct regul_description *desc, bool enable)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+
+	VERBOSE("%s: set state to %d\n", desc->node_name, enable);
+
+	return stpmic2_regulator_set_state(pmic2, regul->id, enable);
+}
+
+static int pmic2_get_state(const struct regul_description *desc)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+	bool enabled;
+
+	VERBOSE("%s: get state\n", desc->node_name);
+
+	if (stpmic2_regulator_get_state(pmic2, regul->id, &enabled) < 0) {
+		panic();
+	}
+
+	return enabled;
+}
+
+static int pmic2_get_voltage(const struct regul_description *desc)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+	uint16_t mv;
+
+	VERBOSE("%s: get volt\n", desc->node_name);
+
+	if (regul->bypass_mv != 0U) {
+		int ret;
+
+		/* If the regul is in bypass mode, return bypass value */
+		ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS);
+		if (ret < 0) {
+			return ret;
+		}
+
+		if (ret == 1) {
+			return regul->bypass_mv;
+		}
+	};
+
+	if (stpmic2_regulator_get_voltage(pmic2, regul->id, &mv) < 0) {
+		panic();
+	}
+
+	return mv;
+}
+
+static int pmic2_set_voltage(const struct regul_description *desc, uint16_t mv)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+
+	VERBOSE("%s: set volt\n", desc->node_name);
+
+	if (regul->bypass_mv != 0U) {
+		int ret;
+
+		/* If the regul is in bypass mode, authorize bypass mV */
+		ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS);
+		if (ret < 0) {
+			return ret;
+		}
+
+		if ((ret == 1) && (mv != regul->bypass_mv)) {
+			return -EPERM;
+		}
+	};
+
+	return stpmic2_regulator_set_voltage(pmic2, regul->id, mv);
+}
+
+static int pmic2_list_voltages(const struct regul_description *desc,
+			       const uint16_t **levels, size_t *count)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+
+	VERBOSE("%s: list volt\n", desc->node_name);
+
+	if (regul->bypass_mv != 0U) {
+		int ret;
+
+		ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS);
+		if (ret < 0) {
+			return ret;
+		}
+
+		/* bypass is enabled, return a list with only bypass mV */
+		if (ret == 1) {
+			if (count != NULL) {
+				*count = 1U;
+			}
+			if (levels != NULL) {
+				*levels = &regul->bypass_mv;
+			}
+			return 0;
+		}
+	};
+
+	return stpmic2_regulator_levels_mv(pmic2, regul->id, levels, count);
+}
+
+static int pmic2_set_flag(const struct regul_description *desc, uint16_t flag)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+	uint32_t id = regul->id;
+	int ret = -EPERM;
+
+	VERBOSE("%s: set_flag 0x%x\n", desc->node_name, flag);
+
+	switch (flag) {
+	case REGUL_PULL_DOWN:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_PULL_DOWN, 1U);
+		break;
+	case REGUL_OCP:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_OCP, 1U);
+		break;
+	case REGUL_SINK_SOURCE:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_SINK_SOURCE, 1U);
+		break;
+	case REGUL_ENABLE_BYPASS:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_BYPASS, 1U);
+		break;
+	case REGUL_MASK_RESET:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_MASK_RESET, 1U);
+		break;
+	default:
+		ERROR("Invalid flag %u", flag);
+		panic();
+	}
+
+	if (ret != 0) {
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+int stpmic2_set_prop(const struct regul_description *desc, uint16_t prop, uint32_t value)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+	int ret;
+
+	VERBOSE("%s: set_prop 0x%x val=%u\n", desc->node_name, prop, value);
+
+	ret = stpmic2_regulator_set_prop(pmic2, regul->id, prop, value);
+	if (ret != 0)
+		return -EPERM;
+
+	return 0;
+}
+
+static struct regul_ops pmic2_ops = {
+	.set_state = pmic2_set_state,
+	.get_state = pmic2_get_state,
+	.set_voltage = pmic2_set_voltage,
+	.get_voltage = pmic2_get_voltage,
+	.list_voltages = pmic2_list_voltages,
+	.set_flag = pmic2_set_flag,
+};
+
+#define DEFINE_PMIC_REGUL_HANDLE(rid) \
+[(rid)] = { \
+	.id = (rid), \
+}
+
+static struct regul_handle_s pmic2_regul_handles[STPMIC2_NB_REG] = {
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK1),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK2),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK3),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK4),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK5),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK6),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK7),
+
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO1),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO2),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO3),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO4),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO5),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO6),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO7),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO8),
+
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_REFDDR),
+};
+
+#define DEFINE_REGUL(rid, name) \
+[rid] = { \
+	.node_name = name, \
+	.ops = &pmic2_ops, \
+	.driver_data = &pmic2_regul_handles[rid], \
+}
+
+static const struct regul_description pmic2_descs[STPMIC2_NB_REG] = {
+	DEFINE_REGUL(STPMIC2_BUCK1, "buck1"),
+	DEFINE_REGUL(STPMIC2_BUCK2, "buck2"),
+	DEFINE_REGUL(STPMIC2_BUCK3, "buck3"),
+	DEFINE_REGUL(STPMIC2_BUCK4, "buck4"),
+	DEFINE_REGUL(STPMIC2_BUCK5, "buck5"),
+	DEFINE_REGUL(STPMIC2_BUCK6, "buck6"),
+	DEFINE_REGUL(STPMIC2_BUCK7, "buck7"),
+
+	DEFINE_REGUL(STPMIC2_LDO1, "ldo1"),
+	DEFINE_REGUL(STPMIC2_LDO2, "ldo2"),
+	DEFINE_REGUL(STPMIC2_LDO3, "ldo3"),
+	DEFINE_REGUL(STPMIC2_LDO4, "ldo4"),
+	DEFINE_REGUL(STPMIC2_LDO5, "ldo5"),
+	DEFINE_REGUL(STPMIC2_LDO6, "ldo6"),
+	DEFINE_REGUL(STPMIC2_LDO7, "ldo7"),
+	DEFINE_REGUL(STPMIC2_LDO8, "ldo8"),
+
+	DEFINE_REGUL(STPMIC2_REFDDR, "refddr"),
+};
+
+static int register_pmic2(void)
+{
+	void *fdt;
+	int pmic_node, regulators_node, subnode;
+
+	VERBOSE("Register pmic2\n");
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	pmic_node = dt_get_pmic_node(fdt);
+	if (pmic_node < 0) {
+		return pmic_node;
+	}
+
+	regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
+	if (regulators_node < 0) {
+		return -ENOENT;
+	}
+
+	fdt_for_each_subnode(subnode, fdt, regulators_node) {
+		const char *reg_name = fdt_get_name(fdt, subnode, NULL);
+		const struct regul_description *desc;
+		unsigned int i;
+		int ret;
+		const fdt32_t *cuint;
+
+		for (i = 0; i < STPMIC2_NB_REG; i++) {
+			desc = &pmic2_descs[i];
+			if (strcmp(desc->node_name, reg_name) == 0) {
+				break;
+			}
+		}
+		assert(i < STPMIC2_NB_REG);
+
+		ret = regulator_register(desc, subnode);
+		if (ret != 0) {
+			WARN("%s:%d failed to register %s\n", __func__,
+			     __LINE__, reg_name);
+			return ret;
+		}
+
+		cuint = fdt_getprop(fdt, subnode, "st,regulator-bypass-microvolt", NULL);
+		if (cuint != NULL) {
+			struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+
+			regul->bypass_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
+			VERBOSE("%s: bypass voltage=%umV\n", desc->node_name,
+				regul->bypass_mv);
+		}
+
+		if (fdt_getprop(fdt, subnode, "st,mask-reset", NULL)  != NULL) {
+			VERBOSE("%s: set mask-reset\n", desc->node_name);
+			ret = pmic2_set_flag(desc, REGUL_MASK_RESET);
+			if (ret != 0) {
+				ERROR("set mask-reset failed\n");
+				return ret;
+			}
+		}
+
+		if (fdt_getprop(fdt, subnode, "st,regulator-sink-source", NULL) != NULL) {
+			VERBOSE("%s: set regulator-sink-source\n", desc->node_name);
+			ret = pmic2_set_flag(desc, REGUL_SINK_SOURCE);
+			if (ret != 0) {
+				ERROR("set regulator-sink-source failed\n");
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+void initialize_pmic(void)
+{
+	int ret;
+	uint8_t val;
+
+	ret = initialize_pmic_i2c();
+	if (!ret) {
+		VERBOSE("No PMIC2\n");
+		return;
+	}
+
+	if (stpmic2_get_version(pmic2, &val) != 0) {
+		ERROR("Failed to access PMIC\n");
+		panic();
+	}
+	INFO("PMIC2 version = 0x%02x\n", val);
+
+	if (stpmic2_get_product_id(pmic2, &val) != 0) {
+		ERROR("Failed to access PMIC\n");
+		panic();
+	}
+	INFO("PMIC2 product ID = 0x%02x\n", val);
+
+	ret = register_pmic2();
+	if (ret < 0) {
+		ERROR("Register pmic2 failed\n");
+		panic();
+	}
+
+#if EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE
+	stpmic2_dump_regulators(pmic2);
+#endif
+}
diff --git a/drivers/st/pmic/stpmic2.c b/drivers/st/pmic/stpmic2.c
new file mode 100644
index 0000000..05a80ec
--- /dev/null
+++ b/drivers/st/pmic/stpmic2.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/st/stpmic2.h>
+
+#define RET_SUCCESS			0
+#define RET_ERROR_NOT_SUPPORTED		-1
+#define RET_ERROR_GENERIC		-2
+#define RET_ERROR_BAD_PARAMETERS	-3
+
+#define I2C_TIMEOUT_MS			25
+
+#define VOLTAGE_INDEX_INVALID		((size_t)~0U)
+
+struct regul_struct {
+	const char *name;
+	const uint16_t *volt_table;
+	uint8_t volt_table_size;
+	uint8_t volt_cr;
+	uint8_t volt_shift;
+	uint8_t en_cr;
+	uint8_t alt_en_cr;
+	uint8_t msrt_reg;
+	uint8_t msrt_mask;
+	uint8_t pd_reg;
+	uint8_t pd_val;
+	uint8_t ocp_reg;
+	uint8_t ocp_mask;
+};
+
+/* Voltage tables in mV */
+static const uint16_t buck1236_volt_table[] = {
+	500U, 510U, 520U, 530U, 540U, 550U, 560U, 570U, 580U, 590U,
+	600U, 610U, 620U, 630U, 640U, 650U, 660U, 670U, 680U, 690U,
+	700U, 710U, 720U, 730U, 740U, 750U, 760U, 770U, 780U, 790U,
+	800U, 810U, 820U, 830U, 840U, 850U, 860U, 870U, 880U, 890U,
+	900U, 910U, 920U, 930U, 940U, 950U, 960U, 970U, 980U, 990U,
+	1000U, 1010U, 1020U, 1030U, 1040U, 1050U, 1060U, 1070U, 1080U, 1090U,
+	1100U, 1110U, 1120U, 1130U, 1140U, 1150U, 1160U, 1170U, 1180U, 1190U,
+	1200U, 1210U, 1220U, 1230U, 1240U, 1250U, 1260U, 1270U, 1280U, 1290U,
+	1300U, 1310U, 1320U, 1330U, 1340U, 1350U, 1360U, 1370U, 1380U, 1390U,
+	1400U, 1410U, 1420U, 1430U, 1440U, 1450U, 1460U, 1470U, 1480U, 1490U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U
+};
+
+static const uint16_t buck457_volt_table[] = {
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1600U, 1700U, 1800U, 1900U, 2000U, 2100U, 2200U, 2300U, 2400U,
+	2500U, 2600U, 2700U, 2800U, 2900U, 3000U, 3100U, 3200U, 3300U, 3400U,
+	3500U, 3600U, 3700U, 3800U, 3900U, 4000U, 4100U, 4200U
+};
+
+static const uint16_t ldo235678_volt_table[] = {
+	900U, 1000U, 1100U, 1200U, 1300U, 1400U, 1500U, 1600U, 1700U, 1800U,
+	1900U, 2000U, 2100U, 2200U, 2300U, 2400U, 2500U, 2600U, 2700U, 2800U,
+	2900U, 3000U, 3100U, 3200U, 3300U, 3400U, 3500U, 3600U, 3700U, 3800U,
+	3900U, 4000U
+};
+
+static const uint16_t ldo1_volt_table[] = {
+	1800U,
+};
+
+static const uint16_t ldo4_volt_table[] = {
+	3300U,
+};
+
+static const uint16_t refddr_volt_table[] = {
+	0,
+};
+
+#define DEFINE_BUCK(regu_name, ID, pd, table) { \
+	.name			= regu_name, \
+	.volt_table		= table, \
+	.volt_table_size	= ARRAY_SIZE(table), \
+	.en_cr			= ID ## _MAIN_CR2, \
+	.volt_cr		= ID ## _MAIN_CR1, \
+	.alt_en_cr		= ID ## _ALT_CR2, \
+	.msrt_reg		= BUCKS_MRST_CR, \
+	.msrt_mask		= ID ## _MRST, \
+	.pd_reg			= pd, \
+	.pd_val			= ID ## _PD_FAST, \
+	.ocp_reg		= FS_OCP_CR1, \
+	.ocp_mask		= FS_OCP_ ## ID, \
+}
+
+#define DEFINE_LDOx(regu_name, ID, table) { \
+	.name			= regu_name, \
+	.volt_table		= table, \
+	.volt_table_size	= ARRAY_SIZE(table), \
+	.volt_shift		= LDO_VOLT_SHIFT, \
+	.en_cr			= ID ## _MAIN_CR, \
+	.volt_cr		= ID ## _MAIN_CR, \
+	.alt_en_cr		= ID ## _ALT_CR, \
+	.msrt_reg		= LDOS_MRST_CR, \
+	.msrt_mask		= ID ## _MRST, \
+	.pd_reg			= LDOS_PD_CR1, \
+	.pd_val			= ID ## _PD, \
+	.ocp_reg		= FS_OCP_CR2, \
+	.ocp_mask		= FS_OCP_ ## ID, \
+}
+
+#define DEFINE_REFDDR(regu_name, ID, table) { \
+	.name			= regu_name, \
+	.volt_table		= table, \
+	.volt_table_size	= ARRAY_SIZE(table), \
+	.en_cr			= ID ## _MAIN_CR, \
+	.volt_cr		= ID ## _MAIN_CR, \
+	.alt_en_cr		= ID ## _ALT_CR, \
+	.msrt_reg		= BUCKS_MRST_CR, \
+	.msrt_mask		= ID ## _MRST, \
+	.pd_reg			= LDOS_PD_CR2, \
+	.pd_val			= ID ## _PD, \
+	.ocp_reg		= FS_OCP_CR1, \
+	.ocp_mask		= FS_OCP_ ## ID, \
+}
+
+/* Table of Regulators in PMIC SoC */
+static const struct regul_struct regul_table[STPMIC2_NB_REG] = {
+	[STPMIC2_BUCK1] = DEFINE_BUCK("buck1", BUCK1, BUCKS_PD_CR1,
+				      buck1236_volt_table),
+	[STPMIC2_BUCK2] = DEFINE_BUCK("buck2", BUCK2, BUCKS_PD_CR1,
+				      buck1236_volt_table),
+	[STPMIC2_BUCK3] = DEFINE_BUCK("buck3", BUCK3, BUCKS_PD_CR1,
+				      buck1236_volt_table),
+	[STPMIC2_BUCK4] = DEFINE_BUCK("buck4", BUCK4, BUCKS_PD_CR1,
+				      buck457_volt_table),
+	[STPMIC2_BUCK5] = DEFINE_BUCK("buck5", BUCK5, BUCKS_PD_CR2,
+				      buck457_volt_table),
+	[STPMIC2_BUCK6] = DEFINE_BUCK("buck6", BUCK6, BUCKS_PD_CR2,
+				      buck1236_volt_table),
+	[STPMIC2_BUCK7] = DEFINE_BUCK("buck7", BUCK7, BUCKS_PD_CR2,
+				      buck457_volt_table),
+
+	[STPMIC2_REFDDR] = DEFINE_REFDDR("refddr", REFDDR, refddr_volt_table),
+
+	[STPMIC2_LDO1] = DEFINE_LDOx("ldo1", LDO1, ldo1_volt_table),
+	[STPMIC2_LDO2] = DEFINE_LDOx("ldo2", LDO2, ldo235678_volt_table),
+	[STPMIC2_LDO3] = DEFINE_LDOx("ldo3", LDO3, ldo235678_volt_table),
+	[STPMIC2_LDO4] = DEFINE_LDOx("ldo4", LDO4, ldo4_volt_table),
+	[STPMIC2_LDO5] = DEFINE_LDOx("ldo5", LDO5, ldo235678_volt_table),
+	[STPMIC2_LDO6] = DEFINE_LDOx("ldo6", LDO6, ldo235678_volt_table),
+	[STPMIC2_LDO7] = DEFINE_LDOx("ldo7", LDO7, ldo235678_volt_table),
+	[STPMIC2_LDO8] = DEFINE_LDOx("ldo8", LDO8, ldo235678_volt_table),
+
+};
+
+int stpmic2_register_read(struct pmic_handle_s *pmic,
+			  uint8_t register_id, uint8_t *value)
+{
+	int ret = stm32_i2c_mem_read(pmic->i2c_handle,
+				     pmic->i2c_addr,
+				     (uint16_t)register_id,
+				     I2C_MEMADD_SIZE_8BIT, value,
+				     1, I2C_TIMEOUT_MS);
+	if (ret != 0) {
+		ERROR("Failed to read reg:0x%x\n", register_id);
+	}
+
+	return ret;
+}
+
+int stpmic2_register_write(struct pmic_handle_s *pmic,
+			   uint8_t register_id, uint8_t value)
+{
+	uint8_t val = value;
+	int ret = stm32_i2c_mem_write(pmic->i2c_handle,
+				      pmic->i2c_addr,
+				      (uint16_t)register_id,
+				      I2C_MEMADD_SIZE_8BIT, &val,
+				      1, I2C_TIMEOUT_MS);
+	if (ret != 0) {
+		ERROR("Failed to write reg:0x%x\n", register_id);
+	}
+
+	return ret;
+}
+
+int stpmic2_register_update(struct pmic_handle_s *pmic,
+			    uint8_t register_id, uint8_t value, uint8_t mask)
+{
+	int status;
+	uint8_t val = 0U;
+
+	status = stpmic2_register_read(pmic, register_id, &val);
+	if (status != 0) {
+		return status;
+	}
+
+	val = (val & ((uint8_t)~mask)) | (value & mask);
+
+	VERBOSE("REG:0x%x v=0x%x mask=0x%x -> 0x%x\n",
+		register_id, value, mask, val);
+
+	return stpmic2_register_write(pmic, register_id, val);
+}
+
+int stpmic2_regulator_set_state(struct pmic_handle_s *pmic,
+				uint8_t id, bool enable)
+{
+	const struct regul_struct *regul = &regul_table[id];
+
+	if (enable) {
+		return stpmic2_register_update(pmic, regul->en_cr, 1U, 1U);
+	} else {
+		return stpmic2_register_update(pmic, regul->en_cr, 0, 1U);
+	}
+}
+
+int stpmic2_regulator_get_state(struct pmic_handle_s *pmic,
+				uint8_t id, bool *enabled)
+{
+	const struct regul_struct *regul = &regul_table[id];
+	uint8_t val;
+
+	if (stpmic2_register_read(pmic, regul->en_cr, &val) != 0) {
+		return RET_ERROR_GENERIC;
+	}
+
+	*enabled = (val & 1U) == 1U;
+
+	return RET_SUCCESS;
+}
+
+int stpmic2_regulator_levels_mv(struct pmic_handle_s *pmic,
+				uint8_t id, const uint16_t **levels,
+				size_t *levels_count)
+{
+	const struct regul_struct *regul = &regul_table[id];
+
+	if (regul == NULL) {
+		return RET_ERROR_BAD_PARAMETERS;
+	}
+
+	if (levels_count != NULL) {
+		*levels_count = regul->volt_table_size;
+	}
+	if (levels != NULL) {
+		*levels = regul->volt_table;
+	}
+
+	return RET_SUCCESS;
+}
+
+int stpmic2_regulator_get_voltage(struct pmic_handle_s *pmic,
+				  uint8_t id, uint16_t *val)
+{
+	const struct regul_struct *regul = &regul_table[id];
+	uint8_t value = 0U;
+	uint8_t mask;
+
+	if (regul->volt_table_size == 0U) {
+		return RET_ERROR_GENERIC;
+	}
+
+	mask = regul->volt_table_size - 1U;
+	if (mask != 0U) {
+		if (stpmic2_register_read(pmic, regul->volt_cr, &value) != 0) {
+			return RET_ERROR_GENERIC;
+		}
+
+		value = (value >> regul->volt_shift) & mask;
+	}
+
+	if (value > regul->volt_table_size) {
+		return RET_ERROR_GENERIC;
+	}
+
+	*val = regul->volt_table[value];
+
+	return RET_SUCCESS;
+}
+
+static size_t voltage_to_index(const struct regul_struct *regul,
+			       uint16_t millivolts)
+{
+	unsigned int i;
+
+	assert(regul->volt_table);
+	for (i = 0U; i < regul->volt_table_size; i++) {
+		if (regul->volt_table[i] == millivolts) {
+			return i;
+		}
+	}
+
+	return VOLTAGE_INDEX_INVALID;
+}
+
+int stpmic2_regulator_set_voltage(struct pmic_handle_s *pmic,
+				  uint8_t id, uint16_t millivolts)
+{
+	const struct regul_struct *regul = &regul_table[id];
+	size_t index;
+	uint8_t mask;
+
+	if (!regul->volt_table_size) {
+		return RET_SUCCESS;
+	}
+
+	mask = regul->volt_table_size - 1U;
+
+	index = voltage_to_index(regul, millivolts);
+	if (index == VOLTAGE_INDEX_INVALID) {
+		return RET_ERROR_GENERIC;
+	}
+
+	return stpmic2_register_update(pmic, regul->volt_cr,
+				       index << regul->volt_shift,
+				       mask << regul->volt_shift);
+}
+
+/* update both normal and alternate register */
+static int stpmic2_update_en_crs(struct pmic_handle_s *pmic, uint8_t id,
+				 uint8_t value, uint8_t mask)
+{
+	const struct regul_struct *regul = &regul_table[id];
+
+	if (stpmic2_register_update(pmic, regul->en_cr, value, mask) != 0) {
+		return RET_ERROR_GENERIC;
+	}
+
+	if (stpmic2_register_update(pmic, regul->alt_en_cr, value, mask) != 0) {
+		return RET_ERROR_GENERIC;
+	}
+
+	return RET_SUCCESS;
+}
+
+int stpmic2_regulator_get_prop(struct pmic_handle_s *pmic, uint8_t id,
+			       enum stpmic2_prop_id prop)
+{
+	const struct regul_struct *regul = &regul_table[id];
+	uint8_t val;
+
+	VERBOSE("%s: get prop 0x%x\n", regul->name, prop);
+
+	switch (prop) {
+	case STPMIC2_BYPASS:
+		if ((id <= STPMIC2_BUCK7) || (id == STPMIC2_LDO1) ||
+		    (id == STPMIC2_LDO4) || (id == STPMIC2_REFDDR)) {
+			return 0;
+		}
+
+		if (stpmic2_register_read(pmic, regul->en_cr, &val) != 0) {
+			return -EIO;
+		}
+
+		if ((val & LDO_BYPASS) != 0) {
+			return 1;
+		}
+
+		break;
+	default:
+		ERROR("Invalid prop %u\n", prop);
+		panic();
+	}
+
+	return 0;
+}
+
+int stpmic2_regulator_set_prop(struct pmic_handle_s *pmic, uint8_t id,
+			       enum stpmic2_prop_id prop, uint32_t arg)
+{
+	const struct regul_struct *regul = &regul_table[id];
+
+	VERBOSE("%s: set prop 0x%x arg=%u\n", regul->name, prop, arg);
+
+	switch (prop) {
+	case STPMIC2_PULL_DOWN:
+		return stpmic2_register_update(pmic, regul->pd_reg,
+					       regul->pd_val,
+					       regul->pd_val);
+	case STPMIC2_MASK_RESET:
+		if (!regul->msrt_mask) {
+			return RET_ERROR_NOT_SUPPORTED;
+		}
+		/* enable mask reset */
+		return stpmic2_register_update(pmic, regul->msrt_reg,
+					       regul->msrt_mask,
+					       regul->msrt_mask);
+	case STPMIC2_BYPASS:
+		if ((id <= STPMIC2_BUCK7) || (id == STPMIC2_LDO1) ||
+		    (id == STPMIC2_LDO4) || (id == STPMIC2_REFDDR)) {
+			return RET_ERROR_NOT_SUPPORTED;
+		}
+
+		/* clear sink source mode */
+		if ((id == STPMIC2_LDO3) && (arg != 0U)) {
+			if (stpmic2_update_en_crs(pmic, id, 0, LDO3_SNK_SRC) != 0) {
+				return RET_ERROR_GENERIC;
+			}
+		}
+
+		/* enable bypass mode */
+		return stpmic2_update_en_crs(pmic, id,
+					     (arg != 0U) ? LDO_BYPASS : 0,
+					     LDO_BYPASS);
+	case STPMIC2_SINK_SOURCE:
+		if (id != STPMIC2_LDO3) {
+			return RET_ERROR_NOT_SUPPORTED;
+		}
+
+		/* clear bypass mode */
+		if (stpmic2_update_en_crs(pmic, id, 0, LDO_BYPASS) != 0) {
+			return RET_ERROR_GENERIC;
+		}
+
+		return stpmic2_update_en_crs(pmic, id, LDO3_SNK_SRC,
+					     LDO3_SNK_SRC);
+	case STPMIC2_OCP:
+		return stpmic2_register_update(pmic, regul->ocp_reg,
+					       regul->ocp_mask,
+					       regul->ocp_mask);
+	default:
+		ERROR("Invalid prop %u\n", prop);
+		panic();
+	}
+
+	return -EPERM;
+}
+
+#if EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE
+void stpmic2_dump_regulators(struct pmic_handle_s *pmic)
+{
+	size_t i;
+	char const *name;
+
+	for (i = 0U; i < ARRAY_SIZE(regul_table); i++) {
+		uint16_t val;
+		bool state;
+
+		if (!regul_table[i].volt_cr) {
+			continue;
+		}
+
+		stpmic2_regulator_get_voltage(pmic, i, &val);
+		stpmic2_regulator_get_state(pmic, i, &state);
+
+		name = regul_table[i].name;
+
+		VERBOSE("PMIC regul %s: %s, %dmV\n",
+			name, state ? "EN" : "DIS", val);
+	}
+}
+#endif
+
+int stpmic2_get_version(struct pmic_handle_s *pmic, uint8_t *val)
+{
+	return stpmic2_register_read(pmic, VERSION_SR, val);
+}
+
+int stpmic2_get_product_id(struct pmic_handle_s *pmic, uint8_t *val)
+{
+	return stpmic2_register_read(pmic, PRODUCT_ID, val);
+}
diff --git a/drivers/st/regulator/regulator_core.c b/drivers/st/regulator/regulator_core.c
index 2a5d0f7..b369acd 100644
--- a/drivers/st/regulator/regulator_core.c
+++ b/drivers/st/regulator/regulator_core.c
@@ -215,14 +215,18 @@
 
 	VERBOSE("%s: set mvolt\n", rdev->desc->node_name);
 
-	if (rdev->desc->ops->set_voltage == NULL) {
-		return -ENODEV;
-	}
-
 	if ((mvolt < rdev->min_mv) || (mvolt > rdev->max_mv)) {
 		return -EPERM;
 	}
 
+	if (regulator_get_voltage(rdev) == mvolt) {
+		return 0U;
+	}
+
+	if (rdev->desc->ops->set_voltage == NULL) {
+		return -ENODEV;
+	}
+
 	lock_driver(rdev);
 
 	ret = rdev->desc->ops->set_voltage(rdev->desc, mvolt);
@@ -420,6 +424,7 @@
 
 static int parse_properties(const void *fdt, struct rdev *rdev, int node)
 {
+	const fdt32_t *cuint;
 	int ret;
 
 	if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL) {
@@ -430,6 +435,13 @@
 		}
 	}
 
+	cuint = fdt_getprop(fdt, node, "regulator-enable-ramp-delay", NULL);
+	if (cuint != NULL) {
+		rdev->enable_ramp_delay = fdt32_to_cpu(*cuint);
+		VERBOSE("%s: enable_ramp_delay=%u\n", rdev->desc->node_name,
+			rdev->enable_ramp_delay);
+	}
+
 	return 0;
 }
 
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 821f600..93d60ea 100644
--- a/fdts/cca_cot_descriptors.dtsi
+++ b/fdts/cca_cot_descriptors.dtsi
@@ -15,7 +15,7 @@
 		cca_content_cert: cca_content_cert {
 			root-certificate;
 			image-id =<CCA_CONTENT_CERT_ID>;
-			antirollback-counter = <&cca_nv_counter>;
+			antirollback-counter = <&cca_nv_ctr>;
 
 			tb_fw_hash: tb_fw_hash {
 				oid = TRUSTED_BOOT_FW_HASH_OID;
@@ -44,7 +44,7 @@
 			root-certificate;
 			image-id = <CORE_SWD_KEY_CERT_ID>;
 			signing-key = <&swd_rot_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			core_swd_pk: core_swd_pk {
 				oid = CORE_SWD_PK_OID;
@@ -55,7 +55,7 @@
 			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
 			parent = <&core_swd_key_cert>;
 			signing-key = <&core_swd_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_hash: tos_fw_hash {
 				oid = TRUSTED_OS_FW_HASH_OID;
@@ -69,7 +69,7 @@
 			root-certificate;
 			image-id = <PLAT_KEY_CERT_ID>;
 			signing-key = <&prot_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			plat_pk: plat_pk {
 				oid = PLAT_PK_OID;
@@ -80,7 +80,7 @@
 			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
 			parent = <&plat_key_cert>;
 			signing-key = <&plat_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_world_bl_hash: nt_world_bl_hash {
 				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
@@ -95,7 +95,7 @@
 			image-id = <SIP_SP_CONTENT_CERT_ID>;
 			parent = <&core_swd_key_cert>;
 			signing-key = <&core_swd_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			sp_pkg1_hash: sp_pkg1_hash {
 				oid = SP_PKG1_HASH_OID;
@@ -115,7 +115,7 @@
 			image-id = <PLAT_SP_CONTENT_CERT_ID>;
 			parent = <&plat_key_cert>;
 			signing-key = <&plat_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			sp_pkg5_hash: sp_pkg5_hash {
 				oid = SP_PKG5_HASH_OID;
@@ -242,17 +242,17 @@
 	#address-cells = <1>;
 	#size-cells = <0>;
 
-	cca_nv_counter: cca_nv_counter {
+	cca_nv_ctr: cca_nv_ctr {
 		id  = <TRUSTED_NV_CTR_ID>;
 		oid = CCA_FW_NVCOUNTER_OID;
 	};
 
-	trusted_nv_counter: trusted_nv_counter {
+	trusted_nv_ctr: trusted_nv_ctr {
 		id  = <TRUSTED_NV_CTR_ID>;
 		oid = TRUSTED_FW_NVCOUNTER_OID;
 	};
 
-	non_trusted_nv_counter: non_trusted_nv_counter {
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
 		id  = <NON_TRUSTED_NV_CTR_ID>;
 		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
 	};
diff --git a/fdts/dualroot_cot_descriptors.dtsi b/fdts/dualroot_cot_descriptors.dtsi
index 459a1dd..bea7af5 100644
--- a/fdts/dualroot_cot_descriptors.dtsi
+++ b/fdts/dualroot_cot_descriptors.dtsi
@@ -15,7 +15,7 @@
 		trusted_boot_fw_cert: trusted_boot_fw_cert {
 			root-certificate;
 			image-id =<TRUSTED_BOOT_FW_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tb_fw_hash: tb_fw_hash {
 				oid = TRUSTED_BOOT_FW_HASH_OID;
@@ -34,7 +34,7 @@
 		trusted_key_cert: trusted_key_cert {
 			root-certificate;
 			image-id = <TRUSTED_KEY_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			trusted_world_pk: trusted_world_pk {
 				oid = TRUSTED_WORLD_PK_OID;
@@ -45,7 +45,7 @@
 			image-id = <SCP_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			scp_fw_content_pk: scp_fw_content_pk {
 				oid = SCP_FW_CONTENT_CERT_PK_OID;
@@ -56,7 +56,7 @@
 			image-id = <SCP_FW_CONTENT_CERT_ID>;
 			parent = <&scp_fw_key_cert>;
 			signing-key = <&scp_fw_content_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			scp_fw_hash: scp_fw_hash {
 				oid = SCP_FW_HASH_OID;
@@ -67,7 +67,7 @@
 			image-id = <SOC_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 			soc_fw_content_pk: soc_fw_content_pk {
 				oid = SOC_FW_CONTENT_CERT_PK_OID;
 			};
@@ -77,7 +77,7 @@
 			image-id = <SOC_FW_CONTENT_CERT_ID>;
 			parent = <&soc_fw_key_cert>;
 			signing-key = <&soc_fw_content_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			soc_fw_hash: soc_fw_hash {
 				oid = SOC_AP_FW_HASH_OID;
@@ -91,7 +91,7 @@
 			image-id = <TRUSTED_OS_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_content_pk: tos_fw_content_pk {
 				oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID;
@@ -102,7 +102,7 @@
 			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>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_hash: tos_fw_hash {
 				oid = TRUSTED_OS_FW_HASH_OID;
@@ -122,7 +122,7 @@
 			root-certificate;
 			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
 			signing-key = <&prot_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_world_bl_hash: nt_world_bl_hash {
 				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
@@ -137,7 +137,7 @@
 			image-id = <SIP_SP_CONTENT_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			sp_pkg1_hash: sp_pkg1_hash {
 				oid = SP_PKG1_HASH_OID;
@@ -157,7 +157,7 @@
 			root-certificate;
 			image-id = <PLAT_SP_CONTENT_CERT_ID>;
 			signing-key = <&prot_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			sp_pkg5_hash: sp_pkg5_hash {
 				oid = SP_PKG5_HASH_OID;
@@ -296,12 +296,12 @@
 	#address-cells = <1>;
 	#size-cells = <0>;
 
-	trusted_nv_counter: trusted_nv_counter {
+	trusted_nv_ctr: trusted_nv_ctr {
 		id  = <TRUSTED_NV_CTR_ID>;
 		oid = TRUSTED_FW_NVCOUNTER_OID;
 	};
 
-	non_trusted_nv_counter: non_trusted_nv_counter {
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
 		id  = <NON_TRUSTED_NV_CTR_ID>;
 		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
 	};
diff --git a/fdts/rd1ae.dts b/fdts/rd1ae.dts
new file mode 100644
index 0000000..3060b5a
--- /dev/null
+++ b/fdts/rd1ae.dts
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	model = "RD-1 AE";
+	compatible = "arm,rd1ae", "arm,neoverse";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen {
+		stdout-path = &soc_serial0;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu1: cpu@10000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu2: cpu@20000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x20000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu3: cpu@30000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x30000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu4: cpu@40000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x40000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu5: cpu@50000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x50000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu6: cpu@60000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x60000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu7: cpu@70000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x70000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu8: cpu@80000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x80000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu9: cpu@90000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x90000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu10: cpu@a0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xa0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu11: cpu@b0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xb0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu12: cpu@c0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xc0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu13: cpu@d0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xd0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu14: cpu@e0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xe0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu15: cpu@f0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xf0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		/*
+		 * 0x7fc0 0000 - 0x7fff ffff : BL32
+		 * 0x7fbf 0000 - 0x7fbf ffff : FFA_SHARED_MM_BUF
+		 */
+		reg = <0x00000000 0x80000000 0 0x7fbf0000>,
+			  <0x00000080 0x80000000 0 0x80000000>;
+	};
+
+	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>;
+	};
+
+	soc_clk24mhz: clk24mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "refclk24mhz";
+	};
+
+	soc_refclk1mhz: refclk1mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000>;
+		clock-output-names = "refclk1mhz";
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller@30000000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x30000000 0 0x10000>,	// GICD
+				  <0x0 0x301c0000 0 0x8000000>;	// GICR
+			#interrupt-cells = <3>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+			its1: msi-controller@30040000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30040000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its2: msi-controller@30080000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30080000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its3: msi-controller@300c0000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x300c0000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its4: msi-controller@30100000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30100000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its5: msi-controller@30140000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30140000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its6: msi-controller@30180000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30180000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+		};
+
+		soc_serial0: serial@2a400000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x0 0x2a400000 0x0 0x10000>;
+			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&soc_clk24mhz>, <&soc_clk24mhz>;
+			clock-names = "uartclk", "apb_pclk";
+		};
+
+		watchdog@2a440000 {
+			compatible = "arm,sbsa-gwdt";
+			reg = <0x0 0x2a440000 0 0x1000>,
+				  <0x0 0x2a450000 0 0x1000>;
+			interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		rtc@c170000 {
+			compatible = "arm,pl031", "arm,primecell";
+			reg = <0x0 0x0c170000 0x0 0x10000>;
+			interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&soc_clk24mhz>;
+			clock-names = "apb_pclk";
+		};
+
+		virtio-net@c150000 {
+			compatible = "virtio,mmio";
+			reg = <0x0 0xc150000 0x0 0x200>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		virtio-block@c130000 {
+			compatible = "virtio,mmio";
+			reg = <0x0 0xc130000 0x0 0x200>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		virtio-rng@c140000 {
+			compatible = "virtio,mmio";
+			reg = <0x0 0xc140000 0x0 0x200>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pci@4000000000 {
+			#address-cells = <0x03>;
+			#size-cells = <0x02>;
+			compatible = "pci-host-ecam-generic";
+			device_type = "pci";
+			bus-range = <0x00 0x11>;
+			reg = <0x40 0x00 0x00 0x04000000>;
+			ranges = <0x43000000 0x40 0x40000000 0x40 0x40000000 0x10 0x00000000
+				  0x02000000 0x00 0x60000000 0x00 0x60000000 0x00 0x08000000
+				  0x01000000 0x00 0x00 0x00 0x77800000 0x00 0x800000>;
+			msi-map = <0x00 &its1 0x40000 0x10000>;
+			iommu-map = <0x00 &smmu 0x40000 0x10000>;
+			dma-coherent;
+		};
+
+		smmu: iommu@280000000 {
+			compatible = "arm,smmu-v3";
+			reg = <0x2 0x80000000 0x0 0x100000>;
+			dma-coherent;
+			#iommu-cells = <1>;
+			interrupts = <1 210 1>,
+				     <1 211 1>,
+				     <1 212 1>,
+				     <1 213 1>;
+			interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
+			msi-parent = <&its1 0x10000>;
+		};
+
+		sysreg: sysreg@c010000 {
+			compatible = "arm,vexpress-sysreg";
+			reg = <0x0 0xc010000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		fixed_3v3: v2m-3v3@c011000 {
+			compatible = "regulator-fixed";
+			reg = <0x0 0xc011000 0x0 0x1000>;
+			regulator-name = "3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		mmci@c050000 {
+			compatible = "arm,pl180", "arm,primecell";
+			reg = <0x0 0xc050000 0x0 0x1000>;
+			interrupts = <0 0x8B 0x4>,
+				     <0 0x8C 0x4>;
+			cd-gpios = <&sysreg 0 0>;
+			wp-gpios = <&sysreg 1 0>;
+			bus-width = <8>;
+			max-frequency = <12000000>;
+			vmmc-supply = <&fixed_3v3>;
+			clocks = <&soc_clk24mhz>, <&soc_clk24mhz>;
+			clock-names = "mclk", "apb_pclk";
+		};
+
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+		cpu_suspend = <0xc4000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0x84000003>;
+	};
+
+};
diff --git a/fdts/stm32mp1-cot-descriptors.dtsi b/fdts/stm32mp1-cot-descriptors.dtsi
index eb632ff..05326be 100644
--- a/fdts/stm32mp1-cot-descriptors.dtsi
+++ b/fdts/stm32mp1-cot-descriptors.dtsi
@@ -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,7 +15,7 @@
 		stm32mp_cfg_cert: stm32mp_cfg_cert {
 			root-certificate;
 			image-id = <STM32MP_CONFIG_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			hw_config_hash: hw_config_hash {
 				oid = HW_CONFIG_HASH_OID;
@@ -29,7 +29,7 @@
 		trusted_key_cert: trusted_key_cert {
 			root-certificate;
 			image-id = <TRUSTED_KEY_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			trusted_world_pk: trusted_world_pk {
 				oid = TRUSTED_WORLD_PK_OID;
@@ -43,7 +43,7 @@
 			image-id = <TRUSTED_OS_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_content_pk: tos_fw_content_pk {
 				oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID;
@@ -54,7 +54,7 @@
 			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>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_hash: tos_fw_hash {
 				oid = TRUSTED_OS_FW_HASH_OID;
@@ -74,7 +74,7 @@
 			image-id = <NON_TRUSTED_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&non_trusted_world_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_fw_content_pk: nt_fw_content_pk {
 				oid = NON_TRUSTED_FW_CONTENT_CERT_PK_OID;
@@ -85,7 +85,7 @@
 			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
 			parent = <&non_trusted_fw_key_cert>;
 			signing-key = <&nt_fw_content_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_world_bl_hash: nt_world_bl_hash {
 				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
@@ -144,12 +144,12 @@
 	#address-cells = <1>;
 	#size-cells = <0>;
 
-	trusted_nv_counter: trusted_nv_counter {
+	trusted_nv_ctr: trusted_nv_ctr {
 		id  = <TRUSTED_NV_CTR_ID>;
 		oid = TRUSTED_FW_NVCOUNTER_OID;
 	};
 
-	non_trusted_nv_counter: non_trusted_nv_counter {
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
 		id  = <NON_TRUSTED_NV_CTR_ID>;
 		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
 	};
diff --git a/fdts/stm32mp25-bl2.dtsi b/fdts/stm32mp25-bl2.dtsi
index 438a58c..e250e3f 100644
--- a/fdts/stm32mp25-bl2.dtsi
+++ b/fdts/stm32mp25-bl2.dtsi
@@ -1,4 +1,38 @@
 // 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
  */
+
+/ {
+	soc@0 {
+#if !STM32MP_EMMC && !STM32MP_SDMMC
+		rifsc@42080000 {
+			/delete-node/ mmc@48220000;
+			/delete-node/ mmc@48230000;
+		};
+#endif
+	};
+
+	/*
+	 * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in
+	 * network order (big endian)
+	 */
+
+	st-io_policies {
+		fip-handles {
+			compatible = "st,io-fip-handle";
+#if STM32MP_DDR_FIP_IO_STORAGE
+			ddr_fw_uuid = "b11249be-92dd-4b10-867c-2c6a4b47a7fb";
+#endif
+			fw_cfg_uuid = "5807e16a-8459-47be-8ed5-648e8dddab0e";
+			bl31_uuid = "47d4086d-4cfe-9846-9b95-2950cbbd5a00";
+			bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38";
+			bl32_extra1_uuid = "0b70c29b-2a5a-7840-9f65-0a5682738288";
+			bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
+			bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
+			hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
+			tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
+			nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
+		};
+	};
+};
diff --git a/fdts/stm32mp25-ddr.dtsi b/fdts/stm32mp25-ddr.dtsi
new file mode 100644
index 0000000..1fcd13d
--- /dev/null
+++ b/fdts/stm32mp25-ddr.dtsi
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+&ddr{
+	st,mem-name = DDR_MEM_NAME;
+	st,mem-speed = <DDR_MEM_SPEED>;
+	st,mem-size = <(DDR_MEM_SIZE >> 32) (DDR_MEM_SIZE & 0xFFFFFFFF)>;
+
+	st,ctl-reg = <
+		DDR_MSTR
+		DDR_MRCTRL0
+		DDR_MRCTRL1
+		DDR_MRCTRL2
+		DDR_DERATEEN
+		DDR_DERATEINT
+		DDR_DERATECTL
+		DDR_PWRCTL
+		DDR_PWRTMG
+		DDR_HWLPCTL
+		DDR_RFSHCTL0
+		DDR_RFSHCTL1
+		DDR_RFSHCTL3
+		DDR_CRCPARCTL0
+		DDR_CRCPARCTL1
+		DDR_INIT0
+		DDR_INIT1
+		DDR_INIT2
+		DDR_INIT3
+		DDR_INIT4
+		DDR_INIT5
+		DDR_INIT6
+		DDR_INIT7
+		DDR_DIMMCTL
+		DDR_RANKCTL
+		DDR_RANKCTL1
+		DDR_ZQCTL0
+		DDR_ZQCTL1
+		DDR_ZQCTL2
+		DDR_DFITMG0
+		DDR_DFITMG1
+		DDR_DFILPCFG0
+		DDR_DFILPCFG1
+		DDR_DFIUPD0
+		DDR_DFIUPD1
+		DDR_DFIUPD2
+		DDR_DFIMISC
+		DDR_DFITMG2
+		DDR_DFITMG3
+		DDR_DBICTL
+		DDR_DFIPHYMSTR
+		DDR_DBG0
+		DDR_DBG1
+		DDR_DBGCMD
+		DDR_SWCTL
+		DDR_SWCTLSTATIC
+		DDR_POISONCFG
+		DDR_PCCFG
+	>;
+
+	st,ctl-timing = <
+		DDR_RFSHTMG
+		DDR_RFSHTMG1
+		DDR_DRAMTMG0
+		DDR_DRAMTMG1
+		DDR_DRAMTMG2
+		DDR_DRAMTMG3
+		DDR_DRAMTMG4
+		DDR_DRAMTMG5
+		DDR_DRAMTMG6
+		DDR_DRAMTMG7
+		DDR_DRAMTMG8
+		DDR_DRAMTMG9
+		DDR_DRAMTMG10
+		DDR_DRAMTMG11
+		DDR_DRAMTMG12
+		DDR_DRAMTMG13
+		DDR_DRAMTMG14
+		DDR_DRAMTMG15
+		DDR_ODTCFG
+		DDR_ODTMAP
+	>;
+
+	st,ctl-map = <
+		DDR_ADDRMAP0
+		DDR_ADDRMAP1
+		DDR_ADDRMAP2
+		DDR_ADDRMAP3
+		DDR_ADDRMAP4
+		DDR_ADDRMAP5
+		DDR_ADDRMAP6
+		DDR_ADDRMAP7
+		DDR_ADDRMAP8
+		DDR_ADDRMAP9
+		DDR_ADDRMAP10
+		DDR_ADDRMAP11
+	>;
+
+	st,ctl-perf = <
+		DDR_SCHED
+		DDR_SCHED1
+		DDR_PERFHPR1
+		DDR_PERFLPR1
+		DDR_PERFWR1
+		DDR_SCHED3
+		DDR_SCHED4
+		DDR_PCFGR_0
+		DDR_PCFGW_0
+		DDR_PCTRL_0
+		DDR_PCFGQOS0_0
+		DDR_PCFGQOS1_0
+		DDR_PCFGWQOS0_0
+		DDR_PCFGWQOS1_0
+		DDR_PCFGR_1
+		DDR_PCFGW_1
+		DDR_PCTRL_1
+		DDR_PCFGQOS0_1
+		DDR_PCFGQOS1_1
+		DDR_PCFGWQOS0_1
+		DDR_PCFGWQOS1_1
+	>;
+
+	st,phy-basic = <
+		DDR_UIB_DRAMTYPE
+		DDR_UIB_DIMMTYPE
+		DDR_UIB_LP4XMODE
+		DDR_UIB_NUMDBYTE
+		DDR_UIB_NUMACTIVEDBYTEDFI0
+		DDR_UIB_NUMACTIVEDBYTEDFI1
+		DDR_UIB_NUMANIB
+		DDR_UIB_NUMRANK_DFI0
+		DDR_UIB_NUMRANK_DFI1
+		DDR_UIB_DRAMDATAWIDTH
+		DDR_UIB_NUMPSTATES
+		DDR_UIB_FREQUENCY_0
+		DDR_UIB_PLLBYPASS_0
+		DDR_UIB_DFIFREQRATIO_0
+		DDR_UIB_DFI1EXISTS
+		DDR_UIB_TRAIN2D
+		DDR_UIB_HARDMACROVER
+		DDR_UIB_READDBIENABLE_0
+		DDR_UIB_DFIMODE
+	>;
+
+	st,phy-advanced = <
+		DDR_UIA_LP4RXPREAMBLEMODE_0
+		DDR_UIA_LP4POSTAMBLEEXT_0
+		DDR_UIA_D4RXPREAMBLELENGTH_0
+		DDR_UIA_D4TXPREAMBLELENGTH_0
+		DDR_UIA_EXTCALRESVAL
+		DDR_UIA_IS2TTIMING_0
+		DDR_UIA_ODTIMPEDANCE_0
+		DDR_UIA_TXIMPEDANCE_0
+		DDR_UIA_ATXIMPEDANCE
+		DDR_UIA_MEMALERTEN
+		DDR_UIA_MEMALERTPUIMP
+		DDR_UIA_MEMALERTVREFLEVEL
+		DDR_UIA_MEMALERTSYNCBYPASS
+		DDR_UIA_DISDYNADRTRI_0
+		DDR_UIA_PHYMSTRTRAININTERVAL_0
+		DDR_UIA_PHYMSTRMAXREQTOACK_0
+		DDR_UIA_WDQSEXT
+		DDR_UIA_CALINTERVAL
+		DDR_UIA_CALONCE
+		DDR_UIA_LP4RL_0
+		DDR_UIA_LP4WL_0
+		DDR_UIA_LP4WLS_0
+		DDR_UIA_LP4DBIRD_0
+		DDR_UIA_LP4DBIWR_0
+		DDR_UIA_LP4NWR_0
+		DDR_UIA_LP4LOWPOWERDRV
+		DDR_UIA_DRAMBYTESWAP
+		DDR_UIA_RXENBACKOFF
+		DDR_UIA_TRAINSEQUENCECTRL
+		DDR_UIA_SNPSUMCTLOPT
+		DDR_UIA_SNPSUMCTLF0RC5X_0
+		DDR_UIA_TXSLEWRISEDQ_0
+		DDR_UIA_TXSLEWFALLDQ_0
+		DDR_UIA_TXSLEWRISEAC
+		DDR_UIA_TXSLEWFALLAC
+		DDR_UIA_DISABLERETRAINING
+		DDR_UIA_DISABLEPHYUPDATE
+		DDR_UIA_ENABLEHIGHCLKSKEWFIX
+		DDR_UIA_DISABLEUNUSEDADDRLNS
+		DDR_UIA_PHYINITSEQUENCENUM
+		DDR_UIA_ENABLEDFICSPOLARITYFIX
+		DDR_UIA_PHYVREF
+		DDR_UIA_SEQUENCECTRL_0
+	>;
+
+	st,phy-mr = <
+		DDR_UIM_MR0_0
+		DDR_UIM_MR1_0
+		DDR_UIM_MR2_0
+		DDR_UIM_MR3_0
+		DDR_UIM_MR4_0
+		DDR_UIM_MR5_0
+		DDR_UIM_MR6_0
+		DDR_UIM_MR11_0
+		DDR_UIM_MR12_0
+		DDR_UIM_MR13_0
+		DDR_UIM_MR14_0
+		DDR_UIM_MR22_0
+	>;
+
+	st,phy-swizzle = <
+		DDR_UIS_SWIZZLE_0
+		DDR_UIS_SWIZZLE_1
+		DDR_UIS_SWIZZLE_2
+		DDR_UIS_SWIZZLE_3
+		DDR_UIS_SWIZZLE_4
+		DDR_UIS_SWIZZLE_5
+		DDR_UIS_SWIZZLE_6
+		DDR_UIS_SWIZZLE_7
+		DDR_UIS_SWIZZLE_8
+		DDR_UIS_SWIZZLE_9
+		DDR_UIS_SWIZZLE_10
+		DDR_UIS_SWIZZLE_11
+		DDR_UIS_SWIZZLE_12
+		DDR_UIS_SWIZZLE_13
+		DDR_UIS_SWIZZLE_14
+		DDR_UIS_SWIZZLE_15
+		DDR_UIS_SWIZZLE_16
+		DDR_UIS_SWIZZLE_17
+		DDR_UIS_SWIZZLE_18
+		DDR_UIS_SWIZZLE_19
+		DDR_UIS_SWIZZLE_20
+		DDR_UIS_SWIZZLE_21
+		DDR_UIS_SWIZZLE_22
+		DDR_UIS_SWIZZLE_23
+		DDR_UIS_SWIZZLE_24
+		DDR_UIS_SWIZZLE_25
+		DDR_UIS_SWIZZLE_26
+		DDR_UIS_SWIZZLE_27
+		DDR_UIS_SWIZZLE_28
+		DDR_UIS_SWIZZLE_29
+		DDR_UIS_SWIZZLE_30
+		DDR_UIS_SWIZZLE_31
+		DDR_UIS_SWIZZLE_32
+		DDR_UIS_SWIZZLE_33
+		DDR_UIS_SWIZZLE_34
+		DDR_UIS_SWIZZLE_35
+		DDR_UIS_SWIZZLE_36
+		DDR_UIS_SWIZZLE_37
+		DDR_UIS_SWIZZLE_38
+		DDR_UIS_SWIZZLE_39
+		DDR_UIS_SWIZZLE_40
+		DDR_UIS_SWIZZLE_41
+		DDR_UIS_SWIZZLE_42
+		DDR_UIS_SWIZZLE_43
+	>;
+};
diff --git a/fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi b/fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi
new file mode 100644
index 0000000..3d69448
--- /dev/null
+++ b/fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 DDR4 board configuration
+ * DDR4 2x16Gbits 2x16bits 1200MHz
+ *
+ * version      2
+ * package      1        Package selection (14x14 and 18x18)
+ * memclk       1200MHz  (2x DFI clock) + range check
+ * Speed_Bin    Worse    from JEDEC
+ * device_width 16       x16 by default
+ * width        32       32: full width / 16: half width
+ * density      16Gbits  (per 16bit device)
+ * Addressing   RBC      row/bank interleaving
+ * RDBI         No       Read DBI
+ */
+
+#define DDR_MEM_NAME	"DDR4 2x16Gbits 2x16bits 1200MHz"
+#define DDR_MEM_SPEED	1200000
+#define DDR_MEM_SIZE	0x100000000
+
+#define DDR_MSTR 0x01040010
+#define DDR_MRCTRL0 0x00000030
+#define DDR_MRCTRL1 0x00000000
+#define DDR_MRCTRL2 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00000000
+#define DDR_DERATECTL 0x00000000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00130001
+#define DDR_HWLPCTL 0x00000002
+#define DDR_RFSHCTL0 0x00210010
+#define DDR_RFSHCTL1 0x00000000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0092014A
+#define DDR_RFSHTMG1 0x008C0000
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_CRCPARCTL1 0x00001000
+#define DDR_INIT0 0xC0020002
+#define DDR_INIT1 0x00010002
+#define DDR_INIT2 0x00000D00
+#define DDR_INIT3 0x09400103
+#define DDR_INIT4 0x00180000
+#define DDR_INIT5 0x00100004
+#define DDR_INIT6 0x00080460
+#define DDR_INIT7 0x00000C16
+#define DDR_DIMMCTL 0x00000000
+#define DDR_RANKCTL 0x0000066F
+#define DDR_RANKCTL1 0x0000000D
+#define DDR_DRAMTMG0 0x11152815
+#define DDR_DRAMTMG1 0x0004051E
+#define DDR_DRAMTMG2 0x0609060D
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x0904050A
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020005
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x0606100B
+#define DDR_DRAMTMG9 0x0002040A
+#define DDR_DRAMTMG10 0x001C180A
+#define DDR_DRAMTMG11 0x4408021C
+#define DDR_DRAMTMG12 0x0C020010
+#define DDR_DRAMTMG13 0x1C200004
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_DRAMTMG15 0x00000000
+#define DDR_ZQCTL0 0x01000040
+#define DDR_ZQCTL1 0x2000493E
+#define DDR_ZQCTL2 0x00000000
+#define DDR_DFITMG0 0x038F8209
+#define DDR_DFITMG1 0x00080303
+#define DDR_DFILPCFG0 0x07004111
+#define DDR_DFILPCFG1 0x00000000
+#define DDR_DFIUPD0 0xC0300018
+#define DDR_DFIUPD1 0x005700B4
+#define DDR_DFIUPD2 0x80000000
+#define DDR_DFIMISC 0x00000041
+#define DDR_DFITMG2 0x00000F09
+#define DDR_DFITMG3 0x00000000
+#define DDR_DBICTL 0x00000001
+#define DDR_DFIPHYMSTR 0x80000000
+#define DDR_ADDRMAP0 0x0000001F
+#define DDR_ADDRMAP1 0x003F0909
+#define DDR_ADDRMAP2 0x00000700
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x070F0707
+#define DDR_ADDRMAP6 0x07070707
+#define DDR_ADDRMAP7 0x00000F07
+#define DDR_ADDRMAP8 0x00003F01
+#define DDR_ADDRMAP9 0x07070707
+#define DDR_ADDRMAP10 0x07070707
+#define DDR_ADDRMAP11 0x00000007
+#define DDR_ODTCFG 0x06000618
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x80001B00
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x04000200
+#define DDR_PERFLPR1 0x08000080
+#define DDR_PERFWR1 0x08000400
+#define DDR_SCHED3 0x04040208
+#define DDR_SCHED4 0x08400810
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_SWCTL 0x00000000
+#define DDR_SWCTLSTATIC 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000000
+#define DDR_PCFGR_0 0x00704100
+#define DDR_PCFGW_0 0x00004100
+#define DDR_PCTRL_0 0x00000000
+#define DDR_PCFGQOS0_0 0x0021000C
+#define DDR_PCFGQOS1_0 0x01000080
+#define DDR_PCFGWQOS0_0 0x01100C07
+#define DDR_PCFGWQOS1_0 0x04000200
+#define DDR_PCFGR_1 0x00704100
+#define DDR_PCFGW_1 0x00004100
+#define DDR_PCTRL_1 0x00000000
+#define DDR_PCFGQOS0_1 0x00100007
+#define DDR_PCFGQOS1_1 0x01000080
+#define DDR_PCFGWQOS0_1 0x01100C07
+#define DDR_PCFGWQOS1_1 0x04000200
+
+#define DDR_UIB_DRAMTYPE 0x00000000
+#define DDR_UIB_DIMMTYPE 0x00000004
+#define DDR_UIB_LP4XMODE 0x00000000
+#define DDR_UIB_NUMDBYTE 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI0 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI1 0x00000000
+#define DDR_UIB_NUMANIB 0x00000008
+#define DDR_UIB_NUMRANK_DFI0 0x00000001
+#define DDR_UIB_NUMRANK_DFI1 0x00000001
+#define DDR_UIB_DRAMDATAWIDTH 0x00000010
+#define DDR_UIB_NUMPSTATES 0x00000001
+#define DDR_UIB_FREQUENCY_0 0x000004B0
+#define DDR_UIB_PLLBYPASS_0 0x00000000
+#define DDR_UIB_DFIFREQRATIO_0 0x00000001
+#define DDR_UIB_DFI1EXISTS 0x00000001
+#define DDR_UIB_TRAIN2D 0x00000000
+#define DDR_UIB_HARDMACROVER 0x00000003
+#define DDR_UIB_READDBIENABLE_0 0x00000000
+#define DDR_UIB_DFIMODE 0x00000000
+
+#define DDR_UIA_LP4RXPREAMBLEMODE_0 0x00000000
+#define DDR_UIA_LP4POSTAMBLEEXT_0 0x00000000
+#define DDR_UIA_D4RXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_D4TXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_EXTCALRESVAL 0x00000000
+#define DDR_UIA_IS2TTIMING_0 0x00000000
+#define DDR_UIA_ODTIMPEDANCE_0 0x00000035
+#define DDR_UIA_TXIMPEDANCE_0 0x00000028
+#define DDR_UIA_ATXIMPEDANCE 0x00000028
+#define DDR_UIA_MEMALERTEN 0x00000000
+#define DDR_UIA_MEMALERTPUIMP 0x00000000
+#define DDR_UIA_MEMALERTVREFLEVEL 0x00000000
+#define DDR_UIA_MEMALERTSYNCBYPASS 0x00000000
+#define DDR_UIA_DISDYNADRTRI_0 0x00000001
+#define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x00000000
+#define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000000
+#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_CALINTERVAL 0x00000009
+#define DDR_UIA_CALONCE 0x00000000
+#define DDR_UIA_LP4RL_0 0x00000000
+#define DDR_UIA_LP4WL_0 0x00000000
+#define DDR_UIA_LP4WLS_0 0x00000000
+#define DDR_UIA_LP4DBIRD_0 0x00000000
+#define DDR_UIA_LP4DBIWR_0 0x00000000
+#define DDR_UIA_LP4NWR_0 0x00000000
+#define DDR_UIA_LP4LOWPOWERDRV 0x00000000
+#define DDR_UIA_DRAMBYTESWAP 0x00000000
+#define DDR_UIA_RXENBACKOFF 0x00000000
+#define DDR_UIA_TRAINSEQUENCECTRL 0x00000000
+#define DDR_UIA_SNPSUMCTLOPT 0x00000000
+#define DDR_UIA_SNPSUMCTLF0RC5X_0 0x00000000
+#define DDR_UIA_TXSLEWRISEDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWFALLDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWRISEAC 0x0000000F
+#define DDR_UIA_TXSLEWFALLAC 0x0000000F
+#define DDR_UIA_DISABLERETRAINING 0x00000001
+#define DDR_UIA_DISABLEPHYUPDATE 0x00000000
+#define DDR_UIA_ENABLEHIGHCLKSKEWFIX 0x00000000
+#define DDR_UIA_DISABLEUNUSEDADDRLNS 0x00000001
+#define DDR_UIA_PHYINITSEQUENCENUM 0x00000000
+#define DDR_UIA_ENABLEDFICSPOLARITYFIX 0x00000000
+#define DDR_UIA_PHYVREF 0x0000005E
+#define DDR_UIA_SEQUENCECTRL_0 0x0000031F
+
+#define DDR_UIM_MR0_0 0x00000940
+#define DDR_UIM_MR1_0 0x00000103
+#define DDR_UIM_MR2_0 0x00000018
+#define DDR_UIM_MR3_0 0x00000000
+#define DDR_UIM_MR4_0 0x00000008
+#define DDR_UIM_MR5_0 0x00000460
+#define DDR_UIM_MR6_0 0x00000C16
+#define DDR_UIM_MR11_0 0x00000000
+#define DDR_UIM_MR12_0 0x00000000
+#define DDR_UIM_MR13_0 0x00000000
+#define DDR_UIM_MR14_0 0x00000000
+#define DDR_UIM_MR22_0 0x00000000
+
+#define DDR_UIS_SWIZZLE_0 0x0000000C
+#define DDR_UIS_SWIZZLE_1 0x00000005
+#define DDR_UIS_SWIZZLE_2 0x00000013
+#define DDR_UIS_SWIZZLE_3 0x0000001A
+#define DDR_UIS_SWIZZLE_4 0x00000009
+#define DDR_UIS_SWIZZLE_5 0x00000003
+#define DDR_UIS_SWIZZLE_6 0x00000001
+#define DDR_UIS_SWIZZLE_7 0x00000019
+#define DDR_UIS_SWIZZLE_8 0x00000007
+#define DDR_UIS_SWIZZLE_9 0x00000004
+#define DDR_UIS_SWIZZLE_10 0x0000000A
+#define DDR_UIS_SWIZZLE_11 0x0000000D
+#define DDR_UIS_SWIZZLE_12 0x00000014
+#define DDR_UIS_SWIZZLE_13 0x00000000
+#define DDR_UIS_SWIZZLE_14 0x00000000
+#define DDR_UIS_SWIZZLE_15 0x00000000
+#define DDR_UIS_SWIZZLE_16 0x00000000
+#define DDR_UIS_SWIZZLE_17 0x00000000
+#define DDR_UIS_SWIZZLE_18 0x00000006
+#define DDR_UIS_SWIZZLE_19 0x0000000B
+#define DDR_UIS_SWIZZLE_20 0x00000000
+#define DDR_UIS_SWIZZLE_21 0x00000000
+#define DDR_UIS_SWIZZLE_22 0x00000000
+#define DDR_UIS_SWIZZLE_23 0x00000008
+#define DDR_UIS_SWIZZLE_24 0x00000002
+#define DDR_UIS_SWIZZLE_25 0x00000018
+#define DDR_UIS_SWIZZLE_26 0x1A13050C
+#define DDR_UIS_SWIZZLE_27 0x19010309
+#define DDR_UIS_SWIZZLE_28 0x0D0A0407
+#define DDR_UIS_SWIZZLE_29 0x00000014
+#define DDR_UIS_SWIZZLE_30 0x000B0600
+#define DDR_UIS_SWIZZLE_31 0x02080000
+#define DDR_UIS_SWIZZLE_32 0x00000018
+#define DDR_UIS_SWIZZLE_33 0x00000000
+#define DDR_UIS_SWIZZLE_34 0x00000000
+#define DDR_UIS_SWIZZLE_35 0x00000000
+#define DDR_UIS_SWIZZLE_36 0x00000000
+#define DDR_UIS_SWIZZLE_37 0x00000000
+#define DDR_UIS_SWIZZLE_38 0x00000000
+#define DDR_UIS_SWIZZLE_39 0x00000000
+#define DDR_UIS_SWIZZLE_40 0x00000000
+#define DDR_UIS_SWIZZLE_41 0x00000000
+#define DDR_UIS_SWIZZLE_42 0x00000000
+#define DDR_UIS_SWIZZLE_43 0x00000000
+
+#include "stm32mp25-ddr.dtsi"
diff --git a/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi b/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
new file mode 100644
index 0000000..674cb3d
--- /dev/null
+++ b/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 DDR4 board configuration
+ * DDR4 2x8Gbits 2x16bits 1200MHz
+ *
+ * version     1
+ * package     1        Package selection (14x14 and 18x18)
+ * memclk      1200MHz  (2x DFI clock) + range check
+ * Speed_Bin   Worse    from JEDEC
+ * width       32       32: full width / 16: half width
+ * ranks       1        Single or Dual rank
+ * density     8Gbits   (per 16bit device)
+ * Addressing  RBC      row/bank interleaving
+ * RDBI        No       Read DBI
+ */
+
+#define DDR_MEM_NAME	"DDR4 2x8Gbits 2x16bits 1200MHz"
+#define DDR_MEM_SPEED	1200000
+#define DDR_MEM_SIZE	0x80000000
+
+#define DDR_MSTR 0x01040010
+#define DDR_MRCTRL0 0x00000030
+#define DDR_MRCTRL1 0x00000000
+#define DDR_MRCTRL2 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00000000
+#define DDR_DERATECTL 0x00000000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00130001
+#define DDR_HWLPCTL 0x00000002
+#define DDR_RFSHCTL0 0x00210010
+#define DDR_RFSHCTL1 0x00000000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x009200D2
+#define DDR_RFSHTMG1 0x008C0000
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_CRCPARCTL1 0x00001000
+#define DDR_INIT0 0xC0020002
+#define DDR_INIT1 0x00010002
+#define DDR_INIT2 0x00000D00
+#define DDR_INIT3 0x09400103
+#define DDR_INIT4 0x00180000
+#define DDR_INIT5 0x00100004
+#define DDR_INIT6 0x00080460
+#define DDR_INIT7 0x00000C16
+#define DDR_DIMMCTL 0x00000000
+#define DDR_RANKCTL 0x0000066F
+#define DDR_DRAMTMG0 0x11152815
+#define DDR_DRAMTMG1 0x0004051E
+#define DDR_DRAMTMG2 0x0609060D
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x0904050A
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020005
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x04041007
+#define DDR_DRAMTMG9 0x0002040A
+#define DDR_DRAMTMG10 0x001C180A
+#define DDR_DRAMTMG11 0x4408021C
+#define DDR_DRAMTMG12 0x0C020010
+#define DDR_DRAMTMG13 0x1C200004
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_DRAMTMG15 0x00000000
+#define DDR_ZQCTL0 0x01000040
+#define DDR_ZQCTL1 0x2000493E
+#define DDR_ZQCTL2 0x00000000
+#define DDR_DFITMG0 0x038F8209
+#define DDR_DFITMG1 0x00080303
+#define DDR_DFILPCFG0 0x07004111
+#define DDR_DFILPCFG1 0x00000000
+#define DDR_DFIUPD0 0xC0300018
+#define DDR_DFIUPD1 0x005700B4
+#define DDR_DFIUPD2 0x80000000
+#define DDR_DFIMISC 0x00000041
+#define DDR_DFITMG2 0x00000F09
+#define DDR_DFITMG3 0x00000000
+#define DDR_DBICTL 0x00000001
+#define DDR_DFIPHYMSTR 0x80000000
+#define DDR_ADDRMAP0 0x0000001F
+#define DDR_ADDRMAP1 0x003F0909
+#define DDR_ADDRMAP2 0x00000700
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x070F0707
+#define DDR_ADDRMAP6 0x07070707
+#define DDR_ADDRMAP7 0x00000F0F
+#define DDR_ADDRMAP8 0x00003F01
+#define DDR_ADDRMAP9 0x07070707
+#define DDR_ADDRMAP10 0x07070707
+#define DDR_ADDRMAP11 0x00000007
+#define DDR_ODTCFG 0x06000618
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00000F00
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x0F000001
+#define DDR_PERFLPR1 0x0F000080
+#define DDR_PERFWR1 0x01000200
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_SWCTL 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000000
+#define DDR_PCFGR_0 0x00004100
+#define DDR_PCFGW_0 0x00004100
+#define DDR_PCTRL_0 0x00000000
+#define DDR_PCFGQOS0_0 0x00200007
+#define DDR_PCFGQOS1_0 0x01000100
+#define DDR_PCFGWQOS0_0 0x00000C07
+#define DDR_PCFGWQOS1_0 0x02000200
+#define DDR_PCFGR_1 0x00004100
+#define DDR_PCFGW_1 0x00004100
+#define DDR_PCTRL_1 0x00000000
+#define DDR_PCFGQOS0_1 0x00200007
+#define DDR_PCFGQOS1_1 0x01000180
+#define DDR_PCFGWQOS0_1 0x00000C07
+#define DDR_PCFGWQOS1_1 0x04000400
+
+#define DDR_UIB_DRAMTYPE 0x00000000
+#define DDR_UIB_DIMMTYPE 0x00000004
+#define DDR_UIB_LP4XMODE 0x00000000
+#define DDR_UIB_NUMDBYTE 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI0 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI1 0x00000000
+#define DDR_UIB_NUMANIB 0x00000008
+#define DDR_UIB_NUMRANK_DFI0 0x00000001
+#define DDR_UIB_NUMRANK_DFI1 0x00000001
+#define DDR_UIB_DRAMDATAWIDTH 0x00000010
+#define DDR_UIB_NUMPSTATES 0x00000001
+#define DDR_UIB_FREQUENCY_0 0x000004B0
+#define DDR_UIB_PLLBYPASS_0 0x00000000
+#define DDR_UIB_DFIFREQRATIO_0 0x00000001
+#define DDR_UIB_DFI1EXISTS 0x00000001
+#define DDR_UIB_TRAIN2D 0x00000000
+#define DDR_UIB_HARDMACROVER 0x00000003
+#define DDR_UIB_READDBIENABLE_0 0x00000000
+#define DDR_UIB_DFIMODE 0x00000000
+
+#define DDR_UIA_LP4RXPREAMBLEMODE_0 0x00000000
+#define DDR_UIA_LP4POSTAMBLEEXT_0 0x00000000
+#define DDR_UIA_D4RXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_D4TXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_EXTCALRESVAL 0x00000000
+#define DDR_UIA_IS2TTIMING_0 0x00000000
+#define DDR_UIA_ODTIMPEDANCE_0 0x00000035
+#define DDR_UIA_TXIMPEDANCE_0 0x00000028
+#define DDR_UIA_ATXIMPEDANCE 0x00000028
+#define DDR_UIA_MEMALERTEN 0x00000000
+#define DDR_UIA_MEMALERTPUIMP 0x00000000
+#define DDR_UIA_MEMALERTVREFLEVEL 0x00000000
+#define DDR_UIA_MEMALERTSYNCBYPASS 0x00000000
+#define DDR_UIA_DISDYNADRTRI_0 0x00000001
+#define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x00000000
+#define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000000
+#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_CALINTERVAL 0x00000009
+#define DDR_UIA_CALONCE 0x00000000
+#define DDR_UIA_LP4RL_0 0x00000000
+#define DDR_UIA_LP4WL_0 0x00000000
+#define DDR_UIA_LP4WLS_0 0x00000000
+#define DDR_UIA_LP4DBIRD_0 0x00000000
+#define DDR_UIA_LP4DBIWR_0 0x00000000
+#define DDR_UIA_LP4NWR_0 0x00000000
+#define DDR_UIA_LP4LOWPOWERDRV 0x00000000
+#define DDR_UIA_DRAMBYTESWAP 0x00000000
+#define DDR_UIA_RXENBACKOFF 0x00000000
+#define DDR_UIA_TRAINSEQUENCECTRL 0x00000000
+#define DDR_UIA_SNPSUMCTLOPT 0x00000000
+#define DDR_UIA_SNPSUMCTLF0RC5X_0 0x00000000
+#define DDR_UIA_TXSLEWRISEDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWFALLDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWRISEAC 0x0000000F
+#define DDR_UIA_TXSLEWFALLAC 0x0000000F
+#define DDR_UIA_DISABLERETRAINING 0x00000001
+#define DDR_UIA_DISABLEPHYUPDATE 0x00000000
+#define DDR_UIA_ENABLEHIGHCLKSKEWFIX 0x00000000
+#define DDR_UIA_DISABLEUNUSEDADDRLNS 0x00000001
+#define DDR_UIA_PHYINITSEQUENCENUM 0x00000000
+#define DDR_UIA_ENABLEDFICSPOLARITYFIX 0x00000000
+#define DDR_UIA_PHYVREF 0x0000005E
+#define DDR_UIA_SEQUENCECTRL_0 0x0000031F
+
+#define DDR_UIM_MR0_0 0x00000940
+#define DDR_UIM_MR1_0 0x00000103
+#define DDR_UIM_MR2_0 0x00000018
+#define DDR_UIM_MR3_0 0x00000000
+#define DDR_UIM_MR4_0 0x00000008
+#define DDR_UIM_MR5_0 0x00000460
+#define DDR_UIM_MR6_0 0x00000C16
+#define DDR_UIM_MR11_0 0x00000000
+#define DDR_UIM_MR12_0 0x00000000
+#define DDR_UIM_MR13_0 0x00000000
+#define DDR_UIM_MR14_0 0x00000000
+#define DDR_UIM_MR22_0 0x00000000
+
+#define DDR_UIS_SWIZZLE_0 0x0000000C
+#define DDR_UIS_SWIZZLE_1 0x00000005
+#define DDR_UIS_SWIZZLE_2 0x00000013
+#define DDR_UIS_SWIZZLE_3 0x0000001A
+#define DDR_UIS_SWIZZLE_4 0x00000009
+#define DDR_UIS_SWIZZLE_5 0x00000003
+#define DDR_UIS_SWIZZLE_6 0x00000001
+#define DDR_UIS_SWIZZLE_7 0x00000019
+#define DDR_UIS_SWIZZLE_8 0x00000007
+#define DDR_UIS_SWIZZLE_9 0x00000004
+#define DDR_UIS_SWIZZLE_10 0x0000000A
+#define DDR_UIS_SWIZZLE_11 0x0000000D
+#define DDR_UIS_SWIZZLE_12 0x00000014
+#define DDR_UIS_SWIZZLE_13 0x00000000
+#define DDR_UIS_SWIZZLE_14 0x00000000
+#define DDR_UIS_SWIZZLE_15 0x00000000
+#define DDR_UIS_SWIZZLE_16 0x00000000
+#define DDR_UIS_SWIZZLE_17 0x00000000
+#define DDR_UIS_SWIZZLE_18 0x00000006
+#define DDR_UIS_SWIZZLE_19 0x0000000B
+#define DDR_UIS_SWIZZLE_20 0x00000000
+#define DDR_UIS_SWIZZLE_21 0x00000000
+#define DDR_UIS_SWIZZLE_22 0x00000000
+#define DDR_UIS_SWIZZLE_23 0x00000008
+#define DDR_UIS_SWIZZLE_24 0x00000002
+#define DDR_UIS_SWIZZLE_25 0x00000018
+#define DDR_UIS_SWIZZLE_26 0x1A13050C
+#define DDR_UIS_SWIZZLE_27 0x19010309
+#define DDR_UIS_SWIZZLE_28 0x0D0A0407
+#define DDR_UIS_SWIZZLE_29 0x00000014
+#define DDR_UIS_SWIZZLE_30 0x000B0600
+#define DDR_UIS_SWIZZLE_31 0x02080000
+#define DDR_UIS_SWIZZLE_32 0x00000018
+#define DDR_UIS_SWIZZLE_33 0x00000000
+#define DDR_UIS_SWIZZLE_34 0x00000000
+#define DDR_UIS_SWIZZLE_35 0x00000000
+#define DDR_UIS_SWIZZLE_36 0x00000000
+#define DDR_UIS_SWIZZLE_37 0x00000000
+#define DDR_UIS_SWIZZLE_38 0x00000000
+#define DDR_UIS_SWIZZLE_39 0x00000000
+#define DDR_UIS_SWIZZLE_40 0x00000000
+#define DDR_UIS_SWIZZLE_41 0x00000000
+#define DDR_UIS_SWIZZLE_42 0x00000000
+#define DDR_UIS_SWIZZLE_43 0x00000000
+
+#include "stm32mp25-ddr.dtsi"
diff --git a/fdts/stm32mp25-fw-config.dtsi b/fdts/stm32mp25-fw-config.dtsi
new file mode 100644
index 0000000..102980d
--- /dev/null
+++ b/fdts/stm32mp25-fw-config.dtsi
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+#include <platform_def.h>
+
+/dts-v1/;
+
+/ {
+	dtb-registry {
+		compatible = "fconf,dyn_cfg-dtb_registry";
+
+		hw-config {
+			load-address = <0x0 STM32MP_HW_CONFIG_BASE>;
+			max-size = <STM32MP_HW_CONFIG_MAX_SIZE>;
+			id = <HW_CONFIG_ID>;
+		};
+
+		nt_fw {
+			load-address = <0x0 STM32MP_BL33_BASE>;
+			max-size = <STM32MP_BL33_MAX_SIZE>;
+			id = <BL33_IMAGE_ID>;
+		};
+
+		soc_fw {
+			load-address = <0x0 STM32MP_SYSRAM_BASE>;
+			max-size = <STM32MP_BL31_SIZE>;
+			id = <BL31_IMAGE_ID>;
+		};
+
+		tos_fw {
+			id = <BL32_IMAGE_ID>;
+		};
+	};
+};
diff --git a/fdts/stm32mp25-pinctrl.dtsi b/fdts/stm32mp25-pinctrl.dtsi
index 05876a3..a22c823 100644
--- a/fdts/stm32mp25-pinctrl.dtsi
+++ b/fdts/stm32mp25-pinctrl.dtsi
@@ -1,12 +1,76 @@
 // 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: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
 
 &pinctrl {
 	/omit-if-no-ref/
+	i2c7_pins_a: i2c7-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('D', 15, AF10)>, /* I2C7_SCL */
+				 <STM32_PINMUX('D', 14, AF10)>; /* I2C7_SDA */
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	/omit-if-no-ref/
+	sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
+				 <STM32_PINMUX('E', 5, AF10)>, /* SDMMC1_D1 */
+				 <STM32_PINMUX('E', 0, AF10)>, /* SDMMC1_D2 */
+				 <STM32_PINMUX('E', 1, AF10)>, /* SDMMC1_D3 */
+				 <STM32_PINMUX('E', 2, AF10)>; /* SDMMC1_CMD */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC1_CK */
+			slew-rate = <3>;
+			drive-push-pull;
+			bias-disable;
+		};
+	};
+
+	/omit-if-no-ref/
+	sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('E', 13, AF12)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('E', 11, AF12)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('E', 8, AF12)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('E', 12, AF12)>, /* SDMMC2_D3 */
+				 <STM32_PINMUX('E', 15, AF12)>; /* SDMMC2_CMD */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 14, AF12)>; /* SDMMC2_CK */
+			slew-rate = <3>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+	};
+
+	/omit-if-no-ref/
+	sdmmc2_d47_pins_a: sdmmc2-d47-0 {
+		pins {
+			pinmux = <STM32_PINMUX('E', 10, AF12)>, /* SDMMC2_D4 */
+				 <STM32_PINMUX('E', 9, AF12)>, /* SDMMC2_D5 */
+				 <STM32_PINMUX('E', 6, AF12)>, /* SDMMC2_D6 */
+				 <STM32_PINMUX('E', 7, AF12)>; /* SDMMC2_D7 */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+	};
+
+	/omit-if-no-ref/
 	usart2_pins_a: usart2-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('A', 4, AF6)>; /* USART2_TX */
diff --git a/fdts/stm32mp251.dtsi b/fdts/stm32mp251.dtsi
index 6e262bb..c2c2764 100644
--- a/fdts/stm32mp251.dtsi
+++ b/fdts/stm32mp251.dtsi
@@ -97,6 +97,160 @@
 				resets = <&rcc USART2_R>;
 				status = "disabled";
 			};
+
+			usart3: serial@400f0000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x400f0000 0x400>;
+				clocks = <&rcc CK_KER_USART3>;
+				resets = <&rcc USART3_R>;
+				status = "disabled";
+			};
+
+			uart4: serial@40100000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40100000 0x400>;
+				clocks = <&rcc CK_KER_UART4>;
+				resets = <&rcc UART4_R>;
+				status = "disabled";
+			};
+
+			uart5: serial@40110000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40110000 0x400>;
+				clocks = <&rcc CK_KER_UART5>;
+				resets = <&rcc UART5_R>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@40120000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40120000 0x400>;
+				clocks = <&rcc CK_KER_I2C1>;
+				resets = <&rcc I2C1_R>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@40130000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40130000 0x400>;
+				clocks = <&rcc CK_KER_I2C2>;
+				resets = <&rcc I2C2_R>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@40140000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40140000 0x400>;
+				clocks = <&rcc CK_KER_I2C3>;
+				resets = <&rcc I2C3_R>;
+				status = "disabled";
+			};
+
+			i2c4: i2c@40150000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40150000 0x400>;
+				clocks = <&rcc CK_KER_I2C4>;
+				resets = <&rcc I2C4_R>;
+				status = "disabled";
+			};
+
+			i2c5: i2c@40160000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40160000 0x400>;
+				clocks = <&rcc CK_KER_I2C5>;
+				resets = <&rcc I2C5_R>;
+				status = "disabled";
+			};
+
+			i2c6: i2c@40170000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40170000 0x400>;
+				clocks = <&rcc CK_KER_I2C6>;
+				resets = <&rcc I2C6_R>;
+				status = "disabled";
+			};
+
+			i2c7: i2c@40180000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40180000 0x400>;
+				clocks = <&rcc CK_KER_I2C7>;
+				resets = <&rcc I2C7_R>;
+				status = "disabled";
+			};
+
+			usart6: serial@40220000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40220000 0x400>;
+				clocks = <&rcc CK_KER_USART6>;
+				resets = <&rcc USART6_R>;
+				status = "disabled";
+			};
+
+			uart9: serial@402c0000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x402c0000 0x400>;
+				clocks = <&rcc CK_KER_UART9>;
+				resets = <&rcc UART9_R>;
+				status = "disabled";
+			};
+
+			usart1: serial@40330000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40330000 0x400>;
+				clocks = <&rcc CK_KER_USART1>;
+				resets = <&rcc USART1_R>;
+				status = "disabled";
+			};
+
+			uart7: serial@40370000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40370000 0x400>;
+				clocks = <&rcc CK_KER_UART7>;
+				resets = <&rcc UART7_R>;
+				status = "disabled";
+			};
+
+			uart8: serial@40380000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40380000 0x400>;
+				clocks = <&rcc CK_KER_UART8>;
+				resets = <&rcc UART8_R>;
+				status = "disabled";
+			};
+
+			i2c8: i2c@46040000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x46040000 0x400>;
+				clocks = <&rcc CK_KER_I2C8>;
+				resets = <&rcc I2C8_R>;
+				status = "disabled";
+			};
+
+			sdmmc1: mmc@48220000 {
+				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
+				arm,primecell-periphid = <0x00353180>;
+				reg = <0x48220000 0x400>, <0x44230400 0x8>;
+				clocks = <&rcc CK_KER_SDMMC1>;
+				clock-names = "apb_pclk";
+				resets = <&rcc SDMMC1_R>;
+				cap-sd-highspeed;
+				cap-mmc-highspeed;
+				max-frequency = <120000000>;
+				status = "disabled";
+			};
+
+			sdmmc2: mmc@48230000 {
+				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
+				arm,primecell-periphid = <0x00353180>;
+				reg = <0x48230000 0x400>, <0x44230800 0x8>;
+				clocks = <&rcc CK_KER_SDMMC2>;
+				clock-names = "apb_pclk";
+				resets = <&rcc SDMMC2_R>;
+				cap-sd-highspeed;
+				cap-mmc-highspeed;
+				max-frequency = <120000000>;
+				status = "disabled";
+			};
 		};
 
 		bsec: efuse@44000000 {
@@ -120,6 +274,9 @@
 			nand2_otp: otp20@50 {
 				reg = <0x50 0x4>;
 			};
+			rev_otp@198 {
+				reg = <0x198 0x4>;
+			};
 			package_otp: package-otp@1e8 {
 				reg = <0x1e8 0x1>;
 			};
@@ -171,12 +328,18 @@
 			reg = <0x44230000 0x10000>;
 		};
 
+		ddr: ddr@48040000 {
+			compatible = "st,stm32mp2-ddr";
+			reg = <0x48040000 0x10000>,
+			      <0x48c00000 0x400000>;
+			status = "okay";
+		};
+
 		pinctrl: pinctrl@44240000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "st,stm32mp257-pinctrl";
 			ranges = <0 0x44240000 0xa0400>;
-			pins-are-numbered;
 
 			gpioa: gpio@44240000 {
 				gpio-controller;
@@ -305,7 +468,6 @@
 			#size-cells = <1>;
 			compatible = "st,stm32mp257-z-pinctrl";
 			ranges = <0 0x46200000 0x400>;
-			pins-are-numbered;
 
 			gpioz: gpio@46200000 {
 				gpio-controller;
diff --git a/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
new file mode 100644
index 0000000..e41c6b9
--- /dev/null
+++ b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2024 - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 tf-a firmware config
+ * Project : open
+ * Generated by XLmx tool version 2.2 - 2/27/2024 11:46:17 AM
+ */
+
+/ {
+	dtb-registry {
+		tos_fw {
+			load-address = <0x0 0x82000000>;
+			max-size = <0x2000000>;
+		};
+	};
+};
diff --git a/fdts/stm32mp257f-ev1-ca35tdcid-rcc.dtsi b/fdts/stm32mp257f-ev1-ca35tdcid-rcc.dtsi
new file mode 100644
index 0000000..3e84df5
--- /dev/null
+++ b/fdts/stm32mp257f-ev1-ca35tdcid-rcc.dtsi
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2024 - All Rights Reserved
+ * Author: Loic Pallardy loic.pallardy@foss.st.com for STMicroelectronics.
+ */
+
+/*
+ * STM32MP25 Clock tree device tree configuration
+ * Project : open
+ * Generated by XLmx tool version 2.2 - 2/27/2024 11:46:16 AM
+ */
+
+&clk_hse {
+	clock-frequency = <40000000>;
+};
+
+&clk_hsi {
+	clock-frequency = <64000000>;
+};
+
+&clk_lse {
+	clock-frequency = <32768>;
+};
+
+&clk_lsi {
+	clock-frequency = <32000>;
+};
+
+&clk_msi {
+	clock-frequency = <16000000>;
+};
+
+&rcc {
+	st,busclk = <
+		DIV_CFG(DIV_LSMCU, 1)
+		DIV_CFG(DIV_APB1, 0)
+		DIV_CFG(DIV_APB2, 0)
+		DIV_CFG(DIV_APB3, 0)
+		DIV_CFG(DIV_APB4, 0)
+		DIV_CFG(DIV_APBDBG, 0)
+	>;
+
+	st,flexgen = <
+		FLEXGEN_CFG(0, XBAR_SRC_PLL4, 0, 2)
+		FLEXGEN_CFG(1, XBAR_SRC_PLL4, 0, 5)
+		FLEXGEN_CFG(2, XBAR_SRC_PLL4, 0, 1)
+		FLEXGEN_CFG(4, XBAR_SRC_PLL4, 0, 3)
+		FLEXGEN_CFG(5, XBAR_SRC_PLL4, 0, 2)
+		FLEXGEN_CFG(8, XBAR_SRC_HSI_KER, 0, 0)
+		FLEXGEN_CFG(48, XBAR_SRC_PLL5, 0, 3)
+		FLEXGEN_CFG(51, XBAR_SRC_PLL4, 0, 5)
+		FLEXGEN_CFG(52, XBAR_SRC_PLL4, 0, 5)
+		FLEXGEN_CFG(58, XBAR_SRC_HSE, 0, 1)
+		FLEXGEN_CFG(63, XBAR_SRC_PLL4, 0, 2)
+	>;
+
+	st,kerclk = <
+		MUX_CFG(MUX_USB2PHY1, MUX_USB2PHY1_FLEX57)
+		MUX_CFG(MUX_USB2PHY2, MUX_USB2PHY2_FLEX58)
+	>;
+
+	pll1: st,pll-1 {
+		st,pll = <&pll1_cfg_1200Mhz>;
+
+		pll1_cfg_1200Mhz: pll1-cfg-1200Mhz {
+			cfg = <30 1 1 1>;
+			src = <MUX_CFG(MUX_MUXSEL5, MUXSEL_HSE)>;
+		};
+	};
+
+	pll2: st,pll-2 {
+		st,pll = <&pll2_cfg_600Mhz>;
+
+		pll2_cfg_600Mhz: pll2-cfg-600Mhz {
+			cfg = <30 1 1 2>;
+			src = <MUX_CFG(MUX_MUXSEL6, MUXSEL_HSE)>;
+		};
+	};
+
+	pll4: st,pll-4 {
+		st,pll = <&pll4_cfg_1200Mhz>;
+
+		pll4_cfg_1200Mhz: pll4-cfg-1200Mhz {
+			cfg = <30 1 1 1>;
+			src = <MUX_CFG(MUX_MUXSEL0, MUXSEL_HSE)>;
+		};
+	};
+
+	pll5: st,pll-5 {
+		st,pll = <&pll5_cfg_532Mhz>;
+
+		pll5_cfg_532Mhz: pll5-cfg-532Mhz {
+			cfg = <133 5 1 2>;
+			src = <MUX_CFG(MUX_MUXSEL1, MUXSEL_HSE)>;
+		};
+	};
+};
diff --git a/fdts/stm32mp257f-ev1-fw-config.dts b/fdts/stm32mp257f-ev1-fw-config.dts
new file mode 100644
index 0000000..9424f49
--- /dev/null
+++ b/fdts/stm32mp257f-ev1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+#include "stm32mp25-fw-config.dtsi"
+#include "stm32mp257f-ev1-ca35tdcid-fw-config.dtsi"
diff --git a/fdts/stm32mp257f-ev1.dts b/fdts/stm32mp257f-ev1.dts
index 09e83d8..5d5e35d 100644
--- a/fdts/stm32mp257f-ev1.dts
+++ b/fdts/stm32mp257f-ev1.dts
@@ -6,8 +6,11 @@
 
 /dts-v1/;
 
+#include <dt-bindings/clock/stm32mp25-clksrc.h>
 #include "stm32mp257.dtsi"
 #include "stm32mp25xf.dtsi"
+#include "stm32mp257f-ev1-ca35tdcid-rcc.dtsi"
+#include "stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi"
 #include "stm32mp25-pinctrl.dtsi"
 #include "stm32mp25xxai-pinctrl.dtsi"
 
@@ -35,6 +38,157 @@
 	};
 };
 
+&ddr {
+	vdd-supply = <&vdd_ddr>;
+	vtt-supply = <&vtt_ddr>;
+	vpp-supply = <&vpp_ddr>;
+	vref-supply = <&vref_ddr>;
+};
+
+&i2c7 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c7_pins_a>;
+	i2c-scl-rising-time-ns = <185>;
+	i2c-scl-falling-time-ns = <20>;
+	clock-frequency = <400000>;
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	pmic2: stpmic@33 {
+		compatible = "st,stpmic2";
+		reg = <0x33>;
+		status = "okay";
+
+		regulators {
+			compatible = "st,stpmic2-regulators";
+
+			vddcpu: buck1 {
+				regulator-name = "vddcpu";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <910000>;
+				regulator-always-on;
+			};
+			vddcore: buck2 {
+				regulator-name = "vddcore";
+				regulator-min-microvolt = <820000>;
+				regulator-max-microvolt = <820000>;
+				regulator-always-on;
+			};
+			vddgpu: buck3 {
+				regulator-name = "vddgpu";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <900000>;
+				regulator-always-on;
+			};
+			vddio_pmic: buck4 {
+				regulator-name = "vddio_pmic";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			v1v8: buck5 {
+				regulator-name = "v1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+			vdd_ddr: buck6 {
+				regulator-name = "vdd_ddr";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+			};
+			v3v3: buck7 {
+				regulator-name = "v3v3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vdda1v8_aon: ldo1 {
+				regulator-name = "vdda1v8_aon";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+			vdd_emmc: ldo2 {
+				regulator-name = "vdd_emmc";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vtt_ddr: ldo3 {
+				regulator-name = "vtt_ddr";
+				st,regulator-sink-source;
+			};
+			vdd3v3_usb: ldo4 {
+				regulator-name = "vdd3v3_usb";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vpp_ddr: ldo5 {
+				regulator-name = "vpp_ddr";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-enable-ramp-delay = <1000>;
+			};
+			vdd_sdcard: ldo7 {
+				regulator-name = "vdd_sdcard";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vddio_sdcard: ldo8 {
+				regulator-name = "vddio_sdcard";
+				st,regulator-bypass-microvolt = <3300000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vref_ddr: refddr {
+				regulator-name = "vref_ddr";
+			};
+		};
+	};
+};
+
+&pwr {
+	vddio1: vddio1 {
+		vddio1-supply = <&vddio_sdcard>;
+	};
+	vddio2: vddio2 {
+		vddio2-supply = <&v1v8>;
+	};
+	vddio3: vddio3 {
+		vddio3-supply = <&vddio_pmic>;
+	};
+	vddio4: vddio4 {
+		vddio4-supply = <&vddio_pmic>;
+	};
+	vddio: vddio {
+		vdd-supply = <&vddio_pmic>;
+	};
+};
+
+&sdmmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc1_b4_pins_a>;
+	st,neg-edge;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&sdmmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	st,neg-edge;
+	bus-width = <8>;
+	status = "okay";
+};
+
 &usart2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usart2_pins_a>;
diff --git a/fdts/tbbr_cot_descriptors.dtsi b/fdts/tbbr_cot_descriptors.dtsi
index d11e2be..253297f 100644
--- a/fdts/tbbr_cot_descriptors.dtsi
+++ b/fdts/tbbr_cot_descriptors.dtsi
@@ -4,7 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#if USE_TBBR_DEFS
 #include <tools_share/tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+
 #include <common/tbbr/tbbr_img_def.h>
 #include <common/nv_cntr_ids.h>
 
@@ -15,7 +20,7 @@
 		trusted_boot_fw_cert: trusted_boot_fw_cert {
 			root-certificate;
 			image-id =<TRUSTED_BOOT_FW_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tb_fw_hash: tb_fw_hash {
 				oid = TRUSTED_BOOT_FW_HASH_OID;
@@ -34,7 +39,7 @@
 		trusted_key_cert: trusted_key_cert {
 			root-certificate;
 			image-id = <TRUSTED_KEY_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			trusted_world_pk: trusted_world_pk {
 				oid = TRUSTED_WORLD_PK_OID;
@@ -48,7 +53,7 @@
 			image-id = <SCP_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			scp_fw_content_pk: scp_fw_content_pk {
 				oid = SCP_FW_CONTENT_CERT_PK_OID;
@@ -59,7 +64,7 @@
 			image-id = <SCP_FW_CONTENT_CERT_ID>;
 			parent = <&scp_fw_key_cert>;
 			signing-key = <&scp_fw_content_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			scp_fw_hash: scp_fw_hash {
 				oid = SCP_FW_HASH_OID;
@@ -70,7 +75,7 @@
 			image-id = <SOC_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 			soc_fw_content_pk: soc_fw_content_pk {
 				oid = SOC_FW_CONTENT_CERT_PK_OID;
 			};
@@ -80,7 +85,7 @@
 			image-id = <SOC_FW_CONTENT_CERT_ID>;
 			parent = <&soc_fw_key_cert>;
 			signing-key = <&soc_fw_content_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			soc_fw_hash: soc_fw_hash {
 				oid = SOC_AP_FW_HASH_OID;
@@ -94,7 +99,7 @@
 			image-id = <TRUSTED_OS_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_content_pk: tos_fw_content_pk {
 				oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID;
@@ -105,7 +110,7 @@
 			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>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_hash: tos_fw_hash {
 				oid = TRUSTED_OS_FW_HASH_OID;
@@ -125,7 +130,7 @@
 			image-id = <NON_TRUSTED_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&non_trusted_world_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_fw_content_pk: nt_fw_content_pk {
 				oid = NON_TRUSTED_FW_CONTENT_CERT_PK_OID;
@@ -136,7 +141,7 @@
 			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
 			parent = <&non_trusted_fw_key_cert>;
 			signing-key = <&nt_fw_content_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_world_bl_hash: nt_world_bl_hash {
 				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
@@ -151,7 +156,7 @@
 			image-id = <SIP_SP_CONTENT_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			sp_pkg1_hash: sp_pkg1_hash {
 				oid = SP_PKG1_HASH_OID;
@@ -190,6 +195,12 @@
 			hash = <&hw_config_hash>;
 		};
 
+		fw_config {
+			image-id = <FW_CONFIG_ID>;
+			parent = <&trusted_boot_fw_cert>;
+			hash = <&fw_config_hash>;
+		};
+
 		scp_bl2_image {
 			image-id = <SCP_BL2_IMAGE_ID>;
 			parent = <&scp_fw_content_cert>;
@@ -302,12 +313,12 @@
 	#address-cells = <1>;
 	#size-cells = <0>;
 
-	trusted_nv_counter: trusted_nv_counter {
+	trusted_nv_ctr: trusted_nv_ctr {
 		id  = <TRUSTED_NV_CTR_ID>;
 		oid = TRUSTED_FW_NVCOUNTER_OID;
 	};
 
-	non_trusted_nv_counter: non_trusted_nv_counter {
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
 		id  = <NON_TRUSTED_NV_CTR_ID>;
 		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
 	};
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
index 2e03be2..735d429 100644
--- a/fdts/tc-base.dtsi
+++ b/fdts/tc-base.dtsi
@@ -247,10 +247,6 @@
 			reg = <0x0 TC_NS_OPTEE_BASE 0x0 TC_NS_OPTEE_SIZE>;
 		};
 
-		fwu_mm {
-			reg = <0x0 TC_NS_FWU_BASE 0x0 TC_NS_FWU_SIZE>;
-			no-map;
-		};
 	};
 
 	memory {
@@ -265,9 +261,22 @@
 		method = "smc";
 	};
 
+	cpu-pmu-little {
+		compatible = LIT_CPU_PMU_COMPATIBLE;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_little>;
+		status = "okay";
+	};
+
-	cpu-pmu {
-		compatible = "arm,armv8-pmuv3";
-		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+	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 {
@@ -290,7 +299,7 @@
 		clocks = <&soc_refclk>;
 		clock-names = "apb_pclk";
 		#mbox-cells = <MHU_MBOX_CELLS>;
-		interrupts = <GIC_SPI MHU_RX_INT_NUM IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI MHU_RX_INT_NUM IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = MHU_RX_INT_NAME;
 	};
 
@@ -332,23 +341,35 @@
 	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 {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
@@ -374,7 +395,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";
@@ -412,9 +433,9 @@
 
 	};
 
-	ethernet: ethernet@18000000 {
-		reg = <0x0 0x18000000 0x0 0x10000>;
-		interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+	ethernet: ethernet@ETHERNET_ADDR {
+		reg = <0x0 ADDRESSIFY(ETHERNET_ADDR) 0x0 0x10000>;
+		interrupts = <GIC_SPI ETHERNET_INT IRQ_TYPE_LEVEL_HIGH 0>;
 
 		reg-io-width = <2>;
 		smsc,irq-push-pull;
@@ -427,10 +448,9 @@
 		clock-output-names = "bp:clock24mhz";
 	};
 
-
-	sysreg: sysreg@1c010000 {
+	sysreg: sysreg@SYS_REGS_ADDR {
 		compatible = "arm,vexpress-sysreg";
-		reg = <0x0 0x001c010000 0x0 0x1000>;
+		reg = <0x0 ADDRESSIFY(SYS_REGS_ADDR) 0x0 0x1000>;
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
@@ -443,11 +463,11 @@
 		regulator-always-on;
 	};
 
-	mmci: mmci@1c050000 {
+	mmci: mmci@MMC_ADDR {
 		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>;
+		reg = <0x0 ADDRESSIFY(MMC_ADDR) 0x0 0x1000>;
+		interrupts = <GIC_SPI MMC_INT_0 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI MMC_INT_1 IRQ_TYPE_LEVEL_HIGH 0>;
 		wp-gpios = <&sysreg 1 0>;
 		bus-width = <4>;
 		max-frequency = <25000000>;
@@ -471,10 +491,6 @@
 	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>;
-		interrupt-names = "JOB", "MMU", "GPU";
 		clocks = <&gpu_core_clk>;
 		clock-names = "shadercores";
 #if TC_SCMI_PD_CTRL_EN
@@ -507,10 +523,10 @@
 	smmu_600: smmu@2ce00000 {
 		compatible = "arm,smmu-v3";
 		reg = <0 0x2ce00000 0 0x20000>;
-		interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>,
-			     <GIC_SPI 74 IRQ_TYPE_EDGE_RISING>,
-			     <GIC_SPI 76 IRQ_TYPE_EDGE_RISING>,
-			     <GIC_SPI 77 IRQ_TYPE_EDGE_RISING>;
+		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";
@@ -520,9 +536,9 @@
 		#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";
@@ -532,9 +548,9 @@
 		#iommu-cells = <1>;
 		compatible = "arm,smmu-v3";
 		reg = <HI(0x4002a00000) LO(0x4002a00000) 0x0 0x5000000>;
-		interrupts = <GIC_SPI 481 IRQ_TYPE_EDGE_RISING>,
-			     <GIC_SPI 482 IRQ_TYPE_EDGE_RISING>,
-			     <GIC_SPI 483 IRQ_TYPE_EDGE_RISING>;
+		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";
@@ -545,7 +561,7 @@
 		#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;
 
@@ -630,7 +646,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-fpga.dtsi b/fdts/tc-fpga.dtsi
index 73f4743..08b9ae5 100644
--- a/fdts/tc-fpga.dtsi
+++ b/fdts/tc-fpga.dtsi
@@ -25,12 +25,12 @@
 		stdout-path = "serial0:38400n8";
 	};
 
-	ethernet: ethernet@18000000 {
+	ethernet: ethernet@ETHERNET_ADDR {
 		compatible = "smsc,lan9115";
 		phy-mode = "mii";
 	};
 
-	mmci: mmci@1c050000 {
+	mmci: mmci@MMC_ADDR {
 		non-removable;
 	};
 };
diff --git a/fdts/tc-fvp.dtsi b/fdts/tc-fvp.dtsi
index 9f3a9ac..f57e21d 100644
--- a/fdts/tc-fvp.dtsi
+++ b/fdts/tc-fvp.dtsi
@@ -43,26 +43,26 @@
 		stdout-path = "serial0:115200n8";
 	};
 
-	ethernet: ethernet@18000000 {
+	ethernet: ethernet@ETHERNET_ADDR {
 		compatible = "smsc,lan91c111";
 	};
 
-	mmci: mmci@1c050000 {
+	mmci: mmci@MMC_ADDR {
 		cd-gpios = <&sysreg 0 0>;
 	};
 
-	rtc@1c170000 {
+	rtc@RTC_ADDR {
 		compatible = "arm,pl031", "arm,primecell";
-		reg = <0x0 0x1C170000 0x0 0x1000>;
-		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x0 ADDRESSIFY(RTC_ADDR) 0x0 0x1000>;
+		interrupts = <GIC_SPI RTC_INT IRQ_TYPE_LEVEL_HIGH 0>;
 		clocks = <&soc_refclk>;
 		clock-names = "apb_pclk";
 	};
 
-	kmi@1c060000 {
+	kmi@KMI_0_ADDR {
 		compatible = "arm,pl050", "arm,primecell";
-		reg = <0x0 0x001c060000 0x0 0x1000>;
-		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x0 ADDRESSIFY(KMI_0_ADDR) 0x0 0x1000>;
+		interrupts = <GIC_SPI KMI_0_INT IRQ_TYPE_LEVEL_HIGH 0>;
 		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
 		clock-names = "KMIREFCLK", "apb_pclk";
 	};
@@ -70,15 +70,15 @@
 	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";
 	};
 
-	virtio_block@1c130000 {
+	virtio_block@VIRTIO_BLOCK_ADDR {
 		compatible = "virtio,mmio";
-		reg = <0x0 0x1c130000 0x0 0x200>;
+		reg = <0x0 ADDRESSIFY(VIRTIO_BLOCK_ADDR) 0x0 0x200>;
 		/* spec lists this wrong */
-		interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI VIRTIO_BLOCK_INT IRQ_TYPE_LEVEL_HIGH 0>;
 	};
 };
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
index 4946aca..c492274 100644
--- a/fdts/tc2.dts
+++ b/fdts/tc2.dts
@@ -31,12 +31,36 @@
 #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
 
 #define DPU_ADDR			2cc00000
 #define DPU_IRQ				69
 
+#define ETHERNET_ADDR			18000000
+#define ETHERNET_INT			109
+
+#define SYS_REGS_ADDR			1c010000
+
+#define MMC_ADDR			1c050000
+#define MMC_INT_0			107
+#define MMC_INT_1			108
+
+#define RTC_ADDR			1c170000
+#define RTC_INT				100
+
+#define KMI_0_ADDR			1c060000
+#define KMI_0_INT			197
+#define KMI_1_ADDR			1c070000
+#define KMI_1_INT			103
+
+#define VIRTIO_BLOCK_ADDR		1c130000
+#define VIRTIO_BLOCK_INT		204
+
 #include "tc-common.dtsi"
 #if TARGET_FLAVOUR_FVP
 #include "tc-fvp.dtsi"
@@ -193,22 +217,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 {
@@ -237,6 +249,36 @@
 		};
 	};
 
+	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";
 	};
@@ -249,6 +291,10 @@
 	};
 
 	gpu: gpu@2d000000 {
+		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";
 		iommus = <&smmu_700 0x200>;
 	};
 };
diff --git a/fdts/tc3-4-base.dtsi b/fdts/tc3-4-base.dtsi
new file mode 100644
index 0000000..169d68f
--- /dev/null
+++ b/fdts/tc3-4-base.dtsi
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define LIT_CAPACITY			239
+#define MID_CAPACITY			686
+#define BIG_CAPACITY			1024
+
+#define MHU_TX_COMPAT			"arm,mhuv3"
+#define MHU_TX_INT_NAME			""
+
+#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 MPAM_ADDR			0x0 0x5f010000 /* 0x5f01_0000 */
+#define UARTCLK_FREQ			3750000
+
+#if TARGET_FLAVOUR_FVP
+#define DPU_ADDR			4000000000
+#define DPU_IRQ				579
+#elif TARGET_FLAVOUR_FPGA
+#define DPU_ADDR			2cc00000
+#define DPU_IRQ				69
+#endif
+#include "tc-base.dtsi"
+
+/ {
+	cpus {
+		CPU2:cpu@200 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+		CPU3:cpu@300 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+		CPU6:cpu@600 {
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+		};
+
+		CPU7:cpu@700 {
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+		};
+	};
+
+	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>;
+			};
+		};
+	};
+
+	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>;
+		};
+	};
+};
diff --git a/fdts/tc3.dts b/fdts/tc3.dts
index c741be0..ffe3b6d 100644
--- a/fdts/tc3.dts
+++ b/fdts/tc3.dts
@@ -10,31 +10,32 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <platform_def.h>
 
-#define LIT_CAPACITY			239
-#define MID_CAPACITY			686
-#define BIG_CAPACITY			1024
-
 #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 MPAM_ADDR			0x0 0x5f010000 /* 0x5f01_0000 */
-#define UARTCLK_FREQ			3750000
+#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"
 
-#if TARGET_FLAVOUR_FVP
-#define DPU_ADDR			4000000000
-#define DPU_IRQ				579
-#elif TARGET_FLAVOUR_FPGA
-#define DPU_ADDR			2cc00000
-#define DPU_IRQ				69
-#endif
+#define ETHERNET_ADDR			18000000
+#define ETHERNET_INT			109
+
+#define SYS_REGS_ADDR			1c010000
+
+#define MMC_ADDR			1c050000
+#define MMC_INT_0			107
+#define MMC_INT_1			108
+
+#define RTC_ADDR			1c170000
+#define RTC_INT				100
+
+#define KMI_0_ADDR			1c060000
+#define KMI_0_INT			197
+#define KMI_1_ADDR			1c070000
+#define KMI_1_INT			103
+
+#define VIRTIO_BLOCK_ADDR		1c130000
+#define VIRTIO_BLOCK_INT		204
 
 #include "tc-common.dtsi"
 #if TARGET_FLAVOUR_FVP
@@ -42,36 +43,9 @@
 #else
 #include "tc-fpga.dtsi"
 #endif /* TARGET_FLAVOUR_FVP */
-#include "tc-base.dtsi"
+#include "tc3-4-base.dtsi"
 
 / {
-	cpus {
-		CPU2:cpu@200 {
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-		};
-
-		CPU3:cpu@300 {
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-		};
-
-		CPU6:cpu@600 {
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG_CAPACITY>;
-		};
-
-		CPU7:cpu@700 {
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG_CAPACITY>;
-		};
-	};
-
-	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>;
@@ -92,18 +66,22 @@
 		reg = <0x0 MCN_PMU_ADDR(3) 0x0 0xffc>;
 	};
 
+	spe-pmu-mid {
+		status = "okay";
+	};
+
+	spe-pmu-big {
+		status = "okay";
+	};
+
-	sram: sram@6000000 {
-		cpu_scp_scmi_p2a: scp-shmem@80 {
-			compatible = "arm,scmi-shmem";
-			reg = <0x80 0x80>;
-		};
+	dsu-pmu {
+		compatible = "arm,dsu-pmu";
+		cpus = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
 	};
 
-	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>;
-		};
+	ni-pmu {
+		compatible = "arm,ni-tower";
+		reg = <0x0 0x4f000000 0x0 0x4000000>;
 	};
 
 #if TARGET_FLAVOUR_FVP
@@ -132,6 +110,10 @@
 	};
 
 	gpu: gpu@2d000000 {
+		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";
 #if TARGET_FLAVOUR_FVP
 		iommus = <&smmu_700 0x200>;
 #endif
diff --git a/fdts/tc4.dts b/fdts/tc4.dts
new file mode 100644
index 0000000..135d30a
--- /dev/null
+++ b/fdts/tc4.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <platform_def.h>
+
+#define MHU_TX_ADDR			46240000 /* hex */
+#define MHU_RX_ADDR			46250000 /* hex */
+
+#define LIT_CPU_PMU_COMPATIBLE		"arm,armv8-pmuv3"
+#define MID_CPU_PMU_COMPATIBLE		"arm,armv8-pmuv3"
+#define BIG_CPU_PMU_COMPATIBLE		"arm,armv8-pmuv3"
+
+#define ETHERNET_ADDR			64000000
+#define ETHERNET_INT			799
+
+#define SYS_REGS_ADDR			60080000
+
+#define MMC_ADDR			600b0000
+#define MMC_INT_0			778
+#define MMC_INT_1			779
+
+#define RTC_ADDR			600a0000
+#define RTC_INT				777
+
+#define KMI_0_ADDR			60100000
+#define KMI_0_INT			784
+#define KMI_1_ADDR			60110000
+#define KMI_1_INT			785
+
+#define VIRTIO_BLOCK_ADDR		60020000
+#define VIRTIO_BLOCK_INT		769
+
+#include "tc-common.dtsi"
+#if TARGET_FLAVOUR_FVP
+#include "tc-fvp.dtsi"
+#else
+#include "tc-fpga.dtsi"
+#endif /* TARGET_FLAVOUR_FVP */
+#include "tc3-4-base.dtsi"
+
+/ {
+	smmu_700: iommu@3f000000 {
+		status = "okay";
+	};
+
+	smmu_700_dpu: iommu@4002a00000 {
+		status = "okay";
+	};
+
+	dp0: display@DPU_ADDR {
+		iommus = <&smmu_700_dpu 0x000>, <&smmu_700_dpu 0x100>,
+			 <&smmu_700_dpu 0x200>, <&smmu_700_dpu 0x600>;
+	};
+
+	gpu: gpu@2d000000 {
+		interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "IRQAW";
+		iommus = <&smmu_700 0x200>;
+	};
+};
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 df0dcc3..8145616 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -24,6 +24,9 @@
 #define MIDR_PN_MASK		U(0xfff)
 #define MIDR_PN_SHIFT		U(0x4)
 
+/* Extracts the CPU part number from MIDR for checking CPU match */
+#define EXTRACT_PARTNUM(x)     ((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+
 /*******************************************************************************
  * MPIDR macros
  ******************************************************************************/
@@ -114,9 +117,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 +232,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)
@@ -326,6 +339,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)
 
@@ -392,6 +406,10 @@
 #define ID_AA64MMFR3_EL1_S1PIE_SHIFT		U(8)
 #define ID_AA64MMFR3_EL1_S1PIE_MASK		ULL(0xf)
 
+#define ID_AA64MMFR3_EL1_SCTLR2_SHIFT		U(4)
+#define ID_AA64MMFR3_EL1_SCTLR2_MASK		ULL(0xf)
+#define SCTLR2_IMPLEMENTED			ULL(1)
+
 #define ID_AA64MMFR3_EL1_TCRX_SHIFT		U(0)
 #define ID_AA64MMFR3_EL1_TCRX_MASK		ULL(0xf)
 
@@ -419,6 +437,10 @@
 #define ID_AA64PFR1_EL1_GCS_MASK	ULL(0xf)
 #define GCS_IMPLEMENTED			ULL(1)
 
+#define ID_AA64PFR1_EL1_THE_SHIFT	U(48)
+#define ID_AA64PFR1_EL1_THE_MASK	ULL(0xf)
+#define THE_IMPLEMENTED			ULL(1)
+
 #define RNG_TRAP_IMPLEMENTED		ULL(0x1)
 
 /* ID_AA64PFR2_EL1 definitions */
@@ -569,12 +591,15 @@
 /* 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)
 #define SCR_TWEDEL_MASK		ULL(0xf)
 #define SCR_PIEN_BIT		(UL(1) << 45)
+#define SCR_SCTLR2En_BIT	(UL(1) << 44)
 #define SCR_TCR2EN_BIT		(UL(1) << 43)
+#define SCR_RCWMASKEn_BIT	(UL(1) << 42)
 #define SCR_TRNDR_BIT		(UL(1) << 40)
 #define SCR_GCSEn_BIT		(UL(1) << 39)
 #define SCR_HXEn_BIT		(UL(1) << 38)
@@ -607,6 +632,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)
@@ -1457,6 +1483,18 @@
 #define TRFCR_EL1		S3_0_C1_C2_1
 
 /*******************************************************************************
+ * FEAT_THE - Translation Hardening Extension Registers
+ ******************************************************************************/
+#define RCWMASK_EL1		S3_0_C13_C0_6
+#define RCWSMASK_EL1		S3_0_C13_C0_3
+
+/*******************************************************************************
+ * FEAT_SCTLR2 - Extension to SCTLR_ELx Registers
+ ******************************************************************************/
+#define SCTLR2_EL2		S3_4_C1_C0_3
+#define SCTLR2_EL1		S3_0_C1_C0_3
+
+/*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
 #define CLUSTERPWRDN_EL1	S3_0_c15_c3_6
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index ddc1c80..de21fea 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,15 @@
  * +----------------------------+
  * |	FEAT_MTPMU		|
  * +----------------------------+
+ * |	FEAT_FGT2		|
+ * +----------------------------+
+ * |	FEAT_THE		|
+ * +----------------------------+
+ * |	FEAT_SCTLR2		|
+ * +----------------------------+
  */
 
+__attribute__((always_inline))
 static inline bool is_armv7_gentimer_present(void)
 {
 	/* The Generic Timer is always present in an ARMv8-A implementation */
@@ -160,6 +169,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 +226,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 +252,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 +266,16 @@
 CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
 		     ID_AA64MMFR3_EL1_S1PIE_MASK, 1U, ENABLE_FEAT_S1PIE)
 
+/* FEAT_THE: Translation Hardening Extension */
+CREATE_FEATURE_FUNCS(feat_the, id_aa64pfr1_el1, ID_AA64PFR1_EL1_THE_SHIFT,
+		     ID_AA64PFR1_EL1_THE_MASK, THE_IMPLEMENTED, ENABLE_FEAT_THE)
+
+/* FEAT_SCTLR2 */
+CREATE_FEATURE_FUNCS(feat_sctlr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_SCTLR2_SHIFT,
+		     ID_AA64MMFR3_EL1_SCTLR2_MASK, SCTLR2_IMPLEMENTED,
+		     ENABLE_FEAT_SCTLR2)
+
+__attribute__((always_inline))
 static inline bool is_feat_sxpie_supported(void)
 {
 	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
@@ -277,6 +302,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 +314,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 +418,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 +429,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 +442,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 1e2f84b..acaa1b8 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)
@@ -663,6 +670,14 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
 
+/* FEAT_THE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwmask_el1, RCWMASK_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwsmask_el1, RCWSMASK_EL1)
+
+/* FEAT_SCTLR2 Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el2, SCTLR2_EL2)
+
 /* DynamIQ Control registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcr_el1, CLUSTERPMCR_EL1)
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 b4c5c1b..60c5a0c 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -437,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/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index abbf976..de08f1d 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -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
  */
@@ -21,6 +21,8 @@
 				 const char *prop_name, uint32_t dflt_value);
 int fdt_read_uint64(const void *dtb, int node, const char *prop_name,
 		    uint64_t *value);
+uint64_t fdt_read_uint64_default(const void *dtb, int node,
+				 const char *prop_name, uint64_t dflt_value);
 int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name,
 			  unsigned int cells, uint32_t *value);
 int fdtw_read_string(const void *dtb, int node, const char *prop,
diff --git a/include/common/feat_detect.h b/include/common/feat_detect.h
index 788dfb3..b85e1ce 100644
--- a/include/common/feat_detect.h
+++ b/include/common/feat_detect.h
@@ -11,8 +11,9 @@
 void detect_arch_features(void);
 
 /* Macro Definitions */
-#define FEAT_STATE_DISABLED	0
-#define FEAT_STATE_ALWAYS	1
-#define FEAT_STATE_CHECK	2
+#define FEAT_STATE_DISABLED		0
+#define FEAT_STATE_ALWAYS		1
+#define FEAT_STATE_CHECK		2
+#define FEAT_STATE_CHECK_ASYMMETRIC	3
 
 #endif /* FEAT_DETECT_H */
diff --git a/include/common/sha_common_macros.h b/include/common/sha_common_macros.h
new file mode 100644
index 0000000..a419488
--- /dev/null
+++ b/include/common/sha_common_macros.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SHA_COMMON_MACROS_H
+#define SHA_COMMON_MACROS_H
+
+#define MD5_DIGEST_SIZE                 16U
+#define SHA1_DIGEST_SIZE                20U
+#define SHA224_DIGEST_SIZE              28U
+#define SHA256_DIGEST_SIZE              32U
+#define SHA384_DIGEST_SIZE              48U
+#define SHA512_224_DIGEST_SIZE          28U
+#define SHA512_256_DIGEST_SIZE          32U
+#define SHA512_DIGEST_SIZE              64U
+
+#endif /* SHA_COMMON_MACROS_H */
diff --git a/include/drivers/arm/dcc.h b/include/drivers/arm/dcc.h
index 072bed5..7f71932 100644
--- a/include/drivers/arm/dcc.h
+++ b/include/drivers/arm/dcc.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2021,  Xilinx Inc.
+ * Copyright (c) 2021-2022, Xilinx Inc.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +15,7 @@
  * Initialize a new dcc console instance and register it with the console
  * framework.
  */
-int console_dcc_register(void);
-void console_dcc_unregister(void);
+int console_dcc_register(console_t *console);
+void console_dcc_unregister(console_t *console);
 
-#endif /* DCC */
+#endif /* DCC_H */
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index bfda31b..0e6137d 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -150,6 +150,7 @@
 /* GICD_TYPER shifts and masks */
 #define	TYPER_ESPI		U(1 << 8)
 #define	TYPER_DVIS		U(1 << 18)
+#define	TYPER_LPIS		U(1 << 17)
 #define	TYPER_ESPI_RANGE_MASK	U(0x1f)
 #define	TYPER_ESPI_RANGE_SHIFT	U(27)
 #define	TYPER_ESPI_RANGE	U(TYPER_ESPI_MASK << TYPER_ESPI_SHIFT)
@@ -340,7 +341,7 @@
 
 /* GITS_CTLR bit definitions */
 #define GITS_CTLR_ENABLED_BIT		BIT_32(0)
-#define GITS_CTLR_QUIESCENT_BIT		BIT_32(1)
+#define GITS_CTLR_QUIESCENT_BIT		BIT_32(31)
 
 #define GITS_TYPER_VSGI			BIT_64(39)
 
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-3.h b/include/drivers/auth/mbedtls/mbedtls_config-3.h
index 37a9288..6ed9397 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config-3.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config-3.h
@@ -73,23 +73,17 @@
 #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
 #endif
 
-/* The library does not currently support enabling SHA-256 without SHA-224. */
-#define MBEDTLS_SHA224_C
-#define MBEDTLS_SHA256_C
-/*
- * If either Trusted Boot or Measured Boot require a stronger algorithm than
- * SHA-256, pull in SHA-512 support. Library currently needs to have SHA_384
- * support when enabling SHA-512.
- */
-#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256) /* TBB hash algo */
-#define MBEDTLS_SHA384_C
-#define	MBEDTLS_SHA512_C
-#else
-   /* TBB uses SHA-256, what about measured boot? */
-#if defined(TF_MBEDTLS_MBOOT_USE_SHA512)
-#define MBEDTLS_SHA384_C
-#define MBEDTLS_SHA512_C
+/* Enable hash algorithms based on TBB or Measured Boot */
+#if (TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256) || defined(TF_MBEDTLS_MBOOT_USE_SHA256)
+    #define MBEDTLS_SHA256_C
 #endif
+
+#if (TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384) || defined(TF_MBEDTLS_MBOOT_USE_SHA384)
+    #define MBEDTLS_SHA384_C
+#endif
+
+#if (TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512) || defined(TF_MBEDTLS_MBOOT_USE_SHA512)
+    #define MBEDTLS_SHA512_C
 #endif
 
 #define MBEDTLS_VERSION_C
@@ -104,7 +98,9 @@
 #endif
 
 /* MPI / BIGNUM options */
-#define MBEDTLS_MPI_WINDOW_SIZE			2
+
+/* Note: Lower numbers trade longer execution time for less RAM allocation */
+#define MBEDTLS_MPI_WINDOW_SIZE			1
 
 #if TF_MBEDTLS_USE_RSA
 #if TF_MBEDTLS_KEY_SIZE <= 2048
diff --git a/include/drivers/delay_timer.h b/include/drivers/delay_timer.h
index 20a5543..e9fdfb7 100644
--- a/include/drivers/delay_timer.h
+++ b/include/drivers/delay_timer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019, Linaro Limited
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,27 +25,12 @@
 	uint32_t (*get_timer_value)(void);
 	uint32_t clk_mult;
 	uint32_t clk_div;
+	uint64_t (*timeout_init_us)(uint32_t usec);
+	bool (*timeout_elapsed)(uint64_t cnt);
 } timer_ops_t;
 
-static inline uint64_t timeout_cnt_us2cnt(uint32_t us)
-{
-	return ((uint64_t)us * (uint64_t)read_cntfrq_el0()) / 1000000ULL;
-}
-
-static inline uint64_t timeout_init_us(uint32_t us)
-{
-	uint64_t cnt = timeout_cnt_us2cnt(us);
-
-	cnt += read_cntpct_el0();
-
-	return cnt;
-}
-
-static inline bool timeout_elapsed(uint64_t expire_cnt)
-{
-	return read_cntpct_el0() > expire_cnt;
-}
-
+uint64_t timeout_init_us(uint32_t usec);
+bool timeout_elapsed(uint64_t cnt);
 void mdelay(uint32_t msec);
 void udelay(uint32_t usec);
 void timer_init(const timer_ops_t *ops_ptr);
diff --git a/include/drivers/measured_boot/event_log/tcg.h b/include/drivers/measured_boot/event_log/tcg.h
index 4ac2c2f..653f9c2 100644
--- a/include/drivers/measured_boot/event_log/tcg.h
+++ b/include/drivers/measured_boot/event_log/tcg.h
@@ -8,6 +8,7 @@
 #define TCG_H
 
 #include <stdint.h>
+#include <common/sha_common_macros.h>
 
 #define TCG_ID_EVENT_SIGNATURE_03	"Spec ID Event03"
 #define TCG_STARTUP_LOCALITY_SIGNATURE	"StartupLocality"
@@ -66,12 +67,6 @@
 #define PLATFORM_CLASS_CLIENT   0
 #define PLATFORM_CLASS_SERVER   1
 
-/* SHA digest sizes in bytes */
-#define SHA1_DIGEST_SIZE	20
-#define SHA256_DIGEST_SIZE	32
-#define SHA384_DIGEST_SIZE	48
-#define SHA512_DIGEST_SIZE	64
-
 enum {
 	/*
 	 * SRTM, BIOS, Host Platform Extensions, Embedded
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
index 633f173..d34dc22 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
@@ -78,4 +78,29 @@
 #define S32CC_CLK_A53_CORE_DIV2			S32CC_ARCH_CLK(4)
 #define S32CC_CLK_A53_CORE_DIV10		S32CC_ARCH_CLK(5)
 
+/* XBAR clock*/
+#define S32CC_CLK_MC_CGM0_MUX0			S32CC_ARCH_CLK(6)
+#define S32CC_CLK_XBAR_2X			S32CC_ARCH_CLK(7)
+#define S32CC_CLK_XBAR				S32CC_ARCH_CLK(8)
+#define S32CC_CLK_XBAR_DIV2			S32CC_ARCH_CLK(9)
+#define S32CC_CLK_XBAR_DIV3			S32CC_ARCH_CLK(10)
+#define S32CC_CLK_XBAR_DIV4			S32CC_ARCH_CLK(11)
+#define S32CC_CLK_XBAR_DIV6			S32CC_ARCH_CLK(12)
+
+/* Periph PLL */
+#define S32CC_CLK_PERIPH_PLL_MUX		S32CC_ARCH_CLK(13)
+#define S32CC_CLK_PERIPH_PLL_VCO		S32CC_ARCH_CLK(14)
+
+#define S32CC_CLK_MC_CGM0_MUX8			S32CC_ARCH_CLK(15)
+#define S32CC_CLK_LINFLEX_BAUD			S32CC_ARCH_CLK(16)
+#define S32CC_CLK_LINFLEX			S32CC_ARCH_CLK(17)
+
+/* DDR PLL */
+#define S32CC_CLK_DDR_PLL_MUX			S32CC_ARCH_CLK(18)
+#define S32CC_CLK_DDR_PLL_VCO			S32CC_ARCH_CLK(19)
+
+/* DDR clock */
+#define S32CC_CLK_MC_CGM5_MUX0			S32CC_ARCH_CLK(20)
+#define S32CC_CLK_DDR				S32CC_ARCH_CLK(21)
+
 #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
index 9524f72..4837f79 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
@@ -6,6 +6,7 @@
 #define S32CC_CLK_MODULES_H
 
 #include <inttypes.h>
+#include <stdbool.h>
 #include <stddef.h>
 
 #define MHZ	UL(1000000)
@@ -14,12 +15,29 @@
 enum s32cc_clkm_type {
 	s32cc_osc_t,
 	s32cc_clk_t,
+	s32cc_pll_t,
+	s32cc_pll_out_div_t,
+	s32cc_dfs_t,
+	s32cc_dfs_div_t,
+	s32cc_clkmux_t,
+	s32cc_shared_clkmux_t,
+	s32cc_fixed_div_t,
+	s32cc_part_t,
+	s32cc_part_block_t,
+	s32cc_part_block_link_t,
 };
 
 enum s32cc_clk_source {
 	S32CC_FIRC,
 	S32CC_FXOSC,
 	S32CC_SIRC,
+	S32CC_ARM_PLL,
+	S32CC_ARM_DFS,
+	S32CC_PERIPH_PLL,
+	S32CC_CGM0,
+	S32CC_CGM1,
+	S32CC_DDR_PLL,
+	S32CC_CGM5,
 };
 
 struct s32cc_clk_obj {
@@ -42,6 +60,125 @@
 	.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_dfs {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	enum s32cc_clk_source instance;
+	uintptr_t base;
+};
+
+#define S32CC_DFS_INIT(PARENT, INSTANCE) \
+{                                        \
+	.desc = {                        \
+		.type = s32cc_dfs_t,     \
+	},                               \
+	.parent = &(PARENT).desc,        \
+	.instance = (INSTANCE),          \
+}
+
+struct s32cc_dfs_div {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	uint32_t index;
+	unsigned long freq;
+};
+
+#define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
+{                                         \
+	.desc = {                         \
+		.type = s32cc_dfs_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;
@@ -56,22 +193,96 @@
 	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_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
+{                                                           \
+	.desc = {                                           \
+		.type = s32cc_clk_t,                        \
+	},                                                  \
+	.pclock = (PARENT),                                 \
+	.module = (PARENT_MODULE),                          \
+	.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)
+	S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
 
 #define S32CC_MODULE_CLK(PARENT_MODULE) \
 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
 
+#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
+	S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
+
+struct s32cc_part {
+	struct s32cc_clk_obj desc;
+	uint32_t partition_id;
+};
+
+#define S32CC_PART(PART_NUM)          \
+{                                     \
+	.desc = {                     \
+		.type = s32cc_part_t, \
+	},                            \
+	.partition_id = (PART_NUM),   \
+}
+
+enum s32cc_part_block_type {
+	s32cc_part_block0,
+	s32cc_part_block1,
+	s32cc_part_block2,
+	s32cc_part_block3,
+	s32cc_part_block4,
+	s32cc_part_block5,
+	s32cc_part_block6,
+	s32cc_part_block7,
+	s32cc_part_block8,
+	s32cc_part_block9,
+	s32cc_part_block10,
+	s32cc_part_block11,
+	s32cc_part_block12,
+	s32cc_part_block13,
+	s32cc_part_block14,
+	s32cc_part_block15,
+};
+
+struct s32cc_part_block {
+	struct s32cc_clk_obj desc;
+	struct s32cc_part *part;
+	enum s32cc_part_block_type block;
+	bool status;
+};
+
+#define S32CC_PART_BLOCK_STATUS(PART_META, BLOCK_TYPE, STATUS) \
+{                                                              \
+	.desc = {                                              \
+		.type = s32cc_part_block_t,                    \
+	},                                                     \
+	.part = (PART_META),                                   \
+	.block = (BLOCK_TYPE),                                 \
+	.status = (STATUS),                                    \
+}
+
+#define S32CC_PART_BLOCK(PARENT, BLOCK_TYPE) \
+	S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, true)
+
+#define S32CC_PART_BLOCK_NO_STATUS(PARENT, BLOCK_TYPE) \
+	S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, false)
+
+struct s32cc_part_block_link {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	struct s32cc_part_block *block;
+};
+
+#define S32CC_PART_BLOCK_LINK(PARENT, BLOCK)     \
+{                                                \
+	.desc = {                                \
+		.type = s32cc_part_block_link_t, \
+	},                                       \
+	.parent = &(PARENT).desc,                \
+	.block = (BLOCK),                        \
+}
+
 static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
 {
 	uintptr_t osc_addr;
@@ -88,4 +299,100 @@
 	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;
+}
+
+static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t dfs_addr;
+
+	dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
+	return (struct s32cc_dfs *)dfs_addr;
+}
+
+static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t dfs_div_addr;
+
+	dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
+	return (struct s32cc_dfs_div *)dfs_div_addr;
+}
+
+static inline struct s32cc_part *s32cc_obj2part(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t part_addr;
+
+	part_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part, desc);
+	return (struct s32cc_part *)part_addr;
+}
+
+static inline struct s32cc_part_block *
+s32cc_obj2partblock(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t part_blk_addr;
+
+	part_blk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part_block, desc);
+	return (struct s32cc_part_block *)part_blk_addr;
+}
+
+static inline struct s32cc_part_block_link *
+s32cc_obj2partblocklink(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t blk_link;
+
+	blk_link = ((uintptr_t)mod) - offsetof(struct s32cc_part_block_link, desc);
+	return (struct s32cc_part_block_link *)blk_link;
+}
+
 #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
index 6a90406..e6adecc 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
@@ -11,7 +11,12 @@
 					   size_t size,
 					   unsigned long clk_id);
 
+int s32cc_get_id_from_table(const struct s32cc_clk_array *const *clk_arr,
+			    size_t size, const struct s32cc_clk *clk,
+			    unsigned long *clk_index);
+
 struct s32cc_clk *s32cc_get_arch_clk(unsigned long id);
+int s32cc_get_clk_id(const struct s32cc_clk *clk, unsigned long *id);
 
 void s32cc_clk_register_drv(void);
 
diff --git a/include/drivers/nxp/crypto/caam/hash.h b/include/drivers/nxp/crypto/caam/hash.h
index 9136dca..6201d23 100644
--- a/include/drivers/nxp/crypto/caam/hash.h
+++ b/include/drivers/nxp/crypto/caam/hash.h
@@ -9,6 +9,7 @@
 #define __HASH_H__
 
 #include <stdbool.h>
+#include <common/sha_common_macros.h>
 
 /* List of hash algorithms */
 enum hash_algo {
@@ -16,9 +17,6 @@
 	SHA256
 };
 
-/* number of bytes in the SHA256-256 digest */
-#define SHA256_DIGEST_SIZE 32
-
 /*
  * number of words in the digest - Digest is kept internally
  * as 8 32-bit words
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/stm32mp2_ddr.h b/include/drivers/st/stm32mp2_ddr.h
new file mode 100644
index 0000000..6b0462c
--- /dev/null
+++ b/include/drivers/st/stm32mp2_ddr.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef STM32MP2_DDR_H
+#define STM32MP2_DDR_H
+
+#include <stdbool.h>
+
+#include <ddrphy_phyinit_struct.h>
+
+#include <drivers/st/stm32mp_ddr.h>
+
+struct stm32mp2_ddrctrl_reg {
+	uint32_t mstr;
+	uint32_t mrctrl0;
+	uint32_t mrctrl1;
+	uint32_t mrctrl2;
+	uint32_t derateen;
+	uint32_t derateint;
+	uint32_t deratectl;
+	uint32_t pwrctl;
+	uint32_t pwrtmg;
+	uint32_t hwlpctl;
+	uint32_t rfshctl0;
+	uint32_t rfshctl1;
+	uint32_t rfshctl3;
+	uint32_t crcparctl0;
+	uint32_t crcparctl1;
+	uint32_t init0;
+	uint32_t init1;
+	uint32_t init2;
+	uint32_t init3;
+	uint32_t init4;
+	uint32_t init5;
+	uint32_t init6;
+	uint32_t init7;
+	uint32_t dimmctl;
+	uint32_t rankctl;
+	uint32_t rankctl1;
+	uint32_t zqctl0;
+	uint32_t zqctl1;
+	uint32_t zqctl2;
+	uint32_t dfitmg0;
+	uint32_t dfitmg1;
+	uint32_t dfilpcfg0;
+	uint32_t dfilpcfg1;
+	uint32_t dfiupd0;
+	uint32_t dfiupd1;
+	uint32_t dfiupd2;
+	uint32_t dfimisc;
+	uint32_t dfitmg2;
+	uint32_t dfitmg3;
+	uint32_t dbictl;
+	uint32_t dfiphymstr;
+	uint32_t dbg0;
+	uint32_t dbg1;
+	uint32_t dbgcmd;
+	uint32_t swctl;
+	uint32_t swctlstatic;
+	uint32_t poisoncfg;
+	uint32_t pccfg;
+};
+
+struct stm32mp2_ddrctrl_timing {
+	uint32_t rfshtmg;
+	uint32_t rfshtmg1;
+	uint32_t dramtmg0;
+	uint32_t dramtmg1;
+	uint32_t dramtmg2;
+	uint32_t dramtmg3;
+	uint32_t dramtmg4;
+	uint32_t dramtmg5;
+	uint32_t dramtmg6;
+	uint32_t dramtmg7;
+	uint32_t dramtmg8;
+	uint32_t dramtmg9;
+	uint32_t dramtmg10;
+	uint32_t dramtmg11;
+	uint32_t dramtmg12;
+	uint32_t dramtmg13;
+	uint32_t dramtmg14;
+	uint32_t dramtmg15;
+	uint32_t odtcfg;
+	uint32_t odtmap;
+};
+
+struct stm32mp2_ddrctrl_map {
+	uint32_t addrmap0;
+	uint32_t addrmap1;
+	uint32_t addrmap2;
+	uint32_t addrmap3;
+	uint32_t addrmap4;
+	uint32_t addrmap5;
+	uint32_t addrmap6;
+	uint32_t addrmap7;
+	uint32_t addrmap8;
+	uint32_t addrmap9;
+	uint32_t addrmap10;
+	uint32_t addrmap11;
+};
+
+struct stm32mp2_ddrctrl_perf {
+	uint32_t sched;
+	uint32_t sched1;
+	uint32_t perfhpr1;
+	uint32_t perflpr1;
+	uint32_t perfwr1;
+	uint32_t sched3;
+	uint32_t sched4;
+	uint32_t pcfgr_0;
+	uint32_t pcfgw_0;
+	uint32_t pctrl_0;
+	uint32_t pcfgqos0_0;
+	uint32_t pcfgqos1_0;
+	uint32_t pcfgwqos0_0;
+	uint32_t pcfgwqos1_0;
+#if STM32MP_DDR_DUAL_AXI_PORT
+	uint32_t pcfgr_1;
+	uint32_t pcfgw_1;
+	uint32_t pctrl_1;
+	uint32_t pcfgqos0_1;
+	uint32_t pcfgqos1_1;
+	uint32_t pcfgwqos0_1;
+	uint32_t pcfgwqos1_1;
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
+};
+
+struct stm32mp_ddr_config {
+	struct stm32mp_ddr_info info;
+	struct stm32mp2_ddrctrl_reg c_reg;
+	struct stm32mp2_ddrctrl_timing c_timing;
+	struct stm32mp2_ddrctrl_map c_map;
+	struct stm32mp2_ddrctrl_perf c_perf;
+	bool self_refresh;
+	uint32_t zdata;
+	struct user_input_basic uib;
+	struct user_input_advanced uia;
+	struct user_input_mode_register uim;
+	struct user_input_swizzle uis;
+};
+
+void stm32mp2_ddr_init(struct stm32mp_ddr_priv *priv, struct stm32mp_ddr_config *config);
+
+#endif /* STM32MP2_DDR_H */
diff --git a/include/drivers/st/stm32mp2_ddr_helpers.h b/include/drivers/st/stm32mp2_ddr_helpers.h
new file mode 100644
index 0000000..9329fff
--- /dev/null
+++ b/include/drivers/st/stm32mp2_ddr_helpers.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_DDR_HELPERS_H
+#define STM32MP2_DDR_HELPERS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <drivers/st/stm32mp2_ddr_regs.h>
+
+enum stm32mp2_ddr_sr_mode {
+	DDR_SR_MODE_INVALID = 0,
+	DDR_SSR_MODE,
+	DDR_HSR_MODE,
+	DDR_ASR_MODE,
+};
+
+void ddr_activate_controller(struct stm32mp_ddrctl *ctl, bool sr_entry);
+void ddr_wait_lp3_mode(bool state);
+int ddr_sr_exit_loop(void);
+uint32_t ddr_get_io_calibration_val(void);
+int ddr_sr_entry(bool standby);
+int ddr_sr_exit(void);
+enum stm32mp2_ddr_sr_mode ddr_read_sr_mode(void);
+void ddr_set_sr_mode(enum stm32mp2_ddr_sr_mode mode);
+void ddr_save_sr_mode(void);
+void ddr_restore_sr_mode(void);
+void ddr_sub_system_clk_init(void);
+void ddr_sub_system_clk_off(void);
+
+#endif /* STM32MP2_DDR_HELPERS_H */
diff --git a/include/drivers/st/stm32mp2_ddr_regs.h b/include/drivers/st/stm32mp2_ddr_regs.h
new file mode 100644
index 0000000..9370f1c
--- /dev/null
+++ b/include/drivers/st/stm32mp2_ddr_regs.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef STM32MP2_DDR_REGS_H
+#define STM32MP2_DDR_REGS_H
+
+#include <drivers/st/stm32mp_ddrctrl_regs.h>
+#include <lib/utils_def.h>
+
+/* DDR Physical Interface Control (DDRPHYC) registers*/
+struct stm32mp_ddrphy {
+	uint32_t dummy;
+} __packed;
+
+/* DDRPHY registers offsets */
+#define DDRPHY_INITENG0_P0_SEQ0BDISABLEFLAG6	U(0x240004)
+#define DDRPHY_INITENG0_P0_PHYINLPX		U(0x2400A0)
+#define DDRPHY_DRTUB0_UCCLKHCLKENABLES		U(0x300200)
+#define DDRPHY_APBONLY0_MICROCONTMUXSEL		U(0x340000)
+
+/* DDRPHY registers fields */
+#define DDRPHY_INITENG0_P0_PHYINLPX_PHYINLP3			BIT(0)
+#define DDRPHY_DRTUB0_UCCLKHCLKENABLES_UCCLKEN			BIT(0)
+#define DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN			BIT(1)
+#define DDRPHY_APBONLY0_MICROCONTMUXSEL_MICROCONTMUXSEL		BIT(0)
+
+/* DDRDBG registers offsets */
+#define DDRDBG_LP_DISABLE			U(0x0)
+#define DDRDBG_BYPASS_PCLKEN			U(0x4)
+
+/* DDRDBG registers fields */
+#define DDRDBG_LP_DISABLE_LPI_XPI_DISABLE	BIT(0)
+#define DDRDBG_LP_DISABLE_LPI_DDRC_DISABLE	BIT(8)
+
+#endif /* STM32MP2_DDR_REGS_H */
diff --git a/include/drivers/st/stm32mp2_pwr.h b/include/drivers/st/stm32mp2_pwr.h
new file mode 100644
index 0000000..356399a
--- /dev/null
+++ b/include/drivers/st/stm32mp2_pwr.h
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_PWR_H
+#define STM32MP2_PWR_H
+
+#include <lib/utils_def.h>
+
+#define PWR_CR1					U(0x00)
+#define PWR_CR2					U(0x04)
+#define PWR_CR3					U(0x08)
+#define PWR_CR4					U(0x0C)
+#define PWR_CR5					U(0x10)
+#define PWR_CR6					U(0x14)
+#define PWR_CR7					U(0x18)
+#define PWR_CR8					U(0x1C)
+#define PWR_CR9					U(0x20)
+#define PWR_CR10				U(0x24)
+#define PWR_CR11				U(0x28)
+#define PWR_CR12				U(0x2C)
+#define PWR_UCPDR				U(0x30)
+#define PWR_BDCR1				U(0x38)
+#define PWR_BDCR2				U(0x3C)
+#define PWR_CPU1CR				U(0x40)
+#define PWR_CPU2CR				U(0x44)
+#define PWR_CPU3CR				U(0x48)
+#define PWR_D1CR				U(0x4C)
+#define PWR_D2CR				U(0x50)
+#define PWR_D3CR				U(0x54)
+#define PWR_WKUPCR1				U(0x60)
+#define PWR_WKUPCR2				U(0x64)
+#define PWR_WKUPCR3				U(0x68)
+#define PWR_WKUPCR4				U(0x6C)
+#define PWR_WKUPCR5				U(0x70)
+#define PWR_WKUPCR6				U(0x74)
+#define PWR_D3WKUPENR				U(0x98)
+#define PWR_RSECCFGR				U(0x100)
+#define PWR_RPRIVCFGR				U(0x104)
+#define PWR_R0CIDCFGR				U(0x108)
+#define PWR_R1CIDCFGR				U(0x10C)
+#define PWR_R2CIDCFGR				U(0x110)
+#define PWR_R3CIDCFGR				U(0x114)
+#define PWR_R4CIDCFGR				U(0x118)
+#define PWR_R5CIDCFGR				U(0x11C)
+#define PWR_R6CIDCFGR				U(0x120)
+#define PWR_WIOSECCFGR				U(0x180)
+#define PWR_WIOPRIVCFGR				U(0x184)
+#define PWR_WIO1CIDCFGR				U(0x188)
+#define PWR_WIO1SEMCR				U(0x18C)
+#define PWR_WIO2CIDCFGR				U(0x190)
+#define PWR_WIO2SEMCR				U(0x194)
+#define PWR_WIO3CIDCFGR				U(0x198)
+#define PWR_WIO3SEMCR				U(0x19C)
+#define PWR_WIO4CIDCFGR				U(0x1A0)
+#define PWR_WIO4SEMCR				U(0x1A4)
+#define PWR_WIO5CIDCFGR				U(0x1A8)
+#define PWR_WIO5SEMCR				U(0x1AC)
+#define PWR_WIO6CIDCFGR				U(0x1B0)
+#define PWR_WIO6SEMCR				U(0x1B4)
+#define PWR_CPU1D1SR				U(0x200)
+#define PWR_CPU2D2SR				U(0x204)
+#define PWR_CPU3D3SR				U(0x208)
+#define PWR_DBGR				U(0x308)
+#define PWR_VERR				U(0x3F4)
+#define PWR_IPIDR				U(0x3F8)
+#define PWR_SIDR				U(0x3FC)
+
+/* PWR_CR1 register fields */
+#define PWR_CR1_VDDIO3VMEN			BIT_32(0)
+#define PWR_CR1_VDDIO4VMEN			BIT_32(1)
+#define PWR_CR1_USB33VMEN			BIT_32(2)
+#define PWR_CR1_UCPDVMEN			BIT_32(3)
+#define PWR_CR1_AVMEN				BIT_32(4)
+#define PWR_CR1_VDDIO3SV			BIT_32(8)
+#define PWR_CR1_VDDIO4SV			BIT_32(9)
+#define PWR_CR1_USB33SV				BIT_32(10)
+#define PWR_CR1_UCPDSV				BIT_32(11)
+#define PWR_CR1_ASV				BIT_32(12)
+#define PWR_CR1_VDDIO3RDY			BIT_32(16)
+#define PWR_CR1_VDDIO4RDY			BIT_32(17)
+#define PWR_CR1_USB33RDY			BIT_32(18)
+#define PWR_CR1_UCPDRDY				BIT_32(19)
+#define PWR_CR1_ARDY				BIT_32(20)
+#define PWR_CR1_VDDIOVRSEL			BIT_32(24)
+#define PWR_CR1_VDDIO3VRSEL			BIT_32(25)
+#define PWR_CR1_VDDIO4VRSEL			BIT_32(26)
+#define PWR_CR1_GPVMO				BIT_32(31)
+
+/* PWR_CR2 register fields */
+#define PWR_CR2_MONEN				BIT_32(0)
+#define PWR_CR2_VBATL				BIT_32(8)
+#define PWR_CR2_VBATH				BIT_32(9)
+#define PWR_CR2_TEMPL				BIT_32(10)
+#define PWR_CR2_TEMPH				BIT_32(11)
+
+/* PWR_CR3 register fields */
+#define PWR_CR3_PVDEN				BIT_32(0)
+#define PWR_CR3_PVDO				BIT_32(8)
+
+/* PWR_CR5 register fields */
+#define PWR_CR5_VCOREMONEN			BIT_32(0)
+#define PWR_CR5_VCOREL				BIT_32(8)
+#define PWR_CR5_VCOREH				BIT_32(9)
+
+/* PWR_CR6 register fields */
+#define PWR_CR6_VCPUMONEN			BIT_32(0)
+#define PWR_CR6_VCPULLS				BIT_32(4)
+#define PWR_CR6_VCPUL				BIT_32(8)
+#define PWR_CR6_VCPUH				BIT_32(9)
+
+/* PWR_CR7 register fields */
+#define PWR_CR7_VDDIO2VMEN			BIT_32(0)
+#define PWR_CR7_VDDIO2SV			BIT_32(8)
+#define PWR_CR7_VDDIO2RDY			BIT_32(16)
+#define PWR_CR7_VDDIO2VRSEL			BIT_32(24)
+#define PWR_CR7_VDDIO2VRSTBY			BIT_32(25)
+
+/* PWR_CR8 register fields */
+#define PWR_CR8_VDDIO1VMEN			BIT_32(0)
+#define PWR_CR8_VDDIO1SV			BIT_32(8)
+#define PWR_CR8_VDDIO1RDY			BIT_32(16)
+#define PWR_CR8_VDDIO1VRSEL			BIT_32(24)
+#define PWR_CR8_VDDIO1VRSTBY			BIT_32(25)
+
+/* PWR_CR9 register fields */
+#define PWR_CR9_BKPRBSEN			BIT_32(0)
+#define PWR_CR9_LPR1BSEN			BIT_32(4)
+
+/* PWR_CR10 register fields */
+#define PWR_CR10_RETRBSEN_MASK			GENMASK_32(1, 0)
+#define PWR_CR10_RETRBSEN_SHIFT			U(0)
+
+/* PWR_CR11 register fields */
+#define PWR_CR11_DDRRETDIS			BIT_32(0)
+
+/* PWR_CR12 register fields */
+#define PWR_CR12_GPUVMEN			BIT_32(0)
+#define PWR_CR12_GPULVTEN			BIT_32(1)
+#define PWR_CR12_GPUSV				BIT_32(8)
+#define PWR_CR12_VDDGPURDY			BIT_32(16)
+
+/* PWR_UCPDR register fields */
+#define PWR_UCPDR_UCPD_DBDIS			BIT_32(0)
+#define PWR_UCPDR_UCPD_STBY			BIT_32(1)
+
+/* PWR_BDCR1 register fields */
+#define PWR_BDCR1_DBD3P				BIT_32(0)
+
+/* PWR_BDCR2 register fields */
+#define PWR_BDCR2_DBP				BIT_32(0)
+
+/* PWR_CPU1CR register fields */
+#define PWR_CPU1CR_PDDS_D2			BIT_32(0)
+#define PWR_CPU1CR_PDDS_D1			BIT_32(1)
+#define PWR_CPU1CR_VBF				BIT_32(4)
+#define PWR_CPU1CR_STOPF			BIT_32(5)
+#define PWR_CPU1CR_SBF				BIT_32(6)
+#define PWR_CPU1CR_SBF_D1			BIT_32(7)
+#define PWR_CPU1CR_SBF_D3			BIT_32(8)
+#define PWR_CPU1CR_CSSF				BIT_32(9)
+#define PWR_CPU1CR_STANDBYWFIL2			BIT_32(15)
+#define PWR_CPU1CR_LPDS_D1			BIT_32(16)
+#define PWR_CPU1CR_LVDS_D1			BIT_32(17)
+
+/* PWR_CPU2CR register fields */
+#define PWR_CPU2CR_PDDS_D2			BIT_32(0)
+#define PWR_CPU2CR_VBF				BIT_32(4)
+#define PWR_CPU2CR_STOPF			BIT_32(5)
+#define PWR_CPU2CR_SBF				BIT_32(6)
+#define PWR_CPU2CR_SBF_D2			BIT_32(7)
+#define PWR_CPU2CR_SBF_D3			BIT_32(8)
+#define PWR_CPU2CR_CSSF				BIT_32(9)
+#define PWR_CPU2CR_DEEPSLEEP			BIT_32(15)
+#define PWR_CPU2CR_LPDS_D2			BIT_32(16)
+#define PWR_CPU2CR_LVDS_D2			BIT_32(17)
+
+/* PWR_CPU3CR register fields */
+#define PWR_CPU3CR_VBF				BIT_32(4)
+#define PWR_CPU3CR_SBF_D3			BIT_32(8)
+#define PWR_CPU3CR_CSSF				BIT_32(9)
+#define PWR_CPU3CR_DEEPSLEEP			BIT_32(15)
+
+/* PWR_D1CR register fields */
+#define PWR_D1CR_LPCFG_D1			BIT_32(0)
+#define PWR_D1CR_POPL_D1_MASK			GENMASK_32(12, 8)
+#define PWR_D1CR_POPL_D1_SHIFT			U(8)
+
+/* PWR_D2CR register fields */
+#define PWR_D2CR_LPCFG_D2			BIT_32(0)
+#define PWR_D2CR_POPL_D2_MASK			GENMASK_32(12, 8)
+#define PWR_D2CR_POPL_D2_SHIFT			U(8)
+#define PWR_D2CR_LPLVDLY_D2_MASK		GENMASK_32(18, 16)
+#define PWR_D2CR_LPLVDLY_D2_SHIFT		U(16)
+#define PWR_D2CR_PODH_D2_MASK			GENMASK_32(27, 24)
+#define PWR_D2CR_PODH_D2_SHIFT			U(24)
+
+/* PWR_D3CR register fields */
+#define PWR_D3CR_PDDS_D3			BIT_32(0)
+#define PWR_D3CR_D3RDY				BIT_32(31)
+
+/* PWR_WKUPCR1 register fields */
+#define PWR_WKUPCR1_WKUPC			BIT_32(0)
+#define PWR_WKUPCR1_WKUPP			BIT_32(8)
+#define PWR_WKUPCR1_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR1_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR1_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR1_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR1_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR2 register fields */
+#define PWR_WKUPCR2_WKUPC			BIT_32(0)
+#define PWR_WKUPCR2_WKUPP			BIT_32(8)
+#define PWR_WKUPCR2_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR2_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR2_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR2_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR2_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR3 register fields */
+#define PWR_WKUPCR3_WKUPC			BIT_32(0)
+#define PWR_WKUPCR3_WKUPP			BIT_32(8)
+#define PWR_WKUPCR3_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR3_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR3_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR3_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR3_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR4 register fields */
+#define PWR_WKUPCR4_WKUPC			BIT_32(0)
+#define PWR_WKUPCR4_WKUPP			BIT_32(8)
+#define PWR_WKUPCR4_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR4_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR4_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR4_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR4_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR5 register fields */
+#define PWR_WKUPCR5_WKUPC			BIT_32(0)
+#define PWR_WKUPCR5_WKUPP			BIT_32(8)
+#define PWR_WKUPCR5_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR5_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR5_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR5_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR5_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR6 register fields */
+#define PWR_WKUPCR6_WKUPC			BIT_32(0)
+#define PWR_WKUPCR6_WKUPP			BIT_32(8)
+#define PWR_WKUPCR6_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR6_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR6_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR6_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR6_WKUPF			BIT_32(31)
+
+/* PWR_D3WKUPENR register fields */
+#define PWR_D3WKUPENR_TAMP_WKUPEN_D3		BIT_32(0)
+
+/* PWR_RSECCFGR register fields */
+#define PWR_RSECCFGR_RSEC0			BIT_32(0)
+#define PWR_RSECCFGR_RSEC1			BIT_32(1)
+#define PWR_RSECCFGR_RSEC2			BIT_32(2)
+#define PWR_RSECCFGR_RSEC3			BIT_32(3)
+#define PWR_RSECCFGR_RSEC4			BIT_32(4)
+#define PWR_RSECCFGR_RSEC5			BIT_32(5)
+#define PWR_RSECCFGR_RSEC6			BIT_32(6)
+
+/* PWR_RPRIVCFGR register fields */
+#define PWR_RPRIVCFGR_RPRIV0			BIT_32(0)
+#define PWR_RPRIVCFGR_RPRIV1			BIT_32(1)
+#define PWR_RPRIVCFGR_RPRIV2			BIT_32(2)
+#define PWR_RPRIVCFGR_RPRIV3			BIT_32(3)
+#define PWR_RPRIVCFGR_RPRIV4			BIT_32(4)
+#define PWR_RPRIVCFGR_RPRIV5			BIT_32(5)
+#define PWR_RPRIVCFGR_RPRIV6			BIT_32(6)
+
+/* PWR_R0CIDCFGR register fields */
+#define PWR_R0CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R0CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R0CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R1CIDCFGR register fields */
+#define PWR_R1CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R1CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R1CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R2CIDCFGR register fields */
+#define PWR_R2CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R2CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R2CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R3CIDCFGR register fields */
+#define PWR_R3CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R3CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R3CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R4CIDCFGR register fields */
+#define PWR_R4CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R4CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R4CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R5CIDCFGR register fields */
+#define PWR_R5CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R5CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R5CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R6CIDCFGR register fields */
+#define PWR_R6CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R6CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R6CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_WIOSECCFGR register fields */
+#define PWR_WIOSECCFGR_WIOSEC1			BIT_32(0)
+#define PWR_WIOSECCFGR_WIOSEC2			BIT_32(1)
+#define PWR_WIOSECCFGR_WIOSEC3			BIT_32(2)
+#define PWR_WIOSECCFGR_WIOSEC4			BIT_32(3)
+#define PWR_WIOSECCFGR_WIOSEC5			BIT_32(4)
+#define PWR_WIOSECCFGR_WIOSEC6			BIT_32(5)
+
+/* PWR_WIOPRIVCFGR register fields */
+#define PWR_WIOPRIVCFGR_WIOPRIV1		BIT_32(0)
+#define PWR_WIOPRIVCFGR_WIOPRIV2		BIT_32(1)
+#define PWR_WIOPRIVCFGR_WIOPRIV3		BIT_32(2)
+#define PWR_WIOPRIVCFGR_WIOPRIV4		BIT_32(3)
+#define PWR_WIOPRIVCFGR_WIOPRIV5		BIT_32(4)
+#define PWR_WIOPRIVCFGR_WIOPRIV6		BIT_32(5)
+
+/* PWR_WIO1CIDCFGR register fields */
+#define PWR_WIO1CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO1CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO1CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO1CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO1CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO1CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO1CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO1CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO1CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO1CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO1CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO1CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO1SEMCR register fields */
+#define PWR_WIO1SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO1SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO1SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO2CIDCFGR register fields */
+#define PWR_WIO2CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO2CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO2CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO2CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO2CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO2CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO2CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO2CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO2CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO2CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO2CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO2CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO2SEMCR register fields */
+#define PWR_WIO2SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO2SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO2SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO3CIDCFGR register fields */
+#define PWR_WIO3CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO3CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO3CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO3CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO3CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO3CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO3CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO3CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO3CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO3CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO3CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO3CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO3SEMCR register fields */
+#define PWR_WIO3SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO3SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO3SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO4CIDCFGR register fields */
+#define PWR_WIO4CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO4CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO4CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO4CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO4CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO4CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO4CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO4CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO4CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO4CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO4CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO4CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO4SEMCR register fields */
+#define PWR_WIO4SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO4SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO4SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO5CIDCFGR register fields */
+#define PWR_WIO5CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO5CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO5CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO5CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO5CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO5CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO5CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO5CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO5CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO5CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO5CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO5CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO5SEMCR register fields */
+#define PWR_WIO5SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO5SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO5SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO6CIDCFGR register fields */
+#define PWR_WIO6CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO6CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO6CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO6CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO6CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO6CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO6CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO6CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO6CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO6CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO6CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO6CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO6SEMCR register fields */
+#define PWR_WIO6SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO6SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO6SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_CPU1D1SR register fields */
+#define PWR_CPU1D1SR_HOLD_BOOT			BIT_32(0)
+#define PWR_CPU1D1SR_CSTATE_MASK		GENMASK_32(3, 2)
+#define PWR_CPU1D1SR_CSTATE_SHIFT		U(2)
+#define PWR_CPU1D1SR_DSTATE_MASK		GENMASK_32(10, 8)
+#define PWR_CPU1D1SR_DSTATE_SHIFT		U(8)
+
+/* PWR_CPU2D2SR register fields */
+#define PWR_CPU2D2SR_HOLD_BOOT			BIT_32(0)
+#define PWR_CPU2D2SR_WFBEN			BIT_32(1)
+#define PWR_CPU2D2SR_CSTATE_MASK		GENMASK_32(3, 2)
+#define PWR_CPU2D2SR_CSTATE_SHIFT		U(2)
+#define PWR_CPU2D2SR_DSTATE_MASK		GENMASK_32(10, 8)
+#define PWR_CPU2D2SR_DSTATE_SHIFT		U(8)
+
+/* PWR_CPU3D3SR register fields */
+#define PWR_CPU3D3SR_CSTATE_MASK		GENMASK_32(3, 2)
+#define PWR_CPU3D3SR_CSTATE_SHIFT		U(2)
+#define PWR_CPU3D3SR_DSTATE_MASK		GENMASK_32(10, 8)
+#define PWR_CPU3D3SR_DSTATE_SHIFT		U(8)
+
+/* PWR_DBGR register fields */
+#define PWR_DBGR_FD3S				BIT_32(0)
+#define PWR_DBGR_VDDIOKRETRAM			BIT_32(16)
+#define PWR_DBGR_VDDIOKBKPRAM			BIT_32(17)
+#define PWR_DBGR_VDDIOKD3			BIT_32(18)
+#define PWR_DBGR_VDDIOKLPSRAM1			BIT_32(19)
+
+/* PWR_VERR register fields */
+#define PWR_VERR_MINREV_MASK			GENMASK_32(3, 0)
+#define PWR_VERR_MINREV_SHIFT			U(0)
+#define PWR_VERR_MAJREV_MASK			GENMASK_32(7, 4)
+#define PWR_VERR_MAJREV_SHIFT			U(4)
+
+#endif /* STM32MP2_PWR_H */
diff --git a/include/drivers/st/stm32mp2_ram.h b/include/drivers/st/stm32mp2_ram.h
new file mode 100644
index 0000000..b6fa928
--- /dev/null
+++ b/include/drivers/st/stm32mp2_ram.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_RAM_H
+#define STM32MP2_RAM_H
+
+bool stm32mp2_ddr_is_restored(void);
+int stm32mp2_ddr_probe(void);
+
+#endif /* STM32MP2_RAM_H */
diff --git a/include/drivers/st/stm32mp_ddr.h b/include/drivers/st/stm32mp_ddr.h
index 4535e3c..57b0668 100644
--- a/include/drivers/st/stm32mp_ddr.h
+++ b/include/drivers/st/stm32mp_ddr.h
@@ -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
  */
@@ -26,9 +26,11 @@
 };
 
 struct stm32mp_ddr_reg_desc {
-	const char *name;
 	uint16_t offset;	/* Offset for base address */
 	uint8_t par_offset;	/* Offset for parameter array */
+#if !STM32MP13 && !STM32MP15
+	bool qd; /* quasi-dynamic register if true */
+#endif
 };
 
 struct stm32mp_ddr_reg_info {
@@ -57,13 +59,26 @@
 	size_t size;    /* Memory size in byte = col * row * width */
 };
 
-#define TIMEOUT_US_1S	1000000U
+#define DDR_DELAY_1US		1U
+#define DDR_DELAY_2US		2U
+#define DDR_DELAY_10US		10U
+#define DDR_DELAY_50US		50U
+#define DDR_TIMEOUT_500US	500U
+#define DDR_TIMEOUT_US_1S	1000000U
 
 void stm32mp_ddr_set_reg(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_reg_type type,
 			 const void *param, const struct stm32mp_ddr_reg_info *ddr_registers);
 void stm32mp_ddr_start_sw_done(struct stm32mp_ddrctl *ctl);
 void stm32mp_ddr_wait_sw_done_ack(struct stm32mp_ddrctl *ctl);
 void stm32mp_ddr_enable_axi_port(struct stm32mp_ddrctl *ctl);
+int stm32mp_ddr_disable_axi_port(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_enable_host_interface(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_disable_host_interface(struct stm32mp_ddrctl *ctl);
+int stm32mp_ddr_sw_selfref_entry(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_sw_selfref_exit(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_set_qd3_update_conditions(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_unset_qd3_update_conditions(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_wait_refresh_update_done_ack(struct stm32mp_ddrctl *ctl);
 int stm32mp_board_ddr_power_init(enum ddr_type ddr_type);
 
 #endif /* STM32MP_DDR_H */
diff --git a/include/drivers/st/stm32mp_ddrctrl_regs.h b/include/drivers/st/stm32mp_ddrctrl_regs.h
index 79de86b..f9f46aa 100644
--- a/include/drivers/st/stm32mp_ddrctrl_regs.h
+++ b/include/drivers/st/stm32mp_ddrctrl_regs.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
  */
@@ -51,7 +51,8 @@
 	uint32_t init7;		/* 0xec SDRAM Initialization 7 */
 	uint32_t dimmctl;	/* 0xf0 DIMM Control */
 	uint32_t rankctl;	/* 0xf4 Rank Control */
-	uint8_t reserved0f4[0x100 - 0xf8];
+	uint32_t rankctl1;	/* 0xf8 Rank Control 1 */
+	uint8_t reserved0fc[0x100 - 0xfc];
 	uint32_t dramtmg0;	/* 0x100 SDRAM Timing 0 */
 	uint32_t dramtmg1;	/* 0x104 SDRAM Timing 1 */
 	uint32_t dramtmg2;	/* 0x108 SDRAM Timing 2 */
@@ -112,7 +113,9 @@
 	uint32_t perflpr1;	/* 0x264 Low Priority Read CAM 1 */
 	uint32_t reserved268;
 	uint32_t perfwr1;	/* 0x26c Write CAM 1 */
-	uint8_t reserved27c[0x300 - 0x270];
+	uint32_t sched3;	/* 0x270 Scheduler Control 3 */
+	uint32_t sched4;	/* 0x274 Scheduler Control 4 */
+	uint8_t reserved278[0x300 - 0x278];
 	uint32_t dbg0;		/* 0x300 Debug 0 */
 	uint32_t dbg1;		/* 0x304 Debug 1 */
 	uint32_t dbgcam;	/* 0x308 CAM Debug */
@@ -121,7 +124,8 @@
 	uint8_t reserved314[0x320 - 0x314];
 	uint32_t swctl;		/* 0x320 Software Programming Control Enable */
 	uint32_t swstat;	/* 0x324 Software Programming Control Status */
-	uint8_t reserved328[0x36c - 0x328];
+	uint32_t swctlstatic;	/* 0x328 Statics Write Enable */
+	uint8_t reserved32c[0x36c - 0x32c];
 	uint32_t poisoncfg;	/* 0x36c AXI Poison Configuration Register */
 	uint32_t poisonstat;	/* 0x370 AXI Poison Status Register */
 	uint8_t reserved374[0x3f0 - 0x374];
@@ -153,7 +157,7 @@
 	uint32_t pcfgqos1_1;	/* 0x548 Read QoS Configuration 1 */
 	uint32_t pcfgwqos0_1;	/* 0x54c Write QoS Configuration 0 */
 	uint32_t pcfgwqos1_1;	/* 0x550 Write QoS Configuration 1 */
-#endif
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
 
 	uint8_t reserved554[0xff0 - 0x554];
 	uint32_t umctl2_ver_number;	/* 0xff0 UMCTL2 Version Number */
@@ -170,6 +174,7 @@
 #define DDRCTRL_RFSHCTL3			0x060
 #define DDRCTRL_RFSHTMG				0x064
 #define DDRCTRL_INIT0				0x0D0
+#define DDRCTRL_DFILPCFG0			0x198
 #define DDRCTRL_DFIMISC				0x1B0
 #define DDRCTRL_DBG1				0x304
 #define DDRCTRL_DBGCAM				0x308
@@ -181,7 +186,7 @@
 #define DDRCTRL_PCTRL_0				0x490
 #if STM32MP_DDR_DUAL_AXI_PORT
 #define DDRCTRL_PCTRL_1				0x540
-#endif
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
 
 /* DDR Controller Register fields */
 #define DDRCTRL_MSTR_DDR3			BIT(0)
@@ -201,6 +206,8 @@
 #define DDRCTRL_STAT_SELFREF_TYPE_MASK		GENMASK(5, 4)
 #define DDRCTRL_STAT_SELFREF_TYPE_ASR		(BIT(4) | BIT(5))
 #define DDRCTRL_STAT_SELFREF_TYPE_SR		BIT(5)
+#define DDRCTRL_STAT_SELFREF_STATE_MASK		GENMASK(9, 8)
+#define DDRCTRL_STAT_SELFREF_STATE_SRPD		BIT(9)
 
 #define DDRCTRL_MRCTRL0_MR_TYPE_WRITE		U(0)
 /* Only one rank supported */
@@ -217,6 +224,7 @@
 #define DDRCTRL_PWRCTL_POWERDOWN_EN		BIT(1)
 #define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE	BIT(3)
 #define DDRCTRL_PWRCTL_SELFREF_SW		BIT(5)
+#define DDRCTRL_PWRCTL_STAY_IN_SELFREF		BIT(6)
 
 #define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK	GENMASK(23, 16)
 #define DDRCTRL_PWRTMG_SELFREF_TO_X32_0		BIT(16)
@@ -225,6 +233,9 @@
 #define DDRCTRL_RFSHCTL3_REFRESH_UPDATE_LEVEL	BIT(1)
 
 #define DDRCTRL_HWLPCTL_HW_LP_EN		BIT(0)
+#define DDRCTRL_HWLPCTL_HW_LP_EXIT_IDLE_EN	BIT(1)
+#define DDRCTRL_HWLPCTL_HW_LP_IDLE_X32_MASK	GENMASK(27, 16)
+#define DDRCTRL_HWLPCTL_HW_LP_IDLE_X32_SHIFT	16
 
 #define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK	GENMASK(27, 16)
 #define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT	16
@@ -232,21 +243,31 @@
 #define DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK	GENMASK(31, 30)
 #define DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL	BIT(30)
 
+#define DDRCTRL_DFILPCFG0_DFI_LP_EN_SR		BIT(8)
+
 #define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN	BIT(0)
 #define DDRCTRL_DFIMISC_DFI_INIT_START		BIT(5)
+#define DDRCTRL_DFIMISC_DFI_FREQUENCY		GENMASK(12, 8)
 
 #define DDRCTRL_DFISTAT_DFI_INIT_COMPLETE	BIT(0)
+#define DDRCTRL_DFISTAT_DFI_LP_ACK		BIT(1)
 
+#define DDRCTRL_DBG1_DIS_DQ			BIT(0)
 #define DDRCTRL_DBG1_DIS_HIF			BIT(1)
 
 #define DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY	BIT(29)
 #define DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY	BIT(28)
 #define DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY		BIT(26)
+#define DDRCTRL_DBGCAM_DBG_RD_Q_EMPTY		BIT(25)
 #define DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH		GENMASK(12, 8)
 #define DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH		GENMASK(4, 0)
 #define DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY \
 		(DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY | \
 		 DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY)
+#define DDRCTRL_DBG_Q_AND_DATA_PIPELINE_EMPTY \
+		(DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \
+		 DDRCTRL_DBGCAM_DBG_RD_Q_EMPTY | \
+		 DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY)
 #define DDRCTRL_DBGCAM_DBG_Q_DEPTH \
 		(DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \
 		 DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH | \
diff --git a/include/drivers/st/stm32mp_pmic.h b/include/drivers/st/stm32mp_pmic.h
index 303c571..7384571 100644
--- a/include/drivers/st/stm32mp_pmic.h
+++ b/include/drivers/st/stm32mp_pmic.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
  */
@@ -42,13 +42,6 @@
 #endif
 
 /*
- * pmic_ddr_power_init - Initialize regulators required for DDR
- *
- * Returns 0 on success, and negative values on errors
- */
-int pmic_ddr_power_init(enum ddr_type ddr_type);
-
-/*
  * pmic_voltages_init - Update voltages for platform init
  *
  * Returns 0 on success, and negative values on errors
diff --git a/include/drivers/st/stm32mp_pmic2.h b/include/drivers/st/stm32mp_pmic2.h
new file mode 100644
index 0000000..51eba38
--- /dev/null
+++ b/include/drivers/st/stm32mp_pmic2.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_PMIC2_H
+#define STM32MP_PMIC2_H
+
+#include <stdbool.h>
+#include <drivers/st/regulator.h>
+
+#include <platform_def.h>
+
+/*
+ * dt_pmic_status - Check PMIC status from device tree
+ *
+ * Returns the status of the PMIC (secure, non-secure), or a negative value on
+ * error
+ */
+int dt_pmic_status(void);
+
+/*
+ * initialize_pmic_i2c - Initialize I2C for the PMIC control
+ *
+ * Returns true if PMIC is available, false if not found, panics on errors
+ */
+bool initialize_pmic_i2c(void);
+
+/*
+ * initialize_pmic - Main PMIC initialization function, called at platform init
+ *
+ * Panics on errors
+ */
+void initialize_pmic(void);
+
+/*
+ * stpmic2_set_prop - Set PMIC2 proprietary property
+ *
+ * Returns non zero on errors
+ */
+int stpmic2_set_prop(const struct regul_description *desc, uint16_t prop, uint32_t value);
+
+/*
+ * pmic_switch_off - switch off the platform with PMIC
+ *
+ * Panics on errors
+ */
+void pmic_switch_off(void);
+
+#endif /* STM32MP_PMIC2_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/drivers/st/stm32mp_risab_regs.h b/include/drivers/st/stm32mp_risab_regs.h
new file mode 100644
index 0000000..1f49bf6
--- /dev/null
+++ b/include/drivers/st/stm32mp_risab_regs.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_RISAB_REGS_H
+#define STM32MP_RISAB_REGS_H
+
+#define RISAB_CR				U(0x00)
+#define RISAB_IASR				U(0x08)
+#define RISAB_IACR				U(0x0C)
+#define RISAB_RIFLOCKR				U(0x10)
+#define RISAB_IAESR				U(0x20)
+#define RISAB_IADDR				U(0x24)
+#define RISAB_PG0_SECCFGR			U(0x100)
+#define RISAB_PG1_SECCFGR			U(0x104)
+#define RISAB_PG2_SECCFGR			U(0x108)
+#define RISAB_PG3_SECCFGR			U(0x10C)
+#define RISAB_PG4_SECCFGR			U(0x110)
+#define RISAB_PG5_SECCFGR			U(0x114)
+#define RISAB_PG6_SECCFGR			U(0x118)
+#define RISAB_PG7_SECCFGR			U(0x11C)
+#define RISAB_PG8_SECCFGR			U(0x120)
+#define RISAB_PG9_SECCFGR			U(0x124)
+#define RISAB_PG10_SECCFGR			U(0x128)
+#define RISAB_PG11_SECCFGR			U(0x12C)
+#define RISAB_PG12_SECCFGR			U(0x130)
+#define RISAB_PG13_SECCFGR			U(0x134)
+#define RISAB_PG14_SECCFGR			U(0x138)
+#define RISAB_PG15_SECCFGR			U(0x13C)
+#define RISAB_PG16_SECCFGR			U(0x140)
+#define RISAB_PG17_SECCFGR			U(0x144)
+#define RISAB_PG18_SECCFGR			U(0x148)
+#define RISAB_PG19_SECCFGR			U(0x14C)
+#define RISAB_PG20_SECCFGR			U(0x150)
+#define RISAB_PG21_SECCFGR			U(0x154)
+#define RISAB_PG22_SECCFGR			U(0x158)
+#define RISAB_PG23_SECCFGR			U(0x15C)
+#define RISAB_PG24_SECCFGR			U(0x160)
+#define RISAB_PG25_SECCFGR			U(0x164)
+#define RISAB_PG26_SECCFGR			U(0x168)
+#define RISAB_PG27_SECCFGR			U(0x16C)
+#define RISAB_PG28_SECCFGR			U(0x170)
+#define RISAB_PG29_SECCFGR			U(0x174)
+#define RISAB_PG30_SECCFGR			U(0x178)
+#define RISAB_PG31_SECCFGR			U(0x17C)
+#define RISAB_PG0_PRIVCFGR			U(0x200)
+#define RISAB_PG1_PRIVCFGR			U(0x204)
+#define RISAB_PG2_PRIVCFGR			U(0x208)
+#define RISAB_PG3_PRIVCFGR			U(0x20C)
+#define RISAB_PG4_PRIVCFGR			U(0x210)
+#define RISAB_PG5_PRIVCFGR			U(0x214)
+#define RISAB_PG6_PRIVCFGR			U(0x218)
+#define RISAB_PG7_PRIVCFGR			U(0x21C)
+#define RISAB_PG8_PRIVCFGR			U(0x220)
+#define RISAB_PG9_PRIVCFGR			U(0x224)
+#define RISAB_PG10_PRIVCFGR			U(0x228)
+#define RISAB_PG11_PRIVCFGR			U(0x22C)
+#define RISAB_PG12_PRIVCFGR			U(0x230)
+#define RISAB_PG13_PRIVCFGR			U(0x234)
+#define RISAB_PG14_PRIVCFGR			U(0x238)
+#define RISAB_PG15_PRIVCFGR			U(0x23C)
+#define RISAB_PG16_PRIVCFGR			U(0x240)
+#define RISAB_PG17_PRIVCFGR			U(0x244)
+#define RISAB_PG18_PRIVCFGR			U(0x248)
+#define RISAB_PG19_PRIVCFGR			U(0x24C)
+#define RISAB_PG20_PRIVCFGR			U(0x250)
+#define RISAB_PG21_PRIVCFGR			U(0x254)
+#define RISAB_PG22_PRIVCFGR			U(0x258)
+#define RISAB_PG23_PRIVCFGR			U(0x25C)
+#define RISAB_PG24_PRIVCFGR			U(0x260)
+#define RISAB_PG25_PRIVCFGR			U(0x264)
+#define RISAB_PG26_PRIVCFGR			U(0x268)
+#define RISAB_PG27_PRIVCFGR			U(0x26C)
+#define RISAB_PG28_PRIVCFGR			U(0x270)
+#define RISAB_PG29_PRIVCFGR			U(0x274)
+#define RISAB_PG30_PRIVCFGR			U(0x278)
+#define RISAB_PG31_PRIVCFGR			U(0x27C)
+#define RISAB_PG0_C2PRIVCFGR			U(0x600)
+#define RISAB_PG1_C2PRIVCFGR			U(0x604)
+#define RISAB_PG2_C2PRIVCFGR			U(0x608)
+#define RISAB_PG3_C2PRIVCFGR			U(0x60C)
+#define RISAB_PG4_C2PRIVCFGR			U(0x610)
+#define RISAB_PG5_C2PRIVCFGR			U(0x614)
+#define RISAB_PG6_C2PRIVCFGR			U(0x618)
+#define RISAB_PG7_C2PRIVCFGR			U(0x61C)
+#define RISAB_PG8_C2PRIVCFGR			U(0x620)
+#define RISAB_PG9_C2PRIVCFGR			U(0x624)
+#define RISAB_PG10_C2PRIVCFGR			U(0x628)
+#define RISAB_PG11_C2PRIVCFGR			U(0x62C)
+#define RISAB_PG12_C2PRIVCFGR			U(0x630)
+#define RISAB_PG13_C2PRIVCFGR			U(0x634)
+#define RISAB_PG14_C2PRIVCFGR			U(0x638)
+#define RISAB_PG15_C2PRIVCFGR			U(0x63C)
+#define RISAB_PG16_C2PRIVCFGR			U(0x640)
+#define RISAB_PG17_C2PRIVCFGR			U(0x644)
+#define RISAB_PG18_C2PRIVCFGR			U(0x648)
+#define RISAB_PG19_C2PRIVCFGR			U(0x64C)
+#define RISAB_PG20_C2PRIVCFGR			U(0x650)
+#define RISAB_PG21_C2PRIVCFGR			U(0x654)
+#define RISAB_PG22_C2PRIVCFGR			U(0x658)
+#define RISAB_PG23_C2PRIVCFGR			U(0x65C)
+#define RISAB_PG24_C2PRIVCFGR			U(0x660)
+#define RISAB_PG25_C2PRIVCFGR			U(0x664)
+#define RISAB_PG26_C2PRIVCFGR			U(0x668)
+#define RISAB_PG27_C2PRIVCFGR			U(0x66C)
+#define RISAB_PG28_C2PRIVCFGR			U(0x670)
+#define RISAB_PG29_C2PRIVCFGR			U(0x674)
+#define RISAB_PG30_C2PRIVCFGR			U(0x678)
+#define RISAB_PG31_C2PRIVCFGR			U(0x67C)
+#define RISAB_CID0PRIVCFGR			U(0x800)
+#define RISAB_CID0RDCFGR			U(0x808)
+#define RISAB_CID0WRCFGR			U(0x810)
+#define RISAB_CID1PRIVCFGR			U(0x820)
+#define RISAB_CID1RDCFGR			U(0x828)
+#define RISAB_CID1WRCFGR			U(0x830)
+#define RISAB_CID2PRIVCFGR			U(0x840)
+#define RISAB_CID2RDCFGR			U(0x848)
+#define RISAB_CID2WRCFGR			U(0x850)
+#define RISAB_CID3PRIVCFGR			U(0x860)
+#define RISAB_CID3RDCFGR			U(0x868)
+#define RISAB_CID3WRCFGR			U(0x870)
+#define RISAB_CID4PRIVCFGR			U(0x880)
+#define RISAB_CID4RDCFGR			U(0x888)
+#define RISAB_CID4WRCFGR			U(0x890)
+#define RISAB_CID5PRIVCFGR			U(0x8A0)
+#define RISAB_CID5RDCFGR			U(0x8A8)
+#define RISAB_CID5WRCFGR			U(0x8B0)
+#define RISAB_CID6PRIVCFGR			U(0x8C0)
+#define RISAB_CID6RDCFGR			U(0x8C8)
+#define RISAB_CID6WRCFGR			U(0x8D0)
+#define RISAB_PG0_CIDCFGR			U(0xA00)
+#define RISAB_PG1_CIDCFGR			U(0xA04)
+#define RISAB_PG2_CIDCFGR			U(0xA08)
+#define RISAB_PG3_CIDCFGR			U(0xA0C)
+#define RISAB_PG4_CIDCFGR			U(0xA10)
+#define RISAB_PG5_CIDCFGR			U(0xA14)
+#define RISAB_PG6_CIDCFGR			U(0xA18)
+#define RISAB_PG7_CIDCFGR			U(0xA1C)
+#define RISAB_PG8_CIDCFGR			U(0xA20)
+#define RISAB_PG9_CIDCFGR			U(0xA24)
+#define RISAB_PG10_CIDCFGR			U(0xA28)
+#define RISAB_PG11_CIDCFGR			U(0xA2C)
+#define RISAB_PG12_CIDCFGR			U(0xA30)
+#define RISAB_PG13_CIDCFGR			U(0xA34)
+#define RISAB_PG14_CIDCFGR			U(0xA38)
+#define RISAB_PG15_CIDCFGR			U(0xA3C)
+#define RISAB_PG16_CIDCFGR			U(0xA40)
+#define RISAB_PG17_CIDCFGR			U(0xA44)
+#define RISAB_PG18_CIDCFGR			U(0xA48)
+#define RISAB_PG19_CIDCFGR			U(0xA4C)
+#define RISAB_PG20_CIDCFGR			U(0xA50)
+#define RISAB_PG21_CIDCFGR			U(0xA54)
+#define RISAB_PG22_CIDCFGR			U(0xA58)
+#define RISAB_PG23_CIDCFGR			U(0xA5C)
+#define RISAB_PG24_CIDCFGR			U(0xA60)
+#define RISAB_PG25_CIDCFGR			U(0xA64)
+#define RISAB_PG26_CIDCFGR			U(0xA68)
+#define RISAB_PG27_CIDCFGR			U(0xA6C)
+#define RISAB_PG28_CIDCFGR			U(0xA70)
+#define RISAB_PG29_CIDCFGR			U(0xA74)
+#define RISAB_PG30_CIDCFGR			U(0xA78)
+#define RISAB_PG31_CIDCFGR			U(0xA7C)
+#define RISAB_HWCFGR3				U(0xFE8)
+#define RISAB_HWCFGR2				U(0xFEC)
+#define RISAB_HWCFGR1				U(0xFF0)
+#define RISAB_VERR				U(0xFF4)
+#define RISAB_IPIDR				U(0xFF8)
+#define RISAB_SIDR				U(0xFFC)
+
+/* RISAB_CR register fields */
+#define RISAB_CR_GLOCK				BIT(0)
+#define RISAB_CR_SRWIAD				BIT(31)
+
+/* RISAB_IASR register fields */
+#define RISAB_IASR_CAEF				BIT(0)
+#define RISAB_IASR_IAEF				BIT(1)
+
+/* RISAB_IACR register fields */
+#define RISAB_IACR_CAEF				BIT(0)
+#define RISAB_IACR_IAEF				BIT(1)
+
+/* RISAB_RIFLOCKR register fields */
+#define RISAB_RIFLOCKR_RLOCK0			BIT(0)
+#define RISAB_RIFLOCKR_RLOCK1			BIT(1)
+#define RISAB_RIFLOCKR_RLOCK2			BIT(2)
+#define RISAB_RIFLOCKR_RLOCK3			BIT(3)
+#define RISAB_RIFLOCKR_RLOCK4			BIT(4)
+#define RISAB_RIFLOCKR_RLOCK5			BIT(5)
+#define RISAB_RIFLOCKR_RLOCK6			BIT(6)
+#define RISAB_RIFLOCKR_RLOCK7			BIT(7)
+#define RISAB_RIFLOCKR_RLOCK8			BIT(8)
+#define RISAB_RIFLOCKR_RLOCK9			BIT(9)
+#define RISAB_RIFLOCKR_RLOCK10			BIT(10)
+#define RISAB_RIFLOCKR_RLOCK11			BIT(11)
+#define RISAB_RIFLOCKR_RLOCK12			BIT(12)
+#define RISAB_RIFLOCKR_RLOCK13			BIT(13)
+#define RISAB_RIFLOCKR_RLOCK14			BIT(14)
+#define RISAB_RIFLOCKR_RLOCK15			BIT(15)
+#define RISAB_RIFLOCKR_RLOCK16			BIT(16)
+#define RISAB_RIFLOCKR_RLOCK17			BIT(17)
+#define RISAB_RIFLOCKR_RLOCK18			BIT(18)
+#define RISAB_RIFLOCKR_RLOCK19			BIT(19)
+#define RISAB_RIFLOCKR_RLOCK20			BIT(20)
+#define RISAB_RIFLOCKR_RLOCK21			BIT(21)
+#define RISAB_RIFLOCKR_RLOCK22			BIT(22)
+#define RISAB_RIFLOCKR_RLOCK23			BIT(23)
+#define RISAB_RIFLOCKR_RLOCK24			BIT(24)
+#define RISAB_RIFLOCKR_RLOCK25			BIT(25)
+#define RISAB_RIFLOCKR_RLOCK26			BIT(26)
+#define RISAB_RIFLOCKR_RLOCK27			BIT(27)
+#define RISAB_RIFLOCKR_RLOCK28			BIT(28)
+#define RISAB_RIFLOCKR_RLOCK29			BIT(29)
+#define RISAB_RIFLOCKR_RLOCK30			BIT(30)
+#define RISAB_RIFLOCKR_RLOCK31			BIT(31)
+
+/* RISAB_IAESR register fields */
+#define RISAB_IAESR_IACID_MASK			GENMASK(2, 0)
+#define RISAB_IAESR_IACID_SHIFT			0
+#define RISAB_IAESR_IAPRIV			BIT(4)
+#define RISAB_IAESR_IASEC			BIT(5)
+#define RISAB_IAESR_IANRW			BIT(7)
+
+/* RISAB_PGx_SECCFGR register fields */
+#define RISAB_PGx_SECCFGR_SEC(_y)		BIT(_y)
+
+/* RISAB_PGx_PRIVCFGR register fields */
+#define RISAB_PGx_PRIVCFGR_PRIV(_y)		BIT(_y)
+
+/* RISAB_PGx_CmPRIVCFGR register fields */
+#define RISAB_PGx_CmPRIVCFGR_PRIV(_y)		BIT(_y)
+
+/* RISAB_CIDxPRIVCFGR register fields */
+#define RISAB_CIDxPRIVCFGR_PPRIV(_y)		BIT(_y)
+
+/* RISAB_CIDxRDCFGR register fields */
+#define RISAB_CIDxRDCFGR_PRDEN(_y)		BIT(_y)
+
+/* RISAB_CIDxWRCFGR register fields */
+#define RISAB_CIDxWRCFGR_PWREN(_y)		BIT(_y)
+
+/* RISAB_PGx_CIDCFGR register fields */
+#define RISAB_PGx_CIDCFGR_CFEN			BIT(0)
+#define RISAB_PGx_CIDCFGR_DCEN			BIT(2)
+#define RISAB_PGx_CIDCFGR_DCCID_MASK		GENMASK(6, 4)
+#define RISAB_PGx_CIDCFGR_DCCID_SHIFT		4
+
+/* RISAB_HWCFGR1 register fields */
+#define RISAB_HWCFGR1_CFG1_MASK			GENMASK(3, 0)
+#define RISAB_HWCFGR1_CFG1_SHIFT		0
+#define RISAB_HWCFGR1_CFG2_MASK			GENMASK(7, 4)
+#define RISAB_HWCFGR1_CFG2_SHIFT		4
+#define RISAB_HWCFGR1_CFG3_MASK			GENMASK(11, 8)
+#define RISAB_HWCFGR1_CFG3_SHIFT		8
+#define RISAB_HWCFGR1_CFG4_MASK			GENMASK(15, 12)
+#define RISAB_HWCFGR1_CFG4_SHIFT		12
+#define RISAB_HWCFGR1_CFG5_MASK			GENMASK(19, 16)
+#define RISAB_HWCFGR1_CFG5_SHIFT		16
+#define RISAB_HWCFGR1_CFG6_MASK			GENMASK(23, 20)
+#define RISAB_HWCFGR1_CFG6_SHIFT		20
+#define RISAB_HWCFGR1_CFG7_MASK			GENMASK(27, 24)
+#define RISAB_HWCFGR1_CFG7_SHIFT		24
+
+/* RISAB_VERR register fields */
+#define RISAB_VERR_MINREV_MASK			GENMASK(3, 0)
+#define RISAB_VERR_MINREV_SHIFT			0
+#define RISAB_VERR_MAJREV_MASK			GENMASK(7, 4)
+#define RISAB_VERR_MAJREV_SHIFT			4
+
+#endif /* STM32MP_RISAB_REGS_H */
diff --git a/include/drivers/st/stpmic2.h b/include/drivers/st/stpmic2.h
new file mode 100644
index 0000000..58ba64a
--- /dev/null
+++ b/include/drivers/st/stpmic2.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STPMIC2_H
+#define STPMIC2_H
+
+#include <drivers/st/stm32_i2c.h>
+#include <lib/utils_def.h>
+
+enum {
+	STPMIC2_BUCK1 = 0,
+	STPMIC2_BUCK2,
+	STPMIC2_BUCK3,
+	STPMIC2_BUCK4,
+	STPMIC2_BUCK5,
+	STPMIC2_BUCK6,
+	STPMIC2_BUCK7,
+	STPMIC2_REFDDR,
+	STPMIC2_LDO1,
+	STPMIC2_LDO2,
+	STPMIC2_LDO3,
+	STPMIC2_LDO4,
+	STPMIC2_LDO5,
+	STPMIC2_LDO6,
+	STPMIC2_LDO7,
+	STPMIC2_LDO8,
+	STPMIC2_NB_REG
+};
+
+/* Status Registers */
+#define PRODUCT_ID		0x00
+#define VERSION_SR		0x01
+#define TURN_ON_SR		0x02
+#define TURN_OFF_SR		0x03
+#define RESTART_SR		0x04
+#define OCP_SR1			0x05
+#define OCP_SR2			0x06
+#define EN_SR1			0x07
+#define EN_SR2			0x08
+#define FS_CNT_SR1		0x09
+#define FS_CNT_SR2		0x0A
+#define FS_CNT_SR3		0x0B
+#define MODE_SR			0x0C
+/* Control Registers */
+#define MAIN_CR			0x10
+#define VINLOW_CR		0x11
+#define PKEY_LKP_CR		0x12
+#define WDG_CR			0x13
+#define WDG_TMR_CR		0x14
+#define WDG_TMR_SR		0x15
+#define FS_OCP_CR1		0x16
+#define FS_OCP_CR2		0x17
+#define PADS_PULL_CR		0x18
+#define BUCKS_PD_CR1		0x19
+#define BUCKS_PD_CR2		0x1A
+#define LDOS_PD_CR1		0x1B
+#define LDOS_PD_CR2		0x1C
+#define BUCKS_MRST_CR		0x1D
+#define LDOS_MRST_CR		0x1E
+/* Buck CR */
+#define BUCK1_MAIN_CR1		0x20
+#define BUCK1_MAIN_CR2		0x21
+#define BUCK1_ALT_CR1		0x22
+#define BUCK1_ALT_CR2		0x23
+#define BUCK1_PWRCTRL_CR	0x24
+#define BUCK2_MAIN_CR1		0x25
+#define BUCK2_MAIN_CR2		0x26
+#define BUCK2_ALT_CR1		0x27
+#define BUCK2_ALT_CR2		0x28
+#define BUCK2_PWRCTRL_CR	0x29
+#define BUCK3_MAIN_CR1		0x2A
+#define BUCK3_MAIN_CR2		0x2B
+#define BUCK3_ALT_CR1		0x2C
+#define BUCK3_ALT_CR2		0x2D
+#define BUCK3_PWRCTRL_CR	0x2E
+#define BUCK4_MAIN_CR1		0x2F
+#define BUCK4_MAIN_CR2		0x30
+#define BUCK4_ALT_CR1		0x31
+#define BUCK4_ALT_CR2		0x32
+#define BUCK4_PWRCTRL_CR	0x33
+#define BUCK5_MAIN_CR1		0x34
+#define BUCK5_MAIN_CR2		0x35
+#define BUCK5_ALT_CR1		0x36
+#define BUCK5_ALT_CR2		0x37
+#define BUCK5_PWRCTRL_CR	0x38
+#define BUCK6_MAIN_CR1		0x39
+#define BUCK6_MAIN_CR2		0x3A
+#define BUCK6_ALT_CR1		0x3B
+#define BUCK6_ALT_CR2		0x3C
+#define BUCK6_PWRCTRL_CR	0x3D
+#define BUCK7_MAIN_CR1		0x3E
+#define BUCK7_MAIN_CR2		0x3F
+#define BUCK7_ALT_CR1		0x40
+#define BUCK7_ALT_CR2		0x41
+#define BUCK7_PWRCTRL_CR	0x42
+/* LDO CR */
+#define LDO1_MAIN_CR		0x4C
+#define LDO1_ALT_CR		0x4D
+#define LDO1_PWRCTRL_CR		0x4E
+#define LDO2_MAIN_CR		0x4F
+#define LDO2_ALT_CR		0x50
+#define LDO2_PWRCTRL_CR		0x51
+#define LDO3_MAIN_CR		0x52
+#define LDO3_ALT_CR		0x53
+#define LDO3_PWRCTRL_CR		0x54
+#define LDO4_MAIN_CR		0x55
+#define LDO4_ALT_CR		0x56
+#define LDO4_PWRCTRL_CR		0x57
+#define LDO5_MAIN_CR		0x58
+#define LDO5_ALT_CR		0x59
+#define LDO5_PWRCTRL_CR		0x5A
+#define LDO6_MAIN_CR		0x5B
+#define LDO6_ALT_CR		0x5C
+#define LDO6_PWRCTRL_CR		0x5D
+#define LDO7_MAIN_CR		0x5E
+#define LDO7_ALT_CR		0x5F
+#define LDO7_PWRCTRL_CR		0x60
+#define LDO8_MAIN_CR		0x61
+#define LDO8_ALT_CR		0x62
+#define LDO8_PWRCTRL_CR		0x63
+#define REFDDR_MAIN_CR		0x64
+#define REFDDR_ALT_CR		0x65
+#define REFDDR_PWRCTRL_CR	0x66
+/* INTERRUPT CR */
+#define INT_PENDING_R1		0x70
+#define INT_PENDING_R2		0x71
+#define INT_PENDING_R3		0x72
+#define INT_PENDING_R4		0x73
+#define INT_CLEAR_R1		0x74
+#define INT_CLEAR_R2		0x75
+#define INT_CLEAR_R3		0x76
+#define INT_CLEAR_R4		0x77
+#define INT_MASK_R1		0x78
+#define INT_MASK_R2		0x79
+#define INT_MASK_R3		0x7A
+#define INT_MASK_R4		0x7B
+#define INT_SRC_R1		0x7C
+#define INT_SRC_R2		0x7D
+#define INT_SRC_R3		0x7E
+#define INT_SRC_R4		0x7F
+#define INT_DBG_LATCH_R1	0x80
+#define INT_DBG_LATCH_R2	0x81
+#define INT_DBG_LATCH_R3	0x82
+#define INT_DBG_LATCH_R4	0x83
+
+/* BUCKS_MRST_CR bits definition */
+#define BUCK1_MRST		BIT(0)
+#define BUCK2_MRST		BIT(1)
+#define BUCK3_MRST		BIT(2)
+#define BUCK4_MRST		BIT(3)
+#define BUCK5_MRST		BIT(4)
+#define BUCK6_MRST		BIT(5)
+#define BUCK7_MRST		BIT(6)
+#define REFDDR_MRST		BIT(7)
+
+/* LDOS_MRST_CR bits definition */
+#define LDO1_MRST		BIT(0)
+#define LDO2_MRST		BIT(1)
+#define LDO3_MRST		BIT(2)
+#define LDO4_MRST		BIT(3)
+#define LDO5_MRST		BIT(4)
+#define LDO6_MRST		BIT(5)
+#define LDO7_MRST		BIT(6)
+#define LDO8_MRST		BIT(7)
+
+/* LDOx_MAIN_CR */
+#define LDO_VOLT_SHIFT		1
+#define LDO_BYPASS		BIT(6)
+#define LDO1_INPUT_SRC		BIT(7)
+#define LDO3_SNK_SRC		BIT(7)
+#define LDO4_INPUT_SRC_SHIFT	6
+#define LDO4_INPUT_SRC_MASK	GENMASK_32(7, 6)
+
+/* PWRCTRL register bit definition */
+#define PWRCTRL_EN		BIT(0)
+#define PWRCTRL_RS		BIT(1)
+#define PWRCTRL_SEL_SHIFT	2
+#define PWRCTRL_SEL_MASK	GENMASK_32(3, 2)
+
+/* BUCKx_MAIN_CR2 */
+#define PREG_MODE_SHIFT		1
+#define PREG_MODE_MASK		GENMASK_32(2, 1)
+
+/* BUCKS_PD_CR1 */
+#define BUCK1_PD_MASK		GENMASK_32(1, 0)
+#define BUCK2_PD_MASK		GENMASK_32(3, 2)
+#define BUCK3_PD_MASK		GENMASK_32(5, 4)
+#define BUCK4_PD_MASK		GENMASK_32(7, 6)
+
+#define BUCK1_PD_FAST		BIT(1)
+#define BUCK2_PD_FAST		BIT(3)
+#define BUCK3_PD_FAST		BIT(5)
+#define BUCK4_PD_FAST		BIT(7)
+
+/* BUCKS_PD_CR2 */
+#define BUCK5_PD_MASK		GENMASK_32(1, 0)
+#define BUCK6_PD_MASK		GENMASK_32(3, 2)
+#define BUCK7_PD_MASK		GENMASK_32(5, 4)
+
+#define BUCK5_PD_FAST		BIT(1)
+#define BUCK6_PD_FAST		BIT(3)
+#define BUCK7_PD_FAST		BIT(5)
+
+/* LDOS_PD_CR1 */
+#define LDO1_PD			BIT(0)
+#define LDO2_PD			BIT(1)
+#define LDO3_PD			BIT(2)
+#define LDO4_PD			BIT(3)
+#define LDO5_PD			BIT(4)
+#define LDO6_PD			BIT(5)
+#define LDO7_PD			BIT(6)
+#define LDO8_PD			BIT(7)
+
+/* LDOS_PD_CR2 */
+#define REFDDR_PD		BIT(0)
+
+/* FS_OCP_CR1 */
+#define FS_OCP_BUCK1		BIT(0)
+#define FS_OCP_BUCK2		BIT(1)
+#define FS_OCP_BUCK3		BIT(2)
+#define FS_OCP_BUCK4		BIT(3)
+#define FS_OCP_BUCK5		BIT(4)
+#define FS_OCP_BUCK6		BIT(5)
+#define FS_OCP_BUCK7		BIT(6)
+#define FS_OCP_REFDDR		BIT(7)
+
+/* FS_OCP_CR2 */
+#define FS_OCP_LDO1		BIT(0)
+#define FS_OCP_LDO2		BIT(1)
+#define FS_OCP_LDO3		BIT(2)
+#define FS_OCP_LDO4		BIT(3)
+#define FS_OCP_LDO5		BIT(4)
+#define FS_OCP_LDO6		BIT(5)
+#define FS_OCP_LDO7		BIT(6)
+#define FS_OCP_LDO8		BIT(7)
+
+/* IRQ definitions */
+#define IT_PONKEY_F	0
+#define IT_PONKEY_R	1
+#define IT_BUCK1_OCP	16
+#define IT_BUCK2_OCP	17
+#define IT_BUCK3_OCP	18
+#define IT_BUCK4_OCP	19
+#define IT_BUCK5_OCP	20
+#define IT_BUCK6_OCP	21
+#define IT_BUCK7_OCP	22
+#define IT_REFDDR_OCP	23
+#define IT_LDO1_OCP	24
+#define IT_LDO2_OCP	25
+#define IT_LDO3_OCP	26
+#define IT_LDO4_OCP	27
+#define IT_LDO5_OCP	28
+#define IT_LDO6_OCP	29
+#define IT_LDO7_OCP	30
+#define IT_LDO8_OCP	31
+
+enum stpmic2_prop_id {
+	STPMIC2_MASK_RESET = 0,
+	STPMIC2_PULL_DOWN,
+	STPMIC2_BYPASS,		/* arg: 1=set 0=reset */
+	STPMIC2_SINK_SOURCE,
+	STPMIC2_OCP,
+};
+
+struct pmic_handle_s {
+	struct i2c_handle_s *i2c_handle;
+	uint32_t i2c_addr;
+	unsigned int pmic_status;
+};
+
+int stpmic2_register_read(struct pmic_handle_s *pmic,
+			  uint8_t register_id, uint8_t *value);
+int stpmic2_register_write(struct pmic_handle_s *pmic,
+			   uint8_t register_id, uint8_t value);
+int stpmic2_register_update(struct pmic_handle_s *pmic,
+			    uint8_t register_id, uint8_t value, uint8_t mask);
+
+int stpmic2_regulator_set_state(struct pmic_handle_s *pmic,
+				uint8_t id, bool enable);
+int stpmic2_regulator_get_state(struct pmic_handle_s *pmic,
+				uint8_t id, bool *enabled);
+
+int stpmic2_regulator_levels_mv(struct pmic_handle_s *pmic,
+				uint8_t id, const uint16_t **levels,
+				size_t *levels_count);
+int stpmic2_regulator_get_voltage(struct pmic_handle_s *pmic,
+				  uint8_t id, uint16_t *val);
+int stpmic2_regulator_set_voltage(struct pmic_handle_s *pmic,
+				  uint8_t id, uint16_t millivolts);
+
+#if EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE
+void stpmic2_dump_regulators(struct pmic_handle_s *pmic);
+#endif
+
+int stpmic2_get_version(struct pmic_handle_s *pmic, uint8_t *val);
+int stpmic2_get_product_id(struct pmic_handle_s *pmic, uint8_t *val);
+
+int stpmic2_regulator_get_prop(struct pmic_handle_s *pmic, uint8_t id,
+			       enum stpmic2_prop_id prop);
+
+int stpmic2_regulator_set_prop(struct pmic_handle_s *pmic, uint8_t id,
+			       enum stpmic2_prop_id prop, uint32_t arg);
+
+#endif /*STPMIC2_H*/
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/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/aarch32/cpu_macros.S b/include/lib/cpus/aarch32/cpu_macros.S
index 096e0b1..cfa5831 100644
--- a/include/lib/cpus/aarch32/cpu_macros.S
+++ b/include/lib/cpus/aarch32/cpu_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -115,11 +115,6 @@
 	  .popsection
 	.endif
 
-	/*
-	 * Mandatory errata status printing function for CPUs of
-	 * this class.
-	 */
-	.word \_name\()_errata_report
 	.word \_name\()_cpu_str
 
 #ifdef IMAGE_BL32
@@ -130,45 +125,6 @@
 #endif
 	.endm
 
-#if REPORT_ERRATA
-	/*
-	 * Print status of a CPU errata
-	 *
-	 * _chosen:
-	 *	Identifier indicating whether or not a CPU errata has been
-	 *	compiled in.
-	 * _cpu:
-	 *	Name of the CPU
-	 * _id:
-	 *	Errata identifier
-	 * _rev_var:
-	 *	Register containing the combined value CPU revision and variant
-	 *	- typically the return value of cpu_get_rev_var
-	 */
-	.macro report_errata _chosen, _cpu, _id, _rev_var=r4
-	/* Stash a string with errata ID */
-	.pushsection .rodata
-	\_cpu\()_errata_\_id\()_str:
-	.asciz	"\_id"
-	.popsection
-
-	/* Check whether errata applies */
-	mov	r0, \_rev_var
-	bl	check_errata_\_id
-
-	.ifeq \_chosen
-	/*
-	 * Errata workaround has not been compiled in. If the errata would have
-	 * applied had it been compiled in, print its status as missing.
-	 */
-	cmp	r0, #0
-	movne	r0, #ERRATA_MISSING
-	.endif
-	ldr	r1, =\_cpu\()_cpu_str
-	ldr	r2, =\_cpu\()_errata_\_id\()_str
-	bl	errata_print_msg
-	.endm
-#endif
 	/*
 	 * Helper macro that reads the part number of the current CPU and jumps
 	 * to the given label if it matches the CPU MIDR provided.
@@ -239,21 +195,4 @@
 	.popsection
 .endm
 
-/*
- * Maintain compatibility with the old scheme of "each cpu has its own reporter".
- * TODO remove entirely once all cpus have been converted. This includes the
- * cpu_ops entry, as print_errata_status can call this directly for all cpus
- */
-.macro errata_report_shim _cpu:req
-	#if REPORT_ERRATA
-	func \_cpu\()_errata_report
-		push	{r12, lr}
-
-		bl generic_errata_report
-
-		pop	{r12, lr}
-		bx	lr
-	endfunc \_cpu\()_errata_report
-	#endif
-.endm
 #endif /* CPU_MACROS_S */
diff --git a/include/lib/cpus/aarch64/cortex_a520.h b/include/lib/cpus/aarch64/cortex_a520.h
index 619a15d..11ddea9 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.
@@ -27,4 +28,15 @@
 #define CORTEX_A520_CPUPWRCTLR_EL1				S3_0_C15_C2_7
 #define CORTEX_A520_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
+#ifndef __ASSEMBLER__
+#if ERRATA_A520_2938996
+long  check_erratum_cortex_a520_2938996(long cpu_rev);
+#else
+static inline long  check_erratum_cortex_a520_2938996(long cpu_rev)
+{
+       return 0;
+}
+#endif /* ERRATA_A520_2938996 */
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_A520_H */
diff --git a/include/lib/cpus/aarch64/cortex_a720.h b/include/lib/cpus/aarch64/cortex_a720.h
index fb27f79..129c1ee 100644
--- a/include/lib/cpus/aarch64/cortex_a720.h
+++ b/include/lib/cpus/aarch64/cortex_a720.h
@@ -23,6 +23,11 @@
 #define CORTEX_A720_CPUACTLR2_EL1				S3_0_C15_C1_1
 
 /*******************************************************************************
+ * CPU Auxiliary Control register 4 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A720_CPUACTLR4_EL1				S3_0_C15_C1_3
+
+/*******************************************************************************
  * CPU Extended Control register specific definitions
  ******************************************************************************/
 #define CORTEX_A720_CPUECTLR_EL1				S3_0_C15_C1_4
diff --git a/include/lib/cpus/aarch64/cortex_a725.h b/include/lib/cpus/aarch64/cortex_a725.h
index 123c5ab..cb1c099 100644
--- a/include/lib/cpus/aarch64/cortex_a725.h
+++ b/include/lib/cpus/aarch64/cortex_a725.h
@@ -13,6 +13,7 @@
  * 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
diff --git a/include/lib/cpus/aarch64/cortex_a75.h b/include/lib/cpus/aarch64/cortex_a75.h
index ca79991..7a97ed1 100644
--- a/include/lib/cpus/aarch64/cortex_a75.h
+++ b/include/lib/cpus/aarch64/cortex_a75.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,6 +50,11 @@
 unsigned int cortex_a75_amu_read_cpuamcntenclr_el0(void);
 void cortex_a75_amu_write_cpuamcntenset_el0(unsigned int mask);
 void cortex_a75_amu_write_cpuamcntenclr_el0(unsigned int mask);
+
+#if ERRATA_A75_764081
+long check_erratum_cortex_a75_764081(long cpu_rev);
+#endif /* ERRATA_A75_764081 */
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* CORTEX_A75_H */
diff --git a/include/lib/cpus/aarch64/cortex_x4.h b/include/lib/cpus/aarch64/cortex_x4.h
index 433687b..f701216 100644
--- a/include/lib/cpus/aarch64/cortex_x4.h
+++ b/include/lib/cpus/aarch64/cortex_x4.h
@@ -26,6 +26,25 @@
 /*******************************************************************************
  * CPU Auxiliary control register specific definitions
  ******************************************************************************/
+#define CORTEX_X4_CPUACTLR_EL1				S3_0_C15_C1_0
 #define CORTEX_X4_CPUACTLR3_EL1				S3_0_C15_C1_2
+#define CORTEX_X4_CPUACTLR4_EL1				S3_0_C15_C1_3
+
+/*******************************************************************************
+ * CPU Auxiliary control register 5 specific definitions
+ ******************************************************************************/
+#define CORTEX_X4_CPUACTLR5_EL1				S3_0_C15_C8_0
+#define CORTEX_X4_CPUACTLR5_EL1_BIT_14			(ULL(1) << 14)
+
+#ifndef __ASSEMBLER__
+#if ERRATA_X4_2726228
+long check_erratum_cortex_x4_2726228(long cpu_rev);
+#else
+static inline long check_erratum_cortex_x4_2726228(long cpu_rev)
+{
+       return 0;
+}
+#endif /* ERRATA_X4_2726228 */
+#endif /* __ASSEMBLER__ */
 
 #endif /* CORTEX_X4_H */
diff --git a/include/lib/cpus/aarch64/cortex_x925.h b/include/lib/cpus/aarch64/cortex_x925.h
index 38aafcf..b0d0ca4 100644
--- a/include/lib/cpus/aarch64/cortex_x925.h
+++ b/include/lib/cpus/aarch64/cortex_x925.h
@@ -13,6 +13,7 @@
  * 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
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 6faef5d..98294b9 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
  */
@@ -132,12 +132,6 @@
 	  .popsection
 	.endif
 
-
-	/*
-	 * Mandatory errata status printing function for CPUs of
-	 * this class.
-	 */
-	.quad \_name\()_errata_report
 	.quad \_name\()_cpu_str
 
 #ifdef IMAGE_BL31
@@ -171,49 +165,6 @@
 			\_extra1, \_extra2, \_extra3, 0, \_power_down_ops
 	.endm
 
-/* TODO can be deleted once all CPUs have been converted */
-#if REPORT_ERRATA
-	/*
-	 * Print status of a CPU errata
-	 *
-	 * _chosen:
-	 *	Identifier indicating whether or not a CPU errata has been
-	 *	compiled in.
-	 * _cpu:
-	 *	Name of the CPU
-	 * _id:
-	 *	Errata identifier
-	 * _rev_var:
-	 *	Register containing the combined value CPU revision and variant
-	 *	- typically the return value of cpu_get_rev_var
-	 */
-	.macro report_errata _chosen, _cpu, _id, _rev_var=x8
-	/* Stash a string with errata ID */
-	.pushsection .rodata
-	\_cpu\()_errata_\_id\()_str:
-	.asciz	"\_id"
-	.popsection
-
-	/* Check whether errata applies */
-	mov	x0, \_rev_var
-	/* Shall clobber: x0-x7 */
-	bl	check_errata_\_id
-
-	.ifeq \_chosen
-	/*
-	 * Errata workaround has not been compiled in. If the errata would have
-	 * applied had it been compiled in, print its status as missing.
-	 */
-	cbz	x0, 900f
-	mov	x0, #ERRATA_MISSING
-	.endif
-900:
-	adr	x1, \_cpu\()_cpu_str
-	adr	x2, \_cpu\()_errata_\_id\()_str
-	bl	errata_print_msg
-	.endm
-#endif
-
 	/*
 	 * This macro is used on some CPUs to detect if they are vulnerable
 	 * to CVE-2017-5715.
@@ -456,6 +407,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
  *
@@ -614,23 +573,4 @@
 	endfunc \_cpu\()_reset_func
 .endm
 
-/*
- * Maintain compatibility with the old scheme of each cpu has its own reporting.
- * TODO remove entirely once all cpus have been converted. This includes the
- * cpu_ops entry, as print_errata_status can call this directly for all cpus
- */
-.macro errata_report_shim _cpu:req
-	#if REPORT_ERRATA
-	func \_cpu\()_errata_report
-		/* normal stack frame for pretty debugging */
-		stp	x29, x30, [sp, #-16]!
-		mov	x29, sp
-
-		bl	generic_errata_report
-
-		ldp	x29, x30, [sp], #16
-		ret
-	endfunc \_cpu\()_errata_report
-	#endif
-.endm
 #endif /* CPU_MACROS_S */
diff --git a/include/lib/cpus/cpu_ops.h b/include/lib/cpus/cpu_ops.h
index 8b36ff1..0084189 100644
--- a/include/lib/cpus/cpu_ops.h
+++ b/include/lib/cpus/cpu_ops.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -57,7 +57,6 @@
 #define CPU_ERRATA_LIST_END_SIZE	CPU_WORD_SIZE
 /* Fields required to print errata status  */
 #if REPORT_ERRATA
-#define CPU_ERRATA_FUNC_SIZE	CPU_WORD_SIZE
 #define CPU_CPU_STR_SIZE	CPU_WORD_SIZE
 /* BL1 doesn't require mutual exclusion and printed flag. */
 #if defined(IMAGE_BL31) || defined(IMAGE_BL32)
@@ -68,7 +67,6 @@
 #define CPU_ERRATA_PRINTED_SIZE	0
 #endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */
 #else
-#define CPU_ERRATA_FUNC_SIZE	0
 #define CPU_CPU_STR_SIZE	0
 #define CPU_ERRATA_LOCK_SIZE	0
 #define CPU_ERRATA_PRINTED_SIZE	0
@@ -98,8 +96,7 @@
 #endif /* __aarch64__ */
 #define CPU_ERRATA_LIST_START	CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE
 #define CPU_ERRATA_LIST_END	CPU_ERRATA_LIST_START + CPU_ERRATA_LIST_START_SIZE
-#define CPU_ERRATA_FUNC		CPU_ERRATA_LIST_END + CPU_ERRATA_LIST_END_SIZE
-#define CPU_CPU_STR		CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE
+#define CPU_CPU_STR		CPU_ERRATA_LIST_END + CPU_ERRATA_LIST_END_SIZE
 #define CPU_ERRATA_LOCK		CPU_CPU_STR + CPU_CPU_STR_SIZE
 #define CPU_ERRATA_PRINTED	CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE
 #if __aarch64__
@@ -130,7 +127,6 @@
 	void *errata_list_start;
 	void *errata_list_end;
 #if REPORT_ERRATA
-	void (*errata_func)(void);
 	char *cpu_str;
 #if defined(IMAGE_BL31) || defined(IMAGE_BL32)
 	spinlock_t *errata_lock;
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index 2080898..2c31515 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.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
  */
@@ -25,11 +25,28 @@
 #define ERRATUM_MITIGATED	ERRATUM_CHOSEN + ERRATUM_CHOSEN_SIZE
 #define ERRATUM_ENTRY_SIZE	ERRATUM_MITIGATED + ERRATUM_MITIGATED_SIZE
 
+/* Errata status */
+#define ERRATA_NOT_APPLIES	0
+#define ERRATA_APPLIES		1
+#define ERRATA_MISSING		2
+
 #ifndef __ASSEMBLER__
 #include <lib/cassert.h>
 
 void print_errata_status(void);
-void errata_print_msg(unsigned int status, const char *cpu, const char *id);
+
+#if ERRATA_A75_764081
+bool errata_a75_764081_applies(void);
+#else
+static inline bool errata_a75_764081_applies(void)
+{
+       return false;
+}
+#endif
+
+#if ERRATA_A520_2938996 || ERRATA_X4_2726228
+unsigned int check_if_affected_core(void);
+#endif
 
 /*
  * NOTE that this structure will be different on AArch32 and AArch64. The
@@ -74,11 +91,6 @@
 
 #endif /* __ASSEMBLER__ */
 
-/* Errata status */
-#define ERRATA_NOT_APPLIES	0
-#define ERRATA_APPLIES		1
-#define ERRATA_MISSING		2
-
 /* Macro to get CPU revision code for checking errata version compatibility. */
 #define CPU_REV(r, p)		((r << 4) | p)
 
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index acf111b..87f1541 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -7,8 +7,18 @@
 #ifndef CONTEXT_H
 #define CONTEXT_H
 
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 #include <lib/el3_runtime/context_el2.h>
+#else
+/**
+ * El1 context is required either when:
+ * IMAGE_BL1 || ((!CTX_INCLUDE_EL2_REGS) && IMAGE_BL31)
+ */
+#include <lib/el3_runtime/context_el1.h>
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
+
 #include <lib/el3_runtime/cpu_data.h>
+#include <lib/el3_runtime/simd_ctx.h>
 #include <lib/utils_def.h>
 
 /*******************************************************************************
@@ -81,208 +91,62 @@
  #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)
-#if CTX_INCLUDE_FPREGS
-#define CTX_FP_Q0		U(0x0)
-#define CTX_FP_Q1		U(0x10)
-#define CTX_FP_Q2		U(0x20)
-#define CTX_FP_Q3		U(0x30)
-#define CTX_FP_Q4		U(0x40)
-#define CTX_FP_Q5		U(0x50)
-#define CTX_FP_Q6		U(0x60)
-#define CTX_FP_Q7		U(0x70)
-#define CTX_FP_Q8		U(0x80)
-#define CTX_FP_Q9		U(0x90)
-#define CTX_FP_Q10		U(0xa0)
-#define CTX_FP_Q11		U(0xb0)
-#define CTX_FP_Q12		U(0xc0)
-#define CTX_FP_Q13		U(0xd0)
-#define CTX_FP_Q14		U(0xe0)
-#define CTX_FP_Q15		U(0xf0)
-#define CTX_FP_Q16		U(0x100)
-#define CTX_FP_Q17		U(0x110)
-#define CTX_FP_Q18		U(0x120)
-#define CTX_FP_Q19		U(0x130)
-#define CTX_FP_Q20		U(0x140)
-#define CTX_FP_Q21		U(0x150)
-#define CTX_FP_Q22		U(0x160)
-#define CTX_FP_Q23		U(0x170)
-#define CTX_FP_Q24		U(0x180)
-#define CTX_FP_Q25		U(0x190)
-#define CTX_FP_Q26		U(0x1a0)
-#define CTX_FP_Q27		U(0x1b0)
-#define CTX_FP_Q28		U(0x1c0)
-#define CTX_FP_Q29		U(0x1d0)
-#define CTX_FP_Q30		U(0x1e0)
-#define CTX_FP_Q31		U(0x1f0)
-#define CTX_FP_FPSR		U(0x200)
-#define CTX_FP_FPCR		U(0x208)
-#if CTX_INCLUDE_AARCH32_REGS
-#define CTX_FP_FPEXC32_EL2	U(0x210)
-#define CTX_FPREGS_END		U(0x220) /* Align to the next 16 byte boundary */
-#else
-#define CTX_FPREGS_END		U(0x210) /* Align to the next 16 byte boundary */
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-#else
-#define CTX_FPREGS_END		U(0)
-#endif /* CTX_INCLUDE_FPREGS */
-
-/*******************************************************************************
  * Registers related to CVE-2018-3639
  ******************************************************************************/
-#define CTX_CVE_2018_3639_OFFSET	(CTX_FPREGS_OFFSET + CTX_FPREGS_END)
+#define CTX_CVE_2018_3639_OFFSET	(CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
 #define CTX_CVE_2018_3639_DISABLE	U(0)
 #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)
@@ -325,13 +189,13 @@
 
 /* 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
@@ -346,21 +210,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.
- */
-#if CTX_INCLUDE_FPREGS
-DEFINE_REG_STRUCT(fp_regs, CTX_FPREG_ALL);
-#endif
-
-/*
  * Miscellaneous registers used by EL3 firmware to maintain its state
  * across exception entries and exits
  */
@@ -369,6 +218,11 @@
 /* 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);
@@ -393,19 +247,27 @@
 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_EL2_REGS
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 	el2_sysregs_t el2_sysregs_ctx;
+#else
+	/* El1 context should be included only either for IMAGE_BL1,
+	 * or for IMAGE_BL31 when CTX_INCLUDE_EL2_REGS=0:
+	 * When SPMD_SPM_AT_SEL2=1, SPMC at S-EL2 takes care of saving
+	 * and restoring EL1 registers. In this case, BL31 at EL3 can
+	 * exclude save and restore of EL1 context registers.
+	 */
+	el1_sysregs_t el1_sysregs_ctx;
 #endif
 
 } cpu_context_t;
@@ -424,15 +286,20 @@
 
 /* Macros to access members of the 'cpu_context_t' structure */
 #define get_el3state_ctx(h)	(&((cpu_context_t *) h)->el3state_ctx)
-#if CTX_INCLUDE_FPREGS
-# define get_fpregs_ctx(h)	(&((cpu_context_t *) h)->fpregs_ctx)
-#endif
+
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
+#define get_el2_sysregs_ctx(h)	(&((cpu_context_t *) h)->el2_sysregs_ctx)
+#else
 #define get_el1_sysregs_ctx(h)	(&((cpu_context_t *) h)->el1_sysregs_ctx)
-#if CTX_INCLUDE_EL2_REGS
-# define get_el2_sysregs_ctx(h)	(&((cpu_context_t *) h)->el2_sysregs_ctx)
 #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
@@ -448,17 +315,15 @@
 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);
-#endif /* CTX_INCLUDE_FPREGS */
 
 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);
@@ -504,10 +369,73 @@
  * Function prototypes
  ******************************************************************************/
 #if CTX_INCLUDE_FPREGS
-void fpregs_context_save(fp_regs_t *regs);
-void fpregs_context_restore(fp_regs_t *regs);
+void fpregs_context_save(simd_regs_t *regs);
+void fpregs_context_restore(simd_regs_t *regs);
 #endif
 
+/*******************************************************************************
+ * The next four inline functions are required for IMAGE_BL1, as well as for
+ * IMAGE_BL31 for the below combinations.
+ * ============================================================================
+ * | ERRATA_SPECULATIVE_AT| CTX_INCLUDE_EL2_REGS |   Combination              |
+ * ============================================================================
+ * |       0              |       0              |   Valid (EL1 ctx)          |
+ * |______________________|______________________|____________________________|
+ * |                      |                      | Invalid (No Errata/EL1 Ctx)|
+ * |       0              |       1              | Hence commented out.       |
+ * |______________________|______________________|____________________________|
+ * |                      |                      |                            |
+ * |       1              |       0              |   Valid (Errata ctx)       |
+ * |______________________|______________________|____________________________|
+ * |                      |                      |                            |
+ * |       1              |       1              |   Valid (Errata ctx)       |
+ * |______________________|______________________|____________________________|
+ * ============================================================================
+ ******************************************************************************/
+#if (IMAGE_BL1 || ((ERRATA_SPECULATIVE_AT) || (!CTX_INCLUDE_EL2_REGS)))
+
+static inline void write_ctx_sctlr_el1_reg_errata(cpu_context_t *ctx, u_register_t val)
+{
+#if (ERRATA_SPECULATIVE_AT)
+	write_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_SCTLR_EL1, val);
+#else
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1, val);
+#endif /* ERRATA_SPECULATIVE_AT */
+}
+
+static inline void write_ctx_tcr_el1_reg_errata(cpu_context_t *ctx, u_register_t val)
+{
+#if (ERRATA_SPECULATIVE_AT)
+	write_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_TCR_EL1, val);
+#else
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), tcr_el1, val);
+#endif /* ERRATA_SPECULATIVE_AT */
+}
+
+static inline u_register_t read_ctx_sctlr_el1_reg_errata(cpu_context_t *ctx)
+{
+#if (ERRATA_SPECULATIVE_AT)
+	return read_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_SCTLR_EL1);
+#else
+	return read_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1);
+#endif /* ERRATA_SPECULATIVE_AT */
+}
+
+static inline u_register_t read_ctx_tcr_el1_reg_errata(cpu_context_t *ctx)
+{
+#if (ERRATA_SPECULATIVE_AT)
+	return read_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_TCR_EL1);
+#else
+	return read_el1_ctx_common(get_el1_sysregs_ctx(ctx), tcr_el1);
+#endif /* ERRATA_SPECULATIVE_AT */
+}
+
+#endif /* (IMAGE_BL1 || ((ERRATA_SPECULATIVE_AT) || (!CTX_INCLUDE_EL2_REGS))) */
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* CONTEXT_H */
diff --git a/include/lib/el3_runtime/context_el1.h b/include/lib/el3_runtime/context_el1.h
new file mode 100644
index 0000000..94af210
--- /dev/null
+++ b/include/lib/el3_runtime/context_el1.h
@@ -0,0 +1,308 @@
+/*
+ * 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_the_regs {
+	uint64_t rcwmask_el1;
+	uint64_t rcwsmask_el1;
+} el1_the_regs_t;
+
+typedef struct el1_sctlr2_regs {
+	uint64_t sctlr2_el1;
+} el1_sctlr2_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
+
+#if ENABLE_FEAT_THE
+	el1_the_regs_t the;
+#endif
+
+#if ENABLE_FEAT_SCTLR2
+	el1_sctlr2_regs_t sctlr2;
+#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 */
+
+#if ENABLE_FEAT_THE
+#define read_el1_ctx_the(ctx, reg)		(((ctx)->the).reg)
+#define write_el1_ctx_the(ctx, reg, val)	((((ctx)->the).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_the(ctx, reg)		ULL(0)
+#define write_el1_ctx_the(ctx, reg, val)
+#endif /* ENABLE_FEAT_THE */
+
+#if ENABLE_FEAT_SCTLR2
+#define read_el1_ctx_sctlr2(ctx, reg)		(((ctx)->sctlr2).reg)
+#define write_el1_ctx_sctlr2(ctx, reg, val)	((((ctx)->sctlr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_sctlr2(ctx, reg)		ULL(0)
+#define write_el1_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
+/******************************************************************************/
+#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 d25ab81..ad0b68f 100644
--- a/include/lib/el3_runtime/context_el2.h
+++ b/include/lib/el3_runtime/context_el2.h
@@ -13,7 +13,6 @@
  * AArch64 EL2 system register context structure for preserving the
  * architectural state during world switches.
  ******************************************************************************/
-#if CTX_INCLUDE_EL2_REGS
 typedef struct el2_common_regs {
 	uint64_t actlr_el2;
 	uint64_t afsr0_el2;
@@ -62,6 +61,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;
@@ -128,6 +135,10 @@
 	uint64_t mpamvpmv_el2;
 } el2_mpam_regs_t;
 
+typedef struct el2_sctlr2_regs {
+	uint64_t sctlr2_el2;
+} el2_sctlr2_regs_t;
+
 typedef struct el2_sysregs {
 
 	el2_common_regs_t common;
@@ -140,6 +151,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
@@ -192,6 +207,10 @@
 	el2_mpam_regs_t mpam;
 #endif
 
+#if ENABLE_FEAT_SCTLR2
+	el2_sctlr2_regs_t sctlr2;
+#endif
+
 } el2_sysregs_t;
 
 /*
@@ -221,6 +240,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)	\
@@ -338,7 +366,15 @@
 #define write_el2_ctx_mpam(ctx, reg, val)
 #endif /* CTX_INCLUDE_MPAM_REGS */
 
-#endif /* CTX_INCLUDE_EL2_REGS */
+#if ENABLE_FEAT_SCTLR2
+#define read_el2_ctx_sctlr2(ctx, reg)		(((ctx)->sctlr2).reg)
+#define write_el2_ctx_sctlr2(ctx, reg, val)	((((ctx)->sctlr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_sctlr2(ctx, reg)		ULL(0)
+#define write_el2_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
 /******************************************************************************/
 
 #endif /* __ASSEMBLER__ */
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index 7451b85..70dbd46 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -44,15 +44,17 @@
 void cm_manage_extensions_el3(void);
 void manage_extensions_nonsecure_per_world(void);
 void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx);
+void cm_handle_asymmetric_features(void);
 #endif
 
-#if CTX_INCLUDE_EL2_REGS
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 void cm_el2_sysregs_context_save(uint32_t security_state);
 void cm_el2_sysregs_context_restore(uint32_t security_state);
-#endif
-
+#else
 void cm_el1_sysregs_context_save(uint32_t security_state);
 void cm_el1_sysregs_context_restore(uint32_t security_state);
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
+
 void cm_set_elr_el3(uint32_t security_state, uintptr_t entrypoint);
 void cm_set_elr_spsr_el3(uint32_t security_state,
 			uintptr_t entrypoint, uint32_t spsr);
@@ -95,6 +97,7 @@
 void cm_set_next_context(void *context);
 static inline void cm_manage_extensions_el3(void) {}
 static inline void manage_extensions_nonsecure_per_world(void) {}
+static inline void cm_handle_asymmetric_features(void) {}
 #endif /* __aarch64__ */
 
 #endif /* CONTEXT_MGMT_H */
diff --git a/include/lib/el3_runtime/simd_ctx.h b/include/lib/el3_runtime/simd_ctx.h
new file mode 100644
index 0000000..fdbe24f
--- /dev/null
+++ b/include/lib/el3_runtime/simd_ctx.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIMD_CTX_H
+#define SIMD_CTX_H
+
+/*******************************************************************************
+ * Constants that allow assembler code to access members of and the 'simd_context'
+ * structure at their correct offsets.
+ ******************************************************************************/
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+#if CTX_INCLUDE_SVE_REGS
+#define SIMD_VECTOR_LEN_BYTES	(SVE_VECTOR_LEN / 8) /* Length of vector in bytes */
+#elif CTX_INCLUDE_FPREGS
+#define SIMD_VECTOR_LEN_BYTES	U(16) /* 128 bits fixed vector length for FPU */
+#endif /* CTX_INCLUDE_SVE_REGS */
+
+#define CTX_SIMD_VECTORS	U(0)
+/* there are 32 vector registers, each of size SIMD_VECTOR_LEN_BYTES */
+#define CTX_SIMD_FPSR		(CTX_SIMD_VECTORS + (32 * SIMD_VECTOR_LEN_BYTES))
+#define CTX_SIMD_FPCR		(CTX_SIMD_FPSR + 8)
+
+#if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS
+#define CTX_SIMD_FPEXC32	(CTX_SIMD_FPCR + 8)
+#define CTX_SIMD_PREDICATES	(CTX_SIMD_FPEXC32 + 16)
+#else
+#define CTX_SIMD_PREDICATES      (CTX_SIMD_FPCR + 8)
+#endif /* CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS */
+
+/*
+ * Each predicate register is 1/8th the size of a vector register and there are 16
+ * predicate registers
+ */
+#define CTX_SIMD_FFR		(CTX_SIMD_PREDICATES + (16 * (SIMD_VECTOR_LEN_BYTES / 8)))
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+#include <lib/cassert.h>
+
+/*
+ * Please don't change order of fields in this struct as that may violate
+ * alignment requirements and affect how assembly code accesses members of this
+ * struct.
+ */
+typedef struct {
+	uint8_t vectors[32][SIMD_VECTOR_LEN_BYTES];
+	uint8_t fpsr[8];
+	uint8_t fpcr[8];
+#if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS
+	/* 16 bytes to align to next 16 byte boundary when CTX_INCLUDE_SVE_REGS is 0 */
+	uint8_t fpexc32_el2[16];
+#endif
+#if CTX_INCLUDE_SVE_REGS
+	/* FFR and each of predicates is one-eigth of the SVE vector length */
+	uint8_t predicates[16][SIMD_VECTOR_LEN_BYTES / 8];
+	uint8_t ffr[SIMD_VECTOR_LEN_BYTES / 8];
+	/* SMCCCv1.3 FID[16] hint bit state recorded on EL3 entry */
+	bool hint;
+#endif /* CTX_INCLUDE_SVE_REGS */
+} __aligned(16) simd_regs_t;
+
+CASSERT(CTX_SIMD_VECTORS == __builtin_offsetof(simd_regs_t, vectors),
+		assert_vectors_mismatch);
+
+CASSERT(CTX_SIMD_FPSR == __builtin_offsetof(simd_regs_t, fpsr),
+		assert_fpsr_mismatch);
+
+CASSERT(CTX_SIMD_FPCR == __builtin_offsetof(simd_regs_t, fpcr),
+		assert_fpcr_mismatch);
+
+#if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS
+CASSERT(CTX_SIMD_FPEXC32 == __builtin_offsetof(simd_regs_t, fpexc32_el2),
+		assert_fpex32_mismtatch);
+#endif
+
+#if CTX_INCLUDE_SVE_REGS
+CASSERT(CTX_SIMD_PREDICATES == __builtin_offsetof(simd_regs_t, predicates),
+		assert_predicates_mismatch);
+
+CASSERT(CTX_SIMD_FFR == __builtin_offsetof(simd_regs_t, ffr),
+		assert_ffr_mismatch);
+#endif
+
+void simd_ctx_save(uint32_t security_state, bool hint_sve);
+void simd_ctx_restore(uint32_t security_state);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
+
+#endif /* SIMD_CTX_H */
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 c6e44f9..4801a22 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.h
@@ -12,16 +12,20 @@
 
 #if ENABLE_SPE_FOR_NS
 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_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/sve.h b/include/lib/extensions/sve.h
index 947c905..2979efb 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.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
  */
@@ -10,6 +10,7 @@
 #include <context.h>
 
 #if (ENABLE_SME_FOR_NS || ENABLE_SVE_FOR_NS)
+
 void sve_init_el2_unused(void);
 void sve_enable_per_world(per_world_context_t *per_world_ctx);
 void sve_disable_per_world(per_world_context_t *per_world_ctx);
@@ -25,4 +26,9 @@
 }
 #endif /* ( ENABLE_SME_FOR_NS | ENABLE_SVE_FOR_NS ) */
 
+#if CTX_INCLUDE_SVE_REGS
+void sve_context_save(simd_regs_t *regs);
+void sve_context_restore(simd_regs_t *regs);
+#endif
+
 #endif /* SVE_H */
diff --git a/include/lib/extensions/tcr2.h b/include/lib/extensions/tcr2.h
new file mode 100644
index 0000000..08a2b08
--- /dev/null
+++ b/include/lib/extensions/tcr2.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TCR2_H
+#define TCR2_H
+
+#include <context.h>
+
+#if ENABLE_FEAT_TCR2
+void tcr2_enable(cpu_context_t *ctx);
+void tcr2_disable(cpu_context_t *ctx);
+#else
+static inline void tcr2_enable(cpu_context_t *ctx)
+{
+}
+static inline void tcr2_disable(cpu_context_t *ctx)
+{
+}
+#endif /* ENABLE_FEAT_TCR2 */
+
+#endif /* TCR2_H */
diff --git a/include/lib/extensions/trbe.h b/include/lib/extensions/trbe.h
index 5db3316..2c488e0 100644
--- a/include/lib/extensions/trbe.h
+++ b/include/lib/extensions/trbe.h
@@ -10,9 +10,13 @@
 #include <context.h>
 
 #if ENABLE_TRBE_FOR_NS
+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_disable(cpu_context_t *ctx)
+{
+}
 static inline void trbe_enable(cpu_context_t *ctx)
 {
 }
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/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 ba8df2a..c3756bf 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -262,6 +262,9 @@
 /* BL2 at EL3 functions */
 void arm_bl2_el3_early_platform_setup(void);
 void arm_bl2_el3_plat_arch_setup(void);
+#if ARM_FW_CONFIG_LOAD_ENABLE
+void arm_bl2_el3_plat_config_load(void);
+#endif /* ARM_FW_CONFIG_LOAD_ENABLE */
 
 /* BL2U utility functions */
 void arm_bl2u_early_platform_setup(struct meminfo *mem_layout,
@@ -284,10 +287,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);
@@ -365,6 +365,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 1015fca..118b537 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -15,6 +15,7 @@
 #endif
 #if ENABLE_RME
 #include <services/rmm_core_manifest.h>
+#include <services/rmm_el3_token_sign.h>
 #endif
 #include <drivers/fwu/fwu_metadata.h>
 #if TRNG_SUPPORT
@@ -370,10 +371,21 @@
  * Mandatory BL31 functions when ENABLE_RME=1
  ******************************************************************************/
 #if ENABLE_RME
+
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
-				   uintptr_t hash, size_t hash_size);
+				   uintptr_t hash, size_t hash_size,
+				   uint64_t *remaining_len);
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type);
+/* The following 3 functions are to be implement if
+ * RMMD_ENABLE_EL3_TOKEN_SIGN=1.
+ * The following three functions are expected to return E_RMM_* error codes.
+ */
+int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
+					   unsigned int type);
+int plat_rmmd_el3_token_sign_push_req(
+				const struct el3_token_sign_request *req);
+int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp);
 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
 #endif
diff --git a/include/services/rmm_el3_token_sign.h b/include/services/rmm_el3_token_sign.h
new file mode 100644
index 0000000..154940c
--- /dev/null
+++ b/include/services/rmm_el3_token_sign.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RMM_EL3_TOKEN_SIGN_H
+#define RMM_EL3_TOKEN_SIGN_H
+
+#include <stdint.h>
+#include <lib/cassert.h>
+#include <services/rmmd_svc.h>
+
+/*
+ * Defines member of structure and reserves space
+ * for the next member with specified offset.
+ */
+/* cppcheck-suppress [misra-c2012-20.7] */
+#define SET_MEMBER(member, start, end)	\
+	union {				\
+		member;			\
+		unsigned char reserved##end[((end) - (start))];	\
+	}
+
+#define EL3_TOKEN_RESPONSE_MAX_SIG_LEN U(512)
+
+struct el3_token_sign_request {
+	SET_MEMBER(uint32_t sig_alg_id, 0x0, 0x8);
+	SET_MEMBER(uint64_t rec_granule, 0x8, 0x10);
+	SET_MEMBER(uint64_t req_ticket, 0x10, 0x18);
+	SET_MEMBER(uint32_t hash_alg_id, 0x18, 0x20);
+	SET_MEMBER(uint8_t hash_buf[SHA512_DIGEST_SIZE], 0x20, 0x60);
+};
+
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, sig_alg_id) == 0x0U,
+	assert_el3_token_sign_request_sig_alg_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, rec_granule) == 0x8U,
+	assert_el3_token_sign_request_rec_granule_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, req_ticket) == 0x10U,
+	assert_el3_token_sign_request_req_ticket_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_alg_id) == 0x18U,
+	assert_el3_token_sign_request_hash_alg_id_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_buf) == 0x20U,
+	assert_el3_token_sign_request_hash_buf_mismatch);
+
+
+struct el3_token_sign_response {
+	SET_MEMBER(uint64_t rec_granule, 0x0, 0x8);
+	SET_MEMBER(uint64_t req_ticket, 0x8, 0x10);
+	SET_MEMBER(uint16_t sig_len, 0x10, 0x12);
+	SET_MEMBER(uint8_t signature_buf[EL3_TOKEN_RESPONSE_MAX_SIG_LEN], 0x12, 0x212);
+};
+
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, rec_granule) == 0x0U,
+	assert_el3_token_sign_resp_rec_granule_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, req_ticket) == 0x8U,
+	assert_el3_token_sign_resp_req_ticket_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, sig_len) == 0x10U,
+	assert_el3_token_sign_resp_sig_len_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, signature_buf) == 0x12U,
+	assert_el3_token_sign_resp_sig_buf_mismatch);
+
+#endif /* RMM_EL3_TOKEN_SIGN_H */
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index a567d28..0cc8628 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.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
  */
@@ -7,6 +7,7 @@
 #ifndef RMMD_SVC_H
 #define RMMD_SVC_H
 
+#include <common/sha_common_macros.h>
 #include <lib/smccc.h>
 #include <lib/utils_def.h>
 
@@ -90,16 +91,12 @@
 #define E_RMM_BAD_PAS			-3
 #define E_RMM_NOMEM			-4
 #define E_RMM_INVAL			-5
+#define E_RMM_AGAIN			-6
 
 /* Return error codes from RMI SMCs */
 #define RMI_SUCCESS			0
 #define RMI_ERROR_INPUT			1
 
-/* Acceptable SHA sizes for Challenge object */
-#define SHA256_DIGEST_SIZE	32U
-#define SHA384_DIGEST_SIZE	48U
-#define SHA512_DIGEST_SIZE	64U
-
 /*
  * Retrieve Realm attestation key from EL3. Only P-384 ECC curve key is
  * supported. The arguments to this SMC are :
@@ -132,8 +129,43 @@
 					/* 0x1B3 */
 #define RMM_ATTEST_GET_PLAT_TOKEN	SMC64_RMMD_EL3_FID(U(3))
 
+/* Starting RMM-EL3 interface version 0.4 */
+#define RMM_EL3_FEATURES				SMC64_RMMD_EL3_FID(U(4))
+#define RMM_EL3_FEAT_REG_0_IDX				U(0)
+/* Bit 0 of FEAT_REG_0 */
+/* 1 - the feature is present in EL3 , 0 - the feature is absent */
+#define RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK		U(0x1)
+
+/*
+ * Function codes to support attestation where EL3 is used to sign
+ * realm attestation tokens. In this model, the private key is not
+ * exposed to the RMM.
+ * The arguments to this SMC are:
+ *     arg0 - Function ID.
+ *     arg1 - Opcode, one of:
+ *               RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP,
+ *               RMM_EL3_TOKEN_SIGN_PULL_RESP_OP,
+ *               RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ *     arg2 - Pointer to buffer with request/response structures,
+ *            which is in the RMM<->EL3 shared buffer.
+ *     arg3 - Buffer size of memory pointed by arg2.
+ *     arg4 - ECC Curve, when opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ * The return arguments are:
+ *     ret0 - Status/Error
+ *     ret1 - Size of public key if opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ */
+#define RMM_EL3_TOKEN_SIGN			SMC64_RMMD_EL3_FID(U(5))
+
+/* Opcodes for RMM_EL3_TOKEN_SIGN  */
+#define RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP          U(1)
+#define RMM_EL3_TOKEN_SIGN_PULL_RESP_OP         U(2)
+#define RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP       U(3)
+
 /* ECC Curve types for attest key generation */
-#define ATTEST_KEY_CURVE_ECC_SECP384R1		0
+#define ATTEST_KEY_CURVE_ECC_SECP384R1		U(0)
+
+/* Identifier for the hash algorithm used for attestation signing */
+#define EL3_TOKEN_SIGN_HASH_ALG_SHA384		U(1)
 
 /*
  * RMM_BOOT_COMPLETE originates on RMM when the boot finishes (either cold
@@ -156,7 +188,7 @@
  * Increase this when a bug is fixed, or a feature is added without
  * breaking compatibility.
  */
-#define RMM_EL3_IFC_VERSION_MINOR	(U(2))
+#define RMM_EL3_IFC_VERSION_MINOR	(U(4))
 
 #define RMM_EL3_INTERFACE_VERSION				\
 	(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) |	\
diff --git a/lib/cpus/aarch32/aem_generic.S b/lib/cpus/aarch32/aem_generic.S
index 9f45e38..f4dc0d1 100644
--- a/lib/cpus/aarch32/aem_generic.S
+++ b/lib/cpus/aarch32/aem_generic.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,14 +40,6 @@
 	b	dcsw_op_all
 endfunc aem_generic_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for AEM. Must follow AAPCS.
- */
-func aem_generic_errata_report
-	bx	lr
-endfunc aem_generic_errata_report
-#endif
 
 /* cpu_ops for Base AEM FVP */
 declare_cpu_ops aem_generic, BASE_AEM_MIDR, CPU_NO_RESET_FUNC, \
diff --git a/lib/cpus/aarch32/cortex_a12.S b/lib/cpus/aarch32/cortex_a12.S
index 8eec27c..b95020e 100644
--- a/lib/cpus/aarch32/cortex_a12.S
+++ b/lib/cpus/aarch32/cortex_a12.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -73,8 +73,6 @@
 	b	cortex_a12_disable_smp
 endfunc cortex_a12_cluster_pwr_dwn
 
-errata_report_shim cortex_a12
-
 declare_cpu_ops cortex_a12, CORTEX_A12_MIDR, \
 	cortex_a12_reset_func, \
 	cortex_a12_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a15.S b/lib/cpus/aarch32/cortex_a15.S
index b41676d..53489ad 100644
--- a/lib/cpus/aarch32/cortex_a15.S
+++ b/lib/cpus/aarch32/cortex_a15.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -172,8 +172,6 @@
 	b	cortex_a15_disable_smp
 endfunc cortex_a15_cluster_pwr_dwn
 
-errata_report_shim cortex_a15
-
 declare_cpu_ops cortex_a15, CORTEX_A15_MIDR, \
 	cortex_a15_reset_func, \
 	cortex_a15_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a17.S b/lib/cpus/aarch32/cortex_a17.S
index 1877570..05e9616 100644
--- a/lib/cpus/aarch32/cortex_a17.S
+++ b/lib/cpus/aarch32/cortex_a17.S
@@ -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,8 +106,6 @@
 
 add_erratum_entry cortex_a17, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
 
-errata_report_shim cortex_a17
-
 func cortex_a17_reset_func
 	mov	r5, lr
 	bl	cpu_get_rev_var
diff --git a/lib/cpus/aarch32/cortex_a32.S b/lib/cpus/aarch32/cortex_a32.S
index d08b4ff..c92a8c1 100644
--- a/lib/cpus/aarch32/cortex_a32.S
+++ b/lib/cpus/aarch32/cortex_a32.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -117,8 +117,6 @@
 	b	cortex_a32_disable_smp
 endfunc cortex_a32_cluster_pwr_dwn
 
-errata_report_shim cortex_a32
-
 declare_cpu_ops cortex_a32, CORTEX_A32_MIDR, \
 	cortex_a32_reset_func, \
 	cortex_a32_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a5.S b/lib/cpus/aarch32/cortex_a5.S
index 625ea7b..146eb9c 100644
--- a/lib/cpus/aarch32/cortex_a5.S
+++ b/lib/cpus/aarch32/cortex_a5.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -69,8 +69,6 @@
 	b	cortex_a5_disable_smp
 endfunc cortex_a5_cluster_pwr_dwn
 
-errata_report_shim cortex_a5
-
 declare_cpu_ops cortex_a5, CORTEX_A5_MIDR, \
 	cortex_a5_reset_func, \
 	cortex_a5_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a53.S b/lib/cpus/aarch32/cortex_a53.S
index 89b238a..60be2b3 100644
--- a/lib/cpus/aarch32/cortex_a53.S
+++ b/lib/cpus/aarch32/cortex_a53.S
@@ -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
  */
@@ -297,8 +297,6 @@
 	b	cortex_a53_disable_smp
 endfunc cortex_a53_cluster_pwr_dwn
 
-errata_report_shim cortex_a53
-
 declare_cpu_ops cortex_a53, CORTEX_A53_MIDR, \
 	cortex_a53_reset_func, \
 	cortex_a53_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a57.S b/lib/cpus/aarch32/cortex_a57.S
index 1e5377b..d563482 100644
--- a/lib/cpus/aarch32/cortex_a57.S
+++ b/lib/cpus/aarch32/cortex_a57.S
@@ -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
  */
@@ -606,8 +606,6 @@
 	b	cortex_a57_disable_ext_debug
 endfunc cortex_a57_cluster_pwr_dwn
 
-errata_report_shim cortex_a57
-
 declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \
 	cortex_a57_reset_func, \
 	cortex_a57_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a7.S b/lib/cpus/aarch32/cortex_a7.S
index 4842ca6..f99ae79 100644
--- a/lib/cpus/aarch32/cortex_a7.S
+++ b/lib/cpus/aarch32/cortex_a7.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -73,8 +73,6 @@
 	b	cortex_a7_disable_smp
 endfunc cortex_a7_cluster_pwr_dwn
 
-errata_report_shim cortex_a7
-
 declare_cpu_ops cortex_a7, CORTEX_A7_MIDR, \
 	cortex_a7_reset_func, \
 	cortex_a7_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a72.S b/lib/cpus/aarch32/cortex_a72.S
index 77cf84d..8d399fd 100644
--- a/lib/cpus/aarch32/cortex_a72.S
+++ b/lib/cpus/aarch32/cortex_a72.S
@@ -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
  */
@@ -256,8 +256,6 @@
 	b	cortex_a72_disable_ext_debug
 endfunc cortex_a72_cluster_pwr_dwn
 
-errata_report_shim cortex_a72
-
 declare_cpu_ops cortex_a72, CORTEX_A72_MIDR, \
 	cortex_a72_reset_func, \
 	cortex_a72_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a9.S b/lib/cpus/aarch32/cortex_a9.S
index 1e9757a..dc5ff27 100644
--- a/lib/cpus/aarch32/cortex_a9.S
+++ b/lib/cpus/aarch32/cortex_a9.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -57,8 +57,6 @@
 
 add_erratum_entry cortex_a9, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
 
-errata_report_shim cortex_a9
-
 func cortex_a9_reset_func
 #if IMAGE_BL32 && WORKAROUND_CVE_2017_5715
 	ldr	r0, =wa_cve_2017_5715_bpiall_vbar
diff --git a/lib/cpus/aarch64/a64fx.S b/lib/cpus/aarch64/a64fx.S
index 54c20c3..4893a44 100644
--- a/lib/cpus/aarch64/a64fx.S
+++ b/lib/cpus/aarch64/a64fx.S
@@ -16,15 +16,6 @@
 func a64fx_cluster_pwr_dwn
 endfunc a64fx_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for A64FX. Must follow AAPCS.
- */
-func a64fx_errata_report
-        ret
-endfunc a64fx_errata_report
-#endif
-
         /* ---------------------------------------------
          * This function provides cpu specific
          * register information for crash reporting.
diff --git a/lib/cpus/aarch64/aem_generic.S b/lib/cpus/aarch64/aem_generic.S
index d47279a..d5634cf 100644
--- a/lib/cpus/aarch64/aem_generic.S
+++ b/lib/cpus/aarch64/aem_generic.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -74,15 +74,6 @@
 	b	dcsw_op_all
 endfunc aem_generic_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for AEM. Must follow AAPCS.
- */
-func aem_generic_errata_report
-	ret
-endfunc aem_generic_errata_report
-#endif
-
 	/* ---------------------------------------------
 	 * This function provides cpu specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a35.S b/lib/cpus/aarch64/cortex_a35.S
index 6ffb944..c3d8c8d 100644
--- a/lib/cpus/aarch64/cortex_a35.S
+++ b/lib/cpus/aarch64/cortex_a35.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -111,8 +111,6 @@
 	b	cortex_a35_disable_smp
 endfunc cortex_a35_cluster_pwr_dwn
 
-errata_report_shim cortex_a35
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a35 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index a59b92c..b49d45a 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -204,8 +204,6 @@
 	ret
 endfunc cortex_a510_core_pwr_dwn
 
-errata_report_shim cortex_a510
-
 cpu_reset_func_start cortex_a510
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_a520.S b/lib/cpus/aarch64/cortex_a520.S
index 74ecbf7..811c836 100644
--- a/lib/cpus/aarch64/cortex_a520.S
+++ b/lib/cpus/aarch64/cortex_a520.S
@@ -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
  */
@@ -11,6 +11,9 @@
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
+/* .global erratum_cortex_a520_2938996_wa */
+.global check_erratum_cortex_a520_2938996
+
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
 #error "Cortex A520 must be compiled with HW_ASSISTED_COHERENCY enabled"
@@ -32,6 +35,25 @@
 workaround_reset_end cortex_a520, ERRATUM(2858100)
 
 check_erratum_ls cortex_a520, ERRATUM(2858100), CPU_REV(0, 1)
+
+workaround_runtime_start cortex_a520, ERRATUM(2938996), ERRATA_A520_2938996, CORTEX_A520_MIDR
+workaround_runtime_end cortex_a520, ERRATUM(2938996)
+
+check_erratum_custom_start cortex_a520, ERRATUM(2938996)
+
+       /* This erratum needs to be enabled for r0p0 and r0p1.
+        * Check if revision is less than or equal to r0p1.
+        */
+
+#if ERRATA_A520_2938996
+       mov     x1, #1
+       b       cpu_rev_var_ls
+#else
+       mov     x0, #ERRATA_MISSING
+#endif
+       ret
+check_erratum_custom_end cortex_a520, ERRATUM(2938996)
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -46,8 +68,6 @@
 	ret
 endfunc cortex_a520_core_pwr_dwn
 
-errata_report_shim cortex_a520
-
 cpu_reset_func_start cortex_a520
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index e6fb08a..4a5b318 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.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
  */
@@ -199,8 +199,6 @@
 	b	cortex_a53_disable_smp
 endfunc cortex_a53_cluster_pwr_dwn
 
-errata_report_shim cortex_a53
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a53 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index 712b6e0..d5a74e9 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -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
  */
@@ -116,8 +116,6 @@
 cpu_reset_func_start cortex_a55
 cpu_reset_func_end cortex_a55
 
-errata_report_shim cortex_a55
-
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index 8fafaca..374cc5d 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.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.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -284,8 +284,6 @@
 	b	cortex_a57_disable_ext_debug
 endfunc cortex_a57_cluster_pwr_dwn
 
-errata_report_shim cortex_a57
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a57 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a65.S b/lib/cpus/aarch64/cortex_a65.S
index 666324c..3023ecb 100644
--- a/lib/cpus/aarch64/cortex_a65.S
+++ b/lib/cpus/aarch64/cortex_a65.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,26 +45,6 @@
 	ret
 endfunc cortex_a65_cpu_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A65. Must follow AAPCS.
- */
-func cortex_a65_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_DSU_936184, cortex_a65, dsu_936184
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a65_errata_report
-#endif
 
 .section .rodata.cortex_a65_regs, "aS"
 cortex_a65_regs:  /* The ascii list of register names to be reported */
diff --git a/lib/cpus/aarch64/cortex_a65ae.S b/lib/cpus/aarch64/cortex_a65ae.S
index 85d1894..1cbb06a 100644
--- a/lib/cpus/aarch64/cortex_a65ae.S
+++ b/lib/cpus/aarch64/cortex_a65ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,8 +41,6 @@
 	ret
 endfunc cortex_a65ae_cpu_pwr_dwn
 
-errata_report_shim cortex_a65ae
-
 .section .rodata.cortex_a65ae_regs, "aS"
 cortex_a65ae_regs:  /* The ascii list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index b99fbb3..4c33dda 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -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
  */
@@ -229,8 +229,6 @@
 	ret
 endfunc cortex_a710_core_pwr_dwn
 
-errata_report_shim cortex_a710
-
 cpu_reset_func_start cortex_a710
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index 16be161..8c9988d 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -148,8 +148,6 @@
 	ret
 endfunc cortex_a715_core_pwr_dwn
 
-errata_report_shim cortex_a715
-
 	/* ---------------------------------------------
 	 * This function provides Cortex-A715 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a72.S b/lib/cpus/aarch64/cortex_a72.S
index 997f261..c300ea7 100644
--- a/lib/cpus/aarch64/cortex_a72.S
+++ b/lib/cpus/aarch64/cortex_a72.S
@@ -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
  */
@@ -271,8 +271,6 @@
 	b	cortex_a72_disable_ext_debug
 endfunc cortex_a72_cluster_pwr_dwn
 
-errata_report_shim cortex_a72
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a72 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a720.S b/lib/cpus/aarch64/cortex_a720.S
index 53a1b78..9befb36 100644
--- a/lib/cpus/aarch64/cortex_a720.S
+++ b/lib/cpus/aarch64/cortex_a720.S
@@ -26,6 +26,18 @@
         wa_cve_2022_23960_bhb_vector_table CORTEX_A720_BHB_LOOP_COUNT, cortex_a720
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_reset_start cortex_a720, ERRATUM(2792132), ERRATA_A720_2792132
+        sysreg_bit_set CORTEX_A720_CPUACTLR2_EL1, BIT(26)
+workaround_reset_end cortex_a720, ERRATUM(2792132)
+
+check_erratum_ls cortex_a720, ERRATUM(2792132), CPU_REV(0, 1)
+
+workaround_reset_start cortex_a720, ERRATUM(2844092), ERRATA_A720_2844092
+        sysreg_bit_set CORTEX_A720_CPUACTLR4_EL1, BIT(11)
+workaround_reset_end cortex_a720, ERRATUM(2844092)
+
+check_erratum_ls cortex_a720, ERRATUM(2844092), CPU_REV(0, 1)
+
 workaround_reset_start cortex_a720, ERRATUM(2926083), ERRATA_A720_2926083
 /* Erratum 2926083 workaround is required only if SPE is enabled */
 #if ENABLE_SPE_FOR_NS != 0
@@ -80,8 +92,6 @@
 	ret
 endfunc cortex_a720_core_pwr_dwn
 
-errata_report_shim cortex_a720
-
 	/* ---------------------------------------------
 	 * This function provides Cortex A720-specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a725.S b/lib/cpus/aarch64/cortex_a725.S
index c08945f..af98d14 100644
--- a/lib/cpus/aarch64/cortex_a725.S
+++ b/lib/cpus/aarch64/cortex_a725.S
@@ -40,8 +40,6 @@
 	ret
 endfunc cortex_a725_core_pwr_dwn
 
-errata_report_shim cortex_a725
-
 	/* ---------------------------------------------
 	 * This function provides Cortex-A725 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a73.S b/lib/cpus/aarch64/cortex_a73.S
index 3a6b922..2130ceb 100644
--- a/lib/cpus/aarch64/cortex_a73.S
+++ b/lib/cpus/aarch64/cortex_a73.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -178,9 +178,6 @@
 	b	cortex_a73_disable_smp
 endfunc cortex_a73_cluster_pwr_dwn
 
-
-errata_report_shim cortex_a73
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a73 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index c90be67..152c81f 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -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
  */
@@ -10,6 +10,8 @@
 #include <cpuamu.h>
 #include <cpu_macros.S>
 
+.global check_erratum_cortex_a75_764081
+
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
 #error "Cortex-A75 must be compiled with HW_ASSISTED_COHERENCY enabled"
@@ -146,8 +148,6 @@
 	ret
 endfunc cortex_a75_core_pwr_dwn
 
-errata_report_shim cortex_a75
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a75 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 8b3d730..97e036e 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -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
  */
@@ -511,8 +511,6 @@
 	ret
 endfunc cortex_a76_core_pwr_dwn
 
-errata_report_shim cortex_a76
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a76 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S
index 08a6ef9..2fe3dbc 100644
--- a/lib/cpus/aarch64/cortex_a76ae.S
+++ b/lib/cpus/aarch64/cortex_a76ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,8 +41,6 @@
 cpu_reset_func_start cortex_a76ae
 cpu_reset_func_end cortex_a76ae
 
-errata_report_shim cortex_a76ae
-
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index 86c2561..d1fc41a 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -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
  */
@@ -167,7 +167,6 @@
 	ret
 endfunc cortex_a77_core_pwr_dwn
 
-errata_report_shim cortex_a77
 	/* ---------------------------------------------
 	 * This function provides Cortex-A77 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index b5c24e1..5a63e78 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -198,8 +198,6 @@
 	ret
 endfunc cortex_a78_core_pwr_dwn
 
-errata_report_shim cortex_a78
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a78 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index d3a3e5d..bc10186 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2021-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -128,8 +128,6 @@
 	ret
 endfunc cortex_a78_ae_core_pwr_dwn
 
-errata_report_shim cortex_a78_ae
-
 	/* -------------------------------------------------------
 	 * This function provides cortex_a78_ae specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 0dc34f7..97d5743 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -121,8 +121,6 @@
 cpu_reset_func_start cortex_a78c
 cpu_reset_func_end cortex_a78c
 
-errata_report_shim cortex_a78c
-
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_gelas.S b/lib/cpus/aarch64/cortex_gelas.S
index 8870019..891e9a6 100644
--- a/lib/cpus/aarch64/cortex_gelas.S
+++ b/lib/cpus/aarch64/cortex_gelas.S
@@ -58,8 +58,6 @@
 	ret
 endfunc cortex_gelas_core_pwr_dwn
 
-errata_report_shim cortex_gelas
-
 	/* ---------------------------------------------
 	 * This function provides Gelas specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_x1.S b/lib/cpus/aarch64/cortex_x1.S
index 42634f1..ca6cac9 100644
--- a/lib/cpus/aarch64/cortex_x1.S
+++ b/lib/cpus/aarch64/cortex_x1.S
@@ -66,8 +66,6 @@
 	ret
 endfunc cortex_x1_core_pwr_dwn
 
-errata_report_shim cortex_x1
-
        /* ---------------------------------------------
 	* This function provides Cortex X1 specific
 	* register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index d018182..ab0b19d 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -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
  */
@@ -182,8 +182,6 @@
 	ret
 endfunc cortex_x2_core_pwr_dwn
 
-errata_report_shim cortex_x2
-
 cpu_reset_func_start cortex_x2
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index 49e9ad1..248f107 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -125,8 +125,6 @@
 	ret
 endfunc cortex_x3_core_pwr_dwn
 
-errata_report_shim cortex_x3
-
 	/* ---------------------------------------------
 	 * This function provides Cortex-X3-
 	 * specific register information for crash
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index 20f1ae1..8820de5 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -22,10 +22,30 @@
 #error "Cortex X4 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+.global check_erratum_cortex_x4_2726228
+
 #if WORKAROUND_CVE_2022_23960
         wa_cve_2022_23960_bhb_vector_table CORTEX_X4_BHB_LOOP_COUNT, cortex_x4
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_runtime_start cortex_x4, ERRATUM(2726228), ERRATA_X4_2726228, CORTEX_X4_MIDR
+workaround_runtime_end cortex_x4, ERRATUM(2726228)
+
+check_erratum_custom_start cortex_x4, ERRATUM(2726228)
+
+	/* This erratum needs to be enabled for r0p0 and r0p1.
+	 * Check if revision is less than or equal to r0p1.
+	 */
+
+#if ERRATA_X4_2726228
+	mov	x1, #1
+	b	cpu_rev_var_ls
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+check_erratum_custom_end cortex_x4, ERRATUM(2726228)
+
 workaround_runtime_start cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089
 	/* dsb before isb of power down sequence */
 	dsb	sy
@@ -39,6 +59,30 @@
 
 check_erratum_ls cortex_x4, ERRATUM(2763018), CPU_REV(0, 1)
 
+workaround_reset_start cortex_x4, ERRATUM(2816013), ERRATA_X4_2816013
+	mrs x1, id_aa64pfr1_el1
+	ubfx x2, x1, ID_AA64PFR1_EL1_MTE_SHIFT, #4
+	cbz x2, #1f
+	sysreg_bit_set CORTEX_X4_CPUACTLR5_EL1, BIT(14)
+1:
+workaround_reset_end cortex_x4, ERRATUM(2816013)
+
+check_erratum_ls cortex_x4, ERRATUM(2816013), CPU_REV(0, 1)
+
+workaround_reset_start cortex_x4, ERRATUM(2897503), ERRATA_X4_2897503
+	sysreg_bit_set	CORTEX_X4_CPUACTLR4_EL1, BIT(8)
+workaround_reset_end cortex_x4, ERRATUM(2897503)
+
+check_erratum_ls cortex_x4, ERRATUM(2897503), CPU_REV(0, 1)
+
+workaround_reset_start cortex_x4, ERRATUM(3076789), ERRATA_X4_3076789
+	sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(14)
+	sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(13)
+	sysreg_bit_set CORTEX_X4_CPUACTLR_EL1, BIT(52)
+workaround_reset_end cortex_x4, ERRATUM(3076789)
+
+check_erratum_ls cortex_x4, ERRATUM(3076789), CPU_REV(0, 1)
+
 workaround_reset_start cortex_x4, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -73,8 +117,6 @@
 	ret
 endfunc cortex_x4_core_pwr_dwn
 
-errata_report_shim cortex_x4
-
 	/* ---------------------------------------------
 	 * This function provides Cortex X4-specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_x925.S b/lib/cpus/aarch64/cortex_x925.S
index 36b442e..8109ffb 100644
--- a/lib/cpus/aarch64/cortex_x925.S
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -40,8 +40,6 @@
 	ret
 endfunc cortex_x925_core_pwr_dwn
 
-errata_report_shim cortex_x925
-
 	/* ---------------------------------------------
 	 * This function provides Cortex-X925 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index 884281d..ca250d3 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -296,8 +296,6 @@
 	ret
 endfunc denver_cluster_pwr_dwn
 
-errata_report_shim denver
-
 	/* ---------------------------------------------
 	 * This function provides Denver specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/generic.S b/lib/cpus/aarch64/generic.S
index ef1f048..5d7a857 100644
--- a/lib/cpus/aarch64/generic.S
+++ b/lib/cpus/aarch64/generic.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -79,7 +79,6 @@
  * Unimplemented functions.
  * ---------------------------------------------
  */
-.equ	generic_errata_report,		0
 .equ	generic_cpu_reg_dump,		0
 .equ	generic_reset_func,		0
 
diff --git a/lib/cpus/aarch64/neoverse_e1.S b/lib/cpus/aarch64/neoverse_e1.S
index 45bd8d3..4bc95d0 100644
--- a/lib/cpus/aarch64/neoverse_e1.S
+++ b/lib/cpus/aarch64/neoverse_e1.S
@@ -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
  */
@@ -42,8 +42,6 @@
 	ret
 endfunc neoverse_e1_cpu_pwr_dwn
 
-errata_report_shim neoverse_e1
-
 .section .rodata.neoverse_e1_regs, "aS"
 neoverse_e1_regs:  /* The ascii list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index 36a7ee7..50e1ae3 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -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
  */
@@ -242,8 +242,6 @@
 	ret
 endfunc neoverse_n1_core_pwr_dwn
 
-errata_report_shim neoverse_n1
-
 /*
  * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB
  * inner-shareable invalidation to an arbitrary address followed by a DSB.
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index a85d956..7d7cc44 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -282,8 +282,6 @@
 	ret
 endfunc neoverse_n2_core_pwr_dwn
 
-errata_report_shim neoverse_n2
-
 	/* ---------------------------------------------
 	 * This function provides Neoverse N2 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/neoverse_n3.S b/lib/cpus/aarch64/neoverse_n3.S
index 0b33b7e..d96c9d4 100644
--- a/lib/cpus/aarch64/neoverse_n3.S
+++ b/lib/cpus/aarch64/neoverse_n3.S
@@ -45,8 +45,6 @@
 	ret
 endfunc neoverse_n3_core_pwr_dwn
 
-errata_report_shim neoverse_n3
-
 	/* ---------------------------------------------
 	 * This function provides Neoverse-N3 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index c2fbb11..89299b7 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -259,8 +259,6 @@
 	ret
 endfunc neoverse_v1_core_pwr_dwn
 
-errata_report_shim neoverse_v1
-
 cpu_reset_func_start neoverse_v1
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index 3179918..d8c32a4 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -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
  */
@@ -116,7 +116,6 @@
 #endif
 cpu_reset_func_end neoverse_v2
 
-errata_report_shim neoverse_v2
 	/* ---------------------------------------------
 	 * This function provides Neoverse V2-
 	 * specific register information for crash
diff --git a/lib/cpus/aarch64/neoverse_v3.S b/lib/cpus/aarch64/neoverse_v3.S
index 67258c8..01ac38f 100644
--- a/lib/cpus/aarch64/neoverse_v3.S
+++ b/lib/cpus/aarch64/neoverse_v3.S
@@ -60,8 +60,6 @@
 	msr	SSBS, xzr
 cpu_reset_func_end neoverse_v3
 
-errata_report_shim neoverse_v3
-
 	/* ---------------------------------------------
 	 * This function provides Neoverse V3 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/nevis.S b/lib/cpus/aarch64/nevis.S
index 36830a9..0180ab7 100644
--- a/lib/cpus/aarch64/nevis.S
+++ b/lib/cpus/aarch64/nevis.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,8 +40,6 @@
 	ret
 endfunc nevis_core_pwr_dwn
 
-errata_report_shim nevis
-
 .section .rodata.nevis_regs, "aS"
 nevis_regs: /* The ASCII list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
diff --git a/lib/cpus/aarch64/qemu_max.S b/lib/cpus/aarch64/qemu_max.S
index 00963bc..fb03cf1 100644
--- a/lib/cpus/aarch64/qemu_max.S
+++ b/lib/cpus/aarch64/qemu_max.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
  */
@@ -47,8 +47,6 @@
 	b	dcsw_op_all
 endfunc qemu_max_cluster_pwr_dwn
 
-errata_report_shim qemu_max
-
 	/* ---------------------------------------------
 	 * This function provides cpu specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/rainier.S b/lib/cpus/aarch64/rainier.S
index c770f54..ea687be 100644
--- a/lib/cpus/aarch64/rainier.S
+++ b/lib/cpus/aarch64/rainier.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,8 +80,6 @@
 	ret
 endfunc rainier_core_pwr_dwn
 
-errata_report_shim rainier
-
 	/* ---------------------------------------------
 	 * This function provides Rainier specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/travis.S b/lib/cpus/aarch64/travis.S
index ba06f55..e8b3860 100644
--- a/lib/cpus/aarch64/travis.S
+++ b/lib/cpus/aarch64/travis.S
@@ -54,8 +54,6 @@
 	ret
 endfunc travis_core_pwr_dwn
 
-errata_report_shim travis
-
 .section .rodata.travis_regs, "aS"
 travis_regs: /* The ASCII list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index f736b5a..4c20785 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -823,6 +823,10 @@
 # cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_X4_2701112
 
+# Flag to apply erratum 2726228 workaround during warmboot. This erratum
+# applies to all revisions <= r0p1 of the Cortex-X4 cpu, it is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2726228
+
 # Flag to apply erratum 2740089 workaround during powerdown. This erratum
 # applies to all revisions <= r0p1 of the Cortex-X4 cpu, it is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_X4_2740089
@@ -831,6 +835,18 @@
 # to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_X4_2763018
 
+# Flag to apply erratum 2816013 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2816013
+
+# Flag to apply erratum 2897503 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2897503
+
+# Flag to apply erratum 3076789 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_3076789
+
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_A510_1922240
@@ -892,6 +908,10 @@
 # applies to revision r0p0 and r0p1 of the Cortex-A520 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_A520_2858100
 
+# Flag to apply erratum 2938996 workaround during reset. This erratum
+# applies to revision r0p0 and r0p1 of the Cortex-A520 cpu and is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A520_2938996
+
 # Flag to apply erratum 2331132 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1 and r0p2. It is still open.
 CPU_FLAG_LIST += ERRATA_V2_2331132
@@ -952,6 +972,14 @@
 # only to revision r0p0, r1p0 and r1p1. It is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_A715_2728106
 
+# Flag to apply erratum 2792132 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A720_2792132
+
+# Flag to apply erratum 2844092 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A720_2844092
+
 # Flag to apply erratum 2926083 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_A720_2926083
diff --git a/lib/cpus/errata_common.c b/lib/cpus/errata_common.c
new file mode 100644
index 0000000..a4515a9
--- /dev/null
+++ b/lib/cpus/errata_common.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Runtime C routines for errata workarounds and common routines */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <cortex_a520.h>
+#include <cortex_x4.h>
+#include <cortex_a75.h>
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
+
+#if ERRATA_A520_2938996 || ERRATA_X4_2726228
+unsigned int check_if_affected_core(void)
+{
+	uint32_t midr_val = read_midr();
+	long rev_var  = cpu_get_rev_var();
+
+	if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(CORTEX_A520_MIDR)) {
+		return check_erratum_cortex_a520_2938996(rev_var);
+	} else if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(CORTEX_X4_MIDR)) {
+		return check_erratum_cortex_x4_2726228(rev_var);
+	}
+
+	return ERRATA_NOT_APPLIES;
+}
+#endif
+
+#if ERRATA_A75_764081
+bool errata_a75_764081_applies(void)
+{
+	long rev_var = cpu_get_rev_var();
+	if (check_erratum_cortex_a75_764081(rev_var) == ERRATA_APPLIES) {
+		return true;
+	}
+	return false;
+}
+#endif /* ERRATA_A75_764081 */
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index 4e9bdfc..e0a9076 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");
 		}
 	}
 }
@@ -67,7 +67,7 @@
  * save space. This functionality is only useful on development and platform
  * bringup builds, when FEATURE_DETECTION should be used anyway
  */
-void __unused generic_errata_report(void)
+void generic_errata_report(void)
 {
 	struct cpu_ops *cpu_ops = get_cpu_ops_ptr();
 	struct erratum_entry *entry = cpu_ops->errata_list_start;
@@ -159,70 +159,16 @@
  */
 void print_errata_status(void)
 {
-	struct cpu_ops *cpu_ops;
 #ifdef IMAGE_BL1
-	/*
-	 * BL1 doesn't have per-CPU data. So retrieve the CPU operations
-	 * directly.
-	 */
-	cpu_ops = get_cpu_ops_ptr();
-
-	if (cpu_ops->errata_func != NULL) {
-		cpu_ops->errata_func();
-	}
+	generic_errata_report();
 #else /* IMAGE_BL1 */
-	cpu_ops = (void *) get_cpu_data(cpu_ops_ptr);
+	struct cpu_ops *cpu_ops = (void *) get_cpu_data(cpu_ops_ptr);
 
 	assert(cpu_ops != NULL);
 
-	if (cpu_ops->errata_func == NULL) {
-		return;
-	}
-
 	if (errata_needs_reporting(cpu_ops->errata_lock, cpu_ops->errata_reported)) {
-		cpu_ops->errata_func();
+		generic_errata_report();
 	}
 #endif /* IMAGE_BL1 */
 }
-
-/*
- * Old errata status message printer
- * TODO: remove once all cpus have been converted to the new printing method
- */
-void __unused errata_print_msg(unsigned int status, const char *cpu, const char *id)
-{
-	/* Errata status strings */
-	static const char *const errata_status_str[] = {
-		[ERRATA_NOT_APPLIES] = "not applied",
-		[ERRATA_APPLIES] = "applied",
-		[ERRATA_MISSING] = "missing!"
-	};
-	static const char *const __unused bl_str = BL_STRING;
-	const char *msg __unused;
-
-
-	assert(status < ARRAY_SIZE(errata_status_str));
-	assert(cpu != NULL);
-	assert(id != NULL);
-
-	msg = errata_status_str[status];
-
-	switch (status) {
-	case ERRATA_NOT_APPLIES:
-		VERBOSE(ERRATA_FORMAT, bl_str, cpu, id, msg);
-		break;
-
-	case ERRATA_APPLIES:
-		INFO(ERRATA_FORMAT, bl_str, cpu, id, msg);
-		break;
-
-	case ERRATA_MISSING:
-		WARN(ERRATA_FORMAT, bl_str, cpu, id, msg);
-		break;
-
-	default:
-		WARN(ERRATA_FORMAT, bl_str, cpu, id, "unknown");
-		break;
-	}
-}
 #endif /* !REPORT_ERRATA */
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 1fce1bf..ab9d4b6 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -9,16 +9,56 @@
 #include <assert_macros.S>
 #include <context.h>
 #include <el3_common_macros.S>
+#include <platform_def.h>
 
 #if CTX_INCLUDE_FPREGS
 	.global	fpregs_context_save
 	.global	fpregs_context_restore
 #endif /* CTX_INCLUDE_FPREGS */
+
+#if CTX_INCLUDE_SVE_REGS
+	.global sve_context_save
+	.global sve_context_restore
+#endif /* CTX_INCLUDE_SVE_REGS */
+
+#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
 
+/* Following macros will be used if any of CTX_INCLUDE_FPREGS or CTX_INCLUDE_SVE_REGS is enabled */
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+.macro fpregs_state_save base:req hold:req
+	mrs	\hold, fpsr
+	str	\hold, [\base, #CTX_SIMD_FPSR]
+
+	mrs	\hold, fpcr
+	str	\hold, [\base, #CTX_SIMD_FPCR]
+
+#if CTX_INCLUDE_AARCH32_REGS && CTX_INCLUDE_FPREGS
+	mrs	\hold, fpexc32_el2
+	str	\hold, [\base, #CTX_SIMD_FPEXC32]
+#endif
+.endm
+
+.macro fpregs_state_restore base:req hold:req
+	ldr	\hold, [\base, #CTX_SIMD_FPSR]
+	msr	fpsr, \hold
+
+	ldr	\hold, [\base, #CTX_SIMD_FPCR]
+	msr	fpcr, \hold
+
+#if CTX_INCLUDE_AARCH32_REGS && CTX_INCLUDE_FPREGS
+	ldr	\hold, [\base, #CTX_SIMD_FPEXC32]
+	msr	fpexc32_el2, \hold
+#endif
+.endm
+
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
+
 /* ------------------------------------------------------------------
  * The following function follows the aapcs_64 strictly to use
  * x9-x17 (temporary caller-saved registers according to AArch64 PCS)
@@ -35,33 +75,25 @@
  */
 #if CTX_INCLUDE_FPREGS
 func fpregs_context_save
-	stp	q0, q1, [x0, #CTX_FP_Q0]
-	stp	q2, q3, [x0, #CTX_FP_Q2]
-	stp	q4, q5, [x0, #CTX_FP_Q4]
-	stp	q6, q7, [x0, #CTX_FP_Q6]
-	stp	q8, q9, [x0, #CTX_FP_Q8]
-	stp	q10, q11, [x0, #CTX_FP_Q10]
-	stp	q12, q13, [x0, #CTX_FP_Q12]
-	stp	q14, q15, [x0, #CTX_FP_Q14]
-	stp	q16, q17, [x0, #CTX_FP_Q16]
-	stp	q18, q19, [x0, #CTX_FP_Q18]
-	stp	q20, q21, [x0, #CTX_FP_Q20]
-	stp	q22, q23, [x0, #CTX_FP_Q22]
-	stp	q24, q25, [x0, #CTX_FP_Q24]
-	stp	q26, q27, [x0, #CTX_FP_Q26]
-	stp	q28, q29, [x0, #CTX_FP_Q28]
-	stp	q30, q31, [x0, #CTX_FP_Q30]
-
-	mrs	x9, fpsr
-	str	x9, [x0, #CTX_FP_FPSR]
+	stp	q0, q1, [x0], #32
+	stp	q2, q3, [x0], #32
+	stp	q4, q5, [x0], #32
+	stp	q6, q7, [x0], #32
+	stp	q8, q9, [x0], #32
+	stp	q10, q11, [x0], #32
+	stp	q12, q13, [x0], #32
+	stp	q14, q15, [x0], #32
+	stp	q16, q17, [x0], #32
+	stp	q18, q19, [x0], #32
+	stp	q20, q21, [x0], #32
+	stp	q22, q23, [x0], #32
+	stp	q24, q25, [x0], #32
+	stp	q26, q27, [x0], #32
+	stp	q28, q29, [x0], #32
+	stp	q30, q31, [x0], #32
 
-	mrs	x10, fpcr
-	str	x10, [x0, #CTX_FP_FPCR]
+	fpregs_state_save x0, x9
 
-#if CTX_INCLUDE_AARCH32_REGS
-	mrs	x11, fpexc32_el2
-	str	x11, [x0, #CTX_FP_FPEXC32_EL2]
-#endif /* CTX_INCLUDE_AARCH32_REGS */
 	ret
 endfunc fpregs_context_save
 
@@ -80,51 +112,196 @@
  * ------------------------------------------------------------------
  */
 func fpregs_context_restore
-	ldp	q0, q1, [x0, #CTX_FP_Q0]
-	ldp	q2, q3, [x0, #CTX_FP_Q2]
-	ldp	q4, q5, [x0, #CTX_FP_Q4]
-	ldp	q6, q7, [x0, #CTX_FP_Q6]
-	ldp	q8, q9, [x0, #CTX_FP_Q8]
-	ldp	q10, q11, [x0, #CTX_FP_Q10]
-	ldp	q12, q13, [x0, #CTX_FP_Q12]
-	ldp	q14, q15, [x0, #CTX_FP_Q14]
-	ldp	q16, q17, [x0, #CTX_FP_Q16]
-	ldp	q18, q19, [x0, #CTX_FP_Q18]
-	ldp	q20, q21, [x0, #CTX_FP_Q20]
-	ldp	q22, q23, [x0, #CTX_FP_Q22]
-	ldp	q24, q25, [x0, #CTX_FP_Q24]
-	ldp	q26, q27, [x0, #CTX_FP_Q26]
-	ldp	q28, q29, [x0, #CTX_FP_Q28]
-	ldp	q30, q31, [x0, #CTX_FP_Q30]
+	ldp	q0, q1, [x0], #32
+	ldp	q2, q3, [x0], #32
+	ldp	q4, q5, [x0], #32
+	ldp	q6, q7, [x0], #32
+	ldp	q8, q9, [x0], #32
+	ldp	q10, q11, [x0], #32
+	ldp	q12, q13, [x0], #32
+	ldp	q14, q15, [x0], #32
+	ldp	q16, q17, [x0], #32
+	ldp	q18, q19, [x0], #32
+	ldp	q20, q21, [x0], #32
+	ldp	q22, q23, [x0], #32
+	ldp	q24, q25, [x0], #32
+	ldp	q26, q27, [x0], #32
+	ldp	q28, q29, [x0], #32
+	ldp	q30, q31, [x0], #32
 
-	ldr	x9, [x0, #CTX_FP_FPSR]
-	msr	fpsr, x9
+	fpregs_state_restore x0, x9
 
-	ldr	x10, [x0, #CTX_FP_FPCR]
-	msr	fpcr, x10
+	ret
+endfunc fpregs_context_restore
+#endif /* CTX_INCLUDE_FPREGS */
 
-#if CTX_INCLUDE_AARCH32_REGS
-	ldr	x11, [x0, #CTX_FP_FPEXC32_EL2]
-	msr	fpexc32_el2, x11
-#endif /* CTX_INCLUDE_AARCH32_REGS */
+#if CTX_INCLUDE_SVE_REGS
+/*
+ * Helper macros for SVE predicates save/restore operations.
+ */
+.macro sve_predicate_op op:req reg:req
+	\op p0, [\reg, #0, MUL VL]
+	\op p1, [\reg, #1, MUL VL]
+	\op p2, [\reg, #2, MUL VL]
+	\op p3, [\reg, #3, MUL VL]
+	\op p4, [\reg, #4, MUL VL]
+	\op p5, [\reg, #5, MUL VL]
+	\op p6, [\reg, #6, MUL VL]
+	\op p7, [\reg, #7, MUL VL]
+	\op p8, [\reg, #8, MUL VL]
+	\op p9, [\reg, #9, MUL VL]
+	\op p10, [\reg, #10, MUL VL]
+	\op p11, [\reg, #11, MUL VL]
+	\op p12, [\reg, #12, MUL VL]
+	\op p13, [\reg, #13, MUL VL]
+	\op p14, [\reg, #14, MUL VL]
+	\op p15, [\reg, #15, MUL VL]
+.endm
 
-	/*
-	 * No explict ISB required here as ERET to
-	 * switch to secure EL1 or non-secure world
-	 * covers it
-	 */
+.macro sve_vectors_op op:req reg:req
+	\op z0, [\reg, #0, MUL VL]
+	\op z1, [\reg, #1, MUL VL]
+	\op z2, [\reg, #2, MUL VL]
+	\op z3, [\reg, #3, MUL VL]
+	\op z4, [\reg, #4, MUL VL]
+	\op z5, [\reg, #5, MUL VL]
+	\op z6, [\reg, #6, MUL VL]
+	\op z7, [\reg, #7, MUL VL]
+	\op z8, [\reg, #8, MUL VL]
+	\op z9, [\reg, #9, MUL VL]
+	\op z10, [\reg, #10, MUL VL]
+	\op z11, [\reg, #11, MUL VL]
+	\op z12, [\reg, #12, MUL VL]
+	\op z13, [\reg, #13, MUL VL]
+	\op z14, [\reg, #14, MUL VL]
+	\op z15, [\reg, #15, MUL VL]
+	\op z16, [\reg, #16, MUL VL]
+	\op z17, [\reg, #17, MUL VL]
+	\op z18, [\reg, #18, MUL VL]
+	\op z19, [\reg, #19, MUL VL]
+	\op z20, [\reg, #20, MUL VL]
+	\op z21, [\reg, #21, MUL VL]
+	\op z22, [\reg, #22, MUL VL]
+	\op z23, [\reg, #23, MUL VL]
+	\op z24, [\reg, #24, MUL VL]
+	\op z25, [\reg, #25, MUL VL]
+	\op z26, [\reg, #26, MUL VL]
+	\op z27, [\reg, #27, MUL VL]
+	\op z28, [\reg, #28, MUL VL]
+	\op z29, [\reg, #29, MUL VL]
+	\op z30, [\reg, #30, MUL VL]
+	\op z31, [\reg, #31, MUL VL]
+.endm
+
+/* ------------------------------------------------------------------
+ * The following function follows the aapcs_64 strictly to use x9-x17
+ * (temporary caller-saved registers according to AArch64 PCS) to
+ * restore SVE register context. It assumes that 'x0' is
+ * pointing to a 'sve_regs_t' structure to which the register context
+ * will be saved.
+ * ------------------------------------------------------------------
+ */
+func sve_context_save
+.arch_extension sve
+	/* Temporarily enable SVE */
+	mrs	x10, cptr_el3
+	orr	x11, x10, #CPTR_EZ_BIT
+	bic	x11, x11, #TFP_BIT
+	msr	cptr_el3, x11
+	isb
+
+	/* zcr_el3 */
+	mrs	x12, S3_6_C1_C2_0
+	mov	x13, #((SVE_VECTOR_LEN >> 7) - 1)
+	msr	S3_6_C1_C2_0, x13
+	isb
+
+	/* Predicate registers */
+	mov x13, #CTX_SIMD_PREDICATES
+	add	x9, x0, x13
+	sve_predicate_op str, x9
+
+	/* Save FFR after predicates */
+	mov x13, #CTX_SIMD_FFR
+	add	x9, x0, x13
+	rdffr   p0.b
+	str	p0, [x9]
+
+	/* Save vector registers */
+	mov x13, #CTX_SIMD_VECTORS
+	add	x9, x0, x13
+	sve_vectors_op  str, x9
+
+	/* Restore SVE enablement */
+	msr	S3_6_C1_C2_0, x12 /* zcr_el3 */
+	msr	cptr_el3, x10
+	isb
+.arch_extension nosve
+
+	/* Save FPSR, FPCR and FPEXC32 */
+	fpregs_state_save x0, x9
 
 	ret
-endfunc fpregs_context_restore
-#endif /* CTX_INCLUDE_FPREGS */
+endfunc sve_context_save
+
+/* ------------------------------------------------------------------
+ * The following function follows the aapcs_64 strictly to use x9-x17
+ * (temporary caller-saved registers according to AArch64 PCS) to
+ * restore SVE register context. It assumes that 'x0' is pointing to
+ * a 'sve_regs_t' structure from where the register context will be
+ * restored.
+ * ------------------------------------------------------------------
+ */
+func sve_context_restore
+.arch_extension sve
+	/* Temporarily enable SVE for EL3 */
+	mrs	x10, cptr_el3
+	orr	x11, x10, #CPTR_EZ_BIT
+	bic	x11, x11, #TFP_BIT
+	msr	cptr_el3, x11
+	isb
+
+	/* zcr_el3 */
+	mrs	x12, S3_6_C1_C2_0
+	mov	x13, #((SVE_VECTOR_LEN >> 7) - 1)
+	msr	S3_6_C1_C2_0, x13
+	isb
+
+	/* Restore FFR register before predicates */
+	mov x13, #CTX_SIMD_FFR
+	add	x9, x0, x13
+	ldr	p0, [x9]
+	wrffr	p0.b
+
+	/* Restore predicate registers */
+	mov x13, #CTX_SIMD_PREDICATES
+	add	x9, x0, x13
+	sve_predicate_op ldr, x9
+
+	/* Restore vector registers */
+	mov x13, #CTX_SIMD_VECTORS
+	add	x9, x0, x13
+	sve_vectors_op	ldr, x9
+
+	/* Restore SVE enablement */
+	msr	S3_6_C1_C2_0, x12 /* zcr_el3 */
+	msr	cptr_el3, x10
+	isb
+.arch_extension nosve
+
+	/* Restore FPSR, FPCR and FPEXC32 */
+	fpregs_state_restore x0, x9
+	ret
+endfunc sve_context_restore
+#endif /* CTX_INCLUDE_SVE_REGS */
 
 	/*
 	 * Set SCR_EL3.EA bit to enable SErrors at EL3
 	 */
 	.macro enable_serror_at_el3
-	mrs     x8, scr_el3
-	orr     x8, x8, #SCR_EA_BIT
-	msr     scr_el3, x8
+	mrs	x8, scr_el3
+	orr	x8, x8, #SCR_EA_BIT
+	msr	scr_el3, x8
 	.endm
 
 	/*
@@ -138,13 +315,13 @@
 	 * always enable DIT in EL3
 	 */
 #if ENABLE_FEAT_DIT
-#if ENABLE_FEAT_DIT == 2
+#if ENABLE_FEAT_DIT >= 2
 	mrs	x8, id_aa64pfr0_el1
 	and	x8, x8, #(ID_AA64PFR0_DIT_MASK << ID_AA64PFR0_DIT_SHIFT)
 	cbz	x8, 1f
 #endif
-	mov     x8, #DIT_BIT
-	msr     DIT, x8
+	mov	x8, #DIT_BIT
+	msr	DIT, x8
 1:
 #endif /* ENABLE_FEAT_DIT */
 	.endm /* set_unset_pstate_bits */
@@ -162,8 +339,7 @@
 
 	.macro	restore_mpam3_el3
 #if ENABLE_FEAT_MPAM
-#if ENABLE_FEAT_MPAM == 2
-
+#if ENABLE_FEAT_MPAM >= 2
 	mrs x8, id_aa64pfr0_el1
 	lsr x8, x8, #(ID_AA64PFR0_MPAM_SHIFT)
 	and x8, x8, #(ID_AA64PFR0_MPAM_MASK)
@@ -329,10 +505,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 +518,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 +545,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.
diff --git a/lib/el3_runtime/aarch64/context_debug.c b/lib/el3_runtime/aarch64/context_debug.c
index 9ffa297..b37bcb7 100644
--- a/lib/el3_runtime/aarch64/context_debug.c
+++ b/lib/el3_runtime/aarch64/context_debug.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,19 +28,11 @@
 	return state_names[security_state_idx];
 }
 
-#if CTX_INCLUDE_EL2_REGS
 #define PRINT_MEM_USAGE_SEPARATOR()					\
 	do {								\
 		printf("+-----------+-----------+-----------"		\
-			"+-----------+-----------+-----------+\n");	\
-	} while (false)
-#else
-#define PRINT_MEM_USAGE_SEPARATOR()					\
-	do {								\
-		printf("+-----------+-----------"			\
 		"+-----------+-----------+-----------+\n");		\
 	} while (false)
-#endif /* CTX_INCLUDE_EL2_REGS */
 
 #define NAME_PLACEHOLDER_LEN 14
 
@@ -49,6 +41,11 @@
 		putchar('-');						\
 	}
 
+#define PRINT_SINGLE_MEM_USAGE_SEP_BLOCK()				\
+	do {								\
+		printf("+-----------");					\
+	} while (false)
+
 /********************************************************************************
  * This function prints the allocated memory for a specific security state.
  * Values are grouped by exception level and core. The memory usage for the
@@ -57,64 +54,119 @@
 static size_t report_allocated_memory(unsigned int security_state_idx)
 {
 	size_t core_total = 0U;
+	size_t gp_total = 0U;
 	size_t el3_total = 0U;
-#if CTX_INCLUDE_EL2_REGS
-	size_t el2_total = 0U;
-#endif /* CTX_INCLUDE_EL2_REGS */
-	size_t el1_total = 0U;
 	size_t other_total = 0U;
 	size_t total = 0U;
 	size_t per_world_ctx_size = 0U;
 
+#if CTX_INCLUDE_EL2_REGS
+	size_t el2_total = 0U;
+#else
+	size_t el1_total = 0U;
+#endif /* CTX_INCLUDE_EL2_REGS */
+
+#if CTX_INCLUDE_PAUTH_REGS
+	size_t pauth_total = 0U;
+	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
+
 	PRINT_MEM_USAGE_SEPARATOR();
-	printf("|    Core   |    EL3    ");
+
+	printf("|    Core   |     GP    |    EL3    ");
 #if CTX_INCLUDE_EL2_REGS
 	printf("|    EL2    ");
+#else
+	printf("|    EL1    ");
 #endif /* CTX_INCLUDE_EL2_REGS */
-	printf("|    EL1    |   Other   |   Total   |\n");
+
+#if CTX_INCLUDE_PAUTH_REGS
+	printf("|   PAUTH   ");
+#endif
+
+	printf("|   Other   |   Total   |\n");
 
 	/* Compute memory usage for each core's context */
 	for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
 		size_t size_other = 0U;
 		size_t el3_size = 0U;
+		size_t gp_size = 0U;
 #if CTX_INCLUDE_EL2_REGS
 		size_t el2_size = 0U;
-#endif /* CTX_INCLUDE_EL2_REGS */
+#else
 		size_t el1_size = 0U;
+#endif /* CTX_INCLUDE_EL2_REGS */
+
+#if CTX_INCLUDE_PAUTH_REGS
+		size_t pauth_size = 0U;
+		PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
 
 		PRINT_MEM_USAGE_SEPARATOR();
+
 		cpu_context_t *ctx = (cpu_context_t *)cm_get_context_by_index(i,
 			security_state_idx);
 		core_total = sizeof(*ctx);
 		el3_size = sizeof(ctx->el3state_ctx);
-#if CTX_INCLUDE_EL2_REGS
-		el2_size = sizeof(ctx->el2_sysregs_ctx);
-#endif /* CTX_INCLUDE_EL2_REGS */
-		el1_size = sizeof(ctx->el1_sysregs_ctx);
+		gp_size = sizeof(ctx->gpregs_ctx);
+		size_other = core_total - (el3_size + gp_size);
+		printf("| %9u | %8luB | %8luB ", i, gp_size, el3_size);
 
-		size_other = core_total - el3_size - el1_size;
-		printf("| %9u | %8luB ", i, el3_size);
 #if CTX_INCLUDE_EL2_REGS
+		el2_size = sizeof(ctx->el2_sysregs_ctx);
 		size_other -= el2_size;
+		el2_total += el2_size;
 		printf("| %8luB ", el2_size);
+#else
+		el1_size = sizeof(ctx->el1_sysregs_ctx);
+		size_other -= el1_size;
+		el1_total += el1_size;
+		printf("| %8luB ", el1_size);
 #endif /* CTX_INCLUDE_EL2_REGS */
-		printf("| %8luB | %8luB | %8luB |\n", el1_size, size_other, core_total);
 
+#if CTX_INCLUDE_PAUTH_REGS
+		pauth_size = sizeof(ctx->pauth_ctx);
+		size_other -= pauth_size;
+		pauth_total += pauth_size;
+		printf("| %8luB ", pauth_size);
+#endif
+		printf("| %8luB | %8luB |\n", size_other, core_total);
+
+		gp_total += gp_size;
 		el3_total += el3_size;
-#if CTX_INCLUDE_EL2_REGS
-		el2_total += el2_size;
-#endif /* CTX_INCLUDE_EL2_REGS */
-		el1_total += el1_size;
 		other_total += size_other;
 		total += core_total;
 	}
+
+#if CTX_INCLUDE_PAUTH_REGS
+	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
+
 	PRINT_MEM_USAGE_SEPARATOR();
+
+#if CTX_INCLUDE_PAUTH_REGS
+	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
+
 	PRINT_MEM_USAGE_SEPARATOR();
-	printf("|    All    | %8luB ", el3_total);
+
+	printf("|    All    | %8luB | %8luB ", gp_total, el3_total);
+
 #if CTX_INCLUDE_EL2_REGS
 	printf("| %8luB ", el2_total);
+#else
+	printf("| %8luB ", el1_total);
 #endif /* CTX_INCLUDE_EL2_REGS */
-	printf("| %8luB | %8luB | %8luB |\n", el1_total, other_total, total);
+
+#if CTX_INCLUDE_PAUTH_REGS
+	printf("| %8luB ", pauth_total);
+#endif
+
+	printf("| %8luB | %8luB |\n", other_total, total);
+
+#if CTX_INCLUDE_PAUTH_REGS
+	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
 	PRINT_MEM_USAGE_SEPARATOR();
 	printf("\n");
 
@@ -146,18 +198,10 @@
 
 		printf("Memory usage for %s:\n", context_name);
 		total += report_allocated_memory(i);
-			printf("------------------------"
-#if CTX_INCLUDE_EL2_REGS
-				"------"
-#endif /* CTX_INCLUDE_EL2_REGS */
-			      );
+			printf("------------------------");
 			len = NAME_PLACEHOLDER_LEN - printf("End %s", context_name);
 			PRINT_DASH(len);
-			printf(
-#if CTX_INCLUDE_EL2_REGS
-				"------"
-#endif /* CTX_INCLUDE_EL2_REGS */
-				"-----------------------\n\n");
+			printf("-----------------------\n\n");
 	}
 
 	printf("Total context memory allocated: %luB\n\n", total);
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 981fddc..7c84e0e 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -19,17 +19,22 @@
 #include <common/debug.h>
 #include <context.h>
 #include <drivers/arm/gicv3.h>
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/el3_runtime/cpu_data.h>
 #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>
 #include <lib/extensions/spe.h>
 #include <lib/extensions/sve.h>
 #include <lib/extensions/sys_reg_trace.h>
+#include <lib/extensions/tcr2.h>
 #include <lib/extensions/trbe.h>
 #include <lib/extensions/trf.h>
 #include <lib/utils.h>
@@ -47,6 +52,7 @@
 static void manage_extensions_secure(cpu_context_t *ctx);
 static void manage_extensions_secure_per_world(void);
 
+#if ((IMAGE_BL1) || (IMAGE_BL31 && (!CTX_INCLUDE_EL2_REGS)))
 static void setup_el1_context(cpu_context_t *ctx, const struct entry_point_info *ep)
 {
 	u_register_t sctlr_elx, actlr_elx;
@@ -83,15 +89,16 @@
 					| SCTLR_NTWI_BIT | SCTLR_NTWE_BIT;
 	}
 
-#if ERRATA_A75_764081
 	/*
 	 * If workaround of errata 764081 for Cortex-A75 is used then set
 	 * SCTLR_EL1.IESB to enable Implicit Error Synchronization Barrier.
 	 */
-	sctlr_elx |= SCTLR_IESB_BIT;
-#endif
+	if (errata_a75_764081_applies()) {
+		sctlr_elx |= SCTLR_IESB_BIT;
+	}
+
 	/* Store the initialised SCTLR_EL1 value in the cpu_context */
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
+	write_ctx_sctlr_el1_reg_errata(ctx, sctlr_elx);
 
 	/*
 	 * Base the context ACTLR_EL1 on the current value, as it is
@@ -101,8 +108,9 @@
 	 * 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);
 }
+#endif /* (IMAGE_BL1) || (IMAGE_BL31 && (!CTX_INCLUDE_EL2_REGS)) */
 
 /******************************************************************************
  * This function performs initializations that are specific to SECURE state
@@ -135,7 +143,7 @@
 	 * Initialize EL1 context registers unless SPMC is running
 	 * at S-EL2.
 	 */
-#if !SPMD_SPM_AT_SEL2
+#if (!SPMD_SPM_AT_SEL2)
 	setup_el1_context(ctx, ep);
 #endif
 
@@ -151,7 +159,6 @@
 	if (!has_secure_perworld_init) {
 		manage_extensions_secure_per_world();
 	}
-
 }
 
 #if ENABLE_RME
@@ -253,13 +260,25 @@
 	 */
 	scr_el3 |= get_scr_el3_from_routing_model(NON_SECURE);
 #endif
-	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 
-	/* Initialize EL1 context registers */
-	setup_el1_context(ctx, ep);
+	if (is_feat_the_supported()) {
+		/* Set the RCWMASKEn bit in SCR_EL3 to enable access to
+		 * RCWMASK_EL1 and RCWSMASK_EL1 registers.
+		 */
+		scr_el3 |= SCR_RCWMASKEn_BIT;
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		/* Set the SCTLR2En bit in SCR_EL3 to enable access to
+		 * SCTLR2_ELx registers.
+		 */
+		scr_el3 |= SCR_SCTLR2En_BIT;
+	}
+
+	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 
 	/* Initialize EL2 context registers */
-#if CTX_INCLUDE_EL2_REGS
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 
 	/*
 	 * Initialize SCTLR_EL2 context register with reset value.
@@ -292,8 +311,10 @@
 		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgwtr_el2,
 			HFGWTR_EL2_INIT_VAL);
 	}
-
-#endif /* CTX_INCLUDE_EL2_REGS */
+#else
+	/* Initialize EL1 context registers */
+	setup_el1_context(ctx, ep);
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 
 	manage_extensions_nonsecure(ctx);
 }
@@ -324,7 +345,7 @@
 	 * to boot correctly. However, there are very few registers where this
 	 * is not true and some values need to be recreated.
 	 */
-#if CTX_INCLUDE_EL2_REGS
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 	el2_sysregs_t *el2_ctx = get_el2_sysregs_ctx(ctx);
 
 	/*
@@ -334,7 +355,13 @@
 	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);
-#endif /* CTX_INCLUDE_EL2_REGS */
+
+	/*
+	 * 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 && IMAGE_BL31) */
 
 	/* Start with a clean SCR_EL3 copy as all relevant values are set */
 	scr_el3 = SCR_RESET_VAL;
@@ -736,7 +763,7 @@
 
 	if (is_feat_trbe_supported()) {
 		/*
-		 * Enable FEAT_SPE for Non-Secure and prohibit for Secure and
+		 * Enable FEAT_TRBE for Non-Secure and prohibit for Secure and
 		 * Realm state.
 		 */
 		trbe_enable(ctx);
@@ -744,14 +771,14 @@
 
 	if (is_feat_trf_supported()) {
 		/*
-		 * Enable FEAT_SPE for Non-Secure and prohibit for Secure state.
+		 * Enable FEAT_TRF for Non-Secure and prohibit for Secure state.
 		 */
 		trf_enable(ctx);
 	}
 
 	if (is_feat_brbe_supported()) {
 		/*
-		 * Enable FEAT_SPE for Non-Secure and prohibit for Secure state.
+		 * Enable FEAT_BRBE for Non-Secure and prohibit for Secure state.
 		 */
 		brbe_enable(ctx);
 	}
@@ -772,6 +799,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 */
 }
@@ -1050,14 +1085,16 @@
 			if ((scr_el3 & SCR_HCE_BIT) != 0U) {
 				/* 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_el2 |= SCTLR_IESB_BIT;
-#endif
+				if (errata_a75_764081_applies()) {
+					sctlr_el2 |= SCTLR_IESB_BIT;
+				}
+
 				write_sctlr_el2(sctlr_el2);
 			} else {
 				/*
@@ -1068,11 +1105,14 @@
 			}
 		}
 	}
+#if (!CTX_INCLUDE_EL2_REGS)
+	/* Restore EL1 system registers, only when CTX_INCLUDE_EL2_REGS=0 */
 	cm_el1_sysregs_context_restore(security_state);
+#endif
 	cm_set_next_eret_context(security_state);
 }
 
-#if CTX_INCLUDE_EL2_REGS
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 
 static void el2_sysregs_context_save_fgt(el2_sysregs_t *ctx)
 {
@@ -1098,6 +1138,24 @@
 	write_hfgwtr_el2(read_el2_ctx_fgt(ctx, hfgwtr_el2));
 }
 
+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_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();
@@ -1337,6 +1395,10 @@
 		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());
 	}
@@ -1390,6 +1452,10 @@
 		write_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2, read_gcscr_el2());
 		write_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2, read_gcspr_el2());
 	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_el2_ctx_sctlr2(el2_sysregs_ctx, sctlr2_el2, read_sctlr2_el2());
+	}
 }
 
 /*******************************************************************************
@@ -1420,6 +1486,10 @@
 		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));
 	}
@@ -1473,8 +1543,60 @@
 		write_gcscr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2));
 		write_gcspr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2));
 	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_sctlr2_el2(read_el2_ctx_sctlr2(el2_sysregs_ctx, sctlr2_el2));
+	}
 }
-#endif /* CTX_INCLUDE_EL2_REGS */
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
+
+#if IMAGE_BL31
+/*********************************************************************************
+* This function allows Architecture features asymmetry among cores.
+* TF-A assumes that all the cores in the platform has architecture feature parity
+* and hence the context is setup on different core (e.g. primary sets up the
+* context for secondary cores).This assumption may not be true for systems where
+* cores are not conforming to same Arch version or there is CPU Erratum which
+* requires certain feature to be be disabled only on a given core.
+*
+* This function is called on secondary cores to override any disparity in context
+* setup by primary, this would be called during warmboot path.
+*********************************************************************************/
+void cm_handle_asymmetric_features(void)
+{
+	cpu_context_t *ctx __maybe_unused = cm_get_context(NON_SECURE);
+
+	assert(ctx != NULL);
+
+#if ENABLE_SPE_FOR_NS == FEAT_STATE_CHECK_ASYMMETRIC
+	if (is_feat_spe_supported()) {
+		spe_enable(ctx);
+	} else {
+		spe_disable(ctx);
+	}
+#endif
+
+#if ERRATA_A520_2938996 || ERRATA_X4_2726228
+	if (check_if_affected_core() == ERRATA_APPLIES) {
+		if (is_feat_trbe_supported()) {
+			trbe_disable(ctx);
+		}
+	}
+#endif
+
+#if ENABLE_FEAT_TCR2 == FEAT_STATE_CHECK_ASYMMETRIC
+	el3_state_t *el3_state = get_el3state_ctx(ctx);
+	u_register_t spsr = read_ctx_reg(el3_state, CTX_SPSR_EL3);
+
+	if (is_feat_tcr2_supported() && (GET_RW(spsr) == MODE_RW_64)) {
+		tcr2_enable(ctx);
+	} else {
+		tcr2_disable(ctx);
+	}
+#endif
+
+}
+#endif
 
 /*******************************************************************************
  * This function is used to exit to Non-secure world. If CTX_INCLUDE_EL2_REGS
@@ -1484,7 +1606,19 @@
  ******************************************************************************/
 void cm_prepare_el3_exit_ns(void)
 {
-#if CTX_INCLUDE_EL2_REGS
+#if IMAGE_BL31
+	/*
+	 * Check and handle Architecture feature asymmetry among cores.
+	 *
+	 * In warmboot path secondary cores context is initialized on core which
+	 * did CPU_ON SMC call, if there is feature asymmetry in these cores handle
+	 * it in this function call.
+	 * For Symmetric cores this is an empty function.
+	 */
+	cm_handle_asymmetric_features();
+#endif
+
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 #if ENABLE_ASSERTIONS
 	cpu_context_t *ctx = cm_get_context(NON_SECURE);
 	assert(ctx != NULL);
@@ -1495,237 +1629,232 @@
 			(el_implemented(2U) != EL_IMPL_NONE));
 #endif /* ENABLE_ASSERTIONS */
 
-	/* Restore EL2 and EL1 sysreg contexts */
+	/* Restore EL2 sysreg contexts */
 	cm_el2_sysregs_context_restore(NON_SECURE);
-	cm_el1_sysregs_context_restore(NON_SECURE);
 	cm_set_next_eret_context(NON_SECURE);
 #else
 	cm_prepare_el3_exit(NON_SECURE);
-#endif /* CTX_INCLUDE_EL2_REGS */
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 }
 
+#if ((IMAGE_BL1) || (IMAGE_BL31 && (!CTX_INCLUDE_EL2_REGS)))
+/*******************************************************************************
+ * The next set of six functions are used by runtime services to save and restore
+ * EL1 context on the 'cpu_context' structure for the specified security state.
+ ******************************************************************************/
 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
+
+	if (is_feat_the_supported()) {
+		write_el1_ctx_the(ctx, rcwmask_el1, read_rcwmask_el1());
+		write_el1_ctx_the(ctx, rcwsmask_el1, read_rcwsmask_el1());
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_el1_ctx_sctlr2(ctx, sctlr2_el1, read_sctlr2_el1());
+	}
+
 }
 
 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
+
+	if (is_feat_the_supported()) {
+		write_rcwmask_el1(read_el1_ctx_the(ctx, rcwmask_el1));
+		write_rcwsmask_el1(read_el1_ctx_the(ctx, rcwsmask_el1));
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_sctlr2_el1(read_el1_ctx_sctlr2(ctx, sctlr2_el1));
+	}
+
 }
 
 /*******************************************************************************
- * The next four functions are used by runtime services to save and restore
- * EL1 context on the 'cpu_context' structure for the specified security
- * state.
+ * The next couple of functions are used by runtime services to save and restore
+ * EL1 context on the 'cpu_context' structure for the specified security state.
  ******************************************************************************/
 void cm_el1_sysregs_context_save(uint32_t security_state)
 {
@@ -1761,6 +1890,8 @@
 #endif
 }
 
+#endif /* ((IMAGE_BL1) || (IMAGE_BL31 && (!CTX_INCLUDE_EL2_REGS))) */
+
 /*******************************************************************************
  * This function populates ELR_EL3 member of 'cpu_context' pertaining to the
  * given security state with the given entrypoint
diff --git a/lib/el3_runtime/simd_ctx.c b/lib/el3_runtime/simd_ctx.c
new file mode 100644
index 0000000..f7a87df
--- /dev/null
+++ b/lib/el3_runtime/simd_ctx.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <lib/el3_runtime/aarch64/context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/el3_runtime/cpu_data.h>
+#include <lib/el3_runtime/simd_ctx.h>
+#include <lib/extensions/sve.h>
+#include <plat/common/platform.h>
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+
+/* SIMD context managed for Secure and Normal Worlds. */
+#define SIMD_CTXT_COUNT	2
+
+#if SEPARATE_SIMD_SECTION
+__section(".simd_context")
+#else
+__section(".bss.simd_context")
+#endif
+static simd_regs_t simd_context[SIMD_CTXT_COUNT][PLATFORM_CORE_COUNT];
+
+void simd_ctx_save(uint32_t security_state, bool hint_sve)
+{
+	simd_regs_t *regs;
+
+	if (security_state != NON_SECURE && security_state != SECURE) {
+		ERROR("Unsupported security state specified for SIMD context: %u\n",
+		      security_state);
+		panic();
+	}
+
+	regs = &simd_context[security_state][plat_my_core_pos()];
+
+#if CTX_INCLUDE_SVE_REGS
+	regs->hint = hint_sve;
+
+	if (hint_sve) {
+		/*
+		 * Hint bit denoting absence of SVE live state. Hence, only
+		 * save FP context.
+		 */
+		fpregs_context_save(regs);
+	} else {
+		sve_context_save(regs);
+	}
+#elif CTX_INCLUDE_FPREGS
+	fpregs_context_save(regs);
+#endif
+}
+
+void simd_ctx_restore(uint32_t security_state)
+{
+	simd_regs_t *regs;
+
+	if (security_state != NON_SECURE && security_state != SECURE) {
+		ERROR("Unsupported security state specified for SIMD context: %u\n",
+		      security_state);
+		panic();
+	}
+
+	regs = &simd_context[security_state][plat_my_core_pos()];
+
+#if CTX_INCLUDE_SVE_REGS
+	if (regs->hint) {
+		fpregs_context_restore(regs);
+	} else {
+		sve_context_restore(regs);
+	}
+#elif CTX_INCLUDE_FPREGS
+	fpregs_context_restore(regs);
+#endif
+}
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
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/pmuv3/aarch64/pmuv3.c b/lib/extensions/pmuv3/aarch64/pmuv3.c
index 71aa303..f9e32ca 100644
--- a/lib/extensions/pmuv3/aarch64/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch64/pmuv3.c
@@ -23,13 +23,13 @@
 
 void pmuv3_enable(cpu_context_t *ctx)
 {
-#if CTX_INCLUDE_EL2_REGS
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 	u_register_t mdcr_el2_val;
 
 	mdcr_el2_val = read_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2);
 	mdcr_el2_val = init_mdcr_el2_hpmn(mdcr_el2_val);
 	write_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2, mdcr_el2_val);
-#endif /* CTX_INCLUDE_EL2_REGS */
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 }
 
 static u_register_t mtpmu_disable_el3(u_register_t mdcr_el3)
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index c6076fe..d653222 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -52,6 +52,27 @@
 	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)
 {
 	uint64_t v;
@@ -70,7 +91,7 @@
 	write_mdcr_el2(v);
 }
 
-void spe_disable(void)
+void spe_stop(void)
 {
 	uint64_t v;
 
diff --git a/lib/extensions/tcr/tcr2.c b/lib/extensions/tcr/tcr2.c
new file mode 100644
index 0000000..70bc5f8
--- /dev/null
+++ b/lib/extensions/tcr/tcr2.c
@@ -0,0 +1,42 @@
+/*
+ * 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/tcr2.h>
+
+void tcr2_enable(cpu_context_t *ctx)
+{
+	u_register_t reg;
+	el3_state_t *state;
+
+	state = get_el3state_ctx(ctx);
+
+	/* Set the TCR2EN bit in SCR_EL3 to enable access to TCR2_EL1,
+	 * and TCR2_EL2 registers .
+	 */
+
+	reg = read_ctx_reg(state, CTX_SCR_EL3);
+	reg |= SCR_TCR2EN_BIT;
+	write_ctx_reg(state, CTX_SCR_EL3, reg);
+}
+
+void tcr2_disable(cpu_context_t *ctx)
+{
+	u_register_t reg;
+	el3_state_t *state;
+
+	state = get_el3state_ctx(ctx);
+
+	/* Clear the TCR2EN bit in SCR_EL3 to disable access to TCR2_EL1,
+	 * and TCR2_EL2 registers .
+	 */
+
+	reg = read_ctx_reg(state, CTX_SCR_EL3);
+	reg &= ~SCR_TCR2EN_BIT;
+	write_ctx_reg(state, CTX_SCR_EL3, reg);
+}
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
index 9157734..8c1c421 100644
--- a/lib/extensions/trbe/trbe.c
+++ b/lib/extensions/trbe/trbe.c
@@ -39,6 +39,25 @@
 	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/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index d028fce..79c4ea5 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -495,7 +495,7 @@
  *
  * Parameters
  *   l0_mem_base	Base address of memory used for L0 tables.
- *   l1_mem_size	Size of memory available for L0 tables.
+ *   l0_mem_size	Size of memory available for L0 tables.
  *
  * Return
  *   Negative Linux error code in the event of a failure, 0 for success.
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 60449f6..375cdba 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -182,9 +182,9 @@
 	}
 
 	my_idx = plat_my_core_pos();
-
-	for (lvl = PSCI_CPU_PWR_LVL; lvl <= end_pwrlvl; lvl++) {
-		parent_idx = psci_cpu_pd_nodes[my_idx].parent_node;
+	parent_idx = psci_cpu_pd_nodes[my_idx].parent_node;
+	for (lvl = PSCI_CPU_PWR_LVL + U(1); lvl < end_pwrlvl; lvl++) {
+		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 	}
 
 	cpu_start_idx = psci_non_cpu_pd_nodes[parent_idx].cpu_start_idx;
@@ -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 9ade331..3d2b850 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -4,12 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-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
 
@@ -44,50 +39,54 @@
 
 .PHONY: all clean distclean
 
-all: $(BUILD_DIR)/romlib.bin $(LIB_DIR)/libwrappers.a
+all: $(BUILD_DIR)/romlib.bin $(BUILD_DIR)/romlib.ldflags $(LIB_DIR)/libwrappers.a
 
-%.o: %.s
+%.o: %.s | $$(@D)/
 	$(s)echo "  AS      $@"
 	$(q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
 
-$(BUILD_DIR)/%.o: %.s
+$(BUILD_DIR)/%.o: %.s | $$(@D)/
 	$(s)echo "  AS      $@"
 	$(q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
 
-$(BUILD_DIR)/romlib.ld: 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
+$(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
+$(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
+$(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)
+$(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
+$(BUILD_DIR)/jmptbl.i: ../../$(PLAT_DIR)/jmptbl.i | $$(@D)/
 	$(s)echo "  PRE     $@"
 	$(q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
 
-$(WRAPPER_SOURCES) &: $(BUILD_DIR)/jmptbl.i
+$(WRAPPER_SOURCES) &: $(BUILD_DIR)/jmptbl.i | $$(@D)/
 	$(s)echo "  WRP     $<"
 	$(q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
 
-$(WRAPPER_OBJS): $(WRAPPER_DIR)/%.o: $(WRAPPER_DIR)/%.s
+$(WRAPPER_OBJS): $(WRAPPER_DIR)/%.o: $(WRAPPER_DIR)/%.s | $$(@D)/
 
-$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i
+$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i | $$(@D)/
 	$(s)echo "  TBL     $@"
 	$(q)$(ROMLIB_GEN) gentbl --output $@ --bti=$(ENABLE_BTI) $<
 
+$(BUILD_DIR)/romlib.ldflags: ../../$(PLAT_DIR)/jmptbl.i
+	$(s)echo "  LDFLAGS $@"
+	$(q)$(ROMLIB_GEN) link-flags $< > $@
+
 clean:
 	$(q)rm -f $(BUILD_DIR)/*
 
diff --git a/lib/romlib/romlib_generator.py b/lib/romlib/romlib_generator.py
index 0682dd4..8d2e88d 100755
--- a/lib/romlib/romlib_generator.py
+++ b/lib/romlib/romlib_generator.py
@@ -182,6 +182,22 @@
                 template_name = "jmptbl_entry_" + item["type"] + bti + ".S"
                 output_file.write(self.build_template(template_name, item, True))
 
+class LinkArgs(RomlibApplication):
+    """ Generates the link arguments to wrap functions. """
+
+    def __init__(self, prog):
+        RomlibApplication.__init__(self, prog)
+        self.args.add_argument("file", help="Input file")
+
+    def main(self):
+        index_file_parser = IndexFileParser()
+        index_file_parser.parse(self.config.file)
+
+        fns = [item["function_name"] for item in index_file_parser.items
+               if not item["patch"] and item["type"] != "reserved"]
+
+        print(" ".join("-Wl,--wrap " + f for f in fns))
+
 class WrapperGenerator(RomlibApplication):
     """
     Generates a wrapper function for each entry in the index file except for the ones that contain
@@ -214,21 +230,19 @@
             if item["type"] == "reserved" or item["patch"]:
                 continue
 
-            asm = self.config.b + "/" + item["function_name"] + ".s"
-            if self.config.list:
-                # Only listing files
-                files.append(asm)
-            else:
-                with open(asm, "w") as asm_file:
-                    # The jump instruction is 4 bytes but BTI requires and extra instruction so
-                    # this makes it 8 bytes per entry.
-                    function_offset = item_index * (8 if self.config.bti else 4)
+            if not self.config.list:
+                # The jump instruction is 4 bytes but BTI requires and extra instruction so
+                # this makes it 8 bytes per entry.
+                function_offset = item_index * (8 if self.config.bti else 4)
 
-                    item["function_offset"] = function_offset
-                    asm_file.write(self.build_template("wrapper" + bti + ".S", item))
+                item["function_offset"] = function_offset
+                files.append(self.build_template("wrapper" + bti + ".S", item))
 
         if self.config.list:
-            print(" ".join(files))
+            print(self.config.b + "/wrappers.s")
+        else:
+            with open(self.config.b + "/wrappers.s", "w") as asm_file:
+                asm_file.write("\n".join(files))
 
 class VariableGenerator(RomlibApplication):
     """ Generates the jump table global variable with the absolute address in ROM. """
@@ -258,7 +272,8 @@
 
 if __name__ == "__main__":
     APPS = {"genvar": VariableGenerator, "pre": IndexPreprocessor,
-            "gentbl": TableGenerator, "genwrappers": WrapperGenerator}
+            "gentbl": TableGenerator, "genwrappers": WrapperGenerator,
+            "link-flags": LinkArgs}
 
     if len(sys.argv) < 2 or sys.argv[1] not in APPS:
         print("usage: romlib_generator.py [%s] [args]" % "|".join(APPS.keys()), file=sys.stderr)
diff --git a/lib/romlib/templates/wrapper.S b/lib/romlib/templates/wrapper.S
index 734a68a..576474a 100644
--- a/lib/romlib/templates/wrapper.S
+++ b/lib/romlib/templates/wrapper.S
@@ -3,8 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-	.globl	${function_name}
-${function_name}:
+	.section .text.__wrap_${function_name}
+	.globl	__wrap_${function_name}
+__wrap_${function_name}:
 	ldr	x17, =jmptbl
 	mov	x16, #${function_offset}
 	ldr	x17, [x17]
diff --git a/lib/romlib/templates/wrapper_bti.S b/lib/romlib/templates/wrapper_bti.S
index ba9b11c..0dc316c 100644
--- a/lib/romlib/templates/wrapper_bti.S
+++ b/lib/romlib/templates/wrapper_bti.S
@@ -3,8 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-	.globl	${function_name}
-${function_name}:
+	.section .text.__wrap_${function_name}
+	.globl	__wrap_${function_name}
+__wrap_${function_name}:
 	bti	jc
 	ldr	x17, =jmptbl
 	mov	x16, #${function_offset}
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..9533e98 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 ENABLE_FEAT_SCTLR2
 # 8.8 Compliant
 armv8-9-a-feats         += ${armv8-8-a-feats}
 FEAT_LIST               := ${armv8-9-a-feats}
@@ -219,6 +219,9 @@
 # Flag to enable access to TCR2 (FEAT_TCR2).
 ENABLE_FEAT_TCR2		?=	0
 
+# Flag to enable access to SCTLR2 (FEAT_SCTLR2).
+ENABLE_FEAT_SCTLR2		?=	0
+
 #
 ################################################################################
 # Optional Features defaulted to 0 or 2, if they are not enabled from
@@ -280,7 +283,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
@@ -310,7 +313,7 @@
 ifeq ($(CTX_INCLUDE_MTE_REGS),1)
         $(warning CTX_INCLUDE_MTE_REGS option is deprecated, Check ENABLE_FEAT_MTE2 usage)
 endif
-ifeq ($(ENABLE_FEAT_MTE),1)
+ifneq ($(ENABLE_FEAT_MTE),)
         $(warning ENABLE_FEAT_MTE option is deprecated, Check ENABLE_FEAT_MTE2 usage)
 endif
 
@@ -337,7 +340,17 @@
 # Disable MTPMU if FEAT_MTPMU is supported.
 DISABLE_MTPMU				?=	0
 
+# Flag to enable FEAT_FGT2 (Fine Granular Traps 2)
+ENABLE_FEAT_FGT2			?=	0
+
 #----
+# 8.8
+#----
+
+# Flag to enable FEAT_THE (Translation Hardening Extension)
+ENABLE_FEAT_THE				?=	0
+
+#----
 # 8.9
 #----
 
@@ -353,6 +366,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 d27408c..f523074 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -289,7 +289,7 @@
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 $(eval LIB := $(call uppercase, $(notdir $(1))))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
 	$$(s)echo "  CC      $$<"
 	$$(q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
@@ -305,7 +305,7 @@
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
+$(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 $$@
 
@@ -328,7 +328,7 @@
 $(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
+$(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 $$@
 
@@ -351,7 +351,7 @@
 $(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
+$(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 $$@
 
@@ -372,7 +372,7 @@
 $(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
+$(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 $$@ $$<
 
@@ -424,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
@@ -445,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}
@@ -465,7 +451,7 @@
 
 all: ${LIB_DIR}/lib$(1).a
 
-${LIB_DIR}/lib$(1).a: $(OBJS)
+${LIB_DIR}/lib$(1).a: $(OBJS) | $$$$(@D)/
 	$$(s)echo "  AR      $$@"
 	$$(q)$($(ARCH)-ar) cr $$@ $$?
 endef
@@ -479,6 +465,10 @@
         $(patsubst %.S,$(BUILD_DIR)/%,$(1))
 endef
 
+ifeq ($(USE_ROMLIB),1)
+WRAPPER_FLAGS := @${BUILD_PLAT}/romlib/romlib.ldflags
+endif
+
 # MAKE_BL macro defines the targets and options to build each BL image.
 # Arguments:
 #   $(1) = BL stage
@@ -503,26 +493,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
@@ -532,14 +502,14 @@
 $(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)
+$(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 \
@@ -548,11 +518,11 @@
 		--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) $$(WRAPPER_FLAGS) $(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) $$(WRAPPER_FLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
 		$(addprefix -T ,$(LINKER_SCRIPTS)) --script $(DEFAULT_LINKER_SCRIPT) \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 endif
@@ -562,11 +532,11 @@
 	$(s)echo
 endif
 
-$(DUMP): $(ELF)
+$(DUMP): $(ELF) | $$$$(@D)/
 	$$(s)echo "  OD      $$@"
 	$$(q)$($(ARCH)-od) -dx $$< > $$@
 
-$(BIN): $(ELF)
+$(BIN): $(ELF) | $$$$(@D)/
 	$$(s)echo "  BIN     $$@"
 	$$(q)$($(ARCH)-oc) -O binary $$< $$@
 	$(s)echo
@@ -598,22 +568,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
@@ -628,12 +582,12 @@
 # Dependencies of the DT compilation on its pre-compiled DTS
 $(eval DTBDEP := $(patsubst %.dtb,%.d,$(DOBJ)))
 
-$(DPRE): $(2) | fdt_dirs
+$(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) $$<
 
-$(DOBJ): $(DPRE) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
+$(DOBJ): $(DPRE) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
 	$$(s)echo "  DTC     $$<"
 	$$(q)$($(ARCH)-dtc) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $$<
 
@@ -651,8 +605,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/defaults.mk b/make_helpers/defaults.mk
index 368d26d..584542c 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -63,6 +63,9 @@
 # Include FP registers in cpu context
 CTX_INCLUDE_FPREGS		:= 0
 
+# Include SVE registers in cpu context
+CTX_INCLUDE_SVE_REGS		:= 0
+
 # Debug build
 DEBUG				:= 0
 
@@ -143,7 +146,7 @@
 RME_GPT_BITLOCK_BLOCK		:= 1
 
 # Default maximum size of GPT contiguous block
-RME_GPT_MAX_BLOCK		:= 2
+RME_GPT_MAX_BLOCK		:= 512
 
 # Hint platform interrupt control layer that Group 0 interrupts are for EL3. By
 # default, they are for Secure EL1.
@@ -237,6 +240,10 @@
 # region, platform Makefile is free to override this value.
 SEPARATE_BL2_NOLOAD_REGION	:= 0
 
+# Put SIMD context data structures in a separate memory region. Platforms
+# have the choice to put it outside of default BSS region of EL3 firmware.
+SEPARATE_SIMD_SECTION		:= 0
+
 # If the BL31 image initialisation code is recalimed after use for the secondary
 # cores stack
 RECLAIM_INIT_CODE		:= 0
@@ -402,3 +409,6 @@
 # Allow platforms to save/restore DSU PMU registers over a power cycle.
 # Disabled by default and must be enabled by individual platforms.
 PRESERVE_DSU_PMU_REGS		:= 0
+
+# Enable RMMD to forward attestation requests from RMM to EL3.
+RMMD_ENABLE_EL3_TOKEN_SIGN	:= 0
diff --git a/make_helpers/plat_helpers.mk b/make_helpers/plat_helpers.mk
index a7ae9a2..bc02a20 100644
--- a/make_helpers/plat_helpers.mk
+++ b/make_helpers/plat_helpers.mk
@@ -11,6 +11,7 @@
 ifndef PLAT_HELPERS_MK
     PLAT_HELPERS_MK := $(lastword $(MAKEFILE_LIST))
 
+    PLAT:= ${DEFAULT_PLAT}
     ifeq (${PLAT},)
         $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform")
     endif
@@ -18,15 +19,18 @@
     # TF_PLATFORM_ROOT can be overridden for when building tools directly
     TF_PLATFORM_ROOT               ?= plat/
     PLAT_MAKEFILE               := platform.mk
+    PLAT_DEFAULTS_MAKEFILE      := platform_defaults.mk
 
     # Generate the platforms list by recursively searching for all directories
     # under /plat containing a PLAT_MAKEFILE. Append each platform with a `|`
     # char and strip out the final '|'.
     ALL_PLATFORM_MK_FILES       := $(call rwildcard,${TF_PLATFORM_ROOT},${PLAT_MAKEFILE})
+    ALL_PLATFORM_MK_DEF_FILES   := $(call rwildcard,${TF_PLATFORM_ROOT},${PLAT_DEFAULTS_MAKEFILE})
     ALL_PLATFORM_DIRS           := $(patsubst %/,%,$(dir ${ALL_PLATFORM_MK_FILES}))
     ALL_PLATFORMS               := $(sort $(notdir ${ALL_PLATFORM_DIRS}))
 
     PLAT_MAKEFILE_FULL          := $(filter %/${PLAT}/${PLAT_MAKEFILE},${ALL_PLATFORM_MK_FILES})
+    PLAT_DEFAULTS_MAKEFILE_FULL := $(filter %/${PLAT}/${PLAT_DEFAULTS_MAKEFILE},${ALL_PLATFORM_MK_DEF_FILES})
     PLATFORM_LIST               := $(subst ${space},|,${ALL_PLATFORMS})
     ifeq ($(PLAT_MAKEFILE_FULL),)
         $(error "Error: Invalid platform. The following platforms are available: ${PLATFORM_LIST}")
diff --git a/make_helpers/toolchain.mk b/make_helpers/toolchain.mk
index 96e43a8..2ab577c 100644
--- a/make_helpers/toolchain.mk
+++ b/make_helpers/toolchain.mk
@@ -18,13 +18,74 @@
 ifndef toolchain-mk
         toolchain-mk := $(lastword $(MAKEFILE_LIST))
 
-        toolchains ?= host $(ARCH)
+        include $(dir $(toolchain-mk))build_env.mk
+        include $(dir $(toolchain-mk))utilities.mk
 
-        include $(dir $(lastword $(MAKEFILE_LIST)))build_env.mk
-        include $(dir $(lastword $(MAKEFILE_LIST)))utilities.mk
+        #
+        # Make assigns generic default values to `CC`, `CPP`, `AS`, etc. if they
+        # are not explicitly assigned values by the user. These are usually okay
+        # for very simple programs when building for the host system, but we
+        # need greater control over the toolchain flow.
+        #
+        # Therefore, we undefine these built-in variables if they have default
+        # values, so that we can provide our own default values later instead.
+        #
+
+        ifeq ($(origin CC),default)
+                undefine CC
+        endif
+
+        ifeq ($(origin CPP),default)
+                undefine CPP
+        endif
+
+        ifeq ($(origin AS),default)
+                undefine AS
+        endif
+
+        ifeq ($(origin AR),default)
+                undefine AR
+        endif
+
+        ifeq ($(origin LD),default)
+                undefine LD
+        endif
+
+        #
+        # The full list of toolchains supported by TF-A.
+        #
+        # Each of these toolchains defines a file of the same name in the
+        # `toolchains` directory, which must configure the following variables:
+        #
+        #   - <toolchain>-name
+        #
+        #     A human-readable name for the toolchain,
+        #
+        # Additionally, for every tool class, it must also define:
+        #
+        #   - <toolchain>-<tool-class>-parameter
+        #
+        #     The command line or environment variable used to set the tool for
+        #     for the given tool class.
+        #
+        #   - <toolchain>-<tool-class>-default-id
+        #
+        #     The default tool identifier used if the tool for the given tool
+        #     class cannot be identified.
+        #
+        #   - <toolchain>-<tool-class>-default
+        #
+        #     The default commands to try, in the order defined, for the given
+        #     tool class if the user does not explicitly provide one, and if the
+        #     command could not be derived from the C compiler.
+        #
 
-        include $(addprefix $(dir $(lastword $(MAKEFILE_LIST)))toolchains/, \
-                $(addsuffix .mk,$(toolchains)))
+        toolchains := host # Used for host targets
+        toolchains += aarch32 # Used for AArch32 targets
+        toolchains += aarch64 # Used for AArch64 targets
+        toolchains += rk3399-m0 # Used for RK3399 Cortex-M0 targets
+
+        include $(toolchains:%=$(dir $(toolchain-mk))toolchains/%.mk)
 
         #
         # Configure tool classes that we recognize.
@@ -33,29 +94,32 @@
         # specific role or type of tool in the toolchain.
         #
 
-        tool-classes := cc
-        tool-class-name-cc := C compiler
+        toolchain-tool-classes := cc
+        toolchain-tool-class-name-cc := C compiler
 
-        tool-classes += cpp
-        tool-class-name-cpp := C preprocessor
+        toolchain-tool-classes += cpp
+        toolchain-tool-class-name-cpp := C preprocessor
 
-        tool-classes += as
-        tool-class-name-as := assembler
+        toolchain-tool-classes += as
+        toolchain-tool-class-name-as := assembler
 
-        tool-classes += ld
-        tool-class-name-ld := linker
+        toolchain-tool-classes += ld
+        toolchain-tool-class-name-ld := linker
 
-        tool-classes += oc
-        tool-class-name-oc := object copier
+        toolchain-tool-classes += oc
+        toolchain-tool-class-name-oc := object copier
 
-        tool-classes += od
-        tool-class-name-od := object dumper
+        toolchain-tool-classes += od
+        toolchain-tool-class-name-od := object dumper
 
-        tool-classes += ar
-        tool-class-name-ar := archiver
+        toolchain-tool-classes += ar
+        toolchain-tool-class-name-ar := archiver
 
-        tool-classes += dtc
-        tool-class-name-dtc := device tree compiler
+        toolchain-tool-classes += dtc
+        toolchain-tool-class-name-dtc := device tree compiler
+
+        toolchain-tool-classes += poetry
+        toolchain-tool-class-name-poetry := Python Poetry package manager
 
         #
         # Configure tools that we recognize.
@@ -66,53 +130,56 @@
         #
 
         # Arm® Compiler for Embedded
-        tools := arm-clang
-        tool-name-arm-clang := Arm® Compiler for Embedded `armclang`
+        toolchain-tools := arm-clang
+        toolchain-tool-name-arm-clang := Arm® Compiler for Embedded `armclang`
 
-        tools += arm-link
-        tool-name-arm-link := Arm® Compiler for Embedded `armlink`
+        toolchain-tools += arm-link
+        toolchain-tool-name-arm-link := Arm® Compiler for Embedded `armlink`
 
-        tools += arm-ar
-        tool-name-arm-ar := Arm® Compiler for Embedded `armar`
+        toolchain-tools += arm-ar
+        toolchain-tool-name-arm-ar := Arm® Compiler for Embedded `armar`
 
-        tools += arm-fromelf
-        tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf`
+        toolchain-tools += arm-fromelf
+        toolchain-tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf`
 
         # LLVM Project
-        tools += llvm-clang
-        tool-name-llvm-clang := LLVM Clang (`clang`)
+        toolchain-tools += llvm-clang
+        toolchain-tool-name-llvm-clang := LLVM Clang (`clang`)
 
-        tools += llvm-lld
-        tool-name-llvm-lld := LLVM LLD (`lld`)
+        toolchain-tools += llvm-lld
+        toolchain-tool-name-llvm-lld := LLVM LLD (`lld`)
 
-        tools += llvm-objcopy
-        tool-name-llvm-objcopy := LLVM `llvm-objcopy`
+        toolchain-tools += llvm-objcopy
+        toolchain-tool-name-llvm-objcopy := LLVM `llvm-objcopy`
 
-        tools += llvm-objdump
-        tool-name-llvm-objdump := LLVM `llvm-objdump`
+        toolchain-tools += llvm-objdump
+        toolchain-tool-name-llvm-objdump := LLVM `llvm-objdump`
 
-        tools += llvm-ar
-        tool-name-llvm-ar := LLVM `llvm-ar`
+        toolchain-tools += llvm-ar
+        toolchain-tool-name-llvm-ar := LLVM `llvm-ar`
 
         # GNU Compiler Collection & GNU Binary Utilities
-        tools += gnu-gcc
-        tool-name-gnu-gcc := GNU GCC (`gcc`)
+        toolchain-tools += gnu-gcc
+        toolchain-tool-name-gnu-gcc := GNU GCC (`gcc`)
 
-        tools += gnu-ld
-        tool-name-gnu-ld := GNU LD (`ld.bfd`)
+        toolchain-tools += gnu-ld
+        toolchain-tool-name-gnu-ld := GNU LD (`ld.bfd`)
 
-        tools += gnu-objcopy
-        tool-name-gnu-objcopy := GNU `objcopy`
+        toolchain-tools += gnu-objcopy
+        toolchain-tool-name-gnu-objcopy := GNU `objcopy`
 
-        tools += gnu-objdump
-        tool-name-gnu-objdump := GNU `objdump`
+        toolchain-tools += gnu-objdump
+        toolchain-tool-name-gnu-objdump := GNU `objdump`
 
-        tools += gnu-ar
-        tool-name-gnu-ar := GNU `ar`
+        toolchain-tools += gnu-ar
+        toolchain-tool-name-gnu-ar := GNU `ar`
 
         # Other tools
-        tools += generic-dtc
-        tool-name-generic-dtc := Device Tree Compiler (`dtc`)
+        toolchain-tools += generic-dtc
+        toolchain-tool-name-generic-dtc := Device Tree Compiler (`dtc`)
+
+        toolchain-tools += generic-poetry
+        toolchain-tool-name-generic-poetry := Poetry (`poetry`)
 
         #
         # Assign tools to tool classes.
@@ -120,71 +187,25 @@
         # 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`.
+        # be placed in both `toolchain-tools-cc` and `toolchain-tools-ld`.
         #
 
         # C-related tools
-        tools-cc := arm-clang llvm-clang gnu-gcc # C compilers
-        tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors
+        toolchain-tools-cc := arm-clang llvm-clang gnu-gcc # C compilers
+        toolchain-tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors
 
         # Assembly-related tools
-        tools-as := arm-clang llvm-clang gnu-gcc # Assemblers
+        toolchain-tools-as := arm-clang llvm-clang gnu-gcc # Assemblers
 
         # 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
+        toolchain-tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers
+        toolchain-tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers
+        toolchain-tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers
+        toolchain-tools-ar := arm-ar llvm-ar gnu-ar # Archivers
 
         # Other tools
-        tools-dtc := generic-dtc # Device tree compilers
-
-        define check-tool-class-tools
-                $(eval tool-class := $(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-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))
-
-                $(foreach tool-class,$(tool-classes), \
-                        $(eval $(call check-toolchain-tool-class-default,$(toolchain),$(tool-class))))
-        endef
-
-        $(foreach toolchain,$(toolchains), \
-                $(eval $(call check-toolchain-tool-class-defaults,$(toolchain))))
+        toolchain-tools-dtc := generic-dtc # Device tree compilers
+        toolchain-tools-poetry := generic-poetry # Python Poetry package manager
 
         #
         # Helper functions to identify toolchain tools.
@@ -194,14 +215,15 @@
         # 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)`:
+        # Each tool-guessing function (`toolchain-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>
+        #     $(call toolchain-guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty>
+        #     $(call toolchain-guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty>
         #
-        # The `guess-tool` function tries to find the corresponding tool
+        # The `toolchain-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
@@ -211,41 +233,75 @@
         # 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
+        #     $(call toolchain-guess-tool,gnu-gcc llvm-clang,armclang) # <empty>
+        #     $(call toolchain-guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang
+        #     $(call toolchain-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.
+        # Tools are checked in the order that they are provided, and the first
+        # match is returned.
         #
 
         # 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")
+        toolchain-guess-tool-arm-clang = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armclang")
+        toolchain-guess-tool-arm-link = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: armlink")
+        toolchain-guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: fromelf")
+        toolchain-guess-tool-arm-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armar")
 
         # 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")
+        toolchain-guess-tool-llvm-clang = $(shell $(1) -v 2>&1 <$(nul) | grep -o "clang version")
+        toolchain-guess-tool-llvm-lld = $(shell $(1) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld")
+        toolchain-guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool")
+        toolchain-guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm object file dumper")
+        toolchain-guess-tool-llvm-ar = $(shell $(1) --help 2>&1 <$(nul) | grep -o "LLVM Archiver")
 
         # 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")
+        toolchain-guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 <$(nul) | grep -o "gcc version")
+        toolchain-guess-tool-gnu-ld = $(shell $(1) -v 2>&1 <$(nul) | grep -o "GNU ld")
+        toolchain-guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objcopy")
+        toolchain-guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objdump")
+        toolchain-guess-tool-gnu-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU ar")
 
         # Other tools
-        guess-tool-generic-dtc = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Version: DTC")
+        toolchain-guess-tool-generic-dtc = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Version: DTC")
+        toolchain-guess-tool-generic-poetry = $(shell $(1) --version 2>&1 <$(nul))
 
-        guess-tool = $(firstword $(foreach candidate,$(1), \
-                $(if $(call guess-tool-$(candidate),$(2)),$(candidate))))
+        toolchain-guess-tool = $(if $(2),$(firstword $(foreach candidate,$(1),$\
+                $(if $(call toolchain-guess-tool-$(candidate),$(2)),$(candidate)))))
 
         #
+        # Warn the user that a tool could not be identified.
+        #
+        # Parameters:
+        #
+        # - $1: The toolchain that the tool belongs to.
+        # - $2: The tool class that the tool belongs to.
+        #
+
+        define toolchain-warn-unrecognized
+                $(warning )
+                $(warning The configured $($(1)-name) $(toolchain-tool-class-name-$(2)) could not be identified:)
+                $(warning )
+                $(warning $(space)   $($(1)-$(2))$(if $($(1)-$(2)-parameter), (via `$($(1)-$(2)-parameter)`)))
+                $(warning )
+                $(warning The following tools were tried, but either did not exist or could not be identified:)
+                $(warning )
+
+                $(foreach default,$($(1)-$(2)-default), \
+                        $(warning $(space) - $(default)))
+
+                $(warning )
+                $(warning The following tools are supported:)
+                $(warning )
+
+                $(foreach tool,$(toolchain-tools-$(2)), \
+                        $(warning $(space) - $(toolchain-tool-name-$(tool))))
+
+                $(warning )
+                $(warning The build system will treat this $(toolchain-tool-class-name-$(2)) as $(toolchain-tool-name-$($(1)-$(2)-default-id)).)
+                $(warning )
+        endef
+
+        #
         # Locate and identify tools belonging to each toolchain.
         #
         # Each tool class in each toolchain receives a variable of the form
@@ -258,89 +314,123 @@
         #
         # 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.
+        # for its location.
         #
-        # 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.
+        # If the C compiler cannot provide the location (or the tool class *is*
+        # the C compiler), then it is assigned a default value specific for that
+        # toolchain.
         #
 
-        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`
+        toolchain-derive-arm-clang-cpp = $(1)
+        toolchain-derive-arm-clang-as = $(1)
+        toolchain-derive-arm-clang-ld = # Fall back to `$(toolchain)-ld-default`
+        toolchain-derive-arm-clang-oc = # Fall back to `$(toolchain)-oc-default`
+        toolchain-derive-arm-clang-od = # Fall back to `$(toolchain)-od-default`
+        toolchain-derive-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))
+        toolchain-derive-llvm-clang-cpp = $(1)
+        toolchain-derive-llvm-clang-as = $(1)
+        toolchain-derive-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul))
+        toolchain-derive-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul))
+        toolchain-derive-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul))
+        toolchain-derive-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul))
 
-        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)))))
+        toolchain-derive-gnu-gcc-cpp = $(1)
+        toolchain-derive-gnu-gcc-as = $(1)
+        toolchain-derive-gnu-gcc-ld = $(1)
+        toolchain-derive-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul))
+        toolchain-derive-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul))
+        toolchain-derive-gnu-gcc-ar = $(shell $(1) --print-prog-name ar 2>$(nul))
 
-        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 )
+        toolchain-derive = $(if $3,$(call toolchain-derive-$1-$2,$3))
+
+        #
+        # Configure a toolchain.
+        #
+        # Parameters:
+        #
+        #   - $1: The toolchain to configure.
+        #
+        # This function iterates over all tool classes and configures them for
+        # the provided toolchain. Toolchain tools are initialized lazily and
+        # on-demand based on the first read of the tool path or identifier
+        # variables.
+        #
 
-                $$(foreach tool,$$(tools-$(2)), \
-                        $$(warning $$(space) - $$(tool-name-$$(tool))))
+        define toolchain-configure
+                $$(foreach tool-class,$$(toolchain-tool-classes), \
+                        $$(eval $$(call toolchain-configure-tool,$1,$$(tool-class))))
+        endef
 
-                $$(warning )
-                $$(warning The build system will treat this $$(tool-class-name-$(2)) as $$(tool-name-$$($(1)-$(2)-id-default)).)
-                $$(warning )
+        #
+        # Configure a specific tool within a toolchain.
+        #
+        # Parameters:
+        #
+        #   - $1: The toolchain to configure.
+        #   - $2: The tool class to configure.
+        #
+
+        define toolchain-configure-tool
+                $1-$2-configure = $\
+                        $$(eval $$(call toolchain-determine-tool,$1,$2))
+
+                #
+                # When either of the following variables are read for the first
+                # time, the appropriate tool is determined and *both* variables
+                # are overwritten with their final values.
+                #
+
+                $1-$2 = $$($1-$2-configure)$$($1-$2)
+                $1-$2-id = $$($1-$2-configure)$$($1-$2-id)
         endef
 
-        define toolchain-determine-tool
-                $(1)-$(2)-guess = $$(if $$(filter-out cc,$(2)),$\
-                        $$(call guess-$$($(1)-cc-id)-$(2),$$($(1)-cc)))
+        #
+        # Determines and identifies a tool.
+        #
+        # Parameters:
+        #
+        #   - $1: The toolchain identifier.
+        #   - $2: The tool class.
+        #
+        # Tool identification happens by reading the designated tool parameter
+        # to get the user-specified command for the tool (e.g. `CC` or `LD`). If
+        # no tool parameter is defined then try to derive the tool from the C
+        # compiler.
+        #
+        # If all else fails, fall back to the default command defined by the
+        # toolchain makefile.
+        #
 
-                $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-guess))
-                $(1)-$(2) := $$(or $$($(1)-$(2)),$$($(1)-$(2)-default))
+        define toolchain-determine-tool
+                toolchain-$1-$2-derive-from-cc = $$(if $$(filter-out cc,$2),$\
+                        $$(call toolchain-derive,$$($1-cc-id),$2,$$($1-cc)))
 
-                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.
+                toolchain-$1-$2-shell = $\
+                        $$(if $$(call defined,$$($1-$2-parameter)),$\
+                                $$($$($1-$2-parameter)),$\
+                                $$(or $$(toolchain-$1-$2-derive-from-cc),$\
+                                        $$(toolchain-$1-$2-default)))
 
-                        $(1)-$(2) := $$(call escape-shell,$$($(1)-$(2)))
-                endif
+                toolchain-$1-$2-default = $$(firstword $\
+                        $$(foreach default,$$($1-$2-default),$\
+                                $$(if $$(call which,$$(default)),$$(default))) $\
+                        $$($1-$2-default))
 
-                $(1)-$(2)-id := $$(call guess-tool,$$(tools-$(2)),$$($(1)-$(2)))
+                $1-$2 := $$(if $$(call which,$$(toolchain-$1-$2-shell)),$\
+                        $$(call escape-shell,$$(toolchain-$1-$2-shell)),$\
+                        $$(toolchain-$1-$2-shell))
 
-                ifndef $(1)-$(2)-id
-                        $(1)-$(2)-id := $$($(1)-$(2)-id-default)
+                $1-$2-id := $$(if $$($1-$2),$$(or $\
+                        $$(call toolchain-guess-tool,$$\
+                                $$(toolchain-tools-$2),$$($1-$2)),$\
+                        $$($1-$2-default-id)))
 
-                        $$(eval $$(call toolchain-warn-unrecognized,$(1),$(2)))
+                ifeq ($$(or $$($1-$2-id),$$(call bool,$$($1-$2-optional))),)
+                        $$(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))))
+                $(eval $(call toolchain-configure,$(toolchain))))
 endif
diff --git a/make_helpers/toolchains/aarch32.mk b/make_helpers/toolchains/aarch32.mk
index ff00a53..4063ed9 100644
--- a/make_helpers/toolchains/aarch32.mk
+++ b/make_helpers/toolchains/aarch32.mk
@@ -6,34 +6,34 @@
 
 aarch32-name := AArch32
 
-aarch32-cc := $(if $(filter-out default,$(origin CC)),$(CC))
+aarch32-cc-parameter := CC
+aarch32-cc-default-id := gnu-gcc
 aarch32-cc-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
-aarch32-cc-id-default := gnu-gcc
 
-aarch32-cpp := $(if $(filter-out default,$(origin CPP)),$(CPP))
+aarch32-cpp-parameter := CPP
+aarch32-cpp-default-id := gnu-gcc
 aarch32-cpp-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
-aarch32-cpp-id-default := gnu-gcc
 
-aarch32-as := $(if $(filter-out default,$(origin AS)),$(AS))
+aarch32-as-parameter := AS
+aarch32-as-default-id := gnu-gcc
 aarch32-as-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
-aarch32-as-id-default := gnu-gcc
 
-aarch32-ld := $(if $(filter-out default,$(origin LD)),$(LD))
+aarch32-ld-parameter := LD
+aarch32-ld-default-id := gnu-gcc
 aarch32-ld-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
-aarch32-ld-id-default := gnu-gcc
 
-aarch32-oc := $(if $(filter-out default,$(origin OC)),$(OC))
+aarch32-oc-parameter := OC
+aarch32-oc-default-id := gnu-objcopy
 aarch32-oc-default := $(or $(CROSS_COMPILE),arm-none-eabi-)objcopy
-aarch32-oc-id-default := gnu-objcopy
 
-aarch32-od := $(if $(filter-out default,$(origin OD)),$(OD))
+aarch32-od-parameter := OD
+aarch32-od-default-id := gnu-objdump
 aarch32-od-default := $(or $(CROSS_COMPILE),arm-none-eabi-)objdump
-aarch32-od-id-default := gnu-objdump
 
-aarch32-ar := $(if $(filter-out default,$(origin AR)),$(AR))
+aarch32-ar-parameter := AR
+aarch32-ar-default-id := gnu-ar
 aarch32-ar-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc-ar
-aarch32-ar-id-default := gnu-ar
 
-aarch32-dtc := $(if $(filter-out default,$(origin DTC)),$(DTC))
+aarch32-dtc-parameter := DTC
+aarch32-dtc-default-id := generic-dtc
 aarch32-dtc-default := dtc
-aarch32-dtc-id-default := generic-dtc
diff --git a/make_helpers/toolchains/aarch64.mk b/make_helpers/toolchains/aarch64.mk
index 407f068..476fbf3 100644
--- a/make_helpers/toolchains/aarch64.mk
+++ b/make_helpers/toolchains/aarch64.mk
@@ -6,34 +6,41 @@
 
 aarch64-name := AArch64
 
-aarch64-cc := $(if $(filter-out default,$(origin CC)),$(CC))
+aarch64-cc-parameter := CC
+aarch64-cc-default-id := gnu-gcc
 aarch64-cc-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
-aarch64-cc-id-default := gnu-gcc
+aarch64-cc-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc)
 
-aarch64-cpp := $(if $(filter-out default,$(origin CPP)),$(CPP))
+aarch64-cpp-parameter := CPP
+aarch64-cpp-default-id := gnu-gcc
 aarch64-cpp-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
-aarch64-cpp-id-default := gnu-gcc
+aarch64-cpp-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc)
 
-aarch64-as := $(if $(filter-out default,$(origin AS)),$(AS))
+aarch64-as-parameter := AS
+aarch64-as-default-id := gnu-gcc
 aarch64-as-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
-aarch64-as-id-default := gnu-gcc
+aarch64-as-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc)
 
-aarch64-ld := $(if $(filter-out default,$(origin LD)),$(LD))
+aarch64-ld-parameter := LD
+aarch64-ld-default-id := gnu-gcc
 aarch64-ld-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
-aarch64-ld-id-default := gnu-gcc
+aarch64-ld-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc)
 
-aarch64-oc := $(if $(filter-out default,$(origin OC)),$(OC))
+aarch64-oc-parameter := OC
+aarch64-oc-default-id := gnu-objcopy
 aarch64-oc-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)objcopy
-aarch64-oc-id-default := gnu-objcopy
+aarch64-oc-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-objcopy)
 
-aarch64-od := $(if $(filter-out default,$(origin OD)),$(OD))
+aarch64-od-parameter := OD
+aarch64-od-default-id := gnu-objdump
 aarch64-od-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)objdump
-aarch64-od-id-default := gnu-objdump
+aarch64-od-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-objdump)
 
-aarch64-ar := $(if $(filter-out default,$(origin AR)),$(AR))
+aarch64-ar-parameter := AR
+aarch64-ar-default-id := gnu-ar
 aarch64-ar-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc-ar
-aarch64-ar-id-default := gnu-ar
+aarch64-ar-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc-ar)
 
-aarch64-dtc := $(if $(filter-out default,$(origin DTC)),$(DTC))
+aarch64-dtc-parameter := DTC
+aarch64-dtc-default-id := generic-dtc
 aarch64-dtc-default := dtc
-aarch64-dtc-id-default := generic-dtc
diff --git a/make_helpers/toolchains/host.mk b/make_helpers/toolchains/host.mk
index 733c289..dc538c6 100644
--- a/make_helpers/toolchains/host.mk
+++ b/make_helpers/toolchains/host.mk
@@ -6,34 +6,39 @@
 
 host-name := host
 
-host-cc := $(HOSTCC)
+host-cc-parameter := HOSTCC
+host-cc-default-id := gnu-gcc
 host-cc-default := gcc
-host-cc-id-default := gnu-gcc
 
-host-cpp := $(HOSTCPP)
+host-cpp-parameter := HOSTCPP
+host-cpp-default-id := gnu-gcc
 host-cpp-default := gcc
-host-cpp-id-default := gnu-gcc
 
-host-as := $(HOSTAS)
+host-as-parameter := HOSTAS
+host-as-default-id := gnu-gcc
 host-as-default := gcc
-host-as-id-default := gnu-gcc
 
-host-ld := $(HOSTLD)
+host-ld-parameter := HOSTLD
+host-ld-default-id := gnu-gcc
 host-ld-default := gcc
-host-ld-id-default := gnu-gcc
 
-host-oc := $(HOSTOC)
+host-oc-parameter := HOSTOC
+host-oc-default-id := gnu-objcopy
 host-oc-default := objcopy
-host-oc-id-default := gnu-objcopy
 
-host-od := $(HOSTOD)
+host-od-parameter := HOSTOD
+host-od-default-id := gnu-objdump
 host-od-default := objdump
-host-od-id-default := gnu-objdump
 
-host-ar := $(HOSTAR)
+host-ar-parameter := HOSTAR
+host-ar-default-id := gnu-ar
 host-ar-default := gcc-ar
-host-ar-id-default := gnu-ar
 
-host-dtc := $(HOSTDTC)
+host-dtc-parameter := HOSTDTC
+host-dtc-default-id := generic-dtc
 host-dtc-default := dtc
-host-dtc-id-default := generic-dtc
+
+host-poetry-parameter := POETRY
+host-poetry-optional := yes
+host-poetry-default-id := generic-poetry
+host-poetry-default := poetry
diff --git a/make_helpers/toolchains/rk3399-m0.mk b/make_helpers/toolchains/rk3399-m0.mk
index 92309f1..3a7f173 100644
--- a/make_helpers/toolchains/rk3399-m0.mk
+++ b/make_helpers/toolchains/rk3399-m0.mk
@@ -6,26 +6,26 @@
 
 rk3399-m0-name := RK3399 M0
 
+rk3399-m0-cc-default-id := gnu-gcc
 rk3399-m0-cc-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
-rk3399-m0-cc-id-default := gnu-gcc
 
+rk3399-m0-cpp-default-id := gnu-gcc
 rk3399-m0-cpp-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
-rk3399-m0-cpp-id-default := gnu-gcc
 
+rk3399-m0-as-default-id := gnu-gcc
 rk3399-m0-as-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
-rk3399-m0-as-id-default := gnu-gcc
 
+rk3399-m0-ld-default-id := gnu-gcc
 rk3399-m0-ld-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
-rk3399-m0-ld-id-default := gnu-gcc
 
+rk3399-m0-oc-default-id := gnu-objcopy
 rk3399-m0-oc-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)objcopy
-rk3399-m0-oc-id-default := gnu-objcopy
 
+rk3399-m0-od-default-id := gnu-objdump
 rk3399-m0-od-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)objdump
-rk3399-m0-od-id-default := gnu-objdump
 
+rk3399-m0-ar-default-id := gnu-ar
 rk3399-m0-ar-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc-ar
-rk3399-m0-ar-id-default := gnu-ar
 
+rk3399-m0-dtc-default-id := generic-dtc
 rk3399-m0-dtc-default := dtc
-rk3399-m0-dtc-id-default := generic-dtc
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
index 4fd819a..fa7722a 100644
--- a/make_helpers/unix.mk
+++ b/make_helpers/unix.mk
@@ -38,18 +38,6 @@
 	-$(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
-    endef
-
     define SHELL_REMOVE_DIR
 	-$(q)rm -rf  "${1}"
     endef
diff --git a/make_helpers/utilities.mk b/make_helpers/utilities.mk
index 45ef12e..efa0ab9 100644
--- a/make_helpers/utilities.mk
+++ b/make_helpers/utilities.mk
@@ -100,3 +100,23 @@
 #
 
 bool-01 = $(if $(call bool,$(1)),1,0)
+
+#
+# Determine whether a variable is defined or not.
+#
+# Parameters:
+#
+#   - $(1): The variable to check.
+#
+# Example usage:
+#
+#     xyz-defined := $(call defined,xyz) # <empty>
+#
+#     xyz :=
+#     xyz-defined := $(call defined,xyz) # <non-empty>
+#
+#     xyz := hello
+#     xyz-defined := $(call defined,xyz) # <non-empty>
+#
+
+defined = $(call bool,$(filter-out undefined,$(origin $(1))))
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
index 2f5d51b..c24aa08 100644
--- a/make_helpers/windows.mk
+++ b/make_helpers/windows.mk
@@ -47,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 a6bb905..26caae4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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/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_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;
 }
 
-int sunxi_pmic_setup(uint16_t socid, const void *fdt)
+static int pmic_bus_init(uint16_t socid, uint16_t rsb_hw_addr)
 {
 	int ret;
 
-	INFO("PMIC: Probing AXP305 on RSB\n");
-
-	ret = sunxi_init_platform_r_twi(socid, true);
+	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 node, parent, ret;
+	uint32_t reg;
+
+	node = fdt_node_offset_by_compatible(fdt, 0, "x-powers,axp806");
+	if (node >= 0) {
+		pmic = AXP305;
+	}
+
+	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;
+	}
+
-	ret = rsb_init();
+	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 RSB: %d\n", ret);
 		return ret;
 	}
 
-	pmic = AXP305;
-	axp_setup_regulators(fdt);
+	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;
+	}
 
-	/* Switch the PMIC back to I2C mode. */
-	ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C);
-	if (ret)
-		return ret;
+	if (is_using_rsb()) {
+		/* Switch the PMIC back to I2C mode. */
+		return rsb_write(rsb_rt_addr, AXP20X_MODE_REG, AXP20X_MODE_I2C);
+	}
+
+	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/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
index e878863..6c8cf5a 100644
--- a/plat/amd/versal2/bl31_setup.c
+++ b/plat/amd/versal2/bl31_setup.c
@@ -20,6 +20,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <plat_arm.h>
+#include <plat_console.h>
 #include <scmi.h>
 
 #include <def.h>
@@ -74,8 +75,11 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
+	(void)arg0;
+	(void)arg1;
+	(void)arg2;
+	(void)arg3;
 	uint32_t uart_clock;
-	int32_t rc;
 
 	board_detection();
 
@@ -121,30 +125,7 @@
 
 	uart_clock = get_uart_clk();
 
-	if (CONSOLE_IS(pl011_0) || CONSOLE_IS(pl011_1)) {
-		static console_t _runtime_console;
-
-		/* Initialize the console to provide early debug support */
-		rc = console_pl011_register(UART_BASE, uart_clock,
-					    UART_BAUDRATE,
-					    &_runtime_console);
-		if (rc == 0) {
-			panic();
-		}
-
-		console_set_scope(&_runtime_console, CONSOLE_FLAG_BOOT |
-				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	} else if (CONSOLE_IS(dcc)) {
-		/* Initialize the dcc console for debug.
-		 * dcc is over jtag and does not configures uart0 or uart1.
-		 */
-		rc = console_dcc_register();
-		if (rc == 0) {
-			panic();
-		}
-	} else {
-		/* Making MISRA C 2012 15.7 compliant */
-	}
+	setup_console();
 
 	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
 	       platform_version / 10U, platform_version % 10U);
@@ -206,6 +187,7 @@
 static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
 					  void *handle, void *cookie)
 {
+	(void)id;
 	uint32_t intr_id;
 	uint32_t i;
 	interrupt_type_handler_t handler = NULL;
@@ -249,6 +231,8 @@
 	if (rc != 0) {
 		panic();
 	}
+
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h
index a8cbaaf..f3a7907 100644
--- a/plat/amd/versal2/include/def.h
+++ b/plat/amd/versal2/include/def.h
@@ -15,12 +15,23 @@
 #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 VERSAL2_CONSOLE_ID_none		0
+#define VERSAL2_CONSOLE_ID_pl011	1
+#define VERSAL2_CONSOLE_ID_pl011_0       1
+#define VERSAL2_CONSOLE_ID_pl011_1       2
+#define VERSAL2_CONSOLE_ID_dcc           3
+#define VERSAL2_CONSOLE_ID_dtb           4
 
-#define CONSOLE_IS(con)	(CONSOLE_ID_ ## con == CONSOLE)
+#define CONSOLE_IS(con) (VERSAL2_CONSOLE_ID_ ## con == VERSAL2_CONSOLE)
+
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011   1
+#define RT_CONSOLE_ID_pl011_0   1
+#define RT_CONSOLE_ID_pl011_1   2
+#define RT_CONSOLE_ID_dcc       3
+#define RT_CONSOLE_ID_dtb       4
+
+#define RT_CONSOLE_IS(con)      (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
 
 /* List all platforms */
 #define SILICON		U(0)
@@ -125,6 +136,10 @@
 #define APU_CLUSTER_STEP	U(0x100000)
 
 #define SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL	U(0xF1060504)
+#define PMXC_IOU_SLCR_SRAM_CSR	U(0xF106104C)
+#define PMXC_IOU_SLCR_PHY_RESET	U(0xF1061050)
+#define PMXC_IOU_SLCR_TX_RX_CONFIG_RDY	U(0xF1061054)
+#define PMXC_CRP_RST_UFS	U(0xF1260340)
 
 /*******************************************************************************
  * IRQ constants
@@ -139,11 +154,35 @@
 
 #define UART_BAUDRATE	115200
 
-#if CONSOLE_IS(pl011_1)
-#define UART_BASE		UART1_BASE
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
+#define UART_BASE	    UART0_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(pl011_1)
+#define UART_BASE           UART1_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
+#else
+# error "invalid VERSAL2_CONSOLE"
+#endif
+
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE UART0_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE UART1_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
 #else
-/* Default console is UART0 */
-#define UART_BASE            UART0_BASE
+# error "invalid CONSOLE_RUNTIME"
+#endif
 #endif
 
 #endif /* DEF_H */
diff --git a/plat/amd/versal2/include/versal2-scmi.h b/plat/amd/versal2/include/versal2-scmi.h
index 4d581e4..c08b4b1 100644
--- a/plat/amd/versal2/include/versal2-scmi.h
+++ b/plat/amd/versal2/include/versal2-scmi.h
@@ -136,5 +136,9 @@
 #define RESET_I3C6_0	32
 #define RESET_I3C7_0	33
 #define RESET_I3C8_0	34
+#define RESET_UFSPHY_0  35
+
+#define PD_USB0		0
+#define PD_USB1		1
 
 #endif /* _VERSAL2_SCMI_H */
diff --git a/plat/amd/versal2/plat_psci.c b/plat/amd/versal2/plat_psci.c
index 4faa434..a55042d 100644
--- a/plat/amd/versal2/plat_psci.c
+++ b/plat/amd/versal2/plat_psci.c
@@ -161,12 +161,31 @@
 static int32_t no_pm_ioctl(uint32_t device_id, uint32_t ioctl_id,
 			   uint32_t arg1, uint32_t arg2)
 {
+	int32_t ret = 0;
 	VERBOSE("%s: ioctl_id: %x, arg1: %x\n", __func__, ioctl_id, arg1);
-	if (ioctl_id == IOCTL_OSPI_MUX_SELECT) {
+
+	switch (ioctl_id) {
+	case IOCTL_OSPI_MUX_SELECT:
 		mmio_write_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, arg1);
-		return 0;
+		break;
+	case IOCTL_UFS_TXRX_CFGRDY_GET:
+		ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_TX_RX_CONFIG_RDY);
+		break;
+	case IOCTL_UFS_SRAM_CSR_SEL:
+		if (arg1 == 1) {
+			ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_SRAM_CSR);
+		} else if (arg1 == 0) {
+			mmio_write_32(PMXC_IOU_SLCR_SRAM_CSR, arg2);
+		}
+		break;
+	case IOCTL_USB_SET_STATE:
+		break;
+	default:
+		ret = PM_RET_ERROR_NOFEATURE;
+		break;
 	}
-	return PM_RET_ERROR_NOFEATURE;
+
+	return ret;
 }
 
 static uint64_t no_pm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
@@ -187,7 +206,13 @@
 	case PM_IOCTL:
 	{
 		ret = no_pm_ioctl(arg[0], arg[1], arg[2], arg[3]);
-		SMC_RET1(handle, (uint64_t)ret);
+		/* Firmware driver expects return code in upper 32 bits and
+		 * status in lower 32 bits.
+		 * status is always SUCCESS(0) for mmio low level register
+		 * r/w calls and return value is the value returned from
+		 * no_pm_ioctl
+		 */
+		SMC_RET1(handle, ((uint64_t)ret << 32));
 	}
 	case PM_GET_CHIPID:
 	{
diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk
index c07fc36..e2112e0 100644
--- a/plat/amd/versal2/platform.mk
+++ b/plat/amd/versal2/platform.mk
@@ -32,7 +32,7 @@
     $(eval $(call add_define,MEM_BASE))
 
     ifndef MEM_SIZE
-        $(error "ATF_BASE defined without ATF_SIZE")
+        $(error "MEM_BASE defined without MEM_SIZE")
     endif
     $(eval $(call add_define,MEM_SIZE))
 
@@ -45,7 +45,7 @@
     $(eval $(call add_define,BL32_MEM_BASE))
 
     ifndef BL32_MEM_SIZE
-        $(error "BL32_BASE defined without BL32_SIZE")
+        $(error "BL32_MEM_BASE defined without BL32_MEM_SIZE")
     endif
     $(eval $(call add_define,BL32_MEM_SIZE))
 endif
@@ -57,13 +57,28 @@
 USE_COHERENT_MEM := 0
 HW_ASSISTED_COHERENCY := 1
 
-CONSOLE	?=	pl011
-ifeq (${CONSOLE}, $(filter ${CONSOLE},pl011 pl011_0 pl011_1 dcc))
+VERSAL2_CONSOLE  ?=      pl011
+ifeq (${VERSAL2_CONSOLE}, $(filter ${VERSAL2_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
+	else
+	  $(error "Please define VERSAL2_CONSOLE")
+  endif
+
+$(eval $(call add_define_val,VERSAL2_CONSOLE,VERSAL2_CONSOLE_ID_${VERSAL2_CONSOLE}))
+
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq 	(${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
 else
-  $(error Please define CONSOLE)
+	$(error "Please define CONSOLE_RUNTIME")
+endif
 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))
@@ -109,6 +124,9 @@
 BL31_SOURCES		+=	${PLAT_PATH}/plat_psci.c
 
 BL31_SOURCES		+=	plat/xilinx/common/plat_fdt.c			\
+				common/fdt_wrappers.c                           \
+				plat/xilinx/common/plat_fdt.c                   \
+				plat/xilinx/common/plat_console.c               \
 				plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/common/ipi.c			\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c	\
@@ -116,6 +134,7 @@
 				plat/xilinx/common/versal.c			\
 				${PLAT_PATH}/bl31_setup.c			\
 				common/fdt_fixup.c				\
+				common/fdt_wrappers.c				\
 				${LIBFDT_SRCS}					\
 				${PLAT_PATH}/sip_svc_setup.c			\
 				${PLAT_PATH}/gicv3.c
diff --git a/plat/amd/versal2/scmi.c b/plat/amd/versal2/scmi.c
index c3c517a..59aff08 100644
--- a/plat/amd/versal2/scmi.c
+++ b/plat/amd/versal2/scmi.c
@@ -10,6 +10,7 @@
 
 #include <drivers/scmi-msg.h>
 #include <drivers/scmi.h>
+#include <lib/mmio.h>
 #include <lib/utils_def.h>
 #include <platform_def.h>
 #include <scmi.h>
@@ -50,8 +51,8 @@
 	CLOCK_CELL(CLK_SERIAL1_0, CLK_SERIAL1_0, "uart1_uartclk", true, 100000000),
 	CLOCK_CELL(CLK_SERIAL1_1, CLK_SERIAL1_1, "uart1_apb_pclk", true, 100000000),
 	CLOCK_CELL(CLK_UFS0_0, CLK_UFS0_0, "ufs_core_clk", true, 100000000),
-	CLOCK_CELL(CLK_UFS0_1, CLK_UFS0_1, "ufs_phy_clk", true, 100000000),
-	CLOCK_CELL(CLK_UFS0_2, CLK_UFS0_2, "ufs_ref_pclk", true, 100000000),
+	CLOCK_CELL(CLK_UFS0_1, CLK_UFS0_1, "ufs_phy_clk", true, 26000000),
+	CLOCK_CELL(CLK_UFS0_2, CLK_UFS0_2, "ufs_ref_pclk", true, 26000000),
 	CLOCK_CELL(CLK_USB0_0, CLK_USB0_0, "usb0_bus_clk", true, 100000000),
 	CLOCK_CELL(CLK_USB0_1, CLK_USB0_1, "usb0_ref_clk", true, 100000000),
 	CLOCK_CELL(CLK_USB0_2, CLK_USB0_2, "usb0_dwc_clk", true, 100000000),
@@ -179,14 +180,40 @@
 	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"),
+	RESET_CELL(RESET_UFSPHY_0, RESET_UFSPHY_0, "ufsphy0"),
 };
 
+/**
+ * struct scmi_pd - Data for the exposed power domain controller
+ * @pd_id: pd identifier in RCC reset driver
+ * @name: pd string ID exposed to agent
+ * @state: keep state setting
+ */
+struct scmi_pd {
+	unsigned long pd_id;
+	const char *name;
+	unsigned int state;
+};
+
+#define PD_CELL(_scmi_id, _id, _name, _state) \
+	[_scmi_id] = { \
+		.pd_id = _id, \
+		.name = _name, \
+		.state = _state, \
+	}
+
+static struct scmi_pd scmi0_pd[] = {
+	PD_CELL(PD_USB0, PD_USB0, "usb0", 0),
+	PD_CELL(PD_USB1, PD_USB1, "usb1", 0),
+};
+
 struct scmi_resources {
 	struct scmi_clk *clock;
 	size_t clock_count;
 	struct scmi_reset *reset;
 	size_t reset_count;
-
+	struct scmi_pd *pd;
+	size_t pd_count;
 };
 
 static const struct scmi_resources resources[] = {
@@ -195,6 +222,8 @@
 		.clock_count = ARRAY_SIZE(scmi0_clock),
 		.reset = scmi0_reset,
 		.reset_count = ARRAY_SIZE(scmi0_reset),
+		.pd = scmi0_pd,
+		.pd_count = ARRAY_SIZE(scmi0_pd),
 	},
 };
 
@@ -433,14 +462,122 @@
 	if (assert_not_deassert) {
 		NOTICE("SCMI reset %lu/%s set\n",
 		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+
+		switch (scmi_id) {
+		case RESET_UFS0_0:
+			mmio_write_32(PMXC_CRP_RST_UFS, 1);
+			break;
+		case RESET_UFSPHY_0:
+			mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 1);
+			break;
+		default:
+			break;
+		}
 	} else {
 		NOTICE("SCMI reset %lu/%s release\n",
 		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+
+		switch (scmi_id) {
+		case RESET_UFS0_0:
+			mmio_write_32(PMXC_CRP_RST_UFS, 0);
+			break;
+		case RESET_UFSPHY_0:
+			mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 0);
+			break;
+		default:
+			break;
+		}
 	}
 
 	return SCMI_SUCCESS;
 }
 
+/*
+ * Platform SCMI reset domains
+ */
+static struct scmi_pd *find_pd(unsigned int agent_id, unsigned int pd_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t n;
+
+	if (resource != NULL) {
+		for (n = 0U; n < resource->pd_count; n++) {
+			if (n == pd_id) {
+				return &resource->pd[n];
+			}
+		}
+	}
+
+	return NULL;
+}
+
+size_t plat_scmi_pd_count(unsigned int agent_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t ret;
+
+	if (resource == NULL) {
+		ret = 0U;
+	} else {
+		ret = resource->pd_count;
+
+		NOTICE("SCMI: PD: %d\n", (unsigned int)ret);
+	}
+	return ret;
+}
+
+const char *plat_scmi_pd_get_name(unsigned int agent_id, unsigned int pd_id)
+{
+	const struct scmi_pd *pd = find_pd(agent_id, pd_id);
+
+	if (pd == NULL) {
+		return NULL;
+	}
+
+	return pd->name;
+}
+
+unsigned int plat_scmi_pd_statistics(unsigned int agent_id, unsigned long *pd_id)
+{
+	return 0U;
+}
+
+unsigned int plat_scmi_pd_get_attributes(unsigned int agent_id, unsigned int pd_id)
+{
+	return 0U;
+}
+
+unsigned int plat_scmi_pd_get_state(unsigned int agent_id, unsigned int pd_id)
+{
+	const struct scmi_pd *pd = find_pd(agent_id, pd_id);
+
+	if (pd == NULL) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	NOTICE("SCMI: PD: get id: %d, state: %x\n", pd_id, pd->state);
+
+	return pd->state;
+}
+
+int32_t plat_scmi_pd_set_state(unsigned int agent_id, unsigned int flags, unsigned int pd_id,
+			       unsigned int state)
+{
+	struct scmi_pd *pd = find_pd(agent_id, pd_id);
+
+	if (pd == NULL) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	NOTICE("SCMI: PD: set id: %d, orig state: %x, new state: %x,  flags: %x\n",
+	       pd_id, pd->state, state, flags);
+
+	pd->state = state;
+
+	return 0U;
+}
+
+
 /* Currently only one channel is supported. Expectation is that channel 0 is used by NS SW */
 static struct scmi_msg_channel scmi_channel[] = {
 	[0] = {
@@ -475,10 +612,8 @@
 	SCMI_PROTOCOL_ID_BASE,
 	SCMI_PROTOCOL_ID_CLOCK,
 	SCMI_PROTOCOL_ID_RESET_DOMAIN,
-	/*
-	 *SCMI_PROTOCOL_ID_POWER_DOMAIN,
-	 *SCMI_PROTOCOL_ID_SENSOR,
-	 */
+	SCMI_PROTOCOL_ID_POWER_DOMAIN,
+	/* SCMI_PROTOCOL_ID_SENSOR, */
 	0U /* Null termination */
 };
 
@@ -514,6 +649,11 @@
 			/* Keep i2c on 100MHz to calculate rates properly */
 			if (i >= CLK_I2C0_0 && i <= CLK_I2C7_0)
 				continue;
+
+			/* Keep UFS clocks to default values to get the expected rates */
+			if (i >= CLK_UFS0_0 && i <= CLK_UFS0_2)
+				continue;
+
 			/*
 			 * SPP supports multiple versions.
 			 * The cpu_clock value is set to corresponding SPP
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
new file mode 100644
index 0000000..53cd3b0
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, Arm Limited. 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";
+
+		hw-config {
+			load-address = <0x0 0x83000000>;
+			max-size = <0x8000>;
+			id = <HW_CONFIG_ID>;
+		};
+	};
+};
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/include/plat_macros.S b/plat/arm/board/automotive_rd/platform/rd1ae/include/plat_macros.S
new file mode 100644
index 0000000..8efe8ac
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/include/plat_macros.S
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <arm_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ *
+ * There are currently no platform specific regs
+ * to print.
+ * ---------------------------------------------
+ */
+	.macro plat_crash_print_regs
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h b/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
new file mode 100644
index 0000000..44c8ee3
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+/* These are referenced by arm_def.h #included next, so #define first. */
+#define PLAT_ARM_TRUSTED_SRAM_BASE		UL(0x0)
+
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/common/common_def.h>
+
+#define PLATFORM_CORE_COUNT			U(16)
+#define PLAT_ARM_CLUSTER_COUNT			U(16)
+#define PLAT_MAX_CPUS_PER_CLUSTER		U(1)
+#define PLAT_MAX_PE_PER_CPU			U(1)
+
+#define PLATFORM_STACK_SIZE			UL(0x1000)
+
+/* BL1 is not supported */
+#define PLAT_ARM_TRUSTED_ROM_BASE		UL(0x0)
+#define PLAT_ARM_TRUSTED_ROM_SIZE		UL(0x0)
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE		UL(0x00080000)
+
+/* USE_ROMLIB is not supported */
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE		U(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE		U(0)
+
+/* Defined based on actual binary sizes */
+#define PLAT_ARM_MAX_BL1_RW_SIZE		0x0
+#define PLAT_ARM_MAX_BL2_SIZE			0x20000
+#define PLAT_ARM_MAX_BL31_SIZE			0x70000
+
+#define PLAT_ARM_DRAM2_BASE			ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE			ULL(0x180000000)
+
+#define PLAT_CSS_MHU_BASE			UL(0x2A920000)
+#define PLAT_ARM_NSTIMER_FRAME_ID		U(0)
+
+#define SOC_CSS_SEC_UART_BASE			UL(0x2A410000)
+#define SOC_CSS_NSEC_UART_BASE			UL(0x2A400000)
+#define SOC_CSS_UART_SIZE			UL(0x10000)
+#define SOC_CSS_UART_CLK_IN_HZ			UL(7372800)
+#define PLAT_ARM_BOOT_UART_BASE			SOC_CSS_SEC_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
+#define PLAT_ARM_RUN_UART_BASE			SOC_CSS_SEC_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
+#define PLAT_ARM_CRASH_UART_BASE		SOC_CSS_SEC_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
+
+/* Physical and virtual address space limits for MMU */
+#define PLAT_PHY_ADDR_SPACE_SIZE		(1ULL << 42)
+#define PLAT_VIRT_ADDR_SPACE_SIZE		(1ULL << 42)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE			UL(0x30000000)
+#define PLAT_ARM_GICR_BASE			UL(0x301C0000)
+#define PLAT_ARM_GICC_BASE			UL(0x2C000000)
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)		CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)		ARM_G0_IRQ_PROPS(grp)
+
+/* Virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME		UL(0xC0000000)
+
+/* Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_BASE			UL(0x2A480000)
+#define SBSA_SECURE_WDOG_TIMEOUT		UL(100)
+
+#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 V2M_SYSREGS_BASE			UL(0x0C010000)
+#define V2M_SYS_LED				U(0x8)
+
+#define PLAT_ARM_SCMI_CHANNEL_COUNT		U(1)
+#define CSS_SYSTEM_PWR_DMN_LVL			ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL				ARM_PWR_LVL1
+
+#define MAX_IO_DEVICES				U(3)
+#define MAX_IO_HANDLES				U(4)
+
+#ifdef IMAGE_BL2
+#define PLAT_ARM_MMAP_ENTRIES			U(5)
+#else
+#define PLAT_ARM_MMAP_ENTRIES			U(6)
+#endif
+#define MAX_XLAT_TABLES				U(6)
+
+#define V2M_FLASH0_BASE				UL(0x08000000)
+#define V2M_FLASH0_SIZE				UL(0x04000000)
+#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_FW_CONFIG_MAX_SIZE			(ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE)
+#define PLAT_FW_CONFIG_BASE			ARM_FW_CONFIG_BASE
+
+/* RD1AE-specific memory mappings */
+#define RD1AE_EXTERNAL_FLASH	MAP_REGION_FLAT(V2M_FLASH0_BASE, \
+						V2M_FLASH0_SIZE, \
+						MT_DEVICE | MT_RO | \
+						MT_SECURE)
+
+#define RD1AE_MAP_NS_DRAM1	MAP_REGION_FLAT(ARM_DRAM1_BASE,	\
+						ARM_DRAM1_SIZE,	\
+						MT_MEMORY | MT_RW | \
+						MT_NS)
+
+#define RD1AE_DEVICE_BASE	(0x20000000)
+#define RD1AE_DEVICE_SIZE	(0x20000000)
+#define RD1AE_MAP_DEVICE	MAP_REGION_FLAT(RD1AE_DEVICE_BASE, \
+						RD1AE_DEVICE_SIZE, \
+						MT_DEVICE | MT_RW | \
+						MT_SECURE)
+
+#define SOC_PLATFORM_PERIPH_BASE	UL(0x0E000000)
+#define SOC_PLATFORM_PERIPH_SIZE	UL(0x02000000)
+#define SOC_PLATFORM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(SOC_PLATFORM_PERIPH_BASE, \
+							SOC_PLATFORM_PERIPH_SIZE, \
+							MT_DEVICE | MT_RW | MT_SECURE)
+
+/* Non-volatile counters */
+#define TRUSTED_NVCTR_BASE_OFFSET	UL(0x00E70000)
+#define TFW_NVCTR_BASE_OFFSET		0x0000
+#define NTFW_CTR_BASE_OFFSET		0x0004
+#define SOC_TRUSTED_NVCTR_BASE		(SOC_PLATFORM_PERIPH_BASE + TRUSTED_NVCTR_BASE_OFFSET)
+#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE + TFW_NVCTR_BASE_OFFSET)
+#define TFW_NVCTR_SIZE			U(4)
+#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + NTFW_CTR_BASE_OFFSET)
+#define NTFW_CTR_SIZE			U(4)
+
+/*******************************************************************************
+ * Memprotect definitions
+ ******************************************************************************/
+/* PSCI memory protect definitions:
+ * This variable is stored in a non-secure flash because some ARM reference
+ * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
+ * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
+ */
+#define PLAT_ARM_MEM_PROT_ADDR	(V2M_FLASH0_BASE + \
+					V2M_FLASH0_SIZE - \
+					V2M_FLASH_BLOCK_SIZE)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/include/rd1ae_helpers.S b/plat/arm/board/automotive_rd/platform/rd1ae/include/rd1ae_helpers.S
new file mode 100644
index 0000000..32260ef
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/include/rd1ae_helpers.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+	.globl	plat_arm_calc_core_pos
+
+	/* ---------------------------------------------------------------------
+	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+	 *
+	 * Function to calculate the core position on rd1ae.
+	 *
+	 * (ClusterId * PLAT_MAX_CPUS_PER_CLUSTER * PLAT_MAX_PE_PER_CPU) +
+	 * (CPUId * PLAT_MAX_PE_PER_CPU) +
+	 * ThreadId
+	 *
+	 * which can be simplified as:
+	 *
+	 * ((ClusterId * PLAT_MAX_CPUS_PER_CLUSTER + CPUId) * PLAT_MAX_PE_PER_CPU)
+	 * + ThreadId
+	 * ---------------------------------------------------------------------
+	 */
+func plat_arm_calc_core_pos
+	mov	x4, x0
+
+	/* Extract individual affinity fields from MPIDR */
+	ubfx    x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS
+
+	/* Compute linear position */
+	mov     x4, #PLAT_ARM_CLUSTER_COUNT
+	madd    x2, x3, x4, x2
+	mov     x4, #PLAT_MAX_CPUS_PER_CLUSTER
+	madd    x1, x2, x4, x1
+	mov     x4, #PLAT_MAX_PE_PER_CPU
+	madd    x0, x1, x4, x0
+	ret
+endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
new file mode 100644
index 0000000..35cd8a1
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
@@ -0,0 +1,88 @@
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# RD1AE (Kronos) platform.
+$(info Platform ${PLAT} is (kronos) specific.)
+
+RD1AE_BASE		=	plat/arm/board/automotive_rd/platform/rd1ae
+
+PLAT_INCLUDES		+=	-I${RD1AE_BASE}/include/
+
+override ARM_FW_CONFIG_LOAD_ENABLE	:=	1
+override ARM_PLAT_MT			:=	1
+override ARM_RECOM_STATE_ID_ENC		:=	1
+override CSS_LOAD_SCP_IMAGES		:=	0
+override CTX_INCLUDE_AARCH32_REGS	:=	0
+override ENABLE_SVE_FOR_NS		:=	1
+override ENABLE_SVE_FOR_SWD		:=	1
+override NEED_BL1			:=	0
+override NEED_BL2U			:=	0
+override PSCI_EXTENDED_STATE_ID		:=	1
+
+ARM_ARCH_MAJOR				:=	9
+ARM_ARCH_MINOR				:=	2
+CSS_USE_SCMI_SDS_DRIVER			:=	1
+ENABLE_FEAT_AMU				:=	1
+ENABLE_FEAT_ECV				:=	1
+ENABLE_FEAT_FGT				:=	1
+ENABLE_FEAT_MTE2			:=	1
+ENABLE_MPAM_FOR_LOWER_ELS		:=	1
+GIC_ENABLE_V4_EXTN			:=	1
+GICV3_SUPPORT_GIC600			:=	1
+HW_ASSISTED_COHERENCY			:=	1
+PLAT_MHU_VERSION			:=	1
+RESET_TO_BL2				:=	1
+SVE_VECTOR_LEN				:=	128
+USE_COHERENT_MEM			:=	0
+
+RD1AE_CPU_SOURCES	:=	lib/cpus/aarch64/neoverse_v3.S
+
+include drivers/arm/gic/v3/gicv3.mk
+RD1AE_GIC_SOURCES	:=	${GICV3_SOURCES}	\
+				plat/common/plat_gicv3.c	\
+				plat/arm/common/arm_gicv3.c
+
+PLAT_BL_COMMON_SOURCES	+=	${RD1AE_BASE}/rd1ae_plat.c	\
+				${RD1AE_BASE}/include/rd1ae_helpers.S
+
+BL2_SOURCES	+=	${RD1AE_CPU_SOURCES}	\
+			${RD1AE_BASE}/rd1ae_err.c	\
+			${RD1AE_BASE}/rd1ae_bl2_mem_params_desc.c	\
+			lib/utils/mem_region.c	\
+			plat/arm/common/arm_nor_psci_mem_protect.c	\
+			drivers/arm/sbsa/sbsa.c
+
+BL31_SOURCES	+=	${RD1AE_CPU_SOURCES}	\
+			${RD1AE_GIC_SOURCES}	\
+			${RD1AE_BASE}/rd1ae_bl31_setup.c	\
+			${RD1AE_BASE}/rd1ae_topology.c	\
+			drivers/cfi/v2m/v2m_flash.c	\
+			lib/utils/mem_region.c	\
+			plat/arm/common/arm_nor_psci_mem_protect.c
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+BL2_SOURCES	+=	${RD1AE_BASE}/rd1ae_tbb.c
+endif
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES	+=	${RD1AE_BASE}/fdts/${PLAT}_fw_config.dts	\
+			fdts/${PLAT}.dts
+
+FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+HW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+FIP_BL2_ARGS	:=	tb-fw
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
+endif
+
+include plat/arm/common/arm_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
new file mode 100644
index 0000000..30cc90f
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Following descriptor provides BL image/ep information that gets used
+ * by BL2 to load the images and also subset of this information is
+ * passed to next BL image. The image loading sequence is managed by
+ * populating the images in required loading order. The image execution
+ * sequence is managed by populating the `next_handoff_image_id` with
+ * the next executable image id.
+ ******************************************************************************/
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+	/* Fill BL31 related information */
+	{
+		.image_id = BL31_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+			VERSION_2, entry_point_info_t,
+			SECURE | EXECUTABLE | EP_FIRST_EXE),
+		.ep_info.pc = BL31_BASE,
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+			DISABLE_ALL_EXCEPTIONS),
+#if DEBUG
+		.ep_info.args.arg3 = ARM_BL31_PLAT_PARAM_VAL,
+#endif
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+			VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+		.image_info.image_base = BL31_BASE,
+		.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+	/* Fill HW_CONFIG related information */
+	{
+		.image_id = HW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+			VERSION_2, entry_point_info_t,
+			NON_SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+			VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+	/* Fill BL33 related information */
+	{
+		.image_id = BL33_IMAGE_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+			VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+		.ep_info.pc = PLAT_ARM_NS_IMAGE_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+			VERSION_2, image_info_t, 0),
+		.image_info.image_base = PLAT_ARM_NS_IMAGE_BASE,
+		.image_info.image_max_size = ARM_DRAM1_BASE + ARM_DRAM1_SIZE
+			- PLAT_ARM_NS_IMAGE_BASE,
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
new file mode 100644
index 0000000..ce7bad7
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+
+static scmi_channel_plat_info_t plat_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,
+	},
+};
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
+{
+	return &plat_rd_scmi_info[channel_id];
+}
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+	return css_scmi_override_pm_ops(ops);
+}
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_err.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_err.c
new file mode 100644
index 0000000..6254473
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_err.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/sbsa.h>
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rd1ae error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+	console_flush();
+
+	sbsa_wdog_refresh(SBSA_SECURE_WDOG_BASE);
+
+	while (1) {
+		wfi();
+	}
+}
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
new file mode 100644
index 0000000..e917330
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/sbsa.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	RD1AE_MAP_DEVICE,
+	RD1AE_EXTERNAL_FLASH,
+	SOC_PLATFORM_PERIPH_MAP_DEVICE,
+#if IMAGE_BL2
+	RD1AE_MAP_NS_DRAM1,
+#endif
+	{0}
+};
+
+void plat_arm_secure_wdt_start(void)
+{
+	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
+
+/*
+ * For rd1ae we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers
+ */
+void plat_arm_interconnect_init(void)
+{
+}
+
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
+
+/*
+ * TZC programming is currently not done.
+ */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_tbb.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_tbb.c
new file mode 100644
index 0000000..01fbcce
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_tbb.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+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);
+}
+
+/*
+ * 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/automotive_rd/platform/rd1ae/rd1ae_topology.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_topology.c
new file mode 100644
index 0000000..2533184
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_topology.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2024, Arm Limited. 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.
+ *
+ * This descriptor defines the layout of the power domain tree for the RD1AE
+ * platform, which consists of 16 clusters.
+ ******************************************************************************/
+const unsigned char rd1_ae_pd_tree_desc[] = {
+	(PLAT_ARM_CLUSTER_COUNT),
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return rd1_ae_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+	(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)),
+	(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)),
+};
+
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+	return PLAT_MAX_CPUS_PER_CLUSTER;
+}
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_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 ee07605..bd3faec 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_pm.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_pm.c
@@ -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) {
diff --git a/plat/arm/board/corstone1000/common/include/platform_def.h b/plat/arm/board/corstone1000/common/include/platform_def.h
index e3f3268..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)
@@ -277,7 +269,7 @@
 
 #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)
@@ -306,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 9d44a14..dfde5aa 100644
--- a/plat/arm/board/corstone1000/platform.mk
+++ b/plat/arm/board/corstone1000/platform.mk
@@ -6,7 +6,7 @@
 
 # Making sure the corstone1000 platform type is specified
 ifeq ($(filter ${TARGET_PLATFORM}, fpga fvp),)
-	$(error TARGET_PLATFORM must be fpga or fvp)
+        $(error TARGET_PLATFORM must be fpga or fvp)
 endif
 
 CORSTONE1000_CPU_LIBS	+=lib/cpus/aarch64/cortex_a35.S
diff --git a/plat/arm/board/fvp/fdts/fvp_cactus_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_cactus_sp_manifest.dts
new file mode 100644
index 0000000..de804e0
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_cactus_sp_manifest.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
+ * that will be consumed by EL3 SPMC.
+ *
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,ffa-manifest-1.0";
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	/* Properties */
+	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
+	id = <0x8001>;
+	uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
+	messaging-method = <3>; /* Direct messaging only */
+	exception-level = <2>; /* S-EL1 */
+	execution-state = <0>; /* AARCH64 */
+	execution-ctx-count = <8>;
+	/* Boot protocol */
+	gp-register-num = <0>;
+};
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 9fba4af..bf0e7f3 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -99,12 +99,17 @@
 
 	memory@2 {
 		device_type = "device-memory";
-		reg = <0x0 0x1c090000 0x0 0x40000>, /* UART */
+		reg = <0x0 0x1c0b0000 0x0 0x20000>, /* UART 2-3 */
 		      <0x0 0x2bfe0000 0x0 0x20000>, /* SMMUv3TestEngine */
 		      <0x0 0x2a490000 0x0 0x20000>, /* SP805 Trusted Watchdog */
 		      <0x0 0x1c130000 0x0 0x10000>; /* Virtio block device */
 	};
 
+	memory@3 {
+		device_type = "ns-device-memory";
+		reg = <0x0 0x1c090000 0x0 0x20000>; /* UART 0-1 */
+	};
+
 
 #if MEASURED_BOOT
 #include "event_log.dtsi"
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 b1d3bc1..f5d7f65 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -117,16 +117,16 @@
 
 #if defined(ARM_COT_cca)
 /* FVP does not support the CCA NV Counter so use the Trusted one. */
-&cca_nv_counter {
+&cca_nv_ctr {
 	reg = <TFW_NVCTR_BASE>;
 };
 #endif
 
-&trusted_nv_counter {
+&trusted_nv_ctr {
 	reg = <TFW_NVCTR_BASE>;
 };
 
-&non_trusted_nv_counter {
+&non_trusted_nv_ctr {
 	reg = <NTFW_CTR_BASE>;
 };
 #endif
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_el3_token_sign.c b/plat/arm/board/fvp/fvp_el3_token_sign.c
new file mode 100644
index 0000000..282f94a
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_el3_token_sign.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <plat/common/platform.h>
+#include <services/rmm_el3_token_sign.h>
+
+static struct el3_token_sign_request el3_req = { 0 };
+static bool el3_req_valid;
+
+/*
+ * According to https://www.secg.org/sec1-v2.pdf 2.3.3
+ * the size of the ECDSA P384 public key is 97 bytes,
+ * with the first byte being 0x04.
+ */
+static uint8_t sample_attest_pub_key[] = {
+	0x04, 0x76, 0xf9, 0x88, 0x09, 0x1b, 0xe5, 0x85, 0xed, 0x41,
+	0x80, 0x1a, 0xec, 0xfa, 0xb8, 0x58, 0x54, 0x8c, 0x63, 0x05,
+	0x7e, 0x16, 0xb0, 0xe6, 0x76, 0x12, 0x0b, 0xbd, 0x0d, 0x2f,
+	0x9c, 0x29, 0xe0, 0x56, 0xc5, 0xd4, 0x1a, 0x01, 0x30, 0xeb,
+	0x9c, 0x21, 0x51, 0x78, 0x99, 0xdc, 0x23, 0x14, 0x6b, 0x28,
+	0xe1, 0xb0, 0x62, 0xbd, 0x3e, 0xa4, 0xb3, 0x15, 0xfd, 0x21,
+	0x9f, 0x1c, 0xbb, 0x52, 0x8c, 0xb6, 0xe7, 0x4c, 0xa4, 0x9b,
+	0xe1, 0x67, 0x73, 0x73, 0x4f, 0x61, 0xa1, 0xca, 0x61, 0x03,
+	0x1b, 0x2b, 0xbf, 0x3d, 0x91, 0x8f, 0x2f, 0x94, 0xff, 0xc4,
+	0x22, 0x8e, 0x50, 0x91, 0x95, 0x44, 0xae
+};
+
+/*
+ * FVP does not support HES, so provide 0's as keys.
+ */
+int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
+					 unsigned int type)
+{
+	(void)type;
+	if (*len < sizeof(sample_attest_pub_key)) {
+		return E_RMM_INVAL;
+	}
+
+	if (type != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+		ERROR("Invalid ECC curve specified\n");
+		return E_RMM_INVAL;
+	}
+
+	*len = sizeof(sample_attest_pub_key);
+
+	(void)memcpy((void *)buf, sample_attest_pub_key,
+		     sizeof(sample_attest_pub_key));
+
+	return 0;
+}
+
+int plat_rmmd_el3_token_sign_push_req(const struct el3_token_sign_request *req)
+{
+	/*
+	 * TODO: Today this function is called with a lock held on the
+	 * RMM<->EL3 shared buffer. In the future, we may move to a
+	 * different design that may require handling multi-threaded
+	 * calls to this function, for example, if we have a per CPU
+	 * buffer between RMM and EL3.
+	 */
+	if (el3_req_valid) {
+		return E_RMM_AGAIN;
+	}
+
+	el3_req = *req;
+
+	if ((el3_req.hash_alg_id != EL3_TOKEN_SIGN_HASH_ALG_SHA384) ||
+	    (el3_req.sig_alg_id != ATTEST_KEY_CURVE_ECC_SECP384R1)) {
+		return E_RMM_INVAL;
+	}
+
+	el3_req_valid = true;
+
+	return 0;
+}
+
+int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp)
+{
+	if (!el3_req_valid) {
+		return E_RMM_AGAIN;
+	}
+
+	resp->rec_granule = el3_req.rec_granule;
+	resp->req_ticket = el3_req.req_ticket;
+	resp->sig_len = (uint16_t)sizeof(resp->signature_buf);
+	/* TODO: Provide real signature */
+	memset(resp->signature_buf, 0, sizeof(resp->signature_buf));
+
+	el3_req_valid = false;
+
+	return 0;
+}
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index 83b52fc..0894bf7 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -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.
  * Copyright (c) 2024, Linaro Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -16,213 +16,244 @@
  */
 static const uint8_t sample_platform_token[] = {
 	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, 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, 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,
+	0x59, 0x05, 0x81, 0xa9, 0x19, 0x01, 0x09, 0x78,
+	0x23, 0x74, 0x61, 0x67, 0x3a, 0x61, 0x72, 0x6d,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x32, 0x30, 0x32,
+	0x33, 0x3a, 0x63, 0x63, 0x61, 0x5f, 0x70, 0x6c,
+	0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x23, 0x31,
+	0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x58, 0x20, 0x0d,
+	0x22, 0xe0, 0x8a, 0x98, 0x46, 0x90, 0x58, 0x48,
+	0x63, 0x18, 0x28, 0x34, 0x89, 0xbd, 0xb3, 0x6f,
+	0x09, 0xdb, 0xef, 0xeb, 0x18, 0x64, 0xdf, 0x43,
+	0x3f, 0xa6, 0xe5, 0x4e, 0xa2, 0xd7, 0x11, 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,
+	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, 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, 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,
+	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, 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,
+	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, 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,
+	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, 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
+	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, 0x31, 0xd0,
+	0x4d, 0x52, 0xcc, 0xde, 0x95, 0x2c, 0x1e, 0x32,
+	0xcb, 0xa1, 0x81, 0x88, 0x5a, 0x40, 0xb8, 0xcc,
+	0x38, 0xe0, 0x52, 0x8c, 0x1e, 0x89, 0x58, 0x98,
+	0x07, 0x64, 0x2a, 0xa5, 0xe3, 0xf2, 0xbc, 0x37,
+	0xf9, 0x53, 0x74, 0x50, 0x6b, 0xff, 0x4d, 0x2e,
+	0x4b, 0xe7, 0x06, 0x3c, 0x4d, 0x72, 0x41, 0x92,
+	0x70, 0xc7, 0x22, 0xe8, 0xd4, 0xd9, 0x3e, 0xe8,
+	0xb6, 0xc9, 0xfa, 0xce, 0x3b, 0x43, 0xc9, 0x76,
+	0x1a, 0x49, 0x94, 0x1a, 0xb6, 0xf3, 0x8f, 0xfd,
+	0xff, 0x49, 0x6a, 0xd4, 0x63, 0xb4, 0xcb, 0xfa,
+	0x11, 0xd8, 0x3e, 0x23, 0xe3, 0x1f, 0x7f, 0x62,
+	0x32, 0x9d, 0xe3, 0x0c, 0x1c, 0xc8
 };
+static uint64_t platform_token_offset;
 
 /*
  * Get the hardcoded platform attestation token as FVP does not support
  * RSE.
+ *
+ * Note: This implementation caters for retrieval of the platform token
+ * in hunks to facilitate EL3-RMM interface testing. For most platforms,
+ * since the shared buffer size is known, the implementation can be more
+ * optimized.
  */
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
-				   uintptr_t hash, size_t hash_size)
+				   uintptr_t hash, size_t hash_size,
+				   size_t *remaining_len)
 {
 	(void)hash;
 	(void)hash_size;
+	size_t platform_token_size = sizeof(sample_platform_token);
+	size_t local_hunk_len;
+	size_t local_remaining_len;
 
-	if (*len < sizeof(sample_platform_token)) {
+	if (hash_size != 0) {
+		platform_token_offset = 0;
+	} else if (platform_token_offset == 0) {
 		return -EINVAL;
 	}
 
+	local_hunk_len = *len;
+	local_remaining_len = platform_token_size - platform_token_offset;
+
+	/*
+	 * If the buffer is enough to fit the remaining bytes of the token,
+	 * return only the remaining bytes of the token.
+	 */
+	if (local_hunk_len >= local_remaining_len) {
+		local_hunk_len = local_remaining_len;
+	}
+	/* Update remaining bytes according to hunk size */
+	local_remaining_len -= local_hunk_len;
+
+	(void)memcpy((void *)buf,
+			(const void *)sample_platform_token
+				+ platform_token_offset,
+			local_hunk_len);
+
-	(void)memcpy((void *)buf, (const void *)sample_platform_token,
-		     sizeof(sample_platform_token));
-	*len = sizeof(sample_platform_token);
+	platform_token_offset += local_hunk_len;
+	*len = local_hunk_len;
+	*remaining_len = local_remaining_len;
 
 	return 0;
 }
diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S
index 7c8bf06..2f99999 100644
--- a/plat/arm/board/fvp/include/plat.ld.S
+++ b/plat/arm/board/fvp/include/plat.ld.S
@@ -1,12 +1,38 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #ifndef PLAT_LD_S
 #define PLAT_LD_S
 
-#include <plat/arm/common/arm_tzc_dram.ld.S>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+MEMORY {
+    EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE
+}
+
+SECTIONS
+{
+	. = ARM_EL3_TZC_DRAM1_BASE;
+	ASSERT(. == ALIGN(PAGE_SIZE),
+	"ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
+	.el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) {
+	__PLAT_SPMC_SHMEM_DATASTORE_START__ = .;
+	*(.arm_spmc_shmem_datastore)
+	__PLAT_SPMC_SHMEM_DATASTORE_END__ = .;
+	__EL3_SEC_DRAM_START__ = .;
+	*(.arm_el3_tzc_dram)
+#if SEPARATE_SIMD_SECTION
+	. = ALIGN(16);
+	*(.simd_context)
+#endif
+	__EL3_SEC_DRAM_UNALIGNED_END__ = .;
+
+	. = ALIGN(PAGE_SIZE);
+	__EL3_SEC_DRAM_END__ = .;
+	} >EL3_SEC_DRAM
+}
 
 #if RECLAIM_INIT_CODE
 #include <plat/arm/common/arm_reclaim_init.ld.S>
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 56de8b8..e0c9725 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -149,6 +149,10 @@
 #define PLAT_ARM_EL3_FW_HANDOFF_BASE	ARM_BL_RAM_BASE
 #define PLAT_ARM_EL3_FW_HANDOFF_LIMIT	PLAT_ARM_EL3_FW_HANDOFF_BASE + PLAT_ARM_FW_HANDOFF_SIZE
 
+#if RESET_TO_BL31
+#define PLAT_ARM_TRANSFER_LIST_DTB_OFFSET	FW_NS_HANDOFF_BASE + TRANSFER_LIST_DTB_OFFSET
+#endif
+
 #else
 #define PLAT_ARM_FW_HANDOFF_SIZE	U(0)
 #endif
@@ -297,7 +301,9 @@
  * calculated using the current SP_MIN PROGBITS debug size plus the sizes of
  * BL2 and BL1-RW
  */
-# define PLAT_ARM_MAX_BL32_SIZE		UL(0x3B000)
+# define PLAT_ARM_MAX_BL32_SIZE		(PLAT_ARM_TRUSTED_SRAM_SIZE - \
+					 ARM_SHARED_RAM_SIZE - \
+					 ARM_FW_CONFIGS_SIZE)
 #endif /* RESET_TO_SP_MIN */
 #endif
 
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index dc8032f..077283e 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -36,7 +36,6 @@
 fdt     fdt_get_name
 fdt     fdt_get_alias
 fdt     fdt_node_offset_by_phandle
-fdt     fdt_subnode_offset
 fdt     fdt_add_subnode
 mbedtls mbedtls_asn1_get_alg
 mbedtls mbedtls_asn1_get_alg_null
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index af2b78d..33e1feb 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -47,6 +47,10 @@
 ifeq (${CTX_INCLUDE_FPREGS}, 0)
       ENABLE_SME_FOR_NS		:= 2
       ENABLE_SME2_FOR_NS	:= 2
+else
+      ENABLE_SVE_FOR_NS		:= 0
+      ENABLE_SME_FOR_NS		:= 0
+      ENABLE_SME2_FOR_NS	:= 0
 endif
 endif
 
@@ -57,6 +61,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,11 +70,15 @@
 ENABLE_TRF_FOR_NS		:= 2
 ENABLE_FEAT_ECV			:= 2
 ENABLE_FEAT_FGT			:= 2
+ENABLE_FEAT_FGT2		:= 2
+ENABLE_FEAT_THE			:= 2
 ENABLE_FEAT_TCR2		:= 2
 ENABLE_FEAT_S2PIE		:= 2
 ENABLE_FEAT_S1PIE		:= 2
 ENABLE_FEAT_S2POE		:= 2
 ENABLE_FEAT_S1POE		:= 2
+ENABLE_FEAT_SCTLR2		:= 2
+ENABLE_FEAT_MTE2		:= 2
 
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))
@@ -257,7 +266,8 @@
 				plat/arm/board/fvp/fvp_cpu_pwr.c
 
 BL31_SOURCES		+=	plat/arm/board/fvp/fvp_plat_attest_token.c	\
-				plat/arm/board/fvp/fvp_realm_attest_key.c
+				plat/arm/board/fvp/fvp_realm_attest_key.c	\
+				plat/arm/board/fvp/fvp_el3_token_sign.c
 endif
 
 ifeq (${ENABLE_FEAT_RNG_TRAP},1)
@@ -321,10 +331,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
@@ -384,6 +390,18 @@
 $(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
+
+TRANSFER_LIST_DTB_OFFSET	:=	0x20
+$(eval $(call add_define,TRANSFER_LIST_DTB_OFFSET))
+endif
+endif
+
 # Enable dynamic mitigation support by default
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk
index f14ea54..71cb9e2 100644
--- a/plat/arm/board/fvp_r/platform.mk
+++ b/plat/arm/board/fvp_r/platform.mk
@@ -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
 #
@@ -25,7 +25,7 @@
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
 
-PLAT_INCLUDES		:=	-Iplat/arm/board/fvp_r/include
+PLAT_INCLUDES		+=	-Iplat/arm/board/fvp_r/include
 
 FVP_R_BL_COMMON_SOURCES	:=	plat/arm/board/fvp_r/fvp_r_common.c		\
 				plat/arm/board/fvp_r/fvp_r_context_mgmt.c	\
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/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h
index 1b92ec2..3fbc125 100644
--- 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
@@ -111,4 +111,18 @@
 			ARM_REALM_SIZE,					\
 			MT_MEMORY | MT_RW | MT_REALM)
 
+#if RESET_TO_BL31
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+
+/* Define the DTB image base and size */
+#define NRD_CSS_BL31_PRELOAD_DTB_BASE	UL(0xF3000000)
+#define NRD_CSS_BL31_PRELOAD_DTB_SIZE	UL(0x1000)
+#define NRD_CSS_MAP_BL31_DTB		MAP_REGION_FLAT(		\
+					NRD_CSS_BL31_PRELOAD_DTB_BASE,	\
+					NRD_CSS_BL31_PRELOAD_DTB_SIZE,	\
+					MT_RW_DATA | MT_NS)
+#endif /* RESET_TO_BL31 */
+
 #endif /* NRD_CSS_FW_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
index 0dce512..8d6d1cb 100644
--- 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
@@ -56,8 +56,8 @@
  * 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))
+#  define PLAT_ARM_MMAP_ENTRIES		(10 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(10 + ((NRD_CHIP_COUNT - 1) * 3))
 #elif defined(IMAGE_BL32)
 # define PLAT_ARM_MMAP_ENTRIES		U(8)
 # define MAX_XLAT_TABLES		U(5)
@@ -442,7 +442,7 @@
  * SRAM layout
  ******************************************************************************/
 
-/*
+/* if !RESET_TO_BL31
  *              Trusted SRAM
  * 0x00100000 +--------------+
  *            |    L0 GPT    |
@@ -460,6 +460,26 @@
  * 0x00019000 +--------------+
  *            |   BL1 (ro)   |
  * 0x00000000 +--------------+
+ *
+ * else
+ *
+ *              Trusted SRAM
+ * 0x00100000 +--------------+
+ *            |    L0 GPT    |
+ * 0x000E0000 +--------------
+ *            |              |  side-loaded    +----------------+
+ *            |              |  <<<<<<<<<<<<<  |                |
+ *            |              |  <<<<<<<<<<<<<  |  BL31 NOBITS   |
+ *            |              |  <<<<<<<<<<<<<  |                |
+ *            |              |  <<<<<<<<<<<<<  |----------------|
+ *            |              |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
+ * 0x00063000 |              |                 +----------------+
+ * 0x0001A000 +--------------+
+ *            |    Shared    |
+ * 0x00019000 +--------------+
+ *            |   BL1 (ro)   |
+ * 0x00000000 +--------------+
+ * endif
  */
 
 /*******************************************************************************
@@ -531,7 +551,11 @@
  * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory
  */
 #define ARM_FW_CONFIGS_SIZE		(PAGE_SIZE * 2)
+#if RESET_TO_BL31
+#define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE)
+#else
 #define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + ARM_FW_CONFIGS_SIZE)
+#endif
 
 /*******************************************************************************
  * BL1 RW specifics
@@ -556,9 +580,13 @@
  ******************************************************************************/
 
 /* Keep BL31 below BL2 in the Trusted SRAM.*/
+#if RESET_TO_BL31
+#define BL31_BASE			(0x63000)
+#else
 #define BL31_BASE			((ARM_BL_RAM_BASE +		\
 					  ARM_BL_RAM_SIZE) -		\
 					  PLAT_ARM_MAX_BL31_SIZE)
+#endif
 #define BL31_PROGBITS_LIMIT		BL2_BASE
 #define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
 
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 391c68c..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,13 +28,13 @@
 #define RD_V2_SID_VER_PART_NUM			0x07F2
 #define RD_V2_CONFIG_ID				0x1
 
-/* SID Version values for RD-Fremont */
-#define RD_FREMONT_SID_VER_PART_NUM		0x07EE
-#define RD_FREMONT_CONFIG_ID			0x0
+/* 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-Fremont variants */
-#define RD_FREMONT_CFG1_SID_VER_PART_NUM	0x07F9
-#define RD_FREMONT_CFG2_SID_VER_PART_NUM	0x07EE
+/* 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 {
diff --git a/plat/arm/board/neoverse_rd/common/nrd-common.mk b/plat/arm/board/neoverse_rd/common/nrd-common.mk
index 95a221f..a09f369 100644
--- a/plat/arm/board/neoverse_rd/common/nrd-common.mk
+++ b/plat/arm/board/neoverse_rd/common/nrd-common.mk
@@ -54,11 +54,6 @@
 				${NRD_COMMON_BASE}/nrd_topology.c	\
 				drivers/delay_timer/generic_delay_timer.c
 
-ifneq (${RESET_TO_BL31},0)
-  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
-  Please set RESET_TO_BL31 to 0.")
-endif
-
 $(eval $(call add_define,NRD_CHIP_COUNT))
 
 $(eval $(call add_define,NRD_PLATFORM_VARIANT))
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 5a7dfb1..bce8834 100644
--- a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
@@ -131,9 +131,9 @@
 			panic();
 		}
 		return &plat_rd_scmi_info[channel_id];
-	} else if (nrd_plat_info.platform_id == RD_FREMONT_SID_VER_PART_NUM ||
-		nrd_plat_info.platform_id == RD_FREMONT_CFG1_SID_VER_PART_NUM ||
-		nrd_plat_info.platform_id == RD_FREMONT_CFG2_SID_VER_PART_NUM) {
+	} 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();
 		}
@@ -155,6 +155,65 @@
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
 }
 
+/*******************************************************************************
+ * This function inserts platform information via device tree nodes as,
+ * system-id {
+ *    platform-id = <0>;
+ *    config-id = <0>;
+ * }
+ ******************************************************************************/
+#if RESET_TO_BL31
+static int append_config_node(uintptr_t fdt_base_addr, uintptr_t fdt_base_size)
+{
+	void *fdt;
+	int nodeoffset, err;
+	unsigned int platid = 0, platcfg = 0;
+
+	if (fdt_base_addr == 0) {
+		ERROR("NT_FW CONFIG base address is NULL\n");
+		return -1;
+	}
+
+	fdt = (void *)fdt_base_addr;
+
+	/* Check the validity of the fdt */
+	if (fdt_check_header(fdt) != 0) {
+		ERROR("Invalid NT_FW_CONFIG DTB passed\n");
+		return -1;
+	}
+
+	nodeoffset = fdt_subnode_offset(fdt, 0, "system-id");
+	if (nodeoffset < 0) {
+		ERROR("Failed to get system-id node offset\n");
+		return -1;
+	}
+
+	platid = plat_arm_nrd_get_platform_id();
+	err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid);
+	if (err < 0) {
+		ERROR("Failed to set platform-id\n");
+		return -1;
+	}
+
+	platcfg = plat_arm_nrd_get_config_id();
+	err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg);
+	if (err < 0) {
+		ERROR("Failed to set config-id\n");
+		return -1;
+	}
+
+	platcfg = plat_arm_nrd_get_multi_chip_mode();
+	err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
+	if (err < 0) {
+		ERROR("Failed to set multi-chip-mode\n");
+		return -1;
+	}
+
+	flush_dcache_range((uintptr_t)fdt, fdt_base_size);
+	return 0;
+}
+#endif
+
 void nrd_bl31_common_platform_setup(void)
 {
 	generic_delay_timer_init();
@@ -169,6 +228,15 @@
 	ehf_register_priority_handler(PLAT_REBOOT_PRI,
 			css_reboot_interrupt_handler);
 #endif
+
+#if RESET_TO_BL31
+	int ret = append_config_node(NRD_CSS_BL31_PRELOAD_DTB_BASE,
+			NRD_CSS_BL31_PRELOAD_DTB_SIZE);
+
+	if (ret != 0) {
+		panic();
+	}
+#endif
 }
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
diff --git a/plat/arm/board/neoverse_rd/common/nrd_plat3.c b/plat/arm/board/neoverse_rd/common/nrd_plat3.c
index 7b98052..00f346e 100644
--- a/plat/arm/board/neoverse_rd/common/nrd_plat3.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_plat3.c
@@ -60,6 +60,9 @@
 	NRD_CSS_GPT_L1_DRAM_MMAP,
 	NRD_CSS_EL3_RMM_SHARED_MEM_MMAP,
 	NRD_CSS_GPC_SMMU_SMMUV3_MMAP,
+#if RESET_TO_BL31
+	NRD_CSS_MAP_BL31_DTB,
+#endif
 	{0}
 };
 #endif /* IMAGE_BL31 */
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..dcee92c 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,39 +62,37 @@
 	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);
+	cpu_info->ErrCtxEl1Reg[7] = read_ctx_sctlr_el1_reg_errata(ctx);
 	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);
+	cpu_info->ErrCtxEl1Reg[11] = read_ctx_tcr_el1_reg_errata(ctx);
+	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
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 	cpu_info->ErrCtxEl2Reg[0]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
 						elr_el2);
 	cpu_info->ErrCtxEl2Reg[1]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
@@ -127,7 +125,7 @@
 						vttbr_el2);
 	cpu_info->ErrCtxEl2Reg[15]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
 						esr_el2);
-#endif /* CTX_INCLUDE_EL2_REGS */
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 
 	cpu_info->ErrCtxEl3Reg[0]   = read_ctx_reg(get_el3state_ctx(ctx),
 						   CTX_ELR_EL3);
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl31_setup.c b/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl31_setup.c
deleted file mode 100644
index 8544930..0000000
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl31_setup.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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 <rdfremont_rse_comms.h>
-
-#if (NRD_PLATFORM_VARIANT == 2)
-static const mmap_region_t rdfremontmc_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 rdfremontmc_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 rdfremontmc_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-Fremont 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-Fremont variant\n");
-
-		for (i = 0; i < ARRAY_SIZE(rdfremontmc_dynamic_mmap); i++) {
-			ret = mmap_add_dynamic_region(
-					rdfremontmc_dynamic_mmap[i].base_pa,
-					rdfremontmc_dynamic_mmap[i].base_va,
-					rdfremontmc_dynamic_mmap[i].size,
-					rdfremontmc_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(
-			rdfremontmc_multichip_gicr_frames);
-		gic600_multichip_init(&rdfremontmc_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/rdn1edge/platform.mk b/plat/arm/board/neoverse_rd/platform/rdn1edge/platform.mk
index 15fc9bb..4892804 100644
--- a/plat/arm/board/neoverse_rd/platform/rdn1edge/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/platform.mk
@@ -71,6 +71,11 @@
      currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
 override CTX_INCLUDE_AARCH32_REGS	:= 0
 override SPMD_SPM_AT_SEL2		:= 0
 
diff --git a/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk b/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
index c8f0899..c2dfba6 100644
--- a/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
@@ -103,6 +103,11 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${TOS_FW_CONFIG},--tos-fw-config,${TOS_FW_CONFIG}))
 endif
 
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
 override CTX_INCLUDE_AARCH32_REGS	:= 0
 override ENABLE_FEAT_AMU		:= 2
 override ENABLE_FEAT_MTE2       	:= 2
diff --git a/plat/arm/board/neoverse_rd/platform/rdv1/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv1/platform.mk
index fe87779..db8efbb 100644
--- a/plat/arm/board/neoverse_rd/platform/rdv1/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/platform.mk
@@ -66,5 +66,10 @@
      currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
 # Enable the flag since RD-V1 has a system level cache
 NEOVERSE_Nx_EXTERNAL_LLC		:=	1
diff --git a/plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk
index a0a1204..6d518d5 100644
--- a/plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk
@@ -77,5 +77,10 @@
      currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
 # Enable the flag since RD-V1-MC has a system level cache
 NEOVERSE_Nx_EXTERNAL_LLC		:=	1
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_fw_config.dts
similarity index 100%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_fw_config.dts
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts
similarity index 92%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts
index 62cad39..941d4a0 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts
@@ -7,7 +7,7 @@
 /dts-v1/;
 / {
 	/* compatible string */
-	compatible = "arm,rd-fremont";
+	compatible = "arm,rd-v3";
 
 	/*
 	 * Place holder for system-id node with default values. The
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_tb_fw_config.dts
similarity index 100%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/fdts/rdfremont_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_tb_fw_config.dts
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h
similarity index 100%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/include/platform_def.h
rename to plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_mhuv3.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h
similarity index 69%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_mhuv3.h
rename to plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h
index 400dcc5..fa64963 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_mhuv3.h
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h
@@ -4,9 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef RDFREMONT_MHUV3_H
-#define RDFREMONT_MHUV3_H
+#ifndef RDV3_MHUV3_H
+#define RDV3_MHUV3_H
 
 void mhu_v3_get_secure_device_base(uintptr_t *base, bool sender);
 
-#endif /* RDFREMONT_MHUV3_H */
+#endif /* RDV3_MHUV3_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_rse_comms.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h
similarity index 62%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_rse_comms.h
rename to plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h
index ad1bc23..cb8e786 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/include/rdfremont_rse_comms.h
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h
@@ -4,9 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef RDFREMONT_RSE_COMMS_H
-#define RDFREMONT_RSE_COMMS_H
+#ifndef RDV3_RSE_COMMS_H
+#define RDV3_RSE_COMMS_H
 
 int plat_rse_comms_init(void);
 
-#endif /* RDFREMONT_RSE_COMMS_H */
+#endif /* RDV3_RSE_COMMS_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
similarity index 61%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/platform.mk
rename to plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
index bca6172..f37d903 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
@@ -3,16 +3,16 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-RD_FREMONT_VARIANTS := 0 1 2
+RD_V3_VARIANTS := 0 1 2
 ifneq ($(NRD_PLATFORM_VARIANT),						\
-	$(filter $(NRD_PLATFORM_VARIANT),$(RD_FREMONT_VARIANTS)))
-	$(error "NRD_PLATFORM_VARIANT for RD-FREMONT should be 0, 1, or 2,"
+	$(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-Fremont-MC should be either $(SEQ) \
+	$(error  "Chip count for RD-V3-MC should be either $(SEQ) \
 	currently it is set to ${NRD_CHIP_COUNT}.")
 endif
 
@@ -21,16 +21,28 @@
 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
 
+ifeq (${PLAT_RESET_TO_BL31}, 1)
+# Support for BL31 boot flow
+override RESET_TO_BL31			:= 1
+
+# arm_common.mk sets ENABLE_PIE=1, but Makefile blocks PIE for RME
+override ENABLE_PIE			:= 0
+
+# Non Trusted Firmware parameters
+override ARM_PRELOADED_DTB_BASE		:= 0xF3000000
+override ARM_LINUX_KERNEL_AS_BL33	:= 1
+override PRELOADED_BL33_BASE		:= 0xE0000000
+
-# RD-Fremont platform uses GIC-700 which is based on GICv4.1
+# These are internal build flags but as of now RESET_TO_BL31 won't work without defining them
+override NEED_BL1			:= no
+override NEED_BL2			:= no
+override NEED_BL32			:= no
+endif
+
+# 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
@@ -38,7 +50,7 @@
 GICV3_IMPL_GIC600_MULTICHIP	:= 1
 endif
 
-# RD-Fremont uses MHUv3
+# RD-V3 uses MHUv3
 PLAT_MHU_VERSION := 3
 
 include plat/arm/board/neoverse_rd/common/nrd-common.mk
@@ -48,58 +60,62 @@
 include drivers/measured_boot/rse/rse_measured_boot.mk
 endif
 
-RDFREMONT_BASE	=	plat/arm/board/neoverse_rd/platform/rdfremont
+RDV3_BASE	=	plat/arm/board/neoverse_rd/platform/rdv3
 
 PLAT_INCLUDES	+=	-I${NRD_COMMON_BASE}/include/nrd3/		\
-			-I${RDFREMONT_BASE}/include/			\
+			-I${RDV3_BASE}/include/			\
 			-Iinclude/lib/psa
 
 NRD_CPU_SOURCES	:=	lib/cpus/aarch64/neoverse_v3.S
 
-# Source files for RD-Fremont variants
+# Source files for RD-V3 variants
 PLAT_BL_COMMON_SOURCES							\
 		+=	${NRD_COMMON_BASE}/nrd_plat3.c			\
-			${RDFREMONT_BASE}/rdfremont_common.c
+			${RDV3_BASE}/rdv3_common.c
 
 PLAT_MEASURED_BOOT_SOURCES						\
 		:=	${MEASURED_BOOT_SOURCES} 			\
 			${RSE_COMMS_SOURCES}				\
-			${RDFREMONT_BASE}/rdfremont_common_measured_boot.c \
+			${RDV3_BASE}/rdv3_common_measured_boot.c \
 			lib/psa/measured_boot.c
 
 BL1_SOURCES	+=	${NRD_CPU_SOURCES}				\
-			${RDFREMONT_BASE}/rdfremont_err.c		\
-			${RDFREMONT_BASE}/rdfremont_mhuv3.c
+			${RDV3_BASE}/rdv3_err.c		\
+			${RDV3_BASE}/rdv3_mhuv3.c
 ifeq (${TRUSTED_BOARD_BOOT}, 1)
-BL1_SOURCES	+=	${RDFREMONT_BASE}/rdfremont_trusted_boot.c
+BL1_SOURCES	+=	${RDV3_BASE}/rdv3_trusted_boot.c
 endif
 ifeq (${MEASURED_BOOT},1)
 BL1_SOURCES	+=	${PLAT_MEASURED_BOOT_SOURCES}			\
-			${RDFREMONT_BASE}/rdfremont_bl1_measured_boot.c
+			${RDV3_BASE}/rdv3_bl1_measured_boot.c
 endif
 
-BL2_SOURCES	+=	${RDFREMONT_BASE}/rdfremont_bl2_setup.c		\
-			${RDFREMONT_BASE}/rdfremont_err.c		\
-			${RDFREMONT_BASE}/rdfremont_mhuv3.c		\
-			${RDFREMONT_BASE}/rdfremont_security.c		\
+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	+=	${RDFREMONT_BASE}/rdfremont_trusted_boot.c
+BL2_SOURCES	+=	${RDV3_BASE}/rdv3_trusted_boot.c
 endif
 ifeq (${MEASURED_BOOT},1)
 BL2_SOURCES	+=	${PLAT_MEASURED_BOOT_SOURCES}			\
-			${RDFREMONT_BASE}/rdfremont_bl2_measured_boot.c
+			${RDV3_BASE}/rdv3_bl2_measured_boot.c
 endif
 
+ifeq (${PLAT_RESET_TO_BL31}, 1)
+BL31_SOURCES	+=	${RDV3_BASE}/rdv3_security.c
+endif
+
 BL31_SOURCES	+=	${NRD_CPU_SOURCES}				\
 			${MBEDTLS_SOURCES}				\
 			${RSE_COMMS_SOURCES}				\
-			${RDFREMONT_BASE}/rdfremont_bl31_setup.c	\
-			${RDFREMONT_BASE}/rdfremont_mhuv3.c		\
-			${RDFREMONT_BASE}/rdfremont_topology.c		\
-			${RDFREMONT_BASE}/rdfremont_plat_attest_token.c	\
-			${RDFREMONT_BASE}/rdfremont_realm_attest_key.c	\
+			${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			\
@@ -111,14 +127,14 @@
 BL31_SOURCES	+=	drivers/arm/gic/v3/gic600_multichip.c
 endif
 
-# XLAT options for RD-Fremont variants
+# 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	+=	${RDFREMONT_BASE}/fdts/${PLAT}_fw_config.dts	\
-			${RDFREMONT_BASE}/fdts/${PLAT}_tb_fw_config.dts \
-			${RDFREMONT_BASE}/fdts/${PLAT}_nt_fw_config.dts
+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
@@ -131,9 +147,10 @@
 # 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-Fremont variants
+# 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
+override CTX_INCLUDE_SVE_REGS	:= 1
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl1_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c
similarity index 88%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl1_measured_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c
index 92e96c2..4db9a11 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl1_measured_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c
@@ -13,13 +13,13 @@
 #include <platform_def.h>
 
 #include <nrd_plat.h>
-#include <rdfremont_rse_comms.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 rdfremont_rse_mboot_metadata[] = {
+struct rse_mboot_metadata rdv3_rse_mboot_metadata[] = {
 	{
 		.id = FW_CONFIG_ID,
 		.slot = U(8),
@@ -51,7 +51,7 @@
 	/* Initialize the communication channel between AP and RSE */
 	(void)plat_rse_comms_init();
 
-	rse_measured_boot_init(rdfremont_rse_mboot_metadata);
+	rse_measured_boot_init(rdv3_rse_mboot_metadata);
 }
 
 void bl1_plat_mboot_finish(void)
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c
similarity index 90%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_measured_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c
index 570c33a..1b94427 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_measured_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c
@@ -13,13 +13,13 @@
 #include <platform_def.h>
 
 #include <nrd_plat.h>
-#include <rdfremont_rse_comms.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 rdfremont_rse_mboot_metadata[] = {
+struct rse_mboot_metadata rdv3_rse_mboot_metadata[] = {
 	{
 		.id = BL31_IMAGE_ID,
 		.slot = U(11),
@@ -60,7 +60,7 @@
 	/* Initialize the communication channel between AP and RSE */
 	(void)plat_rse_comms_init();
 
-	rse_measured_boot_init(rdfremont_rse_mboot_metadata);
+	rse_measured_boot_init(rdv3_rse_mboot_metadata);
 }
 
 void bl2_plat_mboot_finish(void)
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_setup.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_setup.c
similarity index 100%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_bl2_setup.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_setup.c
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..a5d687e
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c
@@ -0,0 +1,221 @@
+/*
+ * 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");
+	}
+}
+
+#if RESET_TO_BL31
+/*
+ * 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;
+}
+
+#endif /* RESET_TO_BL31 */
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
similarity index 98%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
index 31cc2a0..10fe666 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
@@ -11,8 +11,8 @@
 #include <plat/common/platform.h>
 #include <platform_def.h>
 #include <nrd_plat.h>
-#include <rdfremont_mhuv3.h>
-#include <rdfremont_rse_comms.h>
+#include <rdv3_mhuv3.h>
+#include <rdv3_rse_comms.h>
 
 unsigned int plat_arm_nrd_get_platform_id(void)
 {
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c
similarity index 76%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common_measured_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c
index e95c544..f5160ce 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_common_measured_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c
@@ -10,11 +10,11 @@
 #include <common/desc_image_load.h>
 #include <drivers/measured_boot/rse/rse_measured_boot.h>
 
-extern struct rse_mboot_metadata rdfremont_rse_mboot_metadata[];
+extern struct rse_mboot_metadata rdv3_rse_mboot_metadata[];
 
 struct rse_mboot_metadata *plat_rse_mboot_get_metadata(void)
 {
-	return rdfremont_rse_mboot_metadata;
+	return rdv3_rse_mboot_metadata;
 }
 
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
@@ -22,7 +22,7 @@
 	int err;
 
 	/* Calculate image hash and record data in RSE */
-	err = rse_mboot_measure_and_record(rdfremont_rse_mboot_metadata,
+	err = rse_mboot_measure_and_record(rdv3_rse_mboot_metadata,
 					   image_data->image_base,
 					   image_data->image_size,
 					   image_id);
@@ -36,6 +36,6 @@
 
 int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
 {
-	return rse_mboot_set_signer_id(rdfremont_rse_mboot_metadata, pk_oid,
+	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/rdfremont/rdfremont_err.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c
similarity index 89%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_err.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c
index de6cc68..270febf 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c
@@ -7,7 +7,7 @@
 #include <plat/arm/common/plat_arm.h>
 
 /*
- * rdfremont error handler
+ * rdv3 error handler
  */
 void __dead2 plat_arm_error_handler(int err)
 {
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_mhuv3.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c
similarity index 92%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_mhuv3.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c
index 41332cc..738f753 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_mhuv3.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c
@@ -11,7 +11,7 @@
 
 #include <nrd_css_def3.h>
 #include <nrd_plat.h>
-#include <rdfremont_mhuv3.h>
+#include <rdv3_mhuv3.h>
 
 void mhu_v3_get_secure_device_base(uintptr_t *base, bool sender)
 {
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_plat_attest_token.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c
similarity index 71%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_plat_attest_token.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c
index 188a09f..5584662 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_plat_attest_token.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c
@@ -4,23 +4,32 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <errno.h>
 #include <stdint.h>
 
 #include <cca_attestation.h>
 #include <common/debug.h>
+#include <plat/common/common_def.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)
+				   uintptr_t hash, size_t hash_size,
+				   size_t *remaining_len)
 {
 	psa_status_t ret;
 
+	assert(*len == SZ_4K);
+
 	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;
 	}
 
+	assert(*len <= SZ_4K);
+
+	*remaining_len = 0;
+
 	return 0;
 }
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_realm_attest_key.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_realm_attest_key.c
similarity index 100%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_realm_attest_key.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_realm_attest_key.c
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_security.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_security.c
similarity index 100%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_security.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_security.c
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_topology.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c
similarity index 97%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_topology.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c
index e7931d4..6eb5002 100644
--- a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c
@@ -10,7 +10,7 @@
 /******************************************************************************
  * The power domain tree descriptor.
  ******************************************************************************/
-const unsigned char rd_fremont_pd_tree_desc[] = {
+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,
@@ -44,7 +44,7 @@
  ******************************************************************************/
 const unsigned char *plat_get_power_domain_tree_desc(void)
 {
-	return rd_fremont_pd_tree_desc;
+	return rd_v3_pd_tree_desc;
 }
 
 /*******************************************************************************
diff --git a/plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_trusted_boot.c
similarity index 100%
rename from plat/arm/board/neoverse_rd/platform/rdfremont/rdfremont_trusted_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_trusted_boot.c
diff --git a/plat/arm/board/neoverse_rd/platform/sgi575/platform.mk b/plat/arm/board/neoverse_rd/platform/sgi575/platform.mk
index 37306be..1f40107 100644
--- a/plat/arm/board/neoverse_rd/platform/sgi575/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/platform.mk
@@ -65,4 +65,9 @@
      currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
 override SPMD_SPM_AT_SEL2		:= 0
diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
index a6b63a1..737997d 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
@@ -99,11 +99,7 @@
 
 	memory@1 {
 		device_type = "ns-memory";
-		reg =
-#ifdef TS_SP_FW_CONFIG
-		      <0x0 0x08000000 0x0 0x4000000>,
-#endif /* TS_SP_FW_CONFIG */
-		      <0x0 TC_NS_DRAM1_BASE 0x0 TC_NS_DRAM1_SIZE>,
+		reg = <0x0 TC_NS_DRAM1_BASE 0x0 TC_NS_DRAM1_SIZE>,
 		      <HI(PLAT_ARM_DRAM2_BASE) LO(PLAT_ARM_DRAM2_BASE)
 		       HI(TC_NS_DRAM2_SIZE) LO(TC_NS_DRAM2_SIZE)>;
 	};
@@ -117,4 +113,11 @@
 		device_type = "device-memory";
 		reg = <0x0 PLAT_ARM_BOOT_UART_BASE 0x0 0x01000>;
 	};
+
+#ifdef TS_SP_FW_CONFIG
+	ns_flash {
+		device_type = "ns-device-memory";
+		reg = <0x0 V2M_FLASH0_BASE 0x0 V2M_FLASH0_SIZE>;
+	};
+#endif
 };
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 38413ef..613f508 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -7,11 +7,26 @@
 #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>
 #include <plat/arm/board/common/v2m_def.h>
+
+/*
+ * arm_def.h depends on the platform system counter macros, so must define the
+ * platform macros before including arm_def.h.
+ */
+#if TARGET_PLATFORM == 4
+#ifdef ARM_SYS_CNTCTL_BASE
+#error "error: ARM_SYS_CNTCTL_BASE is defined prior to the PLAT_ARM_SYS_CNTCTL_BASE definition"
+#endif
+#define PLAT_ARM_SYS_CNTCTL_BASE	UL(0x47000000)
+#define PLAT_ARM_SYS_CNTREAD_BASE	UL(0x47010000)
+#endif
+
 #include <plat/arm/common/arm_def.h>
+
 #include <plat/arm/common/arm_spm_def.h>
 #include <plat/arm/css/common/css_def.h>
 #include <plat/arm/soc/common/soc_css_def.h>
@@ -36,9 +51,6 @@
  *               |      (4KB)     |
  *  0x8000_9000  ------------------
  *               |       ...      |
- *  0xf8a0_0000  ------------------   TC_NS_FWU_BASE
- *               |    FWU shmem   |
- *               |      (4MB)     |
  *  0xf8e0_0000  ------------------   TC_NS_OPTEE_BASE
  *               |  OP-TEE shmem  |
  *               |      (2MB)     |
@@ -70,8 +82,6 @@
 
 #define TC_NS_OPTEE_SIZE		(2 * SZ_1M)
 #define TC_NS_OPTEE_BASE		(TC_NS_DRAM1_BASE + TC_NS_DRAM1_SIZE - TC_NS_OPTEE_SIZE)
-#define TC_NS_FWU_SIZE			(4 * SZ_1M)
-#define TC_NS_FWU_BASE			(TC_NS_OPTEE_BASE - TC_NS_FWU_SIZE)
 
 /*
  * Mappings for TC DRAM1 (non-secure) and TC TZC DRAM1 (secure)
@@ -177,7 +187,7 @@
 # if SPM_MM
 #  define PLATFORM_STACK_SIZE		0x500
 # else
-#  define PLATFORM_STACK_SIZE		0xa00
+#  define PLATFORM_STACK_SIZE		0xb00
 # endif
 #elif defined(IMAGE_BL32)
 # define PLATFORM_STACK_SIZE		0x440
@@ -213,7 +223,7 @@
 						V2M_FLASH0_SIZE,	\
 						MT_DEVICE | MT_RO | MT_SECURE)
 
-#define PLAT_ARM_NSTIMER_FRAME_ID	0
+#define PLAT_ARM_NSTIMER_FRAME_ID	U(1)
 
 #define PLAT_ARM_TRUSTED_ROM_BASE	0x0
 
@@ -229,9 +239,9 @@
 
 #if TARGET_PLATFORM <= 2
 #define PLAT_ARM_DRAM2_BASE		ULL(0x8080000000)
-#elif TARGET_PLATFORM == 3
+#elif TARGET_PLATFORM >= 3
 #define PLAT_ARM_DRAM2_BASE		ULL(0x880000000)
-#endif /* TARGET_PLATFORM == 3 */
+#endif /* TARGET_PLATFORM >= 3 */
 #define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
 #define PLAT_ARM_DRAM2_END		(PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL)
 
@@ -293,9 +303,9 @@
 /* Message Handling Unit (MHU) base addresses */
 #if TARGET_PLATFORM <= 2
 	#define PLAT_CSS_MHU_BASE		UL(0x45400000)
-#elif TARGET_PLATFORM == 3
+#elif TARGET_PLATFORM >= 3
 	#define PLAT_CSS_MHU_BASE		UL(0x46000000)
-#endif /* TARGET_PLATFORM == 3 */
+#endif /* TARGET_PLATFORM >= 3 */
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
 /* AP<->RSS MHUs */
@@ -305,6 +315,9 @@
 #elif TARGET_PLATFORM == 3
 #define PLAT_RSE_AP_SND_MHU_BASE	UL(0x49000000)
 #define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x49100000)
+#elif TARGET_PLATFORM == 4
+#define PLAT_RSE_AP_SND_MHU_BASE	UL(0x49000000)
+#define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x49010000)
 #endif
 
 #define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
@@ -333,6 +346,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)
@@ -360,6 +374,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)
@@ -444,6 +459,21 @@
 #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..9adf09a 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,46 @@
 	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)
+
+func TC_HANDLER(4)
+	ret
+endfunc TC_HANDLER(4)
+
 	/* -----------------------------------------------------
 	 * 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/plat_tc_mbedtls_config.h b/plat/arm/board/tc/plat_tc_mbedtls_config.h
index de7b1aa..4fd8b6b 100644
--- a/plat/arm/board/tc/plat_tc_mbedtls_config.h
+++ b/plat/arm/board/tc/plat_tc_mbedtls_config.h
@@ -21,6 +21,20 @@
 #endif
 #endif /* TF_MBEDTLS_HEAP_SIZE */
 
+/**
+ * On Arm TC platforms, the ROTPK is always hashed using the SHA-256
+ * algorithm.
+ * TODO: Update to hash the ROTPK with the selected HASH_ALG to avoid
+ * the need for explicitly enabling the SHA-256 configuration in mbedTLS.
+ */
+#define MBEDTLS_SHA256_C
+
+/*
+ * Use an implementation of SHA-256 with a smaller memory footprint
+ * but reduced speed.
+ */
+#define MBEDTLS_SHA256_SMALLER
+
 #define MBEDTLS_PSA_CRYPTO_C
 #define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
 #define MBEDTLS_ECP_C
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 28b98c2..3ef25de 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -26,6 +26,9 @@
 ENABLE_FEAT_MPAM		:=	1 # default is 2, optimise
 ENABLE_SVE_FOR_NS		:=	2 # to show we use it
 ENABLE_SVE_FOR_SWD		:=	1
+ENABLE_SME_FOR_NS		:=	2
+ENABLE_SME2_FOR_NS		:=	2
+ENABLE_SME_FOR_SWD		:=	1
 ENABLE_TRBE_FOR_NS		:=	1
 ENABLE_SYS_REG_TRACE_FOR_NS	:=	1
 ENABLE_FEAT_AMU			:=	1
@@ -33,12 +36,14 @@
 ENABLE_AMU_AUXILIARY_COUNTERS	:=	1
 ENABLE_MPMM			:=	1
 ENABLE_MPMM_FCONF		:=	1
+ENABLE_FEAT_MTE2		:=	2
+ENABLE_SPE_FOR_NS		:=	3
+ENABLE_FEAT_TCR2		:=	3
 
 CTX_INCLUDE_AARCH32_REGS	:=	0
 
 ifeq (${SPD},spmd)
 	SPMD_SPM_AT_SEL2	:=	1
-	ENABLE_FEAT_MTE2	:=	1
 	CTX_INCLUDE_PAUTH_REGS	:=	1
 endif
 
@@ -60,8 +65,8 @@
           Some of the features might not work as expected)
 endif
 
-ifeq ($(shell expr $(TARGET_PLATFORM) \<= 3), 0)
-        $(error TARGET_PLATFORM must be less than or equal to 3)
+ifeq ($(shell expr $(TARGET_PLATFORM) \<= 4), 0)
+        $(error TARGET_PLATFORM must be less than or equal to 4)
 endif
 
 ifeq ($(filter ${TARGET_FLAVOUR}, fvp fpga),)
@@ -109,6 +114,9 @@
 
 # CPU libraries for TARGET_PLATFORM=2
 ifeq (${TARGET_PLATFORM}, 2)
+ERRATA_A520_2938996	:=	1
+ERRATA_X4_2726228	:=	1
+
 TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a520.S \
 			lib/cpus/aarch64/cortex_a720.S \
 			lib/cpus/aarch64/cortex_x4.S
@@ -116,12 +124,22 @@
 
 # CPU libraries for TARGET_PLATFORM=3
 ifeq (${TARGET_PLATFORM}, 3)
+ERRATA_A520_2938996	:=	1
+
 TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a520.S \
 			lib/cpus/aarch64/cortex_a725.S \
 			lib/cpus/aarch64/cortex_x925.S
 endif
 
+# CPU libraries for TARGET_PLATFORM=4
+ifeq (${TARGET_PLATFORM}, 4)
+TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_gelas.S \
+			lib/cpus/aarch64/nevis.S \
+			lib/cpus/aarch64/travis.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
@@ -129,6 +147,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
 
@@ -138,9 +157,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}			\
@@ -258,5 +280,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/platform_test.mk b/plat/arm/board/tc/platform_test.mk
index 8d39325..2ce6648 100644
--- a/plat/arm/board/tc/platform_test.mk
+++ b/plat/arm/board/tc/platform_test.mk
@@ -33,6 +33,7 @@
     $(eval $(call add_define,PLATFORM_TEST_ROTPK))
 else ifeq (${PLATFORM_TEST},tfm-testsuite)
     include drivers/arm/rse/rse_comms.mk
+    include drivers/measured_boot/rse/qcbor.mk
 
     # The variables need to be set to compile the platform test:
     ifeq (${TF_M_TESTS_PATH},)
@@ -80,7 +81,8 @@
 				$(DELEGATED_ATTEST_TESTS_PATH)/delegated_attest_test.c \
 				drivers/auth/mbedtls/mbedtls_common.c		\
 				lib/psa/measured_boot.c				\
-				lib/psa/delegated_attestation.c
+				lib/psa/delegated_attestation.c			\
+				${QCBOR_SOURCES}
 
     PLAT_INCLUDES	+=	-I$(TF_M_EXTRAS_PATH)/partitions/measured_boot/interface/include \
 				-I$(TF_M_EXTRAS_PATH)/partitions/delegated_attestation/interface/include \
@@ -93,7 +95,8 @@
 				-Iplat/arm/board/tc				\
 				-Iinclude/drivers/auth/mbedtls			\
 				-Iinclude/drivers/arm				\
-				-Iinclude/lib/psa
+				-Iinclude/lib/psa				\
+				-I${QCBOR_INCLUDES}
 
     # Some of the PSA functions are declared in multiple header files, that
     # triggers this warning.
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_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 7d1bc9c..801872a 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -58,7 +58,7 @@
 	.db_modify_mask = 0x1,
 	.ring_doorbell = &mhuv2_ring_doorbell,
 };
-#elif TARGET_PLATFORM == 3
+#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),
@@ -66,7 +66,9 @@
 	.db_modify_mask = 0x1,
 	.ring_doorbell = &mhu_ring_doorbell,
 };
+#endif
 
+#if TARGET_PLATFORM == 3
 static void enable_ns_mcn_pmu(void)
 {
 	/*
@@ -110,6 +112,7 @@
 #if TARGET_PLATFORM == 3
 	enable_ns_mcn_pmu();
 	set_mcn_slc_alloc_mode();
+	plat_arm_ni_setup(NCI_BASE_ADDR);
 #endif
 }
 
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_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index 01e0db0..869830d 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_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.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,8 @@
 
 #include <drivers/generic_delay_timer.h>
 #include <drivers/partition/partition.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
@@ -64,6 +66,43 @@
 	generic_delay_timer_init();
 }
 
+#if ARM_FW_CONFIG_LOAD_ENABLE
+/*************************************************************************************
+ * FW CONFIG load function for BL2 when RESET_TO_BL2=1 && ARM_FW_CONFIG_LOAD_ENABLE=1
+ *************************************************************************************/
+void arm_bl2_el3_plat_config_load(void)
+{
+	int ret;
+	const struct dyn_cfg_dtb_info_t *fw_config_info;
+
+	/* Set global DTB info for fixed fw_config information */
+	set_config_info(PLAT_FW_CONFIG_BASE, ~0UL, PLAT_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID);
+
+	/* Fill the device tree information struct with the info from the config dtb */
+	ret = fconf_load_config(FW_CONFIG_ID);
+	if (ret < 0) {
+		ERROR("Loading of FW_CONFIG failed %d\n", ret);
+		plat_error_handler(ret);
+	}
+
+	/*
+	 * FW_CONFIG loaded successfully. Check the FW_CONFIG device tree parsing
+	 * is successful.
+	 */
+	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+	if (fw_config_info == NULL) {
+		ret = -1;
+		ERROR("Invalid FW_CONFIG address\n");
+		plat_error_handler(ret);
+	}
+	ret = fconf_populate_dtb_registry(fw_config_info->config_addr);
+	if (ret < 0) {
+		ERROR("Parsing of FW_CONFIG failed %d\n", ret);
+		plat_error_handler(ret);
+	}
+}
+#endif /* ARM_FW_CONFIG_LOAD_ENABLE */
+
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
  * moment this is only initializes the mmu in a quick and dirty way.
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 58a14ab..90ee70c 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -42,7 +42,7 @@
 #if TRANSFER_LIST
 CASSERT(BL2_BASE >= PLAT_ARM_EL3_FW_HANDOFF_BASE + PLAT_ARM_FW_HANDOFF_SIZE,
 	assert_bl2_base_overflows);
-#else
+#elif !RESET_TO_BL2
 CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
 #endif /* TRANSFER_LIST */
 
@@ -140,6 +140,9 @@
 
 	arm_transfer_list_dyn_cfg_init(secure_tl);
 #else
+#if ARM_FW_CONFIG_LOAD_ENABLE
+	arm_bl2_el3_plat_config_load();
+#endif /* ARM_FW_CONFIG_LOAD_ENABLE */
 	arm_bl2_dyn_cfg_init();
 #endif
 
@@ -162,16 +165,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 +319,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 +329,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..3650854 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
@@ -25,6 +26,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 +98,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 +136,23 @@
 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 = PLAT_ARM_TRANSFER_LIST_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
@@ -480,6 +545,13 @@
 	enable_mmu_el3(0);
 
 #if ENABLE_RME
+#if RESET_TO_BL31
+	/*  initialize GPT only when RME is enabled. */
+	assert(is_feat_rme_present());
+
+	/* Initialise and enable granule protection after MMU. */
+	arm_gpt_setup();
+#endif /* RESET_TO_BL31 */
 	/*
 	 * Initialise Granule Protection library and enable GPC for the primary
 	 * processor. The tables have already been initialized by a previous BL
@@ -497,15 +569,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 f5919ab..2fd993c 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -119,10 +119,6 @@
   endif
 endif
 
-# Use an implementation of SHA-256 with a smaller memory footprint but reduced
-# speed.
-$(eval $(call add_define,MBEDTLS_SHA256_SMALLER))
-
 # Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
 # in the FIP if the platform requires.
 ifneq ($(BL32_EXTRA1),)
@@ -168,6 +164,25 @@
 	ENABLE_PIE			:=	1
 endif
 
+# On Arm platform, disable ARM_FW_CONFIG_LOAD_ENABLE by default.
+ARM_FW_CONFIG_LOAD_ENABLE		:= 0
+$(eval $(call assert_boolean,ARM_FW_CONFIG_LOAD_ENABLE))
+$(eval $(call add_define,ARM_FW_CONFIG_LOAD_ENABLE))
+
+# In order to enable ARM_FW_CONFIG_LOAD_ENABLE for the Arm platform, the
+# platform should be reset to BL2 (RESET_TO_BL2=1), and FW_CONFIG must be
+# specified.
+ifeq (${ARM_FW_CONFIG_LOAD_ENABLE},1)
+    ifneq (${RESET_TO_BL2},1)
+        $(error RESET_TO_BL2 must be enabled when ARM_FW_CONFIG_LOAD_ENABLE \
+            is enabled)
+    endif
+    ifeq (${FW_CONFIG},)
+        $(error FW_CONFIG must be specified when ARM_FW_CONFIG_LOAD_ENABLE \
+            is enabled)
+    endif
+endif
+
 # Disable GPT parser support, use FIP image by default
 ARM_GPT_SUPPORT			:=	0
 $(eval $(call assert_boolean,ARM_GPT_SUPPORT))
@@ -279,7 +294,7 @@
 ifeq (${JUNO_AARCH32_EL3_RUNTIME},1)
 BL2_SOURCES		+=	plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
 else
-ifneq (${PLAT}, corstone1000)
+ifeq ($(filter $(PLAT), corstone1000 rd1ae),)
 BL2_SOURCES		+=	plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c
 endif
 endif
@@ -364,6 +379,17 @@
 BL31_SOURCES            +=	plat/arm/common/arm_err.c
 endif
 
+ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT} ${DRTM_SUPPORT}),)
+    PLAT_INCLUDES		+=	-Iplat/arm/common	\
+					-Iinclude/drivers/auth/mbedtls
+    # Specify mbed TLS configuration file
+    ifeq (${PSA_CRYPTO},1)
+      MBEDTLS_CONFIG_FILE	?=	"<plat_arm_psa_mbedtls_config.h>"
+    else
+      MBEDTLS_CONFIG_FILE	?=	"<plat_arm_mbedtls_config.h>"
+    endif
+endif
+
 ifneq (${TRUSTED_BOARD_BOOT},0)
 
     # Include common TBB sources
@@ -377,30 +403,37 @@
         ifneq (${COT_DESC_IN_DTB},0)
             BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
         else
-            BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_common.c
 	    # Juno has its own TBBR CoT file for BL2
-            ifneq (${PLAT},juno)
-                BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_bl2.c
+            ifeq (${PLAT},juno)
+                BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_common.c
             endif
         endif
     else ifeq (${COT},dualroot)
-        BL1_SOURCES	+=	drivers/auth/dualroot/cot.c
+        BL1_SOURCES	+=	drivers/auth/dualroot/bl1_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
+        BL1_SOURCES	+=	drivers/auth/cca/bl1_cot.c
         ifneq (${COT_DESC_IN_DTB},0)
             BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
-        else
-            BL2_SOURCES	+=	drivers/auth/cca/cot.c
         endif
     else
         $(error Unknown chain of trust ${COT})
     endif
 
+    ifeq (${COT_DESC_IN_DTB},0)
+      ifeq (${COT},dualroot)
+        COTDTPATH := fdts/dualroot_cot_descriptors.dtsi
+      else ifeq (${COT},cca)
+        COTDTPATH := fdts/cca_cot_descriptors.dtsi
+      else ifeq (${COT},tbbr)
+        ifneq (${PLAT},juno)
+          COTDTPATH := fdts/tbbr_cot_descriptors.dtsi
+        endif
+      endif
+    endif
+
     BL1_SOURCES		+=	${AUTH_SOURCES}					\
 				bl1/tbbr/tbbr_img_desc.c			\
 				plat/arm/common/arm_bl1_fwu.c			\
@@ -425,10 +458,6 @@
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
 
-    ifneq (${MBOOT_EL_HASH_ALG}, sha256)
-        $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
-    endif
-
     ifeq (${MEASURED_BOOT},1)
          BL1_SOURCES		+= 	${EVENT_LOG_SOURCES}
          BL2_SOURCES		+= 	${EVENT_LOG_SOURCES}
@@ -458,3 +487,24 @@
         $(error To reclaim init code xlat tables v2 must be used)
     endif
 endif
+
+ifneq ($(COTDTPATH),)
+        cot-dt-defines = IMAGE_BL2 $(BL2_DEFINES) $(PLAT_BL_COMMON_DEFINES)
+        cot-dt-include-dirs = $(BL2_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS)
+
+        cot-dt-cpp-flags  = $(cot-dt-defines:%=-D%)
+        cot-dt-cpp-flags += $(cot-dt-include-dirs:%=-I%)
+
+        cot-dt-cpp-flags += $(BL2_CPPFLAGS) $(PLAT_BL_COMMON_CPPFLAGS)
+        cot-dt-cpp-flags += $(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH))
+        cot-dt-cpp-flags += -c -x assembler-with-cpp -E -P -o $@ $<
+
+        $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.dts): $(COTDTPATH) | $$(@D)/
+		$(q)$($(ARCH)-cpp) $(cot-dt-cpp-flags)
+
+        $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.c): $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.dts) | $$(@D)/
+		$(if $(host-poetry),$(q)poetry -q install)
+		$(q)$(if $(host-poetry),poetry run )cot-dt2c convert-to-c $< $@
+
+        BL2_SOURCES += $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.c)
+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/plat_arm_mbedtls_config.h b/plat/arm/common/plat_arm_mbedtls_config.h
new file mode 100644
index 0000000..a5d0ec4
--- /dev/null
+++ b/plat/arm/common/plat_arm_mbedtls_config.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_ARM_MBEDTLS_CONFIG_H
+#define PLAT_ARM_MBEDTLS_CONFIG_H
+
+#include <mbedtls_config-3.h>
+
+/**
+ * On Arm platforms, the ROTPK is always hashed using the SHA-256
+ * algorithm.
+ * TODO: Update to hash the ROTPK with the selected HASH_ALG to avoid
+ * the need for explicitly enabling the SHA-256 configuration in mbedTLS.
+ */
+#define MBEDTLS_SHA256_C
+
+/*
+ * Use an implementation of SHA-256 with a smaller memory footprint
+ * but reduced speed.
+ */
+#define MBEDTLS_SHA256_SMALLER
+
+#endif /* PLAT_ARM_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/common/plat_arm_psa_mbedtls_config.h b/plat/arm/common/plat_arm_psa_mbedtls_config.h
new file mode 100644
index 0000000..fd434c9
--- /dev/null
+++ b/plat/arm/common/plat_arm_psa_mbedtls_config.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_ARM_PSA_MBEDTLS_CONFIG_H
+#define PLAT_ARM_PSA_MBEDTLS_CONFIG_H
+
+#include "plat_arm_mbedtls_config.h"
+
+#define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
+
+/*
+ * Using PSA crypto API requires an RNG right now. If we don't define the macro
+ * below then we get build errors.
+ *
+ * This is a functionality gap in mbedTLS. The technical limitation is that
+ * psa_crypto_init() is all-or-nothing, and fixing that would require separate
+ * initialization of the keystore, the RNG, etc.
+ *
+ * By defining MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG, we pretend using an external
+ * RNG. As a result, the PSA crypto init code does nothing when it comes to
+ * initializing the RNG, as we are supposed to take care of that ourselves.
+ */
+#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+
+#endif /* PLAT_ARM_PSA_MBEDTLS_CONFIG_H */
diff --git a/plat/aspeed/ast2700/plat_bl31_setup.c b/plat/aspeed/ast2700/plat_bl31_setup.c
index 9fec3e8..087b479 100644
--- a/plat/aspeed/ast2700/plat_bl31_setup.c
+++ b/plat/aspeed/ast2700/plat_bl31_setup.c
@@ -174,7 +174,7 @@
 			break;
 		}
 	} else {
-		if (pll_reg.b.bypass != 0U) {
+		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));
diff --git a/plat/hisilicon/poplar/include/hi3798cv200.h b/plat/hisilicon/poplar/include/hi3798cv200.h
index e31f4b3..802dec5 100644
--- a/plat/hisilicon/poplar/include/hi3798cv200.h
+++ b/plat/hisilicon/poplar/include/hi3798cv200.h
@@ -38,7 +38,11 @@
 
 /* SCTL */
 #define REG_BASE_SCTL			(0xF8000000)
+#define REG_SC_SYSRES			(0x0004)
 #define REG_SC_GEN12			(0x00B0)
+#define REG_SC_LOCKEN			(0x020C)
+
+#define SC_UNLOCK_MAGIC			(0x4F50454E)
 
 /* CRG */
 #define REG_BASE_CRG			(0xF8A22000)
diff --git a/plat/hisilicon/poplar/plat_pm.c b/plat/hisilicon/poplar/plat_pm.c
index 67ebca1..77fc532 100644
--- a/plat/hisilicon/poplar/plat_pm.c
+++ b/plat/hisilicon/poplar/plat_pm.c
@@ -92,14 +92,18 @@
 static void __dead2 poplar_system_off(void)
 {
 	ERROR("Poplar System Off: operation not handled.\n");
+	/* Turn off watchdog0 before panic() */
+	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0xc00), 0x1ACCE551);
+	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x8),   0x00000000);
 	panic();
 }
 
 static void __dead2 poplar_system_reset(void)
 {
-	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0xc00), 0x1ACCE551);
-	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x0),   0x00000100);
-	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x8),   0x00000003);
+	/* Unlock Sysctrl critical registers */
+	mmio_write_32((uintptr_t)(REG_BASE_SCTL + REG_SC_LOCKEN), SC_UNLOCK_MAGIC);
+	/* Assert system reset */
+	mmio_write_32((uintptr_t)(REG_BASE_SCTL + REG_SC_SYSRES), 0xfee1dead);
 
 	wfi();
 	ERROR("Poplar System Reset: operation not handled.\n");
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index 950d8fd..2bda3a5 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -71,7 +71,6 @@
 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)
 
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 40554c3..d1c1259 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -127,7 +127,6 @@
 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)
 
@@ -189,10 +188,6 @@
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
 
-ifneq (${MBOOT_EL_HASH_ALG}, sha256)
-    $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
-endif
-
 BL2_SOURCES		+=	plat/imx/imx8m/imx8m_measured_boot.c	\
 				plat/imx/imx8m/imx8m_dyn_cfg_helpers.c	\
 				${EVENT_LOG_SOURCES}
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 5f4ddee..5df598c 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -124,7 +124,6 @@
 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)
 
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 61c0ef2..084539e 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,6 +31,7 @@
 #include "socfpga_reset_manager.h"
 #include "socfpga_ros.h"
 #include "socfpga_system_manager.h"
+#include "socfpga_vab.h"
 #include "wdt/watchdog.h"
 
 static struct mmc_device_info mmc_info;
@@ -112,7 +114,10 @@
 
 	setup_page_tables(bl_regions, agilex_plat_mmap);
 
-	enable_mmu_el3(0);
+	/*
+	 * TODO: mmu enable in latest phase
+	 */
+	// enable_mmu_el3(0);
 
 	dw_mmc_params_t params = EMMC_INIT_PARAMS(0x100000, get_mmc_clk());
 
@@ -124,11 +129,13 @@
 
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
+		NOTICE("SDMMC boot\n");
 		dw_mmc_init(&params, &mmc_info);
 		socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
 		break;
 
 	case BOOT_SOURCE_QSPI:
+		NOTICE("QSPI boot\n");
 		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
 			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
 			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
@@ -173,6 +180,20 @@
 
 	assert(bl_mem_params);
 
+#if SOCFPGA_SECURE_VAB_AUTH
+	/*
+	 * VAB Authentication start here.
+	 * If failed to authenticate, shall not proceed to process BL31 and hang.
+	 */
+	int ret = 0;
+
+	ret = socfpga_vab_init(image_id);
+	if (ret < 0) {
+		ERROR("SOCFPGA VAB Authentication failed\n");
+		wfi();
+	}
+#endif
+
 	switch (image_id) {
 	case BL33_IMAGE_ID:
 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
@@ -191,4 +212,3 @@
 void bl2_platform_setup(void)
 {
 }
-
diff --git a/plat/intel/soc/agilex/include/agilex_memory_controller.h b/plat/intel/soc/agilex/include/agilex_memory_controller.h
index 9db4292..f0bbeea 100644
--- a/plat/intel/soc/agilex/include/agilex_memory_controller.h
+++ b/plat/intel/soc/agilex/include/agilex_memory_controller.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +28,7 @@
 #define AGX_MPFE_HMC_ADP_ECCCTRL1			0xf8011100
 #define AGX_MPFE_HMC_ADP_ECCCTRL2			0xf8011104
 #define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT		0xf8011218
-#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x000000ff
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x0000000f
 #define AGX_MPFE_HMC_ADP_RSTHANDSHAKECTRL		0xf8011214
 
 
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 9ef7598..4e3397f 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +19,7 @@
 #define PLAT_PRIMARY_CPU			0
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
 #define PLAT_CPU_ID_MPIDR_AFF_SHIFT		MPIDR_AFF0_SHIFT
+#define PLAT_TIMER_BASE_ADDR			0xFFD01000
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 6780845..21cc6a3 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -1,6 +1,7 @@
 #
 # Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2024, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -27,6 +28,7 @@
 			plat/intel/soc/common/aarch64/platform_common.c \
 			plat/intel/soc/common/aarch64/plat_helpers.S	\
 			plat/intel/soc/common/drivers/ccu/ncore_ccu.c	\
+			plat/intel/soc/common/lib/sha/sha.c				\
 			plat/intel/soc/common/socfpga_delay_timer.c
 
 BL2_SOURCES     +=	\
@@ -49,6 +51,7 @@
 		plat/intel/soc/common/socfpga_image_load.c		\
 		plat/intel/soc/common/socfpga_ros.c			\
 		plat/intel/soc/common/socfpga_storage.c			\
+		plat/intel/soc/common/socfpga_vab.c				\
 		plat/intel/soc/common/soc/socfpga_emac.c		\
 		plat/intel/soc/common/soc/socfpga_firewall.c	\
 		plat/intel/soc/common/soc/socfpga_handoff.c		\
@@ -78,9 +81,20 @@
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33	:=	0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
+# Configs for VAB Authentication
+SOCFPGA_SECURE_VAB_AUTH  := 	0
+$(eval $(call assert_boolean,SOCFPGA_SECURE_VAB_AUTH))
+$(eval $(call add_define,SOCFPGA_SECURE_VAB_AUTH))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
 USE_COHERENT_MEM		:= 1
+
+HANDLE_EA_EL3_FIRST_NS			:= 1
\ No newline at end of file
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
index c74d799..b75c78c 100644
--- a/plat/intel/soc/agilex5/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl2_plat_setup.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2021, 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
  */
@@ -19,9 +20,11 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 #include "agilex5_clock_manager.h"
+#include "agilex5_ddr.h"
 #include "agilex5_memory_controller.h"
 #include "agilex5_mmc.h"
 #include "agilex5_pinmux.h"
+#include "agilex5_power_manager.h"
 #include "agilex5_system_manager.h"
 #include "ccu/ncore_ccu.h"
 #include "combophy/combophy.h"
@@ -35,6 +38,7 @@
 #include "socfpga_private.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_ros.h"
+#include "socfpga_vab.h"
 #include "wdt/watchdog.h"
 
 
@@ -68,29 +72,50 @@
 				u_register_t x2, u_register_t x4)
 {
 	static console_t console;
+	handoff reverse_handoff_ptr;
+
+	/* Enable nonsecure access for peripherals and other misc components */
+	enable_nonsecure_access();
 
-	handoff reverse_handoff_ptr = { 0 };
+	/* Bring all the required peripherals out of reset */
+	deassert_peripheral_reset();
 
+	/*
+	 * Initialize the UART console early in BL2 EL3 boot flow to get
+	 * the error/notice messages wherever required.
+	 */
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+			       PLAT_BAUDRATE, &console);
+
+	/* Generic delay timer init */
 	generic_delay_timer_init();
+
+	socfpga_delay_timer_init();
+
+	/* Get the handoff data */
+	if ((socfpga_get_handoff(&reverse_handoff_ptr)) != 0) {
+		ERROR("BL2: Failed to get the correct handoff data\n");
+		panic();
+	}
+
 	config_clkmgr_handoff(&reverse_handoff_ptr);
+	/* Configure power manager PSS SRAM power gate */
+	config_pwrmgr_handoff(&reverse_handoff_ptr);
+
+	/* Initialize the mailbox to enable communication between HPS and SDM */
 	mailbox_init();
-	enable_nonsecure_access();
 
-	deassert_peripheral_reset();
+	/* DDR and IOSSM driver init */
+	agilex5_ddr_init(&reverse_handoff_ptr);
+
 	if (combo_phy_init(&reverse_handoff_ptr) != 0) {
 		ERROR("Combo Phy initialization failed\n");
 	}
 
-	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
-	PLAT_BAUDRATE, &console);
-
-	/* Store magic number */
-	// TODO: Temp workaround to ungate testing
-	// mmio_write_32(L2_RESET_DONE_REG, PLAT_L2_RESET_REQ);
-
+	/* Enable FPGA bridges as required */
 	if (!intel_mailbox_is_fpga_not_ready()) {
 		socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
-					FPGA2SOC_MASK | F2SDRAM0_MASK);
+				       FPGA2SOC_MASK | F2SDRAM0_MASK);
 	}
 }
 
@@ -165,6 +190,20 @@
 
 	assert(bl_mem_params);
 
+#if SOCFPGA_SECURE_VAB_AUTH
+	/*
+	 * VAB Authentication start here.
+	 * If failed to authenticate, shall not proceed to process BL31 and hang.
+	 */
+	int ret = 0;
+
+	ret = socfpga_vab_init(image_id);
+	if (ret < 0) {
+		ERROR("SOCFPGA VAB Authentication failed\n");
+		wfi();
+	}
+#endif
+
 	switch (image_id) {
 	case BL33_IMAGE_ID:
 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index 8d3928f..b6fc93e 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2024, 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
  */
@@ -17,6 +18,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
+#include "agilex5_cache.h"
 #include "agilex5_power_manager.h"
 #include "ccu/ncore_ccu.h"
 #include "socfpga_mailbox.h"
@@ -56,9 +58,8 @@
 	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
 
 	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
-	PLAT_BAUDRATE, &console);
+			       PLAT_BAUDRATE, &console);
 
-	init_ncore_ccu();
 	setup_smmu_stream_id();
 
 	/*
@@ -189,11 +190,12 @@
 	uint32_t boot_core = 0x00;
 	uint32_t cpuid = 0x00;
 
-	cpuid = read_mpidr();
-	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+	cpuid = MPIDR_AFFLVL1_VAL(read_mpidr());
+	boot_core = ((mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00) >> 10);
 	NOTICE("BL31: Boot Core = %x\n", boot_core);
 	NOTICE("BL31: CPU ID = %x\n", cpuid);
-
+	INFO("BL31: Invalidate Data cache\n");
+	invalidate_dcache_all();
 }
 
 /* Get non-secure image entrypoint for BL33. Zephyr and Linux */
diff --git a/plat/intel/soc/agilex5/include/agilex5_cache.h b/plat/intel/soc/agilex5/include/agilex5_cache.h
new file mode 100644
index 0000000..095d99e
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_cache.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGX5_CACHE_H
+#define AGX5_CACHE_H
+
+void invalidate_dcache_all(void);
+
+#endif /* AGX5_CACHE_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_ddr.h b/plat/intel/soc/agilex5/include/agilex5_ddr.h
new file mode 100644
index 0000000..631e006
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_ddr.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGILEX5_DDR_H
+#define AGILEX5_DDR_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <lib/utils_def.h>
+
+#include "socfpga_handoff.h"
+
+#define CONFIG_NR_DRAM_BANKS	1
+
+typedef unsigned long long phys_addr_t;
+typedef unsigned long long phys_size_t;
+typedef phys_addr_t fdt_addr_t;
+
+/* DDR/RAM configuration */
+struct ddr_info {
+	phys_addr_t start;
+	phys_size_t size;
+};
+
+int agilex5_ddr_init(handoff *hoff_ptr);
+
+#endif /* AGILEX5_DDR_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h b/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h
new file mode 100644
index 0000000..1fd8ef6
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGILEX5_IOSSM_MAILBOX_H
+#define AGILEX5_IOSSM_MAILBOX_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "lib/mmio.h"
+#include "agilex5_ddr.h"
+
+#define TIMEOUT_5000MS					5000
+#define TIMEOUT						TIMEOUT_5000MS
+#define IOSSM_STATUS_CAL_SUCCESS			BIT(0)
+#define IOSSM_STATUS_CAL_FAIL				BIT(1)
+#define IOSSM_STATUS_CAL_BUSY				BIT(2)
+#define IOSSM_STATUS_COMMAND_RESPONSE_READY		1
+#define IOSSM_CMD_RESPONSE_STATUS_OFFSET		0x45C
+#define IOSSM_CMD_RESPONSE_DATA_0_OFFSET		0x458
+#define IOSSM_CMD_RESPONSE_DATA_1_OFFSET		0x454
+#define IOSSM_CMD_RESPONSE_DATA_2_OFFSET		0x450
+#define IOSSM_CMD_REQ_OFFSET				0x43C
+#define IOSSM_CMD_PARAM_0_OFFSET			0x438
+#define IOSSM_CMD_PARAM_1_OFFSET			0x434
+#define IOSSM_CMD_PARAM_2_OFFSET			0x430
+#define IOSSM_CMD_PARAM_3_OFFSET			0x42C
+#define IOSSM_CMD_PARAM_4_OFFSET			0x428
+#define IOSSM_CMD_PARAM_5_OFFSET			0x424
+#define IOSSM_CMD_PARAM_6_OFFSET			0x420
+#define IOSSM_STATUS_OFFSET				0x400
+#define IOSSM_CMD_RESPONSE_DATA_SHORT_MASK		GENMASK(31, 16)
+#define IOSSM_CMD_RESPONSE_DATA_SHORT(data)		(((data) & \
+							IOSSM_CMD_RESPONSE_DATA_SHORT_MASK) >> 16)
+#define MAX_IO96B_SUPPORTED				2
+#define MAX_MEM_INTERFACES_SUPPORTED			2
+
+/* supported mailbox command type */
+enum iossm_mailbox_cmd_type  {
+	CMD_NOP,
+	CMD_GET_SYS_INFO,
+	CMD_GET_MEM_INFO,
+	CMD_GET_MEM_CAL_INFO,
+	CMD_TRIG_CONTROLLER_OP,
+	CMD_TRIG_MEM_CAL_OP
+};
+
+/* supported mailbox command opcode */
+enum iossm_mailbox_cmd_opcode  {
+	GET_MEM_INTF_INFO = 0x0001,
+	GET_MEM_TECHNOLOGY,
+	GET_MEMCLK_FREQ_KHZ,
+	GET_MEM_WIDTH_INFO,
+	ECC_ENABLE_SET = 0x0101,
+	ECC_ENABLE_STATUS,
+	ECC_INTERRUPT_STATUS,
+	ECC_INTERRUPT_ACK,
+	ECC_INTERRUPT_MASK,
+	ECC_WRITEBACK_ENABLE,
+	ECC_SCRUB_IN_PROGRESS_STATUS = 0x0201,
+	ECC_SCRUB_MODE_0_START,
+	ECC_SCRUB_MODE_1_START,
+	BIST_STANDARD_MODE_START = 0x0301,
+	BIST_RESULTS_STATUS,
+	BIST_MEM_INIT_START,
+	BIST_MEM_INIT_STATUS,
+	BIST_SET_DATA_PATTERN_UPPER,
+	BIST_SET_DATA_PATTERN_LOWER,
+	TRIG_MEM_CAL = 0x000a,
+	GET_MEM_CAL_STATUS
+};
+
+/*
+ * IOSSM mailbox required information
+ *
+ * @num_mem_interface:	Number of memory interfaces instantiated
+ * @ip_type:		IP type implemented on the IO96B
+ * @ip_instance_id:	IP identifier for every IP instance implemented on the IO96B
+ */
+struct io96b_mb_ctrl {
+	uint32_t num_mem_interface;
+	uint32_t ip_type[2];
+	uint32_t ip_instance_id[2];
+};
+
+/*
+ * IOSSM mailbox response outputs
+ *
+ * @cmd_resp_status: Command Interface status
+ * @cmd_resp_data_*: More spaces for command response
+ */
+struct io96b_mb_resp {
+	uint32_t cmd_resp_status;
+	uint32_t cmd_resp_data_0;
+	uint32_t cmd_resp_data_1;
+	uint32_t cmd_resp_data_2;
+};
+
+/*
+ * IO96B instance specific information
+ *
+ * @size:		Memory size
+ * @io96b_csr_addr:	IO96B instance CSR address
+ * @cal_status:		IO96B instance calibration status
+ * @mb_ctrl:		IOSSM mailbox required information
+ */
+struct io96b_instance {
+	uint16_t size;
+	phys_addr_t io96b_csr_addr;
+	bool cal_status;
+	struct io96b_mb_ctrl mb_ctrl;
+};
+
+/*
+ * Overall IO96B instance(s) information
+ *
+ * @num_instance:	Number of instance(s) assigned to HPS
+ * @overall_cal_status: Overall calibration status for all IO96B instance(s)
+ * @ddr_type:		DDR memory type
+ * @ecc_status:		ECC enable status (false = disabled, true = enabled)
+ * @overall_size:	Total DDR memory size
+ * @io96b_0:		IO96B 0 instance specific information
+ * @io96b_1:		IO96B 1 instance specific information
+ */
+struct io96b_info {
+	uint8_t num_instance;
+	bool overall_cal_status;
+	const char *ddr_type;
+	bool ecc_status;
+	uint16_t overall_size;
+	struct io96b_instance io96b_0;
+	struct io96b_instance io96b_1;
+};
+
+int io96b_mb_req(phys_addr_t io96b_csr_addr, uint32_t ip_type, uint32_t instance_id,
+		 uint32_t usr_cmd_type, uint32_t usr_cmd_opcode, uint32_t cmd_param_0,
+		 uint32_t cmd_param_1, uint32_t cmd_param_2, uint32_t cmd_param_3,
+		 uint32_t cmd_param_4, uint32_t cmd_param_5, uint32_t cmd_param_6,
+		 uint32_t resp_data_len, struct io96b_mb_resp *resp);
+
+/* Supported IOSSM mailbox function */
+void io96b_mb_init(struct io96b_info *io96b_ctrl);
+int io96b_cal_status(phys_addr_t addr);
+void init_mem_cal(struct io96b_info *io96b_ctrl);
+int trig_mem_cal(struct io96b_info *io96b_ctrl);
+int get_mem_technology(struct io96b_info *io96b_ctrl);
+int get_mem_width_info(struct io96b_info *io96b_ctrl);
+int ecc_enable_status(struct io96b_info *io96b_ctrl);
+int bist_mem_init_start(struct io96b_info *io96b_ctrl);
+
+#endif /* AGILEX5_IOSSM_MAILBOX_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_power_manager.h b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
index 1bba74b..178fd5b 100644
--- a/plat/intel/soc/agilex5/include/agilex5_power_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -77,7 +78,5 @@
 #define AGX5_PWRMGR_PSS_STAT_BUSY_E_BUSY			0x0
 #define AGX5_PWRMGR_PSS_STAT_BUSY(x)				(((x) & 0x000000FF) >> 0)
 
-int pss_sram_power_off(handoff *hoff_ptr);
-int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff);
-
+void config_pwrmgr_handoff(handoff *hoff_ptr);
 #endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_system_manager.h b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
index 46596bf..75ae78a 100644
--- a/plat/intel/soc/agilex5/include/agilex5_system_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +25,7 @@
 #define SOCFPGA_SYSMGR_TSN_0_ACE					0x50
 #define SOCFPGA_SYSMGR_TSN_1_ACE					0x54
 #define SOCFPGA_SYSMGR_TSN_2_ACE					0x58
+#define SOCFPGA_SYSMGR_FPGA_BRIDGE_CTRL				0x5C
 #define SOCFPGA_SYSMGR_FPGAINTF_EN_1					0x68
 #define SOCFPGA_SYSMGR_FPGAINTF_EN_2					0x6C
 #define SOCFPGA_SYSMGR_FPGAINTF_EN_3					0x70
@@ -147,6 +149,7 @@
 
 /* QSPI ECC from SDM register */
 #define SOCFPGA_ECC_QSPI_CTRL						0x08
+#define SOCFPGA_ECC_QSPI_INITSTAT					0x0C
 #define SOCFPGA_ECC_QSPI_ERRINTEN					0x10
 #define SOCFPGA_ECC_QSPI_ERRINTENS					0x14
 #define SOCFPGA_ECC_QSPI_ERRINTENR					0x18
@@ -187,6 +190,8 @@
 #define SYSMGR_SDMMC_SMPLSEL(x)						(((x) & 0x7) << 4)
 
 #define SYSMGR_F2S_BRIDGE_CTRL_EN					BIT(0)
+#define SYSMGR_SOC_BRIDGE_CTRL_EN					BIT(0)
+#define SYSMGR_LWSOC_BRIDGE_CTRL_EN					BIT(1)
 #define IDLE_DATA_LWSOC2FPGA						BIT(4)
 #define IDLE_DATA_SOC2FPGA						BIT(0)
 #define IDLE_DATA_MASK							(IDLE_DATA_LWSOC2FPGA \
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
index acdbe17..5789261 100644
--- a/plat/intel/soc/agilex5/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +11,7 @@
 
 #include "agilex5_memory_controller.h"
 #include "agilex5_system_manager.h"
+
 #include <platform_def.h>
 
 /* Platform Setting */
@@ -21,18 +23,19 @@
 #define PLAT_PRIMARY_CPU_A76					0x200
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT				MPIDR_AFF2_SHIFT
 #define PLAT_CPU_ID_MPIDR_AFF_SHIFT				MPIDR_AFF1_SHIFT
-#define PLAT_L2_RESET_REQ			0xB007C0DE
+#define PLAT_L2_RESET_REQ					0xB007C0DE
+#define PLAT_TIMER_BASE_ADDR					0x10D01000
 
 /* System Counter */
 /* TODO: Update back to 400MHz.
  * This shall be updated to read from L4 clock instead of hardcoded.
  */
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS				(400000000)
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ				(400)
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS				U(400000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ				U(400)
 
 /* FPGA config helpers */
-#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR				0x400000
-#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE				0x2000000
+#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR				0x80400000
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE				0x82000000
 
 /* QSPI Setting */
 #define CAD_QSPIDATA_OFST					0x10900000
@@ -87,11 +90,10 @@
 #define GIC_SIZE						(0x00100000)
 
 #define BL2_BASE						(0x00000000)
-#define BL2_LIMIT						(0x0002b000)
+#define BL2_LIMIT						(0x0007E000)
 
 #define BL31_BASE						(0x80000000)
 #define BL31_LIMIT						(0x82000000)
-
 /*******************************************************************************
  * UART related constants
  ******************************************************************************/
@@ -101,7 +103,7 @@
 /*******************************************************************************
  * WDT related constants
  ******************************************************************************/
-#define WDT_BASE			(0x10D00200)
+#define WDT_BASE						(0x10D00200)
 
 /*******************************************************************************
  * GIC related constants
@@ -116,13 +118,13 @@
 /*******************************************************************************
  * SDMMC related pointer function
  ******************************************************************************/
-#define SDMMC_READ_BLOCKS	sdmmc_read_blocks
-#define SDMMC_WRITE_BLOCKS	sdmmc_write_blocks
+#define SDMMC_READ_BLOCKS					sdmmc_read_blocks
+#define SDMMC_WRITE_BLOCKS					sdmmc_write_blocks
 
 /*******************************************************************************
  * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
  * is done and HPS should trigger warm reset via RMR_EL3.
  ******************************************************************************/
-#define L2_RESET_DONE_REG			0x10D12218
+#define L2_RESET_DONE_REG					0x10D12218
 
 #endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
index 7302164..4bb90d5 100644
--- a/plat/intel/soc/agilex5/platform.mk
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -1,6 +1,7 @@
 #
 # Copyright (c) 2019-2020, 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
 #
@@ -8,6 +9,7 @@
 PLAT_INCLUDES		:=	\
 			-Iplat/intel/soc/agilex5/include/		\
 			-Iplat/intel/soc/common/drivers/		\
+			-Iplat/intel/soc/common/lib/sha/		\
 			-Iplat/intel/soc/common/include/
 
 # GIC-600 configuration
@@ -33,6 +35,7 @@
 			plat/intel/soc/common/drivers/sdmmc/sdmmc.c			\
 			plat/intel/soc/common/drivers/ddr/ddr.c			\
 			plat/intel/soc/common/drivers/nand/nand.c			\
+			plat/intel/soc/common/lib/sha/sha.c				\
 			plat/intel/soc/common/socfpga_delay_timer.c
 
 BL2_SOURCES		+=	\
@@ -55,14 +58,16 @@
 		lib/cpus/aarch64/cortex_a76.S				\
 		plat/intel/soc/agilex5/soc/agilex5_clock_manager.c	\
 		plat/intel/soc/agilex5/soc/agilex5_memory_controller.c	\
-		plat/intel/soc/agilex5/soc/agilex5_mmc.c			\
+		plat/intel/soc/agilex5/soc/agilex5_mmc.c		\
 		plat/intel/soc/agilex5/soc/agilex5_pinmux.c		\
 		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
+		plat/intel/soc/agilex5/soc/agilex5_ddr.c		\
+		plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c	\
 		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_image_load.c		\
 		plat/intel/soc/common/socfpga_ros.c			\
 		plat/intel/soc/common/socfpga_storage.c			\
-		plat/intel/soc/common/socfpga_vab.c				\
+		plat/intel/soc/common/socfpga_vab.c			\
 		plat/intel/soc/common/soc/socfpga_emac.c		\
 		plat/intel/soc/common/soc/socfpga_firewall.c		\
 		plat/intel/soc/common/soc/socfpga_handoff.c		\
@@ -84,6 +89,7 @@
 		lib/cpus/aarch64/cortex_a76.S				\
 		plat/common/plat_psci_common.c				\
 		plat/intel/soc/agilex5/bl31_plat_setup.c		\
+		plat/intel/soc/agilex5/soc/agilex5_cache.S		\
 		plat/intel/soc/agilex5/soc/agilex5_clock_manager.c	\
 		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
 		plat/intel/soc/common/socfpga_psci.c			\
@@ -107,6 +113,11 @@
 $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
+# Configs for VAB Authentication
+SOCFPGA_SECURE_VAB_AUTH  := 	0
+$(eval $(call assert_boolean,SOCFPGA_SECURE_VAB_AUTH))
+$(eval $(call add_define,SOCFPGA_SECURE_VAB_AUTH))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
-BL2_INV_DCACHE			:= 0
+BL2_INV_DCACHE			:= 0
\ No newline at end of file
diff --git a/plat/intel/soc/agilex5/soc/agilex5_cache.S b/plat/intel/soc/agilex5/soc/agilex5_cache.S
new file mode 100644
index 0000000..a174386
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_cache.S
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+	.globl invalidate_dcache_all
+
+.pushsection .text.asm_dcache_level, "ax"
+func asm_dcache_level
+	lsl	x12, x0, #1
+	msr	csselr_el1, x12		/* select cache level */
+	isb				/* sync change of cssidr_el1 */
+	mrs	x6, ccsidr_el1		/* read the new cssidr_el1 */
+	ubfx	x2, x6,  #0,  #3	/* x2 <- log2(cache line size)-4 */
+	ubfx	x3, x6,  #3, #10	/* x3 <- number of cache ways - 1 */
+	ubfx	x4, x6, #13, #15	/* x4 <- number of cache sets - 1 */
+	add	x2, x2, #4		/* x2 <- log2(cache line size) */
+	clz	w5, w3			/* bit position of #ways */
+	/* x12 <- cache level << 1 */
+	/* x2 <- line length offset */
+	/* x3 <- number of cache ways - 1 */
+	/* x4 <- number of cache sets - 1 */
+	/* x5 <- bit position of #ways */
+
+loop_set:
+	mov	x6, x3			/* x6 <- working copy of #ways */
+loop_way:
+	lsl	x7, x6, x5
+	orr	x9, x12, x7		/* map way and level to cisw value */
+	lsl	x7, x4, x2
+	orr	x9, x9, x7		/* map set number to cisw value */
+	tbz	w1, #0, 1f
+	dc	isw, x9
+	b	2f
+1:	dc	cisw, x9		/* clean & invalidate by set/way */
+2:	subs	x6, x6, #1		/* decrement the way */
+	b.ge	loop_way
+	subs	x4, x4, #1		/* decrement the set */
+	b.ge	loop_set
+
+	ret
+endfunc asm_dcache_level
+.popsection
+
+/*
+ * void __asm_flush_dcache_all(int invalidate_only)
+ *
+ * x0: 0 clean & invalidate, 1 invalidate only
+ *
+ * flush or invalidate all data cache by SET/WAY.
+ */
+.pushsection .text.asm_dcache_all, "ax"
+func asm_dcache_all
+	mov	x1, x0
+	dsb	sy
+	mrs	x10, clidr_el1		/* read clidr_el1 */
+	ubfx	x11, x10, #24, #3	/* x11 <- loc */
+	cbz	x11, finished		/* if loc is 0, exit */
+	mov	x15, x30
+	mov	x0, #0			/* start flush at cache level 0 */
+	/* x0  <- cache level */
+	/* x10 <- clidr_el1 */
+	/* x11 <- loc */
+	/* x15 <- return address */
+
+loop_level:
+	add	x12, x0, x0, lsl #1	/* x12 <- tripled cache level */
+	lsr	x12, x10, x12
+	and	x12, x12, #7		/* x12 <- cache type */
+	cmp	x12, #2
+	b.lt	skip			/* skip if no cache or icache */
+	bl	asm_dcache_level	/* x1 = 0 flush, 1 invalidate */
+skip:
+	add	x0, x0, #1		/* increment cache level */
+	cmp	x11, x0
+	b.gt	loop_level
+
+	mov	x0, #0
+	msr	csselr_el1, x0		/* restore csselr_el1 */
+	dsb	sy
+	isb
+	mov	x30, x15
+
+finished:
+	ret
+endfunc asm_dcache_all
+.popsection
+
+.pushsection .text.invalidate_dcache_all, "ax"
+func invalidate_dcache_all
+	mov	x0, #0x1
+	b	asm_dcache_all
+endfunc invalidate_dcache_all
+.popsection
diff --git a/plat/intel/soc/agilex5/soc/agilex5_ddr.c b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
new file mode 100644
index 0000000..ef2ae57
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include "lib/mmio.h"
+
+#include "agilex5_ddr.h"
+#include "agilex5_iossm_mailbox.h"
+
+/*
+ * TODO: We need to leverage the legacy products DDR drivers and consider
+ * the upcoming products like KM and then come up with common source code/driver
+ * architecture to address all the products in one view.
+ */
+
+#define SYSMGR_BS_COLD3_DDR_RESET_TYPE_MASK		GENMASK(31, 29)
+#define SYSMGR_BS_COLD3_DDR_RESET_TYPE_SHIFT		29
+#define SYSMGR_BS_COLD3_DDR_DBE_MASK			(1 << 1)
+#define SYSMGR_BS_COLD3_OCRAM_DBE_MASK			(1)
+#define SYSMGR_BS_POR0_DDR_PROGRESS_MASK		(1)
+
+/* MPFE NOC registers */
+#define F2SDRAM_SIDEBAND_FLAGOUTSET0			0x50
+#define F2SDRAM_SIDEBAND_FLAGOUTCLR0			0x54
+#define F2SDRAM_SIDEBAND_FLAGOUTSTATUS0			0x58
+
+#define SOCFPGA_F2SDRAM_MGR_ADDRESS			0x18001000
+#define SOCFPGA_MPFE_SCR_IO96B0				0x18000D00
+#define SOCFPGA_MPFE_SCR_IO96B1				0x18000D04
+#define SOCFPGA_MPFE_NOC_SCHED_CSR			0x18000D08
+
+#define SIDEBANDMGR_FLAGOUTSET0_REG			(SOCFPGA_F2SDRAM_MGR_ADDRESS \
+							+ F2SDRAM_SIDEBAND_FLAGOUTSET0)
+#define SIDEBANDMGR_FLAGOUTSTATUS0_REG			(SOCFPGA_F2SDRAM_MGR_ADDRESS \
+							+F2SDRAM_SIDEBAND_FLAGOUTSTATUS0)
+#define SIDEBANDMGR_FLAGOUTCLR0_REG			(SOCFPGA_F2SDRAM_MGR_ADDRESS \
+							+ F2SDRAM_SIDEBAND_FLAGOUTCLR0)
+#define SZ_8						0x00000008
+
+
+/* Firewall MPU DDR SCR registers */
+#define FW_MPU_DDR_SCR_EN				0x00
+#define FW_MPU_DDR_SCR_EN_SET				0x04
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE		0x10
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT		0x14
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT		0x18
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT		0x1c
+
+#define SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS			0x18000800
+#define SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS			0x18000A00
+#define SOCFPGA_FW_TBU2NOC_ADDRESS			0x18000C00
+
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE		0x90
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT	0x94
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT		0x98
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT	0x9c
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT_FIELD	0xff
+
+/* Firewall F2SDRAM DDR SCR registers */
+#define FW_F2SDRAM_DDR_SCR_EN				0x00
+#define FW_F2SDRAM_DDR_SCR_EN_SET			0x04
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE		0x10
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT		0x14
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT		0x18
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT		0x1c
+
+#define FW_MPU_DDR_SCR_WRITEL(data, reg)					\
+	do {									\
+		mmio_write_32(SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS + (reg), data);	\
+		mmio_write_32(SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS + (reg), data);	\
+	} while (0)
+
+#define FW_F2SDRAM_DDR_SCR_WRITEL(data, reg)				\
+	mmio_write_32(SOCFPGA_FW_TBU2NOC_ADDRESS + (reg), data)
+
+/* DDR banks info set */
+static struct ddr_info ddr_info_set[CONFIG_NR_DRAM_BANKS];
+
+/* Reset type */
+enum reset_type {
+	POR_RESET,
+	WARM_RESET,
+	COLD_RESET,
+	NCONFIG,
+	JTAG_CONFIG,
+	RSU_RECONFIG
+};
+
+/* Get reset type by reading boot scratch register cold3 */
+static inline enum reset_type get_reset_type(uint32_t sys_reg)
+{
+	return ((sys_reg & SYSMGR_BS_COLD3_DDR_RESET_TYPE_MASK) >>
+		 SYSMGR_BS_COLD3_DDR_RESET_TYPE_SHIFT);
+}
+
+/* DDR hang check before the reset */
+static inline bool is_ddr_init_hang(void)
+{
+	uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0));
+
+	if ((sys_reg & SYSMGR_BS_POR0_DDR_PROGRESS_MASK) != 0) {
+		INFO("DDR: Hang before this reset\n");
+		return true;
+	}
+
+	return false;
+}
+
+/* Set the DDR init progress bit */
+static inline void ddr_init_inprogress(bool start)
+{
+	if (start) {
+		mmio_setbits_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0),
+				SYSMGR_BS_POR0_DDR_PROGRESS_MASK);
+	} else {
+		mmio_clrbits_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0),
+				SYSMGR_BS_POR0_DDR_PROGRESS_MASK);
+	}
+}
+
+/* Configure the IO96B CSRs address based on the handoff data */
+static void config_io96b_csr_addr(bool is_dualemif, struct io96b_info *io96b_ctrl)
+{
+	if (is_dualemif)
+		io96b_ctrl->num_instance = 2;
+	else
+		io96b_ctrl->num_instance = 1;
+
+	/* Assign IO96B CSR base address if it is valid */
+	for (int i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			io96b_ctrl->io96b_0.io96b_csr_addr = 0x18400000;
+			INFO("DDR: IO96B0 0x%llx CSR enabled\n",
+			     io96b_ctrl->io96b_0.io96b_csr_addr);
+			break;
+
+		case 1:
+			io96b_ctrl->io96b_1.io96b_csr_addr = 0x18800000;
+			INFO("DDR: IO96B1 0x%llx CSR enabled\n",
+			     io96b_ctrl->io96b_1.io96b_csr_addr);
+			break;
+
+		default:
+			ERROR("%s: Invalid IO96B CSR\n", __func__);
+		} /* switch */
+	} /* for */
+}
+
+static inline bool hps_ocram_dbe_status(void)
+{
+	uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_3));
+
+	if ((sys_reg & SYSMGR_BS_COLD3_OCRAM_DBE_MASK) != 0)
+		return true;
+
+	return false;
+}
+
+static inline bool ddr_ecc_dbe_status(void)
+{
+	uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_3));
+
+	if ((sys_reg & SYSMGR_BS_COLD3_DDR_DBE_MASK) != 0)
+		return true;
+
+	return false;
+}
+
+static void sdram_set_firewall_non_f2sdram(void)
+{
+	uint32_t i;
+	phys_size_t value;
+	uint32_t lower, upper;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (ddr_info_set[i].size == 0) {
+			continue;
+		}
+
+		value = ddr_info_set[i].start;
+
+		/*
+		 * Keep first 1MB of SDRAM memory region as secure region when
+		 * using ATF flow, where the ATF code is located.
+		 */
+		value += SZ_1M;
+
+		/* Setting non-secure MPU region base and base extended */
+		lower = LO(value);
+		upper = HI(value);
+
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		/* Setting non-secure Non-MPU region base and base extended */
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		/* Setting non-secure MPU limit and limit extended */
+		value = ddr_info_set[i].start + ddr_info_set[i].size - 1;
+
+		lower = LO(value);
+		upper = HI(value);
+
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		/* Setting non-secure Non-MPU limit and limit extended */
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		FW_MPU_DDR_SCR_WRITEL(BIT(i) | BIT(i + 8),
+				      FW_MPU_DDR_SCR_EN_SET);
+	}
+}
+
+static void sdram_set_firewall_f2sdram(void)
+{
+	uint32_t i;
+	phys_size_t value;
+	uint32_t lower, upper;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (ddr_info_set[i].size == 0) {
+			continue;
+		}
+
+		value = ddr_info_set[i].start;
+
+		/* Keep first 1MB of SDRAM memory region as secure region when
+		 * using ATF flow, where the ATF code is located.
+		 */
+		value += SZ_1M;
+
+		/* Setting base and base extended */
+		lower = LO(value);
+		upper = HI(value);
+		FW_F2SDRAM_DDR_SCR_WRITEL(lower,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE +
+					  (i * 4 * sizeof(uint32_t)));
+		FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT +
+					  (i * 4 * sizeof(uint32_t)));
+
+		/* Setting limit and limit extended */
+		value = ddr_info_set[i].start + ddr_info_set[i].size - 1;
+
+		lower = LO(value);
+		upper = HI(value);
+
+		FW_F2SDRAM_DDR_SCR_WRITEL(lower,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT +
+					  (i * 4 * sizeof(uint32_t)));
+		FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT +
+					  (i * 4 * sizeof(uint32_t)));
+
+		FW_F2SDRAM_DDR_SCR_WRITEL(BIT(i), FW_F2SDRAM_DDR_SCR_EN_SET);
+	}
+}
+
+static void sdram_set_firewall(void)
+{
+	sdram_set_firewall_non_f2sdram();
+	sdram_set_firewall_f2sdram();
+}
+
+/*
+ * Agilex5 DDR/IOSSM controller initialization routine
+ */
+int agilex5_ddr_init(handoff *hoff_ptr)
+{
+	int ret;
+	bool full_mem_init = false;
+	phys_size_t hw_ddr_size;
+	phys_size_t config_ddr_size;
+	struct io96b_info io96b_ctrl;
+	enum reset_type reset_t = get_reset_type(mmio_read_32(SOCFPGA_SYSMGR(
+						BOOT_SCRATCH_COLD_3)));
+	bool is_dualport = hoff_ptr->ddr_config & BIT(0);
+	bool is_dualemif = hoff_ptr->ddr_config & BIT(1);
+
+	NOTICE("DDR: Reset type is '%s'\n",
+	       (reset_t == POR_RESET ? "Power-On" : (reset_t == COLD_RESET ? "Cold" : "Warm")));
+
+	/* DDR initialization progress status tracking */
+	bool is_ddr_hang_bfr_rst = is_ddr_init_hang();
+
+	/* Set the DDR initialization progress */
+	ddr_init_inprogress(true);
+
+	/* Configure the IO96B CSR address based on the handoff data */
+	config_io96b_csr_addr(is_dualemif, &io96b_ctrl);
+
+	/* Configuring MPFE sideband manager registers */
+	/* Dual port setting */
+	if (is_dualport)
+		mmio_setbits_32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(4));
+
+	/* Dual EMIF setting */
+	if (is_dualemif) {
+		/* Set mpfe_lite_active in the system manager */
+		/* TODO: recheck on the bit value?? */
+		mmio_setbits_32(SOCFPGA_SYSMGR(MPFE_CONFIG), BIT(8));
+
+		mmio_setbits_32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(5));
+	}
+
+	if (is_dualport || is_dualemif)
+		INFO("DDR: SIDEBANDMGR_FLAGOUTSTATUS0: 0x%x\n",
+		     mmio_read_32(SIDEBANDMGR_FLAGOUTSTATUS0_REG));
+
+	/* Ensure calibration status passing */
+	init_mem_cal(&io96b_ctrl);
+
+	/* Initiate IOSSM mailbox */
+	io96b_mb_init(&io96b_ctrl);
+
+	/* Need to trigger re-calibration for DDR DBE */
+	if (ddr_ecc_dbe_status()) {
+		io96b_ctrl.io96b_0.cal_status = false;
+		io96b_ctrl.io96b_1.cal_status = false;
+		io96b_ctrl.overall_cal_status = io96b_ctrl.io96b_0.cal_status ||
+						io96b_ctrl.io96b_1.cal_status;
+	}
+
+	/* Trigger re-calibration if calibration failed */
+	if (!(io96b_ctrl.overall_cal_status)) {
+		NOTICE("DDR: Re-calibration in progress...\n");
+		trig_mem_cal(&io96b_ctrl);
+	}
+	NOTICE("DDR: Calibration success\n");
+
+	/* DDR type, DDR size and ECC status) */
+	ret = get_mem_technology(&io96b_ctrl);
+	if (ret != 0) {
+		ERROR("DDR: Failed to get DDR type\n");
+		return ret;
+	}
+
+	ret = get_mem_width_info(&io96b_ctrl);
+	if (ret != 0) {
+		ERROR("DDR: Failed to get DDR size\n");
+		return ret;
+	}
+
+	/* DDR size queried from the IOSSM controller */
+	hw_ddr_size = (phys_size_t)io96b_ctrl.overall_size * SZ_1G / SZ_8;
+
+	/* TODO: Hard code 1GB as of now, and DDR start and end address */
+	config_ddr_size = 0x40000000;
+	ddr_info_set[0].start = 0x80000000;
+	ddr_info_set[0].size = 0x40000000;
+
+	if (config_ddr_size != hw_ddr_size) {
+		WARN("DDR: DDR size configured is (%lld MiB)\n", config_ddr_size >> 20);
+		WARN("DDR: Mismatch with hardware size (%lld MiB).\n", hw_ddr_size >> 20);
+	}
+
+	if (config_ddr_size > hw_ddr_size) {
+		ERROR("DDR: Confgured DDR size is greater than the hardware size - HANG!!!\n");
+		while (1)
+			;
+	}
+
+	ret = ecc_enable_status(&io96b_ctrl);
+	if (ret != 0) {
+		ERROR("DDR: Failed to get DDR ECC status\n");
+		return ret;
+	}
+
+	/*
+	 * HPS cold or warm reset? If yes, skip full memory initialization if
+	 * ECC is enabled to preserve memory content.
+	 */
+	if (io96b_ctrl.ecc_status != 0) {
+		full_mem_init = hps_ocram_dbe_status() | ddr_ecc_dbe_status() |
+				is_ddr_hang_bfr_rst;
+		if ((full_mem_init == true) || (reset_t == WARM_RESET ||
+			reset_t == COLD_RESET) == 0) {
+			ret = bist_mem_init_start(&io96b_ctrl);
+			if (ret != 0) {
+				ERROR("DDR: Failed to fully initialize DDR memory\n");
+				return ret;
+			}
+		}
+		INFO("DDR: ECC initialized successfully\n");
+	}
+
+	sdram_set_firewall();
+
+	/*
+	 * Firewall setting for MPFE CSRs, allow both secure and non-secure
+	 * transactions.
+	 */
+	/* IO96B0_reg */
+	mmio_setbits_32(SOCFPGA_MPFE_SCR_IO96B0, BIT(0));
+	/* IO96B1_reg */
+	mmio_setbits_32(SOCFPGA_MPFE_SCR_IO96B1, BIT(0));
+	/* noc_scheduler_csr */
+	mmio_setbits_32(SOCFPGA_MPFE_NOC_SCHED_CSR, BIT(0));
+
+	INFO("DDR: firewall init done\n");
+
+	/* Ending DDR driver initialization success tracking */
+	ddr_init_inprogress(false);
+
+	NOTICE("###DDR:init success###\n");
+
+	return 0;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c b/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c
new file mode 100644
index 0000000..c2ab047
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c
@@ -0,0 +1,811 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+
+#include "agilex5_iossm_mailbox.h"
+
+/* supported DDR type list */
+static const char *ddr_type_list[7] = {
+	"DDR4", "DDR5", "DDR5_RDIMM", "LPDDR4", "LPDDR5", "QDRIV", "UNKNOWN"
+};
+
+static inline int wait_for_bit(const void *reg,
+			       const uint32_t mask,
+			       const bool set,
+			       const unsigned int timeout_ms)
+{
+	uint32_t val;
+	uint32_t timeout_sec = (timeout_ms / 1000);
+
+	while (timeout_sec > 0) {
+		val = mmio_read_32((uintptr_t)reg);
+
+		INFO("IOSSM: timeout_sec %d, val %x\n", timeout_sec, val);
+
+		if (!set) {
+			val = ~val;
+		}
+
+		if ((val & mask) == mask) {
+			INFO("IOSSM: %s, success\n", __func__);
+			return 0;
+		}
+
+		/* one second delay */
+		mdelay(1000);
+
+		timeout_sec--;
+	}
+
+	ERROR("IOSSM: %s, failed, time out\n", __func__);
+	return -ETIMEDOUT;
+}
+
+int io96b_mb_req(phys_addr_t io96b_csr_addr, uint32_t ip_type, uint32_t instance_id,
+		 uint32_t usr_cmd_type, uint32_t usr_cmd_opcode, uint32_t cmd_param_0,
+		 uint32_t cmd_param_1, uint32_t cmd_param_2, uint32_t cmd_param_3,
+		 uint32_t cmd_param_4, uint32_t cmd_param_5, uint32_t cmd_param_6,
+		 uint32_t resp_data_len, struct io96b_mb_resp *resp)
+{
+	int i;
+	int ret;
+	uint32_t cmd_req, cmd_resp;
+
+	/* Initialized zeros for responses*/
+	resp->cmd_resp_status = 0;
+	resp->cmd_resp_data_0 = 0;
+	resp->cmd_resp_data_1 = 0;
+	resp->cmd_resp_data_2 = 0;
+
+	/* Ensure CMD_REQ is cleared before write any command request */
+	ret = wait_for_bit((const void *)(io96b_csr_addr + IOSSM_CMD_REQ_OFFSET),
+			   GENMASK(31, 0), 0, 10000);
+
+	if (ret != 0) {
+		ERROR("%s: CMD_REQ not ready\n", __func__);
+		return -1;
+	}
+
+	/* Write CMD_PARAM_* */
+	for (i = 0; i < 6 ; i++) {
+		switch (i) {
+		case 0:
+			if (cmd_param_0 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_0_OFFSET,
+					      cmd_param_0);
+			}
+			break;
+		case 1:
+			if (cmd_param_1 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_1_OFFSET,
+					      cmd_param_1);
+			}
+			break;
+		case 2:
+			if (cmd_param_2 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_2_OFFSET,
+					      cmd_param_2);
+			}
+			break;
+		case 3:
+			if (cmd_param_3 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_3_OFFSET,
+					      cmd_param_3);
+			}
+			break;
+		case 4:
+			if (cmd_param_4 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_4_OFFSET,
+					      cmd_param_4);
+			}
+			break;
+		case 5:
+			if (cmd_param_5 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_5_OFFSET,
+					      cmd_param_5);
+			}
+			break;
+		case 6:
+			if (cmd_param_6 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_6_OFFSET,
+					      cmd_param_6);
+			}
+			break;
+		default:
+			ERROR("IOSSM: %s: Invalid command parameter\n", __func__);
+		}
+	}
+
+	/* Write CMD_REQ (IP_TYPE, IP_INSTANCE_ID, CMD_TYPE and CMD_OPCODE) */
+	cmd_req = (usr_cmd_opcode << 0) | (usr_cmd_type << 16) | (instance_id << 24) |
+		  (ip_type << 29);
+	mmio_write_32(io96b_csr_addr + IOSSM_CMD_REQ_OFFSET, cmd_req);
+	INFO("IOSSM: %s: Write 0x%x to IOSSM_CMD_REQ_OFFSET 0x%llx\n",
+		__func__, cmd_req, io96b_csr_addr + IOSSM_CMD_REQ_OFFSET);
+
+	/* Read CMD_RESPONSE_READY in CMD_RESPONSE_STATUS*/
+	ret = wait_for_bit((const void *)(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET),
+			   IOSSM_STATUS_COMMAND_RESPONSE_READY, 1, 10000);
+
+	if (ret != 0) {
+		ERROR("%s: CMD_RESPONSE ERROR:\n", __func__);
+		cmd_resp = (io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+		ERROR("%s: STATUS_GENERAL_ERROR: 0x%x\n", __func__, (cmd_resp >> 1) & 0xF);
+		ERROR("%s: STATUS_CMD_RESPONSE_ERROR: 0x%x\n", __func__, (cmd_resp >> 5) & 0x7);
+	}
+
+	/* read CMD_RESPONSE_STATUS*/
+	resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+	INFO("IOSSM: %s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n",
+		__func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+	/* read CMD_RESPONSE_DATA_* */
+	for (i = 0; i < resp_data_len; i++) {
+		switch (i) {
+		case 0:
+			resp->cmd_resp_data_0 =
+				mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET);
+
+			break;
+		case 1:
+			resp->cmd_resp_data_1 =
+				mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET);
+
+			break;
+		case 2:
+			resp->cmd_resp_data_2 =
+				mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET);
+			break;
+		default:
+			ERROR("%s: Invalid response data\n", __func__);
+		}
+	}
+
+	resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+	INFO("IOSSM: %s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n",
+		__func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+	/* write CMD_RESPONSE_READY = 0 */
+	mmio_clrbits_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET,
+			IOSSM_STATUS_COMMAND_RESPONSE_READY);
+
+	resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+	INFO("IOSSM: %s: CMD_RESPONSE_READY 0x%llx: 0x%x\n",
+		__func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+	return 0;
+}
+
+/*
+ * Initial function to be called to set memory interface IP type and instance ID
+ * IP type and instance ID need to be determined before sending mailbox command
+ */
+void io96b_mb_init(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	uint8_t ip_type_ret, instance_id_ret;
+	int i, j, k;
+
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			/* Get memory interface IP type & instance ID (IP identifier) */
+			io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+				     CMD_GET_SYS_INFO, GET_MEM_INTF_INFO, 0, 0,
+				     0, 0, 0, 0, 0, 2, &usr_resp);
+			/* Retrieve number of memory interface(s) */
+			io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface =
+				IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+
+			/* Retrieve memory interface IP type and instance ID (IP identifier) */
+			j = 0;
+			for (k = 0; k < MAX_MEM_INTERFACES_SUPPORTED; k++) {
+				switch (k) {
+				case 0:
+					ip_type_ret = (usr_resp.cmd_resp_data_0 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_0 >> 24) & 0x1F;
+					break;
+				case 1:
+					ip_type_ret = (usr_resp.cmd_resp_data_1 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_1 >> 24) & 0x1F;
+					break;
+				}
+
+				if (ip_type_ret != 0) {
+					io96b_ctrl->io96b_0.mb_ctrl.ip_type[j] = ip_type_ret;
+					io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j] =
+						instance_id_ret;
+					j++;
+				}
+			}
+			break;
+		case 1:
+			/* Get memory interface IP type and instance ID (IP identifier) */
+			io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0, CMD_GET_SYS_INFO,
+				     GET_MEM_INTF_INFO, 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+			/* Retrieve number of memory interface(s) */
+			io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface =
+				IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+
+			/* Retrieve memory interface IP type and instance ID (IP identifier) */
+			j = 0;
+			for (k = 0; k < MAX_MEM_INTERFACES_SUPPORTED; k++) {
+				switch (k) {
+				case 0:
+					ip_type_ret = (usr_resp.cmd_resp_data_0 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_0 >> 24) & 0x1F;
+					break;
+				case 1:
+					ip_type_ret = (usr_resp.cmd_resp_data_1 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_1 >> 24) & 0x1F;
+					break;
+				}
+
+				if (ip_type_ret != 0) {
+					io96b_ctrl->io96b_1.mb_ctrl.ip_type[j] = ip_type_ret;
+					io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j] =
+						instance_id_ret;
+					j++;
+				}
+			}
+			break;
+		}
+
+	}
+}
+
+static inline void hang(void)
+{
+	ERROR("IOSSM: %s: system is going to die :(\n", __func__);
+	while (1)
+		;
+}
+
+int io96b_cal_status(phys_addr_t addr)
+{
+	int cal_busy_status, cal_success_status;
+	phys_addr_t status_addr = addr + IOSSM_STATUS_OFFSET;
+
+	/* Ensure calibration busy status */
+	cal_busy_status = wait_for_bit((const void *)status_addr, IOSSM_STATUS_CAL_BUSY,
+					false, 15000);
+	if (cal_busy_status != 0) {
+		ERROR("IOSSM: One or more EMIF instances are busy with calibration\n");
+		return -EBUSY;
+	}
+
+	/* Calibration success status check */
+	NOTICE("IOSSM: Calibration success status check...\n");
+	cal_success_status = wait_for_bit((const void *)status_addr, IOSSM_STATUS_CAL_SUCCESS,
+					  true, 15000);
+	if (cal_success_status != 0) {
+		ERROR("IOSSM: One/more EMIF instances either failed to calibrate/not completed\n");
+		return -EBUSY;
+	}
+
+	NOTICE("IOSSM: All EMIF instances within the IO96 have calibrated successfully!\n");
+	return 0;
+}
+
+void init_mem_cal(struct io96b_info *io96b_ctrl)
+{
+	int count, i, ret;
+
+	/* Initialize overall calibration status */
+	io96b_ctrl->overall_cal_status = false;
+
+	/* Check initial calibration status for the assigned IO96B */
+	count = 0;
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			ret = io96b_cal_status(io96b_ctrl->io96b_0.io96b_csr_addr);
+			if (ret != 0) {
+				io96b_ctrl->io96b_0.cal_status = false;
+				ERROR("%s: Initial DDR calibration IO96B_0 failed %d\n",
+					__func__, ret);
+				break;
+			}
+			io96b_ctrl->io96b_0.cal_status = true;
+			INFO("IOSSM: %s: Initial DDR calibration IO96B_0 succeed\n", __func__);
+			count++;
+			break;
+		case 1:
+			ret = io96b_cal_status(io96b_ctrl->io96b_1.io96b_csr_addr);
+			if (ret != 0) {
+				io96b_ctrl->io96b_1.cal_status = false;
+				ERROR("%s: Initial DDR calibration IO96B_1 failed %d\n",
+					__func__, ret);
+				break;
+			}
+			io96b_ctrl->io96b_1.cal_status = true;
+			INFO("IOSSM: %s: Initial DDR calibration IO96B_1 succeed\n", __func__);
+			count++;
+			break;
+		}
+	}
+
+	if (count == io96b_ctrl->num_instance)
+		io96b_ctrl->overall_cal_status = true;
+}
+
+/*
+ * Trying 3 times re-calibration if initial calibration failed
+ */
+int trig_mem_cal(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	bool recal_success;
+	int i;
+	uint8_t cal_stat;
+
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			if (!(io96b_ctrl->io96b_0.cal_status)) {
+				/* Get the memory calibration status for first memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0,
+					     0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration first memory interface with failed calibration */
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_type[0],
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[0],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("%s: Error as SDRAM calibration failed\n", __func__);
+					hang();
+				}
+
+				/* Get the memory calibration status for second memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration second memory interface with failed calibration*/
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_1 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_type[1],
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[1],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("IOSSMM: Error as SDRAM calibration failed\n");
+					hang();
+				}
+
+				io96b_ctrl->io96b_0.cal_status = true;
+			}
+			break;
+		case 1:
+			if (!(io96b_ctrl->io96b_1.cal_status)) {
+				/* Get the memory calibration status for first memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0,
+					     0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration first memory interface with failed calibration */
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_type[0],
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[0],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("IOSSM: Error as SDRAM calibration failed\n");
+					hang();
+				}
+
+				/* Get the memory calibration status for second memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration second memory interface with failed calibration*/
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_type[1],
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[1],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("IOSSM: Error as SDRAM calibration failed\n");
+					hang();
+				}
+
+				io96b_ctrl->io96b_1.cal_status = true;
+			}
+			break;
+		}
+	}
+
+	if (io96b_ctrl->io96b_0.cal_status && io96b_ctrl->io96b_1.cal_status) {
+		INFO("IOSSM: %s: Overall SDRAM calibration success\n", __func__);
+		io96b_ctrl->overall_cal_status = true;
+	}
+
+	return 0;
+}
+
+int get_mem_technology(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	uint8_t ddr_type_ret;
+
+	/* Initialize ddr type */
+	io96b_ctrl->ddr_type = ddr_type_list[6];
+
+	/* Get and ensure all memory interface(s) same DDR type */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, 0, 0, 0, 0,
+					     0, 0, 0, 0, &usr_resp);
+
+				ddr_type_ret =
+					IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 0);
+
+				if (strcmp(io96b_ctrl->ddr_type, "UNKNOWN") == 0)
+					io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
+
+				if (ddr_type_list[ddr_type_ret] != io96b_ctrl->ddr_type) {
+					ERROR("IOSSM: Mismatch DDR type on IO96B_0\n");
+					return -ENOEXEC;
+				}
+			}
+			break;
+		case 1:
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, 0, 0, 0,
+					     0, 0, 0, 0, 0, &usr_resp);
+
+				ddr_type_ret =
+					IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 0);
+
+				if (strcmp(io96b_ctrl->ddr_type, "UNKNOWN") == 0)
+					io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
+
+				if (ddr_type_list[ddr_type_ret] != io96b_ctrl->ddr_type) {
+					ERROR("IOSSM: Mismatch DDR type on IO96B_1\n");
+					return -ENOEXEC;
+				}
+			}
+			break;
+		}
+	}
+
+	return 0;
+}
+
+int get_mem_width_info(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	uint16_t memory_size = 0U;
+	uint16_t total_memory_size = 0U;
+
+	/* Get all memory interface(s) total memory size on all instance(s) */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			memory_size = 0;
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				memory_size = memory_size +
+						(usr_resp.cmd_resp_data_1 & GENMASK(7, 0));
+			}
+
+			if (memory_size == 0U) {
+				ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+				return -ENOEXEC;
+			}
+
+			io96b_ctrl->io96b_0.size = memory_size;
+
+			break;
+		case 1:
+			memory_size = 0;
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				memory_size = memory_size +
+						(usr_resp.cmd_resp_data_1 & GENMASK(7, 0));
+			}
+
+			if (memory_size == 0U) {
+				ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+				return -ENOEXEC;
+			}
+
+			io96b_ctrl->io96b_1.size = memory_size;
+
+			break;
+		}
+
+		total_memory_size = total_memory_size + memory_size;
+	}
+
+	if (total_memory_size == 0U) {
+		ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+		return -ENOEXEC;
+	}
+
+	io96b_ctrl->overall_size = total_memory_size;
+
+	return 0;
+}
+
+int ecc_enable_status(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	bool ecc_stat_set = false;
+	bool ecc_stat;
+
+	/* Initialize ECC status */
+	io96b_ctrl->ecc_status = false;
+
+	/* Get and ensure all memory interface(s) same ECC status */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS, 0, 0,
+					     0, 0, 0, 0, 0, 0, &usr_resp);
+
+				ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+						& GENMASK(1, 0)) == 0 ? false : true);
+
+				if (!ecc_stat_set) {
+					io96b_ctrl->ecc_status = ecc_stat;
+					ecc_stat_set = true;
+				}
+
+				if (ecc_stat != io96b_ctrl->ecc_status) {
+					ERROR("IOSSM: %s: Mismatch DDR ECC status on IO96B_0\n",
+						__func__);
+					return -ENOEXEC;
+				}
+			}
+			break;
+		case 1:
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS, 0, 0,
+					     0, 0, 0, 0, 0, 0, &usr_resp);
+
+				ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+						& GENMASK(1, 0)) == 0 ? false : true);
+
+				if (!ecc_stat_set) {
+					io96b_ctrl->ecc_status = ecc_stat;
+					ecc_stat_set = true;
+				}
+
+				if (ecc_stat != io96b_ctrl->ecc_status) {
+					ERROR("%s: Mismatch DDR ECC status on IO96B_1\n"
+						, __func__);
+					return -ENOEXEC;
+				}
+			}
+			break;
+		}
+	}
+	return 0;
+}
+
+int bist_mem_init_start(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	bool bist_start, bist_success;
+	uint32_t read_count;
+	uint32_t read_interval_ms;
+
+	/* Full memory initialization BIST performed on all memory interface(s) */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				bist_start = false;
+				bist_success = false;
+				read_interval_ms = 500U;
+
+				/* Start memory initialization BIST on full memory address */
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0x40,
+					     0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+				bist_start =
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& 1);
+
+				if (!bist_start) {
+					ERROR("IOSSM: %s: Failed to initialized memory on IO96B_0\n"
+					, __func__);
+					ERROR("IOSSM: %s: BIST_MEM_INIT_START Error code 0x%x\n",
+					__func__,
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 1)) > 0x1);
+					return -ENOEXEC;
+				}
+
+				/* Polling for the initiated memory initialization BIST status */
+				read_count = read_interval_ms / TIMEOUT;
+				while (!bist_success) {
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+						     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+					bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status) & 1);
+
+					if ((!bist_success) && (read_count == 0U)) {
+						ERROR("IOSSM: %s: Timeout init memory on IO96B_0\n"
+							, __func__);
+						ERROR("IOSSM: %s: BIST_MEM_INIT_STATUS Err code%x\n"
+							, __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status)
+							& GENMASK(2, 1)) > 0x1);
+						return -ETIMEDOUT;
+					}
+					read_count--;
+					mdelay(read_interval_ms);
+				}
+			}
+
+			NOTICE("IOSSM: %s: Memory initialized successfully on IO96B_0\n", __func__);
+			break;
+
+		case 1:
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				bist_start = false;
+				bist_success = false;
+				read_interval_ms = 500U;
+
+				/* Start memory initialization BIST on full memory address */
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0x40,
+					     0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+				bist_start =
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& 1);
+
+				if (!bist_start) {
+					ERROR("IOSSM: %s: Failed to initialized memory on IO96B_1\n"
+						, __func__);
+					ERROR("IOSSM: %s: BIST_MEM_INIT_START Error code 0x%x\n",
+					__func__,
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 1)) > 0x1);
+					return -ENOEXEC;
+				}
+
+				/* Polling for the initiated memory initialization BIST status */
+				read_count = read_interval_ms / TIMEOUT;
+				while (!bist_success) {
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+						     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+					bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status) & 1);
+
+					if ((!bist_success) && (read_count == 0U)) {
+						ERROR("IOSSM: %s: Timeout init memory on IO96B_1\n"
+							, __func__);
+						ERROR("IOSSM: %s: BIST_MEM_INIT_STATUS ErrCode %x\n"
+							, __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status)
+							& GENMASK(2, 1)) > 0x1);
+						return -ETIMEDOUT;
+					}
+					read_count--;
+					mdelay(read_interval_ms);
+				}
+			}
+
+			NOTICE("IOSSM: %s: Memory initialized successfully on IO96B_1\n", __func__);
+			break;
+		}
+	}
+	return 0;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
index 50d9e36..7c4eb57 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -195,11 +196,15 @@
 {
 	unsigned int i;
 
-	mmio_write_32(PINMUX_HANDOFF_CONFIG_ADDR, PINMUX_HANDOFF_CONFIG_VAL);
-	for (i = 0; i < PINMUX_HANDOFF_ARRAY_SIZE(hoff_ptr->pinmux_sel_array); i += 2) {
-		mmio_write_32(AGX5_PINMUX_PIN0SEL +
-			hoff_ptr->pinmux_sel_array[i],
-			hoff_ptr->pinmux_sel_array[i + 1]);
+	/*
+	 * Configure the FPGA use.
+	 * The actual generic handoff contains extra 4 elements, and these 4 elements
+	 * are not applicable to the Agilex5 platform. Writing these extra 4 elements
+	 * will cause the system to crash, so let's avoid writing them here.
+	 */
+	for (i = 0; i < (ARRAY_SIZE(hoff_ptr->pinmux_fpga_array) - 4); i += 2) {
+		mmio_write_32(AGX5_PINMUX_EMAC0_USEFPGA + hoff_ptr->pinmux_fpga_array[i],
+			      hoff_ptr->pinmux_fpga_array[i+1]);
 	}
 
 	config_fpgaintf_mod();
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index 2094c65..ca76b6a 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -10,6 +10,7 @@
 #include <platform_def.h>
 
 #include "ncore_ccu.h"
+#include "socfpga_mailbox.h"
 #include "socfpga_plat_def.h"
 #include "socfpga_system_manager.h"
 
@@ -17,6 +18,486 @@
 
 #define SMMU_DMI			1
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+ncore_ccu_reg_t ncore_ccu_modules[] = {
+				{"caiu0@1c000000",             0x1C000000, 0x00001000},
+				{"ncaiu0@1c001000",            0x1C001000, 0x00001000},
+				{"ncaiu1@1c002000",            0x1C002000, 0x00001000},
+				{"ncaiu2@1c003000",            0x1C003000, 0x00001000},
+				{"ncaiu3@1c004000",            0x1C004000, 0x00001000},
+				{"dce0@1c005000",              0x1C005000, 0x00001000},
+				{"dce1@1c006000",              0x1C006000, 0x00001000},
+				{"dmi0@1c007000",              0x1C007000, 0x00001000},
+				{"dmi1@1c008000",              0x1C008000, 0x00001000},
+				{"noc_fw_l4_per@10d21000",     0x10D21000, 0x0000008C},
+				{"noc_fw_l4_sys@10d21100",     0x10D21100, 0x00000098},
+				{"noc_fw_lwsoc2fpga@10d21300", 0x10D21300, 0x00000004},
+				{"noc_fw_soc2fpga@10d21200",   0x10D21200, 0x00000004},
+				{"noc_fw_tcu@10d21400",        0x10D21400, 0x00000004}
+				};
+
+ncore_ccu_t ccu_caiu0[] = {
+				/* CAIUAMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* CAIUMIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DII1_MPFEREGS */
+				{0x00000414, 0x00018000, 0xFFFFFFFF},
+				{0x00000418, 0x00000000, 0x000000FF},
+				{0x00000410, 0xC0E00200, 0xC1F03E1F},
+				/* DII2_GICREGS */
+				{0x00000424, 0x0001D000, 0xFFFFFFFF},
+				{0x00000428, 0x00000000, 0x000000FF},
+				{0x00000420, 0xC0800400, 0xC1F03E1F},
+				/* NCAIU0_LWSOC2FPGA */
+				{0x00000444, 0x00020000, 0xFFFFFFFF},
+				{0x00000448, 0x00000000, 0x000000FF},
+				{0x00000440, 0xC1100006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_1G */
+				{0x00000454, 0x00040000, 0xFFFFFFFF},
+				{0x00000458, 0x00000000, 0x000000FF},
+				{0x00000450, 0xC1200006, 0xC1F03E1F},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_16G */
+				{0x00000474, 0x00400000, 0xFFFFFFFF},
+				{0x00000478, 0x00000000, 0x000000FF},
+				{0x00000470, 0xC1600006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_256G */
+				{0x00000494, 0x04000000, 0xFFFFFFFF},
+				{0x00000498, 0x00000000, 0x000000FF},
+				{0x00000490, 0xC1A00006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_ncaiu0[] = {
+				/* NCAIU0AMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* NCAIU0MIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* PSS */
+				{0x00000404, 0x00010000, 0xFFFFFFFF},
+				{0x00000408, 0x00000000, 0x000000FF},
+				{0x00000400, 0xC0F00000, 0xC1F03E1F},
+				/* DII1_MPFEREGS */
+				{0x00000414, 0x00018000, 0xFFFFFFFF},
+				{0x00000418, 0x00000000, 0x000000FF},
+				{0x00000410, 0xC0E00200, 0xC1F03E1F},
+				/* NCAIU0_LWSOC2FPGA */
+				{0x00000444, 0x00020000, 0xFFFFFFFF},
+				{0x00000448, 0x00000000, 0x000000FF},
+				{0x00000440, 0xC1100006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_1G */
+				{0x00000454, 0x00040000, 0xFFFFFFFF},
+				{0x00000458, 0x00000000, 0x000000FF},
+				{0x00000450, 0xC1200006, 0xC1F03E1F},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_16G */
+				{0x00000474, 0x00400000, 0xFFFFFFFF},
+				{0x00000478, 0x00000000, 0x000000FF},
+				{0x00000470, 0xC1600006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_256G */
+				{0x00000494, 0x04000000, 0xFFFFFFFF},
+				{0x00000498, 0x00000000, 0x000000FF},
+				{0x00000490, 0xC1A00006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_ncaiu1[] = {
+				/* NCAIU1AMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* NCAIU1MIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_ncaiu2[] = {
+				/* NCAIU2AMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* NCAIU2MIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_ncaiu3[] = {
+				/* NCAIU3AMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* NCAIU3MIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DII1_MPFEREGS */
+				{0x00000414, 0x00018000, 0xFFFFFFFF},
+				{0x00000418, 0x00000000, 0x000000FF},
+				{0x00000410, 0xC0E00200, 0xC1F03E1F},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_dce0[] = {
+				/* DCEUAMIGR0 */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* DCEUMIFSR0 */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_dce1[] = {
+				/* DCEUAMIGR1 */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* DCEUMIFSR1 */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_dmi0[] = {
+				/* DMIUSMCTCR */
+				{0x00000300, 0x00000001, 0x00000003},
+				{0x00000300, 0x00000003, 0x00000003}
+			};
+
+ncore_ccu_t ccu_dmi1[] = {
+				/* DMIUSMCTCR */
+				{0x00000300, 0x00000001, 0x00000003},
+				{0x00000300, 0x00000003, 0x00000003}
+			};
+
+ncore_ccu_t ccu_noc_fw_l4_per[] = {
+				/* NAND */
+				{0x00000000, 0x01010001, 0x01010001},
+				/* USB0 */
+				{0x0000000C, 0x01010001, 0x01010001},
+				/* USB1 */
+				{0x00000010, 0x01010001, 0x01010001},
+				/* SPI_MAIN0 */
+				{0x0000001C, 0x01010301, 0x01010301},
+				/* SPI_MAIN1 */
+				{0x00000020, 0x01010301, 0x01010301},
+				/* SPI_SECONDARY0 */
+				{0x00000024, 0x01010301, 0x01010301},
+				/* SPI_SECONDARY1 */
+				{0x00000028, 0x01010301, 0x01010301},
+				/* EMAC0 */
+				{0x0000002C, 0x01010001, 0x01010001},
+				/* EMAC1 */
+				{0x00000030, 0x01010001, 0x01010001},
+				/* EMAC2 */
+				{0x00000034, 0x01010001, 0x01010001},
+				/* SDMMC */
+				{0x00000040, 0x01010001, 0x01010001},
+				/* GPIO0 */
+				{0x00000044, 0x01010301, 0x01010301},
+				/* GPIO1 */
+				{0x00000048, 0x01010301, 0x01010301},
+				/* I2C0 */
+				{0x00000050, 0x01010301, 0x01010301},
+				/* I2C1 */
+				{0x00000054, 0x01010301, 0x01010301},
+				/* I2C2 */
+				{0x00000058, 0x01010301, 0x01010301},
+				/* I2C3 */
+				{0x0000005C, 0x01010301, 0x01010301},
+				/* I2C4 */
+				{0x00000060, 0x01010301, 0x01010301},
+				/* SP_TIMER0 */
+				{0x00000064, 0x01010301, 0x01010301},
+				/* SP_TIMER1 */
+				{0x00000068, 0x01010301, 0x01010301},
+				/* UART0 */
+				{0x0000006C, 0x01010301, 0x01010301},
+				/* UART1 */
+				{0x00000070, 0x01010301, 0x01010301},
+				/* I3C0 */
+				{0x00000074, 0x01010301, 0x01010301},
+				/* I3C1 */
+				{0x00000078, 0x01010301, 0x01010301},
+				/* DMA0 */
+				{0x0000007C, 0x01010001, 0x01010001},
+				/* DMA1 */
+				{0x00000080, 0x01010001, 0x01010001},
+				/* COMBO_PHY */
+				{0x00000084, 0x01010001, 0x01010001},
+				/* NAND_SDMA */
+				{0x00000088, 0x01010301, 0x01010301}
+			};
+
+ncore_ccu_t ccu_noc_fw_l4_sys[] = {
+				/* DMA_ECC */
+				{0x00000008, 0x01010001, 0x01010001},
+				/* EMAC0RX_ECC */
+				{0x0000000C, 0x01010001, 0x01010001},
+				/* EMAC0TX_ECC */
+				{0x00000010, 0x01010001, 0x01010001},
+				/* EMAC1RX_ECC */
+				{0x00000014, 0x01010001, 0x01010001},
+				/* EMAC1TX_ECC */
+				{0x00000018, 0x01010001, 0x01010001},
+				/* EMAC2RX_ECC */
+				{0x0000001C, 0x01010001, 0x01010001},
+				/* EMAC2TX_ECC */
+				{0x00000020, 0x01010001, 0x01010001},
+				/* NAND_ECC */
+				{0x0000002C, 0x01010001, 0x01010001},
+				/* NAND_READ_ECC */
+				{0x00000030, 0x01010001, 0x01010001},
+				/* NAND_WRITE_ECC */
+				{0x00000034, 0x01010001, 0x01010001},
+				/* OCRAM_ECC */
+				{0x00000038, 0x01010001, 0x01010001},
+				/* SDMMC_ECC */
+				{0x00000040, 0x01010001, 0x01010001},
+				/* USB0_ECC */
+				{0x00000044, 0x01010001, 0x01010001},
+				/* USB1_CACHEECC */
+				{0x00000048, 0x01010001, 0x01010001},
+				/* CLOCK_MANAGER */
+				{0x0000004C, 0x01010001, 0x01010001},
+				/* IO_MANAGER */
+				{0x00000054, 0x01010001, 0x01010001},
+				/* RESET_MANAGER */
+				{0x00000058, 0x01010001, 0x01010001},
+				/* SYSTEM_MANAGER */
+				{0x0000005C, 0x01010001, 0x01010001},
+				/* OSC0_TIMER */
+				{0x00000060, 0x01010301, 0x01010301},
+				/* OSC1_TIMER0*/
+				{0x00000064, 0x01010301, 0x01010301},
+				/* WATCHDOG0 */
+				{0x00000068, 0x01010301, 0x01010301},
+				/* WATCHDOG1 */
+				{0x0000006C, 0x01010301, 0x01010301},
+				/* WATCHDOG2 */
+				{0x00000070, 0x01010301, 0x01010301},
+				/* WATCHDOG3 */
+				{0x00000074, 0x01010301, 0x01010301},
+				/* DAP */
+				{0x00000078, 0x03010001, 0x03010001},
+				/* WATCHDOG4 */
+				{0x0000007C, 0x01010301, 0x01010301},
+				/* POWER_MANAGER */
+				{0x00000080, 0x01010001, 0x01010001},
+				/* USB1_RXECC */
+				{0x00000084, 0x01010001, 0x01010001},
+				/* USB1_TXECC */
+				{0x00000088, 0x01010001, 0x01010001},
+				/* L4_NOC_PROBES */
+				{0x00000090, 0x01010001, 0x01010001},
+				/* L4_NOC_QOS */
+				{0x00000094, 0x01010001, 0x01010001}
+			};
+
+ncore_ccu_t ccu_noc_fw_lwsoc2fpga[] = {
+				/* LWSOC2FPGA_CSR */
+				{0x00000000, 0x0FFE0301, 0x0FFE0301}
+			};
+
+ncore_ccu_t ccu_noc_fw_soc2fpga[] = {
+				/* SOC2FPGA_CSR */
+				{0x00000000, 0x0FFE0301, 0x0FFE0301}
+			};
+
+ncore_ccu_t ccu_noc_fw_tcu[] = {
+				/* TCU_CSR */
+				{0x00000000, 0x01010001, 0x01010001}
+			};
+
+uint32_t init_ncore_ccu(void)
+{
+	ncore_ccu_t *ccu_module_table = NULL;
+	uint32_t base;
+	uint32_t size;
+	uint32_t val;
+	uint32_t offset;
+	uint32_t mask;
+	uint32_t set_mask = 0U;
+	uint32_t reg = 0U;
+
+	for (int index = 0; index < ARRAY_SIZE(ncore_ccu_modules); index++) {
+		base = ncore_ccu_modules[index].base;
+		size = ncore_ccu_modules[index].size;
+
+		switch (index) {
+		case 0:
+			ccu_module_table = ccu_caiu0;
+			size = (sizeof(ccu_caiu0) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 1:
+			ccu_module_table = ccu_ncaiu0;
+			size = (sizeof(ccu_ncaiu0) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 2:
+			ccu_module_table = ccu_ncaiu1;
+			size = (sizeof(ccu_ncaiu1) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 3:
+			ccu_module_table = ccu_ncaiu2;
+			size = (sizeof(ccu_ncaiu2) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 4:
+			ccu_module_table = ccu_ncaiu3;
+			size = (sizeof(ccu_ncaiu3) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 5:
+			ccu_module_table = ccu_dce0;
+			size = (sizeof(ccu_dce0) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 6:
+			ccu_module_table = ccu_dce1;
+			size = (sizeof(ccu_dce1) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 7:
+			ccu_module_table = ccu_dmi0;
+			size = (sizeof(ccu_dmi0) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 8:
+			ccu_module_table = ccu_dmi1;
+			size = (sizeof(ccu_dmi1) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 9:
+			ccu_module_table = ccu_noc_fw_l4_per;
+			size = (sizeof(ccu_noc_fw_l4_per) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 10:
+			ccu_module_table = ccu_noc_fw_l4_sys;
+			size = (sizeof(ccu_noc_fw_l4_sys) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 11:
+			ccu_module_table = ccu_noc_fw_lwsoc2fpga;
+			size = (sizeof(ccu_noc_fw_lwsoc2fpga) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 12:
+			ccu_module_table = ccu_noc_fw_soc2fpga;
+			size = (sizeof(ccu_noc_fw_soc2fpga) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 13:
+			ccu_module_table = ccu_noc_fw_tcu;
+			size = (sizeof(ccu_noc_fw_tcu) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		default:
+			break;
+		}
+
+		VERBOSE("CCU node base addr 0x%x, name %s, size 0x%x and module table %p\n",
+			base, ncore_ccu_modules[index].name, size, (uint32_t *)ccu_module_table);
+
+		/*
+		 * First element: offset
+		 * Second element: val
+		 * Third element: mask
+		 */
+		for (int i = 0; i < size; i++) {
+			offset = ccu_module_table[i].offset;
+			val = ccu_module_table[i].val;
+
+			/* Reads the masking bit value from the list */
+			mask = ccu_module_table[i].mask;
+
+			if (mask != 0) {
+				if (mask == 0xFFFFFFFF) {
+					reg = base + offset;
+					mmio_write_32((uintptr_t)reg, val);
+				} else {
+					/* Mask the value with the masking bits */
+					set_mask = val & mask;
+					reg = base + offset;
+
+					/* Clears and sets specific bits in the register */
+					mmio_clrsetbits_32((uintptr_t)reg, mask, set_mask);
+				}
+			}
+
+		}
+
+	}
+
+	return 0;
+}
+#endif
 
 static coh_ss_id_t subsystem_id;
 void get_subsystem_id(void)
@@ -29,6 +510,7 @@
 	subsystem_id.num_directory = directory;
 	subsystem_id.num_coh_agent = coh_agent;
 }
+
 uint32_t directory_init(void)
 {
 	uint32_t dir_sf_mtn, dir_sf_en;
@@ -42,7 +524,7 @@
 			/* Poll Active Bit */
 			ret = poll_active_bit(dir);
 			if (ret != 0) {
-				ERROR("Timeout during active bit polling");
+				ERROR("Timeout during active bit polling\n");
 				return -ETIMEDOUT;
 			}
 			/* Disable snoop filter, a bit per snoop filter */
@@ -51,6 +533,7 @@
 	}
 	return 0;
 }
+
 uint32_t coherent_agent_intfc_init(void)
 {
 	uint32_t dir, ca, ca_id, ca_type, ca_snoop_en;
@@ -65,11 +548,12 @@
 			ca_type = CACHING_AGENT_TYPE(ca_id);
 			if (ca_type == ACE_W_DVM || ca_type == ACE_L_W_DVM)
 				mmio_setbits_32(NCORE_CCU_CSR(NCORE_CSADSER0),
-				BIT(ca));
+						BIT(ca));
 		}
 	}
 	return 0;
 }
+
 uint32_t poll_active_bit(uint32_t dir)
 {
 	uint32_t timeout = 80000;
@@ -81,6 +565,7 @@
 	}
 	return -1;
 }
+
 void bypass_ocram_firewall(void)
 {
 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
@@ -92,6 +577,7 @@
 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
 }
+
 void ncore_enable_ocram_firewall(void)
 {
 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
@@ -103,6 +589,8 @@
 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
 }
+
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 uint32_t init_ncore_ccu(void)
 {
 	uint32_t status;
@@ -112,6 +600,7 @@
 	bypass_ocram_firewall();
 	return status;
 }
+#endif
 
 void setup_smmu_stream_id(void)
 {
@@ -130,7 +619,6 @@
 	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN0), TSN0);
 	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN1), TSN1);
 	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN2), TSN2);
-
 	/* Enabled Stream ctrl register for Agilex5 */
 	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_CTRL_REG_0_DMA0), ENABLE_STREAMID);
 	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_CTRL_REG_0_DMA1), ENABLE_STREAMID);
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
index 6cdbeb8..e00c4b7 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
@@ -9,192 +9,206 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include "socfpga_plat_def.h"
+
 #ifndef CCU_ACTIVATE_COH_FPGA
-#define CCU_ACTIVATE_COH_FPGA 0
+#define CCU_ACTIVATE_COH_FPGA			0
 #endif
-// Address map for ccu init
-#define addr_CAIUIDR1				(0x1C000000)
-#define addr_GRBUNRRUCR				(0x1c0ffff8)
-#define base_addr_NRS_CAIU0			(0x1c000000)
-#define base_addr_NRS_NCAIU0			(0x1c001000)
-#define base_addr_NRS_NCAIU1			(0x1c002000)
-#define base_addr_NRS_NCAIU2			(0x1c003000)
-#define base_addr_NRS_NCAIU3			(0x1c004000)
-#define base_addr_NRS_DCE0			(0x1c005000)
-#define base_addr_NRS_DCE1			(0x1c006000)
-//#define base_addr_NRS_DMI0			(0x1c007000)
-//#define base_addr_NRS_DMI1			(0x1c008000)
-//DMI
-#define ALT_CCU_CCU_DMI0_DMIUSMCTCR_ADDR	0x1C007300
-#define ALT_CCU_CCU_DMI1_DMIUSMCTCR_ADDR	0x1C008300
-//DSU
-#define ALT_CCU_DSU_CAIUAMIGR_ADDR		0x1C0003C0
-#define ALT_CCU_DSU_CAIUMIFSR_ADDR		0x1C0003C4
-#define ALT_CCU_DSU_CAIUGPRBLR1_ADDR		0x1C000414
-#define ALT_CCU_DSU_CAIUGPRBHR1_ADDR		0x1C000418
-#define ALT_CCU_DSU_CAIUGPRAR1_ADDR		0x1C000410
-#define ALT_CCU_DSU_CAIUGPRBLR2_ADDR		0x1C000424
-#define ALT_CCU_DSU_CAIUGPRBHR2_ADDR		0x1C000428
-#define ALT_CCU_DSU_CAIUGPRAR2_ADDR		0x1C000420
-#define ALT_CCU_DSU_CAIUGPRBLR4_ADDR		0x1C000444
-#define ALT_CCU_DSU_CAIUGPRBHR4_ADDR		0x1C000448
-#define ALT_CCU_DSU_CAIUGPRAR4_ADDR		0x1C000440
-#define ALT_CCU_DSU_CAIUGPRBLR5_ADDR		0x1C000454
-#define ALT_CCU_DSU_CAIUGPRBHR5_ADDR		0x1C000458
-#define ALT_CCU_DSU_CAIUGPRAR5_ADDR		0x1C000450
-#define ALT_CCU_DSU_CAIUGPRBLR6_ADDR		0x1C000464
-#define ALT_CCU_DSU_CAIUGPRBHR6_ADDR		0x1C000468
-#define ALT_CCU_DSU_CAIUGPRAR6_ADDR		0x1C000460
-#define ALT_CCU_DSU_CAIUGPRBLR7_ADDR		0x1C000474
-#define ALT_CCU_DSU_CAIUGPRBHR7_ADDR		0x1C000478
-#define ALT_CCU_DSU_CAIUGPRAR7_ADDR		0x1C000470
-#define ALT_CCU_DSU_CAIUGPRBLR8_ADDR		0x1C000484
-#define ALT_CCU_DSU_CAIUGPRBHR8_ADDR		0x1C000488
-#define ALT_CCU_DSU_CAIUGPRAR8_ADDR		0x1C000480
-#define ALT_CCU_DSU_CAIUGPRBLR9_ADDR		0x1C000494
-#define ALT_CCU_DSU_CAIUGPRBHR9_ADDR		0x1C000498
-#define ALT_CCU_DSU_CAIUGPRAR9_ADDR		0x1C000490
-#define ALT_CCU_DSU_CAIUGPRBLR10_ADDR		0x1C0004A4
-#define ALT_CCU_DSU_CAIUGPRBHR10_ADDR		0x1C0004A8
-#define ALT_CCU_DSU_CAIUGPRAR10_ADDR		0x1C0004A0
-//GIC
-#define ALT_CCU_GIC_M_XAIUAMIGR_ADDR		0x1C0023C0
-#define ALT_CCU_GIC_M_XAIUMIFSR_ADDR		0x1C0023C4
-#define ALT_CCU_GIC_M_XAIUGPRBLR1_ADDR		0x1C002414
-#define ALT_CCU_GIC_M_XAIUGPRBHR1_ADDR		0x1C002418
-#define ALT_CCU_GIC_M_XAIUGPRAR1_ADDR		0x1C002410
-#define ALT_CCU_GIC_M_XAIUGPRBLR6_ADDR		0x1C002464
-#define ALT_CCU_GIC_M_XAIUGPRBHR6_ADDR		0x1C002468
-#define ALT_CCU_GIC_M_XAIUGPRAR6_ADDR		0x1C002460
-#define ALT_CCU_GIC_M_XAIUGPRBLR8_ADDR		0x1C002484
-#define ALT_CCU_GIC_M_XAIUGPRBHR8_ADDR		0x1C002488
-#define ALT_CCU_GIC_M_XAIUGPRAR8_ADDR		0x1C002480
-#define ALT_CCU_GIC_M_XAIUGPRBLR10_ADDR		0x1C0024A4
-#define ALT_CCU_GIC_M_XAIUGPRBHR10_ADDR		0x1C0024A8
-#define ALT_CCU_GIC_M_XAIUGPRAR10_ADDR		0x1C0024A0
-//FPGA2SOC
-#define ALT_CCU_FPGA2SOC_XAIUAMIGR_ADDR		0x1C0013C0
-#define ALT_CCU_FPGA2SOC_XAIUMIFSR_ADDR		0x1C0013C4
-#define ALT_CCU_FPGA2SOC_XAIUGPRBLR1_ADDR	0x1C001414
-#define ALT_CCU_FPGA2SOC_XAIUGPRBHR1_ADDR	0x1C001418
-#define ALT_CCU_FPGA2SOC_XAIUGPRAR1_ADDR	0x1C001410
-#define ALT_CCU_FPGA2SOC_XAIUGPRBLR6_ADDR	0x1C001464
-#define ALT_CCU_FPGA2SOC_XAIUGPRBHR6_ADDR	0x1C001468
-#define ALT_CCU_FPGA2SOC_XAIUGPRAR6_ADDR	0x1C001460
-#define ALT_CCU_FPGA2SOC_XAIUGPRBLR8_ADDR	0x1C001484
-#define ALT_CCU_FPGA2SOC_XAIUGPRBHR8_ADDR	0x1C001488
-#define ALT_CCU_FPGA2SOC_XAIUGPRAR8_ADDR	0x1C001480
-#define ALT_CCU_FPGA2SOC_XAIUGPRBLR10_ADDR	0x1C0014A4
-#define ALT_CCU_FPGA2SOC_XAIUGPRBHR10_ADDR	0x1C0014A8
-#define ALT_CCU_FPGA2SOC_XAIUGPRAR10_ADDR	0x1C0014A0
-//TCU
-#define ALT_CCU_TCU_BASE 0x1C003000
-#define ALT_CCU_TCU_XAIUAMIGR_ADDR		ALT_CCU_TCU_BASE + 0x03C0
-#define ALT_CCU_TCU_XAIUMIFSR_ADDR		ALT_CCU_TCU_BASE + 0x03C4
-#define ALT_CCU_TCU_XAIUGPRBLR0_ADDR		ALT_CCU_TCU_BASE + 0x0404
-#define ALT_CCU_TCU_XAIUGPRBHR0_ADDR		ALT_CCU_TCU_BASE + 0x0408
-#define ALT_CCU_TCU_XAIUGPRAR0_ADDR		ALT_CCU_TCU_BASE + 0x0400
-#define ALT_CCU_TCU_XAIUGPRBLR1_ADDR		ALT_CCU_TCU_BASE + 0x0414
-#define ALT_CCU_TCU_XAIUGPRBHR1_ADDR		ALT_CCU_TCU_BASE + 0x0418
-#define ALT_CCU_TCU_XAIUGPRAR1_ADDR		ALT_CCU_TCU_BASE + 0x0410
-#define ALT_CCU_TCU_XAIUGPRBLR2_ADDR		ALT_CCU_TCU_BASE + 0x0424
-#define ALT_CCU_TCU_XAIUGPRBHR2_ADDR		ALT_CCU_TCU_BASE + 0x0428
-#define ALT_CCU_TCU_XAIUGPRAR2_ADDR		ALT_CCU_TCU_BASE + 0x0420
-#define ALT_CCU_TCU_XAIUGPRBLR6_ADDR		0x1C003464
-#define ALT_CCU_TCU_XAIUGPRBHR6_ADDR		0x1C003468
-#define ALT_CCU_TCU_XAIUGPRAR6_ADDR		0x1C003460
-#define ALT_CCU_TCU_XAIUGPRBLR8_ADDR		0x1C003484
-#define ALT_CCU_TCU_XAIUGPRBHR8_ADDR		0x1C003488
-#define ALT_CCU_TCU_XAIUGPRAR8_ADDR		0x1C003480
-#define ALT_CCU_TCU_XAIUGPRBLR10_ADDR		0x1C0034A4
-#define ALT_CCU_TCU_XAIUGPRBHR10_ADDR		0x1C0034A8
-#define ALT_CCU_TCU_XAIUGPRAR10_ADDR		0x1C0034A0
-//IOM
-#define ALT_CCU_CCU_IOM_XAIUAMIGR_ADDR		0x1C0043C0
-#define ALT_CCU_CCU_IOM_XAIUMIFSR_ADDR		0x1C0013C4
-#define ALT_CCU_IOM_XAIUGPRBLR1_ADDR		0x1C001414
-#define ALT_CCU_IOM_XAIUGPRBHR1_ADDR		0x1C001418
-#define ALT_CCU_IOM_XAIUGPRAR1_ADDR		0x1C001410
-#define ALT_CCU_CCU_IOM_XAIUGPRBLR6_ADDR	0x1C001464
-#define ALT_CCU_CCU_IOM_XAIUGPRBHR6_ADDR	0x1C001468
-#define ALT_CCU_CCU_IOM_XAIUGPRAR6_ADDR		0x1C001460
-#define ALT_CCU_CCU_IOM_XAIUGPRBLR8_ADDR	0x1C001484
-#define ALT_CCU_CCU_IOM_XAIUGPRBHR8_ADDR	0x1C001488
-#define ALT_CCU_CCU_IOM_XAIUGPRAR8_ADDR		0x1C001480
-#define ALT_CCU_CCU_IOM_XAIUGPRBLR10_ADDR	0x1C0014A4
-#define ALT_CCU_CCU_IOM_XAIUGPRBHR10_ADDR	0x1C0014A8
-#define ALT_CCU_CCU_IOM_XAIUGPRAR10_ADDR	0x1C0014A0
-//DCE
-#define ALT_CCU_DCE0_DCEUAMIGR_ADDR		0x1C0053C0
-#define ALT_CCU_DCE0_DCEUMIFSR_ADDR		0x1C0053C4
-#define ALT_CCU_DCE0_DCEUGPRBLR6_ADDR		0x1C005464
-#define ALT_CCU_DCE0_DCEUGPRBHR6_ADDR		0x1C005468
-#define ALT_CCU_DCE0_DCEUGPRAR6_ADDR		0x1C005460
-#define ALT_CCU_DCE0_DCEUGPRBLR8_ADDR		0x1C005484
-#define ALT_CCU_DCE0_DCEUGPRBHR8_ADDR		0x1C005488
-#define ALT_CCU_DCE0_DCEUGPRAR8_ADDR		0x1C005480
-#define ALT_CCU_DCE0_DCEUGPRBLR10_ADDR		0x1C0054A4
-#define ALT_CCU_DCE0_DCEUGPRBHR10_ADDR		0x1C0054A8
-#define ALT_CCU_DCE0_DCEUGPRAR10_ADDR		0x1C0054A0
-#define ALT_CCU_DCE1_DCEUAMIGR_ADDR		0x1C0063C0
-#define ALT_CCU_DCE1_DCEUMIFSR_ADDR		0x1C0063C4
-#define ALT_CCU_DCE1_DCEUGPRBLR6_ADDR		0x1C006464
-#define ALT_CCU_DCE1_DCEUGPRBHR6_ADDR		0x1C006468
-#define ALT_CCU_DCE1_DCEUGPRAR6_ADDR		0x1C006460
-#define ALT_CCU_DCE1_DCEUGPRBLR8_ADDR		0x1C006484
-#define ALT_CCU_DCE1_DCEUGPRBHR8_ADDR		0x1C006488
-#define ALT_CCU_DCE1_DCEUGPRAR8_ADDR		0x1C006480
-#define ALT_CCU_DCE1_DCEUGPRBLR10_ADDR		0x1C0064A4
-#define ALT_CCU_DCE1_DCEUGPRBHR10_ADDR		0x1C0064A8
-#define ALT_CCU_DCE1_DCEUGPRAR10_ADDR		0x1C0064A0
-#define offset_NRS_GPRAR0			(0x400)
-#define offset_NRS_GPRBLR0			(0x404)
-#define offset_NRS_GPRBHR0			(0x408)
-#define offset_NRS_GPRAR1			(0x410)
-#define offset_NRS_GPRBLR1			(0x414)
-#define offset_NRS_GPRBHR1			(0x418)
-#define offset_NRS_GPRAR2			(0x420)
-#define offset_NRS_GPRBLR2			(0x424)
-#define offset_NRS_GPRBHR2			(0x428)
-#define offset_NRS_GPRAR3			(0x430)
-#define offset_NRS_GPRBLR3			(0x434)
-#define offset_NRS_GPRBHR3			(0x438)
-#define offset_NRS_GPRAR4			(0x440)
-#define offset_NRS_GPRBLR4			(0x444)
-#define offset_NRS_GPRBHR4			(0x448)
-#define offset_NRS_GPRAR5			(0x450)
-#define offset_NRS_GPRBLR5			(0x454)
-#define offset_NRS_GPRBHR5			(0x458)
-#define offset_NRS_GPRAR6			(0x460)
-#define offset_NRS_GPRBLR6			(0x464)
-#define offset_NRS_GPRBHR6			(0x468)
-#define offset_NRS_GPRAR7			(0x470)
-#define offset_NRS_GPRBLR7			(0x474)
-#define offset_NRS_GPRBHR7			(0x478)
-#define offset_NRS_GPRAR8			(0x480)
-#define offset_NRS_GPRBLR8			(0x484)
-#define offset_NRS_GPRBHR8			(0x488)
-#define offset_NRS_GPRAR9			(0x490)
-#define offset_NRS_GPRBLR9			(0x494)
-#define offset_NRS_GPRBHR9			(0x498)
-#define offset_NRS_GPRAR10			(0x4a0)
-#define offset_NRS_GPRBLR10			(0x4a4)
-#define offset_NRS_GPRBHR10			(0x4a8)
-#define offset_NRS_AMIGR			(0x3c0)
-#define offset_NRS_MIFSR			(0x3c4)
-#define offset_NRS_DMIUSMCTCR			(0x300)
-#define base_addr_DII0_PSSPERIPHS		(0x10000)
-#define base_addr_DII0_LWHPS2FPGA		(0x20000)
-#define base_addr_DII0_HPS2FPGA_1G		(0x40000)
-#define base_addr_DII0_HPS2FPGA_15G		(0x400000)
-#define base_addr_DII0_HPS2FPGA_240G		(0x4000000)
-#define base_addr_DII1_MPFEREGS			(0x18000)
-#define base_addr_DII2_GICREGS			(0x1D000)
-#define base_addr_DII3_OCRAM			(0x0)
-#define base_addr_BHR				(0x0)
-#define base_addr_DMI_SDRAM_2G			(0x80000)
-#define base_addr_DMI_SDRAM_30G			(0x800000)
-#define base_addr_DMI_SDRAM_480G		(0x8000000)
+
+/* Macros */
+#define CCU_OFFSET_VAL_MASK				3U
+#define CCU_WORD_BYTE					4U
+
+// Address Map for CCU Init
+#define addr_CAIUIDR1				SOCFPGA_CCU_NOC_REG_BASE + 0x00000
+#define addr_GRBUNRRUCR				SOCFPGA_CCU_NOC_REG_BASE + 0xFFFF8
+#define base_addr_NRS_CAIU0			SOCFPGA_CCU_NOC_REG_BASE + 0x00000
+#define base_addr_NRS_NCAIU0			SOCFPGA_CCU_NOC_REG_BASE + 0x01000
+#define base_addr_NRS_NCAIU1			SOCFPGA_CCU_NOC_REG_BASE + 0x02000
+#define base_addr_NRS_NCAIU2			SOCFPGA_CCU_NOC_REG_BASE + 0x03000
+#define base_addr_NRS_NCAIU3			SOCFPGA_CCU_NOC_REG_BASE + 0x04000
+#define base_addr_NRS_DCE0			SOCFPGA_CCU_NOC_REG_BASE + 0x05000
+#define base_addr_NRS_DCE1			SOCFPGA_CCU_NOC_REG_BASE + 0x06000
+//#define base_addr_NRS_DMI0			SOCFPGA_CCU_NOC_REG_BASE + 0x07000
+//#define base_addr_NRS_DMI1			SOCFPGA_CCU_NOC_REG_BASE + 0x08000
+
+/* DMI */
+#define ALT_CCU_CCU_DMI0_DMIUSMCTCR_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x7300
+#define ALT_CCU_CCU_DMI1_DMIUSMCTCR_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x8300
+
+/* DSU */
+#define ALT_CCU_DSU_CAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3C0
+#define ALT_CCU_DSU_CAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3C4
+#define ALT_CCU_DSU_CAIUGPRBLR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x414
+#define ALT_CCU_DSU_CAIUGPRBHR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x418
+#define ALT_CCU_DSU_CAIUGPRAR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x410
+#define ALT_CCU_DSU_CAIUGPRBLR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x424
+#define ALT_CCU_DSU_CAIUGPRBHR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x428
+#define ALT_CCU_DSU_CAIUGPRAR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x420
+#define ALT_CCU_DSU_CAIUGPRBLR4_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x444
+#define ALT_CCU_DSU_CAIUGPRBHR4_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x448
+#define ALT_CCU_DSU_CAIUGPRAR4_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x440
+#define ALT_CCU_DSU_CAIUGPRBLR5_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x454
+#define ALT_CCU_DSU_CAIUGPRBHR5_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x458
+#define ALT_CCU_DSU_CAIUGPRAR5_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x450
+#define ALT_CCU_DSU_CAIUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x464
+#define ALT_CCU_DSU_CAIUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x468
+#define ALT_CCU_DSU_CAIUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x460
+#define ALT_CCU_DSU_CAIUGPRBLR7_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x474
+#define ALT_CCU_DSU_CAIUGPRBHR7_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x478
+#define ALT_CCU_DSU_CAIUGPRAR7_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x470
+#define ALT_CCU_DSU_CAIUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x484
+#define ALT_CCU_DSU_CAIUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x488
+#define ALT_CCU_DSU_CAIUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x480
+#define ALT_CCU_DSU_CAIUGPRBLR9_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x494
+#define ALT_CCU_DSU_CAIUGPRBHR9_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x498
+#define ALT_CCU_DSU_CAIUGPRAR9_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x490
+#define ALT_CCU_DSU_CAIUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x4A4
+#define ALT_CCU_DSU_CAIUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x4A8
+#define ALT_CCU_DSU_CAIUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x4A0
+
+/* GIC */
+#define ALT_CCU_GIC_M_XAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x23C0
+#define ALT_CCU_GIC_M_XAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x23C4
+#define ALT_CCU_GIC_M_XAIUGPRBLR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2414
+#define ALT_CCU_GIC_M_XAIUGPRBHR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2418
+#define ALT_CCU_GIC_M_XAIUGPRAR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2410
+#define ALT_CCU_GIC_M_XAIUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2464
+#define ALT_CCU_GIC_M_XAIUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2468
+#define ALT_CCU_GIC_M_XAIUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2460
+#define ALT_CCU_GIC_M_XAIUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2484
+#define ALT_CCU_GIC_M_XAIUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2488
+#define ALT_CCU_GIC_M_XAIUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2480
+#define ALT_CCU_GIC_M_XAIUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x24A4
+#define ALT_CCU_GIC_M_XAIUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x24A8
+#define ALT_CCU_GIC_M_XAIUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x24A0
+
+/* FPGA2SOC */
+#define ALT_CCU_FPGA2SOC_BASE			SOCFPGA_CCU_NOC_REG_BASE + 0x1000
+#define ALT_CCU_FPGA2SOC_XAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x13C0
+#define ALT_CCU_FPGA2SOC_XAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x13C4
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR1_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1414
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR1_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1418
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR1_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1410
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1464
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1468
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1460
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1484
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1488
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1480
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A4
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A8
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A0
+
+/* TCU */
+#define ALT_CCU_TCU_XAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x33C0
+#define ALT_CCU_TCU_XAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x33C4
+#define ALT_CCU_TCU_XAIUGPRBLR0_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3404
+#define ALT_CCU_TCU_XAIUGPRBHR0_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3408
+#define ALT_CCU_TCU_XAIUGPRAR0_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3400
+#define ALT_CCU_TCU_XAIUGPRBLR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3414
+#define ALT_CCU_TCU_XAIUGPRBHR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3418
+#define ALT_CCU_TCU_XAIUGPRAR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3410
+#define ALT_CCU_TCU_XAIUGPRBLR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3424
+#define ALT_CCU_TCU_XAIUGPRBHR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3428
+#define ALT_CCU_TCU_XAIUGPRAR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3420
+#define ALT_CCU_TCU_XAIUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3464
+#define ALT_CCU_TCU_XAIUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3468
+#define ALT_CCU_TCU_XAIUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3460
+#define ALT_CCU_TCU_XAIUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3484
+#define ALT_CCU_TCU_XAIUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3488
+#define ALT_CCU_TCU_XAIUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3480
+#define ALT_CCU_TCU_XAIUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x34A4
+#define ALT_CCU_TCU_XAIUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x34A8
+#define ALT_CCU_TCU_XAIUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x34A0
+
+/* IOM */
+#define ALT_CCU_CCU_IOM_XAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x43C0
+#define ALT_CCU_CCU_IOM_XAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x13C4
+#define ALT_CCU_IOM_XAIUGPRBLR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1414
+#define ALT_CCU_IOM_XAIUGPRBHR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1418
+#define ALT_CCU_IOM_XAIUGPRAR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1410
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1464
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1468
+#define ALT_CCU_CCU_IOM_XAIUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1460
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1484
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1488
+#define ALT_CCU_CCU_IOM_XAIUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1480
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A4
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A8
+#define ALT_CCU_CCU_IOM_XAIUGPRAR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A0
+
+/* DCE */
+#define ALT_CCU_DCE0_DCEUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x53C0
+#define ALT_CCU_DCE0_DCEUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x53C4
+#define ALT_CCU_DCE0_DCEUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5464
+#define ALT_CCU_DCE0_DCEUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5468
+#define ALT_CCU_DCE0_DCEUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5460
+#define ALT_CCU_DCE0_DCEUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5484
+#define ALT_CCU_DCE0_DCEUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5488
+#define ALT_CCU_DCE0_DCEUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5480
+#define ALT_CCU_DCE0_DCEUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x54A4
+#define ALT_CCU_DCE0_DCEUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x54A8
+#define ALT_CCU_DCE0_DCEUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x54A0
+#define ALT_CCU_DCE1_DCEUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x63C0
+#define ALT_CCU_DCE1_DCEUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x63C4
+#define ALT_CCU_DCE1_DCEUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6464
+#define ALT_CCU_DCE1_DCEUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6468
+#define ALT_CCU_DCE1_DCEUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6460
+#define ALT_CCU_DCE1_DCEUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6484
+#define ALT_CCU_DCE1_DCEUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6488
+#define ALT_CCU_DCE1_DCEUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6480
+#define ALT_CCU_DCE1_DCEUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x64A4
+#define ALT_CCU_DCE1_DCEUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x64A8
+#define ALT_CCU_DCE1_DCEUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x64A0
+#define offset_NRS_GPRAR0			0x400
+#define offset_NRS_GPRBLR0			0x404
+#define offset_NRS_GPRBHR0			0x408
+#define offset_NRS_GPRAR1			0x410
+#define offset_NRS_GPRBLR1			0x414
+#define offset_NRS_GPRBHR1			0x418
+#define offset_NRS_GPRAR2			0x420
+#define offset_NRS_GPRBLR2			0x424
+#define offset_NRS_GPRBHR2			0x428
+#define offset_NRS_GPRAR3			0x430
+#define offset_NRS_GPRBLR3			0x434
+#define offset_NRS_GPRBHR3			0x438
+#define offset_NRS_GPRAR4			0x440
+#define offset_NRS_GPRBLR4			0x444
+#define offset_NRS_GPRBHR4			0x448
+#define offset_NRS_GPRAR5			0x450
+#define offset_NRS_GPRBLR5			0x454
+#define offset_NRS_GPRBHR5			0x458
+#define offset_NRS_GPRAR6			0x460
+#define offset_NRS_GPRBLR6			0x464
+#define offset_NRS_GPRBHR6			0x468
+#define offset_NRS_GPRAR7			0x470
+#define offset_NRS_GPRBLR7			0x474
+#define offset_NRS_GPRBHR7			0x478
+#define offset_NRS_GPRAR8			0x480
+#define offset_NRS_GPRBLR8			0x484
+#define offset_NRS_GPRBHR8			0x488
+#define offset_NRS_GPRAR9			0x490
+#define offset_NRS_GPRBLR9			0x494
+#define offset_NRS_GPRBHR9			0x498
+#define offset_NRS_GPRAR10			0x4A0
+#define offset_NRS_GPRBLR10			0x4A4
+#define offset_NRS_GPRBHR10			0x4A8
+#define offset_NRS_AMIGR			0x3C0
+#define offset_NRS_MIFSR			0x3C4
+#define offset_NRS_DMIUSMCTCR			0x300
+#define base_addr_DII0_PSSPERIPHS		0x10000
+#define base_addr_DII0_LWHPS2FPGA		0x20000
+#define base_addr_DII0_HPS2FPGA_1G		0x40000
+#define base_addr_DII0_HPS2FPGA_15G		0x400000
+#define base_addr_DII0_HPS2FPGA_240G		0x4000000
+#define base_addr_DII1_MPFEREGS			0x18000
+#define base_addr_DII2_GICREGS			0x1D000
+#define base_addr_DII3_OCRAM			0x0
+#define base_addr_BHR				0x0
+#define base_addr_DMI_SDRAM_2G			0x80000
+#define base_addr_DMI_SDRAM_30G			0x800000
+#define base_addr_DMI_SDRAM_480G		0x8000000
 // ((0x0<<9) | (0xf<<20) | (0x1<<30) | (0x1<<31))
 #define wr_DII0_PSSPERIPHS			0xC0F00000
 // ((0x0<<9) | (0x11<<20) | (0x1<<30) | (0x1<<31))
@@ -228,54 +242,46 @@
 // ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x17<<20) | (0x0<<30) | (0x1<<31))
 #define wr_DMI_SDRAM_30G			0x81700006
 // ((0x0<<9) | (0x1a<<20) | (0x0<<30) | (0x1<<31))
-#define wr_DMI_SDRAM_240G_ORDERED		0x81a00000
+#define wr_DMI_SDRAM_240G_ORDERED		0x81A00000
 // ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x1a<<20) | (0x0<<30) | (0x1<<31))
-#define wr_DMI_SDRAM_240G			0x81a00006
+#define wr_DMI_SDRAM_240G			0x81A00006
 // ((0x0<<9) | (0x1b<<20) | (0x0<<30) | (0x1<<31))
-#define wr_DMI_SDRAM_480G_ORDERED		0x81b00000
+#define wr_DMI_SDRAM_480G_ORDERED		0x81B00000
 // ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x1b<<20) | (0x0<<30) | (0x1<<31))
-#define wr_DMI_SDRAM_480G			0x81b00006
+#define wr_DMI_SDRAM_480G			0x81B00006
 
 typedef enum CCU_REGION_SECURITY_e {
-    //
-    // Allow secure accesses only.
-    //
+	/* Allow secure accesses only. */
 	CCU_REGION_SECURITY_SECURE_ONLY,
-    //
-    // Allow non-secure accesses only.
-    //
+
+	/* Allow non-secure accesses only. */
 	CCU_REGION_SECURITY_NON_SECURE_ONLY,
-    //
-    // Allow accesses of any security state.
-    //
+
+	/* Allow accesses of any security state. */
 	CCU_REGION_SECURITY_DONT_CARE
 } CCU_REGION_SECURITY_t;
+
 typedef enum CCU_REGION_PRIVILEGE_e {
-    //
-    // Allow privileged accesses only.
-    //
+	/* Allow privileged accesses only. */
 	CCU_REGION_PRIVILEGE_PRIVILEGED_ONLY,
-    //
-    // Allow unprivileged accesses only.
-    //
+	/* Allow unprivileged accesses only. */
 	CCU_REGION_PRIVILEGE_NON_PRIVILEGED_ONLY,
-    //
-    // Allow accesses of any privilege.
-    //
+	/* Allow accesses of any privilege. */
 	CCU_REGION_PRIVILEGE_DONT_CARE
 } CCU_REGION_PRIVILEGE_t;
-//
-// Initializes the CCU by enabling all regions except RAM 1 - 5.
-// This is needed because of an RTL change around 2016.02.24.
-//
-// Runtime measurement:
-//  - arm     : 14,830,000 ps (2016.05.31; sanity/printf_aarch32)
-//  - aarch64 : 14,837,500 ps (2016.05.31; sanity/printf)
-//
-// Runtime history:
-//  - arm     : 20,916,668 ps (2016.05.30; sanity/printf_aarch32)
-//  - aarch64 : 20,924,168 ps (2016.05.30; sanity/printf)
-//
+
+/*
+ * Initializes the CCU by enabling all regions except RAM 1 - 5.
+ * This is needed because of an RTL change around 2016.02.24.
+ *
+ * Runtime measurement:
+ *  - arm     : 14,830,000 ps (2016.05.31; sanity/printf_aarch32)
+ *  - aarch64 : 14,837,500 ps (2016.05.31; sanity/printf)
+ *
+ * Runtime history:
+ *  - arm     : 20,916,668 ps (2016.05.30; sanity/printf_aarch32)
+ *  - aarch64 : 20,924,168 ps (2016.05.30; sanity/printf)
+ */
 int ccu_hps_init(void);
 
 typedef enum ccu_hps_ram_region_e {
@@ -287,19 +293,21 @@
 	ccu_hps_ram_region_ramspace5 = 5,
 } ccu_hps_ram_region_t;
 
-// Disables a RAM (OCRAM) region with the given ID.
+/* Disables a RAM (OCRAM) region with the given ID. */
 int ccu_hps_ram_region_disable(int id);
 
-// Enables a RAM (OCRAM) region with the given ID.
+/* Enables a RAM (OCRAM) region with the given ID. */
 int ccu_hps_ram_region_enable(int id);
 
-// Attempts to remap a RAM (OCRAM) region with the given ID to span the given
-// start and end address. It also assigns the security and privilege policy.
-// Regions must be a power-of-two size with a minimum size of 64B.
+/*
+ * Attempts to remap a RAM (OCRAM) region with the given ID to span the given
+ * start and end address. It also assigns the security and privilege policy.
+ * Regions must be a power-of-two size with a minimum size of 64B.
+ */
 int ccu_hps_ram_region_remap(int id, uintptr_t start, uintptr_t end,
-CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
+	CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
 
-// Verifies that all enabled RAM (OCRAM) regions does not overlap.
+/* Verifies that all enabled RAM (OCRAM) regions does not overlap. */
 int ccu_hps_ram_validate(void);
 
 typedef enum ccu_hps_mem_region_e {
@@ -312,19 +320,21 @@
 	ccu_hps_mem_region_memspace1e = 6,
 } ccu_hps_mem_region_t;
 
-// Disables mem0 (DDR) region with the given ID.
+/* Disables mem0 (DDR) region with the given ID. */
 int ccu_hps_mem0_region_disable(int id);
 
-// Enables mem0 (DDR) region with the given ID.
+/* Enables mem0 (DDR) region with the given ID. */
 int ccu_hps_mem0_region_enable(int id);
 
-// Attempts to remap mem0 (DDR) region with the given ID to span the given
-// start and end address. It also assigns the security nad privlege policy.
-// Regions must be a power-of-two in size with a minimum size of 64B.
+/*
+ * Attempts to remap mem0 (DDR) region with the given ID to span the given
+ * start and end address. It also assigns the security nad privlege policy.
+ * Regions must be a power-of-two in size with a minimum size of 64B.
+ */
 int ccu_hps_mem0_region_remap(int id, uintptr_t start, uintptr_t end,
-CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
+	CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
 
-// Verifies that all enabled mem0 (DDR) regions does not overlap.
+/* Verifies that all enabled mem0 (DDR) regions does not overlap. */
 int ccu_hps_mem0_validate(void);
 
 typedef enum ccu_hps_ios_region_e {
@@ -342,14 +352,23 @@
 	ccu_hps_ios_region_iospace2c = 11,
 } ccu_hps_ios_region_t;
 
-// Disables the IOS (IO Slave) region with the given ID.
+/* Disables the IOS (IO Slave) region with the given ID. */
 int ccu_hps_ios_region_disable(int id);
 
-// Enables the IOS (IO Slave) region with the given ID.
+/* Enables the IOS (IO Slave) region with the given ID. */
 int ccu_hps_ios_region_enable(int id);
 
+typedef struct ncore_ccu_reg {
+			char name[50];
+			uint32_t base;
+			uint32_t size;
+		} ncore_ccu_reg_t;
 
-#define NCORE_CCU_OFFSET			0xf7000000
+typedef struct ncore_ccu {
+			uint32_t offset;
+			uint32_t val;
+			uint32_t mask;
+		} ncore_ccu_t;
 
 /* Coherent Sub-System Address Map */
 #define NCORE_CAIU_OFFSET			0x00000
@@ -358,43 +377,49 @@
 #define NCORE_NCBU_SIZE				0x01000
 #define NCORE_DIRU_OFFSET			0x80000
 #define NCORE_DIRU_SIZE				0x01000
-#define NCORE_CMIU_OFFSET			0xc0000
+#define NCORE_CMIU_OFFSET			0xC0000
 #define NCORE_CMIU_SIZE				0x01000
-#define NCORE_CSR_OFFSET			0xff000
+#define NCORE_CSR_OFFSET			0xFF000
 #define NCORE_CSADSERO				0x00040
-#define NCORE_CSUIDR				0x00ff8
-#define NCORE_CSIDR				0x00ffc
+#define NCORE_CSUIDR				0x00FF8
+#define NCORE_CSIDR				0x00FFC
+
 /* Directory Unit Register Map */
 #define NCORE_DIRUSFER				0x00010
 #define NCORE_DIRUMRHER				0x00070
 #define NCORE_DIRUSFMCR				0x00080
 #define NCORE_DIRUSFMAR				0x00084
+
 /* Coherent Agent Interface Unit Register Map */
-#define NCORE_CAIUIDR				0x00ffc
+#define NCORE_CAIUIDR				0x00FFC
+
 /* Snoop Enable Register */
 #define NCORE_DIRUCASER0			0x00040
 #define NCORE_DIRUCASER1			0x00044
 #define NCORE_DIRUCASER2			0x00048
-#define NCORE_DIRUCASER3			0x0004c
+#define NCORE_DIRUCASER3			0x0004C
 #define NCORE_CSADSER0				0x00040
 #define NCORE_CSADSER1				0x00044
 #define NCORE_CSADSER2				0x00048
-#define NCORE_CSADSER3				0x0004c
+#define NCORE_CSADSER3				0x0004C
+
 /* Protocols Definition */
 #define ACE_W_DVM				0
 #define ACE_L_W_DVM				1
 #define ACE_WO_DVM				2
 #define ACE_L_WO_DVM				3
-/* Bypass OC Ram Firewall */
+
+/* Bypass OCRAM Firewall */
 #define NCORE_FW_OCRAM_BLK_BASE			0x100200
 #define NCORE_FW_OCRAM_BLK_CGF1			0x04
 #define NCORE_FW_OCRAM_BLK_CGF2			0x08
-#define NCORE_FW_OCRAM_BLK_CGF3			0x0c
+#define NCORE_FW_OCRAM_BLK_CGF3			0x0C
 #define NCORE_FW_OCRAM_BLK_CGF4			0x10
 #define OCRAM_PRIVILEGED_MASK			BIT(29)
 #define OCRAM_SECURE_MASK			BIT(30)
+
 /* Macros */
-#define NCORE_CCU_REG(base)			(NCORE_CCU_OFFSET + (base))
+#define NCORE_CCU_REG(base)			(SOCFPGA_CCU_NOC_REG_BASE + (base))
 #define NCORE_CCU_CSR(reg)			(NCORE_CCU_REG(NCORE_CSR_OFFSET)\
 						+ (reg))
 #define NCORE_CCU_DIR(reg)			(NCORE_CCU_REG(NCORE_DIRU_OFFSET)\
@@ -407,14 +432,14 @@
 						+ NCORE_CAIU_SIZE * (x))
 #define COH_CPU0_BYPASS_REG(reg)		(NCORE_CCU_REG(NCORE_FW_OCRAM_BLK_BASE)\
 						+ (reg))
-#define CSUIDR_NUM_CMI(x)			(((x) & 0x3f000000) >> 24)
-#define CSUIDR_NUM_DIR(x)			(((x) & 0x003f0000) >> 16)
-#define CSUIDR_NUM_NCB(x)			(((x) & 0x00003f00) >> 8)
-#define CSUIDR_NUM_CAI(x)			(((x) & 0x0000007f) >> 0)
-#define CSIDR_NUM_SF(x)				(((x) & 0x007c0000) >> 18)
+#define CSUIDR_NUM_CMI(x)			(((x) & 0x3F000000) >> 24)
+#define CSUIDR_NUM_DIR(x)			(((x) & 0x003F0000) >> 16)
+#define CSUIDR_NUM_NCB(x)			(((x) & 0x00003F00) >> 8)
+#define CSUIDR_NUM_CAI(x)			(((x) & 0x0000007F) >> 0)
+#define CSIDR_NUM_SF(x)				(((x) & 0x007C0000) >> 18)
 #define SNOOP_FILTER_ID(x)			(((x) << 16))
 #define CACHING_AGENT_BIT(x)			(((x) & 0x08000) >> 15)
-#define CACHING_AGENT_TYPE(x)			(((x) & 0xf0000) >> 16)
+#define CACHING_AGENT_TYPE(x)			(((x) & 0xF0000) >> 16)
 
 typedef struct coh_ss_id {
 	uint8_t num_coh_mem;
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/drivers/sdmmc/sdmmc.c b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
index 8666f54..48f91eb 100644
--- a/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,6 +20,7 @@
 
 #include "agilex5_pinmux.h"
 #include "sdmmc.h"
+#include "socfpga_mailbox.h"
 
 static const struct mmc_ops *ops;
 static unsigned int mmc_ocr_value;
@@ -518,7 +520,8 @@
 		return ret;
 	}
 
-	memcpy(&mmc_csd, &resp_data, sizeof(resp_data));
+	memcpy_s(&mmc_csd, sizeof(mmc_csd) / MBOX_WORD_BYTE,
+		&resp_data, sizeof(resp_data) / MBOX_WORD_BYTE);
 
 	/* CMD7: Select Card */
 	ret = sdmmc_send_cmd(MMC_CMD(7), rca << RCA_SHIFT_OFFSET,
@@ -758,7 +761,8 @@
 		(params->bus_width == MMC_BUS_WIDTH_4) ||
 		(params->bus_width == MMC_BUS_WIDTH_8)));
 
-	memcpy(&cdns_params, params, sizeof(struct cdns_sdmmc_params));
+	memcpy_s(&cdns_params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE,
+		params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE);
 	cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
 	cdns_params.cdn_sdmmc_dev_mode = SD_DS;
 
diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
index b2913c7..7e1d0c0 100644
--- a/plat/intel/soc/common/include/socfpga_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,12 +11,12 @@
 #define HANDOFF_MAGIC_HEADER			0x424f4f54	/* BOOT */
 #define HANDOFF_MAGIC_PINMUX_SEL		0x504d5558	/* PMUX */
 #define HANDOFF_MAGIC_IOCTLR			0x494f4354	/* IOCT */
-#define HANDOFF_MAGIC_FPGA				0x46504741	/* FPGA */
+#define HANDOFF_MAGIC_FPGA			0x46504741	/* FPGA */
 #define HANDOFF_MAGIC_IODELAY			0x444c4159	/* DLAY */
-#define HANDOFF_MAGIC_CLOCK				0x434c4b53	/* CLKS */
-#define HANDOFF_MAGIC_MISC				0x4d495343	/* MISC */
+#define HANDOFF_MAGIC_CLOCK			0x434c4b53	/* CLKS */
+#define HANDOFF_MAGIC_MISC			0x4d495343	/* MISC */
 #define HANDOFF_MAGIC_PERIPHERAL		0x50455249	/* PERIPHERAL */
-#define HANDOFF_MAGIC_DDR				0x5344524d	/* DDR */
+#define HANDOFF_MAGIC_DDR			0x5344524d	/* DDR */
 
 #include <socfpga_plat_def.h>
 
@@ -126,6 +127,8 @@
 	uint32_t	clock_magic;
 	uint32_t	clock_length;
 	uint32_t	_pad_0x588_0x590[2];
+
+	/* main group PLL */
 	uint32_t	main_pll_nocclk;
 	uint32_t	main_pll_nocdiv;
 	uint32_t	main_pll_pllglob;
@@ -135,6 +138,8 @@
 	uint32_t	main_pll_pllc2;
 	uint32_t	main_pll_pllc3;
 	uint32_t	main_pll_pllm;
+
+	/* peripheral group PLL */
 	uint32_t	per_pll_emacctl;
 	uint32_t	per_pll_gpiodiv;
 	uint32_t	per_pll_pllglob;
@@ -144,29 +149,25 @@
 	uint32_t	per_pll_pllc2;
 	uint32_t	per_pll_pllc3;
 	uint32_t	per_pll_pllm;
+
+	/* control group */
 	uint32_t	alt_emacactr;
 	uint32_t	alt_emacbctr;
 	uint32_t	alt_emacptpctr;
 	uint32_t	alt_gpiodbctr;
-	uint32_t	alt_sdmmcctr;
 	uint32_t	alt_s2fuser0ctr;
 	uint32_t	alt_s2fuser1ctr;
 	uint32_t	alt_psirefctr;
-	/* TODO: Temp added for clk manager. */
-	uint32_t	qspi_clk_khz;
+	uint32_t	alt_usb31ctr;
+	uint32_t	alt_dsuctr;
+	uint32_t	alt_core01ctr;
+	uint32_t	alt_core23ctr;
+	uint32_t	alt_core2ctr;
+	uint32_t	alt_core3ctr;
 	uint32_t	hps_osc_clk_hz;
 	uint32_t	fpga_clk_hz;
-	/* TODO: Temp added for clk manager. */
-	uint32_t	ddr_reset_type;
-	/* TODO: Temp added for clk manager. */
-	uint32_t	hps_status_coldreset;
-	/* TODO: Temp remove due to add in extra handoff data */
-	//uint32_t	_pad_0x604_0x610[3];
+	uint32_t	_pad_0x604_0x610[3];
 #endif
-	/* misc configuration */
-	uint32_t	misc_magic;
-	uint32_t	misc_length;
-	uint32_t	_pad_0x618_0x620[2];
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 	/* peripheral configuration - select */
@@ -179,7 +180,7 @@
 	uint32_t	ddr_magic;
 	uint32_t	ddr_length;
 	uint32_t	_pad_0x1C_0x20[2];
-	uint32_t	ddr_array[4];	/* offset, value */
+	uint32_t	ddr_config;	/* BIT[0]-Dual Port. BIT[1]-Dual EMIF */
 #endif
 } handoff;
 
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 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/include/socfpga_vab.h b/plat/intel/soc/common/include/socfpga_vab.h
index f6081df..4587d7f 100644
--- a/plat/intel/soc/common/include/socfpga_vab.h
+++ b/plat/intel/soc/common/include/socfpga_vab.h
@@ -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
  */
@@ -7,10 +8,28 @@
 #ifndef SOCFPGA_VAB_H
 #define SOCFPGA_VAB_H
 
-
 #include <stdlib.h>
 #include "socfpga_fcs.h"
 
+/* Macros */
+#define IS_BYTE_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)
+#define BYTE_ALIGN(x, a)		__ALIGN_MASK((x), (typeof(x))(a)-1)
+#define __ALIGN_MASK(x, mask)		(((x)+(mask))&~(mask))
+#define VAB_CERT_HEADER_SIZE		sizeof(struct fcs_hps_vab_certificate_header)
+#define VAB_CERT_MAGIC_OFFSET		offsetof(struct fcs_hps_vab_certificate_header, d)
+#define VAB_CERT_FIT_SHA384_OFFSET	offsetof(struct fcs_hps_vab_certificate_data, fcs_sha384[0])
+#define SDM_CERT_MAGIC_NUM		0x25D04E7F
+#define CHUNKSZ_PER_WD_RESET		(256 * 1024)
+#define CCERT_CMD_TEST_PGM_MASK		0x80000000 //TODO: ATF FDT location
+
+/* SHA related return Macro */
+#define ENOVABCERT			1 /* VAB certificate not available */
+#define EIMGERR				2 /* Image format/size not valid */
+#define ETIMEOUT			3 /* Execution timeout */
+#define EPROCESS			4 /* Process error */
+#define EKEYREJECTED			5 /* Key was rejected by service */
+#define EINITREJECTED			6 /* VAB init was rejected */
+
 struct fcs_hps_vab_certificate_data {
 	uint32_t vab_cert_magic_num;			/* offset 0x10 */
 	uint32_t flags;
@@ -27,28 +46,9 @@
 	/* keychain starts at offset 0x50 */
 };
 
-/* Macros */
-#define IS_BYTE_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)
-#define BYTE_ALIGN(x, a)		__ALIGN_MASK((x), (typeof(x))(a)-1)
-#define __ALIGN_MASK(x, mask)		(((x)+(mask))&~(mask))
-#define VAB_CERT_HEADER_SIZE		sizeof(struct fcs_hps_vab_certificate_header)
-#define VAB_CERT_MAGIC_OFFSET		offsetof(struct fcs_hps_vab_certificate_header, d)
-#define VAB_CERT_FIT_SHA384_OFFSET	offsetof(struct fcs_hps_vab_certificate_data, fcs_sha384[0])
-#define SDM_CERT_MAGIC_NUM		0x25D04E7F
-#define CHUNKSZ_PER_WD_RESET		(256 * 1024)
-
-/* SHA related return Macro */
-#define ENOVABIMG		1 /* VAB certificate not available */
-#define EIMGERR		2 /* Image format/size not valid */
-#define ETIMEOUT		3 /* Execution timeout */
-#define EPROCESS		4 /* Process error */
-#define EKEYREJECTED		5/* Key was rejected by service */
-
 /* Function Definitions */
-static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz);
-int socfpga_vendor_authentication(void **p_image, size_t *p_size);
-static uint32_t get_unaligned_le32(const void *p);
-void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
-unsigned char *output, unsigned int chunk_sz);
-
+size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz);
+uint32_t get_unaligned_le32(const void *p);
+int socfpga_vab_authentication(void **p_image, size_t *p_size);
+int socfpga_vab_init(unsigned int image_id);
 #endif
diff --git a/plat/intel/soc/common/lib/sha/sha.c b/plat/intel/soc/common/lib/sha/sha.c
new file mode 100644
index 0000000..9a6adc6
--- /dev/null
+++ b/plat/intel/soc/common/lib/sha/sha.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+#include <tools_share/firmware_image_package.h>
+
+#include "sha.h"
+#include "wdt/watchdog.h"
+
+/* SHA384 certificate ID */
+#define SHA384_H0	0xcbbb9d5dc1059ed8ULL
+#define SHA384_H1	0x629a292a367cd507ULL
+#define SHA384_H2	0x9159015a3070dd17ULL
+#define SHA384_H3	0x152fecd8f70e5939ULL
+#define SHA384_H4	0x67332667ffc00b31ULL
+#define SHA384_H5	0x8eb44a8768581511ULL
+#define SHA384_H6	0xdb0c2e0d64f98fa7ULL
+#define SHA384_H7	0x47b5481dbefa4fa4ULL
+
+/* SHA512 certificate ID */
+#define SHA512_H0	0x6a09e667f3bcc908ULL
+#define SHA512_H1	0xbb67ae8584caa73bULL
+#define SHA512_H2	0x3c6ef372fe94f82bULL
+#define SHA512_H3	0xa54ff53a5f1d36f1ULL
+#define SHA512_H4	0x510e527fade682d1ULL
+#define SHA512_H5	0x9b05688c2b3e6c1fULL
+#define SHA512_H6	0x1f83d9abfb41bd6bULL
+#define SHA512_H7	0x5be0cd19137e2179ULL
+
+void sha384_init(sha512_context *ctx)
+{
+	ctx->state[0] = SHA384_H0;
+	ctx->state[1] = SHA384_H1;
+	ctx->state[2] = SHA384_H2;
+	ctx->state[3] = SHA384_H3;
+	ctx->state[4] = SHA384_H4;
+	ctx->state[5] = SHA384_H5;
+	ctx->state[6] = SHA384_H6;
+	ctx->state[7] = SHA384_H7;
+	ctx->count[0] = ctx->count[1] = 0;
+}
+
+void sha384_update(sha512_context *ctx, const uint8_t *input, uint32_t length)
+{
+	sha512_base_do_update(ctx, input, length);
+}
+
+void sha384_finish(sha512_context *ctx, uint8_t digest[SHA384_SUM_LEN])
+{
+	int i;
+
+	sha512_base_do_finalize(ctx);
+	for (i = 0; i < SHA384_SUM_LEN / sizeof(uint64_t); i++)
+		PUT_UINT64_BE(ctx->state[i], digest, i * 8);
+}
+
+void sha384_start(const unsigned char *input, unsigned int len,
+					unsigned char *output, unsigned int chunk_sz)
+{
+	/* TODO: Shall trigger watchdog for each chuck byte. */
+	sha512_context ctx;
+	const unsigned char *end;
+	unsigned char *curr;
+	int chunk;
+
+	sha384_init(&ctx);
+
+	curr = (unsigned char *)input;
+	end = input + len;
+	while (curr < end) {
+		chunk = end - curr;
+		if (chunk > chunk_sz) {
+			chunk = chunk_sz;
+		}
+		sha384_update(&ctx, curr, chunk);
+		curr += chunk;
+		watchdog_sw_rst();
+	}
+
+	sha384_finish(&ctx, output);
+}
+
+/* SHA512 Start Here */
+void sha512_init(sha512_context *ctx)
+{
+	ctx->state[0] = SHA512_H0;
+	ctx->state[1] = SHA512_H1;
+	ctx->state[2] = SHA512_H2;
+	ctx->state[3] = SHA512_H3;
+	ctx->state[4] = SHA512_H4;
+	ctx->state[5] = SHA512_H5;
+	ctx->state[6] = SHA512_H6;
+	ctx->state[7] = SHA512_H7;
+	ctx->count[0] = ctx->count[1] = 0;
+}
+
+void sha512_update(sha512_context *ctx, const uint8_t *input, uint32_t length)
+{
+	sha512_base_do_update(ctx, input, length);
+}
+
+void sha512_finish(sha512_context *ctx, uint8_t digest[SHA512_SUM_LEN])
+{
+	int i;
+
+	sha512_base_do_finalize(ctx);
+	for (i = 0; i < SHA512_SUM_LEN / sizeof(uint64_t); i++)
+		PUT_UINT64_BE(ctx->state[i], digest, i * 8);
+}
+
+void sha512_start(const unsigned char *input, unsigned int len, unsigned char *output)
+{
+	/* TODO: Shall trigger watchdog for each chuck byte. */
+	sha512_context ctx;
+
+	sha384_init(&ctx);
+	sha512_update(&ctx, input, len);
+	sha512_finish(&ctx, output);
+}
+
+void sha512_transform(uint64_t *state, const uint8_t *input)
+{
+	uint64_t a, b, c, d, e, f, g, h, t1, t2;
+
+	int i;
+	uint64_t W[16];
+
+	/* load the state into our registers */
+	a = state[0];   b = state[1];   c = state[2];   d = state[3];
+	e = state[4];   f = state[5];   g = state[6];   h = state[7];
+
+	/* now iterate */
+	for (i = 0 ; i < 80; i += 8) {
+		if (!(i & 8)) {
+			int j;
+
+			if (i < 16) {
+				/* load the input */
+				for (j = 0; j < 16; j++)
+					LOAD_OP(i + j, W, input);
+			} else {
+				for (j = 0; j < 16; j++) {
+					BLEND_OP(i + j, W);
+				}
+			}
+		}
+
+		t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i & 15)];
+		t2 = e0(a) + Maj(a, b, c);    d += t1;    h = t1 + t2;
+		t1 = g + e1(d) + Ch(d, e, f) + sha512_K[i+1] + W[(i & 15) + 1];
+		t2 = e0(h) + Maj(h, a, b);    c += t1;    g = t1 + t2;
+		t1 = f + e1(c) + Ch(c, d, e) + sha512_K[i+2] + W[(i & 15) + 2];
+		t2 = e0(g) + Maj(g, h, a);    b += t1;    f = t1 + t2;
+		t1 = e + e1(b) + Ch(b, c, d) + sha512_K[i+3] + W[(i & 15) + 3];
+		t2 = e0(f) + Maj(f, g, h);    a += t1;    e = t1 + t2;
+		t1 = d + e1(a) + Ch(a, b, c) + sha512_K[i+4] + W[(i & 15) + 4];
+		t2 = e0(e) + Maj(e, f, g);    h += t1;    d = t1 + t2;
+		t1 = c + e1(h) + Ch(h, a, b) + sha512_K[i+5] + W[(i & 15) + 5];
+		t2 = e0(d) + Maj(d, e, f);    g += t1;    c = t1 + t2;
+		t1 = b + e1(g) + Ch(g, h, a) + sha512_K[i+6] + W[(i & 15) + 6];
+		t2 = e0(c) + Maj(c, d, e);    f += t1;    b = t1 + t2;
+		t1 = a + e1(f) + Ch(f, g, h) + sha512_K[i+7] + W[(i & 15) + 7];
+		t2 = e0(b) + Maj(b, c, d);    e += t1;    a = t1 + t2;
+	}
+
+	state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+	state[4] += e; state[5] += f; state[6] += g; state[7] += h;
+
+	/* erase our data */
+	a = b = c = d = e = f = g = h = t1 = t2 = 0;
+}
+
+void sha512_block_fn(sha512_context *sst, const uint8_t *src,
+				    int blocks)
+{
+	while (blocks--) {
+		sha512_transform(sst->state, src);
+		src += SHA512_BLOCK_SIZE;
+	}
+}
+
+
+void sha512_base_do_finalize(sha512_context *sctx)
+{
+	const int bit_offset = SHA512_BLOCK_SIZE - sizeof(uint64_t[2]);
+	uint64_t *bits = (uint64_t *)(sctx->buf + bit_offset);
+	unsigned int partial = sctx->count[0] % SHA512_BLOCK_SIZE;
+
+	sctx->buf[partial++] = 0x80;
+	if (partial > bit_offset) {
+		memset(sctx->buf + partial, 0x0, SHA512_BLOCK_SIZE - partial);
+		partial = 0;
+
+		sha512_block_fn(sctx, sctx->buf, 1);
+	}
+
+	memset(sctx->buf + partial, 0x0, bit_offset - partial);
+	bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61);
+	bits[1] = cpu_to_be64(sctx->count[0] << 3);
+
+	sha512_block_fn(sctx, sctx->buf, 1);
+}
+
+void sha512_base_do_update(sha512_context *sctx,
+					const uint8_t *data,
+					unsigned int len)
+{
+	unsigned int partial = sctx->count[0] % SHA512_BLOCK_SIZE;
+
+	sctx->count[0] += len;
+	if (sctx->count[0] < len)
+		sctx->count[1]++;
+
+	if (((partial + len) >= SHA512_BLOCK_SIZE)) {
+		int blocks;
+
+		if (partial) {
+			int p = SHA512_BLOCK_SIZE - partial;
+
+			memcpy(sctx->buf + partial, data, p);
+			data += p;
+			len -= p;
+
+			sha512_block_fn(sctx, sctx->buf, 1);
+		}
+
+		blocks = len / SHA512_BLOCK_SIZE;
+		len %= SHA512_BLOCK_SIZE;
+
+		if (blocks) {
+			sha512_block_fn(sctx, data, blocks);
+			data += blocks * SHA512_BLOCK_SIZE;
+		}
+		partial = 0;
+	}
+	if (len)
+		memcpy(sctx->buf + partial, data, len);
+}
diff --git a/plat/intel/soc/common/lib/sha/sha.h b/plat/intel/soc/common/lib/sha/sha.h
new file mode 100644
index 0000000..41b5fa8
--- /dev/null
+++ b/plat/intel/soc/common/lib/sha/sha.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_SHA_H
+#define SOCFPGA_SHA_H
+
+#include <stdlib.h>
+
+
+#define SHA384_SUM_LEN			48
+#define SHA384_DER_LEN			19
+#define SHA512_SUM_LEN			64
+#define SHA512_DER_LEN			19
+#define SHA512_BLOCK_SIZE		128
+
+
+/* MACRO Function */
+#define GET_UINT64_BE(n, b, i) {	\
+	(n) = ((unsigned long long) (b)[(i)] << 56) |\
+	((unsigned long long) (b)[(i) + 1] << 48) |\
+	((unsigned long long) (b)[(i) + 2] << 40) |\
+	((unsigned long long) (b)[(i) + 3] << 32) |\
+	((unsigned long long) (b)[(i) + 4] << 24) |\
+	((unsigned long long) (b)[(i) + 5] << 16) |\
+	((unsigned long long) (b)[(i) + 6] <<  8) |\
+	((unsigned long long) (b)[(i) + 7]);\
+}
+
+#define PUT_UINT64_BE(n, b, i) {	\
+	(b)[(i)] = (unsigned char) ((n) >> 56);\
+	(b)[(i) + 1] = (unsigned char) ((n) >> 48);\
+	(b)[(i) + 2] = (unsigned char) ((n) >> 40);\
+	(b)[(i) + 3] = (unsigned char) ((n) >> 32);\
+	(b)[(i) + 4] = (unsigned char) ((n) >> 24);\
+	(b)[(i) + 5] = (unsigned char) ((n) >> 16);\
+	(b)[(i) + 6] = (unsigned char) ((n) >>  8);\
+	(b)[(i) + 7] = (unsigned char) ((n));\
+}
+
+#define e0(x)		(ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39))
+#define e1(x)		(ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41))
+#define s0(x)		(ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
+#define s1(x)		(ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6))
+
+/* Inline Function Definitions */
+/* ror64() to rotate its right in 64 bits. */
+static inline uint64_t ror64(uint64_t input, unsigned int shift)
+{
+	return (input >> (shift & 63)) | (input << ((-shift) & 63));
+}
+
+static inline uint64_t Ch(uint64_t x, uint64_t y, uint64_t z)
+{
+	return z ^ (x & (y ^ z));
+}
+
+static inline uint64_t Maj(uint64_t x, uint64_t y, uint64_t z)
+{
+	return (x & y) | (z & (x | y));
+}
+
+static inline void LOAD_OP(int I, uint64_t *W, const uint8_t *input)
+{
+	GET_UINT64_BE(W[I], input, I*8);
+}
+
+static inline void BLEND_OP(int I, uint64_t *W)
+{
+	W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]);
+}
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+inline uint32_t le32_to_cpue(const uint32_t *p)
+{
+	return (uint32_t)*p;
+}
+#else
+inline uint32_t le32_to_cpue(const uint32_t *p)
+{
+	return swab32(*p);
+}
+#endif
+
+static const uint64_t sha512_K[80] = {
+	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+	0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+	0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+	0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+	0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+	0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+	0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+	0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+	0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+	0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+	0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+	0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+	0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+	0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
+};
+
+#define	__cpu_to_le64(x)	((__force __le64)(__u64)(x))
+
+#define _uswap_64(x, sfx)	\
+	((((x) & 0xff00000000000000##sfx) >> 56) |\
+	(((x) & 0x00ff000000000000##sfx) >> 40) |\
+	(((x) & 0x0000ff0000000000##sfx) >> 24) |\
+	(((x) & 0x000000ff00000000##sfx) >>  8) |\
+	(((x) & 0x00000000ff000000##sfx) <<  8) |\
+	(((x) & 0x0000000000ff0000##sfx) << 24) |\
+	(((x) & 0x000000000000ff00##sfx) << 40) |\
+	(((x) & 0x00000000000000ff##sfx) << 56))
+
+#if defined(__GNUC__)
+#define uswap_64(x)		_uswap_64(x, ull)
+#else
+#define uswap_64(x)		_uswap_64(x)
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_be64(x)		uswap_64(x)
+#else
+#define cpu_to_be64(x)		(x)
+#endif
+
+typedef struct {
+	uint64_t state[SHA512_SUM_LEN / 8];
+	uint64_t count[2];
+	uint8_t buf[SHA512_BLOCK_SIZE];
+} sha512_context;
+
+/* Function Definitions */
+/* SHA384 Start Here */
+void sha384_init(sha512_context *ctx);
+void sha384_update(sha512_context *ctx, const uint8_t *input, uint32_t length);
+void sha384_finish(sha512_context *ctx, uint8_t digest[SHA384_SUM_LEN]);
+void sha384_start(const unsigned char *input, unsigned int len,
+			unsigned char *output, unsigned int chunk_sz);
+/* SHA512 Start Here */
+void sha512_init(sha512_context *ctx);
+void sha512_update(sha512_context *ctx, const uint8_t *input, uint32_t length);
+void sha512_finish(sha512_context *ctx, uint8_t digest[SHA512_SUM_LEN]);
+void sha512_start(const unsigned char *input, unsigned int len,
+			unsigned char *output);
+void sha512_transform(uint64_t *state, const uint8_t *input);
+void sha512_block_fn(sha512_context *sst, const uint8_t *src, int blocks);
+void sha512_base_do_finalize(sha512_context *sctx);
+void sha512_base_do_update(sha512_context *sctx, const uint8_t *data,
+				unsigned int len);
+
+#endif
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index adeb069..91df934 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -1164,8 +1165,8 @@
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
-		src_size - data_size);
+		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
+			(void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE);
 
 		i += (src_size - data_size) / MBOX_WORD_BYTE;
 	}
@@ -1298,8 +1299,8 @@
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
-		src_size - data_size);
+		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
+			(void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE);
 
 		memset((void *) dst_addr, 0, *dst_size);
 
@@ -1401,8 +1402,8 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
-			src_size);
+	memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
+		(void *) hash_data_addr, src_size / MBOX_WORD_BYTE);
 
 	i += src_size / MBOX_WORD_BYTE;
 
@@ -1502,8 +1503,8 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	memcpy((uint8_t *) &payload[i],
-			(uint8_t *) hash_sig_pubkey_addr, src_size);
+	memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
+		(void *) hash_sig_pubkey_addr, src_size / MBOX_WORD_BYTE);
 
 	i += (src_size / MBOX_WORD_BYTE);
 
@@ -1839,8 +1840,8 @@
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
-			src_size - data_size);
+		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
+			(void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE);
 
 		i += (src_size - data_size) / MBOX_WORD_BYTE;
 	}
@@ -1971,8 +1972,8 @@
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
-			src_size - data_size);
+		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
+			(void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE);
 
 		memset((void *) dst_addr, 0, *dst_size);
 
@@ -2145,7 +2146,8 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
+	memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
+		(void *) pubkey, src_size / MBOX_WORD_BYTE);
 	i += src_size / MBOX_WORD_BYTE;
 
 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
@@ -2223,8 +2225,8 @@
 	fcs_aes_init_payload.param_size = param_size;
 	fcs_aes_init_payload.key_id	= key_id;
 
-	memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
-		(uint8_t *) param_addr, param_size);
+	memcpy_s(fcs_aes_init_payload.crypto_param, param_size / MBOX_WORD_BYTE,
+		(void *) param_addr, param_size / MBOX_WORD_BYTE);
 
 	fcs_aes_init_payload.is_updated = 0;
 
@@ -2304,9 +2306,10 @@
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
-			(uint8_t *) fcs_aes_init_payload.crypto_param,
-			fcs_aes_init_payload.param_size);
+		memcpy_s(&fcs_aes_crypt_payload[i],
+			fcs_aes_init_payload.param_size / MBOX_WORD_BYTE,
+			(void *) fcs_aes_init_payload.crypto_param,
+			fcs_aes_init_payload.param_size / MBOX_WORD_BYTE);
 
 		i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
 	}
diff --git a/plat/intel/soc/common/soc/socfpga_handoff.c b/plat/intel/soc/common/soc/socfpga_handoff.c
index 526c6e1..6974768 100644
--- a/plat/intel/soc/common/soc/socfpga_handoff.c
+++ b/plat/intel/soc/common/soc/socfpga_handoff.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,15 +16,21 @@
 int socfpga_get_handoff(handoff *reverse_hoff_ptr)
 {
 	int i;
+	int j;
 	uint32_t *buffer;
-	handoff *handoff_ptr = (handoff *) PLAT_HANDOFF_OFFSET;
+	uint32_t *handoff_ptr = (uint32_t *) PLAT_HANDOFF_OFFSET;
+	uint32_t *reverse_hoff_ptr_dst = (uint32_t *) reverse_hoff_ptr;
 
 	if (sizeof(*handoff_ptr) > sizeof(handoff)) {
 		return -EOVERFLOW;
 	}
 
-	memcpy(reverse_hoff_ptr, handoff_ptr, sizeof(handoff));
-	buffer = (uint32_t *)reverse_hoff_ptr;
+	for (j = 0; j < sizeof(handoff) / 4; j++) {
+		memcpy_s((void *) (reverse_hoff_ptr_dst + j), 1,
+			(void *) (handoff_ptr + j), 1);
+	}
+
+	buffer = (uint32_t *)reverse_hoff_ptr_dst;
 
 	/* convert big endian to little endian */
 	for (i = 0; i < sizeof(handoff) / 4; i++)
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index e2a25ea..5d31e99 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
  */
@@ -167,7 +168,7 @@
 		}
 
 		if (MBOX_RESP_ERR(resp_data) > 0U) {
-			INFO("Error in response: %x\n", resp_data);
+			INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
 			return -MBOX_RESP_ERR(resp_data);
 		}
 
@@ -251,7 +252,7 @@
 				return MBOX_RET_ERROR;
 			}
 
-			memcpy((uint8_t *) response,
+			memcpy_s((uint8_t *) response, *resp_len * MBOX_WORD_BYTE,
 				(uint8_t *) mailbox_resp_ctr.payload->data,
 				*resp_len * MBOX_WORD_BYTE);
 		}
@@ -336,7 +337,7 @@
 			}
 
 			if (MBOX_RESP_ERR(resp_data) > 0U) {
-				INFO("Error in response: %x\n", resp_data);
+				INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
 				return -MBOX_RESP_ERR(resp_data);
 			}
 
@@ -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,
@@ -644,7 +652,7 @@
 
 	res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
 	if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
-		ERROR("SoftFunction Status SEU ERROR\n");
+		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
 	}
 
 	if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index 5204146..c7d7076 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -75,7 +76,7 @@
 			RSTMGR_FIELD(PER0, DMAIF6) |
 			RSTMGR_FIELD(PER0, DMAIF7));
 
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
+#if (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5)
 	mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_FIELD(BRG, MPFE));
 #endif
@@ -106,29 +107,9 @@
 		}
 		udelay(1000);
 	}
-	return -ETIMEDOUT;
-}
-
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-static int poll_idle_status_by_counter(uint32_t addr, uint32_t mask,
-					uint32_t match, uint32_t delay_ms)
-{
-	int time_out = delay_ms;
-
-	while (time_out-- > 0) {
-
-		if ((mmio_read_32(addr) & mask) == match) {
-			return 0;
-		}
 
-		/* ToDo: Shall use udelay for product release */
-		for (int i = 0; i < 2000; i++) {
-			/* dummy delay */
-		}
-	}
 	return -ETIMEDOUT;
 }
-#endif
 
 #if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 static int poll_idle_status_by_clkcycles(uint32_t addr, uint32_t mask,
@@ -406,6 +387,7 @@
 	return ret;
 }
 
+/* TODO: Function too long, shall refactor */
 int socfpga_bridges_enable(uint32_t mask)
 {
 	int ret = 0;
@@ -419,54 +401,79 @@
 	uint32_t f2s_respempty = 0;
 	uint32_t f2s_cmdidle = 0;
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-	uint32_t delay = 0;
+	uint32_t brg_lst = 0;
 #endif
 
 	/* Enable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-	/* Enable SOC2FPGA bridge */
-	if (brg_mask & RSTMGR_BRGMODRSTMASK_SOC2FPGA) {
+/**************** SOC2FPGA ****************/
+	brg_lst = mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST));
+	if ((brg_mask & RSTMGR_BRGMODRSTMASK_SOC2FPGA)
+		&& ((brg_lst & RSTMGR_BRGMODRSTMASK_SOC2FPGA) != 0)) {
 		/*
 		 * To request handshake
 		 * Write Reset Manager hdskreq[soc2fpga_flush_req] = 1
 		 */
 		VERBOSE("Set S2F hdskreq ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_SOC2FPGAREQ);
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKREQ_SOC2FPGAREQ));
+
+		udelay(1000);
 
 		/*
 		 * To poll idle status
 		 * Read Reset Manager hdskack[soc2fpga] = 1
 		 */
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_SOC2FPGAACK, RSTMGR_HDSKACK_SOC2FPGAACK,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_SOC2FPGA) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKREQ_SOC2FPGAREQ, RSTMGR_HDSKREQ_SOC2FPGAREQ,
+				300);
+		}
+
+		udelay(1000);
 
 		if (ret < 0) {
 			ERROR("S2F bridge enable: Timeout hdskack\n");
 		}
 
 		/*
+		 * To assert reset
+		 * Write Reset Manager hdskreq[soc2fpga_flush_req] = 0
+		 */
+		VERBOSE("Assert S2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+		(~brg_lst & 0x3) | RSTMGR_BRGMODRST_SOC2FPGA);
+
+		udelay(1000);
+
+		/*
 		 * To clear idle request
 		 * Write Reset Manager hdskreq[soc2fpga_flush_req] = 0
 		 */
 		VERBOSE("Clear S2F hdskreq ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_SOC2FPGAREQ);
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKREQ_SOC2FPGAREQ));
+
+		udelay(1000);
 
 		/*
-		 * To assert reset
-		 * Write Reset Manager hdskreq[soc2fpga_flush_req] = 0
+		 * To clear ack status
+		 * Write Reset Manager hdskack[soc2fpga_flush_ack] = 1
+		 * This bit is W1S/W1C
 		 */
-		VERBOSE("Assert S2F ...\n");
-		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
-			RSTMGR_BRGMODRST_SOC2FPGA);
+		VERBOSE("Clear S2F hdskack ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKACK),
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKACK_SOC2FPGAACK));
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		udelay(1000);
 
 		/*
 		 * To deassert reset
@@ -474,51 +481,87 @@
 		 */
 		VERBOSE("Deassert S2F ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
-			RSTMGR_BRGMODRST_SOC2FPGA);
+				(~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
+				| RSTMGR_BRGMODRST_LWHPS2FPGA))
+				| RSTMGR_BRGMODRST_SOC2FPGA);
+
+		/* Set System Manager soc bridge control register[soc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Set SOC soc2fpga_ready_latency_enable ...\n");
+		mmio_setbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_SOC_BRIDGE_CTRL_EN);
 	}
 
+/**************** LWSOCFPGA ****************/
+
 	/* Enable LWSOC2FPGA bridge */
-	if (brg_mask & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA) {
+	brg_lst = mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST));
+	if ((brg_mask & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA)
+			&& ((brg_lst & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA) != 0)) {
 		/*
 		 * To request handshake
 		 * Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 1
 		 */
 		VERBOSE("Set LWS2F hdskreq ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_LWSOC2FPGAREQ);
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKREQ_LWSOC2FPGAREQ));
+
+		udelay(1000);
 
 		/*
 		 * To poll idle status
 		 * Read Reset Manager hdskack[lwsoc2fpga] = 1
 		 */
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_LWSOC2FPGAACK, RSTMGR_HDSKACK_LWSOC2FPGAACK,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_LWHPS2FPGA) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKREQ_LWSOC2FPGAREQ, RSTMGR_HDSKREQ_LWSOC2FPGAREQ,
+				300);
+		}
+
+		udelay(1000);
 
 		if (ret < 0) {
 			ERROR("LWS2F bridge enable: Timeout hdskack\n");
 		}
 
 		/*
+		 * To assert reset
+		 * Write Reset Manager brgmodrst[lwsoc2fpga] = 1
+		 */
+		VERBOSE("Assert LWS2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+				(~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
+				| RSTMGR_BRGMODRST_LWHPS2FPGA))
+				| RSTMGR_BRGMODRST_LWHPS2FPGA);
+
+		udelay(1000);
+
+		/*
 		 * To clear idle request
 		 * Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 0
 		 */
 		VERBOSE("Clear LWS2F hdskreq ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_LWSOC2FPGAREQ);
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKREQ_LWSOC2FPGAREQ));
+
+		udelay(1000);
 
 		/*
-		 * To assert reset
-		 * Write Reset Manager brgmodrst[lwsoc2fpga] = 1
+		 * To clear ack status
+		 * Write Reset Manager hdskack[lwsoc2fpga_flush_ack] = 1
+		 * This bit is W1S/W1C
 		 */
-		VERBOSE("Assert LWS2F ...\n");
-		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
-			RSTMGR_BRGMODRST_LWHPS2FPGA);
+		VERBOSE("Clear LWS2F hdskack ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKACK),
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKACK_SOC2FPGAACK));
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		udelay(1000);
 
 		/*
 		 * To deassert reset
@@ -526,7 +569,14 @@
 		 */
 		VERBOSE("Deassert LWS2F ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
-			RSTMGR_BRGMODRST_LWHPS2FPGA);
+				((~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
+				| RSTMGR_BRGMODRST_LWHPS2FPGA)))
+				| RSTMGR_BRGMODRST_LWHPS2FPGA);
+
+		/* Set System Manager lwsoc bridge control register[lwsoc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Set LWSOC lwsoc2fpga_ready_latency_enable ...\n");
+		mmio_setbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_LWSOC_BRIDGE_CTRL_EN);
 	}
 #else
 	if (brg_mask != 0U) {
@@ -539,10 +589,7 @@
 
 		/* Wait until idle ack becomes 0 */
 		ret_hps = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
-				       noc_mask, 0, 300);
-		if (ret_hps < 0) {
-			ERROR("S2F bridge enable: Timeout idle ack\n");
-		}
+				       noc_mask, 0, 1000);
 	}
 #endif
 
@@ -552,7 +599,9 @@
 				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 	/* Enable FPGA2SOC bridge */
-	if (brg_mask & RSTMGR_BRGMODRSTMASK_FPGA2SOC) {
+
+	if ((brg_mask & RSTMGR_BRGMODRSTMASK_FPGA2SOC)
+		&& ((brg_lst & RSTMGR_BRGMODRSTMASK_FPGA2SOC) != 0)) {
 		/*
 		 * To request handshake
 		 * Write Reset Manager hdsken[fpgahsen] = 1
@@ -572,9 +621,12 @@
 		 * Read Reset Manager hdskack[fpgahsack] = 1
 		 */
 		VERBOSE("Get FPGA hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("FPGA bridge fpga handshake fpgahsreq: Timeout\n");
@@ -593,9 +645,12 @@
 		 * Read Reset Manager hdskack[f2s_flush_ack] = 1
 		 */
 		VERBOSE("Get F2S hdskack(f2s_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2S bridge fpga handshake f2sdram_flush_req: Timeout\n");
@@ -621,9 +676,12 @@
 		 * Read Reset Manager hdskack[f2s_flush_ack] = 0
 		 */
 		VERBOSE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
@@ -634,9 +692,12 @@
 		 * Read Reset Manager hdskack[fpgahsack] = 0
 		 */
 		VERBOSE("Get FPGA hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+				300);
+				}
 
 		if (ret < 0) {
 			ERROR("F2S bridge fpga handshake fpgahsack: Timeout\n");
@@ -649,10 +710,7 @@
 		VERBOSE("Assert F2S ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		udelay(1000);
 
 		/*
 		 * To deassert reset
@@ -668,7 +726,8 @@
 	}
 
 	/* Enable FPGA2SDRAM bridge */
-	if (brg_mask & RSTMGR_BRGMODRSTMASK_F2SDRAM0) {
+	if ((brg_mask & RSTMGR_BRGMODRSTMASK_F2SDRAM0)
+		&& ((brg_lst & RSTMGR_BRGMODRSTMASK_F2SDRAM0) != 0)) {
 		/*
 		 * To request handshake
 		 * Write Reset Manager hdsken[fpgahsen] = 1
@@ -688,9 +747,12 @@
 		 * Read Reset Manager hdskack[fpgahsack] = 1
 		 */
 		VERBOSE("Get F2SDRAM hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRSTMASK_F2SDRAM0) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2SDRAM bridge fpga handshake fpgahsreq: Timeout\n");
@@ -709,9 +771,12 @@
 		 * Read Reset Manager hdskack[f2sdram_flush_ack] = 1
 		 */
 		VERBOSE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRSTMASK_F2SDRAM0) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2SDRAM bridge fpga handshake f2sdram_flush_req: Timeout\n");
@@ -736,9 +801,12 @@
 		 * Read Reset Manager hdskack[f2sdram_flush_ack] = 0
 		 */
 		VERBOSE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRSTMASK_F2SDRAM0) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2SDRAM bridge fpga handshake f2sdram_flush_ack: Timeout\n");
@@ -749,9 +817,12 @@
 		 * Read Reset Manager hdskack[fpgahsack] = 0
 		 */
 		VERBOSE("Get F2SDRAM hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
-			300);
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRSTMASK_F2SDRAM0) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2SDRAM bridge fpga handshake fpgahsack: Timeout\n");
@@ -765,10 +836,7 @@
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_BRGMODRST_F2SSDRAM0);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		udelay(1000);
 
 		/*
 		 * To deassert reset
@@ -777,14 +845,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) {
@@ -871,10 +931,6 @@
 	uint32_t f2s_idleack = 0;
 	uint32_t f2s_respempty = 0;
 	uint32_t f2s_cmdidle = 0;
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-	uint32_t delay = 0;
-#endif
-
 
 	/* Disable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
@@ -893,7 +949,7 @@
 		 * To poll idle status
 		 * Read Reset Manager hdskack[soc2fpga] = 0
 		 */
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
 			RSTMGR_HDSKACK_SOC2FPGAACK, RSTMGR_HDSKACK_SOC2FPGAACK_DASRT,
 			300);
 
@@ -909,10 +965,12 @@
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_BRGMODRST_SOC2FPGA);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		/* Clear System Manager soc bridge control register[soc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Clear SOC soc2fpga_ready_latency_enable ...\n");
+		mmio_clrbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_SOC_BRIDGE_CTRL_EN);
+
+		udelay(1000);
 	}
 
 	/* Disable LWSOC2FPGA bridge */
@@ -929,7 +987,7 @@
 		 * To poll idle status
 		 * Read Reset Manager hdskack[lwsoc2fpga] = 0
 		 */
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
 			RSTMGR_HDSKACK_LWSOC2FPGAACK, RSTMGR_HDSKACK_LWSOC2FPGAACK_DASRT,
 			300);
 
@@ -945,10 +1003,12 @@
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_BRGMODRST_LWHPS2FPGA);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		/* Clear System Manager lwsoc bridge control register[lwsoc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Clear LWSOC lwsoc2fpga_ready_latency_enable ...\n");
+		mmio_clrbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_LWSOC_BRIDGE_CTRL_EN);
+
+		udelay(1000);
 	}
 #else
 	if (brg_mask != 0U) {
@@ -1009,7 +1069,7 @@
 		 * Read Reset Manager hdskack[f2s_flush_ack] = 0
 		 */
 		VERBOSE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
 			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
 			300);
 
@@ -1022,7 +1082,7 @@
 		 * Read Reset Manager hdskack[fpgahsack] = 0
 		 */
 		VERBOSE("Get FPGA hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
 			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
 			300);
 
@@ -1037,10 +1097,7 @@
 		VERBOSE("Assert F2S ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		udelay(1000);
 
 		/* Write System Manager f2s bridge control register[f2soc_enable] = 0 */
 		VERBOSE("Assert F2S f2soc_enable ...\n");
@@ -1076,7 +1133,7 @@
 		 * Read Reset Manager hdskack[f2sdram_flush_ack] = 0
 		 */
 		VERBOSE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
 			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT,
 			300);
 
@@ -1089,7 +1146,7 @@
 		 * Read Reset Manager hdskack[fpgahsack] = 0
 		 */
 		VERBOSE("Get F2SDRAM hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
 			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
 			300);
 
@@ -1105,10 +1162,7 @@
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_BRGMODRST_F2SSDRAM0);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		udelay(1000);
 
 		/*
 		 * Assert fpga2sdram_manager_main_SidebandManager_FlagOutClr0
@@ -1147,7 +1201,7 @@
 
 		/* Bridge reset */
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
-		/* Software must never write a 0x1 to FPGA2SOC_M0ASK bit */
+		/* Software must never write a 0x1 to FPGA2SOC_MASK bit */
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 				brg_mask & ~RSTMGR_FIELD(BRG, FPGA2SOC));
 #else
@@ -1229,4 +1283,4 @@
 	} while (timeout-- > 0);
 
 	return RSTMGR_RET_ERROR;
-}
+}
\ No newline at end of file
diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c
index db173a4..3759009 100644
--- a/plat/intel/soc/common/socfpga_delay_timer.c
+++ b/plat/intel/soc/common/socfpga_delay_timer.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +11,6 @@
 #include <lib/mmio.h>
 #include "socfpga_plat_def.h"
 
-
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
 #include "agilex_clock_manager.h"
 #elif PLATFORM_MODEL == PLAT_SOCFPGA_N5X
@@ -19,7 +19,7 @@
 #include "s10_clock_manager.h"
 #endif
 
-#define SOCFPGA_GLOBAL_TIMER		0xffd01000
+#define SOCFPGA_GLOBAL_TIMER		PLAT_TIMER_BASE_ADDR
 #define SOCFPGA_GLOBAL_TIMER_EN		0x3
 
 static timer_ops_t plat_timer_ops;
@@ -44,7 +44,6 @@
 	plat_timer_ops.clk_div		= PLAT_SYS_COUNTER_FREQ_IN_MHZ;
 
 	timer_init(&plat_timer_ops);
-
 }
 
 void socfpga_delay_timer_init(void)
@@ -54,5 +53,4 @@
 
 	asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
 	asm volatile("msr cntp_tval_el0, %0" : : "r" (~0));
-
 }
diff --git a/plat/intel/soc/common/socfpga_image_load.c b/plat/intel/soc/common/socfpga_image_load.c
index a5c3279..ee79158 100644
--- a/plat/intel/soc/common/socfpga_image_load.c
+++ b/plat/intel/soc/common/socfpga_image_load.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +13,13 @@
  ******************************************************************************/
 void plat_flush_next_bl_params(void)
 {
+	/*
+	 * We cannot flush these descriptors on the Agilex5 platform,
+	 * since the BL2 runs on the OCRAM and this OCRAM is not cache coherent.
+	 */
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	flush_bl_params_desc();
+#endif
 }
 
 /*******************************************************************************
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index c93e13f..623843e 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -1,6 +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
  */
@@ -183,8 +184,9 @@
 {
 	uint32_t addr_buf[2];
 
-	memcpy(addr_buf, &intel_rsu_update_address,
-			sizeof(intel_rsu_update_address));
+	memcpy_s(addr_buf, sizeof(intel_rsu_update_address),
+		&intel_rsu_update_address, sizeof(intel_rsu_update_address));
+
 	if (intel_rsu_update_address) {
 		mailbox_rsu_update(addr_buf);
 	} else {
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index f68dc29..5dfbc14 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
  */
@@ -417,6 +419,7 @@
 	case(SOCFPGA_MEMCTRL(DIAGINTTEST)):	/* DIAGINTTEST */
 	case(SOCFPGA_MEMCTRL(DERRADDRA)):	/* DERRADDRA */
 
+	case(SOCFPGA_ECC_QSPI(INITSTAT)):	/* ECC_QSPI_INITSTAT */
 	case(SOCFPGA_SYSMGR(EMAC_0)):	/* EMAC0 */
 	case(SOCFPGA_SYSMGR(EMAC_1)):	/* EMAC1 */
 	case(SOCFPGA_SYSMGR(EMAC_2)):	/* EMAC2 */
@@ -507,6 +510,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 +891,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/intel/soc/common/socfpga_vab.c b/plat/intel/soc/common/socfpga_vab.c
index e16610c..969abb3 100644
--- a/plat/intel/soc/common/socfpga_vab.c
+++ b/plat/intel/soc/common/socfpga_vab.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,18 +9,23 @@
 #include <assert.h>
 #include <errno.h>
 
+#include "../lib/sha/sha.h"
+
 #include <arch_helpers.h>
+#include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/desc_image_load.h>
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
+#include <plat/common/platform.h>
 #include <tools_share/firmware_image_package.h>
 
 #include "socfpga_mailbox.h"
 #include "socfpga_vab.h"
 
-static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz)
+size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz)
 {
 	uint8_t *img_buf_end = img_buf + img_buf_sz;
 	uint32_t cert_sz = get_unaligned_le32(img_buf_end - sizeof(uint32_t));
@@ -35,9 +41,33 @@
 	return 0;
 }
 
+int socfpga_vab_init(unsigned int image_id)
+{
+	int ret = 0;
+	size_t image_size;
+	void *image_base_ptr;
+	/*
+	 * Get information about the images to load.
+	 */
+	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
+	assert(bl_mem_params);
+
+	if (bl_mem_params == NULL) {
+		ERROR("SOCFPGA VAB Init failed\n");
+		return -EINITREJECTED;
+	}
+
+	if ((image_id == BL31_IMAGE_ID) || (image_id == BL33_IMAGE_ID)) {
+		image_base_ptr = (void *)bl_mem_params->image_info.image_base;
+		image_size = bl_mem_params->image_info.image_size;
+		ret = socfpga_vab_authentication(&image_base_ptr, &image_size);
+	}
 
+	return ret;
+}
 
-int socfpga_vendor_authentication(void **p_image, size_t *p_size)
+int socfpga_vab_authentication(void **p_image, size_t *p_size)
 {
 	int retry_count = 20;
 	uint8_t hash384[FCS_SHA384_WORD_SIZE];
@@ -46,51 +76,47 @@
 	uint8_t *cert_hash_ptr, *mbox_relocate_data_addr;
 	uint32_t resp = 0, resp_len = 1;
 	int ret = 0;
+	uint8_t u8_buf_static[MBOX_DATA_MAX_LEN];
+
+	mbox_relocate_data_addr = u8_buf_static;
 
 	img_addr = (uintptr_t)*p_image;
 	img_sz = get_img_size((uint8_t *)img_addr, *p_size);
 
 	if (!img_sz) {
-		NOTICE("VAB certificate not found in image!\n");
-		return -ENOVABIMG;
+		ERROR("VAB certificate not found in image!\n");
+		return -ENOVABCERT;
 	}
 
 	if (!IS_BYTE_ALIGNED(img_sz, sizeof(uint32_t))) {
-		NOTICE("Image size (%d bytes) not aliged to 4 bytes!\n", img_sz);
+		ERROR("Image size (%d bytes) not aliged to 4 bytes!\n", img_sz);
 		return -EIMGERR;
 	}
 
 	/* Generate HASH384 from the image */
-	/* TODO: This part need to cross check !!!!!! */
-	sha384_csum_wd((uint8_t *)img_addr, img_sz, hash384, CHUNKSZ_PER_WD_RESET);
-	cert_hash_ptr = (uint8_t *)(img_addr + img_sz +
-	VAB_CERT_MAGIC_OFFSET + VAB_CERT_FIT_SHA384_OFFSET);
+	sha384_start((uint8_t *)img_addr, img_sz, hash384, CHUNKSZ_PER_WD_RESET);
+	cert_hash_ptr = (uint8_t *)(img_addr + img_sz + VAB_CERT_MAGIC_OFFSET +
+								VAB_CERT_FIT_SHA384_OFFSET);
 
 	/*
 	 * Compare the SHA384 found in certificate against the SHA384
 	 * calculated from image
 	 */
 	if (memcmp(hash384, cert_hash_ptr, FCS_SHA384_WORD_SIZE)) {
-		NOTICE("SHA384 does not match!\n");
+		ERROR("SHA384 does not match!\n");
 		return -EKEYREJECTED;
 	}
 
-
 	mbox_data_addr = img_addr + img_sz - sizeof(uint32_t);
 	/* Size in word (32bits) */
 	mbox_data_sz = (BYTE_ALIGN(*p_size - img_sz, sizeof(uint32_t))) >> 2;
 
-	NOTICE("mbox_data_addr = %lx    mbox_data_sz = %d\n", mbox_data_addr, mbox_data_sz);
+	VERBOSE("mbox_data_addr = %lx    mbox_data_sz = %d\n", mbox_data_addr, mbox_data_sz);
 
-	/* TODO: This part need to cross check !!!!!! */
-	// mbox_relocate_data_addr = (uint8_t *)malloc(mbox_data_sz * sizeof(uint32_t));
-	// if (!mbox_relocate_data_addr) {
-		// NOTICE("Cannot allocate memory for VAB certificate relocation!\n");
-		// return -ENOMEM;
-	// }
+	memcpy_s(mbox_relocate_data_addr, mbox_data_sz * sizeof(uint32_t),
+		(uint8_t *)mbox_data_addr, mbox_data_sz * sizeof(uint32_t));
 
-	memcpy(mbox_relocate_data_addr, (uint8_t *)mbox_data_addr, mbox_data_sz * sizeof(uint32_t));
-	*(uint32_t *)mbox_relocate_data_addr = 0;
+	*((unsigned int *)mbox_relocate_data_addr) = CCERT_CMD_TEST_PGM_MASK;
 
 	do {
 		/* Invoke SMC call to ATF to send the VAB certificate to SDM */
@@ -109,7 +135,6 @@
 	/* Free the relocate certificate memory space */
 	zeromem((void *)&mbox_relocate_data_addr, sizeof(uint32_t));
 
-
 	/* Exclude the size of the VAB certificate from image size */
 	*p_size = img_sz;
 
@@ -121,40 +146,32 @@
 		 /* 0x85 = Not allowed under current security setting */
 		if (ret == MBOX_RESP_ERR(0x85)) {
 			/* SDM bypass authentication */
-			NOTICE("Image Authentication bypassed at address\n");
+			ERROR("Image Authentication bypassed at address\n");
 			return 0;
 		}
-		NOTICE("VAB certificate authentication failed in SDM\n");
+		ERROR("VAB certificate authentication failed in SDM\n");
 		/* 0x1FF = The device is busy */
 		if (ret == MBOX_RESP_ERR(0x1FF)) {
-			NOTICE("Operation timed out\n");
+			ERROR("Operation timed out\n");
 			return -ETIMEOUT;
 		} else if (ret == MBOX_WRONG_ID) {
-			NOTICE("No such process\n");
+			ERROR("No such process\n");
 			return -EPROCESS;
 		}
+		return -EAUTH;
 	} else {
 		/* If Certificate Process Status has error */
 		if (resp) {
-			NOTICE("VAB certificate execution format error\n");
+			ERROR("VAB certificate execution format error\n");
 			return -EIMGERR;
 		}
 	}
 
-	NOTICE("Image Authentication bypassed at address\n");
+	NOTICE("%s 0x%lx (%d bytes)\n", "Image Authentication passed at address", img_addr, img_sz);
 	return ret;
-
-}
-
-static uint32_t get_unaligned_le32(const void *p)
-{
-	/* TODO: Temp for testing */
-	//return le32_to_cpup((__le32 *)p);
-	return 0;
 }
 
-void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
-		unsigned char *output, unsigned int chunk_sz)
+uint32_t get_unaligned_le32(const void *p)
 {
-	/* TODO: Update sha384 start, update and finish */
+	return le32_to_cpue((uint32_t *)p);
 }
diff --git a/plat/intel/soc/n5x/include/n5x_clock_manager.h b/plat/intel/soc/n5x/include/n5x_clock_manager.h
index 54477da..95a3d5c 100644
--- a/plat/intel/soc/n5x/include/n5x_clock_manager.h
+++ b/plat/intel/soc/n5x/include/n5x_clock_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +10,6 @@
 
 
 /* MACRO DEFINITION */
-#define SOCFPGA_GLOBAL_TIMER				0xffd01000
 #define SOCFPGA_GLOBAL_TIMER_EN				0x3
 
 #define CLKMGR_PLLGLOB_VCO_PSRC_MASK			GENMASK(17, 16)
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index 1eafeef..1b662ad 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +19,7 @@
 #define PLAT_PRIMARY_CPU			0
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
 #define PLAT_CPU_ID_MPIDR_AFF_SHIFT		MPIDR_AFF0_SHIFT
+#define PLAT_TIMER_BASE_ADDR			0xFFD01000
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
diff --git a/plat/intel/soc/stratix10/include/s10_memory_controller.h b/plat/intel/soc/stratix10/include/s10_memory_controller.h
index 155b279..056f6cf 100644
--- a/plat/intel/soc/stratix10/include/s10_memory_controller.h
+++ b/plat/intel/soc/stratix10/include/s10_memory_controller.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,7 +27,7 @@
 #define S10_MPFE_HMC_ADP_ECCCTRL1			0xf8011100
 #define S10_MPFE_HMC_ADP_ECCCTRL2			0xf8011104
 #define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT		0xf8011218
-#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x000000ff
+#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x0000000f
 #define S10_MPFE_HMC_ADP_RSTHANDSHAKECTRL		0xf8011214
 
 
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 7f452bd..d4c7dab 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +18,7 @@
 #define PLAT_PRIMARY_CPU			0
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
 #define PLAT_CPU_ID_MPIDR_AFF_SHIFT		MPIDR_AFF0_SHIFT
+#define PLAT_TIMER_BASE_ADDR			0xFFD01000
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index 18f5430..e8f892d 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -167,10 +167,9 @@
 	$(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
 
-$(BUILD_PLAT)/$(UART_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(TBB) $(TIMBUILD) $(TIMDDRTOOL)
+$(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)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)
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
index 87a7db4..0cb2014 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -29,7 +29,7 @@
 ifdef $(1)
 ifeq ($(strip $(value $(1))),y)
 DEFINES += -D$(1)$(if $(value $(1)),=1,)
-else
+else ifneq ($(strip $(value $(1))),n)
 DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
 endif
 endif
@@ -71,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/common/mtk_smc_handlers.c b/plat/mediatek/common/mtk_smc_handlers.c
index 5a3ad1f..beb06da 100644
--- a/plat/mediatek/common/mtk_smc_handlers.c
+++ b/plat/mediatek/common/mtk_smc_handlers.c
@@ -99,13 +99,13 @@
 {
 	const struct smc_descriptor *p_smc_desc;
 
-	INFO("print smc descriptor pool\n");
+	VERBOSE("print smc descriptor pool\n");
 	for (p_smc_desc = &pool[0];
 	     (char *)p_smc_desc < (char *)MTK_SMC_POOL_END_UNALIGNED;
 	     p_smc_desc++) {
-		INFO("descriptor name:%s\n", p_smc_desc->smc_name);
-		INFO("descriptor index:%d\n", *p_smc_desc->smc_descriptor_index);
-		INFO("smc id 32:0x%x, smc id 64:0x%x\n",
+		VERBOSE("descriptor name:%s\n", p_smc_desc->smc_name);
+		VERBOSE("descriptor index:%d\n", *p_smc_desc->smc_descriptor_index);
+		VERBOSE("smc id 32:0x%x, smc id 64:0x%x\n",
 		     p_smc_desc->smc_id_aarch32, p_smc_desc->smc_id_aarch64);
 	}
 }
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
index f7ed5e6..c46cca8 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
@@ -25,6 +25,7 @@
 			      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;
@@ -35,6 +36,7 @@
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
 	emi_mpu_set_protection(&region_info);
+#endif
 
 	/* SCP core0 DRAM */
 	region_info.start = SCP_CORE0_REGION_BASE;
@@ -118,13 +120,13 @@
 {
 	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);
+	enum region_ids 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);
 
-	if (zone_id != MPU_REQ_ORIGIN_TEE_ZONE_SVP) {
+	if (zone_id < SVP_DRAM_REGION_ID_START || zone_id > SVP_DRAM_REGION_ID_END) {
 		ERROR("Invalid param %s, %d\n", __func__, __LINE__);
 		return MTK_SIP_E_INVALID_PARAM;
 	}
@@ -133,7 +135,7 @@
 		/* SVP DRAM */
 		region_info.start = phys_addr;
 		region_info.end = phys_addr + zone_size - 1;
-		region_info.region = SVP_DRAM_REGION_ID;
+		region_info.region = zone_id;
 		SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
 					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -142,7 +144,7 @@
 
 		emi_mpu_set_protection(&region_info);
 	} else { /* clear region protection */
-		emi_mpu_clear_protection(SVP_DRAM_REGION_ID);
+		emi_mpu_clear_protection(zone_id);
 	}
 
 	return 0;
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 18acb9c..b64020d 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
@@ -56,13 +56,16 @@
 #define APUSYS_SEC_BUF_PA		(0x55000000)
 #define APUSYS_SEC_BUF_SZ		(0x100000)
 
+#define SVP_DRAM_REGION_COUNT		(10)
+
 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,
+	SVP_DRAM_REGION_ID_START = 5,
+	SVP_DRAM_REGION_ID_END = SVP_DRAM_REGION_ID_START + SVP_DRAM_REGION_COUNT - 1,
 
 	APUSYS_SEC_BUF_EMI_REGION_ID = 21,
 
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/s32/s32g274ardb2/include/platform_def.h b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
index bdfeee2..1a4c495 100644
--- a/plat/nxp/s32/s32g274ardb2/include/platform_def.h
+++ b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
@@ -54,8 +54,7 @@
 /* Console settings */
 #define UART_BASE			UL(0x401C8000)
 #define UART_BAUDRATE			U(115200)
-/* FIRC clock */
-#define UART_CLOCK_HZ			U(48000000)
+#define UART_CLOCK_HZ			U(125000000)
 
 #define S32G_FIP_BASE			UL(0x34100000)
 #define S32G_FIP_SIZE			UL(0x100000)
diff --git a/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h b/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
new file mode 100644
index 0000000..0c0870f
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019-2021, 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef S32G2_NCORE_H
+#define S32G2_NCORE_H
+
+#include <stdbool.h>
+
+#define NCORE_BASE_ADDR			UL(0x50400000)
+
+#define A53_CLUSTER0_CAIU		U(0)
+#define A53_CLUSTER1_CAIU		U(1)
+
+/**
+ * Directory Unit Registers
+ *
+ * The directory provides a point of serialization for establishing transaction
+ * ordering and sequences coherence operations and memory accesses.
+ */
+#define NCORE_DIRU(N)			(NCORE_BASE_ADDR + UL(0x80000) + ((N) * UL(0x1000)))
+
+/* DIRU Snoop Filtering Enable */
+#define NCORE_DIRUSFE(N)		(NCORE_DIRU(N) + UL(0x10))
+#define NCORE_DIRUSFE_SFEN(SF)		BIT_32(SF)
+
+/* DIRU Caching Agent Snoop Enable */
+#define NCORE_DIRUCASE(N)		(NCORE_DIRU(N) + UL(0x40))
+#define NCORE_DIRUCASE_CASNPEN(CAIU)	BIT_32(CAIU)
+
+/* DIRU Snoop Filter Maintenance Control */
+#define NCORE_DIRUSFMC(N)		(NCORE_DIRU(N) + UL(0x80))
+#define NCORE_DIRUSFMC_SFID(SF)		((SF) << 16U)
+#define NCORE_DIRUSFMC_SFMNTOP_ALL	U(0x0)
+
+/* DIRU Snoop Filter Maintenance Activity */
+#define NCORE_DIRUSFMA(N)		(NCORE_DIRU(N) + UL(0x84))
+#define NCORE_DIRUSFMA_MNTOPACTV	BIT_32(0)
+
+/**
+ * Coherent Agent Interface Unit Registers
+ *
+ * CAI provides a means for a fully-coherent agent to be connected to the Ncore.
+ * The CAI behaves as a fully-coherent slave.
+ */
+#define NCORE_CAIU(N)			(NCORE_BASE_ADDR + ((N) * UL(0x1000)))
+#define NCORE_CAIU0_BASE_ADDR		NCORE_BASE_ADDR
+
+/* CAIU Transaction Control */
+#define NCORE_CAIUTC_OFF		UL(0x0)
+#define NCORE_CAIUTC_ISOLEN_SHIFT	U(1)
+#define NCORE_CAIUTC_ISOLEN_MASK	BIT_32(NCORE_CAIUTC_ISOLEN_SHIFT)
+
+#define NCORE_CAIUTC(N)			(NCORE_CAIU(N) + NCORE_CAIUTC_OFF)
+
+/* CAIU Identification */
+#define NCORE_CAIUID(n)			(NCORE_CAIU(n) + UL(0xFFC))
+#define NCORE_CAIUID_TYPE		GENMASK_32(U(19), U(16))
+#define NCORE_CAIUID_TYPE_ACE_DVM	U(0x0)
+
+/**
+ * Coherent Subsystem Registers
+ */
+#define NCORE_CSR			(NCORE_BASE_ADDR + UL(0xFF000))
+
+/* Coherent Subsystem ACE DVM Snoop Enable */
+#define NCORE_CSADSE			(NCORE_CSR + UL(0x40))
+#define NCORE_CSADSE_DVMSNPEN(CAIU)	BIT_32(CAIU)
+
+/* Coherent Subsystem Identification */
+#define NCORE_CSID			(NCORE_CSR + UL(0xFFC))
+#define NCORE_CSID_NUMSFS_SHIFT		U(18)
+#define NCORE_CSID_NUMSFS_MASK		GENMASK_32(U(22), NCORE_CSID_NUMSFS_SHIFT)
+#define NCORE_CSID_NUMSFS(CSIDR)	(((CSIDR) & NCORE_CSID_NUMSFS_MASK) \
+					  >> NCORE_CSID_NUMSFS_SHIFT)
+
+/* Coherent Subsystem Unit Identification */
+#define NCORE_CSUID			(NCORE_CSR + UL(0xFF8))
+#define NCORE_CSUID_NUMCMIUS_SHIFT	U(24)
+#define NCORE_CSUID_NUMCMIUS_MASK	GENMASK_32(U(29), NCORE_CSUID_NUMCMIUS_SHIFT)
+#define NCORE_CSUID_NUMCMIUS(CSUIDR)	(((CSUIDR) & NCORE_CSUID_NUMCMIUS_MASK) \
+					 >> NCORE_CSUID_NUMCMIUS_SHIFT)
+#define NCORE_CSUID_NUMDIRUS_SHIFT	U(16)
+#define NCORE_CSUID_NUMDIRUS_MASK	GENMASK_32(U(21), NCORE_CSUID_NUMDIRUS_SHIFT)
+#define NCORE_CSUID_NUMDIRUS(CSUIDR)	(((CSUIDR) & NCORE_CSUID_NUMDIRUS_MASK) \
+					 >> NCORE_CSUID_NUMDIRUS_SHIFT)
+#define NCORE_CSUID_NUMNCBUS_SHIFT	U(8)
+#define NCORE_CSUID_NUMNCBUS_MASK	GENMASK_32(U(13), NCORE_CSUID_NUMNCBUS_SHIFT)
+#define NCORE_CSUID_NUMNCBUS(CSUIDR)	(((CSUIDR) & NCORE_CSUID_NUMNCBUS_MASK) \
+					 >> NCORE_CSUID_NUMNCBUS_SHIFT)
+
+#ifndef __ASSEMBLER__
+void ncore_caiu_online(uint32_t caiu);
+void ncore_caiu_offline(uint32_t caiu);
+void ncore_init(void);
+bool ncore_is_caiu_online(uint32_t caiu);
+void ncore_disable_caiu_isolation(uint32_t caiu);
+#endif /* __ASSEMBLER__ */
+
+#endif /* S32G2_NCORE_H */
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
index 705832c..4645f01 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
@@ -11,6 +11,7 @@
 #include <plat_console.h>
 #include <s32cc-clk-drv.h>
 #include <plat_io_storage.h>
+#include <s32cc-ncore.h>
 
 #define SIUL2_PC09_MSCR		UL(0x4009C2E4)
 #define SIUL2_PC10_MSCR		UL(0x4009C2E8)
@@ -62,6 +63,14 @@
 	linflex_config_pinctrl();
 	console_s32g2_register();
 
+	/* Restore (clear) the CAIUTC[IsolEn] bit for the primary cluster, which
+	 * we have manually set during early BL2 boot.
+	 */
+	ncore_disable_caiu_isolation(A53_CLUSTER0_CAIU);
+
+	ncore_init();
+	ncore_caiu_online(A53_CLUSTER0_CAIU);
+
 	plat_s32g2_io_setup();
 }
 
diff --git a/plat/nxp/s32/s32g274ardb2/plat_helpers.S b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
index 193c884..7121900 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_helpers.S
+++ b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
@@ -6,10 +6,7 @@
 
 #include <asm_macros.S>
 #include <platform_def.h>
-
-#define S32G_NCORE_CAIU0_BASE_ADDR		UL(0x50400000)
-#define S32G_NCORE_CAIUTC_OFF			U(0x0)
-#define S32G_NCORE_CAIUTC_ISOLEN_SHIFT		U(1)
+#include <s32cc-ncore.h>
 
 .globl	plat_crash_console_flush
 .globl	plat_crash_console_init
@@ -38,6 +35,8 @@
 
 /* void plat_crash_console_flush(void); */
 func plat_crash_console_flush
+	mov_imm	x0, UART_BASE
+	b	console_linflex_core_flush
 	ret
 endfunc plat_crash_console_flush
 
@@ -102,12 +101,12 @@
  * Clobber list: x0, x1, x2
  */
 func plat_reset_handler
-	mov	x0, #S32G_NCORE_CAIU0_BASE_ADDR
-	ldr	w1, [x0, #S32G_NCORE_CAIUTC_OFF]
+	mov	x0, #NCORE_CAIU0_BASE_ADDR
+	ldr	w1, [x0, #NCORE_CAIUTC_OFF]
 	movz	w2, #1
-	lsl	w2, w2, #S32G_NCORE_CAIUTC_ISOLEN_SHIFT
+	lsl	w2, w2, #NCORE_CAIUTC_ISOLEN_SHIFT
 	orr	w1, w1, w2
-	str	w1, [x0, #S32G_NCORE_CAIUTC_OFF]
+	str	w1, [x0, #NCORE_CAIUTC_OFF]
 	ret
 endfunc plat_reset_handler
 
diff --git a/plat/nxp/s32/s32g274ardb2/platform.mk b/plat/nxp/s32/s32g274ardb2/platform.mk
index 316ed2c..7d6e960 100644
--- a/plat/nxp/s32/s32g274ardb2/platform.mk
+++ b/plat/nxp/s32/s32g274ardb2/platform.mk
@@ -15,6 +15,10 @@
 
 include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
 
+# Flag to apply S32 erratum ERR051700. This erratum applies to all S32
+# revisions.
+S32_ERRATA_LIST += ERRATA_S32_051700
+
 PLAT_INCLUDES = \
 	-I${PLAT_S32G274ARDB2}/include
 
@@ -32,6 +36,7 @@
 ERRATA_A53_836870 := 1
 ERRATA_A53_1530924 := 1
 ERRATA_SPECULATIVE_AT := 1
+ERRATA_S32_051700 := 1
 
 # Selecting Drivers for SoC
 $(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
@@ -39,7 +44,6 @@
 
 include ${PLAT_DRIVERS_PATH}/drivers.mk
 
-
 BL_COMMON_SOURCES += \
 	${PLAT_S32G274ARDB2}/plat_console.c \
 	${PLAT_S32G274ARDB2}/plat_helpers.S \
@@ -49,6 +53,7 @@
 	${PLAT_S32G274ARDB2}/plat_bl2_el3_setup.c \
 	${PLAT_S32G274ARDB2}/plat_bl2_image_desc.c \
 	${PLAT_S32G274ARDB2}/plat_io_storage.c \
+	${PLAT_S32G274ARDB2}/s32cc_ncore.c \
 	common/desc_image_load.c \
 	drivers/io/io_fip.c \
 	drivers/io/io_memmap.c \
@@ -64,3 +69,8 @@
 	lib/cpus/aarch64/cortex_a53.S \
 	plat/common/plat_gicv3.c \
 	plat/common/plat_psci_common.c \
+
+# process all errata flags
+$(eval $(call default_zeros, $(S32_ERRATA_LIST)))
+$(eval $(call add_defines, $(S32_ERRATA_LIST)))
+$(eval $(call assert_booleans, $(S32_ERRATA_LIST)))
diff --git a/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c b/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
new file mode 100644
index 0000000..aa60ac4
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2019-2021, 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <s32cc-ncore.h>
+
+static void ncore_diru_online(uint32_t diru)
+{
+	uint32_t numsfs, sf;
+
+	numsfs = NCORE_CSID_NUMSFS(mmio_read_32(NCORE_CSID)) + 1U;
+
+	/* Initialize all entries maintenance operation for each snoop filter */
+	for (sf = 0U; sf < numsfs; sf++) {
+		mmio_write_32(NCORE_DIRUSFMC(diru), NCORE_DIRUSFMC_SFID(sf) |
+			      NCORE_DIRUSFMC_SFMNTOP_ALL);
+
+		while ((mmio_read_32(NCORE_DIRUSFMA(diru)) & NCORE_DIRUSFMA_MNTOPACTV) != 0U) {
+		}
+
+		mmio_setbits_32(NCORE_DIRUSFE(diru), NCORE_DIRUSFE_SFEN(sf));
+	}
+}
+
+void ncore_disable_caiu_isolation(uint32_t caiu)
+{
+	/* Exit from low-power state */
+	mmio_clrbits_32(NCORE_CAIUTC(caiu), NCORE_CAIUTC_ISOLEN_MASK);
+}
+
+static void set_caiu(uint32_t caiu, bool on)
+{
+	uint32_t dirucase, csadser, caiuidr;
+	uint32_t numdirus, diru;
+
+	/* Enable or disable snoop messages to the CAI for each DIRU */
+	numdirus = NCORE_CSUID_NUMDIRUS(mmio_read_32(NCORE_CSUID));
+	for (diru = 0; diru < numdirus; diru++) {
+		dirucase = mmio_read_32(NCORE_DIRUCASE(diru));
+
+		if (on) {
+			dirucase |= NCORE_DIRUCASE_CASNPEN(caiu);
+		} else {
+			dirucase &= ~NCORE_DIRUCASE_CASNPEN(caiu);
+		}
+
+		mmio_write_32(NCORE_DIRUCASE(diru), dirucase);
+	}
+
+	/* Enable or disable DVM messages to the CAI */
+	caiuidr = mmio_read_32(NCORE_CAIUID(caiu));
+	if ((caiuidr & NCORE_CAIUID_TYPE) == NCORE_CAIUID_TYPE_ACE_DVM) {
+		csadser = mmio_read_32(NCORE_CSADSE);
+
+		if (on) {
+			csadser |= NCORE_CSADSE_DVMSNPEN(caiu);
+		} else {
+			csadser &= ~NCORE_CSADSE_DVMSNPEN(caiu);
+		}
+
+		mmio_write_32(NCORE_CSADSE, csadser);
+	}
+}
+
+void ncore_caiu_online(uint32_t caiu)
+{
+	set_caiu(caiu, true);
+}
+
+void ncore_caiu_offline(uint32_t caiu)
+{
+	set_caiu(caiu, false);
+}
+
+bool ncore_is_caiu_online(uint32_t caiu)
+{
+	uint32_t stat = mmio_read_32(NCORE_CSADSE);
+
+	return ((stat & NCORE_CSADSE_DVMSNPEN(caiu)) != 0U);
+}
+
+void ncore_init(void)
+{
+	uint32_t csuidr = mmio_read_32(NCORE_CSUID);
+	uint32_t numdirus, diru;
+
+	numdirus = NCORE_CSUID_NUMDIRUS(csuidr);
+	for (diru = 0U; diru < numdirus; diru++) {
+		/**
+		 * Transition the directory to an online state by ensuring that
+		 * all DIRUs within the interface are operational.
+		 */
+		ncore_diru_online(diru);
+	}
+}
diff --git a/plat/nxp/soc-lx2160a/ddr_fip.mk b/plat/nxp/soc-lx2160a/ddr_fip.mk
index e717cbc..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
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 d752b6c..c96e4b9 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -357,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 141ff57..7b54271 100644
--- a/plat/qemu/common/qemu_plat_attest_token.c
+++ b/plat/qemu/common/qemu_plat_attest_token.c
@@ -16,194 +16,195 @@
  */
 static const uint8_t sample_platform_token[] = {
 	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, 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, 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,
+	0x59, 0x05, 0x81, 0xa9, 0x19, 0x01, 0x09, 0x78,
+	0x23, 0x74, 0x61, 0x67, 0x3a, 0x61, 0x72, 0x6d,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x32, 0x30, 0x32,
+	0x33, 0x3a, 0x63, 0x63, 0x61, 0x5f, 0x70, 0x6c,
+	0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x23, 0x31,
+	0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x58, 0x20, 0x0d,
+	0x22, 0xe0, 0x8a, 0x98, 0x46, 0x90, 0x58, 0x48,
+	0x63, 0x18, 0x28, 0x34, 0x89, 0xbd, 0xb3, 0x6f,
+	0x09, 0xdb, 0xef, 0xeb, 0x18, 0x64, 0xdf, 0x43,
+	0x3f, 0xa6, 0xe5, 0x4e, 0xa2, 0xd7, 0x11, 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,
+	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, 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, 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,
+	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, 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,
+	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, 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,
+	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, 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
+	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, 0x31, 0xd0,
+	0x4d, 0x52, 0xcc, 0xde, 0x95, 0x2c, 0x1e, 0x32,
+	0xcb, 0xa1, 0x81, 0x88, 0x5a, 0x40, 0xb8, 0xcc,
+	0x38, 0xe0, 0x52, 0x8c, 0x1e, 0x89, 0x58, 0x98,
+	0x07, 0x64, 0x2a, 0xa5, 0xe3, 0xf2, 0xbc, 0x37,
+	0xf9, 0x53, 0x74, 0x50, 0x6b, 0xff, 0x4d, 0x2e,
+	0x4b, 0xe7, 0x06, 0x3c, 0x4d, 0x72, 0x41, 0x92,
+	0x70, 0xc7, 0x22, 0xe8, 0xd4, 0xd9, 0x3e, 0xe8,
+	0xb6, 0xc9, 0xfa, 0xce, 0x3b, 0x43, 0xc9, 0x76,
+	0x1a, 0x49, 0x94, 0x1a, 0xb6, 0xf3, 0x8f, 0xfd,
+	0xff, 0x49, 0x6a, 0xd4, 0x63, 0xb4, 0xcb, 0xfa,
+	0x11, 0xd8, 0x3e, 0x23, 0xe3, 0x1f, 0x7f, 0x62,
+	0x32, 0x9d, 0xe3, 0x0c, 0x1c, 0xc8
 };
 
 /*
@@ -211,18 +212,21 @@
  * RSE.
  */
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
-				   uintptr_t hash, size_t hash_size)
+				   uintptr_t hash, size_t hash_size,
+				   size_t *remaining_len)
 {
+	const size_t token_size = sizeof(sample_platform_token);
 	(void)hash;
 	(void)hash_size;
 
-	if (*len < sizeof(sample_platform_token)) {
+	/* Shouldn't happen because RMM uses the whole 4kB shared buffer */
+	if (*len < token_size) {
 		return -EINVAL;
 	}
 
-	(void)memcpy((void *)buf, (const void *)sample_platform_token,
-		     sizeof(sample_platform_token));
-	*len = sizeof(sample_platform_token);
+	memcpy((void *)buf, sample_platform_token, token_size);
+	*len = token_size;
+	*remaining_len = 0;
 
 	return 0;
 }
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 db9d65a..f78be90 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -184,7 +184,7 @@
 # define BL32_LIMIT			(BL32_SRAM_LIMIT - FW_HANDOFF_SIZE)
 #elif BL32_RAM_LOCATION_ID == SEC_DRAM_ID
 # define BL32_MEM_BASE			SEC_DRAM_BASE
-# define BL32_MEM_SIZE			SEC_DRAM_SIZE
+# define BL32_MEM_SIZE			(SEC_DRAM_SIZE - RME_GPT_DRAM_SIZE)
 # define BL32_BASE			BL32_DRAM_BASE
 # define BL32_LIMIT			(BL32_DRAM_LIMIT - FW_HANDOFF_SIZE)
 #else
@@ -379,7 +379,8 @@
 
 #define MAP_GPT_L0_REGION	MAP_REGION_FLAT(			\
 					PLAT_QEMU_L0_GPT_BASE,		\
-					PLAT_QEMU_L0_GPT_SIZE,		\
+					PLAT_QEMU_L0_GPT_SIZE +		\
+					PLAT_QEMU_GPT_BITLOCK_SIZE,	\
 					MT_MEMORY | MT_RW | EL3_PAS)
 
 #define MAP_GPT_L1_REGION	MAP_REGION_FLAT(			\
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 066554a..cf1b3a8 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -96,10 +96,6 @@
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
 
-    ifneq (${MBOOT_EL_HASH_ALG}, sha256)
-        $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
-    endif
-
     BL2_SOURCES		+=	plat/qemu/qemu/qemu_measured_boot.c	\
 				plat/qemu/qemu/qemu_helpers.c		\
 				${EVENT_LOG_SOURCES}
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_gold.S b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
index 9bcdf54..49b7cf0 100644
--- a/plat/qti/common/src/aarch64/qti_kryo4_gold.S
+++ b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -41,16 +41,6 @@
 	ret
 endfunc qti_kryo4_gold_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Kryo4 Gold. Must follow AAPCS.
- */
-func qti_kryo4_gold_errata_report
-	/* TODO : Need to add support. Required only for debug bl31 image.*/
-	ret
-endfunc qti_kryo4_gold_errata_report
-#endif
-
 /* ---------------------------------------------
  * This function provides kryo4_gold specific
  * register information for crash reporting.
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_silver.S b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
index 36374b7..4a98912 100644
--- a/plat/qti/common/src/aarch64/qti_kryo4_silver.S
+++ b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -35,17 +35,6 @@
 	ret
 endfunc qti_kryo4_silver_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Kryo4 Silver. Must follow AAPCS.
- */
-func qti_kryo4_silver_errata_report
-	/* TODO : Need to add support. Required only for debug bl31 image.*/
-	ret
-endfunc qti_kryo4_silver_errata_report
-#endif
-
-
 /* ---------------------------------------------
  * This function provides kryo4_silver specific
  * register information for crash reporting.
diff --git a/plat/qti/common/src/aarch64/qti_kryo6_gold.S b/plat/qti/common/src/aarch64/qti_kryo6_gold.S
index 577e7ff..5f9463f 100644
--- a/plat/qti/common/src/aarch64/qti_kryo6_gold.S
+++ b/plat/qti/common/src/aarch64/qti_kryo6_gold.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -41,16 +41,6 @@
 	ret
 endfunc qti_kryo6_gold_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Kryo4 Gold. Must follow AAPCS.
- */
-func qti_kryo6_gold_errata_report
-	/* TODO : Need to add support. Required only for debug bl31 image.*/
-	ret
-endfunc qti_kryo6_gold_errata_report
-#endif
-
 /* ---------------------------------------------
  * This function provides kryo4_gold specific
  * register information for crash reporting.
diff --git a/plat/qti/common/src/aarch64/qti_kryo6_silver.S b/plat/qti/common/src/aarch64/qti_kryo6_silver.S
index 6ad0bca..4a54a64 100644
--- a/plat/qti/common/src/aarch64/qti_kryo6_silver.S
+++ b/plat/qti/common/src/aarch64/qti_kryo6_silver.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -35,17 +35,6 @@
 	ret
 endfunc qti_kryo6_silver_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Kryo4 Silver. Must follow AAPCS.
- */
-func qti_kryo6_silver_errata_report
-	/* TODO : Need to add support. Required only for debug bl31 image.*/
-	ret
-endfunc qti_kryo6_silver_errata_report
-#endif
-
-
 /* ---------------------------------------------
  * This function provides kryo4_silver specific
  * register information for crash reporting.
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/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index dde66aa..9b8c971 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_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
  */
@@ -32,6 +32,17 @@
 	 *
 	 */
 func plat_reset_handler
+#ifdef PLAT_RK_CPU_RESET_EARLY
+	mov	x18, x30
+	msr	spsel, #0
+	bl	plat_set_my_stack
+	mov	x0, x20
+	mov	x1, x21
+	mov	x2, x22
+	mov	x3, x23
+	bl	rockchip_cpu_reset_early
+	mov	x30, x18
+#endif
 	mrs x0, midr_el1
 	ubfx x0, x0, MIDR_PN_SHIFT, #12
 	cmp w0, #((CORTEX_A72_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
diff --git a/plat/rockchip/common/include/plat_pm_helpers.h b/plat/rockchip/common/include/plat_pm_helpers.h
new file mode 100644
index 0000000..2204a65
--- /dev/null
+++ b/plat/rockchip/common/include/plat_pm_helpers.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PM_HELPERS_H
+#define PLAT_PM_HELPERS_H
+
+#include <stdint.h>
+
+/**
+ * Use this macro to define a register region.
+ * start: start offset from the base address.
+ * end: end offset from the base address.
+ * stride: stride of registers in region.
+ * base: base address of registers in region.
+ * wmsk: write mask of registers in region.
+ */
+#define REG_REGION(_start, _end, _stride, _base, _wmsk)	\
+{							\
+	.start = (_base) + (_start),			\
+	.end   = (_base) + (_end),			\
+	.stride   = _stride,				\
+	.wmsk  = _wmsk					\
+}
+
+struct reg_region {
+	/* Start address of region */
+	uint32_t start;
+	/* End address of region */
+	uint32_t end;
+	/* Stride of registers in region */
+	uint32_t stride;
+	/* Write mask of registers in region */
+	uint32_t wmsk;
+	/* Buffer to save/restore registers in region */
+	uint32_t *buf;
+};
+
+void rockchip_alloc_region_mem(struct reg_region *rgns, uint32_t rgn_num);
+void rockchip_reg_rgn_save(struct reg_region *rgns, uint32_t rgn_num);
+void rockchip_reg_rgn_restore(struct reg_region *rgns, uint32_t rgn_num);
+void rockchip_reg_rgn_restore_reverse(struct reg_region *rgns, uint32_t rgn_num);
+void rockchip_regs_dump(uint32_t base,
+			uint32_t start_offset,
+			uint32_t end_offset,
+			uint32_t stride);
+void rockchip_dump_reg_rgns(struct reg_region *rgns, uint32_t rgn_num);
+
+#endif /* PLAT_PM_HELPERS_H */
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index 44a0c46..1e13a9e 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -141,6 +141,7 @@
 uint32_t rockchip_get_uart_baudrate(void);
 uint32_t rockchip_get_uart_clock(void);
 
+void rockchip_init_scmi_server(void);
 #endif /* __ASSEMBLER__ */
 
 /******************************************************************************
diff --git a/plat/rockchip/common/include/rockchip_sip_svc.h b/plat/rockchip/common/include/rockchip_sip_svc.h
index 340d653..8836f9b 100644
--- a/plat/rockchip/common/include/rockchip_sip_svc.h
+++ b/plat/rockchip/common/include/rockchip_sip_svc.h
@@ -11,6 +11,7 @@
 #define SIP_SVC_CALL_COUNT		0x8200ff00
 #define SIP_SVC_UID			0x8200ff01
 #define SIP_SVC_VERSION			0x8200ff03
+#define RK_SIP_SCMI_AGENT0		0x82000010
 
 /* rockchip SiP Service Calls version numbers */
 #define RK_SIP_SVC_VERSION_MAJOR	0x0
diff --git a/plat/rockchip/common/plat_pm_helpers.c b/plat/rockchip/common/plat_pm_helpers.c
new file mode 100644
index 0000000..191b0ca
--- /dev/null
+++ b/plat/rockchip/common/plat_pm_helpers.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <plat_pm_helpers.h>
+
+#define ROCKCHIP_PM_REG_REGION_MEM_LEN	(ROCKCHIP_PM_REG_REGION_MEM_SIZE / sizeof(uint32_t))
+
+/* REG region */
+#define RGN_LEN(_rgn)		(((_rgn)->end - (_rgn)->start) / (_rgn)->stride + 1)
+
+#ifndef ROCKCHIP_PM_REG_REGION_MEM_SIZE
+#define ROCKCHIP_PM_REG_REGION_MEM_SIZE		0
+#endif
+
+#ifdef ROCKCHIP_REG_RGN_MEM_BASE
+static uint32_t *region_mem = (uint32_t *)ROCKCHIP_REG_RGN_MEM_BASE;
+#else
+static uint32_t region_mem[ROCKCHIP_PM_REG_REGION_MEM_LEN];
+#endif
+
+static int region_mem_idx;
+
+static int alloc_region_mem(uint32_t *buf, int max_len,
+			    struct reg_region *rgns, uint32_t rgn_num)
+{
+	int i;
+	int total_len = 0, len = 0;
+	struct reg_region *r = rgns;
+
+	assert(buf && rgns && rgn_num);
+
+	for (i = 0; i < rgn_num; i++, r++) {
+		if (total_len < max_len)
+			r->buf = &buf[total_len];
+
+		len = RGN_LEN(r);
+		total_len += len;
+	}
+
+	if (total_len > max_len) {
+		ERROR("%s The buffer remain length:%d is too small for region:0x%x, at least %d\n",
+		      __func__, max_len, rgns[0].start, total_len);
+		panic();
+	}
+
+	return total_len;
+}
+
+/**
+ * Alloc memory to reg_region->buf from region_mem.
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_alloc_region_mem(struct reg_region *rgns, uint32_t rgn_num)
+{
+	int max_len = 0, len;
+
+	assert(rgns && rgn_num);
+
+	max_len = ROCKCHIP_PM_REG_REGION_MEM_LEN - region_mem_idx;
+
+	len = alloc_region_mem(region_mem + region_mem_idx, max_len,
+			       rgns, rgn_num);
+
+	region_mem_idx += len;
+}
+
+/**
+ * Save (reg_region->start ~ reg_region->end) to reg_region->buf.
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_reg_rgn_save(struct reg_region *rgns, uint32_t rgn_num)
+{
+	struct reg_region *r;
+	uint32_t addr;
+	int i, j;
+
+	assert(rgns && rgn_num);
+
+	for (i = 0; i < rgn_num; i++) {
+		r = &rgns[i];
+		for (j = 0, addr = r->start; addr <= r->end; addr += r->stride, j++)
+			r->buf[j] = mmio_read_32(addr);
+	}
+}
+
+/**
+ * Restore reg_region->buf to (reg_region->start ~ reg_region->end).
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_reg_rgn_restore(struct reg_region *rgns, uint32_t rgn_num)
+{
+	struct reg_region *r;
+	uint32_t addr;
+	int i, j;
+
+	assert(rgns && rgn_num);
+
+	for (i = 0; i < rgn_num; i++) {
+		r = &rgns[i];
+		for (j = 0, addr = r->start; addr <= r->end; addr += r->stride, j++)
+			mmio_write_32(addr, r->buf[j] | r->wmsk);
+
+		dsb();
+	}
+}
+
+/**
+ * Restore reg_region->buf to (reg_region->start ~ reg_region->end) reversely.
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_reg_rgn_restore_reverse(struct reg_region *rgns, uint32_t rgn_num)
+{
+	struct reg_region *r;
+	uint32_t addr;
+	int i, j;
+
+	assert(rgns && rgn_num);
+
+	for (i = rgn_num - 1; i >= 0; i--) {
+		r = &rgns[i];
+		j = RGN_LEN(r) - 1;
+		for (addr = r->end; addr >= r->start; addr -= r->stride, j--)
+			mmio_write_32(addr, r->buf[j] | r->wmsk);
+
+		dsb();
+	}
+}
+
+static void rockchip_print_hex(uint32_t val)
+{
+	int i;
+	unsigned char tmp;
+
+	putchar('0');
+	putchar('x');
+	for (i = 0; i < 8; val <<= 4, ++i) {
+		tmp = (val & 0xf0000000) >> 28;
+		if (tmp < 10)
+			putchar('0' + tmp);
+		else
+			putchar('a' + tmp - 10);
+	}
+}
+
+/**
+ * Dump registers (base + start_offset ~ base + end_offset)
+ * @base - the base addr of the register.
+ * @start_offset - the start offset to dump.
+ * @end_offset - the end offset to dump.
+ * @stride - the stride of the registers.
+ */
+void rockchip_regs_dump(uint32_t base,
+			uint32_t start_offset,
+			uint32_t end_offset,
+			uint32_t stride)
+{
+	uint32_t i;
+
+	for (i = start_offset; i <= end_offset; i += stride) {
+		if ((i - start_offset) % 16 == 0) {
+			putchar('\n');
+			rockchip_print_hex(base + i);
+			putchar(':');
+			putchar(' ');
+			putchar(' ');
+			putchar(' ');
+			putchar(' ');
+		}
+		rockchip_print_hex(mmio_read_32(base + i));
+		putchar(' ');
+		putchar(' ');
+		putchar(' ');
+		putchar(' ');
+	}
+	putchar('\n');
+}
+
+/**
+ * Dump reg regions
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_dump_reg_rgns(struct reg_region *rgns, uint32_t rgn_num)
+{
+	struct reg_region *r;
+	int i;
+
+	assert(rgns && rgn_num);
+
+	for (i = 0; i < rgn_num; i++) {
+		r = &rgns[i];
+		rockchip_regs_dump(0x0, r->start, r->end, r->stride);
+	}
+}
diff --git a/plat/rockchip/common/scmi/scmi.c b/plat/rockchip/common/scmi/scmi.c
new file mode 100644
index 0000000..5c43c51
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+#include <lib/utils.h>
+#include <lib/utils_def.h>
+
+#define MAX_PROTOCOL_IN_LIST		8U
+
+static const char vendor[] = "rockchip";
+static const char sub_vendor[] = "";
+
+#pragma weak rockchip_scmi_protocol_table
+
+const uint8_t rockchip_scmi_protocol_table[1][MAX_PROTOCOL_IN_LIST] = {
+	{
+		SCMI_PROTOCOL_ID_CLOCK,
+		SCMI_PROTOCOL_ID_RESET_DOMAIN,
+		0
+	}
+};
+
+const char *plat_scmi_vendor_name(void)
+{
+	return vendor;
+}
+
+const char *plat_scmi_sub_vendor_name(void)
+{
+	return sub_vendor;
+}
+
+size_t plat_scmi_protocol_count(void)
+{
+	unsigned int count = 0U;
+	const uint8_t *protocol_list = rockchip_scmi_protocol_table[0];
+
+	while (protocol_list[count])
+		count++;
+
+	return count;
+}
+
+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(rockchip_scmi_protocol_table));
+
+	return rockchip_scmi_protocol_table[agent_id];
+}
+
+static struct scmi_msg_channel scmi_channel[] = {
+	[0] = {
+		.shm_addr = SMT_BUFFER0_BASE,
+		.shm_size = SMT_BUF_SLOT_SIZE,
+	},
+
+#ifdef SMT_BUFFER1_BASE
+	[1] = {
+		.shm_addr = SMT_BUFFER1_BASE,
+		.shm_size = SMT_BUF_SLOT_SIZE,
+	},
+#endif
+};
+
+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(scmi_channel));
+
+	return &scmi_channel[agent_id];
+}
+
+#pragma weak rockchip_init_scmi_server
+
+void rockchip_init_scmi_server(void)
+{
+	size_t i;
+
+	for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++)
+		scmi_smt_init_agent_channel(&scmi_channel[i]);
+}
diff --git a/plat/rockchip/common/scmi/scmi_clock.c b/plat/rockchip/common/scmi/scmi_clock.c
new file mode 100644
index 0000000..d6d4b37
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi_clock.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+
+#include "scmi_clock.h"
+
+#pragma weak rockchip_scmi_clock_count
+#pragma weak rockchip_scmi_get_clock
+
+size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
+{
+	return 0;
+}
+
+rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
+					 uint32_t scmi_id __unused)
+{
+	return NULL;
+}
+
+size_t plat_scmi_clock_count(unsigned int agent_id)
+{
+	return rockchip_scmi_clock_count(agent_id);
+}
+
+const char *plat_scmi_clock_get_name(unsigned int agent_id,
+				     unsigned int scmi_id)
+{
+	rk_scmi_clock_t *clock;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return NULL;
+
+	return clock->name;
+}
+
+int32_t plat_scmi_clock_rates_array(unsigned int agent_id,
+				    unsigned int scmi_id,
+				    unsigned long *rates,
+				    size_t *nb_elts,
+				    uint32_t start_idx)
+{
+	uint32_t i;
+	unsigned long *rate_table;
+	rk_scmi_clock_t *clock;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return SCMI_NOT_FOUND;
+
+	rate_table = clock->rate_table;
+	if (rate_table == NULL)
+		return SCMI_NOT_SUPPORTED;
+
+	if (rates == 0) {
+		*nb_elts = clock->rate_cnt;
+		goto out;
+	}
+
+	if (start_idx + *nb_elts > clock->rate_cnt)
+		return SCMI_OUT_OF_RANGE;
+
+	for (i = 0; i < *nb_elts; i++)
+		rates[i] = rate_table[start_idx + i];
+
+out:
+	return SCMI_SUCCESS;
+}
+
+int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused,
+				      unsigned int scmi_id __unused,
+				      unsigned long *steps __unused)
+{
+	return SCMI_NOT_SUPPORTED;
+}
+
+unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
+				       unsigned int scmi_id)
+{
+	rk_scmi_clock_t *clock;
+	unsigned long rate = 0;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return 0;
+
+	if (clock->clk_ops && clock->clk_ops->get_rate)
+		rate = clock->clk_ops->get_rate(clock);
+
+	/* return cur_rate if no get_rate ops or get_rate return 0 */
+	if (rate == 0)
+		rate = clock->cur_rate;
+
+	return rate;
+}
+
+int32_t plat_scmi_clock_set_rate(unsigned int agent_id,
+				 unsigned int scmi_id,
+				 unsigned long rate)
+{
+	rk_scmi_clock_t *clock;
+	int32_t status = 0;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return SCMI_NOT_FOUND;
+
+	if (clock->clk_ops && clock->clk_ops->set_rate) {
+		status = clock->clk_ops->set_rate(clock, rate);
+		if (status == SCMI_SUCCESS)
+			clock->cur_rate = rate;
+	} else {
+		status = SCMI_NOT_SUPPORTED;
+	}
+
+	return status;
+}
+
+int32_t plat_scmi_clock_get_state(unsigned int agent_id,
+				  unsigned int scmi_id)
+{
+	rk_scmi_clock_t *clock;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return 0;
+
+	return clock->enable;
+}
+
+int32_t plat_scmi_clock_set_state(unsigned int agent_id,
+				  unsigned int scmi_id,
+				  bool enable_not_disable)
+{
+	rk_scmi_clock_t *clock;
+	int32_t status = 0;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return SCMI_NOT_FOUND;
+
+	if (clock->clk_ops && clock->clk_ops->set_status) {
+		status = clock->clk_ops->set_status(clock, enable_not_disable);
+		if (status == SCMI_SUCCESS)
+			clock->enable = enable_not_disable;
+	} else {
+		status = SCMI_NOT_SUPPORTED;
+	}
+
+	return status;
+}
diff --git a/plat/rockchip/common/scmi/scmi_clock.h b/plat/rockchip/common/scmi/scmi_clock.h
new file mode 100644
index 0000000..e640fe1
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi_clock.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RK_SCMI_CLOCK_H
+#define RK_SCMI_CLOCK_H
+
+#include <stdint.h>
+
+#include <common.h>
+
+struct rk_scmi_clock;
+
+struct rk_clk_ops {
+	unsigned long (*get_rate)(struct rk_scmi_clock *clock);
+	int (*set_rate)(struct rk_scmi_clock *clock, unsigned long rate);
+	int (*set_status)(struct rk_scmi_clock *clock, bool status);
+};
+
+typedef struct rk_scmi_clock {
+	char name[SCMI_CLOCK_NAME_LENGTH_MAX];
+	uint8_t enable;
+	int8_t is_security;
+	uint32_t id;
+	uint32_t rate_cnt;
+	uint64_t cur_rate;
+	uint32_t enable_count;
+	const struct rk_clk_ops *clk_ops;
+	unsigned long *rate_table;
+} rk_scmi_clock_t;
+
+/*
+ * Return number of clock controllers for an agent
+ * @agent_id: SCMI agent ID
+ * Return number of clock controllers
+ */
+size_t rockchip_scmi_clock_count(unsigned int agent_id);
+
+/*
+ * Get rk_scmi_clock_t point
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI clock ID
+ * Return a rk_scmi_clock_t point
+ */
+rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id,
+					 uint32_t scmi_id);
+
+#endif /* RK_SCMI_CLOCK_H */
diff --git a/plat/rockchip/common/scmi/scmi_rstd.c b/plat/rockchip/common/scmi/scmi_rstd.c
new file mode 100644
index 0000000..35c5e0b
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi_rstd.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+
+#include "scmi_rstd.h"
+
+#pragma weak rockchip_scmi_rstd_count
+#pragma weak rockchip_scmi_get_rstd
+
+size_t rockchip_scmi_rstd_count(unsigned int agent_id __unused)
+{
+	return 0U;
+}
+
+rk_scmi_rstd_t *rockchip_scmi_get_rstd(unsigned int agent_id __unused,
+				       unsigned int scmi_id __unused)
+{
+	return NULL;
+}
+
+size_t plat_scmi_rstd_count(unsigned int agent_id)
+{
+	return rockchip_scmi_rstd_count(agent_id);
+}
+
+const char *plat_scmi_rstd_get_name(unsigned int agent_id,
+				    unsigned int scmi_id)
+{
+	rk_scmi_rstd_t *rstd;
+
+	rstd = rockchip_scmi_get_rstd(agent_id, scmi_id);
+	if (rstd == NULL)
+		return NULL;
+
+	return rstd->name;
+}
+
+int32_t plat_scmi_rstd_autonomous(unsigned int agent_id,
+				  unsigned int scmi_id,
+				  unsigned int state)
+{
+	rk_scmi_rstd_t *rstd;
+
+	rstd = rockchip_scmi_get_rstd(agent_id, scmi_id);
+	if (rstd == NULL)
+		return SCMI_NOT_FOUND;
+
+	if ((rstd->rstd_ops && rstd->rstd_ops->reset_auto) != 0)
+		return rstd->rstd_ops->reset_auto(rstd, state);
+	else
+		return SCMI_NOT_SUPPORTED;
+}
+
+int32_t plat_scmi_rstd_set_state(unsigned int agent_id,
+				 unsigned int scmi_id,
+				 bool assert_not_deassert)
+{
+	rk_scmi_rstd_t *rstd;
+
+	rstd = rockchip_scmi_get_rstd(agent_id, scmi_id);
+	if (rstd == NULL)
+		return SCMI_NOT_FOUND;
+
+	if ((rstd->rstd_ops && rstd->rstd_ops->reset_explicit) != 0)
+		return rstd->rstd_ops->reset_explicit(rstd,
+						      assert_not_deassert);
+	else
+		return SCMI_NOT_SUPPORTED;
+}
diff --git a/plat/rockchip/common/scmi/scmi_rstd.h b/plat/rockchip/common/scmi/scmi_rstd.h
new file mode 100644
index 0000000..1af5881
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi_rstd.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RK_SCMI_RESET_DOMAIN_H
+#define RK_SCMI_RESET_DOMAIN_H
+
+#include <stdint.h>
+
+#include <common.h>
+
+struct rk_scmi_rstd;
+
+struct rk_scmi_rstd_ops {
+	int (*reset_auto)(struct rk_scmi_rstd *rstd, uint32_t state);
+	int (*reset_explicit)(struct rk_scmi_rstd *rstd, bool assert_not_deassert);
+};
+
+typedef struct rk_scmi_rstd {
+	char name[SCMI_RESET_DOMAIN_ATTR_NAME_SZ];
+	uint32_t id;
+	uint32_t attribute;
+	uint32_t latency;
+	struct rk_scmi_rstd_ops *rstd_ops;
+} rk_scmi_rstd_t;
+
+/*
+ * Return number of reset domain for an agent
+ * @agent_id: SCMI agent ID
+ * Return number of reset domain
+ */
+size_t rockchip_scmi_rstd_count(unsigned int agent_id);
+
+/*
+ * Get rk_scmi_rstd_t point
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI rstd ID
+ * Return a rk_scmi_rstd_t point
+ */
+rk_scmi_rstd_t *rockchip_scmi_get_rstd(unsigned int agent_id,
+				       unsigned int scmi_id);
+
+#endif /* RK_SCMI_RESET_DOMAIN_H */
diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile
index e742591..32446ef 100644
--- a/plat/rockchip/rk3399/drivers/m0/Makefile
+++ b/plat/rockchip/rk3399/drivers/m0/Makefile
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-toolchains := rk3399-m0
-
 include ../../../../../make_helpers/common.mk
 include ../../../../../make_helpers/toolchain.mk
 
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/rk3588/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3588/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 0000000..c278899
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+.globl	clst_warmboot_data
+
+.macro	func_rockchip_clst_warmboot
+.endm
+
+.macro rockchip_clst_warmboot_data
+clst_warmboot_data:
+	.rept	PLATFORM_CLUSTER_COUNT
+	.word	0
+	.endr
+.endm
diff --git a/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.c b/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.c
new file mode 100644
index 0000000..78e8500
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.c
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <plat_pm_helpers.h>
+#include <plat_private.h>
+#include <pm_pd_regs.h>
+#include <soc.h>
+
+#define WMSK_VAL		0xffff0000
+
+static struct reg_region qos_reg_rgns[] = {
+	[QOS_ISP0_MWO] = REG_REGION(0x08, 0x18, 4, 0xfdf40500, 0),
+	[QOS_ISP0_MRO] = REG_REGION(0x08, 0x18, 4, 0xfdf40400, 0),
+	[QOS_ISP1_MWO] = REG_REGION(0x08, 0x18, 4, 0xfdf41000, 0),
+	[QOS_ISP1_MRO] = REG_REGION(0x08, 0x18, 4, 0xfdf41100, 0),
+	[QOS_VICAP_M0] = REG_REGION(0x08, 0x18, 4, 0xfdf40600, 0),
+	[QOS_VICAP_M1] = REG_REGION(0x08, 0x18, 4, 0xfdf40800, 0),
+	[QOS_FISHEYE0] = REG_REGION(0x08, 0x18, 4, 0xfdf40000, 0),
+	[QOS_FISHEYE1] = REG_REGION(0x08, 0x18, 4, 0xfdf40200, 0),
+	[QOS_VOP_M0] = REG_REGION(0x08, 0x18, 4, 0xfdf82000, 0),
+	[QOS_VOP_M1] = REG_REGION(0x08, 0x18, 4, 0xfdf82200, 0),
+	[QOS_RKVDEC0] = REG_REGION(0x08, 0x18, 4, 0xfdf62000, 0),
+	[QOS_RKVDEC1] = REG_REGION(0x08, 0x18, 4, 0xfdf63000, 0),
+	[QOS_AV1] = REG_REGION(0x08, 0x18, 4, 0xfdf64000, 0),
+	[QOS_RKVENC0_M0RO] = REG_REGION(0x08, 0x18, 4, 0xfdf60000, 0),
+	[QOS_RKVENC0_M1RO] = REG_REGION(0x08, 0x18, 4, 0xfdf60200, 0),
+	[QOS_RKVENC0_M2WO] = REG_REGION(0x08, 0x18, 4, 0xfdf60400, 0),
+	[QOS_RKVENC1_M0RO] = REG_REGION(0x08, 0x18, 4, 0xfdf61000, 0),
+	[QOS_RKVENC1_M1RO] = REG_REGION(0x08, 0x18, 4, 0xfdf61200, 0),
+	[QOS_RKVENC1_M2WO] = REG_REGION(0x08, 0x18, 4, 0xfdf61400, 0),
+	[QOS_DSU_M0] = REG_REGION(0x08, 0x18, 4, 0xfe008000, 0),
+	[QOS_DSU_M1] = REG_REGION(0x08, 0x18, 4, 0xfe008800, 0),
+	[QOS_DSU_MP] = REG_REGION(0x08, 0x18, 4, 0xfdf34200, 0),
+	[QOS_DEBUG] = REG_REGION(0x08, 0x18, 4, 0xfdf34400, 0),
+	[QOS_GPU_M0] = REG_REGION(0x08, 0x18, 4, 0xfdf35000, 0),
+	[QOS_GPU_M1] = REG_REGION(0x08, 0x18, 4, 0xfdf35200, 0),
+	[QOS_GPU_M2] = REG_REGION(0x08, 0x18, 4, 0xfdf35400, 0),
+	[QOS_GPU_M3] = REG_REGION(0x08, 0x18, 4, 0xfdf35600, 0),
+	[QOS_NPU1] = REG_REGION(0x08, 0x18, 4, 0xfdf70000, 0),
+	[QOS_NPU0_MRO] = REG_REGION(0x08, 0x18, 4, 0xfdf72200, 0),
+	[QOS_NPU2] = REG_REGION(0x08, 0x18, 4, 0xfdf71000, 0),
+	[QOS_NPU0_MWR] = REG_REGION(0x08, 0x18, 4, 0xfdf72000, 0),
+	[QOS_MCU_NPU] = REG_REGION(0x08, 0x18, 4, 0xfdf72400, 0),
+	[QOS_JPEG_DEC] = REG_REGION(0x08, 0x18, 4, 0xfdf66200, 0),
+	[QOS_JPEG_ENC0] = REG_REGION(0x08, 0x18, 4, 0xfdf66400, 0),
+	[QOS_JPEG_ENC1] = REG_REGION(0x08, 0x18, 4, 0xfdf66600, 0),
+	[QOS_JPEG_ENC2] = REG_REGION(0x08, 0x18, 4, 0xfdf66800, 0),
+	[QOS_JPEG_ENC3] = REG_REGION(0x08, 0x18, 4, 0xfdf66a00, 0),
+	[QOS_RGA2_MRO] = REG_REGION(0x08, 0x18, 4, 0xfdf66c00, 0),
+	[QOS_RGA2_MWO] = REG_REGION(0x08, 0x18, 4, 0xfdf66e00, 0),
+	[QOS_RGA3_0] = REG_REGION(0x08, 0x18, 4, 0xfdf67000, 0),
+	[QOS_RGA3_1] = REG_REGION(0x08, 0x18, 4, 0xfdf36000, 0),
+	[QOS_VDPU] = REG_REGION(0x08, 0x18, 4, 0xfdf67200, 0),
+	[QOS_IEP] = REG_REGION(0x08, 0x18, 4, 0xfdf66000, 0),
+	[QOS_HDCP0] = REG_REGION(0x08, 0x18, 4, 0xfdf80000, 0),
+	[QOS_HDCP1] = REG_REGION(0x08, 0x18, 4, 0xfdf81000, 0),
+	[QOS_HDMIRX] = REG_REGION(0x08, 0x18, 4, 0xfdf81200, 0),
+	[QOS_GIC600_M0] = REG_REGION(0x08, 0x18, 4, 0xfdf3a000, 0),
+	[QOS_GIC600_M1] = REG_REGION(0x08, 0x18, 4, 0xfdf3a200, 0),
+	[QOS_MMU600PCIE_TCU] = REG_REGION(0x08, 0x18, 4, 0xfdf3a400, 0),
+	[QOS_MMU600PHP_TBU] = REG_REGION(0x08, 0x18, 4, 0xfdf3a600, 0),
+	[QOS_MMU600PHP_TCU] = REG_REGION(0x08, 0x18, 4, 0xfdf3a800, 0),
+	[QOS_USB3_0] = REG_REGION(0x08, 0x18, 4, 0xfdf3e200, 0),
+	[QOS_USB3_1] = REG_REGION(0x08, 0x18, 4, 0xfdf3e000, 0),
+	[QOS_USBHOST_0] = REG_REGION(0x08, 0x18, 4, 0xfdf3e400, 0),
+	[QOS_USBHOST_1] = REG_REGION(0x08, 0x18, 4, 0xfdf3e600, 0),
+	[QOS_EMMC] = REG_REGION(0x08, 0x18, 4, 0xfdf38200, 0),
+	[QOS_FSPI] = REG_REGION(0x08, 0x18, 4, 0xfdf38000, 0),
+	[QOS_SDIO] = REG_REGION(0x08, 0x18, 4, 0xfdf39000, 0),
+	[QOS_DECOM] = REG_REGION(0x08, 0x18, 4, 0xfdf32000, 0),
+	[QOS_DMAC0] = REG_REGION(0x08, 0x18, 4, 0xfdf32200, 0),
+	[QOS_DMAC1] = REG_REGION(0x08, 0x18, 4, 0xfdf32400, 0),
+	[QOS_DMAC2] = REG_REGION(0x08, 0x18, 4, 0xfdf32600, 0),
+	[QOS_GIC600M] = REG_REGION(0x08, 0x18, 4, 0xfdf32800, 0),
+	[QOS_DMA2DDR] = REG_REGION(0x08, 0x18, 4, 0xfdf52000, 0),
+	[QOS_MCU_DDR] = REG_REGION(0x08, 0x18, 4, 0xfdf52200, 0),
+	[QOS_VAD] = REG_REGION(0x08, 0x18, 4, 0xfdf3b200, 0),
+	[QOS_MCU_PMU] = REG_REGION(0x08, 0x18, 4, 0xfdf3b000, 0),
+	[QOS_CRYPTOS] = REG_REGION(0x08, 0x18, 4, 0xfdf3d200, 0),
+	[QOS_CRYPTONS] = REG_REGION(0x08, 0x18, 4, 0xfdf3d000, 0),
+	[QOS_DCF] = REG_REGION(0x08, 0x18, 4, 0xfdf3d400, 0),
+	[QOS_SDMMC] = REG_REGION(0x08, 0x18, 4, 0xfdf3d800, 0),
+};
+
+static struct reg_region pd_crypto_reg_rgns[] = {
+	/* SECURE CRU */
+	REG_REGION(0x300, 0x30c, 4, SCRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x80c, 4, SCRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa0c, 4, SCRU_BASE, WMSK_VAL),
+	REG_REGION(0xd00, 0xd20, 8, SCRU_BASE, 0),
+	REG_REGION(0xd04, 0xd24, 8, SCRU_BASE, WMSK_VAL),
+
+	/* S TIMER0 6 channel */
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x00, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x00, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x20, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x20, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x40, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x40, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x60, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x60, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x80, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x80, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0xa0, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0xa0, 0),
+
+	/* S TIMER1 6 channel */
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x00, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x00, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x20, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x20, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x40, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x40, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x60, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x60, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x80, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x80, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0xa0, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0xa0, 0),
+
+	/* wdt_s */
+	REG_REGION(0x04, 0x04, 4, WDT_S_BASE, 0),
+	REG_REGION(0x00, 0x00, 4, WDT_S_BASE, 0),
+};
+
+static struct reg_region pd_dsu_reg_rgns[] = {
+	/* dsucru */
+	REG_REGION(0x040, 0x054, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0x300, 0x31c, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x80c, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa0c, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0xd00, 0xd20, 8, DSUCRU_BASE, 0),
+	REG_REGION(0xd04, 0xd24, 8, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0xf00, 0xf00, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0xf10, 0xf1c, 4, DSUCRU_BASE, 0),
+
+	/* bcore0cru */
+	REG_REGION(0x000, 0x014, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+	REG_REGION(0x300, 0x304, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x804, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa04, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+	REG_REGION(0xcc0, 0xcc4, 4, BIGCORE0CRU_BASE, 0),
+	REG_REGION(0xd00, 0xd00, 4, BIGCORE0CRU_BASE, 0),
+	REG_REGION(0xd04, 0xd04, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+
+	/* bcore1cru */
+	REG_REGION(0x020, 0x034, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+	REG_REGION(0x300, 0x304, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x804, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa04, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+	REG_REGION(0xcc0, 0xcc4, 4, BIGCORE1CRU_BASE, 0),
+	REG_REGION(0xd00, 0xd00, 4, BIGCORE1CRU_BASE, 0),
+	REG_REGION(0xd04, 0xd04, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+
+	/* dsugrf */
+	REG_REGION(0x00, 0x18, 4, DSUGRF_BASE, WMSK_VAL),
+	REG_REGION(0x20, 0x20, 4, DSUGRF_BASE, WMSK_VAL),
+	REG_REGION(0x28, 0x30, 4, DSUGRF_BASE, WMSK_VAL),
+	REG_REGION(0x38, 0x38, 4, DSUGRF_BASE, WMSK_VAL),
+
+	/* lcore_grf */
+	REG_REGION(0x20, 0x20, 4, LITCOREGRF_BASE, WMSK_VAL),
+	REG_REGION(0x28, 0x30, 4, LITCOREGRF_BASE, WMSK_VAL),
+
+	/* bcore0_grf */
+	REG_REGION(0x20, 0x20, 4, BIGCORE0GRF_BASE, WMSK_VAL),
+	REG_REGION(0x28, 0x30, 4, BIGCORE0GRF_BASE, WMSK_VAL),
+
+	/* bcore1_grf */
+	REG_REGION(0x20, 0x20, 4, BIGCORE1GRF_BASE, WMSK_VAL),
+	REG_REGION(0x28, 0x28, 4, BIGCORE1GRF_BASE, WMSK_VAL),
+};
+
+static struct reg_region pd_php_reg_rgns[] = {
+	/* php_grf */
+	REG_REGION(0x000, 0x008, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x014, 0x024, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x028, 0x02c, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x030, 0x03c, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x05c, 0x060, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x064, 0x068, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x070, 0x070, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x074, 0x0d0, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x0d4, 0x0d4, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x0e0, 0x0e0, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x0e4, 0x0ec, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x100, 0x104, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x10c, 0x130, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x138, 0x138, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x144, 0x168, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x16c, 0x174, 4, PHPGRF_BASE, WMSK_VAL),
+
+	/* php_cru */
+	REG_REGION(0x200, 0x218, 4, PHP_CRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x800, 4, PHP_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa00, 4, PHP_CRU_BASE, WMSK_VAL),
+
+	/* pcie3phy_grf_cmn_con0 */
+	REG_REGION(0x00, 0x00, 4, PCIE3PHYGRF_BASE, WMSK_VAL),
+};
+
+void qos_save(void)
+{
+	uint32_t pmu_pd_st0 = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(0));
+
+	if ((pmu_pd_st0 & BIT(PD_GPU)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GPU_M0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GPU_M1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GPU_M2], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GPU_M3], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_NPU1)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_NPU1], 1);
+	if ((pmu_pd_st0 & BIT(PD_NPU2)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_NPU2], 1);
+	if ((pmu_pd_st0 & BIT(PD_NPUTOP)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_NPU0_MRO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_NPU0_MWR], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_MCU_NPU], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RKVDEC1)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVDEC1], 1);
+	if ((pmu_pd_st0 & BIT(PD_RKVDEC0)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVDEC0], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_VENC1)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC1_M0RO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC1_M1RO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC1_M2WO], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VENC0)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC0_M0RO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC0_M1RO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC0_M2WO], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RGA30)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RGA3_0], 1);
+	if ((pmu_pd_st0 & BIT(PD_AV1)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_AV1], 1);
+	if ((pmu_pd_st0 & BIT(PD_VDPU)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_DEC], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_ENC0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_ENC1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_ENC2], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_ENC3], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RGA2_MRO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RGA2_MWO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VDPU], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_IEP], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_VO0)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_HDCP0], 1);
+	if ((pmu_pd_st0 & BIT(PD_VO1)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_HDCP1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_HDMIRX], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VOP)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VOP_M0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VOP_M1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_FEC)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_FISHEYE0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_FISHEYE1], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_ISP1)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_ISP1_MWO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_ISP1_MRO], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VI)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_ISP0_MWO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_ISP0_MRO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VICAP_M0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VICAP_M1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RGA31)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RGA3_1], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_USB)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_USB3_0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_USB3_1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_USBHOST_0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_USBHOST_1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_PHP)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GIC600_M0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GIC600_M1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_MMU600PCIE_TCU], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_MMU600PHP_TBU], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_MMU600PHP_TCU], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_SDIO)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_SDIO], 1);
+	if ((pmu_pd_st0 & BIT(PD_NVM0)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_FSPI], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_EMMC], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_SDMMC)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_SDMMC], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_CRYPTO)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_CRYPTONS], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_CRYPTOS], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DCF], 1);
+	}
+
+	/* PD_DSU */
+	rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DSU_M0], 1);
+	rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DSU_M1], 1);
+	rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DSU_MP], 1);
+	rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DEBUG], 1);
+}
+
+void qos_restore(void)
+{
+	uint32_t pmu_pd_st0 = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(0));
+
+	if ((pmu_pd_st0 & BIT(PD_GPU)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GPU_M0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GPU_M1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GPU_M2], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GPU_M3], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_NPU1)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_NPU1], 1);
+	if ((pmu_pd_st0 & BIT(PD_NPU2)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_NPU2], 1);
+	if ((pmu_pd_st0 & BIT(PD_NPUTOP)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_NPU0_MRO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_NPU0_MWR], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_MCU_NPU], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RKVDEC1)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVDEC1], 1);
+	if ((pmu_pd_st0 & BIT(PD_RKVDEC0)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVDEC0], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_VENC1)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC1_M0RO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC1_M1RO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC1_M2WO], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VENC0)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC0_M0RO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC0_M1RO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC0_M2WO], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RGA30)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RGA3_0], 1);
+	if ((pmu_pd_st0 & BIT(PD_AV1)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_AV1], 1);
+	if ((pmu_pd_st0 & BIT(PD_VDPU)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_DEC], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_ENC0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_ENC1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_ENC2], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_ENC3], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RGA2_MRO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RGA2_MWO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VDPU], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_IEP], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_VO0)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_HDCP0], 1);
+	if ((pmu_pd_st0 & BIT(PD_VO1)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_HDCP1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_HDMIRX], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VOP)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VOP_M0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VOP_M1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_FEC)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_FISHEYE0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_FISHEYE1], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_ISP1)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_ISP1_MWO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_ISP1_MRO], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VI)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_ISP0_MWO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_ISP0_MRO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VICAP_M0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VICAP_M1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RGA31)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RGA3_1], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_USB)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_USB3_0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_USB3_1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_USBHOST_0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_USBHOST_1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_PHP)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GIC600_M0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GIC600_M1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_MMU600PCIE_TCU], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_MMU600PHP_TBU], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_MMU600PHP_TCU], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_SDIO)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_SDIO], 1);
+	if ((pmu_pd_st0 & BIT(PD_NVM0)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_FSPI], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_EMMC], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_SDMMC)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_SDMMC], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_CRYPTO)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_CRYPTONS], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_CRYPTOS], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DCF], 1);
+	}
+
+	/* PD_DSU */
+	rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DSU_M0], 1);
+	rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DSU_M1], 1);
+	rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DSU_MP], 1);
+	rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DEBUG], 1);
+}
+
+void pd_crypto_save(void)
+{
+	rockchip_reg_rgn_save(pd_crypto_reg_rgns, ARRAY_SIZE(pd_crypto_reg_rgns));
+}
+
+void pd_crypto_restore(void)
+{
+	rockchip_reg_rgn_restore(pd_crypto_reg_rgns, ARRAY_SIZE(pd_crypto_reg_rgns));
+}
+
+static uint32_t b0_cru_mode;
+static uint32_t b1_cru_mode;
+static uint32_t dsu_cru_mode;
+static uint32_t bcore0_cru_sel_con2, bcore1_cru_sel_con2;
+
+void pd_dsu_core_save(void)
+{
+	b0_cru_mode = mmio_read_32(BIGCORE0CRU_BASE + 0x280);
+	b1_cru_mode = mmio_read_32(BIGCORE1CRU_BASE + 0x280);
+	dsu_cru_mode = mmio_read_32(DSUCRU_BASE + 0x280);
+	bcore0_cru_sel_con2 = mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2));
+	bcore1_cru_sel_con2 = mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2));
+
+	rockchip_reg_rgn_save(pd_dsu_reg_rgns, ARRAY_SIZE(pd_dsu_reg_rgns));
+}
+
+void pd_dsu_core_restore(void)
+{
+	/* switch bcore0/1 pclk root to 24M */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(2, 0x3, 0));
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(2, 0x3, 0));
+
+	/* slow mode */
+	mmio_write_32(BIGCORE0CRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(BIGCORE1CRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(DSUCRU_BASE + 0x280, 0x00030000);
+
+	rockchip_reg_rgn_restore(pd_dsu_reg_rgns, ARRAY_SIZE(pd_dsu_reg_rgns));
+
+	/* trigger dsu/lcore/bcore mem_cfg */
+	mmio_write_32(DSUGRF_BASE + 0x18, BITS_WITH_WMASK(1, 0x1, 14));
+	mmio_write_32(LITCOREGRF_BASE + 0x30, BITS_WITH_WMASK(1, 0x1, 5));
+	mmio_write_32(BIGCORE0GRF_BASE + 0x30, BITS_WITH_WMASK(1, 0x1, 5));
+	mmio_write_32(BIGCORE1GRF_BASE + 0x30, BITS_WITH_WMASK(1, 0x1, 5));
+	udelay(1);
+	mmio_write_32(DSUGRF_BASE + 0x18, BITS_WITH_WMASK(0, 0x1, 14));
+	mmio_write_32(LITCOREGRF_BASE + 0x30, BITS_WITH_WMASK(0, 0x1, 5));
+	mmio_write_32(BIGCORE0GRF_BASE + 0x30, BITS_WITH_WMASK(0, 0x1, 5));
+	mmio_write_32(BIGCORE1GRF_BASE + 0x30, BITS_WITH_WMASK(0, 0x1, 5));
+
+	/* wait lock */
+	pm_pll_wait_lock(BIGCORE0CRU_BASE + 0x00);
+	pm_pll_wait_lock(BIGCORE1CRU_BASE + 0x20);
+	pm_pll_wait_lock(DSUCRU_BASE + 0x40);
+
+	/* restore mode */
+	mmio_write_32(BIGCORE0CRU_BASE + 0x280, WITH_16BITS_WMSK(b0_cru_mode));
+	mmio_write_32(BIGCORE1CRU_BASE + 0x280, WITH_16BITS_WMSK(b1_cru_mode));
+	mmio_write_32(DSUCRU_BASE + 0x280, WITH_16BITS_WMSK(dsu_cru_mode));
+
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+		      WITH_16BITS_WMSK(bcore0_cru_sel_con2));
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+		      WITH_16BITS_WMSK(bcore1_cru_sel_con2));
+}
+
+static uint32_t php_ppll_con0;
+
+void pd_php_save(void)
+{
+	php_ppll_con0 = mmio_read_32(PHP_CRU_BASE + 0x200);
+
+	/* php_ppll bypass */
+	mmio_write_32(PHP_CRU_BASE + 0x200, BITS_WITH_WMASK(1u, 1u, 15));
+	dsb();
+	isb();
+	rockchip_reg_rgn_save(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+}
+
+void pd_php_restore(void)
+{
+	rockchip_reg_rgn_restore(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+
+	pm_pll_wait_lock(PHP_CRU_BASE + 0x200);
+
+	/* restore php_ppll bypass */
+	mmio_write_32(PHP_CRU_BASE + 0x200, WITH_16BITS_WMSK(php_ppll_con0));
+}
+
+void pm_reg_rgns_init(void)
+{
+	rockchip_alloc_region_mem(qos_reg_rgns, ARRAY_SIZE(qos_reg_rgns));
+	rockchip_alloc_region_mem(pd_crypto_reg_rgns, ARRAY_SIZE(pd_crypto_reg_rgns));
+	rockchip_alloc_region_mem(pd_dsu_reg_rgns, ARRAY_SIZE(pd_dsu_reg_rgns));
+	rockchip_alloc_region_mem(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+}
diff --git a/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.h b/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.h
new file mode 100644
index 0000000..8baf69a
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PM_PD_REGS_H
+#define PM_PD_REGS_H
+
+#include <stdint.h>
+
+void qos_save(void);
+void qos_restore(void);
+void pd_crypto_save(void);
+void pd_crypto_restore(void);
+void pd_dsu_core_save(void);
+void pd_dsu_core_restore(void);
+void pd_php_save(void);
+void pd_php_restore(void);
+
+void pm_reg_rgns_init(void);
+
+#endif
diff --git a/plat/rockchip/rk3588/drivers/pmu/pmu.c b/plat/rockchip/rk3588/drivers/pmu/pmu.c
new file mode 100644
index 0000000..f693dbd
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/pmu.c
@@ -0,0 +1,1512 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <cpus_on_fixed_addr.h>
+#include <plat_pm_helpers.h>
+#include <plat_private.h>
+#include <pm_pd_regs.h>
+#include <rk3588_clk.h>
+#include <rockchip_sip_svc.h>
+#include <secure.h>
+#include <soc.h>
+
+#define PSRAM_SP_TOP	((PMUSRAM_BASE + PMUSRAM_RSIZE) & ~0xf)
+#define NONBOOT_CPUS_OFF_LOOP (500000)
+
+#define DSUGRF_REG_CNT			(0x78 / 4 + 1)
+#define BCORE_GRF_REG_CNT		(0x30 / 4 + 1)
+#define LCORE_GRF_REG_CNT		(0x30 / 4 + 1)
+
+#define CENTER_GRF_REG_CNT		(0x20 / 4 + 1)
+
+static struct psram_data_t *psram_sleep_cfg =
+	(struct psram_data_t *)&sys_sleep_flag_sram;
+
+static int8_t pd_repair_map[] = {
+	[PD_GPU] = PD_RPR_GPU,
+	[PD_NPU] = -1,
+	[PD_VCODEC] = -1,
+	[PD_NPUTOP] = PD_RPR_NPUTOP,
+	[PD_NPU1] = PD_RPR_NPU1,
+	[PD_NPU2] = PD_RPR_NPU2,
+	[PD_VENC0] = PD_RPR_VENC0,
+	[PD_VENC1] = PD_RPR_VENC1,
+	[PD_RKVDEC0] = PD_RPR_RKVDEC0,
+	[PD_RKVDEC1] = PD_RPR_RKVDEC1,
+	[PD_VDPU] = PD_RPR_VDPU,
+	[PD_RGA30] = PD_RPR_RGA30,
+	[PD_AV1] = PD_RPR_AV1,
+	[PD_VI] = PD_RPR_VI,
+	[PD_FEC] = PD_RPR_FEC,
+	[PD_ISP1] = PD_RPR_ISP1,
+	[PD_RGA31] = PD_RPR_RGA31,
+	[PD_VOP] = PD_RPR_VOP,
+	[PD_VO0] = PD_RPR_VO0,
+	[PD_VO1] = PD_RPR_VO1,
+	[PD_AUDIO] = PD_RPR_AUDIO,
+	[PD_PHP] = PD_RPR_PHP,
+	[PD_GMAC] = PD_RPR_GMAC,
+	[PD_PCIE] = PD_RPR_PCIE,
+	[PD_NVM] = -1,
+	[PD_NVM0] = PD_RPR_NVM0,
+	[PD_SDIO] = PD_RPR_SDIO,
+	[PD_USB] = PD_RPR_USB,
+	[PD_SECURE] = -1,
+	[PD_SDMMC] = PD_RPR_SDMMC,
+	[PD_CRYPTO] = PD_RPR_CRYPTO,
+	[PD_CENTER] = PD_RPR_CENTER,
+	[PD_DDR01] = PD_RPR_DDR01,
+	[PD_DDR23] = PD_RPR_DDR23,
+};
+
+struct rk3588_sleep_ddr_data {
+	uint32_t gpio0a_iomux_l, gpio0a_iomux_h, gpio0b_iomux_l;
+	uint32_t pmu_pd_st0, bus_idle_st0, qch_pwr_st;
+	uint32_t pmu2_vol_gate_con[3], pmu2_submem_gate_sft_con0;
+	uint32_t pmu2_bisr_con0;
+	uint32_t cpll_con0;
+	uint32_t cru_mode_con, busscru_mode_con;
+	uint32_t bussgrf_soc_con7;
+	uint32_t pmu0grf_soc_con0, pmu0grf_soc_con1, pmu0grf_soc_con3;
+	uint32_t pmu1grf_soc_con2, pmu1grf_soc_con7, pmu1grf_soc_con8, pmu1grf_soc_con9;
+	uint32_t pmu0sgrf_soc_con1;
+	uint32_t pmu1sgrf_soc_con14;
+	uint32_t ddrgrf_chn_con0[4], ddrgrf_chn_con1[4],
+		ddrgrf_chn_con2[4], pmu1_ddr_pwr_sft_con[4];
+	uint32_t pmu1cru_clksel_con1;
+};
+
+static struct rk3588_sleep_ddr_data ddr_data;
+
+struct rk3588_sleep_pmusram_data {
+	uint32_t dsusgrf_soc_con[DSUSGRF_SOC_CON_CNT],
+		dsusgrf_ddr_hash_con[DSUSGRF_DDR_HASH_CON_CNT];
+	uint32_t dsu_ddr_fw_rgn_reg[FIREWALL_DSU_RGN_CNT],
+		dsu_ddr_fw_mst_reg[FIREWALL_DSU_MST_CNT],
+		dsu_ddr_fw_con_reg[FIREWALL_DSU_CON_CNT];
+	uint32_t busioc_gpio0b_iomux_h;
+};
+
+static __pmusramdata struct rk3588_sleep_pmusram_data pmusram_data;
+
+static __pmusramfunc void dsu_restore_early(void)
+{
+	int i;
+
+	/* dsusgrf */
+	for (i = 0; i < DSUSGRF_SOC_CON_CNT; i++)
+		mmio_write_32(DSUSGRF_BASE + DSUSGRF_SOC_CON(i),
+			      WITH_16BITS_WMSK(pmusram_data.dsusgrf_soc_con[i]));
+
+	for (i = 0; i < DSUSGRF_DDR_HASH_CON_CNT; i++)
+		mmio_write_32(DSUSGRF_BASE + DSUSGRF_DDR_HASH_CON(i),
+			      pmusram_data.dsusgrf_ddr_hash_con[i]);
+
+	/* dsu ddr firewall */
+	for (i = 0; i < FIREWALL_DSU_RGN_CNT; i++)
+		mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_RGN(i),
+			      pmusram_data.dsu_ddr_fw_rgn_reg[i]);
+
+	for (i = 0; i < FIREWALL_DSU_MST_CNT; i++)
+		mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_MST(i),
+			      pmusram_data.dsu_ddr_fw_mst_reg[i]);
+
+	for (i = 0; i < FIREWALL_DSU_CON_CNT; i++)
+		mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_CON(i),
+			      pmusram_data.dsu_ddr_fw_con_reg[i]);
+}
+
+static __pmusramfunc void ddr_resume(void)
+{
+	/* check the crypto function had been enabled or not */
+	if ((mmio_read_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4)) & BIT(4)) != 0) {
+		/* enable the crypto function */
+		mmio_write_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4), BITS_WITH_WMASK(0, 0x1, 4));
+		dsb();
+		isb();
+
+		__asm__ volatile ("mov	x0, #3\n"
+				  "dsb	sy\n"
+				  "msr	rmr_el3, x0\n"
+				  "1:\n"
+				  "isb\n"
+				  "wfi\n"
+				  "b 1b\n");
+	}
+
+	dsu_restore_early();
+}
+
+static void dsu_core_save(void)
+{
+	int i;
+
+	/* dsusgrf */
+	for (i = 0; i < DSUSGRF_SOC_CON_CNT; i++)
+		pmusram_data.dsusgrf_soc_con[i] =
+			mmio_read_32(DSUSGRF_BASE + DSUSGRF_SOC_CON(i));
+
+	for (i = 0; i < DSUSGRF_DDR_HASH_CON_CNT; i++)
+		pmusram_data.dsusgrf_ddr_hash_con[i] =
+			mmio_read_32(DSUSGRF_BASE + DSUSGRF_DDR_HASH_CON(i));
+
+	/* dsu ddr firewall */
+	for (i = 0; i < FIREWALL_DSU_RGN_CNT; i++)
+		pmusram_data.dsu_ddr_fw_rgn_reg[i] =
+			mmio_read_32(FIREWALL_DSU_BASE + FIREWALL_DSU_RGN(i));
+
+	for (i = 0; i < FIREWALL_DSU_MST_CNT; i++)
+		pmusram_data.dsu_ddr_fw_mst_reg[i] =
+			mmio_read_32(FIREWALL_DSU_BASE + FIREWALL_DSU_MST(i));
+
+	for (i = 0; i < FIREWALL_DSU_CON_CNT; i++)
+		pmusram_data.dsu_ddr_fw_con_reg[i] =
+			mmio_read_32(FIREWALL_DSU_BASE + FIREWALL_DSU_CON(i));
+
+	pvtplls_suspend();
+	pd_dsu_core_save();
+}
+
+static void dsu_core_restore(void)
+{
+	pd_dsu_core_restore();
+	pvtplls_resume();
+}
+
+static uint32_t clk_save[CRU_CLKGATE_CON_CNT + PHPCRU_CLKGATE_CON_CNT +
+			 SECURECRU_CLKGATE_CON_CNT + PMU1CRU_CLKGATE_CON_CNT];
+
+void clk_gate_con_save(void)
+{
+	int i, j = 0;
+
+	for (i = 0; i < CRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(CRU_BASE + CRU_CLKGATE_CON(i));
+
+	clk_save[j] = mmio_read_32(PHP_CRU_BASE + PHPCRU_CLKGATE_CON);
+
+	for (i = 0; i < SECURECRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(SCRU_BASE + SECURECRU_CLKGATE_CON(i));
+
+	for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(PMU1CRU_BASE + CRU_CLKGATE_CON(i));
+}
+
+void clk_gate_con_disable(void)
+{
+	int i;
+
+	for (i = 0; i < CRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i), 0xffff0000);
+
+	 mmio_write_32(PHP_CRU_BASE + PHPCRU_CLKGATE_CON, 0xffff0000);
+
+	for (i = 0; i < SECURECRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(SCRU_BASE + SECURECRU_CLKGATE_CON(i), 0xffff0000);
+
+	for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(PMU1CRU_BASE + CRU_CLKGATE_CON(i), 0xffff0000);
+}
+
+void clk_gate_con_restore(void)
+{
+	int i, j = 0;
+
+	for (i = 0; i < CRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+
+	mmio_write_32(PHP_CRU_BASE + PHPCRU_CLKGATE_CON,
+		      WITH_16BITS_WMSK(clk_save[j]));
+
+	for (i = 0; i < SECURECRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(SCRU_BASE + SECURECRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+
+	for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(PMU1CRU_BASE + CRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+}
+
+static void pmu_bus_idle_req(uint32_t bus, uint32_t state)
+{
+	uint32_t wait_cnt = 0;
+
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_SFTCON(bus / 16),
+		      BITS_WITH_WMASK(state, 0x1, bus % 16));
+
+	while (pmu_bus_idle_st(bus) != state ||
+	       pmu_bus_idle_ack(bus) != state) {
+		if (++wait_cnt > BUS_IDLE_LOOP)
+			break;
+		udelay(1);
+	}
+
+	if (wait_cnt > BUS_IDLE_LOOP)
+		WARN("%s: can't  wait state %d for bus %d (0x%x)\n",
+		     __func__, state, bus,
+		     mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST(bus / 32)));
+}
+
+static void pmu_qch_pwr_ctlr(uint32_t msk, uint32_t state)
+{
+	uint32_t wait_cnt = 0;
+
+	if (state != 0)
+		state = msk;
+
+	mmio_write_32(PMU_BASE + PMU2_QCHANNEL_PWR_SFTCON,
+		      BITS_WITH_WMASK(state, msk, 0));
+
+	while ((mmio_read_32(PMU_BASE + PMU2_QCHANNEL_STATUS) & msk) != state) {
+		if (++wait_cnt > QCH_PWR_LOOP)
+			break;
+		udelay(1);
+	}
+
+	if (wait_cnt > BUS_IDLE_LOOP)
+		WARN("%s: can't wait qch:0x%x to state:0x%x (0x%x)\n",
+		     __func__, msk, state,
+		     mmio_read_32(PMU_BASE + PMU2_QCHANNEL_STATUS));
+}
+
+static inline uint32_t pmu_power_domain_chain_st(uint32_t pd)
+{
+	return mmio_read_32(PMU_BASE + PMU2_PWR_CHAIN1_ST(pd / 32)) & BIT(pd % 32) ?
+	       pmu_pd_on :
+	       pmu_pd_off;
+}
+
+static inline uint32_t pmu_power_domain_mem_st(uint32_t pd)
+{
+	return mmio_read_32(PMU_BASE + PMU2_PWR_MEM_ST(pd / 32)) & BIT(pd % 32) ?
+	       pmu_pd_off :
+	       pmu_pd_on;
+}
+
+static inline uint32_t pmu_power_domain_st(uint32_t pd)
+{
+	int8_t pd_repair = pd_repair_map[pd];
+
+	if (pd_repair >= 0)
+		return mmio_read_32(PMU_BASE + PMU2_BISR_STATUS(4)) & BIT(pd_repair) ?
+		       pmu_pd_on :
+		       pmu_pd_off;
+	else
+		return mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(pd / 32)) & BIT(pd % 32) ?
+		       pmu_pd_off :
+		       pmu_pd_on;
+}
+
+static int pmu_power_domain_pd_to_mem_st(uint32_t pd, uint32_t *pd_mem_st)
+{
+	uint32_t mem_st;
+
+	switch (pd) {
+	case PD_NPUTOP:
+		mem_st = PD_NPU_TOP_MEM_ST;
+		break;
+	case PD_NPU1:
+		mem_st = PD_NPU1_MEM_ST;
+		break;
+	case PD_NPU2:
+		mem_st = PD_NPU2_MEM_ST;
+		break;
+	case PD_VENC0:
+		mem_st = PD_VENC0_MEM_ST;
+		break;
+	case PD_VENC1:
+		mem_st = PD_VENC1_MEM_ST;
+		break;
+	case PD_RKVDEC0:
+		mem_st = PD_RKVDEC0_MEM_ST;
+		break;
+	case PD_RKVDEC1:
+		mem_st = PD_RKVDEC1_MEM_ST;
+		break;
+	case PD_RGA30:
+		mem_st = PD_RGA30_MEM_ST;
+		break;
+	case PD_AV1:
+		mem_st = PD_AV1_MEM_ST;
+		break;
+	case PD_VI:
+		mem_st = PD_VI_MEM_ST;
+		break;
+	case PD_FEC:
+		mem_st = PD_FEC_MEM_ST;
+		break;
+	case PD_ISP1:
+		mem_st = PD_ISP1_MEM_ST;
+		break;
+	case PD_RGA31:
+		mem_st = PD_RGA31_MEM_ST;
+		break;
+	case PD_VOP:
+		mem_st = PD_VOP_MEM_ST;
+		break;
+	case PD_VO0:
+		mem_st = PD_VO0_MEM_ST;
+		break;
+	case PD_VO1:
+		mem_st = PD_VO1_MEM_ST;
+		break;
+	case PD_AUDIO:
+		mem_st = PD_AUDIO_MEM_ST;
+		break;
+	case PD_PHP:
+		mem_st = PD_PHP_MEM_ST;
+		break;
+	case PD_GMAC:
+		mem_st = PD_GMAC_MEM_ST;
+		break;
+	case PD_PCIE:
+		mem_st = PD_PCIE_MEM_ST;
+		break;
+	case PD_NVM0:
+		mem_st = PD_NVM0_MEM_ST;
+		break;
+	case PD_SDIO:
+		mem_st = PD_SDIO_MEM_ST;
+		break;
+	case PD_USB:
+		mem_st = PD_USB_MEM_ST;
+		break;
+	case PD_SDMMC:
+		mem_st = PD_SDMMC_MEM_ST;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	*pd_mem_st = mem_st;
+
+	return 0;
+}
+
+static int pmu_power_domain_reset_mem(uint32_t pd, uint32_t pd_mem_st)
+{
+	uint32_t loop = 0;
+	int ret = 0;
+
+	while (pmu_power_domain_chain_st(pd_mem_st) != pmu_pd_on) {
+		udelay(1);
+		loop++;
+		if (loop >= PD_CTR_LOOP) {
+			WARN("%s: %d chain up time out\n", __func__, pd);
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+
+	udelay(60);
+
+	mmio_write_32(PMU_BASE + PMU2_MEMPWR_GATE_SFTCON(pd / 16),
+		      BITS_WITH_WMASK(pmu_pd_off, 0x1, pd % 16));
+	dsb();
+
+	loop = 0;
+	while (pmu_power_domain_mem_st(pd_mem_st) != pmu_pd_off) {
+		udelay(1);
+		loop++;
+		if (loop >= PD_CTR_LOOP) {
+			WARN("%s: %d mem down time out\n", __func__, pd);
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+
+	mmio_write_32(PMU_BASE + PMU2_MEMPWR_GATE_SFTCON(pd / 16),
+		      BITS_WITH_WMASK(pmu_pd_on, 0x1, pd % 16));
+	dsb();
+
+	loop = 0;
+	while (pmu_power_domain_mem_st(pd_mem_st) != pmu_pd_on) {
+		udelay(1);
+		loop++;
+		if (loop >= PD_CTR_LOOP) {
+			WARN("%s: %d mem up time out\n", __func__, pd);
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+
+	return 0;
+
+error:
+	return ret;
+}
+
+static int pmu_power_domain_ctr(uint32_t pd, uint32_t pd_state)
+{
+	uint32_t loop = 0;
+	uint32_t is_mem_on = pmu_pd_off;
+	uint32_t pd_mem_st;
+	int ret = 0;
+
+	if (pd_state == pmu_pd_on) {
+		ret = pmu_power_domain_pd_to_mem_st(pd, &pd_mem_st);
+		if (ret == 0) {
+			is_mem_on = pmu_power_domain_mem_st(pd_mem_st);
+			if (is_mem_on == pmu_pd_on)
+				WARN("%s: %d mem is up\n", __func__, pd);
+		}
+	}
+
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_SFTCON(pd / 16),
+		      BITS_WITH_WMASK(pd_state, 0x1, pd % 16));
+	dsb();
+
+	if (is_mem_on == pmu_pd_on) {
+		ret = pmu_power_domain_reset_mem(pd, pd_mem_st);
+		if (ret != 0)
+			goto out;
+		WARN("%s: %d mem reset ok\n", __func__, pd);
+	}
+
+	while ((pmu_power_domain_st(pd) != pd_state) && (loop < PD_CTR_LOOP)) {
+		udelay(1);
+		loop++;
+	}
+
+	if (pmu_power_domain_st(pd) != pd_state) {
+		WARN("%s: %d, %d, (0x%x, 0x%x) error!\n", __func__, pd, pd_state,
+		     mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(0)),
+		     mmio_read_32(PMU_BASE + PMU2_BISR_STATUS(4)));
+		ret = -EINVAL;
+	}
+
+out:
+	return ret;
+}
+
+static int pmu_set_power_domain(uint32_t pd_id, uint32_t pd_state)
+{
+	uint32_t state;
+
+	if (pmu_power_domain_st(pd_id) == pd_state)
+		goto out;
+
+	if (pd_state == pmu_pd_on)
+		pmu_power_domain_ctr(pd_id, pd_state);
+
+	state = (pd_state == pmu_pd_off) ? bus_idle : bus_active;
+
+	switch (pd_id) {
+	case PD_GPU:
+		pmu_bus_idle_req(BUS_ID_GPU, state);
+		break;
+	case PD_NPUTOP:
+		pmu_bus_idle_req(BUS_ID_NPUTOP, state);
+		break;
+	case PD_NPU1:
+		pmu_bus_idle_req(BUS_ID_NPU1, state);
+		break;
+	case PD_NPU2:
+		pmu_bus_idle_req(BUS_ID_NPU2, state);
+		break;
+	case PD_VENC0:
+		pmu_bus_idle_req(BUS_ID_RKVENC0, state);
+		break;
+	case PD_VENC1:
+		pmu_bus_idle_req(BUS_ID_RKVENC1, state);
+		break;
+	case PD_RKVDEC0:
+		pmu_bus_idle_req(BUS_ID_RKVDEC0, state);
+		break;
+	case PD_RKVDEC1:
+		pmu_bus_idle_req(BUS_ID_RKVDEC1, state);
+		break;
+	case PD_VDPU:
+		pmu_bus_idle_req(BUS_ID_VDPU, state);
+		break;
+	case PD_AV1:
+		pmu_bus_idle_req(BUS_ID_AV1, state);
+		break;
+	case PD_VI:
+		pmu_bus_idle_req(BUS_ID_VI, state);
+		break;
+	case PD_ISP1:
+		pmu_bus_idle_req(BUS_ID_ISP, state);
+		break;
+	case PD_RGA31:
+		pmu_bus_idle_req(BUS_ID_RGA31, state);
+		break;
+	case PD_VOP:
+		pmu_bus_idle_req(BUS_ID_VOP_CHANNEL, state);
+		pmu_bus_idle_req(BUS_ID_VOP, state);
+		break;
+	case PD_VO0:
+		pmu_bus_idle_req(BUS_ID_VO0, state);
+		break;
+	case PD_VO1:
+		pmu_bus_idle_req(BUS_ID_VO1, state);
+		break;
+	case PD_AUDIO:
+		pmu_bus_idle_req(BUS_ID_AUDIO, state);
+		break;
+	case PD_PHP:
+		pmu_bus_idle_req(BUS_ID_PHP, state);
+		break;
+	case PD_NVM:
+		pmu_bus_idle_req(BUS_ID_NVM, state);
+		break;
+	case PD_SDIO:
+		pmu_bus_idle_req(BUS_ID_SDIO, state);
+		break;
+	case PD_USB:
+		pmu_bus_idle_req(BUS_ID_USB, state);
+		break;
+	case PD_SECURE:
+		pmu_bus_idle_req(BUS_ID_SECURE, state);
+		break;
+	default:
+		break;
+	}
+
+	if (pd_state == pmu_pd_off)
+		pmu_power_domain_ctr(pd_id, pd_state);
+
+out:
+	return 0;
+}
+
+static void pmu_power_domains_suspend(void)
+{
+	ddr_data.qch_pwr_st =
+		mmio_read_32(PMU_BASE + PMU2_QCHANNEL_STATUS) & PMU2_QCH_PWR_MSK;
+	ddr_data.pmu_pd_st0 = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(0));
+	ddr_data.bus_idle_st0 = mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST(0));
+
+	qos_save();
+
+	if ((ddr_data.pmu_pd_st0 & BIT(PD_PHP)) == 0)
+		pd_php_save();
+
+	if ((ddr_data.pmu_pd_st0 & BIT(PD_CRYPTO)) == 0)
+		pd_crypto_save();
+
+	pmu_qch_pwr_ctlr(0x20, 1);
+	pmu_qch_pwr_ctlr(0x40, 1);
+	pmu_qch_pwr_ctlr(0x1, 1);
+	pmu_qch_pwr_ctlr(0x2, 1);
+	pmu_qch_pwr_ctlr(0x4, 1);
+	pmu_qch_pwr_ctlr(0x8, 1);
+	pmu_qch_pwr_ctlr(0x10, 1);
+
+	pmu_bus_idle_req(BUS_ID_VO1USBTOP, bus_idle);
+	pmu_bus_idle_req(BUS_ID_SECURE_VO1USB_CHANNEL, bus_idle);
+
+	pmu_bus_idle_req(BUS_ID_USB, bus_idle);
+
+	pmu_set_power_domain(PD_GPU, pmu_pd_off);
+
+	pmu_set_power_domain(PD_NPU1, pmu_pd_off);
+	pmu_set_power_domain(PD_NPU2, pmu_pd_off);
+	pmu_set_power_domain(PD_NPUTOP, pmu_pd_off);
+	pmu_set_power_domain(PD_NPU, pmu_pd_off);
+
+	pmu_set_power_domain(PD_RKVDEC1, pmu_pd_off);
+	pmu_set_power_domain(PD_RKVDEC0, pmu_pd_off);
+	pmu_set_power_domain(PD_VENC1, pmu_pd_off);
+	pmu_set_power_domain(PD_VENC0, pmu_pd_off);
+	pmu_set_power_domain(PD_VCODEC, pmu_pd_off);
+
+	pmu_set_power_domain(PD_RGA30, pmu_pd_off);
+	pmu_set_power_domain(PD_AV1, pmu_pd_off);
+	pmu_set_power_domain(PD_VDPU, pmu_pd_off);
+
+	pmu_set_power_domain(PD_VO0, pmu_pd_off);
+	pmu_set_power_domain(PD_VO1, pmu_pd_off);
+	pmu_set_power_domain(PD_VOP, pmu_pd_off);
+
+	pmu_set_power_domain(PD_FEC, pmu_pd_off);
+	pmu_set_power_domain(PD_ISP1, pmu_pd_off);
+	pmu_set_power_domain(PD_VI, pmu_pd_off);
+
+	pmu_set_power_domain(PD_RGA31, pmu_pd_off);
+
+	pmu_set_power_domain(PD_AUDIO, pmu_pd_off);
+
+	pmu_set_power_domain(PD_GMAC, pmu_pd_off);
+	pmu_set_power_domain(PD_PCIE, pmu_pd_off);
+	pmu_set_power_domain(PD_PHP, pmu_pd_off);
+
+	pmu_set_power_domain(PD_SDIO, pmu_pd_off);
+
+	pmu_set_power_domain(PD_NVM0, pmu_pd_off);
+	pmu_set_power_domain(PD_NVM, pmu_pd_off);
+
+	pmu_set_power_domain(PD_SDMMC, pmu_pd_off);
+	pmu_set_power_domain(PD_CRYPTO, pmu_pd_off);
+}
+
+static void pmu_power_domains_resume(void)
+{
+	int i;
+
+	pmu_set_power_domain(PD_CRYPTO, !!(ddr_data.pmu_pd_st0 & BIT(PD_CRYPTO)));
+	pmu_set_power_domain(PD_SDMMC, !!(ddr_data.pmu_pd_st0 & BIT(PD_SDMMC)));
+
+	pmu_set_power_domain(PD_NVM, !!(ddr_data.pmu_pd_st0 & BIT(PD_NVM)));
+	pmu_set_power_domain(PD_NVM0, !!(ddr_data.pmu_pd_st0 & BIT(PD_NVM0)));
+
+	pmu_set_power_domain(PD_SDIO, !!(ddr_data.pmu_pd_st0 & BIT(PD_SDIO)));
+
+	pmu_set_power_domain(PD_PHP, !!(ddr_data.pmu_pd_st0 & BIT(PD_PHP)));
+	pmu_set_power_domain(PD_PCIE, !!(ddr_data.pmu_pd_st0 & BIT(PD_PCIE)));
+	pmu_set_power_domain(PD_GMAC, !!(ddr_data.pmu_pd_st0 & BIT(PD_GMAC)));
+
+	pmu_set_power_domain(PD_AUDIO, !!(ddr_data.pmu_pd_st0 & BIT(PD_AUDIO)));
+
+	pmu_set_power_domain(PD_USB, !!(ddr_data.pmu_pd_st0 & BIT(PD_USB)));
+
+	pmu_set_power_domain(PD_RGA31, !!(ddr_data.pmu_pd_st0 & BIT(PD_RGA31)));
+
+	pmu_set_power_domain(PD_VI, !!(ddr_data.pmu_pd_st0 & BIT(PD_VI)));
+	pmu_set_power_domain(PD_ISP1, !!(ddr_data.pmu_pd_st0 & BIT(PD_ISP1)));
+	pmu_set_power_domain(PD_FEC, !!(ddr_data.pmu_pd_st0 & BIT(PD_FEC)));
+
+	pmu_set_power_domain(PD_VOP, !!(ddr_data.pmu_pd_st0 & BIT(PD_VOP)));
+
+	pmu_set_power_domain(PD_VO1, !!(ddr_data.pmu_pd_st0 & BIT(PD_VO1)));
+
+	pmu_set_power_domain(PD_VO0, !!(ddr_data.pmu_pd_st0 & BIT(PD_VO0)));
+
+	pmu_set_power_domain(PD_VDPU, !!(ddr_data.pmu_pd_st0 & BIT(PD_VDPU)));
+	pmu_set_power_domain(PD_AV1, !!(ddr_data.pmu_pd_st0 & BIT(PD_AV1)));
+	pmu_set_power_domain(PD_RGA30, !!(ddr_data.pmu_pd_st0 & BIT(PD_RGA30)));
+
+	pmu_set_power_domain(PD_VCODEC, !!(ddr_data.pmu_pd_st0 & BIT(PD_VCODEC)));
+	pmu_set_power_domain(PD_VENC0, !!(ddr_data.pmu_pd_st0 & BIT(PD_VENC0)));
+	pmu_set_power_domain(PD_VENC1, !!(ddr_data.pmu_pd_st0 & BIT(PD_VENC1)));
+	pmu_set_power_domain(PD_RKVDEC0, !!(ddr_data.pmu_pd_st0 & BIT(PD_RKVDEC0)));
+	pmu_set_power_domain(PD_RKVDEC1, !!(ddr_data.pmu_pd_st0 & BIT(PD_RKVDEC1)));
+
+	pmu_set_power_domain(PD_NPU, !!(ddr_data.pmu_pd_st0 & BIT(PD_NPU)));
+	pmu_set_power_domain(PD_NPUTOP, !!(ddr_data.pmu_pd_st0 & BIT(PD_NPUTOP)));
+	pmu_set_power_domain(PD_NPU2, !!(ddr_data.pmu_pd_st0 & BIT(PD_NPU2)));
+	pmu_set_power_domain(PD_NPU1, !!(ddr_data.pmu_pd_st0 & BIT(PD_NPU1)));
+
+	pmu_set_power_domain(PD_GPU, !!(ddr_data.pmu_pd_st0 & BIT(PD_GPU)));
+
+	for (i = 0; i < 32; i++)
+		pmu_bus_idle_req(i, !!(ddr_data.bus_idle_st0 & BIT(i)));
+
+	pmu_qch_pwr_ctlr(0x10, !!(ddr_data.qch_pwr_st & 0x10));
+	pmu_qch_pwr_ctlr(0x8, !!(ddr_data.qch_pwr_st & 0x8));
+	pmu_qch_pwr_ctlr(0x4, !!(ddr_data.qch_pwr_st & 0x4));
+	pmu_qch_pwr_ctlr(0x2, !!(ddr_data.qch_pwr_st & 0x2));
+	pmu_qch_pwr_ctlr(0x1, !!(ddr_data.qch_pwr_st & 0x1));
+	pmu_qch_pwr_ctlr(0x40, !!(ddr_data.qch_pwr_st & 0x40));
+	pmu_qch_pwr_ctlr(0x20, !!(ddr_data.qch_pwr_st & 0x20));
+
+	if ((ddr_data.pmu_pd_st0 & BIT(PD_CRYPTO)) == 0)
+		pd_crypto_restore();
+
+	if ((ddr_data.pmu_pd_st0 & BIT(PD_PHP)) == 0)
+		pd_php_restore();
+
+	qos_restore();
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(0, 0x1, core_pm_en));
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(1, 0x1, core_pm_sft_wakeup_en));
+	dsb();
+
+	return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
+{
+	uint32_t apm_value = BIT(core_pm_en);
+
+	if (pd_cfg == core_pwr_wfi_int)
+		apm_value |= BIT(core_pm_int_wakeup_en);
+
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(apm_value, 0x3, 0));
+	dsb();
+
+	return 0;
+}
+
+static inline void cpus_pd_req_enter_wfi(void)
+{
+	/* CORTEX_A55_CPUACTLR_EL1 */
+	__asm__ volatile ("msr	DBGPRCR_EL1, xzr\n"
+			  "mrs	x0, S3_0_C15_C2_7\n"
+			  "orr	x0, x0, #0x1\n"
+			  "msr	S3_0_C15_C2_7, x0\n"
+			  "wfi_loop:\n"
+			  "isb\n"
+			  "wfi\n"
+			  "b wfi_loop\n");
+}
+
+static void nonboot_cpus_off(void)
+{
+	uint32_t boot_cpu, cpu, tmp;
+	uint32_t exp_st;
+	uint32_t bcore0_rst_msk = 0, bcore1_rst_msk = 0;
+	int wait_cnt;
+
+	bcore0_rst_msk = CRU_BIGCPU02_RST_MSK | CRU_BIGCPU13_RST_MSK;
+	bcore1_rst_msk = CRU_BIGCPU02_RST_MSK | CRU_BIGCPU13_RST_MSK;
+
+	mmio_write_32(BIGCORE0CRU_BASE + 0xa00, BITS_WITH_WMASK(0, bcore0_rst_msk, 0));
+	mmio_write_32(BIGCORE1CRU_BASE + 0xa00, BITS_WITH_WMASK(0, bcore1_rst_msk, 0));
+
+	wait_cnt = NONBOOT_CPUS_OFF_LOOP;
+	exp_st = SYS_GRF_BIG_CPUS_WFE;
+	do {
+		wait_cnt--;
+		tmp = mmio_read_32(SYSGRF_BASE + SYS_GRF_SOC_STATUS(3));
+		tmp &= SYS_GRF_BIG_CPUS_WFE;
+	} while (tmp != exp_st && wait_cnt);
+
+	boot_cpu = plat_my_core_pos();
+
+	/* turn off noboot cpus */
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
+		if (cpu == boot_cpu)
+			continue;
+		cpus_power_domain_off(cpu, core_pwr_wfi);
+	}
+
+	mmio_write_32(SRAM_BASE + 0x08, (uintptr_t)&cpus_pd_req_enter_wfi);
+	mmio_write_32(SRAM_BASE + 0x04, 0xdeadbeaf);
+
+	dsb();
+	isb();
+
+	sev();
+
+	wait_cnt = NONBOOT_CPUS_OFF_LOOP;
+	do {
+		wait_cnt--;
+		tmp = mmio_read_32(PMU_BASE + PMU2_CLUSTER_ST);
+		tmp &= CLUSTER_STS_NONBOOT_CPUS_DWN;
+	} while (tmp != CLUSTER_STS_NONBOOT_CPUS_DWN && wait_cnt);
+
+	if (tmp != CLUSTER_STS_NONBOOT_CPUS_DWN)
+		ERROR("nonboot cpus status(%x) error!\n", tmp);
+}
+
+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);
+	assert(cpuson_flags[cpu_id] == 0);
+	cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+	cpuson_entry_point[cpu_id] = entrypoint;
+	dsb();
+
+	flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
+	flush_dcache_range((uintptr_t)cpuson_entry_point,
+			   sizeof(cpuson_entry_point));
+	dsb();
+	isb();
+
+	cpus_power_domain_on(cpu_id);
+
+	return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(0, 0xf, 0));
+
+	return PSCI_E_SUCCESS;
+}
+
+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 PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_suspend(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	assert(cpu_id < PLATFORM_CORE_COUNT);
+
+	cpuson_flags[cpu_id] = PMU_CPU_AUTO_PWRDN;
+	cpuson_entry_point[cpu_id] = plat_get_sec_entrypoint();
+	dsb();
+	flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
+	flush_dcache_range((uintptr_t)cpuson_entry_point,
+			   sizeof(cpuson_entry_point));
+	dsb();
+	isb();
+
+	cpus_power_domain_off(cpu_id, core_pwr_wfi_int);
+
+	__asm__ volatile ("msr	DBGPRCR_EL1, xzr\n"
+			  "mrs	x0, S3_0_C15_C2_7\n"
+			  "orr	x0, x0, #0x1\n"
+			  "msr	S3_0_C15_C2_7, x0\n");
+
+	return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_resume(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(0, 0x3, 0));
+
+	dsb();
+
+	return PSCI_E_SUCCESS;
+}
+
+static void ddr_sleep_config(void)
+{
+	int i;
+
+	if (pmu_power_domain_st(PD_DDR01) == 0) {
+		ddr_data.ddrgrf_chn_con0[0] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHA_CON(0));
+		ddr_data.ddrgrf_chn_con0[1] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHB_CON(0));
+		ddr_data.ddrgrf_chn_con1[0] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHA_CON(1));
+		ddr_data.ddrgrf_chn_con1[1] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHB_CON(1));
+		ddr_data.ddrgrf_chn_con2[0] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHA_CON(2));
+		ddr_data.ddrgrf_chn_con2[1] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHB_CON(2));
+
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(2), 0x20002000);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(2), 0x20002000);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(2), 0x08000000);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(2), 0x08000000);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(0), 0x00200020);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(0), 0x00200020);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(1), 0x00400040);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(1), 0x00400040);
+	}
+
+	if (pmu_power_domain_st(PD_DDR23) == 0) {
+		ddr_data.ddrgrf_chn_con0[2] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHA_CON(0));
+		ddr_data.ddrgrf_chn_con0[3] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHB_CON(0));
+		ddr_data.ddrgrf_chn_con1[2] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHA_CON(1));
+		ddr_data.ddrgrf_chn_con1[3] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHB_CON(1));
+		ddr_data.ddrgrf_chn_con2[2] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHA_CON(2));
+		ddr_data.ddrgrf_chn_con2[3] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHB_CON(2));
+
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(2), 0x20002000);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(2), 0x20002000);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(2), 0x08000000);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(2), 0x08000000);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(0), 0x00200020);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(0), 0x00200020);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(1), 0x00400040);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(1), 0x00400040);
+	}
+
+	for (i = 0; i < DDR_CHN_CNT; i++) {
+		ddr_data.pmu1_ddr_pwr_sft_con[i] =
+			mmio_read_32(PMU_BASE + PMU1_DDR_PWR_SFTCON(i));
+		mmio_write_32(PMU_BASE + PMU1_DDR_PWR_SFTCON(i), 0x0fff0900);
+	}
+}
+
+static void ddr_sleep_config_restore(void)
+{
+	int i;
+
+	for (i = 0; i < DDR_CHN_CNT; i++) {
+		mmio_write_32(PMU_BASE + PMU1_DDR_PWR_SFTCON(i),
+			      0x0fff0000 | ddr_data.pmu1_ddr_pwr_sft_con[i]);
+	}
+
+	if (pmu_power_domain_st(PD_DDR01) == 0) {
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(1),
+			      0x00400000 | ddr_data.ddrgrf_chn_con1[0]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(1),
+			      0x00400000 | ddr_data.ddrgrf_chn_con1[1]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(0),
+			      0x00200000 | ddr_data.ddrgrf_chn_con0[0]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(0),
+			      0x00200000 | ddr_data.ddrgrf_chn_con0[1]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(2),
+			      0x28000000 | ddr_data.ddrgrf_chn_con2[0]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(2),
+			      0x28000000 | ddr_data.ddrgrf_chn_con2[1]);
+	}
+
+	if (pmu_power_domain_st(PD_DDR23) == 0) {
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(1),
+			      0x00400000 | ddr_data.ddrgrf_chn_con1[2]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(1),
+			      0x00400000 | ddr_data.ddrgrf_chn_con1[3]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(0),
+			      0x00200000 | ddr_data.ddrgrf_chn_con0[2]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(0),
+			      0x00200000 | ddr_data.ddrgrf_chn_con0[3]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(2),
+			      0x28000000 | ddr_data.ddrgrf_chn_con2[2]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(2),
+			      0x28000000 | ddr_data.ddrgrf_chn_con2[3]);
+	}
+}
+
+static void pmu_sleep_config(void)
+{
+	uint32_t pmu1_pwr_con, pmu1_wkup_int_con, pmu1_cru_pwr_con;
+	uint32_t pmu1_ddr_pwr_con, pmu1_pll_pd_con[2] = {0};
+	uint32_t pmu2_dsu_pwr_con, pmu2_core_pwr_con, pmu2_clst_idle_con;
+	uint32_t pmu2_bus_idle_con[3] = {0}, pmu2_pwr_gate_con[3] = {0};
+	uint32_t pmu2_vol_gate_con[3] = {0}, pmu2_qch_pwr_con = 0;
+	int i;
+
+	ddr_data.pmu1grf_soc_con7 = mmio_read_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(7));
+	ddr_data.pmu1grf_soc_con8 = mmio_read_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(8));
+	ddr_data.pmu1grf_soc_con9 = mmio_read_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(9));
+	ddr_data.pmu1sgrf_soc_con14 = mmio_read_32(PMU1SGRF_BASE + PMU1_SGRF_SOC_CON(14));
+	ddr_data.pmu0sgrf_soc_con1 = mmio_read_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(1));
+	ddr_data.pmu0grf_soc_con1 = mmio_read_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(1));
+
+	ddr_data.pmu2_vol_gate_con[0] = mmio_read_32(PMU_BASE + PMU2_VOL_GATE_CON(0));
+	ddr_data.pmu2_vol_gate_con[1] = mmio_read_32(PMU_BASE + PMU2_VOL_GATE_CON(1));
+	ddr_data.pmu2_vol_gate_con[2] = mmio_read_32(PMU_BASE + PMU2_VOL_GATE_CON(2));
+
+	ddr_data.pmu2_submem_gate_sft_con0 =
+		mmio_read_32(PMU_BASE + PMU2_MEMPWR_MD_GATE_SFTCON(0));
+
+	/* save pmic_sleep iomux gpio0_a4 */
+	ddr_data.gpio0a_iomux_l = mmio_read_32(PMU0IOC_BASE + 0);
+	ddr_data.gpio0a_iomux_h = mmio_read_32(PMU0IOC_BASE + 4);
+	ddr_data.pmu0grf_soc_con3 = mmio_read_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(3));
+
+	/* PMU1 repair disable */
+	mmio_write_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(0), 0x00010000);
+
+	/* set pmic_sleep iomux */
+	mmio_write_32(PMU0IOC_BASE + 0,
+		      BITS_WITH_WMASK(1, 0xf, 8) |
+		      BITS_WITH_WMASK(1, 0xfu, 12));
+
+	/* set tsadc_shut_m0 pin iomux to gpio */
+	mmio_write_32(PMU0IOC_BASE + 0,
+		      BITS_WITH_WMASK(0, 0xf, 4));
+
+	/* set spi2_cs0/1 pin iomux to gpio */
+	mmio_write_32(PMU0IOC_BASE + 8,
+		      BITS_WITH_WMASK(0, 0xff, 0));
+
+	/* sleep 1~2 src select */
+	mmio_write_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(3),
+		      BITS_WITH_WMASK(0x8, 0xf, 0) |
+		      BITS_WITH_WMASK(0x8, 0xf, 4) |
+		      BITS_WITH_WMASK(0x0, 0x3, 8));
+
+	pmu1_wkup_int_con = BIT(WAKEUP_GPIO0_INT_EN) |
+			    BIT(WAKEUP_CPU0_INT_EN);
+
+	pmu1_pwr_con = BIT(powermode_en);
+
+	pmu1_cru_pwr_con =
+		BIT(alive_osc_mode_en) |
+		BIT(power_off_en) |
+		BIT(pd_clk_src_gate_en);
+
+	pmu1_ddr_pwr_con = 0;
+
+	pmu2_dsu_pwr_con =
+		BIT(DSU_PWRDN_EN) |
+		BIT(DSU_PWROFF_EN);
+
+	pmu2_core_pwr_con = BIT(CORE_PWRDN_EN);
+
+	pmu2_clst_idle_con =
+		BIT(IDLE_REQ_BIGCORE0_EN) |
+		BIT(IDLE_REQ_BIGCORE1_EN) |
+		BIT(IDLE_REQ_DSU_EN) |
+		BIT(IDLE_REQ_LITDSU_EN) |
+		BIT(IDLE_REQ_ADB400_CORE_QCH_EN);
+
+	pmu1_pll_pd_con[0] =
+		BIT(B0PLL_PD_EN) |
+		BIT(B1PLL_PD_EN) |
+		BIT(LPLL_PD_EN) |
+		BIT(V0PLL_PD_EN) |
+		BIT(AUPLL_PD_EN) |
+		BIT(GPLL_PD_EN) |
+		BIT(CPLL_PD_EN) |
+		BIT(NPLL_PD_EN);
+
+	pmu1_pll_pd_con[1] =
+		BIT(PPLL_PD_EN) |
+		BIT(SPLL_PD_EN);
+
+	pmu2_bus_idle_con[0] = 0;
+
+	pmu2_bus_idle_con[1] =
+		BIT(BUS_ID_SECURE - 16) |
+		BIT(BUS_ID_SECURE_CENTER_CHANNEL - 16) |
+		BIT(BUS_ID_CENTER_CHANNEL - 16);
+
+	pmu2_bus_idle_con[2] =
+		BIT(BUS_ID_MSCH - 32) |
+		BIT(BUS_ID_BUS - 32) |
+		BIT(BUS_ID_TOP - 32);
+
+	pmu2_pwr_gate_con[0] = 0;
+	pmu2_pwr_gate_con[1] = BIT(PD_SECURE - 16);
+	pmu2_pwr_gate_con[2] = 0;
+
+	pmu2_qch_pwr_con = 0;
+
+	pmu2_vol_gate_con[0] = 0x7;
+	pmu2_vol_gate_con[2] = 0;
+
+	mmio_write_32(PMU_BASE + PMU2_CORE_AUTO_PWR_CON(0), 0x00030000);
+	mmio_write_32(PMU_BASE + PMU2_CORE_AUTO_PWR_CON(1), 0x00030000);
+	mmio_write_32(PMU_BASE + PMU2_CORE_PWR_CON(0),
+		      WITH_16BITS_WMSK(pmu2_core_pwr_con));
+	mmio_write_32(PMU_BASE + PMU2_CORE_PWR_CON(1),
+		      WITH_16BITS_WMSK(pmu2_core_pwr_con));
+	mmio_write_32(PMU_BASE + PMU2_CLUSTER_IDLE_CON,
+		      WITH_16BITS_WMSK(pmu2_clst_idle_con));
+	mmio_write_32(PMU_BASE + PMU2_DSU_AUTO_PWR_CON, 0x00030000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_PWR_CON,
+		      WITH_16BITS_WMSK(pmu2_dsu_pwr_con));
+
+	mmio_write_32(PMU_BASE + PMU1_OSC_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU1_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU1_WAKEUP_RST_CLR_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU1_PLL_LOCK_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU1_PWM_SWITCH_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE0_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE0_PWRUP_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE0_PWRDN_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE1_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE1_PWRUP_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE1_PWRDN_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_PWRUP_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_PWRDN_CNT_THRESH, 24000);
+
+	/* Config pmu power mode and pmu wakeup source */
+	mmio_write_32(PMU_BASE + PMU1_INT_MASK_CON,
+		      BITS_WITH_WMASK(1, 0x1, 0));
+
+	/* pmu1_pwr_con */
+	mmio_write_32(PMU_BASE + PMU1_PWR_CON,
+		      WITH_16BITS_WMSK(pmu1_pwr_con));
+
+	/* cru_pwr_con */
+	mmio_write_32(PMU_BASE + PMU1_CRU_PWR_CON,
+		      WITH_16BITS_WMSK(pmu1_cru_pwr_con));
+
+	/* wakeup source */
+	mmio_write_32(PMU_BASE + PMU1_WAKEUP_INT_CON, pmu1_wkup_int_con);
+
+	/* ddr pwr con */
+	for (i = 0; i < DDR_CHN_CNT; i++) {
+		mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(i),
+			      WITH_16BITS_WMSK(pmu1_ddr_pwr_con));
+		pmu2_bus_idle_con[1] |=
+			BIT(BUS_ID_MSCH0 - 16 + i);
+	}
+
+	/* pll_pd */
+	mmio_write_32(PMU_BASE + PMU1_PLLPD_CON(0),
+		      WITH_16BITS_WMSK(pmu1_pll_pd_con[0]));
+	mmio_write_32(PMU_BASE + PMU1_PLLPD_CON(1),
+		      WITH_16BITS_WMSK(pmu1_pll_pd_con[1]));
+
+	/* bypass cpu1~7*/
+	mmio_write_32(PMU_BASE + PMU2_PWR_CON1, 0x00ff00fe);
+
+	/* bus idle */
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(0),
+		      WITH_16BITS_WMSK(pmu2_bus_idle_con[0]));
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(1),
+		      WITH_16BITS_WMSK(pmu2_bus_idle_con[1]));
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(2),
+		      WITH_16BITS_WMSK(pmu2_bus_idle_con[2]));
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(2),
+		      0xf000f000);
+	/* power gate */
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(0),
+		      WITH_16BITS_WMSK(pmu2_pwr_gate_con[0]));
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(1),
+		      WITH_16BITS_WMSK(pmu2_pwr_gate_con[1]));
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(2),
+		      WITH_16BITS_WMSK(pmu2_pwr_gate_con[2]));
+	/* vol gate */
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(0),
+		      BITS_WITH_WMASK(pmu2_vol_gate_con[0], 0x7, 0));
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(1), 0);
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(2),
+		      BITS_WITH_WMASK(pmu2_vol_gate_con[2], 0x3, 0));
+	/* qch */
+	mmio_write_32(PMU_BASE + PMU2_QCHANNEL_PWR_CON,
+		      BITS_WITH_WMASK(pmu2_qch_pwr_con, 0x7f, 0));
+
+	mmio_write_32(PMU_BASE + PMU2_MEMPWR_MD_GATE_SFTCON(0),
+		      0x000f000f);
+}
+
+static void pmu_sleep_restore(void)
+{
+	mmio_write_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(7),
+		      WITH_16BITS_WMSK(ddr_data.pmu1grf_soc_con7));
+	mmio_write_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(8),
+		      WITH_16BITS_WMSK(ddr_data.pmu1grf_soc_con8));
+	mmio_write_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(9),
+		      WITH_16BITS_WMSK(ddr_data.pmu1grf_soc_con9));
+	mmio_write_32(PMU1SGRF_BASE + PMU1_SGRF_SOC_CON(14),
+		      WITH_16BITS_WMSK(ddr_data.pmu1sgrf_soc_con14));
+
+	mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(1),
+		      WITH_16BITS_WMSK(ddr_data.pmu0sgrf_soc_con1));
+	mmio_write_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(1),
+		      WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con1));
+
+	mmio_write_32(PMU_BASE + PMU2_CORE_PWR_CON(0), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_CORE_PWR_CON(1), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_CLUSTER_IDLE_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_PWR_CON1, 0xffff0000);
+
+	/* Must clear PMU1_WAKEUP_INT_CON because the wakeup source
+	 * in PMU1_WAKEUP_INT_CON will wakeup cpus in cpu_auto_pd state.
+	 */
+	mmio_write_32(PMU_BASE + PMU1_WAKEUP_INT_CON, 0);
+	mmio_write_32(PMU_BASE + PMU1_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_INT_MASK_CON, 0x00010000);
+	mmio_write_32(PMU_BASE + PMU0_WAKEUP_INT_CON, 0x00010000);
+	mmio_write_32(PMU_BASE + PMU0_PWR_CON, 0xffff0000);
+
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(0),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_vol_gate_con[0]));
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(1),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_vol_gate_con[1]));
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(2),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_vol_gate_con[2]));
+
+	mmio_write_32(PMU_BASE + PMU2_MEMPWR_MD_GATE_SFTCON(0),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_submem_gate_sft_con0));
+
+	mmio_write_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(3),
+		      WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con3));
+	mmio_write_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(2),
+		      WITH_16BITS_WMSK(ddr_data.pmu1grf_soc_con2));
+
+	mmio_write_32(PMU0IOC_BASE + 0x4,
+		      WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h));
+	mmio_write_32(PMU0IOC_BASE + 0,
+		      WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l));
+}
+
+static void soc_sleep_config(void)
+{
+	ddr_data.gpio0b_iomux_l = mmio_read_32(PMU0IOC_BASE + 0x8);
+
+	pmu_sleep_config();
+	ddr_sleep_config();
+}
+
+static void soc_sleep_restore(void)
+{
+	ddr_sleep_config_restore();
+	pmu_sleep_restore();
+
+	mmio_write_32(PMU0IOC_BASE + 0x8, WITH_16BITS_WMSK(ddr_data.gpio0b_iomux_l));
+}
+
+static void pm_pll_suspend(void)
+{
+	ddr_data.cru_mode_con = mmio_read_32(CRU_BASE + 0x280);
+	ddr_data.busscru_mode_con = mmio_read_32(BUSSCRU_BASE + 0x280);
+	ddr_data.pmu2_bisr_con0 = mmio_read_32(PMU_BASE + PMU2_BISR_CON(0));
+	ddr_data.cpll_con0 = mmio_read_32(CRU_BASE + CRU_PLLS_CON(2, 0));
+	ddr_data.pmu1cru_clksel_con1 = mmio_read_32(PMU1CRU_BASE + CRU_CLKSEL_CON(1));
+
+	/* disable bisr_init */
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(0), BITS_WITH_WMASK(0, 0x1, 0));
+	/* cpll bypass */
+	mmio_write_32(CRU_BASE + CRU_PLLS_CON(2, 0), BITS_WITH_WMASK(1u, 1u, 15));
+}
+
+static void pm_pll_restore(void)
+{
+	pm_pll_wait_lock(CRU_BASE + CRU_PLLS_CON(2, 0));
+
+	mmio_write_32(CRU_BASE + 0x280, WITH_16BITS_WMSK(ddr_data.cru_mode_con));
+	mmio_write_32(BUSSCRU_BASE + 0x280, WITH_16BITS_WMSK(ddr_data.busscru_mode_con));
+	mmio_write_32(CRU_BASE + CRU_PLLS_CON(2, 0), WITH_16BITS_WMSK(ddr_data.cpll_con0));
+	dsb();
+	isb();
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(0), WITH_16BITS_WMSK(ddr_data.pmu2_bisr_con0));
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+	clk_gate_con_save();
+	clk_gate_con_disable();
+
+	psram_sleep_cfg->pm_flag &= ~PM_WARM_BOOT_BIT;
+
+	pmu_power_domains_suspend();
+	soc_sleep_config();
+	dsu_core_save();
+	pm_pll_suspend();
+
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+	pm_pll_restore();
+	dsu_core_restore();
+	soc_sleep_restore();
+	pmu_power_domains_resume();
+	plat_rockchip_gic_cpuif_enable();
+
+	psram_sleep_cfg->pm_flag |= PM_WARM_BOOT_BIT;
+
+	clk_gate_con_restore();
+
+	return 0;
+}
+
+void __dead2 rockchip_soc_cores_pd_pwr_dn_wfi(const
+					psci_power_state_t *target_state)
+{
+	psci_power_down_wfi();
+}
+
+void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
+{
+	cpus_pd_req_enter_wfi();
+	psci_power_down_wfi();
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+	/* pll slow mode */
+	mmio_write_32(CRU_BASE + 0x280, 0x03ff0000);
+	mmio_write_32(BIGCORE0CRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(BIGCORE0CRU_BASE + 0x300, 0x60000000);
+	mmio_write_32(BIGCORE0CRU_BASE + 0x304, 0x00600000);
+	mmio_write_32(BIGCORE1CRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(BIGCORE1CRU_BASE + 0x300, 0x60000000);
+	mmio_write_32(BIGCORE1CRU_BASE + 0x304, 0x00600000);
+	mmio_write_32(DSUCRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(DSUCRU_BASE + 0x318, 0x30600000);
+	mmio_write_32(DSUCRU_BASE + 0x31c, 0x30600000);
+	mmio_write_32(DSUCRU_BASE + 0x304, 0x00010000);
+	mmio_write_32(BUSSCRU_BASE + 0x280, 0x0003000);
+	dsb();
+	isb();
+
+	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 execute valid codes.
+	 */
+	psci_power_down_wfi();
+}
+
+void __dead2 rockchip_soc_system_off(void)
+{
+	/* set pmic_sleep pin(gpio0_a2) to gpio mode */
+	mmio_write_32(PMU0IOC_BASE + 0, BITS_WITH_WMASK(0, 0xf, 8));
+
+	/* config output */
+	mmio_write_32(GPIO0_BASE + GPIO_SWPORT_DDR_L,
+		      BITS_WITH_WMASK(1, 0x1, 2));
+
+	/* config output high level */
+	mmio_write_32(GPIO0_BASE + GPIO_SWPORT_DR_L,
+		      BITS_WITH_WMASK(1, 0x1, 2));
+	dsb();
+
+	/*
+	 * Maybe the HW needs some times to reset the system,
+	 * so we do not hope the core to execute valid codes.
+	 */
+	psci_power_down_wfi();
+}
+
+static void rockchip_pmu_pd_init(void)
+{
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(1), 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(2), 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(3), 0xffffffff);
+
+	pmu_set_power_domain(PD_PHP, pmu_pd_on);
+	pmu_set_power_domain(PD_PCIE, pmu_pd_on);
+	pmu_set_power_domain(PD_GMAC, pmu_pd_on);
+	pmu_set_power_domain(PD_SECURE, pmu_pd_on);
+	pmu_set_power_domain(PD_VOP, pmu_pd_on);
+	pmu_set_power_domain(PD_VO0, pmu_pd_on);
+	pmu_set_power_domain(PD_VO1, pmu_pd_on);
+}
+
+#define PLL_LOCKED_TIMEOUT 600000U
+
+void pm_pll_wait_lock(uint32_t pll_base)
+{
+	int delay = PLL_LOCKED_TIMEOUT;
+
+	if ((mmio_read_32(pll_base + CRU_PLL_CON(1)) & CRU_PLLCON1_PWRDOWN) != 0)
+		return;
+
+	while (delay-- >= 0) {
+		if (mmio_read_32(pll_base + CRU_PLL_CON(6)) &
+		    CRU_PLLCON6_LOCK_STATUS)
+			break;
+		udelay(1);
+	}
+
+	if (delay <= 0)
+		ERROR("Can't wait pll(0x%x) lock\n", pll_base);
+}
+
+void rockchip_plat_mmu_el3(void)
+{
+	/* Nothing todo */
+}
+
+void plat_rockchip_pmu_init(void)
+{
+	int cpu;
+
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+		cpuson_flags[cpu] = 0;
+
+	psram_sleep_cfg->sp = PSRAM_SP_TOP;
+	psram_sleep_cfg->ddr_func = (uint64_t)ddr_resume;
+	psram_sleep_cfg->ddr_data = 0;
+	psram_sleep_cfg->ddr_flag = 0;
+	psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
+	psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+
+	nonboot_cpus_off();
+
+	/*
+	 * When perform idle operation, corresponding clock can be
+	 * opened or gated automatically.
+	 */
+	mmio_write_32(PMU_BASE + PMU2_BIU_AUTO_CON(0), 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU2_BIU_AUTO_CON(1), 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU2_BIU_AUTO_CON(2), 0x00070007);
+
+	rockchip_pmu_pd_init();
+
+	/* 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(PMU0GRF_BASE + PMU0_GRF_SOC_CON(3), 0x03ff0000);
+
+	/* pmusram remap to 0xffff0000 */
+	mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(2), 0x00030001);
+
+	pm_reg_rgns_init();
+}
+
+static uint64_t boot_cpu_save[4];
+/* define in .data section */
+static uint32_t need_en_crypto = 1;
+
+void rockchip_cpu_reset_early(u_register_t arg0, u_register_t arg1,
+			      u_register_t arg2, u_register_t arg3)
+{
+	if (need_en_crypto == 0)
+		return;
+
+	/* check the crypto function had been enabled or not */
+	if ((mmio_read_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4)) & BIT(4)) != 0) {
+		/* save x0~x3 */
+		boot_cpu_save[0] = arg0;
+		boot_cpu_save[1] = arg1;
+		boot_cpu_save[2] = arg2;
+		boot_cpu_save[3] = arg3;
+
+		/* enable the crypto function */
+		mmio_write_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4),
+			      BITS_WITH_WMASK(0, 0x1, 4));
+
+		/* remap pmusram to 0xffff0000 */
+		mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(2), 0x00030001);
+		psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+		cpuson_flags[0] = PMU_CPU_HOTPLUG;
+		cpuson_entry_point[0] = (uintptr_t)BL31_BASE;
+		dsb();
+
+		/* Must reset core0 to enable the crypto function.
+		 * Core0 will boot from pmu_sram and jump to BL31_BASE.
+		 */
+		__asm__ volatile ("mov	x0, #3\n"
+				  "dsb	sy\n"
+				  "msr	rmr_el3, x0\n"
+				  "1:\n"
+				  "isb\n"
+				  "wfi\n"
+				  "b	1b\n");
+	} else {
+		need_en_crypto = 0;
+
+		/* remap bootrom to 0xffff0000 */
+		mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(2), 0x00030000);
+
+		/*
+		 * the crypto function has been enabled,
+		 * restore the x0~x3.
+		 */
+		__asm__ volatile ("ldr	x20, [%0]\n"
+				  "ldr	x21, [%0, 0x8]\n"
+				  "ldr	x22, [%0, 0x10]\n"
+				  "ldr	x23, [%0, 0x18]\n"
+				  : : "r" (&boot_cpu_save[0]));
+	}
+}
diff --git a/plat/rockchip/rk3588/drivers/pmu/pmu.h b/plat/rockchip/rk3588/drivers/pmu/pmu.h
new file mode 100644
index 0000000..7d8288c
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/pmu.h
@@ -0,0 +1,589 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#include <lib/mmio.h>
+
+#define PMU0_PWR_CON			0x0000
+#define PMU0_WAKEUP_INT_CON		0x0008
+#define PMU0_WAKEUP_INT_ST		0x000c
+#define PMU0_PMIC_STABLE_CNT_THRES	0x0010
+#define PMU0_WAKEUP_RST_CLR_CNT_THRES	0x0014
+#define PMU0_OSC_STABLE_CNT_THRES	0x0018
+#define PMU0_PWR_CHAIN_STABLE_CON	0x001c
+#define PMU0_DDR_RET_CON(i)		(0x0020 + (i) * 4)
+#define PMU0_INFO_TX_CON		0x0030
+
+#define PMU1_VERSION_ID			0x4000
+#define PMU1_PWR_CON			0x4004
+#define PMU1_PWR_FSM			0x4008
+#define PMU1_INT_MASK_CON		0x400c
+#define PMU1_WAKEUP_INT_CON		0x4010
+#define PMU1_WAKEUP_INT_ST		0x4014
+#define PMU1_WAKEUP_EDGE_CON		0x4018
+#define PMU1_WAKEUP_EDGE_ST		0x401c
+#define PMU1_DDR_PWR_CON(i)		(0x4020 + (i) * 4)
+#define PMU1_DDR_PWR_SFTCON(i)		(0x4030 + (i) * 4)
+#define PMU1_DDR_PWR_FSM		0x4040
+#define PMU1_DDR_PWR_ST			0x4044
+#define PMU1_CRU_PWR_CON		0x4050
+#define PMU1_CRU_PWR_SFTCON		0x4054
+#define PMU1_CRU_PWR_FSM		0x4058
+#define PMU1_PLLPD_CON(i)		(0x4060 + (i) * 4)
+#define PMU1_PLLPD_SFTCON(i)		(0x4068 + (i) * 4)
+#define PMU1_STABLE_CNT_THRESH		0x4080
+#define PMU1_OSC_STABLE_CNT_THRESH	0x4084
+#define PMU1_WAKEUP_RST_CLR_CNT_THRESH	0x4088
+#define PMU1_PLL_LOCK_CNT_THRESH	0x408c
+#define PMU1_WAKEUP_TIMEOUT_THRESH	0x4094
+#define PMU1_PWM_SWITCH_CNT_THRESH	0x4098
+#define PMU1_SYS_REG(i)			(0x4100 + (i) * 4)
+
+#define PMU2_PWR_CON1			0x8000
+#define PMU2_DSU_PWR_CON		0x8004
+#define PMU2_DSU_PWR_SFTCON		0x8008
+#define PMU2_DSU_AUTO_PWR_CON		0x800c
+#define PMU2_CPU_AUTO_PWR_CON(i)	(0x8010 + (i) * 4)
+#define PMU2_CPU_PWR_SFTCON(i)		(0x8030 + (i) * 4)
+#define PMU2_CORE_PWR_CON(i)		(0x8050 + (i) * 4)
+#define PMU2_CORE_PWR_SFTCON(i)		(0x8058 + (i) * 4)
+#define PMU2_CORE_AUTO_PWR_CON(i)	(0x8060 + (i) * 4)
+#define PMU2_CLUSTER_NOC_AUTO_CON	0x8068
+#define PMU2_CLUSTER_DBG_PWR_CON	0x806c
+#define PMU2_CLUSTER_IDLE_CON		0x8070
+#define PMU2_CLUSTER_IDLE_SFTCON	0x8074
+#define PMU2_CLUSTER_IDLE_ACK		0x8078
+#define PMU2_CLUSTER_IDLE_ST		0x807c
+#define PMU2_CLUSTER_ST			0x8080
+#define PMU2_SCU_PWR_FSM_STATUS(i)	(0x8084 + (i) * 4)
+#define PMU2_CORE_PCHANNEL_STATUS(i)	(0x808c + (i) * 4)
+#define PMU2_CPU_PWR_CHAIN_STABLE_CON	0x8098
+#define PMU2_CLUSTER_MEMPWR_GATE_SFTCON	0x809c
+#define PMU2_DSU_STABLE_CNT_THRESH	0x80b0
+#define PMU2_DSU_PWRUP_CNT_THRESH	0x80b4
+#define PMU2_DSU_PWRDN_CNT_THRESH	0x80b8
+#define PMU2_CORE0_STABLE_CNT_THRESH	0x80bc
+#define PMU2_CORE0_PWRUP_CNT_THRESH	0x80c0
+#define PMU2_CORE0_PWRDN_CNT_THRESH	0x80c4
+#define PMU2_CORE1_STABLE_CNT_THRESH	0x80c8
+#define PMU2_CORE1_PWRUP_CNT_THRESH	0x80cc
+#define PMU2_CORE1_PWRDN_CNT_THRESH	0x80d0
+#define PMU2_DBG_RST_CNT_THRESH(i)	(0x80d4 + (i) * 4)
+#define PMU2_BUS_IDLE_CON(i)		(0x8100 + (i) * 4)
+#define PMU2_BUS_IDLE_SFTCON(i)		(0x810c + (i) * 4)
+#define PMU2_BUS_IDLE_ACK(i)		(0x8118 + (i) * 4)
+#define PMU2_BUS_IDLE_ST(i)		(0x8120 + (i) * 4)
+#define PMU2_BIU_AUTO_CON(i)		(0x8128 + (i) * 4)
+#define PMU2_PWR_GATE_CON(i)		(0x8140 + (i) * 4)
+#define PMU2_PWR_GATE_SFTCON(i)		(0x814c + (i) * 4)
+#define PMU2_VOL_GATE_CON(i)		(0x8158 + (i) * 4)
+#define PMU2_PWR_UP_CHAIN_STABLE_CON(i)	(0x8164 + (i) * 4)
+#define PMU2_PWR_DWN_CHAIN_STABLE_CON(i)(0x8170 + (i) * 4)
+#define PMU2_PWR_STABLE_CHAIN_CNT_THRES	0x817c
+#define PMU2_PWR_GATE_ST(i)		(0x8180 + (i) * 4)
+#define PMU2_PWR_GATE_FSM		0x8188
+#define PMU2_VOL_GATE_FAST_CON		0x818c
+#define PMU2_GPU_PWRUP_CNT		0x8190
+#define PMU2_GPU_PWRDN_CNT		0x8194
+#define PMU2_NPU_PWRUP_CNT		0x8198
+#define PMU2_NPU_PWRDN_CNT		0x819c
+#define PMU2_MEMPWR_GATE_SFTCON(i)	(0x81a0 + (i) * 4)
+#define PMU2_MEMPWR_MD_GATE_SFTCON(i)	(0x81b0 + (i) * 4)
+#define PMU2_MEMPWR_MD_GATE_STATUS	0x81bc
+#define PMU2_SUBMEM_PWR_ACK_BYPASS(i)	(0x81c0 + (i) * 4)
+#define PMU2_QCHANNEL_PWR_CON		0x81d0
+#define PMU2_QCHANNEL_PWR_SFTCON	0x81d4
+#define PMU2_QCHANNEL_STATUS		0x81d8
+#define PMU2_DEBUG_INFO_SEL		0x81e0
+#define PMU2_VOP_SUBPD_STATE		0x81e4
+#define PMU2_PWR_CHAIN0_ST(i)		(0x81e8 + (i) * 4)
+#define PMU2_PWR_CHAIN1_ST(i)		(0x81f0 + (i) * 4)
+#define PMU2_PWR_MEM_ST(i)		(0x81f8 + (i) * 4)
+#define PMU2_BISR_CON(i)		(0x8200 + (i) * 4)
+#define PMU2_BISR_STATUS(i)		(0x8280 + (i) * 4)
+
+#define PMU2_QCH_PWR_MSK		0x7f
+
+#define PD_CTR_LOOP			500
+#define PD_CHECK_LOOP			500
+#define WFEI_CHECK_LOOP			500
+#define BUS_IDLE_LOOP			1000
+#define QCH_PWR_LOOP			5000
+
+/* PMU1SCRU */
+#define PMU1SCRU_GATE_CON(i)		(0x800 + (i) * 4)
+
+/* PMU_GRF */
+#define PMU0_GRF_SOC_CON(i)		((i) * 4)
+#define PMU0_GRF_OS_REGS(i)		(0x80 + ((i) - 8) * 4)
+#define PMU1_GRF_SOC_CON(i)		((i) * 4)
+#define PMU0_GRF_IO_RET_CON(i)		(0x20 + (i) * 4)
+
+/* PMU_SGRF */
+#define PMU0_SGRF_SOC_CON(i)		((i) * 4)
+#define PMU1_SGRF_SOC_CON(i)		((i) * 4)
+
+/* sys grf */
+#define GRF_CPU_STATUS0			0x0420
+
+#define CORES_PM_DISABLE		0x0
+#define PD_CHECK_LOOP			500
+#define WFEI_CHECK_LOOP			500
+
+/* 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
+};
+
+/* PMU0_PWR_CON */
+enum pmu0_pwr_con {
+	pmu0_powermode_en = 0,
+	pmu0_pmu1_pwr_bypass = 1,
+	pmu0_pmu1_bus_bypass = 2,
+	pmu0_wkup_bypass = 3,
+	pmu0_pmic_bypass = 4,
+	pmu0_reset_bypass = 5,
+	pmu0_freq_sw_bypass = 6,
+	pmu0_osc_dis_bypass = 7,
+	pmu0_pmu1_pwr_gt_en = 8,
+	pmu0_pmu1_pwr_gt_sft_en = 9,
+	pmu0_pmu1_mem_gt_sft_en = 10,
+	pmu0_pmu1_bus_idle_en = 11,
+	pmu0_pmu1_bus_idle_sft_en = 12,
+	pmu0_pmu1_biu_auto_en = 13,
+	pmu0_pwr_off_io_en = 14,
+};
+
+/* PMU1_PWR_CON */
+enum pmu1_pwr_con {
+	powermode_en = 0,
+	dsu_bypass = 1,
+	bus_bypass = 4,
+	ddr_bypass = 5,
+	pwrdn_bypass = 6,
+	cru_bypass = 7,
+	qch_bypass = 8,
+	core_bypass = 9,
+	cpu_sleep_wfi_dis = 12,
+};
+
+/* PMU1_DDR_PWR_CON */
+enum pmu1_ddr_pwr_con {
+	ddr_sref_en = 0,
+	ddr_sref_a_en = 1,
+	ddrio_ret_en = 2,
+	ddrio_ret_exit_en = 5,
+	ddrio_rstiov_en = 6,
+	ddrio_rstiov_exit_en = 7,
+	ddr_gating_a_en = 8,
+	ddr_gating_c_en = 9,
+	ddr_gating_p_en = 10,
+};
+
+/* PMU_CRU_PWR_CON */
+enum pmu1_cru_pwr_con {
+	alive_32k_en = 0,
+	osc_dis_en = 1,
+	wakeup_rst_en = 2,
+	input_clamp_en = 3,
+	alive_osc_mode_en = 4,
+	power_off_en = 5,
+	pwm_switch_en = 6,
+	pwm_gpio_ioe_en = 7,
+	pwm_switch_io = 8,
+	pd_clk_src_gate_en = 9,
+};
+
+/* PMU_PLLPD_CON */
+enum pmu1_pllpd_con {
+	B0PLL_PD_EN,
+	B1PLL_PD_EN,
+	LPLL_PD_EN,
+	D0APLL_PD_EN,
+	D0BPLL_PD_EN,
+	D1APLL_PD_EN,
+	D1BPLL_PD_EN,
+	D2APLL_PD_EN,
+	D2BPLL_PD_EN,
+	D3APLL_PD_EN,
+	D3BPLL_PD_EN,
+	V0PLL_PD_EN,
+	AUPLL_PD_EN,
+	GPLL_PD_EN,
+	CPLL_PD_EN,
+	NPLL_PD_EN,
+	PPLL_PD_EN = 0,
+	SPLL_PD_EN = 1,
+};
+
+enum pmu1_wakeup_int {
+	WAKEUP_CPU0_INT_EN,
+	WAKEUP_CPU1_INT_EN,
+	WAKEUP_CPU2_INT_EN,
+	WAKEUP_CPU3_INT_EN,
+	WAKEUP_CPU4_INT_EN,
+	WAKEUP_CPU5_INT_EN,
+	WAKEUP_CPU6_INT_EN,
+	WAKEUP_CPU7_INT_EN,
+	WAKEUP_GPIO0_INT_EN,
+	WAKEUP_SDMMC_EN,
+	WAKEUP_SDIO_EN,
+	WAKEUP_USBDEV_EN,
+	WAKEUP_UART0_EN,
+	WAKEUP_VAD_EN,
+	WAKEUP_TIMER_EN,
+	WAKEUP_SOC_INT_EN,
+	WAKEUP_TIMEROUT_EN,
+	WAKEUP_PMUMCU_CEC_EN = 20,
+};
+
+enum pmu2_dsu_auto_pwr_con {
+	dsu_pm_en = 0,
+	dsu_pm_int_wakeup_en = 1,
+	dsu_pm_sft_wakeup_en = 3,
+};
+
+enum pmu2_cpu_auto_pwr_con {
+	cpu_pm_en = 0,
+	cpu_pm_int_wakeup_en = 1,
+	cpu_pm_sft_wakeup_en = 3,
+};
+
+enum pmu2_core_auto_pwr_con {
+	core_pm_en = 0,
+	core_pm_int_wakeup_en = 1,
+	core_pm_int_wakeup_glb_msk = 2,
+	core_pm_sft_wakeup_en = 3,
+};
+
+enum pmu2_dsu_power_con {
+	DSU_PWRDN_EN,
+	DSU_PWROFF_EN,
+	BIT_FULL_EN,
+	DSU_RET_EN,
+	CLUSTER_CLK_SRC_GT_EN,
+};
+
+enum pmu2_core_power_con {
+	CORE_PWRDN_EN,
+	CORE_PWROFF_EN,
+	CORE_CPU_PWRDN_EN,
+	CORE_PWR_CNT_EN,
+};
+
+enum pmu2_cluster_idle_con {
+	IDLE_REQ_BIGCORE0_EN = 0,
+	IDLE_REQ_BIGCORE1_EN = 2,
+	IDLE_REQ_DSU_EN = 4,
+	IDLE_REQ_LITDSU_EN = 5,
+	IDLE_REQ_ADB400_CORE_QCH_EN = 6,
+};
+
+enum qos_id {
+	QOS_ISP0_MWO = 0,
+	QOS_ISP0_MRO = 1,
+	QOS_ISP1_MWO = 2,
+	QOS_ISP1_MRO = 3,
+	QOS_VICAP_M0 = 4,
+	QOS_VICAP_M1 = 5,
+	QOS_FISHEYE0 = 6,
+	QOS_FISHEYE1 = 7,
+	QOS_VOP_M0 = 8,
+	QOS_VOP_M1 = 9,
+	QOS_RKVDEC0 = 10,
+	QOS_RKVDEC1 = 11,
+	QOS_AV1 = 12,
+	QOS_RKVENC0_M0RO = 13,
+	QOS_RKVENC0_M1RO = 14,
+	QOS_RKVENC0_M2WO = 15,
+	QOS_RKVENC1_M0RO = 16,
+	QOS_RKVENC1_M1RO = 17,
+	QOS_RKVENC1_M2WO = 18,
+	QOS_DSU_M0 = 19,
+	QOS_DSU_M1 = 20,
+	QOS_DSU_MP = 21,
+	QOS_DEBUG = 22,
+	QOS_GPU_M0 = 23,
+	QOS_GPU_M1 = 24,
+	QOS_GPU_M2 = 25,
+	QOS_GPU_M3 = 26,
+	QOS_NPU1 = 27,
+	QOS_NPU0_MRO = 28,
+	QOS_NPU2 = 29,
+	QOS_NPU0_MWR = 30,
+	QOS_MCU_NPU = 31,
+	QOS_JPEG_DEC = 32,
+	QOS_JPEG_ENC0 = 33,
+	QOS_JPEG_ENC1 = 34,
+	QOS_JPEG_ENC2 = 35,
+	QOS_JPEG_ENC3 = 36,
+	QOS_RGA2_MRO = 37,
+	QOS_RGA2_MWO = 38,
+	QOS_RGA3_0 = 39,
+	QOS_RGA3_1 = 40,
+	QOS_VDPU = 41,
+	QOS_IEP = 42,
+	QOS_HDCP0 = 43,
+	QOS_HDCP1 = 44,
+	QOS_HDMIRX = 45,
+	QOS_GIC600_M0 = 46,
+	QOS_GIC600_M1 = 47,
+	QOS_MMU600PCIE_TCU = 48,
+	QOS_MMU600PHP_TBU = 49,
+	QOS_MMU600PHP_TCU = 50,
+	QOS_USB3_0 = 51,
+	QOS_USB3_1 = 52,
+	QOS_USBHOST_0 = 53,
+	QOS_USBHOST_1 = 54,
+	QOS_EMMC = 55,
+	QOS_FSPI = 56,
+	QOS_SDIO = 57,
+	QOS_DECOM = 58,
+	QOS_DMAC0 = 59,
+	QOS_DMAC1 = 60,
+	QOS_DMAC2 = 61,
+	QOS_GIC600M = 62,
+	QOS_DMA2DDR = 63,
+	QOS_MCU_DDR = 64,
+	QOS_VAD = 65,
+	QOS_MCU_PMU = 66,
+	QOS_CRYPTOS = 67,
+	QOS_CRYPTONS = 68,
+	QOS_DCF = 69,
+	QOS_SDMMC = 70,
+};
+
+enum pmu2_pdid {
+	PD_GPU = 0,
+	PD_NPU = 1,
+	PD_VCODEC = 2,
+	PD_NPUTOP = 3,
+	PD_NPU1 = 4,
+	PD_NPU2 = 5,
+	PD_VENC0 = 6,
+	PD_VENC1 = 7,
+	PD_RKVDEC0 = 8,
+	PD_RKVDEC1 = 9,
+	PD_VDPU = 10,
+	PD_RGA30 = 11,
+	PD_AV1 = 12,
+	PD_VI = 13,
+	PD_FEC = 14,
+	PD_ISP1 = 15,
+	PD_RGA31 = 16,
+	PD_VOP = 17,
+	PD_VO0 = 18,
+	PD_VO1 = 19,
+	PD_AUDIO = 20,
+	PD_PHP = 21,
+	PD_GMAC = 22,
+	PD_PCIE = 23,
+	PD_NVM = 24,
+	PD_NVM0 = 25,
+	PD_SDIO = 26,
+	PD_USB = 27,
+	PD_SECURE = 28,
+	PD_SDMMC = 29,
+	PD_CRYPTO = 30,
+	PD_CENTER = 31,
+	PD_DDR01 = 32,
+	PD_DDR23 = 33,
+};
+
+enum pmu2_pd_repair_id {
+	PD_RPR_PMU = 0,
+	PD_RPR_GPU = 1,
+	PD_RPR_NPUTOP = 2,
+	PD_RPR_NPU1 = 3,
+	PD_RPR_NPU2 = 4,
+	PD_RPR_VENC0 = 5,
+	PD_RPR_VENC1 = 6,
+	PD_RPR_RKVDEC0 = 7,
+	PD_RPR_RKVDEC1 = 8,
+	PD_RPR_VDPU = 9,
+	PD_RPR_RGA30 = 10,
+	PD_RPR_AV1 = 11,
+	PD_RPR_VI = 12,
+	PD_RPR_FEC = 13,
+	PD_RPR_ISP1 = 14,
+	PD_RPR_RGA31 = 15,
+	PD_RPR_VOP = 16,
+	PD_RPR_VO0 = 17,
+	PD_RPR_VO1 = 18,
+	PD_RPR_AUDIO = 19,
+	PD_RPR_PHP = 20,
+	PD_RPR_GMAC = 21,
+	PD_RPR_PCIE = 22,
+	PD_RPR_NVM0 = 23,
+	PD_RPR_SDIO = 24,
+	PD_RPR_USB = 25,
+	PD_RPR_SDMMC = 26,
+	PD_RPR_CRYPTO = 27,
+	PD_RPR_CENTER = 28,
+	PD_RPR_DDR01 = 29,
+	PD_RPR_DDR23 = 30,
+	PD_RPR_BUS = 31,
+};
+
+enum pmu2_bus_id {
+	BUS_ID_GPU = 0,
+	BUS_ID_NPUTOP = 1,
+	BUS_ID_NPU1 = 2,
+	BUS_ID_NPU2 = 3,
+	BUS_ID_RKVENC0 = 4,
+	BUS_ID_RKVENC1 = 5,
+	BUS_ID_RKVDEC0 = 6,
+	BUS_ID_RKVDEC1 = 7,
+	BUS_ID_VDPU = 8,
+	BUS_ID_AV1 = 9,
+	BUS_ID_VI = 10,
+	BUS_ID_ISP = 11,
+	BUS_ID_RGA31 = 12,
+	BUS_ID_VOP = 13,
+	BUS_ID_VOP_CHANNEL = 14,
+	BUS_ID_VO0 = 15,
+	BUS_ID_VO1 = 16,
+	BUS_ID_AUDIO = 17,
+	BUS_ID_NVM = 18,
+	BUS_ID_SDIO = 19,
+	BUS_ID_USB = 20,
+	BUS_ID_PHP = 21,
+	BUS_ID_VO1USBTOP = 22,
+	BUS_ID_SECURE = 23,
+	BUS_ID_SECURE_CENTER_CHANNEL = 24,
+	BUS_ID_SECURE_VO1USB_CHANNEL = 25,
+	BUS_ID_CENTER = 26,
+	BUS_ID_CENTER_CHANNEL = 27,
+	BUS_ID_MSCH0 = 28,
+	BUS_ID_MSCH1 = 29,
+	BUS_ID_MSCH2 = 30,
+	BUS_ID_MSCH3 = 31,
+	BUS_ID_MSCH = 32,
+	BUS_ID_BUS = 33,
+	BUS_ID_TOP = 34,
+};
+
+enum pmu2_mem_st {
+	PD_NPU_TOP_MEM_ST = 11,
+	PD_NPU1_MEM_ST = 12,
+	PD_NPU2_MEM_ST = 13,
+	PD_VENC0_MEM_ST = 14,
+	PD_VENC1_MEM_ST = 15,
+	PD_RKVDEC0_MEM_ST = 16,
+	PD_RKVDEC1_MEM_ST = 17,
+	PD_RGA30_MEM_ST = 19,
+	PD_AV1_MEM_ST = 20,
+	PD_VI_MEM_ST = 21,
+	PD_FEC_MEM_ST = 22,
+	PD_ISP1_MEM_ST = 23,
+	PD_RGA31_MEM_ST = 24,
+	PD_VOP_MEM_ST = 25,
+	PD_VO0_MEM_ST = 26,
+	PD_VO1_MEM_ST = 27,
+	PD_AUDIO_MEM_ST = 28,
+	PD_PHP_MEM_ST = 29,
+	PD_GMAC_MEM_ST = 30,
+	PD_PCIE_MEM_ST = 31,
+	PD_NVM0_MEM_ST = 33,
+	PD_SDIO_MEM_ST = 34,
+	PD_USB_MEM_ST = 35,
+	PD_SDMMC_MEM_ST = 37,
+};
+
+enum pmu2_qid {
+	QID_PHPMMU_TBU = 0,
+	QID_PHPMMU_TCU = 1,
+	QID_PCIEMMU_TBU0 = 2,
+	QID_PCIEMU_TCU = 3,
+	QID_PHP_GICITS = 4,
+	QID_BUS_GICITS0 = 5,
+	QID_BUS_GICITS1 = 6,
+};
+
+/* 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
+};
+
+/* PMU2_CLUSTER_STS 0x8080 */
+enum pmu2_cluster_sts_bits {
+	pd_cpu0_dwn = 0,
+	pd_cpu1_dwn,
+	pd_cpu2_dwn,
+	pd_cpu3_dwn,
+	pd_cpu4_dwn,
+	pd_cpu5_dwn,
+	pd_cpu6_dwn,
+	pd_cpu7_dwn,
+	pd_core0_dwn,
+	pd_core1_dwn
+};
+
+#define CLUSTER_STS_NONBOOT_CPUS_DWN	0xfe
+
+enum cpu_off_trigger {
+	CPU_OFF_TRIGGER_WFE = 0,
+	CPU_OFF_TRIGGER_REQ_EML,
+	CPU_OFF_TRIGGER_REQ_WFI,
+	CPU_OFF_TRIGGER_REQ_WFI_NBT_CPU,
+	CPU_OFF_TRIGGER_REQ_WFI_NBT_CPU_SRAM
+};
+
+/*****************************************************************************
+ * power domain on or off
+ *****************************************************************************/
+enum pmu_pd_state {
+	pmu_pd_on = 0,
+	pmu_pd_off = 1
+};
+
+enum bus_state {
+	bus_active,
+	bus_idle,
+};
+
+#define RK_CPU_STATUS_OFF		0
+#define RK_CPU_STATUS_ON		1
+#define RK_CPU_STATUS_BUSY		-1
+
+#define PD_CTR_LOOP			500
+#define MAX_WAIT_COUNT			500
+
+#define pmu_bus_idle_st(id)	\
+	(!!(mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST((id) / 32)) & BIT((id) % 32)))
+
+#define pmu_bus_idle_ack(id)	\
+	(!!(mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ACK((id) / 32)) & BIT((id) % 32)))
+
+void pm_pll_wait_lock(uint32_t pll_base);
+#endif /* __PMU_H__ */
diff --git a/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c
new file mode 100644
index 0000000..ab3af5f
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c
@@ -0,0 +1,2463 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include "rk3588_clk.h"
+#include <rockchip_sip_svc.h>
+#include <scmi_clock.h>
+#include <soc.h>
+
+enum pll_type_sel {
+	PLL_SEL_AUTO, /* all plls (normal pll or pvtpll) */
+	PLL_SEL_PVT,
+	PLL_SEL_NOR,
+	PLL_SEL_AUTO_NOR /* all normal plls (apll/gpll/npll) */
+};
+
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
+#define RK3588_CPUL_PVTPLL_CON0_L	0x40
+#define RK3588_CPUL_PVTPLL_CON0_H	0x44
+#define RK3588_CPUL_PVTPLL_CON1		0x48
+#define RK3588_CPUL_PVTPLL_CON2		0x4c
+#define RK3588_CPUB_PVTPLL_CON0_L	0x00
+#define RK3588_CPUB_PVTPLL_CON0_H	0x04
+#define RK3588_CPUB_PVTPLL_CON1		0x08
+#define RK3588_CPUB_PVTPLL_CON2		0x0c
+#define RK3588_DSU_PVTPLL_CON0_L	0x60
+#define RK3588_DSU_PVTPLL_CON0_H	0x64
+#define RK3588_DSU_PVTPLL_CON1		0x70
+#define RK3588_DSU_PVTPLL_CON2		0x74
+#define RK3588_GPU_PVTPLL_CON0_L	0x00
+#define RK3588_GPU_PVTPLL_CON0_H	0x04
+#define RK3588_GPU_PVTPLL_CON1		0x08
+#define RK3588_GPU_PVTPLL_CON2		0x0c
+#define RK3588_NPU_PVTPLL_CON0_L	0x0c
+#define RK3588_NPU_PVTPLL_CON0_H	0x10
+#define RK3588_NPU_PVTPLL_CON1		0x14
+#define RK3588_NPU_PVTPLL_CON2		0x18
+#define RK3588_PVTPLL_MAX_LENGTH	0x3f
+
+#define GPLL_RATE			1188000000
+#define CPLL_RATE			1500000000
+#define SPLL_RATE			702000000
+#define AUPLL_RATE			786431952
+#define NPLL_RATE			850000000
+
+#define MAX_RATE_TABLE			16
+
+#define CLKDIV_6BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3fU, shift)
+#define CLKDIV_5BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1fU, shift)
+#define CLKDIV_4BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0xfU, shift)
+#define CLKDIV_3BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x7U, shift)
+#define CLKDIV_2BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3U, shift)
+#define CLKDIV_1BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1U, shift)
+
+#define CPU_PLL_PATH_SLOWMODE		BITS_WITH_WMASK(0U, 0x3U, 0)
+#define CPU_PLL_PATH_NORMAL		BITS_WITH_WMASK(1U, 0x3U, 0)
+#define CPU_PLL_PATH_DEEP_SLOW		BITS_WITH_WMASK(2U, 0x3U, 0)
+
+#define CRU_PLL_POWER_DOWN		BIT_WITH_WMSK(13)
+#define CRU_PLL_POWER_UP		WMSK_BIT(13)
+
+/* core_i: from gpll or apll */
+#define CLK_CORE_I_SEL_APLL		WMSK_BIT(6)
+#define CLK_CORE_I_SEL_GPLL		BIT_WITH_WMSK(6)
+
+/* clk_core:
+ * from normal pll(core_i: gpll or apll) path or direct pass from apll
+ */
+
+/* cpul clk path */
+#define CPUL_CLK_PATH_NOR_XIN		BITS_WITH_WMASK(0U, 0x3U, 14)
+#define CPUL_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(1U, 0x3U, 14)
+#define CPUL_CLK_PATH_NOR_LPLL		BITS_WITH_WMASK(2U, 0x3U, 14)
+
+#define CPUL_CLK_PATH_LPLL		(BITS_WITH_WMASK(0U, 0x3U, 5) | \
+					BITS_WITH_WMASK(0U, 0x3U, 12))
+#define CPUL_CLK_PATH_DIR_LPLL		(BITS_WITH_WMASK(0x1, 0x3U, 5) | \
+					BITS_WITH_WMASK(1U, 0x3U, 12))
+#define CPUL_CLK_PATH_PVTPLL		(BITS_WITH_WMASK(0x2, 0x3U, 5) | \
+					BITS_WITH_WMASK(2U, 0x3U, 12))
+
+#define CPUL_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 14)
+#define CPUL_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x1U, 14)
+
+/* cpub01 clk path */
+#define CPUB01_CLK_PATH_NOR_XIN		BITS_WITH_WMASK(0U, 0x3U, 6)
+#define CPUB01_CLK_PATH_NOR_GPLL	BITS_WITH_WMASK(1U, 0x3U, 6)
+#define CPUB01_CLK_PATH_NOR_B0PLL	BITS_WITH_WMASK(2U, 0x3U, 6)
+
+#define CPUB01_CLK_PATH_B0PLL		BITS_WITH_WMASK(0U, 0x3U, 13)
+#define CPUB01_CLK_PATH_DIR_B0PLL	BITS_WITH_WMASK(1U, 0x3U, 13)
+#define CPUB01_CLK_PATH_B0_PVTPLL	BITS_WITH_WMASK(2U, 0x3U, 13)
+
+#define CPUB01_CLK_PATH_B1PLL		BITS_WITH_WMASK(0U, 0x3U, 5)
+#define CPUB01_CLK_PATH_DIR_B1PLL	BITS_WITH_WMASK(1U, 0x3U, 5)
+#define CPUB01_CLK_PATH_B1_PVTPLL	BITS_WITH_WMASK(2U, 0x3U, 5)
+
+#define CPUB01_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 2)
+#define CPUB01_PVTPLL_PATH_PVTPLL	BITS_WITH_WMASK(1U, 0x1U, 2)
+
+#define CPUB_PCLK_PATH_100M		BITS_WITH_WMASK(0U, 0x3U, 0)
+#define CPUB_PCLK_PATH_50M		BITS_WITH_WMASK(1U, 0x3U, 0)
+#define CPUB_PCLK_PATH_24M		BITS_WITH_WMASK(2U, 0x3U, 0)
+
+/* dsu clk path */
+#define SCLK_DSU_PATH_NOR_B0PLL		BITS_WITH_WMASK(0U, 0x3U, 12)
+#define SCLK_DSU_PATH_NOR_B1PLL		BITS_WITH_WMASK(1U, 0x3U, 12)
+#define SCLK_DSU_PATH_NOR_LPLL		BITS_WITH_WMASK(2U, 0x3U, 12)
+#define SCLK_DSU_PATH_NOR_GPLL		BITS_WITH_WMASK(3U, 0x3U, 12)
+
+#define DSU_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 15)
+#define DSU_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x1U, 15)
+
+#define SCLK_DSU_PATH_NOR_PLL		WMSK_BIT(0)
+#define SCLK_DSU_PATH_PVTPLL		BIT_WITH_WMSK(0)
+
+/* npu clk path */
+#define NPU_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(0U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_CPLL		BITS_WITH_WMASK(1U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_AUPLL		BITS_WITH_WMASK(2U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_NPLL		BITS_WITH_WMASK(3U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_SPLL		BITS_WITH_WMASK(4U, 0x7U, 7)
+
+#define NPU_CLK_PATH_NOR_PLL		WMSK_BIT(0)
+#define NPU_CLK_PATH_PVTPLL		BIT_WITH_WMSK(0)
+
+/* gpu clk path */
+#define GPU_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(0U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_CPLL		BITS_WITH_WMASK(1U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_AUPLL		BITS_WITH_WMASK(2U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_NPLL		BITS_WITH_WMASK(3U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_SPLL		BITS_WITH_WMASK(4U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_PLL		WMSK_BIT(14)
+#define GPU_CLK_PATH_PVTPLL		BIT_WITH_WMSK(14)
+
+#define PVTPLL_NEED(type, length)	(((type) == PLL_SEL_PVT || \
+					  (type) == PLL_SEL_AUTO) && \
+					 (length))
+
+struct pvtpll_table {
+	unsigned int rate;
+	uint32_t length;
+	uint32_t ring_sel;
+};
+
+struct sys_clk_info_t {
+	struct pvtpll_table *cpul_table;
+	struct pvtpll_table *cpub01_table;
+	struct pvtpll_table *cpub23_table;
+	struct pvtpll_table *gpu_table;
+	struct pvtpll_table *npu_table;
+	unsigned int cpul_rate_count;
+	unsigned int cpub01_rate_count;
+	unsigned int cpub23_rate_count;
+	unsigned int gpu_rate_count;
+	unsigned int npu_rate_count;
+	unsigned long cpul_rate;
+	unsigned long dsu_rate;
+	unsigned long cpub01_rate;
+	unsigned long cpub23_rate;
+	unsigned long gpu_rate;
+	unsigned long npu_rate;
+};
+
+#define RK3588_SCMI_CLOCK(_id, _name, _data, _table, _cnt, _is_s)	\
+{									\
+	.id	= _id,							\
+	.name = _name,							\
+	.clk_ops = _data,						\
+	.rate_table = _table,						\
+	.rate_cnt = _cnt,						\
+	.is_security = _is_s,						\
+}
+
+#define ROCKCHIP_PVTPLL(_rate, _sel, _len)				\
+{									\
+	.rate = _rate##U,						\
+	.ring_sel = _sel,						\
+	.length = _len,							\
+}
+
+static struct pvtpll_table rk3588_cpul_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length */
+	ROCKCHIP_PVTPLL(1800000000, 1, 15),
+	ROCKCHIP_PVTPLL(1704000000, 1, 15),
+	ROCKCHIP_PVTPLL(1608000000, 1, 15),
+	ROCKCHIP_PVTPLL(1416000000, 1, 15),
+	ROCKCHIP_PVTPLL(1200000000, 1, 17),
+	ROCKCHIP_PVTPLL(1008000000, 1, 22),
+	ROCKCHIP_PVTPLL(816000000, 1, 32),
+	ROCKCHIP_PVTPLL(600000000, 0, 0),
+	ROCKCHIP_PVTPLL(408000000, 0, 0),
+	{ /* sentinel */ },
+};
+
+static struct pvtpll_table rk3588_cpub0_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length */
+	ROCKCHIP_PVTPLL(2400000000, 1, 11),
+	ROCKCHIP_PVTPLL(2352000000, 1, 11),
+	ROCKCHIP_PVTPLL(2304000000, 1, 11),
+	ROCKCHIP_PVTPLL(2256000000, 1, 11),
+	ROCKCHIP_PVTPLL(2208000000, 1, 11),
+	ROCKCHIP_PVTPLL(2112000000, 1, 11),
+	ROCKCHIP_PVTPLL(2016000000, 1, 11),
+	ROCKCHIP_PVTPLL(1800000000, 1, 11),
+	ROCKCHIP_PVTPLL(1608000000, 1, 11),
+	ROCKCHIP_PVTPLL(1416000000, 1, 13),
+	ROCKCHIP_PVTPLL(1200000000, 1, 17),
+	ROCKCHIP_PVTPLL(1008000000, 1, 23),
+	ROCKCHIP_PVTPLL(816000000, 1, 33),
+	ROCKCHIP_PVTPLL(600000000, 0, 0),
+	ROCKCHIP_PVTPLL(408000000, 0, 0),
+	{ /* sentinel */ },
+};
+
+static struct
+pvtpll_table rk3588_cpub1_pvtpll_table[ARRAY_SIZE(rk3588_cpub0_pvtpll_table)] = { 0 };
+
+static struct pvtpll_table rk3588_gpu_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length */
+	ROCKCHIP_PVTPLL(1000000000, 1, 12),
+	ROCKCHIP_PVTPLL(900000000, 1, 12),
+	ROCKCHIP_PVTPLL(800000000, 1, 12),
+	ROCKCHIP_PVTPLL(700000000, 1, 13),
+	ROCKCHIP_PVTPLL(600000000, 1, 17),
+	ROCKCHIP_PVTPLL(500000000, 1, 25),
+	ROCKCHIP_PVTPLL(400000000, 1, 38),
+	ROCKCHIP_PVTPLL(300000000, 1, 55),
+	ROCKCHIP_PVTPLL(200000000, 0, 0),
+	{ /* sentinel */ },
+};
+
+static struct pvtpll_table rk3588_npu_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length */
+	ROCKCHIP_PVTPLL(1000000000, 1, 12),
+	ROCKCHIP_PVTPLL(900000000, 1, 12),
+	ROCKCHIP_PVTPLL(800000000, 1, 12),
+	ROCKCHIP_PVTPLL(700000000, 1, 13),
+	ROCKCHIP_PVTPLL(600000000, 1, 17),
+	ROCKCHIP_PVTPLL(500000000, 1, 25),
+	ROCKCHIP_PVTPLL(400000000, 1, 38),
+	ROCKCHIP_PVTPLL(300000000, 1, 55),
+	ROCKCHIP_PVTPLL(200000000, 0, 0),
+	{ /* sentinel */ },
+};
+
+static unsigned long rk3588_cpul_rates[] = {
+	408000000, 600000000, 816000000, 1008000000,
+	1200000000, 1416000000, 1608000000, 1800000063,
+};
+
+static unsigned long rk3588_cpub_rates[] = {
+	408000000, 816000000, 1008000000, 1200000000,
+	1416000000, 1608000000, 1800000000, 2016000000,
+	2208000000, 2304000000, 2400000063
+};
+
+static unsigned long rk3588_gpu_rates[] = {
+	200000000, 300000000, 400000000, 500000000,
+	600000000, 700000000, 800000000, 900000000,
+	1000000063
+};
+
+static unsigned long rk3588_sbus_rates[] = {
+	24000000, 50000000, 100000000, 150000000, 200000000,
+	250000000, 350000000, 700000000
+};
+
+static unsigned long rk3588_sdmmc_rates[] = {
+	400000, 24000000, 50000000, 100000000, 150000000, 200000000,
+	300000000, 400000000, 600000000, 700000000
+};
+
+static struct sys_clk_info_t sys_clk_info;
+static int clk_scmi_dsu_set_rate(rk_scmi_clock_t *clock, unsigned long rate);
+
+static struct pvtpll_table *rkclk_get_pvtpll_config(struct pvtpll_table *table,
+						    unsigned int count,
+						    unsigned int freq_hz)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		if (freq_hz == table[i].rate)
+			return &table[i];
+	}
+	return NULL;
+}
+
+static int clk_cpul_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpul_table,
+					 sys_clk_info.cpul_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	/* set lpll */
+	if (PVTPLL_NEED(type, pvtpll->length) != 0) {
+		/* set clock gating interval */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set corel mux pvtpll */
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+			      CPUL_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
+			      CPUL_CLK_PATH_PVTPLL);
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+			      CPUL_CLK_PATH_PVTPLL);
+		return 0;
+	}
+
+	/* set clk corel div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
+		      CLKDIV_5BITS_SHF(div, 0) | CLKDIV_5BITS_SHF(div, 7));
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+		      CLKDIV_5BITS_SHF(div, 0) | CLKDIV_5BITS_SHF(div, 7));
+	/* set corel mux gpll */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5),
+		      CPUL_CLK_PATH_NOR_GPLL);
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
+		      CPUL_CLK_PATH_LPLL);
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+		      CPUL_CLK_PATH_LPLL);
+
+	return 0;
+}
+
+static int clk_scmi_cpul_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_cpul_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0) {
+		sys_clk_info.cpul_rate = rate;
+		ret = clk_scmi_dsu_set_rate(clock, rate);
+	}
+
+	return ret;
+}
+
+static unsigned long rk3588_lpll_get_rate(void)
+{
+	unsigned int m, p, s, k;
+	uint64_t rate64 = 24000000, postdiv;
+	int mode;
+
+	mode = (mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(5)) >> 14) &
+	       0x3;
+
+	if (mode == 0)
+		return rate64;
+
+	m = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(16)) >>
+		 CRU_PLLCON0_M_SHIFT) &
+		CRU_PLLCON0_M_MASK;
+	p = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(17)) >>
+		    CRU_PLLCON1_P_SHIFT) &
+		   CRU_PLLCON1_P_MASK;
+	s = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(17)) >>
+		  CRU_PLLCON1_S_SHIFT) &
+		 CRU_PLLCON1_S_MASK;
+	k = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(18)) >>
+		    CRU_PLLCON2_K_SHIFT) &
+		   CRU_PLLCON2_K_MASK;
+
+	rate64 *= m;
+	rate64 = rate64 / p;
+
+	if (k != 0) {
+		/* fractional mode */
+		uint64_t frac_rate64 = 24000000 * k;
+
+		postdiv = p * 65535;
+		frac_rate64 = frac_rate64 / postdiv;
+		rate64 += frac_rate64;
+	}
+	rate64 = rate64 >> s;
+
+	return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpul_get_rate(rk_scmi_clock_t *clock)
+{
+	int src, div;
+
+	src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(6)) & 0x0060;
+	src = src >> 5;
+	if (src == 2) {
+		return sys_clk_info.cpul_rate;
+	} else {
+		src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(5)) & 0xc000;
+		src = src >> 14;
+		div = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(6)) & 0x1f;
+		switch (src) {
+		case 0:
+			return 24000000;
+		case 1:
+			/* Make the return rate is equal to the set rate */
+			if (sys_clk_info.cpul_rate)
+				return sys_clk_info.cpul_rate;
+			else
+				return GPLL_RATE / (div + 1);
+		case 2:
+			return rk3588_lpll_get_rate();
+		default:
+			return 0;
+		}
+	}
+}
+
+static int clk_scmi_cpul_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static void clk_scmi_b0pll_disable(void)
+{
+	static bool is_b0pll_disabled;
+
+	if (is_b0pll_disabled != 0)
+		return;
+
+	/* set coreb01 mux gpll */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_NOR_GPLL);
+	 /* pll enter slow mode */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
+	/* set pll power down */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1), CRU_PLL_POWER_DOWN);
+
+	is_b0pll_disabled = true;
+}
+
+static int clk_cpub01_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpub01_table,
+					 sys_clk_info.cpub01_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	/* set b0pll */
+	if (PVTPLL_NEED(type, pvtpll->length)) {
+		/* set clock gating interval */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set core mux pvtpll */
+		mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+			      CPUB01_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+			      CPUB01_CLK_PATH_B0_PVTPLL);
+		mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
+			      CPUB01_CLK_PATH_B1_PVTPLL);
+		goto out;
+	}
+
+	/* set clk coreb01 div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div, 8));
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
+		      CLKDIV_5BITS_SHF(div, 0));
+	/* set coreb01 mux gpll */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_NOR_GPLL);
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_B0PLL);
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
+		      CPUB01_CLK_PATH_B1PLL);
+
+out:
+	clk_scmi_b0pll_disable();
+
+	return 0;
+}
+
+static int clk_scmi_cpub01_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_cpub01_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0)
+		sys_clk_info.cpub01_rate = rate;
+
+	return ret;
+}
+
+static unsigned long rk3588_b0pll_get_rate(void)
+{
+	unsigned int m, p, s, k;
+	uint64_t rate64 = 24000000, postdiv;
+	int mode;
+
+	mode = (mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0)) >> 6) &
+	       0x3;
+
+	if (mode == 0)
+		return rate64;
+
+	m = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(0)) >>
+		 CRU_PLLCON0_M_SHIFT) &
+		CRU_PLLCON0_M_MASK;
+	p = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1)) >>
+		    CRU_PLLCON1_P_SHIFT) &
+		   CRU_PLLCON1_P_MASK;
+	s = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1)) >>
+		  CRU_PLLCON1_S_SHIFT) &
+		 CRU_PLLCON1_S_MASK;
+	k = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(2)) >>
+		    CRU_PLLCON2_K_SHIFT) &
+		   CRU_PLLCON2_K_MASK;
+
+	rate64 *= m;
+	rate64 = rate64 / p;
+
+	if (k != 0) {
+		/* fractional mode */
+		uint64_t frac_rate64 = 24000000 * k;
+
+		postdiv = p * 65535;
+		frac_rate64 = frac_rate64 / postdiv;
+		rate64 += frac_rate64;
+	}
+	rate64 = rate64 >> s;
+
+	return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpub01_get_rate(rk_scmi_clock_t *clock)
+{
+	int value, src, div;
+
+	value = mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0));
+	src = (value & 0x6000) >> 13;
+	if (src == 2) {
+		return sys_clk_info.cpub01_rate;
+	} else {
+		src = (value & 0x00c0) >> 6;
+		div = (value & 0x1f00) >> 8;
+		switch (src) {
+		case 0:
+			return 24000000;
+		case 1:
+			/* Make the return rate is equal to the set rate */
+			if (sys_clk_info.cpub01_rate)
+				return sys_clk_info.cpub01_rate;
+			else
+				return GPLL_RATE / (div + 1);
+		case 2:
+			return rk3588_b0pll_get_rate();
+		default:
+			return 0;
+		}
+	}
+}
+
+static int clk_scmi_cpub01_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static void clk_scmi_b1pll_disable(void)
+{
+	static bool is_b1pll_disabled;
+
+	if (is_b1pll_disabled != 0)
+		return;
+
+	/* set coreb23 mux gpll */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_NOR_GPLL);
+	 /* pll enter slow mode */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
+	/* set pll power down */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9), CRU_PLL_POWER_DOWN);
+
+	is_b1pll_disabled = true;
+}
+
+static int clk_cpub23_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpub23_table,
+					 sys_clk_info.cpub23_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	/* set b1pll */
+	if (PVTPLL_NEED(type, pvtpll->length)) {
+		/* set clock gating interval */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set core mux pvtpll */
+		mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+			      CPUB01_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+			      CPUB01_CLK_PATH_B0_PVTPLL);
+		mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
+			      CPUB01_CLK_PATH_B1_PVTPLL);
+		goto out;
+	}
+
+	/* set clk coreb23 div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div, 8));
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
+		      CLKDIV_5BITS_SHF(div, 0));
+	/* set coreb23 mux gpll */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_NOR_GPLL);
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_B0PLL);
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
+		      CPUB01_CLK_PATH_B1PLL);
+
+out:
+	clk_scmi_b1pll_disable();
+
+	return 0;
+}
+
+static int clk_scmi_cpub23_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_cpub23_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0)
+		sys_clk_info.cpub23_rate = rate;
+
+	return ret;
+}
+
+static unsigned long rk3588_b1pll_get_rate(void)
+{
+	unsigned int m, p, s, k;
+	uint64_t rate64 = 24000000, postdiv;
+	int mode;
+
+	mode = (mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0)) >> 6) &
+	       0x3;
+
+	if (mode == 0)
+		return rate64;
+
+	m = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(8)) >>
+		 CRU_PLLCON0_M_SHIFT) &
+		CRU_PLLCON0_M_MASK;
+	p = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9)) >>
+		    CRU_PLLCON1_P_SHIFT) &
+		   CRU_PLLCON1_P_MASK;
+	s = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9)) >>
+		  CRU_PLLCON1_S_SHIFT) &
+		 CRU_PLLCON1_S_MASK;
+	k = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(10)) >>
+		    CRU_PLLCON2_K_SHIFT) &
+		   CRU_PLLCON2_K_MASK;
+
+	rate64 *= m;
+	rate64 = rate64 / p;
+
+	if (k != 0) {
+		/* fractional mode */
+		uint64_t frac_rate64 = 24000000 * k;
+
+		postdiv = p * 65535;
+		frac_rate64 = frac_rate64 / postdiv;
+		rate64 += frac_rate64;
+	}
+	rate64 = rate64 >> s;
+
+	return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpub23_get_rate(rk_scmi_clock_t *clock)
+{
+	int value, src, div;
+
+	value = mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0));
+	src = (value & 0x6000) >> 13;
+	if (src == 2) {
+		return sys_clk_info.cpub23_rate;
+	} else {
+		src = (value & 0x00c0) >> 6;
+		div = (value & 0x1f00) >> 8;
+		switch (src) {
+		case 0:
+			return 24000000;
+		case 1:
+			/* Make the return rate is equal to the set rate */
+			if (sys_clk_info.cpub23_rate)
+				return sys_clk_info.cpub23_rate;
+			else
+				return GPLL_RATE / (div + 1);
+		case 2:
+			return rk3588_b1pll_get_rate();
+		default:
+			return 0;
+		}
+	}
+}
+
+static int clk_scmi_cpub23_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_dsu_get_rate(rk_scmi_clock_t *clock)
+{
+	int src, div;
+
+	src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(1)) & 0x1;
+	if (src != 0) {
+		return sys_clk_info.dsu_rate;
+	} else {
+		src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(0)) & 0x3000;
+		src = src >> 12;
+		div = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(0)) & 0xf80;
+		div = div >> 7;
+		switch (src) {
+		case 0:
+			return rk3588_b0pll_get_rate() / (div + 1);
+		case 1:
+			return rk3588_b1pll_get_rate() / (div + 1);
+		case 2:
+			return rk3588_lpll_get_rate() / (div + 1);
+		case 3:
+			return GPLL_RATE / (div + 1);
+		default:
+			return 0;
+		}
+	}
+}
+
+static void clk_scmi_lpll_disable(void)
+{
+	static bool is_lpll_disabled;
+
+	if (is_lpll_disabled)
+		return;
+
+	/* set corel mux gpll */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5),
+		      CPUL_CLK_PATH_NOR_GPLL);
+	/* set dsu mux gpll */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
+		      SCLK_DSU_PATH_NOR_GPLL);
+	/* pll enter slow mode */
+	mmio_write_32(DSUCRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
+	/* set pll power down */
+	mmio_write_32(DSUCRU_BASE + CRU_PLL_CON(17), CRU_PLL_POWER_DOWN);
+
+	is_lpll_disabled = true;
+}
+
+static int clk_dsu_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpul_table,
+					 sys_clk_info.cpul_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	/* set pvtpll */
+	if (PVTPLL_NEED(type, pvtpll->length)) {
+		/* set clock gating interval */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set dsu mux pvtpll */
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+			      DSU_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(1),
+			      SCLK_DSU_PATH_PVTPLL);
+		goto out;
+	}
+	/* set dsu div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div, 7));
+	/* set dsu mux gpll */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
+		      SCLK_DSU_PATH_NOR_GPLL);
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(1),
+		      SCLK_DSU_PATH_NOR_PLL);
+
+out:
+	clk_scmi_lpll_disable();
+
+	return 0;
+}
+
+static int clk_scmi_dsu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_dsu_set_rate(rate, PLL_SEL_AUTO);
+
+	if (ret == 0)
+		sys_clk_info.dsu_rate = rate;
+	return ret;
+}
+
+static int clk_scmi_dsu_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_gpu_get_rate(rk_scmi_clock_t *clock)
+{
+	int div, src;
+
+	if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x4000) != 0) {
+		return sys_clk_info.gpu_rate;
+	} else {
+		div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x1f;
+		src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x00e0;
+		src = src >> 5;
+		switch (src) {
+		case 0:
+			/* Make the return rate is equal to the set rate */
+			if (sys_clk_info.gpu_rate)
+				return sys_clk_info.gpu_rate;
+			else
+				return GPLL_RATE / (div + 1);
+		case 1:
+			return CPLL_RATE / (div + 1);
+		case 2:
+			return AUPLL_RATE / (div + 1);
+		case 3:
+			return NPLL_RATE / (div + 1);
+		case 4:
+			return SPLL_RATE / (div + 1);
+		default:
+			return 0;
+		}
+	}
+}
+
+static int clk_gpu_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.gpu_table,
+					 sys_clk_info.gpu_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	if (PVTPLL_NEED(type, pvtpll->length)) {
+		/* set clock gating interval */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set gpu mux pvtpll */
+		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+			      GPU_CLK_PATH_PVTPLL);
+		return 0;
+	}
+
+	/* set gpu div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+		      CLKDIV_5BITS_SHF(div - 1, 0));
+	/* set gpu mux gpll */
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+		      GPU_CLK_PATH_NOR_GPLL);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+		      GPU_CLK_PATH_NOR_PLL);
+
+	return 0;
+}
+
+static int clk_scmi_gpu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_gpu_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0)
+		sys_clk_info.gpu_rate = rate;
+
+	return ret;
+}
+
+static int clk_scmi_gpu_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_npu_get_rate(rk_scmi_clock_t *clock)
+{
+	int div, src;
+
+	if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(74)) & 0x1) != 0) {
+		return sys_clk_info.npu_rate;
+	} else {
+		div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(73)) & 0x007c;
+		div = div >> 2;
+		src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(73)) & 0x0380;
+		src = src >> 7;
+		switch (src) {
+		case 0:
+			/* Make the return rate is equal to the set rate */
+			if (sys_clk_info.npu_rate != 0)
+				return sys_clk_info.npu_rate;
+			else
+				return GPLL_RATE / (div + 1);
+		case 1:
+			return CPLL_RATE / (div + 1);
+		case 2:
+			return AUPLL_RATE / (div + 1);
+		case 3:
+			return NPLL_RATE / (div + 1);
+		case 4:
+			return SPLL_RATE / (div + 1);
+		default:
+			return 0;
+		}
+	}
+}
+
+static int clk_npu_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.npu_table,
+					 sys_clk_info.npu_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	if (PVTPLL_NEED(type, pvtpll->length)) {
+		/* set clock gating interval */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set npu mux pvtpll */
+		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(74),
+			      NPU_CLK_PATH_PVTPLL);
+		return 0;
+	}
+
+	/* set npu div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(73),
+		      CLKDIV_5BITS_SHF(div - 1, 2));
+	/* set npu mux gpll */
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(73),
+		      NPU_CLK_PATH_NOR_GPLL);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(74),
+		      NPU_CLK_PATH_NOR_PLL);
+
+	return 0;
+}
+
+static int clk_scmi_npu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_npu_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0)
+		sys_clk_info.npu_rate = rate;
+
+	return ret;
+}
+
+static int clk_scmi_npu_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_sbus_get_rate(rk_scmi_clock_t *clock)
+{
+	int div;
+
+	if ((mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0)) & 0x0800) != 0) {
+		div = mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0));
+		div = (div & 0x03e0) >> 5;
+		return SPLL_RATE / (div + 1);
+	} else {
+		return OSC_HZ;
+	}
+}
+
+static int clk_scmi_sbus_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int div;
+
+	if (rate == OSC_HZ) {
+		mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+			      WMSK_BIT(11));
+		return 0;
+	}
+
+	div = DIV_ROUND_UP(SPLL_RATE, rate);
+	mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div - 1, 5));
+	mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+		      BIT_WITH_WMSK(11) | WMSK_BIT(10));
+	return 0;
+}
+
+static int clk_scmi_sbus_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_pclk_sbus_get_rate(rk_scmi_clock_t *clock)
+{
+	int div;
+
+	div = mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0));
+	div = div & 0x001f;
+	return SPLL_RATE / (div + 1);
+
+}
+
+static int clk_scmi_pclk_sbus_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int div;
+
+	div = DIV_ROUND_UP(SPLL_RATE, rate);
+	mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div - 1, 0));
+	return 0;
+}
+
+static int clk_scmi_pclk_sbus_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_cclk_sdmmc_get_rate(rk_scmi_clock_t *clock)
+{
+	int div;
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x3000;
+	src = src >> 12;
+	div = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x0fc0;
+	div = div >> 6;
+	if (src == 1) {
+		return SPLL_RATE / (div + 1);
+	} else if (src == 2) {
+		return OSC_HZ / (div + 1);
+	} else {
+		return GPLL_RATE / (div + 1);
+	}
+}
+
+static int clk_scmi_cclk_sdmmc_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int div;
+
+	if ((OSC_HZ % rate) == 0) {
+		div = DIV_ROUND_UP(OSC_HZ, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_6BITS_SHF(div - 1, 6) |
+			      BITS_WITH_WMASK(2U, 0x3U, 12));
+	} else if ((SPLL_RATE % rate) == 0) {
+		div = DIV_ROUND_UP(SPLL_RATE, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_6BITS_SHF(div - 1, 6) |
+			      BITS_WITH_WMASK(1U, 0x3U, 12));
+	} else {
+		div = DIV_ROUND_UP(GPLL_RATE, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_6BITS_SHF(div - 1, 6) |
+			      BITS_WITH_WMASK(0U, 0x3U, 12));
+	}
+
+	return 0;
+}
+
+static int clk_scmi_cclk_sdmmc_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+		      BITS_WITH_WMASK(!status, 0x1U, 4));
+	return 0;
+}
+
+static unsigned long clk_scmi_dclk_sdmmc_get_rate(rk_scmi_clock_t *clock)
+{
+	int div;
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x0020;
+	div = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x001f;
+	if (src != 0) {
+		return SPLL_RATE / (div + 1);
+	} else {
+		return GPLL_RATE / (div + 1);
+	}
+}
+
+static int clk_scmi_dclk_sdmmc_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int div;
+
+	if ((SPLL_RATE % rate) == 0) {
+		div = DIV_ROUND_UP(SPLL_RATE, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_5BITS_SHF(div - 1, 0) |
+			      BITS_WITH_WMASK(1U, 0x1U, 5));
+	} else {
+		div = DIV_ROUND_UP(GPLL_RATE, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_5BITS_SHF(div - 1, 0) |
+			      BITS_WITH_WMASK(0U, 0x1U, 5));
+	}
+	return 0;
+}
+
+static int clk_scmi_dclk_sdmmc_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+		      BITS_WITH_WMASK(!status, 0x1U, 1));
+	return 0;
+}
+
+static unsigned long clk_scmi_aclk_secure_ns_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0003;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 200 * MHz;
+	case 2:
+		return 100 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_aclk_secure_ns_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 200 * MHz)
+		src = 1;
+	else if (rate >= 100 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 0));
+
+	return 0;
+}
+
+static int clk_scmi_aclk_secure_ns_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_hclk_secure_ns_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x000c;
+	src = src >> 2;
+	switch (src) {
+	case 0:
+		return 150 * MHz;
+	case 1:
+		return 100 * MHz;
+	case 2:
+		return 50 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_hclk_secure_ns_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 150 * MHz)
+		src = 0;
+	else if (rate >= 100 * MHz)
+		src = 1;
+	else if (rate >= 50 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 2));
+	return 0;
+}
+
+static int clk_scmi_hclk_secure_ns_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_tclk_wdt_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_tclk_wdt_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+		      BITS_WITH_WMASK(!status, 0x1U, 0));
+	return 0;
+}
+
+static unsigned long clk_scmi_keyladder_core_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x00c0;
+	src = src >> 6;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_keyladder_core_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 6));
+	return 0;
+}
+
+static int clk_scmi_keyladder_core_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 9));
+	return 0;
+}
+
+static unsigned long clk_scmi_keyladder_rng_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x0300;
+	src = src >> 8;
+	switch (src) {
+	case 0:
+		return 175 * MHz;
+	case 1:
+		return 116 * MHz;
+	case 2:
+		return 58 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_keyladder_rng_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 175 * MHz)
+		src = 0;
+	else if (rate >= 116 * MHz)
+		src = 1;
+	else if (rate >= 58 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 8));
+	return 0;
+}
+
+static int clk_scmi_keyladder_rng_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 10));
+	return 0;
+}
+
+static unsigned long clk_scmi_aclk_secure_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0030;
+	src = src >> 4;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_aclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 4));
+	return 0;
+}
+
+static int clk_scmi_aclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_hclk_secure_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x00c0;
+	src = src >> 6;
+	switch (src) {
+	case 0:
+		return 175 * MHz;
+	case 1:
+		return 116 * MHz;
+	case 2:
+		return 58 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_hclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 175 * MHz)
+		src = 0;
+	else if (rate >= 116 * MHz)
+		src = 1;
+	else if (rate >= 58 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 6));
+	return 0;
+}
+
+static int clk_scmi_hclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_pclk_secure_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0300;
+	src = src >> 8;
+	switch (src) {
+	case 0:
+		return 116 * MHz;
+	case 1:
+		return 58 * MHz;
+	case 2:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_pclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 116 * MHz)
+		src = 0;
+	else if (rate >= 58 * MHz)
+		src = 1;
+	else
+		src = 2;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 8));
+	return 0;
+}
+
+static int clk_scmi_pclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_rng_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0xc000;
+	src = src >> 14;
+	switch (src) {
+	case 0:
+		return 175 * MHz;
+	case 1:
+		return 116 * MHz;
+	case 2:
+		return 58 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_rng_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 175 * MHz)
+		src = 0;
+	else if (rate >= 116 * MHz)
+		src = 1;
+	else if (rate >= 58 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 14));
+	return 0;
+}
+
+static int clk_scmi_crypto_rng_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 1));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_core_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0c00;
+	src = src >> 10;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_core_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 10));
+	return 0;
+}
+
+static int clk_scmi_crypto_core_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(0),
+		      BITS_WITH_WMASK(!status, 0x1U, 15));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_pka_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x3000;
+	src = src >> 12;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_pka_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 12));
+	return 0;
+}
+
+static int clk_scmi_crypto_pka_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 0));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_spll_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(BUSSCRU_BASE + CRU_MODE_CON0) & 0x3;
+	switch (src) {
+	case 0:
+		return OSC_HZ;
+	case 1:
+		return 702 * MHz;
+	case 2:
+		return 32768;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_spll_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 700 * MHz)
+		src = 1;
+	else
+		src = 0;
+
+	mmio_write_32(BUSSCRU_BASE + CRU_MODE_CON0,
+		      BITS_WITH_WMASK(0, 0x3U, 0));
+	mmio_write_32(BUSSCRU_BASE + CRU_PLL_CON(137),
+		      BITS_WITH_WMASK(2, 0x7U, 6));
+
+	mmio_write_32(BUSSCRU_BASE + CRU_MODE_CON0,
+		      BITS_WITH_WMASK(src, 0x3U, 0));
+	return 0;
+}
+
+static int clk_scmi_spll_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_hclk_sd_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_ns_get_rate(clock);
+}
+
+static int clk_scmi_hclk_sd_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+		      BITS_WITH_WMASK(!status, 0x1U, 2));
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_rng_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x0030;
+	src = src >> 4;
+	switch (src) {
+	case 0:
+		return 175 * MHz;
+	case 1:
+		return 116 * MHz;
+	case 2:
+		return 58 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_rng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 175 * MHz)
+		src = 0;
+	else if (rate >= 116 * MHz)
+		src = 1;
+	else if (rate >= 58 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 4));
+	return 0;
+}
+
+static int clk_scmi_crypto_rng_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 6));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_core_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x3;
+	src = src >> 0;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_core_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 0));
+	return 0;
+}
+
+static int clk_scmi_crypto_core_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 4));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_pka_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x000c;
+	src = src >> 2;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_pka_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 2));
+	return 0;
+}
+
+static int clk_scmi_crypto_pka_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 5));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_a_crypto_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_aclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_a_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_aclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_a_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 7));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_h_crypto_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_h_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_h_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 8));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_p_crypto_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_pclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_p_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_pclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_p_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+		      BITS_WITH_WMASK(!status, 0x1U, 13));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_a_keylad_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_aclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_a_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_aclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_a_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 11));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_h_keylad_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_h_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_h_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 12));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_p_keylad_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_pclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_p_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_pclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_p_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+		      BITS_WITH_WMASK(!status, 0x1U, 14));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_trng_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_trng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_trng_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+		      BITS_WITH_WMASK(!status, 0x1U, 6));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_h_trng_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_h_trng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_h_trng_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+		      BITS_WITH_WMASK(!status, 0x1U, 15));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_p_otpc_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_pclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_p_otpc_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_pclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_p_otpc_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 13));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_otpc_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_otpc_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 14));
+	return 0;
+}
+
+static unsigned long clk_scmi_otp_phy_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_otp_phy_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
+		      BITS_WITH_WMASK(!status, 0x1U, 13));
+	return 0;
+}
+
+static unsigned long clk_scmi_otpc_rd_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_otpc_rd_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
+		      BITS_WITH_WMASK(!status, 0x1U, 12));
+	return 0;
+}
+
+static unsigned long clk_scmi_otpc_arb_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_otpc_arb_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
+		      BITS_WITH_WMASK(!status, 0x1U, 11));
+	return 0;
+}
+
+static const struct rk_clk_ops clk_scmi_cpul_ops = {
+	.get_rate = clk_scmi_cpul_get_rate,
+	.set_rate = clk_scmi_cpul_set_rate,
+	.set_status = clk_scmi_cpul_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_dsu_ops = {
+	.get_rate = clk_scmi_dsu_get_rate,
+	.set_rate = clk_scmi_dsu_set_rate,
+	.set_status = clk_scmi_dsu_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cpub01_ops = {
+	.get_rate = clk_scmi_cpub01_get_rate,
+	.set_rate = clk_scmi_cpub01_set_rate,
+	.set_status = clk_scmi_cpub01_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cpub23_ops = {
+	.get_rate = clk_scmi_cpub23_get_rate,
+	.set_rate = clk_scmi_cpub23_set_rate,
+	.set_status = clk_scmi_cpub23_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_gpu_ops = {
+	.get_rate = clk_scmi_gpu_get_rate,
+	.set_rate = clk_scmi_gpu_set_rate,
+	.set_status = clk_scmi_gpu_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_npu_ops = {
+	.get_rate = clk_scmi_npu_get_rate,
+	.set_rate = clk_scmi_npu_set_rate,
+	.set_status = clk_scmi_npu_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_sbus_ops = {
+	.get_rate = clk_scmi_sbus_get_rate,
+	.set_rate = clk_scmi_sbus_set_rate,
+	.set_status = clk_scmi_sbus_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_pclk_sbus_ops = {
+	.get_rate = clk_scmi_pclk_sbus_get_rate,
+	.set_rate = clk_scmi_pclk_sbus_set_rate,
+	.set_status = clk_scmi_pclk_sbus_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cclk_sdmmc_ops = {
+	.get_rate = clk_scmi_cclk_sdmmc_get_rate,
+	.set_rate = clk_scmi_cclk_sdmmc_set_rate,
+	.set_status = clk_scmi_cclk_sdmmc_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_dclk_sdmmc_ops = {
+	.get_rate = clk_scmi_dclk_sdmmc_get_rate,
+	.set_rate = clk_scmi_dclk_sdmmc_set_rate,
+	.set_status = clk_scmi_dclk_sdmmc_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_aclk_secure_ns_ops = {
+	.get_rate = clk_scmi_aclk_secure_ns_get_rate,
+	.set_rate = clk_scmi_aclk_secure_ns_set_rate,
+	.set_status = clk_scmi_aclk_secure_ns_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_hclk_secure_ns_ops = {
+	.get_rate = clk_scmi_hclk_secure_ns_get_rate,
+	.set_rate = clk_scmi_hclk_secure_ns_set_rate,
+	.set_status = clk_scmi_hclk_secure_ns_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_tclk_wdt_ops = {
+	.get_rate = clk_scmi_tclk_wdt_get_rate,
+	.set_status = clk_scmi_tclk_wdt_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_keyladder_core_ops = {
+	.get_rate = clk_scmi_keyladder_core_get_rate,
+	.set_rate = clk_scmi_keyladder_core_set_rate,
+	.set_status = clk_scmi_keyladder_core_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_keyladder_rng_ops = {
+	.get_rate = clk_scmi_keyladder_rng_get_rate,
+	.set_rate = clk_scmi_keyladder_rng_set_rate,
+	.set_status = clk_scmi_keyladder_rng_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_aclk_secure_s_ops = {
+	.get_rate = clk_scmi_aclk_secure_s_get_rate,
+	.set_rate = clk_scmi_aclk_secure_s_set_rate,
+	.set_status = clk_scmi_aclk_secure_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_hclk_secure_s_ops = {
+	.get_rate = clk_scmi_hclk_secure_s_get_rate,
+	.set_rate = clk_scmi_hclk_secure_s_set_rate,
+	.set_status = clk_scmi_hclk_secure_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_pclk_secure_s_ops = {
+	.get_rate = clk_scmi_pclk_secure_s_get_rate,
+	.set_rate = clk_scmi_pclk_secure_s_set_rate,
+	.set_status = clk_scmi_pclk_secure_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_rng_ops = {
+	.get_rate = clk_scmi_crypto_rng_get_rate,
+	.set_rate = clk_scmi_crypto_rng_set_rate,
+	.set_status = clk_scmi_crypto_rng_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_core_ops = {
+	.get_rate = clk_scmi_crypto_core_get_rate,
+	.set_rate = clk_scmi_crypto_core_set_rate,
+	.set_status = clk_scmi_crypto_core_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_pka_ops = {
+	.get_rate = clk_scmi_crypto_pka_get_rate,
+	.set_rate = clk_scmi_crypto_pka_set_rate,
+	.set_status = clk_scmi_crypto_pka_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_spll_ops = {
+	.get_rate = clk_scmi_spll_get_rate,
+	.set_rate = clk_scmi_spll_set_rate,
+	.set_status = clk_scmi_spll_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_hclk_sd_ops = {
+	.get_rate = clk_scmi_hclk_sd_get_rate,
+	.set_status = clk_scmi_hclk_sd_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_rng_s_ops = {
+	.get_rate = clk_scmi_crypto_rng_s_get_rate,
+	.set_rate = clk_scmi_crypto_rng_s_set_rate,
+	.set_status = clk_scmi_crypto_rng_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_core_s_ops = {
+	.get_rate = clk_scmi_crypto_core_s_get_rate,
+	.set_rate = clk_scmi_crypto_core_s_set_rate,
+	.set_status = clk_scmi_crypto_core_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_pka_s_ops = {
+	.get_rate = clk_scmi_crypto_pka_s_get_rate,
+	.set_rate = clk_scmi_crypto_pka_s_set_rate,
+	.set_status = clk_scmi_crypto_pka_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_a_crypto_s_ops = {
+	.get_rate = clk_scmi_a_crypto_s_get_rate,
+	.set_rate = clk_scmi_a_crypto_s_set_rate,
+	.set_status = clk_scmi_a_crypto_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_h_crypto_s_ops = {
+	.get_rate = clk_scmi_h_crypto_s_get_rate,
+	.set_rate = clk_scmi_h_crypto_s_set_rate,
+	.set_status = clk_scmi_h_crypto_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_p_crypto_s_ops = {
+	.get_rate = clk_scmi_p_crypto_s_get_rate,
+	.set_rate = clk_scmi_p_crypto_s_set_rate,
+	.set_status = clk_scmi_p_crypto_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_a_keylad_s_ops = {
+	.get_rate = clk_scmi_a_keylad_s_get_rate,
+	.set_rate = clk_scmi_a_keylad_s_set_rate,
+	.set_status = clk_scmi_a_keylad_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_h_keylad_s_ops = {
+	.get_rate = clk_scmi_h_keylad_s_get_rate,
+	.set_rate = clk_scmi_h_keylad_s_set_rate,
+	.set_status = clk_scmi_h_keylad_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_p_keylad_s_ops = {
+	.get_rate = clk_scmi_p_keylad_s_get_rate,
+	.set_rate = clk_scmi_p_keylad_s_set_rate,
+	.set_status = clk_scmi_p_keylad_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_trng_s_ops = {
+	.get_rate = clk_scmi_trng_s_get_rate,
+	.set_rate = clk_scmi_trng_s_set_rate,
+	.set_status = clk_scmi_trng_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_h_trng_s_ops = {
+	.get_rate = clk_scmi_h_trng_s_get_rate,
+	.set_rate = clk_scmi_h_trng_s_set_rate,
+	.set_status = clk_scmi_h_trng_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_p_otpc_s_ops = {
+	.get_rate = clk_scmi_p_otpc_s_get_rate,
+	.set_rate = clk_scmi_p_otpc_s_set_rate,
+	.set_status = clk_scmi_p_otpc_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otpc_s_ops = {
+	.get_rate = clk_scmi_otpc_s_get_rate,
+	.set_status = clk_scmi_otpc_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otp_phy_ops = {
+	.get_rate = clk_scmi_otp_phy_get_rate,
+	.set_status = clk_scmi_otp_phy_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otpc_rd_ops = {
+	.get_rate = clk_scmi_otpc_rd_get_rate,
+	.set_status = clk_scmi_otpc_rd_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otpc_arb_ops = {
+	.get_rate = clk_scmi_otpc_arb_get_rate,
+	.set_status = clk_scmi_otpc_arb_set_status,
+};
+
+rk_scmi_clock_t clock_table[] = {
+	RK3588_SCMI_CLOCK(SCMI_CLK_CPUL, "scmi_clk_cpul", &clk_scmi_cpul_ops, rk3588_cpul_rates, ARRAY_SIZE(rk3588_cpul_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_DSU, "scmi_clk_dsu", &clk_scmi_dsu_ops, rk3588_cpul_rates, ARRAY_SIZE(rk3588_cpul_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_CPUB01, "scmi_clk_cpub01", &clk_scmi_cpub01_ops, rk3588_cpub_rates, ARRAY_SIZE(rk3588_cpub_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_CPUB23, "scmi_clk_cpub23", &clk_scmi_cpub23_ops, rk3588_cpub_rates, ARRAY_SIZE(rk3588_cpub_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_DDR, "scmi_clk_ddr", NULL, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_GPU, "scmi_clk_gpu", &clk_scmi_gpu_ops, rk3588_gpu_rates, ARRAY_SIZE(rk3588_gpu_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_NPU, "scmi_clk_npu", &clk_scmi_npu_ops, rk3588_gpu_rates, ARRAY_SIZE(rk3588_gpu_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_SBUS, "scmi_clk_sbus", &clk_scmi_sbus_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_PCLK_SBUS, "scmi_pclk_sbus", &clk_scmi_pclk_sbus_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_CCLK_SD, "scmi_cclk_sd", &clk_scmi_cclk_sdmmc_ops, rk3588_sdmmc_rates, ARRAY_SIZE(rk3588_sdmmc_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_DCLK_SD, "scmi_dclk_sd", &clk_scmi_dclk_sdmmc_ops, rk3588_sdmmc_rates, ARRAY_SIZE(rk3588_sdmmc_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_ACLK_SECURE_NS, "scmi_aclk_se_ns", &clk_scmi_aclk_secure_ns_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_HCLK_SECURE_NS, "scmi_hclk_se_ns", &clk_scmi_hclk_secure_ns_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_TCLK_WDT, "scmi_tclk_wdt", &clk_scmi_tclk_wdt_ops, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_KEYLADDER_CORE, "scmi_keylad_c", &clk_scmi_keyladder_core_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_KEYLADDER_RNG, "scmi_keylad_r", &clk_scmi_keyladder_rng_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_ACLK_SECURE_S, "scmi_aclk_se_s", &clk_scmi_aclk_secure_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_HCLK_SECURE_S, "scmi_hclk_se_s", &clk_scmi_hclk_secure_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_PCLK_SECURE_S, "scmi_pclk_se_s", &clk_scmi_pclk_secure_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_RNG, "scmi_crypto_r", &clk_scmi_crypto_rng_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_CORE, "scmi_crypto_c", &clk_scmi_crypto_core_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_PKA, "scmi_crypto_p", &clk_scmi_crypto_pka_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_SPLL, "scmi_spll", &clk_scmi_spll_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_HCLK_SD, "scmi_hclk_sd", &clk_scmi_hclk_sd_ops, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_RNG_S, "scmi_crypto_r_s", &clk_scmi_crypto_rng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_CORE_S, "scmi_crypto_c_s", &clk_scmi_crypto_core_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_PKA_S, "scmi_crypto_p_s", &clk_scmi_crypto_pka_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_A_CRYPTO_S, "scmi_a_crypto_s", &clk_scmi_a_crypto_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_H_CRYPTO_S, "scmi_h_crypto_s", &clk_scmi_h_crypto_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_P_CRYPTO_S, "scmi_p_crypto_s", &clk_scmi_p_crypto_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_A_KEYLADDER_S, "scmi_a_keylad_s", &clk_scmi_a_keylad_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_H_KEYLADDER_S, "scmi_h_keylad_s", &clk_scmi_h_keylad_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_P_KEYLADDER_S, "scmi_p_keylad_s", &clk_scmi_p_keylad_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_TRNG_S, "scmi_trng_s", &clk_scmi_trng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_H_TRNG_S, "scmi_h_trng_s", &clk_scmi_h_trng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_P_OTPC_S, "scmi_p_otpc_s", &clk_scmi_p_otpc_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_OTPC_S, "scmi_otpc_s", &clk_scmi_otpc_s_ops, NULL, 0, true),
+	RK3588_SCMI_CLOCK(SCMI_OTP_PHY, "scmi_otp_phy", &clk_scmi_otp_phy_ops, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_OTPC_AUTO_RD, "scmi_otpc_rd", &clk_scmi_otpc_rd_ops, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_OTPC_ARB, "scmi_otpc_arb", &clk_scmi_otpc_arb_ops, NULL, 0, false),
+};
+
+size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
+{
+	return ARRAY_SIZE(clock_table);
+}
+
+rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
+					 uint32_t clock_id)
+{
+	rk_scmi_clock_t *table = NULL;
+
+	if (clock_id < ARRAY_SIZE(clock_table))
+		table = &clock_table[clock_id];
+
+	if (table && !table->is_security)
+		return table;
+	else
+		return NULL;
+}
+
+void pvtplls_suspend(void)
+{
+	clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+	clk_dsu_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub01_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub23_set_rate(408000000, PLL_SEL_NOR);
+}
+
+void pvtplls_resume(void)
+{
+	clk_cpul_set_rate(sys_clk_info.cpul_rate, PLL_SEL_AUTO);
+	clk_dsu_set_rate(sys_clk_info.dsu_rate, PLL_SEL_AUTO);
+	clk_cpub01_set_rate(sys_clk_info.cpub01_rate, PLL_SEL_AUTO);
+	clk_cpub23_set_rate(sys_clk_info.cpub23_rate, PLL_SEL_AUTO);
+}
+
+void sys_reset_pvtplls_prepare(void)
+{
+	clk_gpu_set_rate(100000000, PLL_SEL_NOR);
+	clk_npu_set_rate(100000000, PLL_SEL_NOR);
+	clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub01_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub23_set_rate(408000000, PLL_SEL_NOR);
+	clk_dsu_set_rate(408000000, PLL_SEL_NOR);
+}
+
+void rockchip_clock_init(void)
+{
+	/* set gpll src div to 0 for cpul */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5), CLKDIV_5BITS_SHF(0U, 9));
+	/* set gpll src div to 0 for cpub01 */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(0U, 1));
+	/* set gpll src div to 0 for cpu23 */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(0U, 1));
+
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+		      CPUB_PCLK_PATH_50M);
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+		      CPUB_PCLK_PATH_50M);
+
+	mmio_write_32(DSUCRU_BASE + DSUCRU_CLKSEL_CON(4),
+		      CLKDIV_5BITS_SHF(5U, 0));
+	mmio_write_32(DSUCRU_BASE + DSUCRU_CLKSEL_CON(4),
+		      BITS_WITH_WMASK(PCLK_DSU_ROOT_SEL_GPLL,
+				      PCLK_DSU_ROOT_SEL_MASK,
+				      PCLK_DSU_ROOT_SEL_SHIFT));
+
+	sys_clk_info.cpul_table = rk3588_cpul_pvtpll_table;
+	sys_clk_info.cpul_rate_count = ARRAY_SIZE(rk3588_cpul_pvtpll_table);
+	sys_clk_info.cpub01_table = rk3588_cpub0_pvtpll_table;
+	sys_clk_info.cpub01_rate_count = ARRAY_SIZE(rk3588_cpub0_pvtpll_table);
+	sys_clk_info.cpub23_table = rk3588_cpub1_pvtpll_table;
+	sys_clk_info.cpub23_rate_count = ARRAY_SIZE(rk3588_cpub1_pvtpll_table);
+	memcpy(sys_clk_info.cpub23_table, sys_clk_info.cpub01_table,
+	       sys_clk_info.cpub01_rate_count * sizeof(*sys_clk_info.cpub01_table));
+	sys_clk_info.gpu_table = rk3588_gpu_pvtpll_table;
+	sys_clk_info.gpu_rate_count = ARRAY_SIZE(rk3588_gpu_pvtpll_table);
+	sys_clk_info.npu_table = rk3588_npu_pvtpll_table;
+	sys_clk_info.npu_rate_count = ARRAY_SIZE(rk3588_npu_pvtpll_table);
+}
diff --git a/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h
new file mode 100644
index 0000000..66fddaa
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CLOCK_H__
+#define __CLOCK_H__
+
+/* scmi-clocks indices */
+
+#define SCMI_CLK_CPUL			0
+#define SCMI_CLK_DSU			1
+#define SCMI_CLK_CPUB01			2
+#define SCMI_CLK_CPUB23			3
+#define SCMI_CLK_DDR			4
+#define SCMI_CLK_GPU			5
+#define SCMI_CLK_NPU			6
+#define SCMI_CLK_SBUS			7
+#define SCMI_PCLK_SBUS			8
+#define SCMI_CCLK_SD			9
+#define SCMI_DCLK_SD			10
+#define SCMI_ACLK_SECURE_NS		11
+#define SCMI_HCLK_SECURE_NS		12
+#define SCMI_TCLK_WDT			13
+#define SCMI_KEYLADDER_CORE		14
+#define SCMI_KEYLADDER_RNG		15
+#define SCMI_ACLK_SECURE_S		16
+#define SCMI_HCLK_SECURE_S		17
+#define SCMI_PCLK_SECURE_S		18
+#define SCMI_CRYPTO_RNG			19
+#define SCMI_CRYPTO_CORE		20
+#define SCMI_CRYPTO_PKA			21
+#define SCMI_SPLL			22
+#define SCMI_HCLK_SD			23
+#define SCMI_CRYPTO_RNG_S		24
+#define SCMI_CRYPTO_CORE_S		25
+#define SCMI_CRYPTO_PKA_S		26
+#define SCMI_A_CRYPTO_S			27
+#define SCMI_H_CRYPTO_S			28
+#define SCMI_P_CRYPTO_S			29
+#define SCMI_A_KEYLADDER_S		30
+#define SCMI_H_KEYLADDER_S		31
+#define SCMI_P_KEYLADDER_S		32
+#define SCMI_TRNG_S			33
+#define SCMI_H_TRNG_S			34
+#define SCMI_P_OTPC_S			35
+#define SCMI_OTPC_S			36
+#define SCMI_OTP_PHY			37
+#define SCMI_OTPC_AUTO_RD		38
+#define SCMI_OTPC_ARB			39
+
+/******** DSUCRU **************************************/
+#define DSUCRU_CLKSEL_CON(n)		(0x0300 + (n) * 4)
+
+/********Name=DSUCRU_CLKSEL_CON04,Offset=0x310********/
+#define PCLK_DSU_ROOT_SEL_SHIFT		5
+#define PCLK_DSU_ROOT_SEL_MASK		0x3
+#define PCLK_DSU_ROOT_SEL_GPLL		0x3
+
+/********Name=SECURE_SOFTRST_CON00,Offset=0xA00********/
+#define SRST_A_SECURE_NS_BIU		10
+#define SRST_H_SECURE_NS_BIU		11
+#define SRST_A_SECURE_S_BIU		12
+#define SRST_H_SECURE_S_BIU		13
+#define SRST_P_SECURE_S_BIU		14
+#define SRST_CRYPTO_CORE		15
+/********Name=SECURE_SOFTRST_CON01,Offset=0xA04********/
+#define SRST_CRYPTO_PKA			16
+#define SRST_CRYPTO_RNG			17
+#define SRST_A_CRYPTO			18
+#define SRST_H_CRYPTO			19
+#define SRST_KEYLADDER_CORE		25
+#define SRST_KEYLADDER_RNG		26
+#define SRST_A_KEYLADDER		27
+#define SRST_H_KEYLADDER		28
+#define SRST_P_OTPC_S			29
+#define SRST_OTPC_S			30
+#define SRST_WDT_S			31
+/********Name=SECURE_SOFTRST_CON02,Offset=0xA08********/
+#define SRST_T_WDT_S			32
+#define SRST_H_BOOTROM			33
+#define SRST_A_DCF			34
+#define SRST_P_DCF			35
+#define SRST_H_BOOTROM_NS		37
+#define SRST_P_KEYLADDER		46
+#define SRST_H_TRNG_S			47
+/********Name=SECURE_SOFTRST_CON03,Offset=0xA0C********/
+#define SRST_H_TRNG_NS			48
+#define SRST_D_SDMMC_BUFFER		49
+#define SRST_H_SDMMC			50
+#define SRST_H_SDMMC_BUFFER		51
+#define SRST_SDMMC			52
+#define SRST_P_TRNG_CHK			53
+#define SRST_TRNG_S			54
+
+#define SRST_INVALID			55
+
+void pvtplls_suspend(void);
+void pvtplls_resume(void);
+
+void rockchip_clock_init(void);
+
+#endif
diff --git a/plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c b/plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c
new file mode 100644
index 0000000..50b99e7
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include "rk3588_clk.h"
+#include <scmi_rstd.h>
+#include <soc.h>
+
+#define DEFAULT_RESET_DOM_ATTRIBUTE	0
+
+#define RK3588_SCMI_RESET(_id, _name, _attribute, _ops)		\
+{								\
+	.id = _id,						\
+	.name = _name,						\
+	.attribute = _attribute,				\
+	.rstd_ops = _ops,					\
+}
+
+static int rk3588_reset_explicit(rk_scmi_rstd_t *reset_domain,
+				 bool assert_not_deassert)
+{
+	int bank = reset_domain->id / 16;
+	int offset = reset_domain->id % 16;
+
+	mmio_write_32(SCRU_BASE + CRU_SOFTRST_CON(bank),
+		      BITS_WITH_WMASK(assert_not_deassert, 0x1U, offset));
+	return SCMI_SUCCESS;
+}
+
+static struct rk_scmi_rstd_ops rk3588_reset_domain_ops = {
+	.reset_explicit = rk3588_reset_explicit,
+};
+
+static rk_scmi_rstd_t rk3588_reset_domain_table[] = {
+	RK3588_SCMI_RESET(SRST_CRYPTO_CORE, "scmi_sr_cy_core", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_CRYPTO_PKA, "scmi_sr_cy_pka", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_CRYPTO_RNG, "scmi_sr_cy_rng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_A_CRYPTO, "scmi_sr_a_cy", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_CRYPTO, "scmi_sr_h_cy", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_KEYLADDER_CORE, "scmi_sr_k_core", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_KEYLADDER_RNG, "scmi_sr_k_rng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_P_OTPC_S, "scmi_sr_p_otp", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_OTPC_S, "scmi_sr_otp", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_WDT_S, "scmi_sr_wdt", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_T_WDT_S, "scmi_sr_t_wdt", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_BOOTROM, "scmi_sr_h_boot", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_P_KEYLADDER, "scmi_sr_p_ky", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_TRNG_S, "scmi_sr_h_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_TRNG_NS, "scmi_sr_t_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_D_SDMMC_BUFFER, "scmi_sr_d_sd", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_SDMMC, "scmi_sr_h_sd", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_SDMMC_BUFFER, "scmi_sr_h_sd_b", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_SDMMC, "scmi_sr_sd", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_P_TRNG_CHK, "scmi_sr_p_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_TRNG_S, "scmi_sr_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_INVALID, "scmi_sr_invalid", DEFAULT_RESET_DOM_ATTRIBUTE, NULL),
+};
+
+static rk_scmi_rstd_t *
+rockchip_get_reset_domain_table(int id)
+{
+	rk_scmi_rstd_t *reset = rk3588_reset_domain_table;
+	int i = 0, cnt = ARRAY_SIZE(rk3588_reset_domain_table);
+
+	for (i = 0; i < cnt; i++) {
+		if (reset->id == id)
+			return &rk3588_reset_domain_table[i];
+		reset++;
+	}
+
+	return &rk3588_reset_domain_table[cnt - 1];
+}
+
+rk_scmi_rstd_t *rockchip_scmi_get_rstd(unsigned int agent_id,
+				       unsigned int scmi_id)
+
+{
+	return rockchip_get_reset_domain_table(scmi_id);
+}
+
+size_t rockchip_scmi_rstd_count(unsigned int agent_id)
+{
+	return SRST_TRNG_S;
+}
+
diff --git a/plat/rockchip/rk3588/drivers/secure/secure.c b/plat/rockchip/rk3588/drivers/secure/secure.c
new file mode 100644
index 0000000..fc9f211
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/secure/secure.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#include <secure.h>
+#include <soc.h>
+
+static void secure_fw_master_init(void)
+{
+	uint32_t i;
+
+	/* ddr_mcu can access all ddr-regions */
+	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_MST(1), 0x0000ffff);
+	/* dcf/crypto_s can access all ddr-regions */
+	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_MST(14), 0x00000000);
+	/* dsu_mp_sec can access all ddr-regions.
+	 * DSU access memory [f000_0000~ff00_0000] through MP in firewall_ddr.
+	 */
+	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_MST(36), 0xffff0000);
+
+	/* all other ns-master can't access all ddr-regions */
+	for (i = 0; i < FIREWALL_DDR_MST_CNT; i++) {
+		if (i == 1 || i == 14 || i == 36)
+			continue;
+
+		mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_MST(i), 0xffffffff);
+	}
+
+	/* mcu_pmu can access all sram-regions */
+	mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_MST(19), 0x000000ff);
+	/* dsu mp-sec can access all sram-regions */
+	mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_MST(38), 0x000000ff);
+	/* nsp_dsu2main_sec can access all sram-regions */
+	mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_MST(41), 0x00000000);
+
+	/* all ns-master can't access all sram-regions */
+	for (i = 0; i < FIREWALL_SYSMEM_MST_CNT; i++) {
+		if (i == 19 || i == 38 || i == 41)
+			continue;
+
+		mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_MST(i),
+			      0x00ff00ff);
+	}
+
+	/* dsu-ns can't access all ddr-regions, dsu-s can access all ddr-regions */
+	mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_MST(0), 0xffffffff);
+	mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_MST(1), 0x00000000);
+	dsb();
+	isb();
+}
+
+/* unit: Mb */
+static void dsu_fw_rgn_config(uint64_t base_mb, uint64_t top_mb, int rgn_id)
+{
+	int i;
+
+	if (rgn_id >= FIREWALL_DSU_RGN_CNT || rgn_id < 0) {
+		ERROR("%s regions-id:%d is invalid!\n", __func__, rgn_id);
+		panic();
+	}
+
+	mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_RGN(rgn_id),
+		      RG_MAP_SECURE(top_mb, base_mb));
+
+	for (i = 0; i < DDR_CHN_CNT; i++)
+		mmio_setbits_32(FIREWALL_DSU_BASE + FIREWALL_DSU_CON(i),
+				BIT(rgn_id));
+}
+
+/* unit: Mb */
+static void ddr_fw_rgn_config(uint64_t base_mb, uint64_t top_mb, int rgn_id)
+{
+	if (rgn_id >= FIREWALL_DDR_RGN_CNT || rgn_id < 0) {
+		ERROR("%s regions-id:%d is invalid!\n", __func__, rgn_id);
+		panic();
+	}
+
+	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_RGN(rgn_id),
+		      RG_MAP_SECURE(top_mb, base_mb));
+
+	/* enable region */
+	mmio_setbits_32(FIREWALL_DDR_BASE + FIREWALL_DDR_CON,
+			BIT(rgn_id));
+}
+
+/* Unit: Kb */
+static void sram_fw_rgn_config(uint64_t base_kb, uint64_t top_kb, int rgn_id)
+{
+	if (rgn_id >= FIREWALL_SYSMEM_RGN_CNT || rgn_id < 0) {
+		ERROR("%s regions-id:%d is invalid!\n", __func__, rgn_id);
+		panic();
+	}
+
+	mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_RGN(rgn_id),
+		      RG_MAP_SRAM_SECURE(top_kb, base_kb));
+
+	/* enable region */
+	mmio_setbits_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_CON, BIT(rgn_id));
+}
+
+static void secure_region_init(void)
+{
+	uint32_t i;
+
+	/* disable all region first except region0 */
+	mmio_clrbits_32(FIREWALL_DDR_BASE + FIREWALL_DDR_CON, 0xfffe);
+	for (i = 0; i < FIREWALL_DSU_CON_CNT; i++)
+		mmio_clrbits_32(FIREWALL_DSU_BASE + FIREWALL_DSU_CON(i), 0xfffe);
+	mmio_clrbits_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_CON, 0xfe);
+
+	secure_fw_master_init();
+
+	/* Use FW_DDR_RGN0_REG to config 0~1M space to secure */
+	dsu_fw_rgn_config(0, 1, 0);
+	ddr_fw_rgn_config(0, 1, 0);
+
+	/* Use FIREWALL_SYSMEM_RGN0 to config SRAM_ENTRY code(0~4k of sram) to secure */
+	sram_fw_rgn_config(0, 4, 0);
+	/* For 0xffff0000~0xffffffff, use FIREWALL_SYSMEM_RGN7 to config
+	 * 960~1024k of sram to secure.
+	 */
+	sram_fw_rgn_config(960, 1024, 7);
+}
+
+void secure_timer_init(void)
+{
+	/* gpu's cntvalue comes from stimer1 channel_5 */
+	mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG,
+		      TIMER_DIS);
+
+	mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+	/* auto reload & enable the timer */
+	mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG,
+		      TIMER_EN | TIMER_FMODE);
+}
+
+void sgrf_init(void)
+{
+	uint32_t i;
+
+	secure_region_init();
+
+	/* config master ddr_mcu_prot|dcf_wr|dcf_rd as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(14), 0x001f0011);
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(15), 0xffffffff);
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(16), 0x03ff03ff);
+
+	/* config slave mailbox_mcu_ddr as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(4), 0xffff2000);
+	/* config slave int256mux4_mcu_ddr|int256mux4_mcu_pmu as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(5), 0xffff0060);
+	/* config slave ddrgrf*|dma2ddr|ddrphy*_cru|umctl* as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(24), 0xffff0fbf);
+	/* config slave ddrphy*|ddr_stanby*|ddr_mcu_timer|ddr_mcu_wdt as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(25), 0xffff03ff);
+
+	/* config all other slave as ns */
+	for (i = 0; i < SGRF_FIREWALL_CON_CNT; i++) {
+		if (i == 4 || i == 5 || i == 24 || i == 25)
+			continue;
+
+		mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(i), 0xffff0000);
+	}
+
+	/* config vad_hprot non-secure, pmu_mcu_hprot as secure */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(0), 0x00180010);
+	/* config pmu1, pmu0, pmu_sram as secure */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(1), 0xefbe6020);
+	/* config remap_pmu_mem, h_pmu_mem as secure */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(2), 0x01f900c0);
+
+	/* disable dp encryption */
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(13), 0x00180018);
+
+	/* select grf config for pcie ats */
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(17), 0x11111111);
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(18), 0x11111111);
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(19), 0x00110011);
+}
diff --git a/plat/rockchip/rk3588/drivers/secure/secure.h b/plat/rockchip/rk3588/drivers/secure/secure.h
new file mode 100644
index 0000000..d9c234f
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/secure/secure.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURE_H
+#define SECURE_H
+
+/* DSUSGRF */
+#define DSU_SGRF_SOC_CON(i)		((i) * 4)
+#define DSUSGRF_SOC_CON(i)		((i) * 4)
+#define DSUSGRF_SOC_CON_CNT		13
+#define DSUSGRF_DDR_HASH_CON(i)		(0x240 + (i) * 4)
+#define DSUSGRF_DDR_HASH_CON_CNT	8
+
+/* PMUSGRF */
+#define PMU1SGRF_SOC_CON(n)		((n) * 4)
+
+/* SGRF */
+#define SGRF_SOC_CON(i)			((i) * 4)
+#define SGRF_FIREWALL_CON(i)		(0x240 + (i) * 4)
+#define SGRF_FIREWALL_CON_CNT		32
+
+/* ddr firewall */
+#define FIREWALL_DDR_RGN(i)		((i) * 0x4)
+#define FIREWALL_DDR_RGN_CNT		16
+#define FIREWALL_DDR_MST(i)		(0x40 + (i) * 0x4)
+#define FIREWALL_DDR_MST_CNT		42
+#define FIREWALL_DDR_CON		0xf0
+
+#define FIREWALL_SYSMEM_RGN(i)		((i) * 0x4)
+#define FIREWALL_SYSMEM_RGN_CNT		8
+#define FIREWALL_SYSMEM_MST(i)		(0x40 + (i) * 0x4)
+#define FIREWALL_SYSMEM_MST_CNT		43
+#define FIREWALL_SYSMEM_CON		0xf0
+
+#define FIREWALL_DSU_RGN(i)		((i) * 0x4)
+#define FIREWALL_DSU_RGN_CNT		16
+#define FIREWALL_DSU_MST(i)		(0x40 + (i) * 0x4)
+#define FIREWALL_DSU_MST_CNT		2
+#define FIREWALL_DSU_CON(i)		(0xf0 + (i) * 4)
+#define FIREWALL_DSU_CON_CNT		4
+
+#define PLAT_MAX_DDR_CAPACITY_MB	0x8000	/* for 32Gb */
+#define RG_MAP_SECURE(top, base)	\
+	(((((top) - 1) & 0x7fff) << 16) | ((base) & 0x7fff))
+#define RG_MAP_SRAM_SECURE(top_kb, base_kb)	\
+	(((((top_kb) / 4 - 1) & 0xff) << 16) | ((base_kb) / 4 & 0xff))
+
+void secure_timer_init(void);
+void sgrf_init(void);
+
+#endif /* SECURE_H */
diff --git a/plat/rockchip/rk3588/drivers/soc/soc.c b/plat/rockchip/rk3588/drivers/soc/soc.c
new file mode 100644
index 0000000..6db81ee
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/soc/soc.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <plat_private.h>
+#include <rk3588_clk.h>
+#include <secure.h>
+#include <soc.h>
+
+#define RK3588_DEV_RNG0_BASE	0xf0000000
+#define RK3588_DEV_RNG0_SIZE	0x0ffff000
+
+const mmap_region_t plat_rk_mmap[] = {
+	MAP_REGION_FLAT(RK3588_DEV_RNG0_BASE, RK3588_DEV_RNG0_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DDR_SHARE_MEM, DDR_SHARE_SIZE,
+			MT_DEVICE | MT_RW | MT_NS),
+	{ 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,
+	/* No of children for the second cluster node */
+	PLATFORM_CLUSTER1_CORE_COUNT
+};
+
+void timer_hp_init(void)
+{
+	if ((mmio_read_32(TIMER_HP_BASE + TIMER_HP_CTRL) & 0x1) != 0)
+		return;
+
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_CTRL, 0x0);
+	dsb();
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_LOAD_COUNT1, 0xffffffff);
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_INT_EN, 0);
+	dsb();
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_CTRL, 0x1);
+}
+
+static void system_reset_init(void)
+{
+	/* enable wdt_ns0~4 trigger global reset and select first reset.
+	 * enable tsadc trigger global reset and select first reset.
+	 * enable global reset and wdt trigger pmu reset.
+	 * select first reset trigger pmu reset.s
+	 */
+	mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, 0xffdf);
+
+	/* enable wdt_s, wdt_ns reset */
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(2), 0x0c000c00);
+
+	/* reset width = 0xffff */
+	mmio_write_32(PMU1GRF_BASE + PMU1GRF_SOC_CON(1), 0xffffffff);
+
+	/* enable first/tsadc/wdt reset output */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(0), 0x00070007);
+
+	/* pmu1_grf pmu1_ioc hold */
+	mmio_write_32(PMU1GRF_BASE + PMU1GRF_SOC_CON(7), 0x30003000);
+
+	/* pmu1sgrf hold */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(14), 0x00200020);
+
+	/* select tsadc_shut_m0 ionmux*/
+	mmio_write_32(PMU0IOC_BASE + 0x0, 0x00f00020);
+}
+
+void plat_rockchip_soc_init(void)
+{
+	rockchip_clock_init();
+	secure_timer_init();
+	timer_hp_init();
+	system_reset_init();
+	sgrf_init();
+	rockchip_init_scmi_server();
+}
diff --git a/plat/rockchip/rk3588/drivers/soc/soc.h b/plat/rockchip/rk3588/drivers/soc/soc.h
new file mode 100644
index 0000000..9af179a
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/soc/soc.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SOC_H__
+#define __SOC_H__
+
+enum pll_id {
+	APLL_ID,
+	DPLL_ID,
+	GPLL_ID,
+	CPLL_ID,
+	NPLL_ID,
+	VPLL_ID,
+};
+
+enum pmu_pll_id {
+	PPLL_ID = 0,
+	HPLL_ID
+};
+
+enum cru_mode_con00 {
+	CLK_APLL,
+	CLK_DPLL,
+	CLK_CPLL,
+	CLK_GPLL,
+	CLK_REVSERVED,
+	CLK_NPLL,
+	CLK_VPLL,
+	CLK_USBPLL,
+};
+
+#define KHz				1000
+#define MHz				(1000 * KHz)
+#define OSC_HZ				(24 * MHz)
+
+/* CRU */
+#define GLB_SRST_FST_CFG_VAL		0xfdb9
+
+#define CRU_PLLS_CON(pll_id, i)		(0x160 + (pll_id) * 0x20 + (i) * 0x4)
+#define CRU_PLL_CON(i)			((i) * 0x4)
+#define CRU_MODE_CON0			0x280
+#define CRU_CLKSEL_CON(i)		((i) * 0x4 + 0x300)
+#define CRU_CLKGATE_CON(i)		((i) * 0x4 + 0x800)
+#define CRU_CLKGATE_CON_CNT		78
+#define CRU_SOFTRST_CON(i)		((i) * 0x4 + 0xa00)
+#define CRU_GLB_CNT_TH			0xc00
+#define CRU_GLB_SRST_FST		0xc08
+#define CRU_GLB_SRST_SND		0xc0c
+#define CRU_GLB_RST_CON			0xc10
+#define CRU_GLB_RST_ST			0xc04
+#define CRU_SDIO_CON0			0xc24
+#define CRU_SDIO_CON1			0xc28
+#define CRU_SDMMC_CON0			0xc30
+#define CRU_SDMMC_CON1			0xc34
+#define CRU_AUTOCS_CON0(id)		(0xd00 + (id) * 8)
+#define CRU_AUTOCS_CON1(id)		(0xd04 + (id) * 8)
+
+#define CRU_AUTOCS_ID_CNT		74
+
+#define CRU_PLLCON0_M_MASK		0x3ff
+#define CRU_PLLCON0_M_SHIFT		0
+#define CRU_PLLCON1_P_MASK		0x3f
+#define CRU_PLLCON1_P_SHIFT		0
+#define CRU_PLLCON1_S_MASK		0x7
+#define CRU_PLLCON1_S_SHIFT		6
+#define CRU_PLLCON2_K_MASK		0xffff
+#define CRU_PLLCON2_K_SHIFT		0
+#define CRU_PLLCON1_PWRDOWN		BIT(13)
+#define CRU_PLLCON6_LOCK_STATUS		BIT(15)
+
+#define CRU_BIGCPU02_RST_MSK		0x30
+#define CRU_BIGCPU13_RST_MSK		0x300
+
+#define PHPCRU_CLKGATE_CON		0x800
+#define PHPCRU_CLKGATE_CON_CNT		1
+
+#define SECURECRU_CLKGATE_CON(i)	((i) * 0x4 + 0x800)
+#define SECURECRU_CLKGATE_CON_CNT	4
+
+#define PMU1CRU_CLKGATE_CON_CNT		6
+
+/* CENTER GRF */
+#define CENTER_GRF_CON(i)		((i) * 4)
+
+/* PMU1GRF */
+#define PMU1GRF_SOC_CON(n)		((n) * 4)
+#define PMU1GRF_SOC_ST			0x60
+#define PMU1GRF_OS_REG(n)		(0x200 + ((n) * 4))
+
+#define PMU_MCU_HALT			BIT(7)
+#define PMU_MCU_SLEEP			BIT(9)
+#define PMU_MCU_DEEPSLEEP		BIT(10)
+#define PMU_MCU_STOP_MSK		\
+	(PMU_MCU_HALT | PMU_MCU_SLEEP | PMU_MCU_DEEPSLEEP)
+
+/* SYSGRF */
+#define SYS_GRF_NOC_CON(n)		(0x100 + (n) * 4)
+#define SYS_GRF_SOC_CON(n)		(0x300 + (n) * 4)
+#define SYS_GRF_SOC_STATUS(n)		(0x380 + (n) * 4)
+
+#define SYS_GRF_LITTLE_CPUS_WFE		0xf
+#define SYS_GRF_CORE0_CPUS_WFE		0x30
+#define SYS_GRF_CORE1_CPUS_WFE		0xc0
+#define SYS_GRF_BIG_CPUS_WFE		0xf0
+#define SYS_GRF_LITTLE_CPUS_WFI		0xf00
+#define SYS_GRF_CORE0_CPUS_WFI		0x3000
+#define SYS_GRF_CORE1_CPUS_WFI		0xc000
+
+/* pvtm */
+#define PVTM_CON(i)			(0x4 + (i) * 4)
+#define PVTM_INTEN			0x70
+#define PVTM_INTSTS			0x74
+#define PVTM_STATUS(i)			(0x80 + (i) * 4)
+#define PVTM_CALC_CNT			0x200
+
+enum pvtm_con0 {
+	pvtm_start = 0,
+	pvtm_osc_en = 1,
+	pvtm_osc_sel = 2,
+	pvtm_rnd_seed_en = 5,
+};
+
+/* timer */
+#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 TIMER_FMODE			(0x0 << 1)
+#define TIMER_RMODE			(0x1 << 1)
+
+#define STIMER0_CHN_BASE(n)		(STIMER0_BASE + 0x20 * (n))
+#define STIMER1_CHN_BASE(n)		(STIMER1_BASE + 0x20 * (n))
+
+/* cpu timer */
+#define TIMER_HP_REVISION		0x0
+#define TIMER_HP_CTRL			0x4
+#define TIMER_HP_INT_EN			0x8
+#define TIMER_HP_T24_GCD		0xc
+#define TIMER_HP_T32_GCD		0x10
+#define TIMER_HP_LOAD_COUNT0		0x14
+#define TIMER_HP_LOAD_COUNT1		0x18
+#define TIMER_HP_T24_DELAT_COUNT0	0x1c
+#define TIMER_HP_T24_DELAT_COUNT1	0x20
+#define TIMER_HP_CURR_32K_VALUE0	0x24
+#define TIMER_HP_CURR_32K_VALUE1	0x28
+#define TIMER_HP_CURR_TIMER_VALUE0	0x2c
+#define TIMER_HP_CURR_TIMER_VALUE1	0x30
+#define TIMER_HP_T24_32BEGIN0		0x34
+#define TIMER_HP_T24_32BEGIN1		0x38
+#define TIMER_HP_T32_24END0		0x3c
+#define TIMER_HP_T32_24END1		0x40
+#define TIMER_HP_BEGIN_END_VALID	0x44
+#define TIMER_HP_SYNC_REQ		0x48
+#define TIMER_HP_INTR_STATUS		0x4c
+
+ /* GPIO */
+#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 GPIO_INT_EN_L			0x0010
+#define GPIO_INT_EN_H			0x0014
+#define GPIO_INT_MASK_L			0x0018
+#define GPIO_INT_MASK_H			0x001c
+#define GPIO_INT_TYPE_L			0x0020
+#define GPIO_INT_TYPE_H			0x0024
+#define GPIO_INT_POLARITY_L		0x0028
+#define GPIO_INT_POLARITY_H		0x002c
+#define GPIO_INT_BOTHEDGE_L		0x0030
+#define GPIO_INT_BOTHEDGE_H		0x0034
+#define GPIO_DEBOUNCE_L			0x0038
+#define GPIO_DEBOUNCE_H			0x003c
+#define GPIO_DBCLK_DIV_EN_L		0x0040
+#define GPIO_DBCLK_DIV_EN_H		0x0044
+#define GPIO_DBCLK_DIV_CON		0x0048
+#define GPIO_INT_STATUS			0x0050
+#define GPIO_INT_RAWSTATUS		0x0058
+#define GPIO_PORT_EOI_L			0x0060
+#define GPIO_PORT_EOI_H			0x0064
+#define GPIO_EXT_PORT			0x0070
+#define GPIO_VER_ID			0x0078
+
+/* DDRGRF */
+#define DDRGRF_CHA_CON(i)		((i) * 4)
+#define DDRGRF_CHB_CON(i)		(0x30 + (i) * 4)
+
+#define DDR_CHN_CNT			4
+
+#endif /* __SOC_H__ */
diff --git a/plat/rockchip/rk3588/include/plat.ld.S b/plat/rockchip/rk3588/include/plat.ld.S
new file mode 100644
index 0000000..e3ea9cc
--- /dev/null
+++ b/plat/rockchip/rk3588/include/plat.ld.S
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. 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
+	 */
+	.text_pmusram : {
+		ASSERT(. == ALIGN(64 * 1024),
+			".pmusram.entry request 64K aligned.");
+		 KEEP(*(.pmusram.entry))
+		__bl31_pmusram_text_start = .;
+		*(.pmusram.text)
+		*(.pmusram.rodata)
+		. = ALIGN(PAGE_SIZE);
+		__bl31_pmusram_text_end = .;
+		__bl31_pmusram_data_start = .;
+		*(.pmusram.data)
+		. = ALIGN(PAGE_SIZE);
+		__bl31_pmusram_data_end = .;
+
+		ASSERT(__bl31_pmusram_data_end <= PMUSRAM_BASE + PMUSRAM_RSIZE,
+			".pmusram has exceeded its limit.");
+	} >PMUSRAM
+}
+
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3588/include/plat_sip_calls.h b/plat/rockchip/rk3588/include/plat_sip_calls.h
new file mode 100644
index 0000000..bc4455f
--- /dev/null
+++ b/plat/rockchip/rk3588/include/plat_sip_calls.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. 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/rk3588/include/platform_def.h b/plat/rockchip/rk3588/include/platform_def.h
new file mode 100644
index 0000000..5946af0
--- /dev/null
+++ b/plat/rockchip/rk3588/include/platform_def.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <plat/common/common_def.h>
+
+#include <rk3588_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	8
+#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 PLAT_RK_UART_BASE	RK_DBG_UART_BASE
+#define PLAT_RK_UART_CLOCK	RK_DBG_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE	RK_DBG_UART_BAUDRATE
+
+#define PLAT_RK_PRIMARY_CPU	0x0
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/rockchip/rk3588/plat_sip_calls.c b/plat/rockchip/rk3588/plat_sip_calls.c
new file mode 100644
index 0000000..496e8d7
--- /dev/null
+++ b/plat/rockchip/rk3588/plat_sip_calls.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/scmi-msg.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)
+{
+	switch (smc_fid) {
+	case RK_SIP_SCMI_AGENT0:
+		scmi_smt_fastcall_smc_entry(0);
+		SMC_RET1(handle, 0);
+
+	default:
+		ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
diff --git a/plat/rockchip/rk3588/platform.mk b/plat/rockchip/rk3588/platform.mk
new file mode 100644
index 0000000..2fadb5a
--- /dev/null
+++ b/plat/rockchip/rk3588/platform.mk
@@ -0,0 +1,98 @@
+#
+# Copyright (c) 2024, Rockchip, Inc. 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
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+# GIC-600 configuration
+GICV3_IMPL		:=	GIC600
+GICV3_SUPPORT_GIC600   	:=      1
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+PLAT_INCLUDES		:=	-Iinclude/plat/common				\
+				-Idrivers/arm/gic/v3/				\
+				-Idrivers/scmi-msg/				\
+				-I${RK_PLAT_COMMON}/				\
+				-I${RK_PLAT_COMMON}/drivers/pmu/		\
+				-I${RK_PLAT_COMMON}/drivers/parameter/		\
+				-I${RK_PLAT_COMMON}/include/			\
+				-I${RK_PLAT_COMMON}/pmusram/			\
+				-I${RK_PLAT_COMMON}/scmi/			\
+				-I${RK_PLAT_SOC}/				\
+				-I${RK_PLAT_SOC}/drivers/pmu/			\
+				-I${RK_PLAT_SOC}/drivers/scmi/			\
+				-I${RK_PLAT_SOC}/drivers/secure/		\
+				-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/ti/uart/aarch64/16550_console.S		\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				drivers/scmi-msg/base.c				\
+				drivers/scmi-msg/clock.c			\
+				drivers/scmi-msg/entry.c			\
+				drivers/scmi-msg/reset_domain.c			\
+				drivers/scmi-msg/smt.c				\
+				lib/cpus/aarch64/cortex_a55.S			\
+				lib/cpus/aarch64/cortex_a76.S			\
+				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
+				${RK_PLAT_COMMON}/aarch64/platform_common.c	\
+				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
+				${RK_PLAT_COMMON}/plat_pm.c			\
+				${RK_PLAT_COMMON}/plat_pm_helpers.c		\
+				${RK_PLAT_COMMON}/plat_topology.c		\
+				${RK_PLAT_COMMON}/params_setup.c                \
+				${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S	\
+				${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
+				${RK_PLAT_COMMON}/scmi/scmi.c			\
+				${RK_PLAT_COMMON}/scmi/scmi_clock.c		\
+				${RK_PLAT_COMMON}/scmi/scmi_rstd.c		\
+				${RK_PLAT_SOC}/plat_sip_calls.c         	\
+				${RK_PLAT_SOC}/drivers/secure/secure.c		\
+				${RK_PLAT_SOC}/drivers/soc/soc.c		\
+				${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
+				${RK_PLAT_SOC}/drivers/pmu/pm_pd_regs.c		\
+				${RK_PLAT_SOC}/drivers/scmi/rk3588_clk.c	\
+				${RK_PLAT_SOC}/drivers/scmi/rk3588_rstd.c
+
+CTX_INCLUDE_AARCH32_REGS :=     0
+ENABLE_PLAT_COMPAT	:=	0
+MULTI_CONSOLE_API	:=	1
+ERRATA_A55_1530923	:=	1
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY	:=	1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM	:=	0
+
+ENABLE_SPE_FOR_LOWER_ELS	:= 0
+
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+$(eval $(call add_define,PLAT_RK_CPU_RESET_EARLY))
diff --git a/plat/rockchip/rk3588/rk3588_def.h b/plat/rockchip/rk3588/rk3588_def.h
new file mode 100644
index 0000000..412495a
--- /dev/null
+++ b/plat/rockchip/rk3588/rk3588_def.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_DEF_H__
+#define __PLAT_DEF_H__
+
+#define SIZE_K(n)		((n) * 1024)
+
+#define WITH_16BITS_WMSK(bits)	(0xffff0000 | (bits))
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define RK_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
+
+#define UMCTL0_BASE		0xf7000000
+#define UMCTL1_BASE		0xf8000000
+#define UMCTL2_BASE		0xf9000000
+#define UMCTL3_BASE		0xfa000000
+
+#define GIC600_BASE		0xfe600000
+#define GIC600_SIZE		SIZE_K(64)
+
+#define DAPLITE_BASE		0xfd100000
+#define PMU0SGRF_BASE		0xfd580000
+#define PMU1SGRF_BASE		0xfd582000
+#define BUSSGRF_BASE		0xfd586000
+#define DSUSGRF_BASE		0xfd587000
+#define PMU0GRF_BASE		0xfd588000
+#define PMU1GRF_BASE		0xfd58a000
+
+#define SYSGRF_BASE		0xfd58c000
+#define BIGCORE0GRF_BASE	0xfd590000
+#define BIGCORE1GRF_BASE	0xfd592000
+#define LITCOREGRF_BASE		0xfd594000
+#define DSUGRF_BASE		0xfd598000
+#define DDR01GRF_BASE		0xfd59c000
+#define DDR23GRF_BASE		0xfd59d000
+#define CENTERGRF_BASE		0xfd59e000
+#define GPUGRF_BASE		0xfd5a0000
+#define NPUGRF_BASE		0xfd5a2000
+#define USBGRF_BASE		0xfd5ac000
+#define PHPGRF_BASE		0xfd5b0000
+#define PCIE3PHYGRF_BASE	0xfd5b8000
+#define USB2PHY0_GRF_BASE	0xfd5d0000
+#define USB2PHY1_GRF_BASE	0xfd5d4000
+#define USB2PHY2_GRF_BASE	0xfd5d8000
+#define USB2PHY3_GRF_BASE	0xfd5dc000
+
+#define PMU0IOC_BASE		0xfd5f0000
+#define PMU1IOC_BASE		0xfd5f4000
+#define BUSIOC_BASE		0xfd5f8000
+#define VCCIO1_4_IOC_BASE	0xfd5f9000
+#define VCCIO3_5_IOC_BASE	0xfd5fa000
+#define VCCIO2_IOC_BASE		0xfd5fb000
+#define VCCIO6_IOC_BASE		0xfd5fc000
+
+#define SRAM_BASE		0xff000000
+#define PMUSRAM_BASE		0xff100000
+#define PMUSRAM_SIZE		SIZE_K(128)
+#define PMUSRAM_RSIZE		SIZE_K(64)
+
+#define CRU_BASE		0xfd7c0000
+#define PHP_CRU_BASE		0xfd7c8000
+#define SCRU_BASE		0xfd7d0000
+#define BUSSCRU_BASE		0xfd7d8000
+#define PMU1SCRU_BASE		0xfd7e0000
+#define PMU1CRU_BASE		0xfd7f0000
+
+#define DDR0CRU_BASE		0xfd800000
+#define DDR1CRU_BASE		0xfd804000
+#define DDR2CRU_BASE		0xfd808000
+#define DDR3CRU_BASE		0xfd80c000
+
+#define BIGCORE0CRU_BASE	0xfd810000
+#define BIGCORE1CRU_BASE	0xfd812000
+#define LITCRU_BASE		0xfd814000
+#define DSUCRU_BASE		0xfd818000
+
+#define I2C0_BASE		0xfd880000
+#define UART0_BASE		0xfd890000
+#define GPIO0_BASE		0xfd8a0000
+#define PWM0_BASE		0xfd8b0000
+#define PMUPVTM_BASE		0xfd8c0000
+#define TIMER_HP_BASE		0xfd8c8000
+#define PMU0_BASE		0xfd8d0000
+#define PMU1_BASE		0xfd8d4000
+#define PMU2_BASE		0xfd8d8000
+#define PMU_BASE		PMU0_BASE
+#define PMUWDT_BASE		0xfd8e0000
+#define PMUTIMER_BASE		0xfd8f0000
+#define OSC_CHK_BASE		0xfd9b0000
+#define VOP_BASE		0xfdd90000
+#define HDMIRX_BASE		0xfdee0000
+
+#define MSCH0_BASE		0xfe000000
+#define MSCH1_BASE		0xfe002000
+#define MSCH2_BASE		0xfe004000
+#define MSCH3_BASE		0xfe006000
+#define FIREWALL_DSU_BASE	0xfe010000
+#define FIREWALL_DDR_BASE	0xfe030000
+#define FIREWALL_SYSMEM_BASE	0xfe038000
+#define DDRPHY0_BASE		0xfe0c0000
+#define DDRPHY1_BASE		0xfe0d0000
+#define DDRPHY2_BASE		0xfe0e0000
+#define DDRPHY3_BASE		0xfe0f0000
+#define TIMER_DDR_BASE		0xfe118000
+#define KEYLADDER_BASE		0xfe380000
+#define CRYPTO_S_BASE		0xfe390000
+#define OTP_S_BASE		0xfe3a0000
+#define DCF_BASE		0xfe3c0000
+#define STIMER0_BASE		0xfe3d0000
+#define WDT_S_BASE		0xfe3e0000
+#define CRYPTO_S_BY_KEYLAD_BASE	0xfe420000
+#define NSTIMER0_BASE		0xfeae0000
+#define NSTIMER1_BASE		0xfeae8000
+#define WDT_NS_BASE		0xfeaf0000
+
+#define UART1_BASE		0xfeb40000
+#define UART2_BASE		0xfeb50000
+#define UART3_BASE		0xfeb60000
+#define UART4_BASE		0xfeb70000
+#define UART5_BASE		0xfeb80000
+#define UART6_BASE		0xfeb90000
+#define UART7_BASE		0xfeba0000
+#define UART8_BASE		0xfebb0000
+#define UART9_BASE		0xfebc0000
+
+#define GPIO1_BASE		0xfec20000
+#define GPIO2_BASE		0xfec30000
+#define GPIO3_BASE		0xfec40000
+#define GPIO4_BASE		0xfec50000
+
+#define MAILBOX1_BASE		0xfec70000
+#define OTP_NS_BASE		0xfecc0000
+#define INTMUX0_DDR_BASE	0Xfecf8000
+#define INTMUX1_DDR_BASE	0Xfecfc000
+#define STIMER1_BASE		0xfed30000
+
+/**************************************************************************
+ * sys sram allocation
+ **************************************************************************/
+#define SRAM_ENTRY_BASE		SRAM_BASE
+#define SRAM_PMUM0_SHMEM_BASE	(SRAM_ENTRY_BASE + SIZE_K(3))
+#define SRAM_LD_BASE		(SRAM_ENTRY_BASE + SIZE_K(4))
+#define SRAM_LD_SIZE		SIZE_K(64)
+
+#define SRAM_LD_SP		(SRAM_LD_BASE + SRAM_LD_SIZE -\
+				 128)
+
+/**************************************************************************
+ * share mem region allocation: 1M~2M
+ **************************************************************************/
+#define DDR_SHARE_MEM		SIZE_K(1024)
+#define DDR_SHARE_SIZE		SIZE_K(64)
+
+#define SHARE_MEM_BASE		DDR_SHARE_MEM
+#define SHARE_MEM_PAGE_NUM	15
+#define SHARE_MEM_SIZE		SIZE_K(SHARE_MEM_PAGE_NUM * 4)
+
+#define	SCMI_SHARE_MEM_BASE	(SHARE_MEM_BASE + SHARE_MEM_SIZE)
+#define	SCMI_SHARE_MEM_SIZE	SIZE_K(4)
+
+#define SMT_BUFFER_BASE		SCMI_SHARE_MEM_BASE
+#define SMT_BUFFER0_BASE	SMT_BUFFER_BASE
+
+/**************************************************************************
+ * UART related constants
+ **************************************************************************/
+#define RK_DBG_UART_BASE		UART2_BASE
+#define RK_DBG_UART_BAUDRATE		1500000
+#define RK_DBG_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 + 0x80000)
+#define PLAT_GICITS0_BASE		0xfe640000
+#define PLAT_GICITS1_BASE		0xfe660000
+
+/******************************************************************************
+ * sgi, ppi
+ ******************************************************************************/
+#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 RK_IRQ_SEC_PHY_TIMER		29
+
+/*
+ * 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)
+
+/******************************************************************************
+ * pm reg region memory
+ ******************************************************************************/
+#define ROCKCHIP_PM_REG_REGION_MEM_SIZE		SIZE_K(4)
+
+#endif /* __PLAT_DEF_H__ */
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index eaaff7d..e139b49 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -23,6 +23,7 @@
 BL1_SOURCES		+=	drivers/io/io_fip.c			\
 				drivers/io/io_memmap.c			\
 				drivers/io/io_storage.c			\
+				drivers/delay_timer/generic_delay_timer.c \
 				lib/cpus/aarch64/cortex_a53.S		\
 				plat/common/aarch64/platform_mp_stack.S	\
 				plat/rpi/rpi3/rpi3_bl1_setup.c		\
diff --git a/plat/rpi/rpi3/rpi3_bl1_setup.c b/plat/rpi/rpi3/rpi3_bl1_setup.c
index 3ac30e0..6c8fb2d 100644
--- a/plat/rpi/rpi3/rpi3_bl1_setup.c
+++ b/plat/rpi/rpi3/rpi3_bl1_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,8 @@
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
+#include <drivers/generic_delay_timer.h>
+#include <plat/common/platform.h>
 
 #include <rpi_shared.h>
 
@@ -37,6 +39,15 @@
 	/* Initialize the console to provide early debug support */
 	rpi3_console_init();
 
+	/*
+	 * Write the System Timer Frequency to CNTFRQ manually, this
+	 * is required to use the delay_timer functionality.
+	 */
+	write_cntfrq_el0(plat_get_syscnt_freq2());
+
+	/* Enable arch timer */
+	generic_delay_timer_init();
+
 	/* Allow BL1 to see the whole Trusted RAM */
 	bl1_tzram_layout.total_base = BL_RAM_BASE;
 	bl1_tzram_layout.total_size = BL_RAM_SIZE;
diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk
index cbfa6f2..c39a587 100644
--- a/plat/rpi/rpi4/platform.mk
+++ b/plat/rpi/rpi4/platform.mk
@@ -31,6 +31,7 @@
 				plat/common/plat_psci_common.c		\
 				plat/rpi/common/rpi3_topology.c		\
 				common/fdt_fixup.c			\
+				common/fdt_wrappers.c			\
 				${LIBFDT_SRCS}				\
 				${GICV2_SOURCES}
 
diff --git a/plat/st/common/common_rules.mk b/plat/st/common/common_rules.mk
index 8b81c7f..fba7783 100644
--- a/plat/st/common/common_rules.mk
+++ b/plat/st/common/common_rules.mk
@@ -41,7 +41,7 @@
 	fi
 
 # Create DTB file for BL2
-${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs
+${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | $$(@D)/
 	$(q)echo '#include "$(patsubst fdts/%,%,$<)"' > $@
 	$(q)echo '#include "${BL2_DTSI}"' >> $@
 
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index 9af221c..f65301f 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -77,6 +77,8 @@
 /* Setup the UART console */
 int stm32mp_uart_console_setup(void);
 
+bool stm32mp_is_wakeup_from_standby(void);
+
 /*
  * Platform util functions for the GPIO driver
  * @bank: Target GPIO bank ID as per DT bindings
@@ -120,6 +122,10 @@
 int stm32mp_map_ddr_non_cacheable(void);
 int stm32mp_unmap_ddr(void);
 
+/* Functions to map RETRAM, and unmap it */
+int stm32mp_map_retram(void);
+int stm32mp_unmap_retram(void);
+
 /* Function to save boot info */
 void stm32_save_boot_info(boot_api_context_t *boot_context);
 /* Function to get boot peripheral info */
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index 1cbf51b..282f53f 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.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
  */
@@ -243,7 +243,11 @@
 		return 0U;
 	}
 
+#ifdef __aarch64__
+	size = (size_t)fdt_read_uint64_default(fdt, node, "st,mem-size", 0ULL);
+#else /* __aarch64__ */
 	size = (size_t)fdt_read_uint32_default(fdt, node, "st,mem-size", 0U);
+#endif /* __aarch64__ */
 
 	flush_dcache_range((uintptr_t)&size, sizeof(size_t));
 
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 6ed09d9..1aecece 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -76,14 +76,28 @@
 
 #define DEFAULT_UUID_NUMBER	U(7)
 
+#ifdef __aarch64__
+#define BL31_UUID_NUMBER	U(1)
+#else
+#define BL31_UUID_NUMBER	U(0)
+#endif
+
 #if TRUSTED_BOARD_BOOT
 #define TBBR_UUID_NUMBER	U(6)
 #else
 #define TBBR_UUID_NUMBER	U(0)
 #endif
 
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define DDR_FW_UUID_NUMBER	U(1)
+#else
+#define DDR_FW_UUID_NUMBER	U(0)
+#endif
+
 #define FCONF_ST_IO_UUID_NUMBER	(DEFAULT_UUID_NUMBER + \
-				 TBBR_UUID_NUMBER)
+				 BL31_UUID_NUMBER + \
+				 TBBR_UUID_NUMBER + \
+				 DDR_FW_UUID_NUMBER)
 
 static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER];
 static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids);
@@ -95,7 +109,13 @@
 
 /* image id to property name table */
 static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = {
+#if STM32MP_DDR_FIP_IO_STORAGE
+	{DDR_FW_ID, "ddr_fw_uuid"},
+#endif
 	{FW_CONFIG_ID, "fw_cfg_uuid"},
+#ifdef __aarch64__
+	{BL31_IMAGE_ID, "bl31_uuid"},
+#endif
 	{BL32_IMAGE_ID, "bl32_uuid"},
 	{BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
 	{BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"},
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 2ade242..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);
 
@@ -461,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 */
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/plat_ddr.c b/plat/st/stm32mp1/plat_ddr.c
new file mode 100644
index 0000000..a6a0cdb
--- /dev/null
+++ b/plat/st/stm32mp1/plat_ddr.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <drivers/st/regulator.h>
+#include <drivers/st/stm32mp_ddr.h>
+#include <drivers/st/stm32mp_pmic.h>
+
+/* configure the STPMIC1 regulators on STMicroelectronics boards */
+static int pmic_ddr_power_init(enum ddr_type ddr_type)
+{
+	int status;
+	uint16_t buck3_min_mv __maybe_unused;
+	struct rdev *buck2, *buck3 __maybe_unused, *vref;
+	struct rdev *ldo3 __maybe_unused;
+
+	buck2 = regulator_get_by_name("buck2");
+	if (buck2 == NULL) {
+		return -ENOENT;
+	}
+
+#if STM32MP15
+	ldo3 = regulator_get_by_name("ldo3");
+	if (ldo3 == NULL) {
+		return -ENOENT;
+	}
+#endif
+
+	vref = regulator_get_by_name("vref_ddr");
+	if (vref == NULL) {
+		return -ENOENT;
+	}
+
+	switch (ddr_type) {
+	case STM32MP_DDR3:
+#if STM32MP15
+		status = regulator_set_flag(ldo3, REGUL_SINK_SOURCE);
+		if (status != 0) {
+			return status;
+		}
+#endif
+
+		status = regulator_set_min_voltage(buck2);
+		if (status != 0) {
+			return status;
+		}
+
+		status = regulator_enable(buck2);
+		if (status != 0) {
+			return status;
+		}
+
+		status = regulator_enable(vref);
+		if (status != 0) {
+			return status;
+		}
+
+#if STM32MP15
+		status = regulator_enable(ldo3);
+		if (status != 0) {
+			return status;
+		}
+#endif
+		break;
+
+	case STM32MP_LPDDR2:
+	case STM32MP_LPDDR3:
+#if STM32MP15
+		/*
+		 * Set LDO3 to 1.8V according  BUCK3 voltage
+		 * => bypass mode if BUCK3 = 1.8V
+		 * => normal mode if BUCK3 != 1.8V
+		 */
+		buck3 = regulator_get_by_name("buck3");
+		if (buck3 == NULL) {
+			return -ENOENT;
+		}
+
+		regulator_get_range(buck3, &buck3_min_mv, NULL);
+
+		if (buck3_min_mv != 1800) {
+			status = regulator_set_min_voltage(ldo3);
+			if (status != 0) {
+				return status;
+			}
+		} else {
+			status = regulator_set_flag(ldo3, REGUL_ENABLE_BYPASS);
+			if (status != 0) {
+				return status;
+			}
+		}
+#endif
+
+		status = regulator_set_min_voltage(buck2);
+		if (status != 0) {
+			return status;
+		}
+
+#if STM32MP15
+		status = regulator_enable(ldo3);
+		if (status != 0) {
+			return status;
+		}
+#endif
+
+		status = regulator_enable(buck2);
+		if (status != 0) {
+			return status;
+		}
+
+		status = regulator_enable(vref);
+		if (status != 0) {
+			return status;
+		}
+		break;
+
+	default:
+		break;
+	};
+
+	return 0;
+}
+
+int stm32mp_board_ddr_power_init(enum ddr_type ddr_type)
+{
+	if (dt_pmic_status() > 0) {
+		return pmic_ddr_power_init(ddr_type);
+	}
+
+	return 0;
+}
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index a1f44e8..3d37738 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -253,13 +253,15 @@
 BL2_SOURCES		+=	drivers/st/ddr/stm32mp1_ddr.c				\
 				drivers/st/ddr/stm32mp1_ram.c
 
+BL2_SOURCES		+=	plat/st/stm32mp1/plat_ddr.c
+
 ifeq ($(AARCH32_SP),sp_min)
 # Create DTB file for BL32
-${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | ${BUILD_PLAT} fdt_dirs
+${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_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 189f83d..45446dc 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -280,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;
@@ -297,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;
@@ -664,6 +664,12 @@
 }
 #endif
 
+bool stm32mp_is_wakeup_from_standby(void)
+{
+	/* TODO add source code to determine if platform is waking up from standby mode */
+	return false;
+}
+
 uintptr_t stm32_get_bkpr_boot_mode_addr(void)
 {
 	return tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
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/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 724209a..345850b 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -4,30 +4,389 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <cdefs.h>
+#include <errno.h>
 #include <stdint.h>
 
 #include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/clk.h>
+#include <drivers/mmc.h>
+#include <drivers/st/regulator_fixed.h>
+#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp2_ram.h>
+#include <drivers/st/stm32mp_pmic2.h>
+#include <drivers/st/stm32mp_risab_regs.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/mmio.h>
+#include <lib/optee_utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
 #include <platform_def.h>
 #include <stm32mp_common.h>
+#include <stm32mp_dt.h>
+
+#define BOOT_CTX_ADDR	0x0e000020UL
+
+static void print_reset_reason(void)
+{
+	uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_C1BOOTRSTSCLRR);
+
+	if (rstsr == 0U) {
+		WARN("Reset reason unknown\n");
+		return;
+	}
+
+	INFO("Reset reason (0x%x):\n", rstsr);
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_PADRSTF) == 0U) {
+		if ((rstsr & RCC_C1BOOTRSTSCLRR_STBYC1RSTF) != 0U) {
+			INFO("System exits from Standby for CA35\n");
+			return;
+		}
+
+		if ((rstsr & RCC_C1BOOTRSTSCLRR_D1STBYRSTF) != 0U) {
+			INFO("D1 domain exits from DStandby\n");
+			return;
+		}
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_PORRSTF) != 0U) {
+		INFO("  Power-on Reset (rst_por)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_BORRSTF) != 0U) {
+		INFO("  Brownout Reset (rst_bor)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSSETR_SYSC2RSTF) != 0U) {
+		INFO("  System reset (SYSRST) by M33\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSSETR_SYSC1RSTF) != 0U) {
+		INFO("  System reset (SYSRST) by A35\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_HCSSRSTF) != 0U) {
+		INFO("  Clock failure on HSE\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG1SYSRSTF) != 0U) {
+		INFO("  IWDG1 system reset (rst_iwdg1)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG2SYSRSTF) != 0U) {
+		INFO("  IWDG2 system reset (rst_iwdg2)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG3SYSRSTF) != 0U) {
+		INFO("  IWDG3 system reset (rst_iwdg3)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG4SYSRSTF) != 0U) {
+		INFO("  IWDG4 system reset (rst_iwdg4)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG5SYSRSTF) != 0U) {
+		INFO("  IWDG5 system reset (rst_iwdg5)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_C1P1RSTF) != 0U) {
+		INFO("  A35 processor core 1 reset\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_PADRSTF) != 0U) {
+		INFO("  Pad Reset from NRST\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_VCORERSTF) != 0U) {
+		INFO("  Reset due to a failure of VDD_CORE\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_C1RSTF) != 0U) {
+		INFO("  A35 processor reset\n");
+		return;
+	}
+
+	ERROR("  Unidentified reset reason\n");
+}
 
 void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
 				  u_register_t arg1 __unused,
 				  u_register_t arg2 __unused,
 				  u_register_t arg3 __unused)
 {
+	stm32mp_save_boot_ctx_address(BOOT_CTX_ADDR);
 }
 
 void bl2_platform_setup(void)
 {
+	int ret;
+
+	ret = stm32mp2_ddr_probe();
+	if (ret != 0) {
+		ERROR("DDR probe: error %d\n", ret);
+		panic();
+	}
+
+	/* Map DDR for binary load, now with cacheable attribute */
+	ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE,
+				      STM32MP_DDR_MAX_SIZE, MT_MEMORY | MT_RW | MT_SECURE);
+	if (ret < 0) {
+		ERROR("DDR mapping: error %d\n", ret);
+		panic();
+	}
+}
+
+static void reset_backup_domain(void)
+{
+	uintptr_t pwr_base = stm32mp_pwr_base();
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	/*
+	 * Disable the backup domain write protection.
+	 * The protection is enable at each reset by hardware
+	 * and must be disabled by software.
+	 */
+	mmio_setbits_32(pwr_base + PWR_BDCR1, PWR_BDCR1_DBD3P);
+
+	while ((mmio_read_32(pwr_base + PWR_BDCR1) & PWR_BDCR1_DBD3P) == 0U) {
+		;
+	}
+
+	/* Reset backup domain on cold boot cases */
+	if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_RTCCKEN) == 0U) {
+		mmio_setbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST);
+
+		while ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_VSWRST) == 0U) {
+			;
+		}
+
+		mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST);
+	}
 }
 
 void bl2_el3_plat_arch_setup(void)
 {
+	const char *board_model;
+	boot_api_context_t *boot_context =
+		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
+
 	if (stm32_otp_probe() != 0U) {
 		EARLY_ERROR("OTP probe failed\n");
 		panic();
 	}
+
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+
+	configure_mmu();
+
+	if (dt_open_and_check(STM32MP_DTB_BASE) < 0) {
+		panic();
+	}
+
+	reset_backup_domain();
+
+	/*
+	 * Initialize DDR sub-system clock. This needs to be done before enabling DDR PLL (PLL2),
+	 * and so before stm32mp2_clk_init().
+	 */
+	ddr_sub_system_clk_init();
+
+	if (stm32mp2_clk_init() < 0) {
+		panic();
+	}
+
+#if STM32MP_DDR_FIP_IO_STORAGE
+	/*
+	 * RISAB3 setup (dedicated for SRAM1)
+	 *
+	 * Allow secure read/writes data accesses to non-secure
+	 * blocks or pages, all RISAB registers are writable.
+	 * DDR firmwares are saved there before being loaded in DDRPHY memory.
+	 */
+	mmio_write_32(RISAB3_BASE + RISAB_CR, RISAB_CR_SRWIAD);
+#endif
+
+	stm32_save_boot_info(boot_context);
+
+	if (stm32mp_uart_console_setup() != 0) {
+		goto skip_console_init;
+	}
+
+	stm32mp_print_cpuinfo();
+
+	board_model = dt_get_board_model();
+	if (board_model != NULL) {
+		NOTICE("Model: %s\n", board_model);
+	}
+
+	stm32mp_print_boardinfo();
+
+	print_reset_reason();
+
+skip_console_init:
+	if (fixed_regulator_register() != 0) {
+		panic();
+	}
+
+	if (dt_pmic_status() > 0) {
+		initialize_pmic();
+	}
+
+	fconf_populate("TB_FW", STM32MP_DTB_BASE);
+
+	/*
+	 * RISAB5 setup (dedicated for RETRAM)
+	 *
+	 * Allow secure read/writes data accesses to non-secure
+	 * blocks or pages, all RISAB registers are writable.
+	 * DDR retention registers are saved there and restored
+	 * when exiting standby low power state.
+	 */
+	mmio_write_32(RISAB5_BASE + RISAB_CR, RISAB_CR_SRWIAD);
+
+	stm32mp_io_setup();
+}
+
+/*******************************************************************************
+ * This function can be used by the platforms to update/use image
+ * information for given `image_id`.
+ ******************************************************************************/
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	int err = 0;
+	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+	bl_mem_params_node_t *pager_mem_params;
+	const struct dyn_cfg_dtb_info_t *config_info;
+	unsigned int i;
+	const unsigned int image_ids[] = {
+		BL31_IMAGE_ID,
+		BL32_IMAGE_ID,
+		BL33_IMAGE_ID,
+		HW_CONFIG_ID,
+	};
+
+	assert(bl_mem_params != NULL);
+
+#if STM32MP_SDMMC || STM32MP_EMMC
+	/*
+	 * Invalidate remaining data read from MMC but not flushed by load_image_flush().
+	 * We take the worst case which is 2 MMC blocks.
+	 */
+	if ((image_id != FW_CONFIG_ID) &&
+	    ((bl_mem_params->image_info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U)) {
+		inv_dcache_range(bl_mem_params->image_info.image_base +
+				 bl_mem_params->image_info.image_size,
+				 2U * MMC_BLOCK_SIZE);
+	}
+#endif /* STM32MP_SDMMC || STM32MP_EMMC */
+
+	switch (image_id) {
+	case FW_CONFIG_ID:
+		/* Set global DTB info for fixed fw_config information */
+		set_config_info(STM32MP_FW_CONFIG_BASE, ~0UL, STM32MP_FW_CONFIG_MAX_SIZE,
+				FW_CONFIG_ID);
+		fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE);
+
+		/* Iterate through all the fw config IDs */
+		for (i = 0U; i < ARRAY_SIZE(image_ids); i++) {
+			bl_mem_params = get_bl_mem_params_node(image_ids[i]);
+			assert(bl_mem_params != NULL);
+
+			config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_ids[i]);
+			if (config_info == NULL) {
+				continue;
+			}
+
+			bl_mem_params->image_info.image_base = config_info->config_addr;
+			bl_mem_params->image_info.image_max_size = config_info->config_max_size;
+
+			bl_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+
+			switch (image_ids[i]) {
+			case BL31_IMAGE_ID:
+				bl_mem_params->ep_info.pc = config_info->config_addr;
+				break;
+
+			case BL32_IMAGE_ID:
+				bl_mem_params->ep_info.pc = config_info->config_addr;
+
+				/* In case of OPTEE, initialize address space with tos_fw addr */
+				pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+				if (pager_mem_params != NULL) {
+					pager_mem_params->image_info.image_base =
+						config_info->config_addr;
+					pager_mem_params->image_info.image_max_size =
+						config_info->config_max_size;
+				}
+				break;
+
+			case BL33_IMAGE_ID:
+				bl_mem_params->ep_info.pc = config_info->config_addr;
+				break;
+
+			case HW_CONFIG_ID:
+				break;
+
+			default:
+				return -EINVAL;
+			}
+		}
+
+		/*
+		 * After this step, the BL2 device tree area will be overwritten
+		 * with BL31 binary, no other data should be read from BL2 DT.
+		 */
+
+		break;
+
+	case BL32_IMAGE_ID:
+		if ((bl_mem_params->image_info.image_base != 0UL) &&
+		    (optee_header_is_valid(bl_mem_params->image_info.image_base))) {
+			/* BL32 is OP-TEE header */
+			bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
+			pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+			assert(pager_mem_params != NULL);
+
+			err = parse_optee_header(&bl_mem_params->ep_info,
+						 &pager_mem_params->image_info,
+						 NULL);
+			if (err != 0) {
+				ERROR("OPTEE header parse error.\n");
+				panic();
+			}
+
+			/* Set optee boot info from parsed header data */
+			bl_mem_params->ep_info.args.arg0 = 0U; /* Unused */
+			bl_mem_params->ep_info.args.arg1 = 0U; /* Unused */
+			bl_mem_params->ep_info.args.arg2 = 0U; /* No DT supported */
+		}
+		break;
+
+	case BL33_IMAGE_ID:
+	default:
+		/* Do nothing in default case */
+		break;
+	}
+
+	return err;
 }
diff --git a/plat/st/stm32mp2/bl31_plat_setup.c b/plat/st/stm32mp2/bl31_plat_setup.c
new file mode 100644
index 0000000..dbf1371
--- /dev/null
+++ b/plat/st/stm32mp2/bl31_plat_setup.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/bl_common.h>
+#include <drivers/st/stm32_console.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	bl_params_t *params_from_bl2;
+	int ret;
+
+	/*
+	 * Invalidate remaining data from second half of SYSRAM (used by BL2) as this area will
+	 * be later used as non-secure.
+	 */
+	inv_dcache_range(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+			 STM32MP_SYSRAM_SIZE / 2U);
+
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+
+#if USE_COHERENT_MEM
+	/* Map coherent memory */
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
+	configure_mmu();
+
+	/*
+	 * Map upper SYSRAM where bl_params_t are stored in BL2
+	 */
+	ret = mmap_add_dynamic_region(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+				      STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+				      STM32MP_SYSRAM_SIZE / 2U, MT_RO_DATA | MT_SECURE);
+	if (ret < 0) {
+		ERROR("BL2 params area mapping: %d\n", ret);
+		panic();
+	}
+
+	assert(arg0 != 0UL);
+	params_from_bl2 = (bl_params_t *)arg0;
+	assert(params_from_bl2 != NULL);
+	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
+	assert(params_from_bl2->h.version >= VERSION_2);
+
+	bl_params_node_t *bl_params = params_from_bl2->head;
+
+	while (bl_params != NULL) {
+		bl_params = bl_params->next_params_info;
+	}
+
+	ret = mmap_remove_dynamic_region(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+					 STM32MP_SYSRAM_SIZE / 2U);
+	if (ret < 0) {
+		ERROR("BL2 params area unmapping: %d\n", ret);
+		panic();
+	}
+}
+
+void bl31_plat_arch_setup(void)
+{
+}
+
+void bl31_platform_setup(void)
+{
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+	return NULL;
+}
diff --git a/plat/st/stm32mp2/include/boot_api.h b/plat/st/stm32mp2/include/boot_api.h
index d3bed76..580a65b 100644
--- a/plat/st/stm32mp2/include/boot_api.h
+++ b/plat/st/stm32mp2/include/boot_api.h
@@ -86,7 +86,7 @@
 /* Image Header related definitions */
 
 /* Definition of header version */
-#define BOOT_API_HEADER_VERSION					0x00020000U
+#define BOOT_API_HEADER_VERSION					0x00020200U
 
 /*
  * Magic number used to detect header in memory
diff --git a/plat/st/stm32mp2/include/plat_tbbr_img_def.h b/plat/st/stm32mp2/include/plat_tbbr_img_def.h
new file mode 100644
index 0000000..830bf88
--- /dev/null
+++ b/plat/st/stm32mp2/include/plat_tbbr_img_def.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_TBBR_IMG_DEF_H
+#define PLAT_TBBR_IMG_DEF_H
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/* Undef the existing values */
+#undef BKUP_FWU_METADATA_IMAGE_ID
+#undef FWU_METADATA_IMAGE_ID
+#undef FW_CONFIG_ID
+#undef ENC_IMAGE_ID
+#undef GPT_IMAGE_ID
+#undef NT_FW_CONFIG_ID
+#undef SOC_FW_CONFIG_ID
+#undef TB_FW_CONFIG_ID
+#undef HW_CONFIG_ID
+#undef TRUSTED_BOOT_FW_CERT_ID
+#undef SOC_FW_CONTENT_CERT_ID
+#undef BL32_EXTRA1_IMAGE_ID
+#undef TOS_FW_CONFIG_ID
+
+/* Define the STM32MP2 used ID */
+#define FW_CONFIG_ID			U(1)
+#define HW_CONFIG_ID			U(2)
+#define ENC_IMAGE_ID			U(6)
+#define BL32_EXTRA1_IMAGE_ID		U(8)
+#define FWU_METADATA_IMAGE_ID		U(12)
+#define BKUP_FWU_METADATA_IMAGE_ID	U(13)
+#define TOS_FW_CONFIG_ID		U(16)
+#define NT_FW_CONFIG_ID			U(18)
+#define SOC_FW_CONFIG_ID		U(19)
+#define TB_FW_CONFIG_ID			U(20)
+#define TRUSTED_BOOT_FW_CERT_ID		U(21)
+#define SOC_FW_CONTENT_CERT_ID		U(23)
+#define STM32MP_CONFIG_CERT_ID		U(24)
+#define GPT_IMAGE_ID			U(25)
+
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define DDR_FW_ID			U(26)
+/* Increase the MAX_NUMBER_IDS to match the authentication pool required */
+#define MAX_NUMBER_IDS			U(27)
+
+#else
+/* Increase the MAX_NUMBER_IDS to match the authentication pool required */
+#define MAX_NUMBER_IDS			U(26)
+
+#endif
+
+#endif /* PLAT_TBBR_IMG_DEF_H */
+
diff --git a/plat/st/stm32mp2/include/platform_def.h b/plat/st/stm32mp2/include/platform_def.h
index 404c384..b98b56d 100644
--- a/plat/st/stm32mp2/include/platform_def.h
+++ b/plat/st/stm32mp2/include/platform_def.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
  */
@@ -8,6 +8,7 @@
 #define PLATFORM_DEF_H
 
 #include <arch.h>
+#include <drivers/arm/gic_common.h>
 #include <lib/utils_def.h>
 #include <plat/common/common_def.h>
 
@@ -32,9 +33,9 @@
 #define PLATFORM_CORE_COUNT		U(2)
 #define PLATFORM_MAX_CPUS_PER_CLUSTER	U(2)
 
-#define PLAT_MAX_PWR_LVL		U(5)
-#define PLAT_MAX_CPU_SUSPEND_PWR_LVL	U(5)
-#define PLAT_NUM_PWR_DOMAINS		U(7)
+#define PLAT_MAX_PWR_LVL		U(3)
+#define PLAT_MIN_SUSPEND_PWR_LVL	U(2)
+#define PLAT_NUM_PWR_DOMAINS		U(6)
 
 /* Local power state for power domains in Run state. */
 #define STM32MP_LOCAL_STATE_RUN		U(0)
@@ -61,6 +62,20 @@
 #define BL2_LIMIT			(STM32MP_BL2_BASE + \
 					 STM32MP_BL2_SIZE)
 
+#define BL2_RO_BASE			STM32MP_BL2_RO_BASE
+#define BL2_RO_LIMIT			(STM32MP_BL2_RO_BASE + \
+					 STM32MP_BL2_RO_SIZE)
+
+#define BL2_RW_BASE			STM32MP_BL2_RW_BASE
+#define BL2_RW_LIMIT			(STM32MP_BL2_RW_BASE + \
+					 STM32MP_BL2_RW_SIZE)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+#define BL31_BASE			0
+#define BL31_LIMIT			(STM32MP_SEC_SYSRAM_SIZE / 2)
+
 /*******************************************************************************
  * BL33 specific defines.
  ******************************************************************************/
@@ -84,4 +99,59 @@
 #define CACHE_WRITEBACK_SHIFT		6
 #define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
 
+/*
+ * Secure Interrupt: based on the standard ARM mapping
+ */
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+
+#define ARM_IRQ_NON_SEC_SGI_0		U(0)
+
+#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)
+
+/* Platform IRQ Priority */
+#define STM32MP_IRQ_SEC_SPI_PRIO	U(0x10)
+
+/*
+ * 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 PLATFORM_G1S_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 PLATFORM_G0_PROPS(grp) \
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/st/stm32mp2/include/stm32mp2_private.h b/plat/st/stm32mp2/include/stm32mp2_private.h
index e1403d2..4bb8c52 100644
--- a/plat/st/stm32mp2/include/stm32mp2_private.h
+++ b/plat/st/stm32mp2/include/stm32mp2_private.h
@@ -7,6 +7,13 @@
 #ifndef STM32MP2_PRIVATE_H
 #define STM32MP2_PRIVATE_H
 
+void configure_mmu(void);
+
+uint32_t stm32mp_syscfg_get_chip_dev_id(void);
+
+/* Get DDRDBG peripheral IO memory base address */
+uintptr_t stm32_ddrdbg_get_base(void);
+
 /* Wrappers for OTP / BSEC functions */
 static inline uint32_t stm32_otp_probe(void)
 {
diff --git a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
index 630cc84..ecad0b4 100644
--- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
@@ -1,10 +1,14 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/bl_common.h>
 #include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
 
 /*******************************************************************************
  * Following descriptor provides BL image/ep information that gets used
@@ -15,6 +19,118 @@
  * the next executable image id.
  ******************************************************************************/
 static bl_mem_params_node_t bl2_mem_params_descs[] = {
+#if STM32MP_DDR_FIP_IO_STORAGE
+	/* Fill FW_DDR related information if it exists */
+	{
+		.image_id = DDR_FW_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      0),
+
+		.image_info.image_base = STM32MP_DDR_FW_BASE,
+		.image_info.image_max_size = STM32MP_DDR_FW_MAX_SIZE,
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+#endif
+
+	/* Fill FW_CONFIG related information if it exists */
+	{
+		.image_id = FW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_PLAT_SETUP),
+
+		.image_info.image_base = STM32MP_FW_CONFIG_BASE,
+		.image_info.image_max_size = STM32MP_FW_CONFIG_MAX_SIZE,
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/* Fill BL31 related information */
+	{
+		.image_id = BL31_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE | EP_FIRST_EXE),
+
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = BL32_IMAGE_ID,
+	},
+
+	/* Fill BL32 related information */
+	{
+		.image_id = BL32_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+
+	/* Fill BL32 external 1 image related information */
+	{
+		.image_id = BL32_EXTRA1_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/* Fill HW_CONFIG related information if it exists */
+	{
+		.image_id = HW_CONFIG_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      NON_SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/* Fill BL33 related information */
+	{
+		.image_id = BL33_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      NON_SECURE | EXECUTABLE),
+
+		.ep_info.spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	}
 };
 
 REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/st/stm32mp2/plat_ddr.c b/plat/st/stm32mp2/plat_ddr.c
new file mode 100644
index 0000000..5302e45
--- /dev/null
+++ b/plat/st/stm32mp2/plat_ddr.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <common/fdt_wrappers.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/st/regulator.h>
+#include <drivers/st/stm32mp_ddr.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#if STM32MP_DDR3_TYPE
+struct ddr3_supply {
+	struct rdev *vdd;
+	struct rdev *vref;
+	struct rdev *vtt;
+};
+
+static void ddr3_supply_read(void *fdt, int node, struct ddr3_supply *supply)
+{
+	supply->vdd = regulator_get_by_supply_name(fdt, node, "vdd");
+	supply->vref = regulator_get_by_supply_name(fdt, node, "vref");
+	supply->vtt = regulator_get_by_supply_name(fdt, node, "vtt");
+}
+
+static int ddr_power_init(void *fdt, int node)
+{
+	int status;
+	struct ddr3_supply supply;
+
+	ddr3_supply_read(fdt, node, &supply);
+	if ((supply.vdd == NULL) || (supply.vref == NULL) || (supply.vtt == NULL)) {
+		return -ENOENT;
+	}
+
+	/*
+	 * DDR3 power on sequence is:
+	 * enable VREF_DDR, VTT_DDR, VPP_DDR
+	 */
+	status = regulator_set_min_voltage(supply.vdd);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vdd);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vref);
+	if (status != 0) {
+		return status;
+	}
+
+	return regulator_enable(supply.vtt);
+}
+#endif /* STM32MP_DDR3_TYPE */
+
+#if STM32MP_DDR4_TYPE
+struct ddr4_supply {
+	struct rdev *vdd;
+	struct rdev *vref;
+	struct rdev *vtt;
+	struct rdev *vpp;
+};
+
+static void ddr4_supply_read(void *fdt, int node, struct ddr4_supply *supply)
+{
+	supply->vpp = regulator_get_by_supply_name(fdt, node, "vpp");
+	supply->vdd = regulator_get_by_supply_name(fdt, node, "vdd");
+	supply->vref = regulator_get_by_supply_name(fdt, node, "vref");
+	supply->vtt = regulator_get_by_supply_name(fdt, node, "vtt");
+}
+
+static int ddr_power_init(void *fdt, int node)
+{
+	int status;
+	struct ddr4_supply supply;
+
+	ddr4_supply_read(fdt, node, &supply);
+	if ((supply.vpp == NULL) || (supply.vdd == NULL) || (supply.vref == NULL) ||
+	    (supply.vtt == NULL)) {
+		return -ENOENT;
+	}
+
+	/*
+	 * DDR4 power on sequence is:
+	 * enable VPP_DDR
+	 * enable VREF_DDR, VTT_DDR, VPP_DDR
+	 */
+	status = regulator_set_min_voltage(supply.vpp);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_set_min_voltage(supply.vdd);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vpp);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vdd);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vref);
+	if (status != 0) {
+		return status;
+	}
+
+	return regulator_enable(supply.vtt);
+}
+#endif /* STM32MP_DDR4_TYPE */
+
+#if STM32MP_LPDDR4_TYPE
+struct lpddr4_supply {
+	struct rdev *vdd1;
+	struct rdev *vdd2;
+	struct rdev *vddq;
+};
+
+static void lpddr4_supply_read(void *fdt, int node, struct lpddr4_supply *supply)
+{
+	supply->vdd1 = regulator_get_by_supply_name(fdt, node, "vdd1");
+	supply->vdd2 = regulator_get_by_supply_name(fdt, node, "vdd2");
+	supply->vddq = regulator_get_by_supply_name(fdt, node, "vddq");
+}
+
+static int ddr_power_init(void *fdt, int node)
+{
+	int status;
+	struct lpddr4_supply supply;
+
+	lpddr4_supply_read(fdt, node, &supply);
+	if ((supply.vdd1 == NULL) || (supply.vdd2 == NULL) || (supply.vddq == NULL)) {
+		return -ENOENT;
+	}
+
+	/*
+	 * LPDDR4 power on sequence is:
+	 * enable VDD1_DDR
+	 * enable VDD2_DDR
+	 * enable VDDQ_DDR
+	 */
+	status = regulator_set_min_voltage(supply.vdd1);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_set_min_voltage(supply.vdd2);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_set_min_voltage(supply.vddq);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vdd1);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vdd2);
+	if (status != 0) {
+		return status;
+	}
+
+	return regulator_enable(supply.vddq);
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+int stm32mp_board_ddr_power_init(enum ddr_type ddr_type)
+{
+	void *fdt = NULL;
+	int node;
+
+	VERBOSE("DDR power init, ddr_type = %u\n", ddr_type);
+
+#if STM32MP_DDR3_TYPE
+	assert(ddr_type == STM32MP_DDR3);
+#elif STM32MP_DDR4_TYPE
+	assert(ddr_type == STM32MP_DDR4);
+#elif STM32MP_LPDDR4_TYPE
+	assert(ddr_type == STM32MP_LPDDR4);
+#else
+	ERROR("DDR type (%u) not supported\n", ddr_type);
+	panic();
+#endif
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
+	if (node < 0) {
+		ERROR("%s: Cannot read DDR node in DT\n", __func__);
+		return -EINVAL;
+	}
+
+	return ddr_power_init(fdt, node);
+}
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index 11b1138..c12e512 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -13,6 +13,7 @@
 CRASH_REPORTING			:=	1
 ENABLE_PIE			:=	1
 PROGRAMMABLE_RESET_ADDRESS	:=	1
+BL2_IN_XIP_MEM			:=	1
 
 # Default Device tree
 DTB_FILE_NAME			?=	stm32mp257f-ev1.dtb
@@ -24,7 +25,25 @@
 STM32_HEADER_VERSION_MINOR	:=	2
 
 # Set load address for serial boot devices
-DWL_BUFFER_BASE 	?=	0x87000000
+DWL_BUFFER_BASE 		?=	0x87000000
+
+# DDR types
+STM32MP_DDR3_TYPE		?=	0
+STM32MP_DDR4_TYPE		?=	0
+STM32MP_LPDDR4_TYPE		?=	0
+ifeq (${STM32MP_DDR3_TYPE},1)
+DDR_TYPE			:=	ddr3
+endif
+ifeq (${STM32MP_DDR4_TYPE},1)
+DDR_TYPE			:=	ddr4
+endif
+ifeq (${STM32MP_LPDDR4_TYPE},1)
+DDR_TYPE			:=	lpddr4
+endif
+
+# DDR features
+STM32MP_DDR_DUAL_AXI_PORT	:=	1
+STM32MP_DDR_FIP_IO_STORAGE	:=	1
 
 # Device tree
 BL2_DTSI			:=	stm32mp25-bl2.dtsi
@@ -35,9 +54,52 @@
 STM32_LD_FILE			:=	plat/st/stm32mp2/${ARCH}/stm32mp2.ld.S
 STM32_BINARY_MAPPING		:=	plat/st/stm32mp2/${ARCH}/stm32mp2.S
 
+STM32MP_FW_CONFIG_NAME		:=	$(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
+STM32MP_FW_CONFIG		:=	${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
+ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
+STM32MP_DDR_FW_PATH		?=	drivers/st/ddr/phy/firmware/bin/stm32mp2
+STM32MP_DDR_FW_NAME		:=	${DDR_TYPE}_pmu_train.bin
+STM32MP_DDR_FW			:=	${STM32MP_DDR_FW_PATH}/${STM32MP_DDR_FW_NAME}
+endif
+FDT_SOURCES			+=	$(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
+ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
+# Add the FW_DDR to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_IMG,STM32MP_DDR_FW,--ddr-fw))
+endif
+
+# Enable flags for C files
+$(eval $(call assert_booleans,\
+	$(sort \
+		STM32MP_DDR_DUAL_AXI_PORT \
+		STM32MP_DDR_FIP_IO_STORAGE \
+		STM32MP_DDR3_TYPE \
+		STM32MP_DDR4_TYPE \
+		STM32MP_LPDDR4_TYPE \
+		STM32MP25 \
+)))
+
+$(eval $(call assert_numerics,\
+	$(sort \
+		PLAT_PARTITION_MAX_ENTRIES \
+		STM32_HEADER_VERSION_MAJOR \
+		STM32_TF_A_COPIES \
+)))
+
 $(eval $(call add_defines,\
 	$(sort \
 		DWL_BUFFER_BASE \
+		PLAT_DEF_FIP_UUID \
+		PLAT_PARTITION_MAX_ENTRIES \
+		PLAT_TBBR_IMG_DEF \
+		STM32_TF_A_COPIES \
+		STM32MP_DDR_DUAL_AXI_PORT \
+		STM32MP_DDR_FIP_IO_STORAGE \
+		STM32MP_DDR3_TYPE \
+		STM32MP_DDR4_TYPE \
+		STM32MP_LPDDR4_TYPE \
+		STM32MP25 \
 )))
 
 # STM32MP2x is based on Cortex-A35, which is Armv8.0, and does not support BTI
@@ -46,18 +108,94 @@
 
 # Include paths and source files
 PLAT_INCLUDES			+=	-Iplat/st/stm32mp2/include/
+PLAT_INCLUDES			+=	-Idrivers/st/ddr/phy/phyinit/include/
+PLAT_INCLUDES			+=	-Idrivers/st/ddr/phy/firmware/include/
 
 PLAT_BL_COMMON_SOURCES		+=	lib/cpus/${ARCH}/cortex_a35.S
 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/pmic/stm32mp_pmic2.c				\
+					drivers/st/pmic/stpmic2.c				\
+
+PLAT_BL_COMMON_SOURCES		+=	drivers/st/i2c/stm32_i2c.c
+
+PLAT_BL_COMMON_SOURCES		+=	plat/st/stm32mp2/stm32mp2_private.c
+
+PLAT_BL_COMMON_SOURCES		+=	drivers/st/bsec/bsec3.c					\
+					drivers/st/reset/stm32mp2_reset.c			\
+					plat/st/stm32mp2/stm32mp2_syscfg.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
+
+BL2_SOURCES			+=	plat/st/stm32mp2/bl2_plat_setup.c			\
+					plat/st/stm32mp2/plat_ddr.c
+
+ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
+BL2_SOURCES			+=	drivers/st/mmc/stm32_sdmmc2.c
+endif
 
 ifeq (${STM32MP_USB_PROGRAMMER},1)
 BL2_SOURCES			+=	plat/st/stm32mp2/stm32mp2_usb_dfu.c
 endif
 
+BL2_SOURCES			+=	drivers/st/ddr/stm32mp2_ddr.c				\
+					drivers/st/ddr/stm32mp2_ddr_helpers.c			\
+					drivers/st/ddr/stm32mp2_ram.c
+
+BL2_SOURCES			+=	drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_calcmb.c					\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_i_loadpieimage.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_initstruct.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_isdbytedisabled.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_loadpieprodcode.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_progcsrskiptrain.c			\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_reginterface.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_restore_sequence.c			\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_sequence.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_softsetmb.c				\
+					drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_custompretrain.c	\
+					drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_saveretregs.c
+
+BL2_SOURCES			+=	drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_d_loadimem.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_f_loaddmem.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_g_execfw.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_writeoutmem.c				\
+					drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_g_waitfwdone.c
+
+# BL31 sources
+BL31_SOURCES			+=	${FDT_WRAPPERS_SOURCES}
+
+BL31_SOURCES			+=	plat/st/stm32mp2/bl31_plat_setup.c			\
+					plat/st/stm32mp2/stm32mp2_pm.c				\
+					plat/st/stm32mp2/stm32mp2_topology.c
+# Generic GIC v2
+include drivers/arm/gic/v2/gicv2.mk
+
+BL31_SOURCES			+=	${GICV2_SOURCES}					\
+					plat/common/plat_gicv2.c				\
+					plat/st/common/stm32mp_gic.c
+
+# Generic PSCI
+BL31_SOURCES			+=	plat/common/plat_psci_common.c
+
+# Compilation rules
+.PHONY: check_ddr_type
+.SUFFIXES:
+
+bl2: check_ddr_type
+
+check_ddr_type:
+	$(eval DDR_TYPE = $(shell echo $$(($(STM32MP_DDR3_TYPE) + \
+					   $(STM32MP_DDR4_TYPE) + \
+					   $(STM32MP_LPDDR4_TYPE)))))
+	@if [ ${DDR_TYPE} != 1 ]; then \
+		echo "One and only one DDR type must be defined"; \
+		false; \
+	fi
+
 include plat/st/common/common_rules.mk
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index e3662ad..73116db 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -12,6 +12,10 @@
 #include <drivers/st/bsec.h>
 #endif
 #include <drivers/st/stm32mp25_rcc.h>
+#ifndef __ASSEMBLER__
+#include <drivers/st/stm32mp2_clk.h>
+#endif
+#include <drivers/st/stm32mp2_pwr.h>
 #include <dt-bindings/clock/stm32mp25-clks.h>
 #include <dt-bindings/clock/stm32mp25-clksrc.h>
 #include <dt-bindings/gpio/stm32-gpio.h>
@@ -26,12 +30,52 @@
 #endif
 
 /*******************************************************************************
+ * CHIP ID
+ ******************************************************************************/
+#define STM32MP2_CHIP_ID			U(0x505)
+
+#define STM32MP251A_PART_NB			U(0x400B3E6D)
+#define STM32MP251C_PART_NB			U(0x000B306D)
+#define STM32MP251D_PART_NB			U(0xC00B3E6D)
+#define STM32MP251F_PART_NB			U(0x800B306D)
+#define STM32MP253A_PART_NB			U(0x400B3E0C)
+#define STM32MP253C_PART_NB			U(0x000B300C)
+#define STM32MP253D_PART_NB			U(0xC00B3E0C)
+#define STM32MP253F_PART_NB			U(0x800B300C)
+#define STM32MP255A_PART_NB			U(0x40082E00)
+#define STM32MP255C_PART_NB			U(0x00082000)
+#define STM32MP255D_PART_NB			U(0xC0082E00)
+#define STM32MP255F_PART_NB			U(0x80082000)
+#define STM32MP257A_PART_NB			U(0x40002E00)
+#define STM32MP257C_PART_NB			U(0x00002000)
+#define STM32MP257D_PART_NB			U(0xC0002E00)
+#define STM32MP257F_PART_NB			U(0x80002000)
+
+#define STM32MP2_REV_A				U(0x08)
+#define STM32MP2_REV_B				U(0x10)
+#define STM32MP2_REV_X				U(0x12)
+#define STM32MP2_REV_Y				U(0x11)
+#define STM32MP2_REV_Z				U(0x09)
+
+/*******************************************************************************
+ * PACKAGE ID
+ ******************************************************************************/
+#define STM32MP25_PKG_CUSTOM			U(0)
+#define STM32MP25_PKG_AL_VFBGA361		U(1)
+#define STM32MP25_PKG_AK_VFBGA424		U(3)
+#define STM32MP25_PKG_AI_TFBGA436		U(5)
+#define STM32MP25_PKG_UNKNOWN			U(7)
+
+/*******************************************************************************
  * STM32MP2 memory map related constants
  ******************************************************************************/
 #define STM32MP_SYSRAM_BASE			U(0x0E000000)
 #define STM32MP_SYSRAM_SIZE			U(0x00040000)
+#define SRAM1_BASE				U(0x0E040000)
+#define SRAM1_SIZE_FOR_TFA			U(0x00010000)
+#define RETRAM_BASE				U(0x0E080000)
+#define RETRAM_SIZE				U(0x00020000)
 
-#define STM32MP_SEC_SYSRAM_BASE			STM32MP_SYSRAM_BASE
 #define STM32MP_SEC_SYSRAM_SIZE			STM32MP_SYSRAM_SIZE
 
 /* DDR configuration */
@@ -49,28 +93,44 @@
 
 /* Section used inside TF binaries */
 #define STM32MP_PARAM_LOAD_SIZE			U(0x00002400) /* 9 KB for param */
-/* 512 Octets reserved for header */
+/* 512 Bytes reserved for header */
 #define STM32MP_HEADER_SIZE			U(0x00000200)
-#define STM32MP_HEADER_BASE			(STM32MP_SEC_SYSRAM_BASE +	\
+#define STM32MP_HEADER_BASE			(STM32MP_SYSRAM_BASE +	\
 						 STM32MP_PARAM_LOAD_SIZE)
 
 /* round_up(STM32MP_PARAM_LOAD_SIZE + STM32MP_HEADER_SIZE, PAGE_SIZE) */
 #define STM32MP_HEADER_RESERVED_SIZE		U(0x3000)
 
-#define STM32MP_BINARY_BASE			(STM32MP_SEC_SYSRAM_BASE +	\
+#define STM32MP_BINARY_BASE			(STM32MP_SYSRAM_BASE +	\
 						 STM32MP_PARAM_LOAD_SIZE +	\
 						 STM32MP_HEADER_SIZE)
 
-#define STM32MP_BINARY_SIZE			(STM32MP_SEC_SYSRAM_SIZE -	\
+#define STM32MP_BINARY_SIZE			(STM32MP_SYSRAM_SIZE -	\
 						 (STM32MP_PARAM_LOAD_SIZE +	\
 						  STM32MP_HEADER_SIZE))
 
-#define STM32MP_BL2_SIZE			U(0x0002A000) /* 168 KB for BL2 */
+#define STM32MP_BL2_RO_SIZE			U(0x00020000) /* 128 KB */
+#define STM32MP_BL2_SIZE			U(0x00029000) /* 164 KB for BL2 */
 
-#define STM32MP_BL2_BASE			(STM32MP_SEC_SYSRAM_BASE + \
-						 STM32MP_SEC_SYSRAM_SIZE - \
+/* Allocate remaining sysram to BL31 Binary only */
+#define STM32MP_BL31_SIZE			(STM32MP_SEC_SYSRAM_SIZE - \
 						 STM32MP_BL2_SIZE)
 
+#define BL31_PROGBITS_LIMIT			STM32MP_BL31_SIZE
+
+#define STM32MP_BL2_BASE			(STM32MP_SYSRAM_BASE + \
+						 STM32MP_SYSRAM_SIZE - \
+						 STM32MP_BL2_SIZE)
+
+#define STM32MP_BL2_RO_BASE			STM32MP_BL2_BASE
+
+#define STM32MP_BL2_RW_BASE			(STM32MP_BL2_RO_BASE + \
+						 STM32MP_BL2_RO_SIZE)
+
+#define STM32MP_BL2_RW_SIZE			(STM32MP_SYSRAM_BASE + \
+						 STM32MP_SYSRAM_SIZE - \
+						 STM32MP_BL2_RW_BASE)
+
 /* BL2 and BL32/sp_min require 4 tables */
 #define MAX_XLAT_TABLES				U(4)	/* 16 KB for mapping */
 
@@ -81,15 +141,39 @@
 #define MAX_MMAP_REGIONS			6
 
 /* DTB initialization value */
-#define STM32MP_BL2_DTB_SIZE			U(0x00005000) /* 20 KB for DTB */
+#define STM32MP_BL2_DTB_SIZE			U(0x00006000)	/* 24 KB for DTB */
 
 #define STM32MP_BL2_DTB_BASE			(STM32MP_BL2_BASE - \
 						 STM32MP_BL2_DTB_SIZE)
 
+#if defined(IMAGE_BL2)
+#define STM32MP_DTB_SIZE			STM32MP_BL2_DTB_SIZE
+#define STM32MP_DTB_BASE			STM32MP_BL2_DTB_BASE
+#endif
+
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define STM32MP_DDR_FW_BASE			SRAM1_BASE
+#define STM32MP_DDR_FW_DMEM_OFFSET		U(0x400)
+#define STM32MP_DDR_FW_IMEM_OFFSET		U(0x800)
+#define STM32MP_DDR_FW_MAX_SIZE			U(0x8800)
+#endif
+
+#define STM32MP_FW_CONFIG_MAX_SIZE		PAGE_SIZE
+#define STM32MP_FW_CONFIG_BASE			STM32MP_SYSRAM_BASE
+
 #define STM32MP_BL33_BASE			(STM32MP_DDR_BASE + U(0x04000000))
 #define STM32MP_BL33_MAX_SIZE			U(0x400000)
+#define STM32MP_HW_CONFIG_BASE			(STM32MP_BL33_BASE + \
+						STM32MP_BL33_MAX_SIZE)
+#define STM32MP_HW_CONFIG_MAX_SIZE		U(0x40000)
 
 /*******************************************************************************
+ * STM32MP2 device/io map related constants (used for MMU)
+ ******************************************************************************/
+#define STM32MP_DEVICE_BASE			U(0x40000000)
+#define STM32MP_DEVICE_SIZE			U(0x40000000)
+
+/*******************************************************************************
  * STM32MP2 RCC
  ******************************************************************************/
 #define RCC_BASE				U(0x44200000)
@@ -172,6 +256,7 @@
 
 /* OTP labels */
 #define PART_NUMBER_OTP				"part-number-otp"
+#define REVISION_OTP				"rev_otp"
 #define PACKAGE_OTP				"package-otp"
 #define HCONF1_OTP				"otp124"
 #define NAND_OTP				"otp16"
@@ -293,6 +378,17 @@
 #define SYSCFG_BASE				U(0x44230000)
 
 /*******************************************************************************
+ * STM32MP RIF
+ ******************************************************************************/
+#define RISAB3_BASE				U(0x42110000)
+#define RISAB5_BASE				U(0x42130000)
+
+/*******************************************************************************
+ * STM32MP CA35SSC
+ ******************************************************************************/
+#define A35SSC_BASE				U(0x48800000)
+
+/*******************************************************************************
  * REGULATORS
  ******************************************************************************/
 /* 3 PWR + 1 VREFBUF + 14 PMIC regulators + 1 FIXED */
@@ -309,6 +405,7 @@
 #define DT_DDR_COMPAT				"st,stm32mp2-ddr"
 #define DT_PWR_COMPAT				"st,stm32mp25-pwr"
 #define DT_RCC_CLK_COMPAT			"st,stm32mp25-rcc"
+#define DT_SDMMC2_COMPAT			"st,stm32mp25-sdmmc2"
 #define DT_UART_COMPAT				"st,stm32h7-uart"
 
 #endif /* STM32MP2_DEF_H */
diff --git a/plat/st/stm32mp2/stm32mp2_pm.c b/plat/st/stm32mp2/stm32mp2_pm.c
new file mode 100644
index 0000000..5bb381d
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_pm.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+static uintptr_t stm32_sec_entrypoint;
+
+static void stm32_cpu_standby(plat_local_state_t cpu_state)
+{
+}
+
+static int stm32_pwr_domain_on(u_register_t mpidr)
+{
+	return PSCI_E_INTERN_FAIL;
+}
+
+static void stm32_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	/* Nothing to do */
+}
+
+static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	/* Nothing to do, power domain is not disabled */
+}
+
+static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+}
+
+/*******************************************************************************
+ * STM32MP2 handler called when a power domain has just been powered on after
+ * having been suspended earlier. The target_state encodes the low power state
+ * that each level has woken up from.
+ ******************************************************************************/
+static void stm32_pwr_domain_suspend_finish(const psci_power_state_t
+					    *target_state)
+{
+	/* Nothing to do, power domain is not disabled */
+}
+
+static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t
+						  *target_state)
+{
+	ERROR("stm32mp2 Power Down WFI: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 stm32_system_off(void)
+{
+	ERROR("stm32mp2 System Off: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 stm32_system_reset(void)
+{
+	stm32mp_system_reset();
+}
+
+static int stm32_validate_power_state(unsigned int power_state,
+				      psci_power_state_t *req_state)
+{
+	return PSCI_E_INVALID_PARAMS;
+}
+
+static int stm32_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/* The non-secure entry point must be in DDR */
+	if (entrypoint < STM32MP_DDR_BASE) {
+		return PSCI_E_INVALID_ADDRESS;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+static void stm32_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+}
+
+/*******************************************************************************
+ * Export the platform handlers. The ARM Standard platform layer will take care
+ * of registering the handlers with PSCI.
+ ******************************************************************************/
+static const plat_psci_ops_t stm32_psci_ops = {
+	.cpu_standby = stm32_cpu_standby,
+	.pwr_domain_on = stm32_pwr_domain_on,
+	.pwr_domain_off = stm32_pwr_domain_off,
+	.pwr_domain_suspend = stm32_pwr_domain_suspend,
+	.pwr_domain_on_finish = stm32_pwr_domain_on_finish,
+	.pwr_domain_suspend_finish = stm32_pwr_domain_suspend_finish,
+	.pwr_domain_pwr_down_wfi = stm32_pwr_domain_pwr_down_wfi,
+	.system_off = stm32_system_off,
+	.system_reset = stm32_system_reset,
+	.validate_power_state = stm32_validate_power_state,
+	.validate_ns_entrypoint = stm32_validate_ns_entrypoint,
+	.get_sys_suspend_power_state = stm32_get_sys_suspend_power_state,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	stm32_sec_entrypoint = sec_entrypoint;
+	*psci_ops = &stm32_psci_ops;
+
+	return 0;
+}
diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c
new file mode 100644
index 0000000..7ad974f
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_private.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <platform_def.h>
+
+#define BKPR_BOOT_MODE	96U
+
+#if defined(IMAGE_BL31)
+/* BL31 only uses the first half of the SYSRAM */
+#define MAP_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
+					STM32MP_SYSRAM_SIZE / 2U, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+#else
+#define MAP_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
+					STM32MP_SYSRAM_SIZE, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+#endif
+
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define MAP_SRAM1	MAP_REGION_FLAT(SRAM1_BASE, \
+					SRAM1_SIZE_FOR_TFA, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+#endif
+
+#define MAP_DEVICE	MAP_REGION_FLAT(STM32MP_DEVICE_BASE, \
+					STM32MP_DEVICE_SIZE, \
+					MT_DEVICE | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+
+#if defined(IMAGE_BL2)
+static const mmap_region_t stm32mp2_mmap[] = {
+	MAP_SYSRAM,
+#if STM32MP_DDR_FIP_IO_STORAGE
+	MAP_SRAM1,
+#endif
+	MAP_DEVICE,
+	{0}
+};
+#endif
+#if defined(IMAGE_BL31)
+static const mmap_region_t stm32mp2_mmap[] = {
+	MAP_SYSRAM,
+	MAP_DEVICE,
+	{0}
+};
+#endif
+
+void configure_mmu(void)
+{
+	mmap_add(stm32mp2_mmap);
+	init_xlat_tables();
+
+	enable_mmu_el3(0);
+}
+
+int stm32mp_map_retram(void)
+{
+	return  mmap_add_dynamic_region(RETRAM_BASE, RETRAM_BASE,
+					RETRAM_SIZE,
+					MT_RW | MT_SECURE);
+}
+
+int stm32mp_unmap_retram(void)
+{
+	return  mmap_remove_dynamic_region(RETRAM_BASE,
+					   RETRAM_SIZE);
+}
+
+uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
+{
+	if (bank == GPIO_BANK_Z) {
+		return GPIOZ_BASE;
+	}
+
+	assert(bank <= GPIO_BANK_K);
+
+	return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
+}
+
+uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
+{
+	if (bank == GPIO_BANK_Z) {
+		return 0;
+	}
+
+	assert(bank <= GPIO_BANK_K);
+
+	return bank * GPIO_BANK_OFFSET;
+}
+
+unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
+{
+	if (bank == GPIO_BANK_Z) {
+		return CK_BUS_GPIOZ;
+	}
+
+	assert(bank <= GPIO_BANK_K);
+
+	return CK_BUS_GPIOA + (bank - GPIO_BANK_A);
+}
+
+uint32_t stm32mp_get_chip_version(void)
+{
+	static uint32_t rev;
+
+	if (rev != 0U) {
+		return rev;
+	}
+
+	if (stm32_get_otp_value(REVISION_OTP, &rev) != 0) {
+		panic();
+	}
+
+	return rev;
+}
+
+uint32_t stm32mp_get_chip_dev_id(void)
+{
+	return stm32mp_syscfg_get_chip_dev_id();
+}
+
+static uint32_t get_part_number(void)
+{
+	static uint32_t part_number;
+
+	if (part_number != 0U) {
+		return part_number;
+	}
+
+	if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
+		panic();
+	}
+
+	return part_number;
+}
+
+static uint32_t get_cpu_package(void)
+{
+	static uint32_t package = UINT32_MAX;
+
+	if (package == UINT32_MAX) {
+		if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
+			panic();
+		}
+	}
+
+	return (package & PACKAGE_OTP_PKG_MASK) >> PACKAGE_OTP_PKG_SHIFT;
+}
+
+void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
+{
+	char *cpu_s, *cpu_r, *pkg;
+
+	/* MPUs Part Numbers */
+	switch (get_part_number()) {
+	case STM32MP251A_PART_NB:
+		cpu_s = "251A";
+		break;
+	case STM32MP251C_PART_NB:
+		cpu_s = "251C";
+		break;
+	case STM32MP251D_PART_NB:
+		cpu_s = "251D";
+		break;
+	case STM32MP251F_PART_NB:
+		cpu_s = "251F";
+		break;
+	case STM32MP253A_PART_NB:
+		cpu_s = "253A";
+		break;
+	case STM32MP253C_PART_NB:
+		cpu_s = "253C";
+		break;
+	case STM32MP253D_PART_NB:
+		cpu_s = "253D";
+		break;
+	case STM32MP253F_PART_NB:
+		cpu_s = "253F";
+		break;
+	case STM32MP255A_PART_NB:
+		cpu_s = "255A";
+		break;
+	case STM32MP255C_PART_NB:
+		cpu_s = "255C";
+		break;
+	case STM32MP255D_PART_NB:
+		cpu_s = "255D";
+		break;
+	case STM32MP255F_PART_NB:
+		cpu_s = "255F";
+		break;
+	case STM32MP257A_PART_NB:
+		cpu_s = "257A";
+		break;
+	case STM32MP257C_PART_NB:
+		cpu_s = "257C";
+		break;
+	case STM32MP257D_PART_NB:
+		cpu_s = "257D";
+		break;
+	case STM32MP257F_PART_NB:
+		cpu_s = "257F";
+		break;
+	default:
+		cpu_s = "????";
+		break;
+	}
+
+	/* Package */
+	switch (get_cpu_package()) {
+	case STM32MP25_PKG_CUSTOM:
+		pkg = "XX";
+		break;
+	case STM32MP25_PKG_AL_VFBGA361:
+		pkg = "AL";
+		break;
+	case STM32MP25_PKG_AK_VFBGA424:
+		pkg = "AK";
+		break;
+	case STM32MP25_PKG_AI_TFBGA436:
+		pkg = "AI";
+		break;
+	default:
+		pkg = "??";
+		break;
+	}
+
+	/* REVISION */
+	switch (stm32mp_get_chip_version()) {
+	case STM32MP2_REV_A:
+		cpu_r = "A";
+		break;
+	case STM32MP2_REV_B:
+		cpu_r = "B";
+		break;
+	case STM32MP2_REV_X:
+		cpu_r = "X";
+		break;
+	case STM32MP2_REV_Y:
+		cpu_r = "Y";
+		break;
+	case STM32MP2_REV_Z:
+		cpu_r = "Z";
+		break;
+	default:
+		cpu_r = "?";
+		break;
+	}
+
+	snprintf(name, STM32_SOC_NAME_SIZE,
+		 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
+}
+
+void stm32mp_print_cpuinfo(void)
+{
+	char name[STM32_SOC_NAME_SIZE];
+
+	stm32mp_get_soc_name(name);
+	NOTICE("CPU: %s\n", name);
+}
+
+void stm32mp_print_boardinfo(void)
+{
+	uint32_t board_id = 0U;
+
+	if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
+		return;
+	}
+
+	if (board_id != 0U) {
+		stm32_display_board_info(board_id);
+	}
+}
+
+bool stm32mp_is_wakeup_from_standby(void)
+{
+	/* TODO add source code to determine if platform is waking up from standby mode */
+	return false;
+}
+
+uintptr_t stm32_get_bkpr_boot_mode_addr(void)
+{
+	return tamp_bkpr(BKPR_BOOT_MODE);
+}
+
+uintptr_t stm32_ddrdbg_get_base(void)
+{
+	return DDRDBG_BASE;
+}
diff --git a/plat/st/stm32mp2/stm32mp2_syscfg.c b/plat/st/stm32mp2/stm32mp2_syscfg.c
new file mode 100644
index 0000000..46c75a6
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_syscfg.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+#include <stm32mp2_private.h>
+
+/*
+ * SYSCFG register offsets (base relative)
+ */
+#define SYSCFG_DEVICEID			0x6400U
+
+/*
+ * SYSCFG_DEVICEID Register
+ */
+#define SYSCFG_DEVICEID_DEV_ID_MASK	GENMASK_32(11, 0)
+
+/*
+ * @brief  Get device ID from SYSCFG registers.
+ * @retval device ID (DEV_ID).
+ */
+uint32_t stm32mp_syscfg_get_chip_dev_id(void)
+{
+	return mmio_read_32(SYSCFG_BASE + SYSCFG_DEVICEID) & SYSCFG_DEVICEID_DEV_ID_MASK;
+}
diff --git a/plat/st/stm32mp2/stm32mp2_topology.c b/plat/st/stm32mp2/stm32mp2_topology.c
new file mode 100644
index 0000000..cc2d58c
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_topology.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/* 1 cluster, all cores into */
+static const unsigned char stm32mp2_power_domain_tree_desc[] = {
+	PLATFORM_CLUSTER_COUNT,
+	PLATFORM_CORE_COUNT,
+};
+
+/* This function returns the platform topology */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return stm32mp2_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.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+	u_register_t mpidr_copy = mpidr;
+
+	mpidr_copy &= MPIDR_AFFINITY_MASK;
+
+	if ((mpidr_copy & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) {
+		return -1;
+	}
+
+	cluster_id = (mpidr_copy >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr_copy >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -1;
+	}
+
+	/*
+	 * 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) {
+		return -1;
+	}
+
+	return (int)cpu_id;
+}
diff --git a/plat/xilinx/common/include/plat_console.h b/plat/xilinx/common/include/plat_console.h
index 0f8320e..fa6021d 100644
--- a/plat/xilinx/common/include/plat_console.h
+++ b/plat/xilinx/common/include/plat_console.h
@@ -8,18 +8,30 @@
 #define PLAT_DT_UART_H
 
 #define DT_UART_DCC_COMPAT	"arm,dcc"
+#define DT_UART_CAD_COMPAT	"xlnx,zynqmp-uart"
+#define DT_UART_PL011_COMPAT	"arm,pl011"
 
-#if defined(PLAT_zynqmp)
-#define DT_UART_COMPAT	"xlnx,zynqmp-uart"
-#else
-#define DT_UART_COMPAT	"arm,pl011"
-#endif
+/* Default console type is either CADENCE0 or CADENCE1 or PL011_0 or PL011_1
+ * Debug console type is DCC
+ */
+#define CONSOLE_NONE	0
+#define CONSOLE_CDNS	1
+#define CONSOLE_PL011   2
+#define CONSOLE_DCC	3
+
+typedef struct console_hd {
+	uint32_t clk;
+	uint32_t baud_rate;
+	uintptr_t base;
+	uint32_t console_scope;
+	uint8_t console_type;
+} console_holder;
 
 typedef struct dt_uart_info_s {
 	char compatible[30];
 	uintptr_t base;
 	uint32_t baud_rate;
-	int32_t status;
+	uint8_t console_type;
 } dt_uart_info_t;
 
 void setup_console(void);
diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
index ffee805..029bb43 100644
--- a/plat/xilinx/common/include/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -64,6 +64,7 @@
 					uint32_t wake, uint32_t enable,
 					uint32_t flag);
 enum pm_ret_status pm_get_chipid(uint32_t *value);
+enum pm_ret_status eemi_feature_check(uint32_t api_id, uint32_t *ret_payload);
 
 /*
  * Assigning of argument values into array elements.
@@ -97,4 +98,9 @@
 	PM_PACK_PAYLOAD5(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4));		\
 }
 
+#define PM_PACK_PAYLOAD7(pl, mid, flag, arg0, arg1, arg2, arg3, arg4, arg5, arg6) {	\
+	pl[6] = (uint32_t)(arg6);							\
+	PM_PACK_PAYLOAD6(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4), (arg5));	\
+}
+
 #endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
index c0308ab..68d1db2 100644
--- a/plat/xilinx/common/include/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2018, 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
  */
@@ -24,8 +24,9 @@
 #define CRC_ORDER               16U
 #define CRC_POLYNOM             0x8005U
 #else
-#define PAYLOAD_ARG_CNT         6U
+#define PAYLOAD_ARG_CNT		7U
 #endif
+#define RET_PAYLOAD_ARG_CNT	6U
 #define PAYLOAD_ARG_SIZE	4U	/* size in bytes */
 
 #define TZ_VERSION_MAJOR	1
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index 055fa3d..9920611 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -35,6 +35,7 @@
 				       (uint32_t)XPM_NODESUBCL_DEV_PERIPH, \
 				       (uint32_t)XPM_NODETYPE_DEV_PERIPH, (IDX))
 
+#define TF_A_FEATURE_CHECK		0xa00U
 #define PM_GET_CALLBACK_DATA		0xa01U
 #define PM_GET_TRUSTZONE_VERSION	0xa03U
 #define TF_A_PM_REGISTER_SGI		0xa04U
@@ -95,6 +96,8 @@
 	IOCTL_GET_LAST_RESET_REASON = 23,
 	/* AI engine NPI ISR clear */
 	IOCTL_AIE_ISR_CLEAR = 24,
+	IOCTL_UFS_TXRX_CFGRDY_GET = 40,
+	IOCTL_UFS_SRAM_CSR_SEL = 41,
 };
 
 /**
diff --git a/plat/xilinx/common/include/pm_svc_main.h b/plat/xilinx/common/include/pm_svc_main.h
index 67fbeae..000f198 100644
--- a/plat/xilinx/common/include/pm_svc_main.h
+++ b/plat/xilinx/common/include/pm_svc_main.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
  */
@@ -12,6 +12,8 @@
 
 extern bool pwrdwn_req_received;
 
+#define PASS_THROUGH_FW_CMD_ID	U(0xfff)
+
 /******************************************************************************/
 /**
  * SECURE_REDUNDANT_CALL() - Adds redundancy to the function call. This is to
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index 434cd88..0ea51f0 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -70,6 +70,9 @@
 			 uint64_t x3, uint64_t x4, const void *cookie,
 			 void *handle, uint64_t flags)
 {
+	(void) x4;
+	(void) flags;
+	(void) cookie;
 	int32_t ret;
 	uint32_t ipi_local_id;
 	uint32_t ipi_remote_id;
@@ -103,11 +106,11 @@
 		SMC_RET1(handle, 0);
 	case IPI_MAILBOX_STATUS_ENQUIRY:
 	{
-		int32_t disable_irq;
+		int32_t disable_interrupt;
 
-		disable_irq = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
+		disable_interrupt = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
 		ret = ipi_mb_enquire_status(ipi_local_id, ipi_remote_id);
-		if ((ret & IPI_MB_STATUS_RECV_PENDING) && disable_irq)
+		if ((ret & IPI_MB_STATUS_RECV_PENDING) && disable_interrupt)
 			ipi_mb_disable_irq(ipi_local_id, ipi_remote_id);
 		SMC_RET1(handle, ret);
 	}
@@ -121,11 +124,11 @@
 	}
 	case IPI_MAILBOX_ACK:
 	{
-		int32_t enable_irq;
+		int32_t enable_interrupt;
 
-		enable_irq = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
+		enable_interrupt = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
 		ipi_mb_ack(ipi_local_id, ipi_remote_id);
-		if (enable_irq)
+		if (enable_interrupt)
 			ipi_mb_enable_irq(ipi_local_id, ipi_remote_id);
 		SMC_RET1(handle, 0);
 	}
diff --git a/plat/xilinx/common/plat_console.c b/plat/xilinx/common/plat_console.c
index b84912a..681226f 100644
--- a/plat/xilinx/common/plat_console.c
+++ b/plat/xilinx/common/plat_console.c
@@ -23,9 +23,64 @@
 #include <platform_def.h>
 #include <plat_private.h>
 
-static console_t console;
+#if !(CONSOLE_IS(none))
+static console_t boot_console;
+static console_holder boot_hd_console;
+#if defined(CONSOLE_RUNTIME)
+static console_t runtime_console;
+static console_holder rt_hd_console;
+#endif
+
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
+static dt_uart_info_t dt_uart_info;
+#endif
+
+/**
+ * register_console() - Registers the uart with console list.
+ * @consoleh: Console holder structure with UART base address,
+ *  UART clock, UART buad rate, flags & console type
+ * @console: Pointer to the console information structure.
+ */
+static void register_console(const console_holder *consoleh, console_t *console)
+{
+	int32_t rc = 0;
+
+	switch (consoleh->console_type) {
+#if defined(PLAT_zynqmp)
+	case CONSOLE_CDNS:
+		rc = console_cdns_register(consoleh->base,
+				consoleh->clk,
+				consoleh->baud_rate,
+				console);
+		break;
+#else
+	case CONSOLE_PL011:
+		rc = console_pl011_register(consoleh->base,
+				consoleh->clk,
+				consoleh->baud_rate,
+				console);
+		break;
+#endif
+	case CONSOLE_DCC:
+		rc = console_dcc_register(console);
+		break;
+	default:
+		INFO("Invalid console type\n");
+		break;
+	}
 
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+	if (rc == 0) {
+		panic();
+	}
+
+	console_set_scope(console, consoleh->console_scope);
+}
+
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
 /**
  * get_baudrate() - Get the baudrate form DTB.
  * @dtb: Address of the Device Tree Blob (DTB).
@@ -103,34 +158,56 @@
  * @node: Node address in the device tree.
  * @dtb: Address of the Device Tree Blob(DTB).
  *
- * Return: On success, it returns 1; on failure, it returns an 0.
+ * Return: On success, it returns 0; on failure, it returns -1 or -FDT_ERR_NOTFOUND.
  */
-static uint32_t fdt_add_uart_info(dt_uart_info_t *info, int node, void *dtb)
+static int32_t fdt_add_uart_info(dt_uart_info_t *info, int node, void *dtb)
 {
 	uintptr_t base_addr;
 	const char *com;
 	int32_t ret = 0;
+	uint32_t status;
 
 	com = fdt_getprop(dtb, node, "compatible", NULL);
 	if (com != NULL) {
 		strlcpy(info->compatible, com, sizeof(info->compatible));
 	} else {
 		ERROR("Compatible property not found in DTB node\n");
-		ret  = -FDT_ERR_NOTFOUND;
+		ret = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
-	ret = fdt_get_reg_props_by_index(dtb, node, 0, &base_addr, NULL);
-	if (ret >= 0) {
-		info->base = base_addr;
-	} else {
-		ERROR("Failed to retrieve base address. Error code: %d\n", ret);
-		ret  = -FDT_ERR_NOTFOUND;
+	status = get_node_status(dtb, node);
+	if (status == 0) {
+		ERROR("Uart node is disabled in DTB\n");
+		ret = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
+	if (strncmp(info->compatible, DT_UART_DCC_COMPAT, strlen(DT_UART_DCC_COMPAT)) != 0) {
+		ret = fdt_get_reg_props_by_index(dtb, node, 0, &base_addr, NULL);
+		if (ret >= 0) {
+			info->base = base_addr;
+		} else {
+			ERROR("Failed to retrieve base address. Error code: %d\n", ret);
+			ret = -FDT_ERR_NOTFOUND;
+			goto error;
+		}
+
-	info->status = get_node_status(dtb, node);
-	info->baud_rate = get_baudrate(dtb);
+		info->baud_rate = get_baudrate(dtb);
+
+		if (strncmp(info->compatible, DT_UART_CAD_COMPAT,
+					strlen(DT_UART_CAD_COMPAT)) == 0) {
+			info->console_type = CONSOLE_CDNS;
+		} else if (strncmp(info->compatible, DT_UART_PL011_COMPAT,
+					strlen(DT_UART_PL011_COMPAT)) == 0) {
+			info->console_type = CONSOLE_PL011;
+		} else {
+			ERROR("Incompatible uart node in DTB\n");
+			ret = -FDT_ERR_NOTFOUND;
+		}
+	} else {
+		info->console_type = CONSOLE_DCC;
+	}
 
 error:
 	return ret;
@@ -150,194 +227,87 @@
 	ret = is_valid_dtb(dtb);
 	if (ret < 0) {
 		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
-		ret  = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
 	node = fdt_get_stdout_node_offset(dtb);
 	if (node < 0) {
 		ERROR("DT get stdout node failed : %d\n", node);
-		ret  = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
 	ret = fdt_add_uart_info(info, node, dtb);
 	if (ret < 0) {
 		ERROR("Failed to add DT UART info: %d\n", ret);
-		ret  = -FDT_ERR_NOTFOUND;
-		goto error;
-	}
-
-error:
-	return ret;
-}
-
-/**
- * check_fdt_uart_info() - Check early uart info with DTB uart info.
- * @info: Pointer to the UART information structure.
- *
- * Return: On success, it returns 0; on failure, it returns an error+reason.
- */
-static int32_t check_fdt_uart_info(dt_uart_info_t *info)
-{
-	int32_t ret = 0;
-
-	if (info->status == 0) {
-		ret = -ENODEV;
-		goto error;
-	}
-
-	if ((info->base == console.base) &&
-	   (info->baud_rate == UART_BAUDRATE) && !CONSOLE_IS(dcc)) {
-		ret = -ENODEV;
 		goto error;
 	}
 
 error:
 	return ret;
 }
-
-/**
- * console_boot_end() - Unregister the console_t instance form the console list.
- * @boot_console: Pointer to the console information structure.
- */
-static void console_boot_end(console_t *boot_console)
-{
-	if (CONSOLE_IS(dcc)) {
-		console_dcc_unregister();
-	} else {
-		console_flush();
-		(void)console_unregister(boot_console);
-	}
-}
-
-/**
- * setup_runtime_console() - Registers the runtime uart with console list.
- * @clock: UART clock.
- * @info: Pointer to the UART information structure.
- */
-static void setup_runtime_console(uint32_t clock, dt_uart_info_t *info)
-{
-	static console_t bl31_runtime_console;
-	int32_t rc;
-
-#if defined(PLAT_zynqmp)
-	rc = console_cdns_register(info->base,
-				   clock,
-				   info->baud_rate,
-				   &bl31_runtime_console);
-#else
-	rc = console_pl011_register(info->base,
-				    clock,
-				    info->baud_rate,
-				    &bl31_runtime_console);
 #endif
-	if (rc == 0) {
-		panic();
-	}
-
-	console_set_scope(&bl31_runtime_console,
-			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME |
-			  CONSOLE_FLAG_CRASH);
-}
 
-
-/**
- * runtime_console_init() - Initializes the run time console information.
- * @uart_info: Pointer to the UART information structure.
- * @bl31_boot_console: Pointer to the console information structure.
- * @clock: UART clock.
- *
- * Return: On success, it returns 0; on failure, it returns an error+reason;
- */
-static int32_t runtime_console_init(dt_uart_info_t *uart_info,
-			  console_t *bl31_boot_console,
-			  uint32_t clock)
+void setup_console(void)
 {
-	int32_t rc = 0;
+	/* This is hardcoded console setup just in case that DTB console fails */
+	boot_hd_console.base = (uintptr_t)UART_BASE;
+	boot_hd_console.baud_rate = (uint32_t)UART_BAUDRATE;
+	boot_hd_console.clk = get_uart_clk();
+	boot_hd_console.console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH;
+	boot_hd_console.console_type = UART_TYPE;
 
-	/* Parse UART information from Device Tree Blob (DTB) */
-	rc = fdt_get_uart_info(uart_info);
-	if (rc < 0) {
-		rc = -FDT_ERR_NOTFOUND;
-		goto error;
-	}
+	/* For DT code decoding uncomment console registration below */
+	/* register_console(&boot_hd_console, &boot_console); */
 
-	if (strncmp(uart_info->compatible, DT_UART_COMPAT,
-		   strlen(DT_UART_COMPAT)) == 0) {
-
-		if (check_fdt_uart_info(uart_info) == 0) {
-			setup_runtime_console(clock, uart_info);
-			console_boot_end(bl31_boot_console);
-			INFO("Runtime console setup\n");
-		} else {
-			INFO("Early console and DTB console are same\n");
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
+	/* Parse DTB console for UART information  */
+	if (fdt_get_uart_info(&dt_uart_info) == 0) {
+		if (CONSOLE_IS(dtb)) {
+			boot_hd_console.base = dt_uart_info.base;
+			boot_hd_console.baud_rate = dt_uart_info.baud_rate;
+			boot_hd_console.console_type = dt_uart_info.console_type;
 		}
-	} else if (strncmp(uart_info->compatible, DT_UART_DCC_COMPAT,
-			  strlen(DT_UART_DCC_COMPAT)) == 0) {
-		rc = console_dcc_register();
-		if (rc == 0) {
-			panic();
-		}
-		console_boot_end(bl31_boot_console);
 	} else {
-		WARN("BL31: No console device found in DT.\n");
+		ERROR("Failed to initialize DT console or console node is disabled\n");
 	}
-
-error:
-	return rc;
-}
 #endif
 
-void setup_console(void)
-{
-	int32_t rc;
-	uint32_t uart_clk = get_uart_clk();
+	/* Initialize the boot console */
+	register_console(&boot_hd_console, &boot_console);
 
-#if defined(PLAT_zynqmp)
-	if (CONSOLE_IS(cadence) || (CONSOLE_IS(cadence1))) {
-		rc = console_cdns_register(UART_BASE,
-					   uart_clk,
-					   UART_BAUDRATE,
-					   &console);
-		if (rc == 0) {
-			panic();
-		}
+	INFO("BL31: Early console setup\n");
 
-		console_set_scope(&console, CONSOLE_FLAG_BOOT |
-				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	}
+#ifdef CONSOLE_RUNTIME
+#if (RT_CONSOLE_IS(dtb) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	       (!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+					!IS_TFA_IN_OCM(BL31_BASE)))
+	rt_hd_console.base = dt_uart_info.base;
+	rt_hd_console.baud_rate = dt_uart_info.baud_rate;
+	rt_hd_console.console_type = dt_uart_info.console_type;
 #else
-	if (CONSOLE_IS(pl011) || (CONSOLE_IS(pl011_1))) {
-		/* Initialize the console to provide early debug support */
-		rc = console_pl011_register((uint32_t)UART_BASE,
-					   uart_clk,
-					   (uint32_t)UART_BAUDRATE,
-					   &console);
-		if (rc == 0) {
-			panic();
-		}
-
-		console_set_scope(&console, CONSOLE_FLAG_BOOT |
-				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	}
+	rt_hd_console.base = (uintptr_t)RT_UART_BASE;
+	rt_hd_console.baud_rate = (uint32_t)UART_BAUDRATE;
+	rt_hd_console.console_type = RT_UART_TYPE;
 #endif
-	if (CONSOLE_IS(dcc)) {
-		/* Initialize the dcc console for debug */
-		rc = console_dcc_register();
-		if (rc == 0) {
-			panic();
-		}
-	}
-	INFO("BL31: Early console setup\n");
 
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
-	static dt_uart_info_t uart_info = {0};
+	if ((rt_hd_console.console_type == boot_hd_console.console_type) &&
+			(rt_hd_console.base == boot_hd_console.base)) {
+		console_set_scope(&boot_console,
+				CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH | CONSOLE_FLAG_RUNTIME);
+		INFO("Successfully initialized runtime console\n");
+	} else {
+		rt_hd_console.clk = get_uart_clk();
+		rt_hd_console.console_scope = CONSOLE_FLAG_RUNTIME;
 
-	/* Initialize the runtime console using UART information from the DTB */
-	rc = runtime_console_init(&uart_info, &console, uart_clk);
-	if (rc < 0) {
-		ERROR("Failed to initialize runtime console: %d\n", rc);
+		register_console(&rt_hd_console, &runtime_console);
+		INFO("Successfully initialized new runtime console\n");
 	}
 #endif
 }
+#else
+void setup_console(void)
+{
+}
+#endif
diff --git a/plat/xilinx/common/plat_fdt.c b/plat/xilinx/common/plat_fdt.c
index ebcc31b..4ad7b2d 100644
--- a/plat/xilinx/common/plat_fdt.c
+++ b/plat/xilinx/common/plat_fdt.c
@@ -86,6 +86,18 @@
 }
 #endif
 
+#if defined(XILINX_OF_BOARD_DTB_ADDR)
+static int check_fdt_reserved_memory(void *dtb, const char *node_name)
+{
+	int offset = fdt_path_offset(dtb, "/reserved-memory");
+
+	if (offset >= 0) {
+		offset = fdt_subnode_offset(dtb, offset, node_name);
+	}
+	return offset;
+}
+#endif
+
 void prepare_dtb(void)
 {
 #if defined(XILINX_OF_BOARD_DTB_ADDR)
@@ -112,12 +124,19 @@
 					WARN("Failed to add PSCI cpu enable methods in DT\n");
 				}
 
-				/* Reserve memory used by Trusted Firmware. */
-				ret = fdt_add_reserved_memory(dtb, "tf-a",
-							      BL31_BASE,
-							      BL31_LIMIT - BL31_BASE);
+				/* Check reserved memory set in DT*/
+				ret = check_fdt_reserved_memory(dtb, "tf-a");
 				if (ret < 0) {
-					WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
+					/* Reserve memory used by Trusted Firmware. */
+					ret = fdt_add_reserved_memory(dtb, "tf-a",
+							BL31_BASE,
+							BL31_LIMIT - BL31_BASE);
+					if (ret < 0) {
+						WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
+					}
+
+				} else {
+					WARN("Reserved memory pre-exists in DT.\n");
 				}
 
 				ret = fdt_pack(dtb);
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index 0a6e810..e9c5f13 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -122,7 +122,7 @@
 	}
 
 	PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
-	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
+	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, RET_PAYLOAD_ARG_CNT);
 }
 
 /**
@@ -364,6 +364,37 @@
 }
 
 /**
+ * eemi_feature_check() - Returns the supported API version if supported.
+ * @api_id: API ID to check.
+ * @ret_payload: pointer to array of PAYLOAD_ARG_CNT number of
+ *               words Returned supported API version
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status eemi_feature_check(uint32_t api_id, uint32_t *ret_payload)
+{
+	enum pm_ret_status ret;
+
+	/* Return version of API which are implemented in TF-A only */
+	switch (api_id) {
+	case PM_GET_CALLBACK_DATA:
+	case PM_GET_TRUSTZONE_VERSION:
+		ret_payload[0] = PM_API_VERSION_2;
+		ret = PM_RET_SUCCESS;
+		break;
+	case TF_A_PM_REGISTER_SGI:
+	case TF_A_FEATURE_CHECK:
+		ret_payload[0] = PM_API_BASE_VERSION;
+		ret = PM_RET_SUCCESS;
+		break;
+	default:
+		ret = PM_RET_ERROR_NO_FEATURE;
+	}
+
+	return ret;
+}
+
+/**
  * pm_feature_check() - Returns the supported API version if supported.
  * @api_id: API ID to check.
  * @flag: 0 - Call from secure source.
@@ -406,7 +437,7 @@
 
 	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
 			 PM_FEATURE_CHECK, api_id);
-	return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
+	return pm_ipi_send_sync(primary_proc, payload, ret_payload, RET_PAYLOAD_ARG_CNT);
 }
 
 /**
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 56567dd..425fdcb 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
  * 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
  */
@@ -169,9 +169,7 @@
 	size_t i;
 	enum pm_ret_status ret;
 #if IPI_CRC_CHECK
-	uint32_t *payload_ptr = value;
-	size_t j;
-	uint32_t response_payload[PAYLOAD_ARG_CNT];
+	uint32_t crc;
 #endif
 	uintptr_t buffer_base = proc->ipi->buffer_base +
 				IPI_BUFFER_TARGET_REMOTE_OFFSET +
@@ -184,27 +182,20 @@
 	 * buf-2: unused
 	 * buf-3: unused
 	 */
-	for (i = 1; i <= count; i++) {
-		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
-		value++;
+	for (i = 0U; i < count; i++) {
+		value[i] = mmio_read_32(buffer_base + ((i + 1U) * PAYLOAD_ARG_SIZE));
 	}
 
 	ret = mmio_read_32(buffer_base);
 #if IPI_CRC_CHECK
-	for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
-		response_payload[j] = mmio_read_32(buffer_base +
-						(j * PAYLOAD_ARG_SIZE));
-	}
-
-	if (response_payload[PAYLOAD_CRC_POS] !=
-			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
-		NOTICE("ERROR in CRC response payload value:0x%x\n",
-					response_payload[PAYLOAD_CRC_POS]);
+	crc = mmio_read_32(buffer_base + (PAYLOAD_CRC_POS * PAYLOAD_ARG_SIZE));
+	if (crc != calculate_crc((uint32_t *)buffer_base, IPI_W0_TO_W6_SIZE)) {
+		NOTICE("ERROR in CRC response payload value:0x%x\n", crc);
 		ret = PM_RET_ERROR_INVALID_CRC;
 		/* Payload data is invalid as CRC validation failed
 		 * Clear the payload to avoid leakage of data to upper layers
 		 */
-		memset(payload_ptr, 0, count);
+		memset(value, 0, count);
 	}
 #endif
 
@@ -227,9 +218,7 @@
 {
 	size_t i;
 #if IPI_CRC_CHECK
-	uint32_t *payload_ptr = value;
-	size_t j;
-	unsigned int response_payload[PAYLOAD_ARG_CNT] = {0};
+	uint32_t crc;
 #endif
 	uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE +
 				IPI_BUFFER_TARGET_LOCAL_OFFSET +
@@ -240,25 +229,18 @@
 		count = IPI_BUFFER_MAX_WORDS;
 	}
 
-	for (i = 0; i <= count; i++) {
-		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
-		value++;
+	for (i = 0; i < count; i++) {
+		value[i] = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
 	}
 #if IPI_CRC_CHECK
-	for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
-		response_payload[j] = mmio_read_32(buffer_base +
-						(j * PAYLOAD_ARG_SIZE));
-	}
-
-	if (response_payload[PAYLOAD_CRC_POS] !=
-			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
-		NOTICE("ERROR in CRC response payload value:0x%x\n",
-					response_payload[PAYLOAD_CRC_POS]);
+	crc = mmio_read_32(buffer_base + (PAYLOAD_CRC_POS * PAYLOAD_ARG_SIZE));
+	if (crc != calculate_crc((uint32_t *)buffer_base, IPI_W0_TO_W6_SIZE)) {
+		NOTICE("ERROR in CRC response payload value:0x%x\n", crc);
 		ret = PM_RET_ERROR_INVALID_CRC;
 		/* Payload data is invalid as CRC validation failed
 		 * Clear the payload to avoid leakage of data to upper layers
 		 */
-		memset(payload_ptr, 0, count);
+		memset(value, 0, count);
 	}
 #endif
 	return ret;
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 7ac0ac1..861c5b3 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -36,6 +36,32 @@
 #define EVENT_CPU_PWRDWN	(4U)
 #define MBOX_SGI_SHARED_IPI	(7U)
 
+/**
+ * upper_32_bits - return bits 32-63 of a number
+ * @n: the number we're accessing
+ */
+#define upper_32_bits(n)	((uint32_t)((n) >> 32U))
+
+/**
+ * lower_32_bits - return bits 0-31 of a number
+ * @n: the number we're accessing
+ */
+#define lower_32_bits(n)	((uint32_t)((n) & 0xffffffffU))
+
+/**
+ * EXTRACT_SMC_ARGS - extracts 32-bit payloads from 64-bit SMC arguments
+ * @pm_arg: array of 32-bit payloads
+ * @x: array of 64-bit SMC arguments
+ */
+#define EXTRACT_ARGS(pm_arg, x)						\
+	for (uint32_t i = 0U; i < (PAYLOAD_ARG_CNT - 1U); i++) {	\
+		if ((i % 2U) != 0U) {					\
+			pm_arg[i] = lower_32_bits(x[(i / 2U) + 1U]);	\
+		} else {						\
+			pm_arg[i] = upper_32_bits(x[i / 2U]);		\
+		}							\
+	}
+
 /* 1 sec of wait timeout for secondary core down */
 #define PWRDWN_WAIT_TIMEOUT	(1000U)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r_el1, S3_0_C12_C11_6)
@@ -53,6 +79,10 @@
 static uint64_t cpu_pwrdwn_req_handler(uint32_t id, uint32_t flags,
 				       void *handle, void *cookie)
 {
+	(void)id;
+	(void)flags;
+	(void)handle;
+	(void)cookie;
 	uint32_t cpu_id = plat_my_core_pos();
 
 	VERBOSE("Powering down CPU %d\n", cpu_id);
@@ -97,6 +127,9 @@
 static uint64_t ipi_fiq_handler(uint32_t id, uint32_t flags, void *handle,
 				void *cookie)
 {
+	(void)flags;
+	(void)handle;
+	(void)cookie;
 	uint32_t payload[4] = {0};
 	enum pm_ret_status ret;
 	int ipi_status, i;
@@ -278,7 +311,7 @@
 
 	case (uint32_t)PM_FEATURE_CHECK:
 	{
-		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
+		uint32_t result[RET_PAYLOAD_ARG_CNT] = {0U};
 
 		ret = pm_feature_check(pm_arg[0], result, security_flag);
 		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
@@ -367,6 +400,15 @@
 {
 	switch (api_id) {
 
+	case TF_A_FEATURE_CHECK:
+	{
+		enum pm_ret_status ret;
+		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
+
+		ret = eemi_feature_check(pm_arg[0], result);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U));
+	}
+
 	case TF_A_PM_REGISTER_SGI:
 	{
 		int32_t ret;
@@ -424,7 +466,7 @@
 			      void *handle, uint32_t security_flag)
 {
 	enum pm_ret_status ret;
-	uint32_t buf[PAYLOAD_ARG_CNT] = {0};
+	uint32_t buf[RET_PAYLOAD_ARG_CNT] = {0};
 
 	ret = pm_handle_eemi_call(security_flag, api_id, pm_arg[0], pm_arg[1],
 				  pm_arg[2], pm_arg[3], pm_arg[4],
@@ -449,6 +491,45 @@
 }
 
 /**
+ * eemi_api_handler() - Prepare EEMI payload and perform IPI transaction.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
+ *
+ * EEMI - Embedded Energy Management Interface is AMD-Xilinx proprietary
+ * protocol to allow communication between power management controller and
+ * different processing clusters.
+ *
+ * This handler prepares EEMI protocol payload received from kernel and performs
+ * IPI transaction.
+ *
+ * Return: If EEMI API found then, uintptr_t type address, else 0
+ */
+static uintptr_t eemi_api_handler(uint32_t api_id, const uint32_t *pm_arg,
+				  void *handle, uint32_t security_flag)
+{
+	enum pm_ret_status ret;
+	uint32_t buf[RET_PAYLOAD_ARG_CNT] = {0U};
+	uint32_t payload[PAYLOAD_ARG_CNT] = {0U};
+	uint32_t module_id;
+
+	module_id = (api_id & MODULE_ID_MASK) >> 8U;
+
+	PM_PACK_PAYLOAD7(payload, module_id, security_flag, api_id,
+			 pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
+			 pm_arg[4], pm_arg[5]);
+
+	ret = pm_ipi_send_sync(primary_proc, payload, (uint32_t *)buf,
+			       RET_PAYLOAD_ARG_CNT);
+
+	SMC_RET4(handle, (uint64_t)ret | ((uint64_t)buf[0] << 32U),
+		 (uint64_t)buf[1] | ((uint64_t)buf[2] << 32U),
+		 (uint64_t)buf[3] | ((uint64_t)buf[4] << 32U),
+		 (uint64_t)buf[5]);
+}
+
+/**
  * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
  * @smc_fid: Function Identifier.
  * @x1: SMC64 Arguments from kernel.
@@ -472,11 +553,13 @@
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
 {
+	(void)cookie;
 	uintptr_t ret;
 	uint32_t pm_arg[PAYLOAD_ARG_CNT] = {0};
 	uint32_t security_flag = NON_SECURE_FLAG;
 	uint32_t api_id;
 	bool status = false, status_tmp = false;
+	uint64_t x[4] = {x1, x2, x3, x4};
 
 	/* Handle case where PM wasn't initialized properly */
 	if (pm_up == false) {
@@ -494,6 +577,14 @@
 		security_flag = SECURE_FLAG;
 	}
 
+	if ((smc_fid & FUNCID_NUM_MASK) == PASS_THROUGH_FW_CMD_ID) {
+		api_id = lower_32_bits(x[0]);
+
+		EXTRACT_ARGS(pm_arg, x);
+
+		return eemi_api_handler(api_id, pm_arg, handle, security_flag);
+	}
+
 	pm_arg[0] = (uint32_t)x1;
 	pm_arg[1] = (uint32_t)(x1 >> 32U);
 	pm_arg[2] = (uint32_t)x2;
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index 772477f..4236d8a 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -1,12 +1,11 @@
 /*
  * Copyright (c) 2018-2020, 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
  */
 
 #include <common/debug.h>
-#include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
@@ -18,7 +17,7 @@
 #include <versal_def.h>
 
 uint32_t platform_id, platform_version;
-uint32_t cpu_clock = VERSAL_CPU_CLOCK;
+uint32_t cpu_clock;
 
 /*
  * Table of regions to map using the MMU.
@@ -39,19 +38,10 @@
 	return plat_versal_mmap;
 }
 
-static void versal_print_platform_name(void)
-{
-	NOTICE("TF-A running on %s\n", PLATFORM_NAME);
-}
-
 void versal_config_setup(void)
 {
 	/* Configure IPI data for versal */
 	versal_ipi_config_table_init();
-
-	versal_print_platform_name();
-
-	generic_delay_timer_init();
 }
 
 void board_detection(void)
@@ -68,9 +58,54 @@
 
 	platform_id = FIELD_GET(PLATFORM_MASK, plat_info[1]);
 	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, plat_info[1]);
+
+	if (platform_id == VERSAL_COSIM) {
+		platform_id = VERSAL_QEMU;
+	}
 }
 
+const char *board_name_decode(void)
+{
+	const char *platform;
+
+	switch (platform_id) {
+	case VERSAL_SPP:
+		platform = "IPP";
+		break;
+	case VERSAL_EMU:
+		platform = "EMU";
+		break;
+	case VERSAL_QEMU:
+		platform = "QEMU";
+		break;
+	case VERSAL_SILICON:
+		platform = "SILICON";
+		break;
+	default:
+		platform = "unknown";
+	}
+
+	return platform;
+}
+
 uint32_t get_uart_clk(void)
 {
-	return UART_CLOCK;
+	uint32_t uart_clock;
+
+	switch (platform_id) {
+	case VERSAL_SPP:
+		uart_clock = 25000000;
+		break;
+	case VERSAL_EMU:
+		uart_clock = 212000;
+		break;
+	case VERSAL_QEMU:
+	case VERSAL_SILICON:
+		uart_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+
+	return uart_clock;
 }
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 594784f..58589ad 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2024, Arm Limited and Contributors. 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
  */
@@ -12,6 +12,7 @@
 #include <bl31/bl31.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
@@ -68,27 +69,47 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
+	(void)arg0;
+	(void)arg1;
+	(void)arg2;
+	(void)arg3;
 	uint64_t tfa_handoff_addr;
 	uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE;
 	enum pm_ret_status ret_status;
 	uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
 
-	set_cnt_freq();
-
-	setup_console();
-
-	/* Initialize the platform config for future decision making */
-	versal_config_setup();
-
-	/* Get platform related information */
-	board_detection();
-
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
 	 * Base VERSAL only DRAM security is programmable (via TrustZone), but
 	 * other platforms might have more programmable security devices
 	 * present.
 	 */
+	versal_config_setup();
+
+	/* Initialize the platform config for future decision making */
+	board_detection();
+
+	switch (platform_id) {
+	case VERSAL_SPP:
+		cpu_clock = 2720000;
+		break;
+	case VERSAL_EMU:
+		cpu_clock = 212000;
+		break;
+	case VERSAL_QEMU:
+	case VERSAL_SILICON:
+		cpu_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+	set_cnt_freq();
+
+	generic_delay_timer_init();
+
+	setup_console();
+
+	NOTICE("TF-A running on %s %d\n", board_name_decode(), platform_version);
 
 	/* Populate common information for BL32 and BL33 */
 	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
@@ -154,6 +175,7 @@
 static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
 					  void *handle, void *cookie)
 {
+	(void)id;
 	uint32_t intr_id;
 	uint32_t i;
 	interrupt_type_handler_t handler = NULL;
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index 932c6de..4b2b6cf 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2019, Arm Limited and Contributors. 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
  */
@@ -25,6 +25,8 @@
 extern uint32_t cpu_clock, platform_id, platform_version;
 
 void board_detection(void);
+const char *board_name_decode(void);
+
 void plat_versal_gic_driver_init(void);
 void plat_versal_gic_init(void);
 void plat_versal_gic_cpuif_enable(void);
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index f21d409..3a1c127 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
  * 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
  */
@@ -18,20 +18,30 @@
 /* number of interrupt handlers. increase as required */
 #define MAX_INTR_EL3			2
 /* List all consoles */
+#define VERSAL_CONSOLE_ID_none		0
 #define VERSAL_CONSOLE_ID_pl011	1
 #define VERSAL_CONSOLE_ID_pl011_0	1
 #define VERSAL_CONSOLE_ID_pl011_1	2
 #define VERSAL_CONSOLE_ID_dcc		3
+#define VERSAL_CONSOLE_ID_dtb		4
 
 #define CONSOLE_IS(con)	(VERSAL_CONSOLE_ID_ ## con == VERSAL_CONSOLE)
 
-/* List all supported platforms */
-#define VERSAL_PLATFORM_ID_versal_virt	1
-#define VERSAL_PLATFORM_ID_spp_itr6	2
-#define VERSAL_PLATFORM_ID_emu_itr6	3
-#define VERSAL_PLATFORM_ID_silicon	4
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011	1
+#define RT_CONSOLE_ID_pl011_0	1
+#define RT_CONSOLE_ID_pl011_1	2
+#define RT_CONSOLE_ID_dcc	3
+#define RT_CONSOLE_ID_dtb	4
 
-#define VERSAL_PLATFORM_IS(con)	(VERSAL_PLATFORM_ID_ ## con == VERSAL_PLATFORM)
+#define RT_CONSOLE_IS(con)	(RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
+/* List of platforms */
+#define VERSAL_SILICON              U(0)
+#define VERSAL_SPP                  U(1)
+#define VERSAL_EMU                  U(2)
+#define VERSAL_QEMU                 U(3)
+#define VERSAL_COSIM                U(7)
 
 /* Firmware Image Package */
 #define VERSAL_PRIMARY_CPU	0
@@ -64,38 +74,41 @@
 #define VERSAL_UART0_BASE		0xFF000000
 #define VERSAL_UART1_BASE		0xFF010000
 
-#if CONSOLE_IS(pl011) || CONSOLE_IS(dcc)
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
 # define UART_BASE	VERSAL_UART0_BASE
+# define UART_TYPE	CONSOLE_PL011
 #elif CONSOLE_IS(pl011_1)
 # define UART_BASE	VERSAL_UART1_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
 #else
 # error "invalid VERSAL_CONSOLE"
 #endif
 
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE VERSAL_UART0_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE VERSAL_UART1_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
 /*******************************************************************************
  * Platform related constants
  ******************************************************************************/
-#if VERSAL_PLATFORM_IS(versal_virt)
-# define PLATFORM_NAME		"Versal Virt"
-# define UART_CLOCK	25000000
-# define UART_BAUDRATE	115200
-# define VERSAL_CPU_CLOCK	2720000
-#elif VERSAL_PLATFORM_IS(silicon)
-# define PLATFORM_NAME		"Versal Silicon"
-# define UART_CLOCK	100000000
-# define UART_BAUDRATE	115200
-# define VERSAL_CPU_CLOCK	100000000
-#elif VERSAL_PLATFORM_IS(spp_itr6)
-# define PLATFORM_NAME		"SPP ITR6"
-# define UART_CLOCK	25000000
-# define UART_BAUDRATE	115200
-# define VERSAL_CPU_CLOCK	2720000
-#elif VERSAL_PLATFORM_IS(emu_itr6)
-# define PLATFORM_NAME		"EMU ITR6"
-# define UART_CLOCK	212000
-# define UART_BAUDRATE	9600
-# define VERSAL_CPU_CLOCK	212000
-#endif
+#define UART_BAUDRATE  115200
 
 /* Access control register defines */
 #define ACTLR_EL3_L2ACTLR_BIT	(1 << 6)
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 4cf1ed1..a299d14 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -197,7 +197,7 @@
  */
 static void versal_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	uint32_t ret, fw_api_version, version[PAYLOAD_ARG_CNT] = {0U};
+	uint32_t ret, fw_api_version, version[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
@@ -250,7 +250,7 @@
 
 	uint32_t pstate = psci_get_pstate_type(power_state);
 
-	assert(req_state);
+	assert(req_state != NULL);
 
 	/* Sanity check the requested state */
 	if (pstate == PSTATE_TYPE_STANDBY) {
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 2f07996..7c15be0 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -1,5 +1,5 @@
 # Copyright (c) 2018-2021, 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
 
@@ -22,7 +22,7 @@
     $(eval $(call add_define,VERSAL_ATF_MEM_BASE))
 
     ifndef VERSAL_ATF_MEM_SIZE
-        $(error "VERSAL_ATF_BASE defined without VERSAL_ATF_SIZE")
+        $(error "VERSAL_ATF_MEM_BASE defined without VERSAL_ATF_MEM_SIZE")
     endif
     $(eval $(call add_define,VERSAL_ATF_MEM_SIZE))
 
@@ -35,7 +35,7 @@
     $(eval $(call add_define,VERSAL_BL32_MEM_BASE))
 
     ifndef VERSAL_BL32_MEM_SIZE
-        $(error "VERSAL_BL32_BASE defined without VERSAL_BL32_SIZE")
+        $(error "VERSAL_BL32_MEM_BASE defined without VERSAL_BL32_MEM_SIZE")
     endif
     $(eval $(call add_define,VERSAL_BL32_MEM_SIZE))
 endif
@@ -44,8 +44,9 @@
     $(eval $(call add_define,IPI_CRC_CHECK))
 endif
 
-VERSAL_PLATFORM ?= silicon
-$(eval $(call add_define_val,VERSAL_PLATFORM,VERSAL_PLATFORM_ID_${VERSAL_PLATFORM}))
+ifdef VERSAL_PLATFORM
+    $(warning "VERSAL_PLATFORM has been deprecated")
+endif
 
 ifdef XILINX_OF_BOARD_DTB_ADDR
 $(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
@@ -84,13 +85,27 @@
 				${XLAT_TABLES_LIB_SRCS}
 
 VERSAL_CONSOLE	?=	pl011
-ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc))
+ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
 else
   $(error "Please define VERSAL_CONSOLE")
 endif
 
 $(eval $(call add_define_val,VERSAL_CONSOLE,VERSAL_CONSOLE_ID_${VERSAL_CONSOLE}))
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
 				lib/cpus/aarch64/cortex_a72.S			\
 				common/fdt_wrappers.c                           \
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index ccbfe77..3e44153 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.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
  */
@@ -155,6 +155,9 @@
 	case 74:
 		dev_idx = XPM_NODEIDX_DEV_USB_0;
 		break;
+	case 122:
+		dev_idx = XPM_NODEIDX_DEV_GPIO_PMC;
+		break;
 	case 126:
 	case 127:
 		dev_idx = XPM_NODEIDX_DEV_SDIO_0;
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index 4441d3e..3c0bd63 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-2021, 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
  */
@@ -22,7 +22,7 @@
 
 /* SiP Service Calls version numbers */
 #define SIP_SVC_VERSION_MAJOR	U(0)
-#define SIP_SVC_VERSION_MINOR	U(1)
+#define SIP_SVC_VERSION_MINOR	U(2)
 
 /* These macros are used to identify PM calls from the SMC function ID */
 #define SIP_FID_MASK	GENMASK(23, 16)
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 5af2b1d..ebde49f 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -82,6 +82,11 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
+	(void)arg0;
+	(void)arg1;
+	(void)arg2;
+	(void)arg3;
+
 #if !(TFA_NO_PM)
 	uint64_t tfa_handoff_addr, buff[HANDOFF_PARAMS_MAX_SIZE] = {0};
 	uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE;
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index e7d234b..5caf376 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -15,13 +15,24 @@
 #define MAX_INTR_EL3			2
 
 /* List all consoles */
+#define VERSAL_NET_CONSOLE_ID_none	U(0)
 #define VERSAL_NET_CONSOLE_ID_pl011	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_0	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_1	U(2)
 #define VERSAL_NET_CONSOLE_ID_dcc	U(3)
+#define VERSAL_NET_CONSOLE_ID_dtb	U(4)
 
 #define CONSOLE_IS(con)	(VERSAL_NET_CONSOLE_ID_ ## con == VERSAL_NET_CONSOLE)
 
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011    1
+#define RT_CONSOLE_ID_pl011_0  1
+#define RT_CONSOLE_ID_pl011_1  2
+#define RT_CONSOLE_ID_dcc      3
+#define RT_CONSOLE_ID_dtb      4
+
+#define RT_CONSOLE_IS(con)     (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
 /* List all platforms */
 #define VERSAL_NET_SILICON		U(0)
 #define VERSAL_NET_SPP			U(1)
@@ -138,11 +149,35 @@
 
 #define UART_BAUDRATE	115200
 
-#if CONSOLE_IS(pl011_1)
-#define UART_BASE		VERSAL_NET_UART1_BASE
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
+#define UART_BASE		VERSAL_NET_UART0_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(pl011_1)
+#define UART_BASE            VERSAL_NET_UART1_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
+#else
+# error "invalid VERSAL_NET_CONSOLE"
+#endif
+
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE VERSAL_NET_UART0_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE VERSAL_NET_UART1_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
 #else
-/* Default console is UART0 */
-#define UART_BASE            VERSAL_NET_UART0_BASE
+# error "invalid CONSOLE_RUNTIME"
+#endif
 #endif
 
 /* Processor core device IDs */
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index e5a5235..7a653d4 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -59,7 +59,7 @@
  */
 static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	uint32_t ret, fw_api_version, version[PAYLOAD_ARG_CNT] = {0U};
+	uint32_t ret, fw_api_version, version[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
@@ -247,7 +247,7 @@
 
 	int32_t pstate = psci_get_pstate_type(power_state);
 
-	assert(req_state);
+	assert(req_state != NULL);
 
 	/* Sanity check the requested state */
 	if (pstate == PSTATE_TYPE_STANDBY) {
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index da91abc..9534118 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -34,7 +34,7 @@
     $(eval $(call add_define,VERSAL_NET_ATF_MEM_BASE))
 
     ifndef VERSAL_NET_ATF_MEM_SIZE
-        $(error "VERSAL_NET_ATF_BASE defined without VERSAL_NET_ATF_SIZE")
+        $(error "VERSAL_NET_ATF_MEM_BASE defined without VERSAL_NET_ATF_MEM_SIZE")
     endif
     $(eval $(call add_define,VERSAL_NET_ATF_MEM_SIZE))
 
@@ -47,7 +47,7 @@
     $(eval $(call add_define,VERSAL_NET_BL32_MEM_BASE))
 
     ifndef VERSAL_NET_BL32_MEM_SIZE
-        $(error "VERSAL_NET_BL32_BASE defined without VERSAL_NET_BL32_SIZE")
+        $(error "VERSAL_NET_BL32_MEM_BASE defined without VERSAL_NET_BL32_MEM_SIZE")
     endif
     $(eval $(call add_define,VERSAL_NET_BL32_MEM_SIZE))
 endif
@@ -60,7 +60,7 @@
 HW_ASSISTED_COHERENCY := 1
 
 VERSAL_NET_CONSOLE	?=	pl011
-ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc))
+ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
 else
   $(error Please define VERSAL_NET_CONSOLE)
 endif
@@ -71,6 +71,20 @@
 $(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
 endif
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 # enable assert() for release/debug builds
 ENABLE_ASSERTIONS := 1
 
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index 80d5a53..c974810 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2019, 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.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,7 +25,7 @@
 
 /* SiP Service Calls version numbers */
 #define SIP_SVC_VERSION_MAJOR		(0U)
-#define SIP_SVC_VERSION_MINOR		(1U)
+#define SIP_SVC_VERSION_MINOR		(2U)
 
 /* These macros are used to identify PM calls from the SMC function ID */
 #define SIP_FID_MASK	GENMASK(23, 16)
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..ede3a21 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>
@@ -71,6 +72,10 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
+	(void)arg0;
+	(void)arg1;
+	(void)arg2;
+	(void)arg3;
 	uint64_t tfa_handoff_addr;
 
 	setup_console();
@@ -220,5 +225,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/custom_sip_svc.c b/plat/xilinx/zynqmp/custom_sip_svc.c
index b9664af..c61c92c 100644
--- a/plat/xilinx/zynqmp/custom_sip_svc.c
+++ b/plat/xilinx/zynqmp/custom_sip_svc.c
@@ -12,6 +12,12 @@
 			    uint64_t x3, uint64_t x4, void *cookie,
 			    void *handle, uint64_t flags)
 {
+	(void)x1;
+	(void)x2;
+	(void)x3;
+	(void)x4;
+	(void)cookie;
+	(void)flags;
 	WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
 	SMC_RET1(handle, SMC_UNK);
 }
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/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index d715ce2..68485cf 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -10,13 +10,24 @@
 #include <plat/arm/common/smccc_def.h>
 #include <plat/common/common_def.h>
 
+#define ZYNQMP_CONSOLE_ID_none		0
 #define ZYNQMP_CONSOLE_ID_cadence	1
 #define ZYNQMP_CONSOLE_ID_cadence0	1
 #define ZYNQMP_CONSOLE_ID_cadence1	2
 #define ZYNQMP_CONSOLE_ID_dcc		3
+#define ZYNQMP_CONSOLE_ID_dtb		4
 
 #define CONSOLE_IS(con)	(ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
 
+/* Runtime console */
+#define RT_CONSOLE_ID_cadence	1
+#define RT_CONSOLE_ID_cadence0	1
+#define RT_CONSOLE_ID_cadence1	2
+#define RT_CONSOLE_ID_dcc	3
+#define RT_CONSOLE_ID_dtb	4
+
+#define RT_CONSOLE_IS(con)	(RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
 /* Default counter frequency */
 #define ZYNQMP_DEFAULT_COUNTER_FREQ	0U
 
@@ -144,14 +155,38 @@
 #define ZYNQMP_UART0_BASE		U(0xFF000000)
 #define ZYNQMP_UART1_BASE		U(0xFF010000)
 
-#if CONSOLE_IS(cadence) || CONSOLE_IS(dcc)
+/* Boot console */
+#if CONSOLE_IS(cadence) || CONSOLE_IS(dtb)
 # define UART_BASE	ZYNQMP_UART0_BASE
+# define UART_TYPE	CONSOLE_CDNS
 #elif CONSOLE_IS(cadence1)
 # define UART_BASE	ZYNQMP_UART1_BASE
+# define UART_TYPE	CONSOLE_CDNS
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
 #else
 # error "invalid ZYNQMP_CONSOLE"
 #endif
 
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(cadence) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE	ZYNQMP_UART0_BASE
+# define RT_UART_TYPE	CONSOLE_CDNS
+#elif RT_CONSOLE_IS(cadence1)
+# define RT_UART_BASE	ZYNQMP_UART1_BASE
+# define RT_UART_TYPE	CONSOLE_CDNS
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
 /* Must be non zero */
 #define UART_BAUDRATE		115200
 
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 3a752b2..5a86658 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -21,7 +21,7 @@
 EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
 
 # pncd SPD requires secure SGI to be handled at EL1
-ifeq (${SPD}, $(filter ${SPD},pncd tspd))
+ifeq (${SPD}, $(filter ${SPD},pncd tspd opteed))
 ifeq (${ZYNQMP_WDT_RESTART},1)
 $(error "Error: ZYNQMP_WDT_RESTART and SPD=pncd are incompatible")
 endif
@@ -35,15 +35,11 @@
 
 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))
 
     ifndef ZYNQMP_ATF_MEM_SIZE
-        $(error "ZYNQMP_ATF_BASE defined without ZYNQMP_ATF_SIZE")
+        $(error "ZYNQMP_ATF_MEM_BASE defined without ZYNQMP_ATF_MEM_SIZE")
     endif
     $(eval $(call add_define,ZYNQMP_ATF_MEM_SIZE))
 
@@ -60,7 +56,7 @@
     $(eval $(call add_define,ZYNQMP_BL32_MEM_BASE))
 
     ifndef ZYNQMP_BL32_MEM_SIZE
-        $(error "ZYNQMP_BL32_BASE defined without ZYNQMP_BL32_SIZE")
+        $(error "ZYNQMP_BL32_MEM_BASE defined without ZYNQMP_BL32_MEM_SIZE")
     endif
     $(eval $(call add_define,ZYNQMP_BL32_MEM_SIZE))
 endif
@@ -96,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}				\
@@ -112,15 +107,30 @@
 				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))
+ifeq (${ZYNQMP_CONSOLE}, $(filter ${ZYNQMP_CONSOLE},cadence cadence0 cadence1 dcc dtb none))
 else
   $(error "Please define ZYNQMP_CONSOLE")
 endif
 $(eval $(call add_define_val,ZYNQMP_CONSOLE,ZYNQMP_CONSOLE_ID_${ZYNQMP_CONSOLE}))
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= cadence
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},cadence cadence0 cadence1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 # Build PM code as a Library
 include plat/xilinx/zynqmp/libpm.mk
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 9682e59..5a1e218 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -2791,7 +2791,7 @@
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if (pll) {
+	if (pll != NULL) {
 		*node_id = pll->nid;
 		return PM_RET_SUCCESS;
 	}
@@ -2883,7 +2883,7 @@
 	enum pm_ret_status status;
 	enum pm_pll_mode mode;
 
-	if ((pll == NULL) || !state) {
+	if ((pll == NULL) || (state == NULL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -3013,7 +3013,7 @@
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if ((pll == NULL) || !mode) {
+	if ((pll == NULL) || (mode == NULL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 	*mode = pll->mode;
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index 3d546b3..d7c9f24 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -268,6 +268,7 @@
 				   uint32_t state,
 				   uintptr_t address)
 {
+	(void)nid;
 	uint32_t payload[PAYLOAD_ARG_CNT];
 	uint32_t cpuid = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpuid);
@@ -919,7 +920,7 @@
 enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
 				    uint32_t *bit_mask, uint8_t len)
 {
-	uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U};
+	uint32_t ret_payload[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t status;
 
 	/* Get API version implemented in TF-A */
@@ -1149,7 +1150,7 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_enable(pll);
 	}
 
@@ -1174,7 +1175,7 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_disable(pll);
 	}
 
@@ -1202,9 +1203,9 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll)
+	if (pll != NULL) {
 		return pm_clock_pll_get_state(pll, state);
-
+	}
 	/* Check if clock ID is a valid on-chip clock */
 	status = pm_clock_id_is_valid(clock_id);
 	if (status != PM_RET_SUCCESS) {
@@ -1340,7 +1341,7 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll_by_related_clk(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_set_parent(pll, clock_id, parent_index);
 	}
 
@@ -1375,7 +1376,7 @@
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll_by_related_clk(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_get_parent(pll, clock_id, parent_index);
 	}
 
@@ -1514,6 +1515,7 @@
 void pm_query_data(enum pm_query_ids qid, uint32_t arg1, uint32_t arg2,
 		   uint32_t arg3, uint32_t *data)
 {
+	(void)arg3;
 	switch (qid) {
 	case PM_QID_CLOCK_GET_NAME:
 		pm_clock_get_name(arg1, (char *)data);
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index 5a6a9f8..65b2426 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -281,11 +281,14 @@
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
 {
+	(void)x4;
+	(void)cookie;
+	(void)flags;
 	enum pm_ret_status ret;
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	uint32_t pm_arg[5];
-	uint32_t result[PAYLOAD_ARG_CNT] = {0};
+	uint32_t result[RET_PAYLOAD_ARG_CNT] = {0};
 	uint32_t api_id;
 
 	/* Handle case where PM wasn't initialized properly */
@@ -566,7 +569,7 @@
 		PM_PACK_PAYLOAD6(payload, api_id, pm_arg[0], pm_arg[1],
 				 pm_arg[2], pm_arg[3], pm_arg[4]);
 		ret = pm_ipi_send_sync(primary_proc, payload, result,
-				       PAYLOAD_ARG_CNT);
+				       RET_PAYLOAD_ARG_CNT);
 		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
 			 (uint64_t)result[1] | ((uint64_t)result[2] << 32U));
 	}
diff --git a/poetry.lock b/poetry.lock
index 08b2b37..9a90704 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,201 @@
 
 [[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.16.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.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"},
+    {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"},
 ]
 
 [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.2"
 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.2-py3-none-any.whl", hash = "sha256:277ccc71619d98afdd841a0e96ac9fe1593b823af481d3b0cea748e8894e0613"},
+    {file = "build-1.2.2.tar.gz", hash = "sha256:119b2fb462adef986483438377a13b2f42064a2a3a4161f24a0cca698a07ac8c"},
 ]
 
 [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 = "cachetools"
+version = "5.5.0"
+description = "Extensible memoizing collections and decorators"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"},
+    {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"},
+]
+
+[[package]]
 name = "certifi"
-version = "2023.7.22"
+version = "2024.8.30"
 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.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
+    {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
 ]
 
 [[package]]
+name = "chardet"
+version = "5.2.0"
+description = "Universal encoding detector for Python 3"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
+    {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
+]
+
+[[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 +225,51 @@
 ]
 
 [[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 = "cot-dt2c"
+version = "0.1.0"
+description = "CoT-dt2c Tool is a python script to convert CoT DT file into corresponding C file"
+optional = false
+python-versions = "^3.8"
+files = []
+develop = true
+
+[package.dependencies]
+click = "^8.1.7"
+igraph = "^0.11.6"
+plotly = "^5.23.0"
+pydevicetree = "0.0.13"
+pyparsing = "^3.1.2"
+
+[package.source]
+type = "directory"
+url = "tools/cot_dt2c"
+
+[[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 = "docutils"
 version = "0.18.1"
 description = "Docutils -- Python Documentation Utilities"
@@ -198,17 +281,93 @@
 ]
 
 [[package]]
+name = "filelock"
+version = "3.16.0"
+description = "A platform independent file lock."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "filelock-3.16.0-py3-none-any.whl", hash = "sha256:f6ed4c963184f4c84dd5557ce8fece759a3724b37b80c6c4f20a2f63a4dc6609"},
+    {file = "filelock-3.16.0.tar.gz", hash = "sha256:81de9eb8453c769b63369f87f11131a7ab04e367f8d97ad39dc230daa07e3bec"},
+]
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.1.1)", "pytest (>=8.3.2)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.3)"]
+typing = ["typing-extensions (>=4.12.2)"]
+
+[[package]]
 name = "idna"
-version = "3.4"
+version = "3.8"
 description = "Internationalized Domain Names in Applications (IDNA)"
 optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
 files = [
-    {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
-    {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+    {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"},
+    {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"},
 ]
 
 [[package]]
+name = "igraph"
+version = "0.11.6"
+description = "High performance graph data structures and algorithms"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "igraph-0.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3f8b837181e8e87676be3873ce87cc92cc234efd58a2da2f6b4e050db150fcf4"},
+    {file = "igraph-0.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:245c4b7d7657849eff80416f5df4525c8fc44c74a981ee4d44f0ef2612c3bada"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdb7be3d165073c0136295c0808e9edc57ba096cdb26e94086abb04561f7a292"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58974e20df2986a1ae52a16e51ecb387cc0cbeb41c5c0ddff4d373a1bbf1d9c5"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bef14de5e8ab70724a43808b1ed14aaa6fe1002f87e592289027a3827a8f44a"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:86c1e98de2e32d074df8510bf18abfa1f4c5fda4cb28a009985a5d746b0c0125"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ebc5b3d702158abeb2e4d2414374586a2b932e1a07e48352b470600e1733d528"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0efe6d0fb22d3987a800eb3857ed04df9eb4c5dddd0998be05232cb646f1c337"},
+    {file = "igraph-0.11.6-cp38-cp38-win32.whl", hash = "sha256:f4e68b27497b1c8ada2fb2bc35ef3fa7b0d72e84306b3d648d3de240fc618c32"},
+    {file = "igraph-0.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:5665b33dfbfca5f54ce9b4fea6b97903bd0e99fb1b02acf5e57e600bdfa5a355"},
+    {file = "igraph-0.11.6-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8aabef03d787b519d1075dfc0da4a1109fb113b941334883e3e7947ac30a459e"},
+    {file = "igraph-0.11.6-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1f2cc4a518d99cdf6cae514f85e93e56852bc8c325b3abb96037d1d690b5975f"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e859238be52ab8ccc614d18f9362942bc88ce543afc12548f81ae99b10801d"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d61fbe5e85eb4ae9efe08c461f9bdeedb02a2b5739fbc223d324a71f40a28be2"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6620ba39df29fd42151becf82309b54e57148233c9c3ef890eed62e25eed8a5"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59666589bb3d07f310cda2c5106a8adeeb77c2ef27fecf1c6438b6091f4ca69d"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:8750b6d6caebf199cf7dc41c931f58e330153779707391e30f0a29f02666fb6e"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:967d6f2c30fe94317da15e459374d0fb8ca3e56020412f201ecd07dd5b5352f2"},
+    {file = "igraph-0.11.6-cp39-abi3-win32.whl", hash = "sha256:9744f95a67319eb6cb487ceabf30f5d7940de34bada51f0ba63adbd23e0f94ad"},
+    {file = "igraph-0.11.6-cp39-abi3-win_amd64.whl", hash = "sha256:b80e69eb11faa9c57330a9ffebdde5808966efe1c1f638d4d4827ea04df7aca8"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0329c16092e2ea7930d5f8368666ce7cb704900cc0ea04e4afe9ea1dd46e44af"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:21752313f449bd8688e5688e95ea7231cea5e9199c7162535029be0d9af848ac"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea25e136c6c4161f53ff58868b23ff6c845193050ab0e502236d68e5d4174e32"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac84433a03aef15e4b810010b08882b09854a3669450ccf31e392dbe295d2a66"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac697a44e3573169fa2b28c9c37dcf9cf01e0f558b845dd7123860d4c7c8fb89"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bdeae8bf35316eb1fb27bf667dcf5ecf5fcfb0b8f51831bc1b00c39c09c2d73b"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ad7e4aa442935de72554b96733bf6d7f09eac5cee97988a2562bdd3ca173cfa3"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d2818780358a686178866d01568b9df1f29678581734ad7a78882bab54df004"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2352276a20d979f1dea360af4202bb9f0c9a7d2c77f51815c0e625165e82013d"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:687fdab543b507d622fa3043f4227e5b26dc61dcf8ff8c0919fccddcc655f8b8"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f7f8214cd48c9a4d97f7346a4152ba2d4ac95fb5ee0df4ecf224fce4ba3d14"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2b9cc69ede53f76ffae03b066609aa90184dd68ef15da8c104a97cebb9210838"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:591e1e447c3f0092daf7613a3eaedab83f9a0b0adbaf7702724c5117ded038a5"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ca558eb331bc687bc33e5cd23717e22676e9412f8cda3a31d30c996a0487610d"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf43c30e08debb087c9e3da69aa5cf1b6732968da34d55a614e3421b9a452146"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d38e8d7db72b187d9d2211d0d06b3271fa9f32b04d49d789e2859b5480db0d0"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a318b059051ff78144a1c3cb880f4d933c812bcdb3d833a49cd7168d0427672"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2c54027add809b3c5b6685b8deca4ea4763fd000b9ea45c7ee46b7c9d61ff15e"},
+    {file = "igraph-0.11.6.tar.gz", hash = "sha256:837f233256c3319f2a35a6a80d94eafe47b43791ef4c6f9e9871061341ac8e28"},
+]
+
+[package.dependencies]
+texttable = ">=1.6.2"
+
+[package.extras]
+cairo = ["cairocffi (>=1.2.0)"]
+doc = ["Sphinx (>=7.0.0)", "pydoctor (>=23.4.0)", "sphinx-gallery (>=0.14.0)", "sphinx-rtd-theme (>=1.3.0)"]
+matplotlib = ["matplotlib (>=3.6.0)"]
+plotly = ["plotly (>=5.3.0)"]
+plotting = ["cairocffi (>=1.2.0)"]
+test = ["Pillow (>=9)", "cairocffi (>=1.2.0)", "matplotlib (>=3.6.0)", "networkx (>=2.5)", "numpy (>=1.19.0)", "pandas (>=1.1.0)", "plotly (>=5.3.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "scipy (>=1.5.0)"]
+test-musl = ["cairocffi (>=1.2.0)", "networkx (>=2.5)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)"]
+
+[[package]]
 name = "imagesize"
 version = "1.4.1"
 description = "Getting image size from png/jpeg/jpeg2000/gif file"
@@ -221,32 +380,32 @@
 
 [[package]]
 name = "importlib-metadata"
-version = "6.6.0"
+version = "8.4.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.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"},
+    {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"},
 ]
 
 [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 +440,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 +565,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 +601,89 @@
 click = ">=8"
 pip = ">=22.2"
 setuptools = "*"
+tomli = {version = "*", markers = "python_version < \"3.11\""}
 wheel = "*"
 
 [package.extras]
+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 = "platformdirs"
+version = "4.3.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.3.2-py3-none-any.whl", hash = "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617"},
+    {file = "platformdirs-4.3.2.tar.gz", hash = "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c"},
+]
+
+[package.extras]
-coverage = ["pytest-cov"]
-testing = ["flit-core (>=2,<4)", "poetry-core (>=1.0.0)", "pytest (>=7.2.0)", "pytest-rerunfailures", "pytest-xdist"]
+docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"]
+type = ["mypy (>=1.11.2)"]
 
 [[package]]
+name = "plotly"
+version = "5.24.0"
+description = "An open-source, interactive data visualization library for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "plotly-5.24.0-py3-none-any.whl", hash = "sha256:0e54efe52c8cef899f7daa41be9ed97dfb6be622613a2a8f56a86a0634b2b67e"},
+    {file = "plotly-5.24.0.tar.gz", hash = "sha256:eae9f4f54448682442c92c1e97148e3ad0c52f0cf86306e1b76daba24add554a"},
+]
+
+[package.dependencies]
+packaging = "*"
+tenacity = ">=6.2.0"
+
+[[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 = "prettytable"
-version = "3.7.0"
+version = "3.11.0"
 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.11.0-py3-none-any.whl", hash = "sha256:aa17083feb6c71da11a68b2c213b04675c4af4ce9c541762632ca3f2cb3546dd"},
+    {file = "prettytable-3.11.0.tar.gz", hash = "sha256:7e23ca1e68bbfd06ba8de98bf553bf3493264c96d5e8a615c0471025deeba722"},
 ]
 
 [package.dependencies]
 wcwidth = "*"
 
 [package.extras]
-tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"]
+tests = ["pytest", "pytest-cov", "pytest-lazy-fixtures"]
+
+[[package]]
+name = "pydevicetree"
+version = "0.0.13"
+description = "A library for parsing Devicetree Source v1"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "pydevicetree-0.0.13-py3-none-any.whl", hash = "sha256:d61c695cec925b90a8b5740053f4b604e51154a9b36e62a2f12ed9ceaf2f8c38"},
+    {file = "pydevicetree-0.0.13.tar.gz", hash = "sha256:5700c05df89bad8fd729c11aa6f764a3323bcb3796f13b32481ae34445cfc1b7"},
+]
+
+[package.dependencies]
+pyparsing = "*"
 
 [[package]]
 name = "pyelftools"
@@ -468,101 +698,144 @@
 
 [[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.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 = "pyparsing"
+version = "3.1.4"
+description = "pyparsing module - Classes and methods to define and execute parsing grammars"
+optional = false
+python-versions = ">=3.6.8"
+files = [
+    {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"},
+    {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"},
+]
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
+
+[[package]]
+name = "pyproject-api"
+version = "1.7.1"
+description = "API to interact with the python pyproject.toml based projects"
+optional = false
+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 = "pyproject_api-1.7.1-py3-none-any.whl", hash = "sha256:2dc1654062c2b27733d8fd4cdda672b22fe8741ef1dde8e3a998a9547b071eeb"},
+    {file = "pyproject_api-1.7.1.tar.gz", hash = "sha256:7ebc6cd10710f89f4cf2a2731710a98abce37ebff19427116ff2174c9236a827"},
 ]
 
+[package.dependencies]
+packaging = ">=24.1"
+tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
+
 [package.extras]
-plugins = ["importlib-metadata"]
+docs = ["furo (>=2024.5.6)", "sphinx-autodoc-typehints (>=2.2.1)"]
+testing = ["covdefaults (>=2.3)", "pytest (>=8.2.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "setuptools (>=70.1)"]
 
 [[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.2"
 description = "YAML parser and emitter for Python"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
 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.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
+    {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
+    {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
+    {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
+    {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
+    {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
+    {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
+    {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
+    {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
+    {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
+    {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
+    {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
+    {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
+    {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
+    {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
+    {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
+    {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
+    {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
+    {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
+    {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
+    {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
+    {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
+    {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
+    {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
+    {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
+    {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
+    {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
+    {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
+    {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
+    {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
+    {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
+    {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
+    {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
+    {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
+    {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
 ]
 
 [[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 +849,54 @@
 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 = "74.1.2"
 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-74.1.2-py3-none-any.whl", hash = "sha256:5f4c08aa4d3ebcb57a50c33b1b07e94315d7fc7230f7115e47fc99776c8ce308"},
+    {file = "setuptools-74.1.2.tar.gz", hash = "sha256:95b40ed940a1c67eb70fc099094bd6e99c6ee7c23aa2306f4d2697ba7916f9c6"},
 ]
 
 [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"]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
+core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+cover = ["pytest-cov"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
+enabler = ["pytest-enabler (>=2.2)"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
+type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
+
+[[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 +957,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 +1111,53 @@
 cairosvg = ["cairosvg (>=1.0)"]
 
 [[package]]
+name = "tenacity"
+version = "9.0.0"
+description = "Retry code until it succeeds"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"},
+    {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"},
+]
+
+[package.extras]
+doc = ["reno", "sphinx"]
+test = ["pytest", "tornado (>=4.5)", "typeguard"]
+
+[[package]]
+name = "texttable"
+version = "1.7.0"
+description = "module to create simple ASCII tables"
+optional = false
+python-versions = "*"
+files = [
+    {file = "texttable-1.7.0-py2.py3-none-any.whl", hash = "sha256:72227d592c82b3d7f672731ae73e4d1f88cd8e2ef5b075a7a7f01a23a3743917"},
+    {file = "texttable-1.7.0.tar.gz", hash = "sha256:2d2068fb55115807d3ac77a4ca68fa48803e84ebb0ee2340f858107a36522638"},
+]
+
+[[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 = true
+
+[package.dependencies]
+click = "^8.1.7"
+jinja2 = "^3.1.4"
+pyyaml = "^6.0.1"
+rich = "^10.14.0"
+tox = "^4.18.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 +1169,147 @@
 ]
 
 [[package]]
+name = "tox"
+version = "4.18.1"
+description = "tox is a generic virtualenv management and test command line tool"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tox-4.18.1-py3-none-any.whl", hash = "sha256:35d472032ee1f73fe20c3e0e73d7073a4e85075c86ff02c576f9fc7c6a15a578"},
+    {file = "tox-4.18.1.tar.gz", hash = "sha256:3c0c96bc3a568a5c7e66387a4cfcf8c875b52e09f4d47c9f7a277ec82f1a0b11"},
+]
+
+[package.dependencies]
+cachetools = ">=5.5"
+chardet = ">=5.2"
+colorama = ">=0.4.6"
+filelock = ">=3.15.4"
+packaging = ">=24.1"
+platformdirs = ">=4.2.2"
+pluggy = ">=1.5"
+pyproject-api = ">=1.7.1"
+tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
+virtualenv = ">=20.26.3"
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-argparse-cli (>=1.17)", "sphinx-autodoc-typehints (>=2.4)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=24.8)"]
+testing = ["build[virtualenv] (>=1.2.2)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.2)", "devpi-process (>=1)", "diff-cover (>=9.1.1)", "distlib (>=0.3.8)", "flaky (>=3.8.1)", "hatch-vcs (>=0.4)", "hatchling (>=1.25)", "psutil (>=6)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-xdist (>=3.6.1)", "re-assert (>=1.1)", "setuptools (>=74.1.2)", "time-machine (>=2.15)", "wheel (>=0.44)"]
+
+[[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.5.0"
-description = "Backported and Experimental Type Hints for Python 3.7+"
+version = "4.12.2"
+description = "Backported and Experimental Type Hints for Python 3.8+"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 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 = "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 = "virtualenv"
+version = "20.26.4"
+description = "Virtual Python Environment builder"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "virtualenv-20.26.4-py3-none-any.whl", hash = "sha256:48f2695d9809277003f30776d155615ffc11328e6a0a8c1f0ec80188d7874a55"},
+    {file = "virtualenv-20.26.4.tar.gz", hash = "sha256:c17f4e0f3e6036e9f26700446f85c76ab11df65ff6d8a9cbfad9f71aabfcf23c"},
+]
+
+[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 = "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.44.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.44.0-py3-none-any.whl", hash = "sha256:2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f"},
+    {file = "wheel-0.44.0.tar.gz", hash = "sha256:a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49"},
 ]
 
 [package.extras]
-test = ["pytest (>=6.0.0)"]
+test = ["pytest (>=6.0.0)", "setuptools (>=65)"]
 
 [[package]]
 name = "zipp"
-version = "3.15.0"
+version = "3.20.1"
 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.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"},
+    {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"},
 ]
 
 [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)"]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
+cover = ["pytest-cov"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+enabler = ["pytest-enabler (>=2.2)"]
+test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
+type = ["pytest-mypy"]
 
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.8"
-content-hash = "62d9ce9ca1c9f4669c7b40724acfc93968cde31c0460d1d7515d289739dc9464"
+content-hash = "6a6d2fe9390a4d7d1ecf808d5f303f2dc1eeb44736827b706a858046f3eea1db"
diff --git a/pyproject.toml b/pyproject.toml
index 7814497..f34c3d1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -14,8 +14,13 @@
 
 [tool.poetry.dependencies]
 python = "^3.8"
+cot-dt2c = {path = "tools/cot_dt2c", develop = true}
+tlc = {path = "tools/tlc", develop = true}
+
+[tool.poetry.group.docs]
+optional = true
 
-[tool.poetry.group.doc.dependencies]
+[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/pncd/pncd_common.c b/services/spd/pncd/pncd_common.c
index 6fdb629..8e89491 100644
--- a/services/spd/pncd/pncd_common.c
+++ b/services/spd/pncd/pncd_common.c
@@ -67,8 +67,9 @@
 	/* Apply the Secure EL1 system register context and switch to it */
 	assert(cm_get_context(SECURE) == &pnc_ctx->cpu_ctx);
 	cm_el1_sysregs_context_restore(SECURE);
+
 #if CTX_INCLUDE_FPREGS
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
+	simd_ctx_restore(SECURE);
 #endif
 	cm_set_next_eret_context(SECURE);
 
@@ -90,8 +91,9 @@
 	/* Save the Secure EL1 system register context */
 	assert(cm_get_context(SECURE) == &pnc_ctx->cpu_ctx);
 	cm_el1_sysregs_context_save(SECURE);
+
 #if CTX_INCLUDE_FPREGS
-	fpregs_context_save(get_fpregs_ctx(cm_get_context(SECURE)));
+	simd_ctx_save(SECURE, false);
 #endif
 
 	assert(pnc_ctx->c_rt_ctx != 0);
diff --git a/services/spd/pncd/pncd_main.c b/services/spd/pncd/pncd_main.c
index 99c4aa1..cc1c1f2 100644
--- a/services/spd/pncd/pncd_main.c
+++ b/services/spd/pncd/pncd_main.c
@@ -55,8 +55,9 @@
 	assert(sec_state_is_valid(security_state));
 
 	cm_el1_sysregs_context_save((uint32_t) security_state);
+
 #if CTX_INCLUDE_FPREGS
-	fpregs_context_save(get_fpregs_ctx(cm_get_context(security_state)));
+	simd_ctx_save((uint32_t)security_state, false);
 #endif
 }
 
@@ -72,8 +73,9 @@
 
 	/* Restore state */
 	cm_el1_sysregs_context_restore((uint32_t) security_state);
+
 #if CTX_INCLUDE_FPREGS
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(security_state)));
+	simd_ctx_restore((uint32_t)security_state);
 #endif
 
 	cm_set_next_eret_context((uint32_t) security_state);
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index 7daebcd..aae2d9a 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
@@ -118,8 +118,10 @@
 	 * when it's needed the PSCI caller has preserved FP context before
 	 * going here.
 	 */
-	if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME)
-		fpregs_context_save(get_fpregs_ctx(cm_get_context(security_state)));
+	if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME) {
+		simd_ctx_save(security_state, false);
+	}
+
 	cm_el1_sysregs_context_save(security_state);
 
 	ctx->saved_security_state = security_state;
@@ -128,8 +130,9 @@
 	assert(ctx->saved_security_state == ((security_state == 0U) ? 1U : 0U));
 
 	cm_el1_sysregs_context_restore(security_state);
-	if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME)
-		fpregs_context_restore(get_fpregs_ctx(cm_get_context(security_state)));
+	if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME) {
+		simd_ctx_restore(security_state);
+	}
 
 	cm_set_next_eret_context(security_state);
 
@@ -160,9 +163,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 +224,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);
@@ -320,7 +323,7 @@
 	ep_info = bl31_plat_get_next_image_ep_info(SECURE);
 	assert(ep_info != NULL);
 
-	fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
+	simd_ctx_save(NON_SECURE, false);
 	cm_el1_sysregs_context_save(NON_SECURE);
 
 	cm_set_context(&ctx->cpu_ctx, SECURE);
@@ -337,7 +340,7 @@
 	}
 
 	cm_el1_sysregs_context_restore(SECURE);
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
+	simd_ctx_restore(SECURE);
 	cm_set_next_eret_context(SECURE);
 
 	ctx->saved_security_state = ~0U; /* initial saved state is invalid */
@@ -346,7 +349,7 @@
 	(void)trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
 
 	cm_el1_sysregs_context_restore(NON_SECURE);
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
+	simd_ctx_restore(NON_SECURE);
 	cm_set_next_eret_context(NON_SECURE);
 
 	return 1;
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
index b9c83fa..8d27e96 100644
--- a/services/std_svc/drtm/drtm_main.c
+++ b/services/std_svc/drtm/drtm_main.c
@@ -463,7 +463,7 @@
 	 * is required to avoid / defend against racing with cache evictions
 	 */
 	va_mapping_size = ALIGNED_UP((dlme_end - dlme_start), DRTM_PAGE_SIZE);
-	rc = mmap_add_dynamic_region_alloc_va(dlme_img_start, &va_mapping, va_mapping_size,
+	rc = mmap_add_dynamic_region_alloc_va(dlme_start, &va_mapping, va_mapping_size,
 					      MT_MEMORY | MT_NS | MT_RO |
 					      MT_SHAREABILITY_ISH);
 	if (rc != 0) {
@@ -512,10 +512,10 @@
 	sctlr &= ~(/* Disable DLME's EL MMU, since the existing page-tables are untrusted. */
 		   SCTLR_M_BIT
 		   | SCTLR_EE_BIT               /* Little-endian data accesses. */
+		   | SCTLR_C_BIT		/* disable data caching */
+		   | SCTLR_I_BIT		/* disable instruction caching */
 		  );
 
-	sctlr |= SCTLR_C_BIT | SCTLR_I_BIT; /* Allow instruction and data caching. */
-
 	switch (dlme_el) {
 	case DLME_AT_EL1:
 		write_sctlr_el1(sctlr);
@@ -655,6 +655,10 @@
 	drtm_dl_reset_dlme_el_state(dlme_el);
 	drtm_dl_reset_dlme_context(dlme_el);
 
+	/*
+	 * Setting the Generic Timer frequency is required before launching
+	 * DLME and is already done for running CPU during PSCI setup.
+	 */
 	drtm_dl_prepare_eret_to_dlme(&args, dlme_el);
 
 	/*
@@ -808,12 +812,12 @@
 
 	case ARM_DRTM_SVC_GET_ERROR:
 		INFO("DRTM service handler: get error\n");
-		drtm_get_error(handle);
+		return drtm_get_error(handle);
 		break;	/* not reached */
 
 	case ARM_DRTM_SVC_SET_ERROR:
 		INFO("DRTM service handler: set error\n");
-		drtm_set_error(x1, handle);
+		return drtm_set_error(x1, handle);
 		break;	/* not reached */
 
 	case ARM_DRTM_SVC_SET_TCB_HASH:
diff --git a/services/std_svc/drtm/drtm_remediation.c b/services/std_svc/drtm/drtm_remediation.c
index 696b4ea..81d27ec 100644
--- a/services/std_svc/drtm/drtm_remediation.c
+++ b/services/std_svc/drtm/drtm_remediation.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -21,7 +21,7 @@
 	rc = plat_set_drtm_error(x1);
 
 	if (rc != 0) {
-		SMC_RET1(ctx, INTERNAL_ERROR);
+		SMC_RET1(ctx, NOT_FOUND);
 	}
 
 	SMC_RET1(ctx, SUCCESS);
@@ -35,7 +35,7 @@
 	rc = plat_get_drtm_error(&error_code);
 
 	if (rc != 0) {
-		SMC_RET1(ctx, INTERNAL_ERROR);
+		SMC_RET1(ctx, NOT_FOUND);
 	}
 
 	SMC_RET2(ctx, SUCCESS, error_code);
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
index 61e1076..d688431 100644
--- a/services/std_svc/errata_abi/cpu_errata_info.h
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -8,6 +8,7 @@
 #define ERRATA_CPUSPEC_H
 
 #include <stdint.h>
+#include <arch.h>
 #include <arch_helpers.h>
 
 #if __aarch64__
@@ -31,8 +32,6 @@
 /* Default values for unused memory in the array */
 #define UNDEF_ERRATA		{UINT_MAX, UCHAR_MAX, UCHAR_MAX}
 
-#define EXTRACT_PARTNUM(x)	((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
-
 #define RXPX_RANGE(x, y, z)	(((x >= y) && (x <= z)) ? true : false)
 
 /*
diff --git a/services/std_svc/rmmd/rmmd_attest.c b/services/std_svc/rmmd/rmmd_attest.c
index 25adf50..7d4ea70 100644
--- a/services/std_svc/rmmd/rmmd_attest.c
+++ b/services/std_svc/rmmd/rmmd_attest.c
@@ -1,8 +1,10 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include <errno.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -11,7 +13,8 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include "rmmd_private.h"
-#include <services/rmmd_svc.h>
+#include <services/rmm_el3_token_sign.h>
+#include <smccc_helpers.h>
 
 static spinlock_t lock;
 
@@ -85,7 +88,8 @@
 }
 
 int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
-				   uint64_t c_size)
+				   uint64_t c_size,
+				   uint64_t *remaining_len)
 {
 	int err;
 	uint8_t temp_buf[SHA512_DIGEST_SIZE];
@@ -110,9 +114,19 @@
 
 	/* Get the platform token. */
 	err = plat_rmmd_get_cca_attest_token((uintptr_t)buf_pa,
-		buf_size, (uintptr_t)temp_buf, c_size);
+		buf_size, (uintptr_t)temp_buf, c_size, remaining_len);
 
-	if (err != 0) {
+	switch (err) {
+	case 0:
+		err = E_RMM_OK;
+		break;
+	case -EAGAIN:
+		err = E_RMM_AGAIN;
+		break;
+	case -EINVAL:
+		err = E_RMM_INVAL;
+		break;
+	default:
 		ERROR("Failed to get platform token: %d.\n", err);
 		err = E_RMM_UNK;
 	}
@@ -144,10 +158,110 @@
 						 (unsigned int)ecc_curve);
 	if (err != 0) {
 		ERROR("Failed to get attestation key: %d.\n", err);
-		err =  E_RMM_UNK;
+		err = E_RMM_UNK;
 	}
 
 	spin_unlock(&lock);
 
 	return err;
 }
+
+static int rmmd_el3_token_sign_push_req(uint64_t buf_pa, uint64_t buf_size)
+{
+	int err;
+
+	err = validate_buffer_params(buf_pa, buf_size);
+	if (err != 0) {
+		return err;
+	}
+
+	if (buf_size < sizeof(struct el3_token_sign_request)) {
+		return E_RMM_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Call platform port to handle attestation toekn signing request. */
+	err = plat_rmmd_el3_token_sign_push_req((struct el3_token_sign_request *)buf_pa);
+
+	spin_unlock(&lock);
+
+	return err;
+}
+
+static int rmmd_el3_token_sign_pull_resp(uint64_t buf_pa, uint64_t buf_size)
+{
+	int err;
+
+	err = validate_buffer_params(buf_pa, buf_size);
+	if (err != 0) {
+		return err;
+	}
+
+
+	if (buf_size < sizeof(struct el3_token_sign_response)) {
+		return E_RMM_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Pull attestation signing response from HES. */
+	err = plat_rmmd_el3_token_sign_pull_resp(
+			(struct el3_token_sign_response *)buf_pa);
+
+	spin_unlock(&lock);
+
+	return err;
+}
+
+static int rmmd_attest_get_attest_pub_key(uint64_t buf_pa, uint64_t *buf_size,
+				   uint64_t ecc_curve)
+{
+	int err;
+
+	err = validate_buffer_params(buf_pa, *buf_size);
+	if (err != 0) {
+		return err;
+	}
+
+	if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+		ERROR("Invalid ECC curve specified\n");
+		return E_RMM_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Get the Realm attestation public key from platform port. */
+	err = plat_rmmd_el3_token_sign_get_rak_pub(
+		(uintptr_t)buf_pa, buf_size, (unsigned int)ecc_curve);
+
+	spin_unlock(&lock);
+	if (err != 0) {
+		ERROR("Failed to get attestation public key from HES: %d.\n",
+		      err);
+		err = E_RMM_UNK;
+	}
+
+
+	return err;
+}
+
+uint64_t rmmd_el3_token_sign(void *handle, uint64_t opcode, uint64_t x2,
+				    uint64_t x3, uint64_t x4)
+{
+	int ret;
+
+	switch (opcode) {
+	case RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP:
+		ret = rmmd_el3_token_sign_push_req(x2, x3);
+		SMC_RET1(handle, ret);
+	case RMM_EL3_TOKEN_SIGN_PULL_RESP_OP:
+		ret = rmmd_el3_token_sign_pull_resp(x2, x3);
+		SMC_RET1(handle, ret);
+	case RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP:
+		ret = rmmd_attest_get_attest_pub_key(x2, &x3, x4);
+		SMC_RET2(handle, ret, x3);
+	default:
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 6ccb003..d063ea3 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);
@@ -435,6 +441,21 @@
 	return ret;
 }
 
+static int rmm_el3_ifc_get_feat_register(uint64_t feat_reg_idx,
+					 uint64_t *feat_reg)
+{
+	if (feat_reg_idx != RMM_EL3_FEAT_REG_0_IDX) {
+		ERROR("RMMD: Failed to get feature register %ld\n", feat_reg_idx);
+		return E_RMM_INVAL;
+	}
+
+	*feat_reg = 0UL;
+#if RMMD_ENABLE_EL3_TOKEN_SIGN
+	*feat_reg |= RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK;
+#endif
+	return E_RMM_OK;
+}
+
 /*******************************************************************************
  * This function handles RMM-EL3 interface SMCs
  ******************************************************************************/
@@ -442,6 +463,7 @@
 				uint64_t x3, uint64_t x4, void *cookie,
 				void *handle, uint64_t flags)
 {
+	uint64_t remaining_len = 0UL;
 	uint32_t src_sec_state;
 	int ret;
 
@@ -467,12 +489,18 @@
 		ret = gpt_undelegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
 		SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
 	case RMM_ATTEST_GET_PLAT_TOKEN:
-		ret = rmmd_attest_get_platform_token(x1, &x2, x3);
-		SMC_RET2(handle, ret, x2);
+		ret = rmmd_attest_get_platform_token(x1, &x2, x3, &remaining_len);
+		SMC_RET3(handle, ret, x2, remaining_len);
 	case RMM_ATTEST_GET_REALM_KEY:
 		ret = rmmd_attest_get_signing_key(x1, &x2, x3);
 		SMC_RET2(handle, ret, x2);
-
+	case RMM_EL3_FEATURES:
+		ret = rmm_el3_ifc_get_feat_register(x1, &x2);
+		SMC_RET2(handle, ret, x2);
+#if RMMD_ENABLE_EL3_TOKEN_SIGN
+	case RMM_EL3_TOKEN_SIGN:
+		return rmmd_el3_token_sign(handle, x1, x2, x3, x4);
+#endif
 	case RMM_BOOT_COMPLETE:
 		VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
 		rmmd_rmm_sync_exit(x1);
diff --git a/services/std_svc/rmmd/rmmd_private.h b/services/std_svc/rmmd/rmmd_private.h
index 4954a43..0ce104d 100644
--- a/services/std_svc/rmmd/rmmd_private.h
+++ b/services/std_svc/rmmd/rmmd_private.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
  */
@@ -47,9 +47,12 @@
 
 /* Functions implementing attestation utilities for RMM */
 int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
-				   uint64_t c_size);
+				   uint64_t c_size,
+				   uint64_t *remaining_len);
 int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
 				uint64_t ecc_curve);
+uint64_t rmmd_el3_token_sign(void *handle, uint64_t x1, uint64_t x2,
+				    uint64_t x3, uint64_t x4);
 
 /* Assembly helpers */
 uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index 59a1673..01cc131 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -744,7 +744,9 @@
 			return SDEI_ENOMEM;
 
 		/* The returned mapping must be dynamic */
-		assert(is_map_dynamic(map));
+		if (!is_map_dynamic(map)) {
+			return SDEI_ENOMEM;
+		}
 
 		/*
 		 * We cannot assert for bound maps here, as we might be racing
diff --git a/services/std_svc/spm/el3_spmc/spmc_setup.c b/services/std_svc/spm/el3_spmc/spmc_setup.c
index 609d968..f7357f1 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,23 @@
 		      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,
-		      mmu_cfg_params[MMU_CFG_TCR]);
+	write_ctx_tcr_el1_reg_errata(ctx, mmu_cfg_params[MMU_CFG_TCR]);
 
-	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);
+	sctlr_el1_val = read_ctx_sctlr_el1_reg_errata(ctx);
 
-	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 +356,7 @@
 		/* Enable MMU. */
 		SCTLR_M_BIT;
 
-	sctlr_el1 &= ~(
+	sctlr_el1_val &= ~(
 		/* Explicit data accesses at EL0 are little-endian. */
 		SCTLR_E0E_BIT |
 		/*
@@ -369,7 +368,8 @@
 		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 */
+	write_ctx_sctlr_el1_reg_errata(ctx, sctlr_el1_val);
 }
 
 static void spmc_el0_sp_setup_system_registers(struct secure_partition_desc *sp,
@@ -383,10 +383,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_arch_timer(get_el1_sysregs_ctx(ctx), cntkctl_el1,
 		      EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT);
 #endif
 
@@ -397,7 +397,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_main.c b/services/std_svc/spm/spm_mm/spm_mm_main.c
index 1ff7bb7..34e2c00 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_main.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, 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 <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/el3_runtime/simd_ctx.h>
 #include <lib/smccc.h>
 #include <lib/spinlock.h>
 #include <lib/utils.h>
@@ -190,13 +191,13 @@
 	uint64_t rc;
 	sp_context_t *sp_ptr = &sp_ctx;
 
-#if CTX_INCLUDE_FPREGS
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
 	/*
-	 * SP runs to completion, no need to restore FP registers of secure context.
-	 * Save FP registers only for non secure context.
+	 * SP runs to completion, no need to restore FP/SVE registers of secure context.
+	 * Save FP/SVE registers only for non secure context.
 	 */
-	fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
-#endif
+	simd_ctx_save(NON_SECURE, false);
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
 
 	/* Wait until the Secure Partition is idle and set it to busy. */
 	sp_state_wait_switch(sp_ptr, SP_STATE_IDLE, SP_STATE_BUSY);
@@ -216,13 +217,13 @@
 	assert(sp_ptr->state == SP_STATE_BUSY);
 	sp_state_set(sp_ptr, SP_STATE_IDLE);
 
-#if CTX_INCLUDE_FPREGS
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
 	/*
-	 * SP runs to completion, no need to save FP registers of secure context.
-	 * Restore only non secure world FP registers.
+	 * SP runs to completion, no need to save FP/SVE registers of secure context.
+	 * Restore only non secure world FP/SVE registers.
 	 */
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
-#endif
+	simd_ctx_restore(NON_SECURE);
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
 
 	return rc;
 }
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..de05459 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,17 @@
 		      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_tcr_el1_reg_errata(ctx, mmu_cfg_params[MMU_CFG_TCR]);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TCR_EL1,
-		      mmu_cfg_params[MMU_CFG_TCR]);
-
-	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);
+	sctlr_el1_val = read_ctx_sctlr_el1_reg_errata(ctx);
 
-	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 +154,7 @@
 		SCTLR_M_BIT
 	;
 
-	sctlr_el1 &= ~(
+	sctlr_el1_val &= ~(
 		/* Explicit data accesses at EL0 are little-endian. */
 		SCTLR_E0E_BIT							|
 		/*
@@ -168,7 +166,8 @@
 		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 */
+	write_ctx_sctlr_el1_reg_errata(ctx, sctlr_el1_val);
 
 	/*
 	 * Setup other system registers
@@ -176,10 +175,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 +188,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..3953b24 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 */
@@ -231,6 +215,14 @@
 	cm_el2_sysregs_context_save(NON_SECURE);
 #else
 	cm_el1_sysregs_context_save(NON_SECURE);
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	/*
+	 * The hint bit denoting absence of SVE live state is effectively false
+	 * in this scenario where execution was trapped to EL3 due to FIQ.
+	 */
+	simd_ctx_save(NON_SECURE, false);
+#endif
 #endif
 
 	/* Convey the event to the SPMC through the FFA_INTERRUPT interface. */
@@ -246,9 +238,16 @@
 	/* Mark current core as handling a secure interrupt. */
 	ctx->secure_interrupt_ongoing = true;
 
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	simd_ctx_restore(SECURE);
+#endif
 	rc = spmd_spm_core_sync_entry(ctx);
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	simd_ctx_save(SECURE, false);
+#endif
 	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;
@@ -257,6 +256,10 @@
 	cm_el2_sysregs_context_restore(NON_SECURE);
 #else
 	cm_el1_sysregs_context_restore(NON_SECURE);
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	simd_ctx_restore(NON_SECURE);
+#endif
 #endif
 	cm_set_next_eret_context(NON_SECURE);
 
@@ -677,6 +680,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)) {
@@ -693,6 +697,10 @@
 	cm_el2_sysregs_context_save(secure_state_in);
 #else
 	cm_el1_sysregs_context_save(secure_state_in);
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	/* Forward the hint bit denoting the absence of SVE live state. */
+	simd_ctx_save(secure_state_in, (!secure_origin && (is_sve_hint_set(flags) == true)));
+#endif
 #endif
 
 	/* Restore outgoing security state */
@@ -700,9 +708,13 @@
 	cm_el2_sysregs_context_restore(secure_state_out);
 #else
 	cm_el1_sysregs_context_restore(secure_state_out);
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	simd_ctx_restore(secure_state_out);
+#endif
 #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 +727,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 +744,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));
@@ -797,19 +809,6 @@
 		&& (ffa_endpoint_source(ep) == spmc_attrs.spmc_id));
 }
 
-/******************************************************************************
- * spmd_handle_spmc_message
- *****************************************************************************/
-static int spmd_handle_spmc_message(unsigned long long msg,
-		unsigned long long parm1, unsigned long long parm2,
-		unsigned long long parm3, unsigned long long parm4)
-{
-	VERBOSE("%s %llx %llx %llx %llx %llx\n", __func__,
-		msg, parm1, parm2, parm3, parm4);
-
-	return -EINVAL;
-}
-
 /*******************************************************************************
  * This function forwards FF-A SMCs to either the main SPMD handler or the
  * SPMC at EL3, depending on the origin security state, if enabled.
@@ -852,7 +851,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 +861,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));
@@ -1112,6 +1110,7 @@
 
 	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
 	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+	case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
 		/*
 		 * Regardless of secure_origin, SPMD logical partitions cannot
 		 * handle direct messages. They can only initiate direct
@@ -1145,35 +1144,8 @@
 			}
 		}
 		if (secure_origin && spmd_is_spmc_message(x1)) {
-			ret = spmd_handle_spmc_message(x3, x4,
-				SMC_GET_GP(handle, CTX_GPREG_X5),
-				SMC_GET_GP(handle, CTX_GPREG_X6),
-				SMC_GET_GP(handle, CTX_GPREG_X7));
-
-			SMC_RET8(handle, FFA_SUCCESS_SMC32,
-				FFA_TARGET_INFO_MBZ, ret,
-				FFA_PARAM_MBZ, FFA_PARAM_MBZ,
-				FFA_PARAM_MBZ, FFA_PARAM_MBZ,
-				FFA_PARAM_MBZ);
-		} else {
-			/* Forward direct message to the other world */
-			return spmd_smc_forward(smc_fid, secure_origin,
-						x1, x2, x3, x4, cookie,
-						handle, flags);
-		}
-		break; /* Not reached */
-
-	case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
-		if (!secure_origin) {
-			/* Validate source endpoint is non-secure for non-secure caller. */
-			if (ffa_is_secure_world_id(ffa_endpoint_source(x1))) {
 				return spmd_ffa_error_return(handle,
-						FFA_ERROR_INVALID_PARAMETER);
-			}
-		}
-		/* FFA_MSG_SEND_DIRECT_REQ2 not used for framework messages. */
-		if (secure_origin && spmd_is_spmc_message(x1)) {
-			return spmd_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
+						FFA_ERROR_DENIED);
 		} else {
 			/* Forward direct message to the other world */
 			return spmd_smc_forward(smc_fid, secure_origin,
@@ -1184,6 +1156,7 @@
 
 	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+	case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
 		if (secure_origin && (spmd_is_spmc_message(x1) ||
 		    is_spmd_logical_sp_dir_req_in_progress(ctx))) {
 			spmd_spm_core_sync_exit(0ULL);
@@ -1194,12 +1167,6 @@
 						handle, flags);
 		}
 		break; /* Not reached */
-	case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
-		/* Forward direct message to the other world */
-		return spmd_smc_forward(smc_fid, secure_origin,
-					x1, x2, x3, x4, cookie,
-					handle, flags);
-		break; /* Not reached */
 	case FFA_RX_RELEASE:
 	case FFA_RXTX_MAP_SMC32:
 	case FFA_RXTX_MAP_SMC64:
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 7a53437..7bfee7d 100644
--- a/tools/amlogic/Makefile
+++ b/tools/amlogic/Makefile
@@ -5,8 +5,6 @@
 # https://spdx.org/licenses
 #
 
-toolchains := host
-
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 16f4aa3..ce12a66 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -10,8 +10,6 @@
 BINARY		:= $(notdir ${CRTTOOL})
 COT		:= tbbr
 
-toolchains := host
-
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index e0ecdae..f7adfab 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -65,35 +65,35 @@
 	const char *desc;	/* Key description (debug purposes) */
 	char *fn;		/* Filename to load/store the key */
 	EVP_PKEY *key;		/* Key container */
-} key_t;
+} cert_key_t;
 
 /* Exported API */
 int key_init(void);
-key_t *key_get_by_opt(const char *opt);
+cert_key_t *key_get_by_opt(const char *opt);
 #if !USING_OPENSSL3
-int key_new(key_t *key);
+int key_new(cert_key_t *key);
 #endif
-int key_create(key_t *key, int type, int key_bits);
-unsigned int key_load(key_t *key);
-int key_store(key_t *key);
+int key_create(cert_key_t *key, int type, int key_bits);
+unsigned int key_load(cert_key_t *key);
+int key_store(cert_key_t *key);
 void key_cleanup(void);
 
 /* Macro to register the keys used in the CoT */
 #define REGISTER_KEYS(_keys) \
-	key_t *def_keys = &_keys[0]; \
+	cert_key_t *def_keys = &_keys[0]; \
 	const unsigned int num_def_keys = sizeof(_keys)/sizeof(_keys[0])
 
 /* Macro to register the platform defined keys used in the CoT */
 #define PLAT_REGISTER_KEYS(_pdef_keys) \
-	key_t *pdef_keys = &_pdef_keys[0]; \
+	cert_key_t *pdef_keys = &_pdef_keys[0]; \
 	const unsigned int num_pdef_keys = sizeof(_pdef_keys)/sizeof(_pdef_keys[0])
 
 /* Exported variables */
-extern key_t *def_keys;
+extern cert_key_t *def_keys;
 extern const unsigned int num_def_keys;
-extern key_t *pdef_keys;
+extern cert_key_t *pdef_keys;
 extern const unsigned int num_pdef_keys;
 
-extern key_t *keys;
+extern cert_key_t *keys;
 extern unsigned int num_keys;
 #endif /* KEY_H */
diff --git a/tools/cert_create/src/cca/cot.c b/tools/cert_create/src/cca/cot.c
index 372d908..658b81c 100644
--- a/tools/cert_create/src/cca/cot.c
+++ b/tools/cert_create/src/cca/cot.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
  */
@@ -410,7 +410,7 @@
 REGISTER_EXTENSIONS(cot_ext);
 
 /* Keys used to establish the chain of trust. */
-static key_t cot_keys[] = {
+static cert_key_t cot_keys[] = {
 	[ROT_KEY] = {
 		.id = ROT_KEY,
 		.opt = "rot-key",
diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c
index 81a7d75..d2c15bf 100644
--- a/tools/cert_create/src/dualroot/cot.c
+++ b/tools/cert_create/src/dualroot/cot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -536,7 +536,7 @@
 
 
 /* Keys used to establish the chain of trust. */
-static key_t cot_keys[] = {
+static cert_key_t cot_keys[] = {
 	[ROT_KEY] = {
 		.id = ROT_KEY,
 		.opt = "rot-key",
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index f6ceeda..190c096 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.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
  */
@@ -26,14 +26,14 @@
 
 #define MAX_FILENAME_LEN		1024
 
-key_t *keys;
+cert_key_t *keys;
 unsigned int num_keys;
 
 #if !USING_OPENSSL3
 /*
  * Create a new key container
  */
-int key_new(key_t *key)
+int key_new(cert_key_t *key)
 {
 	/* Create key pair container */
 	key->key = EVP_PKEY_new();
@@ -45,7 +45,7 @@
 }
 #endif
 
-static int key_create_rsa(key_t *key, int key_bits)
+static int key_create_rsa(cert_key_t *key, int key_bits)
 {
 #if USING_OPENSSL3
 	EVP_PKEY *rsa = EVP_RSA_gen(key_bits);
@@ -99,7 +99,7 @@
 
 #ifndef OPENSSL_NO_EC
 #if USING_OPENSSL3
-static int key_create_ecdsa(key_t *key, int key_bits, const char *curve)
+static int key_create_ecdsa(cert_key_t *key, int key_bits, const char *curve)
 {
 	EVP_PKEY *ec = EVP_EC_gen(curve);
 	if (ec == NULL) {
@@ -111,7 +111,7 @@
 	return 1;
 }
 
-static int key_create_ecdsa_nist(key_t *key, int key_bits)
+static int key_create_ecdsa_nist(cert_key_t *key, int key_bits)
 {
 	if (key_bits == 384) {
 		return key_create_ecdsa(key, key_bits, "secp384r1");
@@ -121,17 +121,17 @@
 	}
 }
 
-static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
+static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits)
 {
 	return key_create_ecdsa(key, key_bits, "brainpoolP256r1");
 }
 
-static int key_create_ecdsa_brainpool_t(key_t *key, int key_bits)
+static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits)
 {
 	return key_create_ecdsa(key, key_bits, "brainpoolP256t1");
 }
 #else
-static int key_create_ecdsa(key_t *key, int key_bits, const int curve_id)
+static int key_create_ecdsa(cert_key_t *key, int key_bits, const int curve_id)
 {
 	EC_KEY *ec;
 
@@ -158,7 +158,7 @@
 	return 0;
 }
 
-static int key_create_ecdsa_nist(key_t *key, int key_bits)
+static int key_create_ecdsa_nist(cert_key_t *key, int key_bits)
 {
 	if (key_bits == 384) {
 		return key_create_ecdsa(key, key_bits, NID_secp384r1);
@@ -169,12 +169,12 @@
 }
 
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
-static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
+static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits)
 {
 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256r1);
 }
 
-static int key_create_ecdsa_brainpool_t(key_t *key, int key_bits)
+static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits)
 {
 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1);
 }
@@ -182,7 +182,7 @@
 #endif /* USING_OPENSSL3 */
 #endif /* OPENSSL_NO_EC */
 
-typedef int (*key_create_fn_t)(key_t *key, int key_bits);
+typedef int (*key_create_fn_t)(cert_key_t *key, int key_bits);
 static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
 	[KEY_ALG_RSA] = key_create_rsa,
 #ifndef OPENSSL_NO_EC
@@ -194,7 +194,7 @@
 #endif /* OPENSSL_NO_EC */
 };
 
-int key_create(key_t *key, int type, int key_bits)
+int key_create(cert_key_t *key, int type, int key_bits)
 {
 	if (type >= KEY_ALG_MAX_NUM) {
 		printf("Invalid key type\n");
@@ -243,7 +243,7 @@
 
 }
 
-unsigned int key_load(key_t *key)
+unsigned int key_load(cert_key_t *key)
 {
 	if (key->fn == NULL) {
 		VERBOSE("Key not specified\n");
@@ -273,7 +273,7 @@
 	return KEY_ERR_NONE;
 }
 
-int key_store(key_t *key)
+int key_store(cert_key_t *key)
 {
 	FILE *fp;
 
@@ -301,7 +301,7 @@
 int key_init(void)
 {
 	cmd_opt_t cmd_opt;
-	key_t *key;
+	cert_key_t *key;
 	unsigned int i;
 
 	keys = malloc((num_def_keys * sizeof(def_keys[0]))
@@ -341,9 +341,9 @@
 	return 0;
 }
 
-key_t *key_get_by_opt(const char *opt)
+cert_key_t *key_get_by_opt(const char *opt)
 {
-	key_t *key;
+	cert_key_t *key;
 	unsigned int i;
 
 	/* Sequential search. This is not a performance concern since the number
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index edc2d68..aa21206 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -4,6 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#define _POSIX_C_SOURCE 200809L
+
 #include <assert.h>
 #include <ctype.h>
 #include <getopt.h>
@@ -69,16 +71,6 @@
 static const char build_msg[] = "Built : " __TIME__ ", " __DATE__;
 static const char platform_msg[] = PLAT_MSG;
 
-static char *strdup(const char *str)
-{
-	int n = strlen(str) + 1;
-	char *dup = malloc(n);
-	if (dup) {
-		strcpy(dup, str);
-	}
-	return dup;
-}
-
 static const char *key_algs_str[] = {
 	[KEY_ALG_RSA] = "rsa",
 #ifndef OPENSSL_NO_EC
@@ -178,7 +170,7 @@
 {
 	cert_t *cert;
 	ext_t *ext;
-	key_t *key;
+	cert_key_t *key;
 	int i, j;
 	bool valid_size;
 
@@ -303,7 +295,7 @@
 	STACK_OF(X509_EXTENSION) * sk;
 	X509_EXTENSION *cert_ext = NULL;
 	ext_t *ext;
-	key_t *key;
+	cert_key_t *key;
 	cert_t *cert;
 	FILE *file;
 	int i, j, ext_nid, nvctr;
diff --git a/tools/cert_create/src/tbbr/tbb_key.c b/tools/cert_create/src/tbbr/tbb_key.c
index 5b84b6e..3d99067 100644
--- a/tools/cert_create/src/tbbr/tbb_key.c
+++ b/tools/cert_create/src/tbbr/tbb_key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
  *
  * The order of the keys must follow the enumeration specified in tbb_key.h
  */
-static key_t tbb_keys[] = {
+static cert_key_t tbb_keys[] = {
 	[ROT_KEY] = {
 		.id = ROT_KEY,
 		.opt = "rot-key",
diff --git a/tools/cot_dt2c/.gitignore b/tools/cot_dt2c/.gitignore
new file mode 100644
index 0000000..ad4a1f1
--- /dev/null
+++ b/tools/cot_dt2c/.gitignore
@@ -0,0 +1,176 @@
+# Created by https://www.toptal.com/developers/gitignore/api/python
+# Edit at https://www.toptal.com/developers/gitignore?templates=python
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+#   in version control.
+#   https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+### Python Patch ###
+# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
+poetry.toml
+
+# ruff
+.ruff_cache/
+
+# LSP config files
+pyrightconfig.json
+
+# End of https://www.toptal.com/developers/gitignore/api/python
diff --git a/tools/cot_dt2c/cot_dt2c/__init__.py b/tools/cot_dt2c/cot_dt2c/__init__.py
new file mode 100644
index 0000000..621c55a
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/__init__.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+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/cot_dt2c/cot_dt2c/__main__.py b/tools/cot_dt2c/cot_dt2c/__main__.py
new file mode 100644
index 0000000..5aa4a92
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/__main__.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+from cot_dt2c.cli import cli
+if __name__ == "__main__":
+    cli()
diff --git a/tools/cot_dt2c/cot_dt2c/cli.py b/tools/cot_dt2c/cot_dt2c/cli.py
new file mode 100644
index 0000000..d338430
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/cli.py
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+from pathlib import Path
+from cot_dt2c.cot_dt2c import generateMain
+from cot_dt2c.cot_dt2c import validateMain
+from cot_dt2c.cot_dt2c import visualizeMain
+from cot_dt2c.dt_validator import dtValidatorMain
+
+import click
+
+@click.group()
+@click.version_option()
+def cli():
+    pass
+
+@cli.command()
+@click.argument("inputfile", type=click.Path(dir_okay=True))
+@click.argument("outputfile", type=click.Path(dir_okay=True))
+def convert_to_c(inputfile, outputfile):
+    generateMain(inputfile, outputfile)
+
+@cli.command()
+@click.argument("inputfile", type=click.Path(dir_okay=True))
+def validate_cot(inputfile):
+    validateMain(inputfile)
+
+@cli.command()
+@click.argument("inputfile", type=click.Path(dir_okay=True))
+def visualize_cot(inputfile):
+    visualizeMain(inputfile)
+
+@cli.command()
+@click.argument("inputfiledir", type=click.Path(dir_okay=True))
+def validate_dt(inputfiledir):
+    dtValidatorMain(inputfiledir)
diff --git a/tools/cot_dt2c/cot_dt2c/cot_dt2c.py b/tools/cot_dt2c/cot_dt2c/cot_dt2c.py
new file mode 100644
index 0000000..4056aac
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/cot_dt2c.py
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import sys
+from cot_dt2c.cot_parser import COT
+
+def generateMain(input, output=None):
+    cot = COT(input, output)
+    cot.generate_c_file()
+
+def validateMain(input):
+    cot = COT(input)
+    if not cot.validate_nodes():
+        print("not a valid CoT DT file")
+
+def visualizeMain(input):
+    cot = COT(input)
+    cot.tree_visualization()
+
+if __name__=="__main__":
+    if (len(sys.argv) < 2):
+        print("usage: python3 " + sys.argv[0] + " [dtsi file path] [optional output c file path]")
+        exit()
+    if len(sys.argv) == 3:
+        generateMain(sys.argv[1], sys.argv[2])
+    if len(sys.argv) == 2:
+        validateMain(sys.argv[1])
diff --git a/tools/cot_dt2c/cot_dt2c/cot_parser.py b/tools/cot_dt2c/cot_dt2c/cot_parser.py
new file mode 100644
index 0000000..39e51db
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/cot_parser.py
@@ -0,0 +1,673 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import sys
+import re
+from pydevicetree.ast import CellArray, LabelReference
+from pydevicetree import Devicetree, Property, Node
+from pathlib import Path
+from typing import List, Optional
+
+class COT:
+    def __init__(self, inputfile: str, outputfile=None):
+        try:
+            self.tree = Devicetree.parseFile(inputfile)
+        except:
+            print("not a valid CoT DT file")
+            exit(1)
+
+        self.output = outputfile
+        self.input = inputfile
+        self.has_root = False
+
+        # edge cases
+        certs = self.get_all_certificates()
+        for c in certs:
+            if self.if_root(c):
+                if not c.get_fields("signing-key"):
+                    c.properties.append(Property("signing-key", CellArray([LabelReference("subject_pk")])))
+
+    def print_cert_info(self, node:Node):
+        img_id = node.get_field("image-id").values[0].replace('"', "")
+        sign_key = self.get_sign_key(node)
+        nv = self.get_nv_ctr(node)
+
+        info = "<b>name:</b> {}<br><b>image-id:</b> {}<br>{}{}{}"\
+                .format(node.name, img_id, "<b>root-certificate</b><br>" if self.if_root(node) else "", \
+                     "<b>signing-key:</b> " + self.extract_label(sign_key) + "<br>" if sign_key else "", \
+                     "<b>nv counter:</b> " + self.extract_label(nv) + "<br>" if nv else "")
+        return info
+
+    def print_data_info(self, node:Node):
+        oid = node.get_field("oid")
+        info = "<b>name:</b> {}<br><b>oid:</b> {}<br>" \
+                .format(node.name, oid)
+
+        return info
+
+    def print_img_info(self, node:Node):
+        hash = self.extract_label(node.get_fields("hash"))
+        img_id = node.get_field("image-id").values[0].replace('"', "")
+        info = "<b>name:</b> {}<br><b>image-id:</b> {}<br><b>hash:</b> {}"\
+                .format(node.name, img_id, hash)
+
+        return info
+
+    def tree_width(self, parent_set, root):
+        ans = 1
+        stack = [root]
+
+        while stack:
+            tmp_stack = []
+            while stack:
+                cur_node = stack.pop()
+                child = parent_set[cur_node]
+                for c in child:
+                    tmp_stack.append(c)
+
+            stack = tmp_stack.copy()
+            ans = max(ans, len(tmp_stack))
+
+        return ans
+
+    def resolve_lay(self, parent_set, lay, name_idx, root, bounds, break_name):
+        child = parent_set[root]
+
+        if len(child) == 0:
+            return
+
+        width = []
+        total_width = 0
+        for c in child:
+            w = self.tree_width(parent_set, c)
+            width.append(w)
+            total_width += w
+
+        allow_width = bounds[1] - bounds[0]
+        interval = allow_width / total_width
+        start = bounds[0]
+        for i, c in enumerate(child):
+            end = start + interval * width[i]
+            new_bounds = [start, end]
+            lay[name_idx[c]][0] = start + (end - start) / 2
+            if end - start < 0.28:
+                break_name.add(c)
+            start = end
+            self.resolve_lay(parent_set, lay, name_idx, c, new_bounds, break_name)
+
+    def tree_visualization(self):
+        import igraph
+        from igraph import Graph, EdgeSeq
+        import collections
+
+        cert = self.get_certificates()
+        pk = self.get_rot_keys()
+        nv = self.get_nv_counters()
+        image = self.get_images()
+
+        certs = cert.children
+        if pk:
+            pks = pk.children
+        else:
+            pks = []
+        nvs = nv.children
+        images = image.children
+
+        root_name = "CoT"
+
+        G = Graph()
+        detail = []
+        lay = []
+        name_idx = {}
+        parent_set = collections.defaultdict(list)
+
+        G.add_vertex(root_name)
+        detail.append("CoT Root")
+        name_idx[root_name] = len(lay)
+        lay.append([0,0])
+
+        G.add_vertex(cert.name)
+        G.add_edge(root_name, cert.name)
+        detail.append("All Certificates")
+        name_idx[cert.name] = len(lay)
+        lay.append([0, 1])
+        parent_set[root_name].append(cert.name)
+
+        if pk:
+            G.add_vertex(pk.name)
+            detail.append("All Public Trusted Key")
+            G.add_edge(root_name, pk.name)
+            name_idx[pk.name] = len(lay)
+            lay.append([-2.0, 1])
+            parent_set[root_name].append(pk.name)
+
+        G.add_vertex(nv.name)
+        detail.append("All NV Counters")
+        G.add_edge(root_name, nv.name)
+        name_idx[nv.name] = len(lay)
+        lay.append([2.0, 1])
+        parent_set[root_name].append(nv.name)
+
+        if pks:
+            for i, p in enumerate(pks):
+                G.add_vertex(p.name)
+                detail.append(self.print_data_info(p))
+                G.add_edge(pk.name, p.name)
+                name_idx[p.name] = len(lay)
+                parent_set[pk.name].append(p.name)
+                lay.append([0, lay[name_idx[pk.name]][1] + 1])
+
+        for c in certs:
+            G.add_vertex(c.name)
+            detail.append(self.print_cert_info(c))
+            name_idx[c.name] = len(lay)
+            if self.if_root(c):
+                G.add_edge(cert.name, c.name)
+                parent_set[cert.name].append(c.name)
+                lay.append([0, 2])
+            else:
+                parent = self.extract_label(c.get_fields("parent"))
+                G.add_edge(parent, c.name)
+                parent_set[parent].append(c.name)
+                lay.append([0, lay[name_idx[parent]][1] + 1])
+
+        for idx, i in enumerate(images):
+            G.add_vertex(i.name)
+            detail.append(self.print_img_info(i))
+            parent = self.extract_label(i.get_fields("parent"))
+            G.add_edge(parent, i.name)
+            parent_set[parent].append(i.name)
+            name_idx[i.name] = len(lay)
+            lay.append([0, lay[name_idx[parent]][1] + 1])
+
+        for i, n in enumerate(nvs):
+            G.add_vertex(n.name)
+            detail.append(self.print_data_info(n))
+            G.add_edge(nv.name, n.name)
+            name_idx[n.name] = len(lay)
+            parent_set[nv.name].append(n.name)
+            lay.append([0, lay[name_idx[nv.name]][1] + 1])
+
+        break_name = set()
+        self.resolve_lay(parent_set, lay, name_idx, root_name, [-3, 3], break_name)
+        #lay = G.layout('rt')
+
+        numVertex = len(G.get_vertex_dataframe())
+        vertices = G.get_vertex_dataframe()
+        v_label = []
+
+        for i in vertices['name']:
+            if i in break_name and len(i) > 10:
+                middle = len(i) // 2
+                v_label.append(i[:middle] + "<br>" + i[middle:])
+            else:
+                v_label.append(i)
+
+        position = {k: lay[k] for k in range(numVertex)}
+        Y = [lay[k][1] for k in range(numVertex)]
+        M = max(Y)
+
+        es = EdgeSeq(G) # sequence of edges
+        E = [e.tuple for e in G.es] # list of edges
+
+        L = len(position)
+        Xn = [position[k][0] for k in range(L)]
+        Yn = [2*M-position[k][1] for k in range(L)]
+        Xe = []
+        Ye = []
+        for edge in E:
+            Xe += [position[edge[0]][0], position[edge[1]][0], None]
+            Ye += [2*M-position[edge[0]][1], 2*M-position[edge[1]][1], None]
+
+        labels = v_label
+
+        import plotly.graph_objects as go
+        fig = go.Figure()
+        fig.add_trace(go.Scatter(x = Xe,
+                        y = Ye,
+                        mode = 'lines',
+                        line = dict(color='rgb(210,210,210)', width=2),
+                        hoverinfo = 'none'
+                        ))
+        fig.add_trace(go.Scatter(x = Xn,
+                        y = Yn,
+                        mode = 'markers',
+                        name = 'detail',
+                        marker = dict(symbol = 'circle-dot',
+                                        size = 50,
+                                        color = 'rgba(135, 206, 250, 0.8)',    #'#DB4551',
+                                        line = dict(color='MediumPurple', width=3)
+                                        ),
+                        text=detail,
+                        hoverinfo='text',
+                        hovertemplate =
+                            '<b>Detail</b><br>'
+                            '%{text}',
+                        opacity=0.8
+                        ))
+
+        def make_annotations(pos, text, font_size=10, font_color='rgb(0,0,0)'):
+            L = len(pos)
+            if len(text) != L:
+                raise ValueError('The lists pos and text must have the same len')
+            annotations = []
+            for k in range(L):
+                annotations.append(
+                    dict(
+                        text = labels[k],
+                        x = pos[k][0], y = 2*M-position[k][1],
+                        xref = 'x1', yref = 'y1',
+                        font = dict(color = font_color, size = font_size),
+                        showarrow = False)
+                )
+            return annotations
+
+        axis = dict(showline=False, # hide axis line, grid, ticklabels and  title
+            zeroline=False,
+            showgrid=False,
+            showticklabels=False,
+            )
+
+        fig.update_layout(title= 'CoT Device Tree',
+                    annotations=make_annotations(position, v_label),
+                    font_size=12,
+                    showlegend=False,
+                    xaxis=axis,
+                    yaxis=axis,
+                    margin=dict(l=40, r=40, b=85, t=100),
+                    hovermode='closest',
+                    plot_bgcolor='rgb(248,248,248)'
+                    )
+
+        fig.show()
+
+        return
+
+    def if_root(self, node:Node) -> bool:
+        for p in node.properties:
+            if p.name == "root-certificate":
+                return True
+        return False
+
+    def get_sign_key(self, node:Node):
+        for p in node.properties:
+            if p.name == "signing-key":
+                return p.values
+
+        return None
+
+    def get_nv_ctr(self, node:Node):
+        for nv in node.properties:
+            if nv.name == "antirollback-counter":
+                return nv.values
+
+        return None
+
+    def extract_label(self, label) -> str:
+        if not label:
+            return label
+        return label[0].label.name
+
+    def get_auth_data(self, node:Node):
+        return node.children
+
+    def format_auth_data_val(self, node:Node, cert:Node):
+        type_desc = node.name
+        ptr = type_desc + "_buf"
+        len = "HASH_DER_LEN"
+        if re.search("_pk$", type_desc):
+            len = "PK_DER_LEN"
+
+        # edge case
+        if not self.if_root(cert) and "key_cert" in cert.name:
+            if "content_pk" in ptr:
+                ptr = "content_pk_buf"
+
+        return type_desc, ptr, len
+
+    def get_node(self, nodes: List[Node], name: str) -> Node:
+        for i in nodes:
+            if i.name == name:
+                return i
+
+    def get_certificates(self) -> Node:
+        children = self.tree.children
+        for i in children:
+            if i.name == "cot":
+                return self.get_node(i.children, "manifests")
+
+    def get_images(self)-> Node:
+        children = self.tree.children
+        for i in children:
+            if i.name == "cot":
+                return self.get_node(i.children, "images")
+
+    def get_nv_counters(self) -> Node:
+        children = self.tree.children
+        return self.get_node(children, "non_volatile_counters")
+
+    def get_rot_keys(self) -> Node:
+        children = self.tree.children
+        return self.get_node(children, "rot_keys")
+
+    def get_all_certificates(self) -> Node:
+        cert = self.get_certificates()
+        return cert.children
+
+    def get_all_images(self) -> Node:
+        image = self.get_images()
+        return image.children
+
+    def get_all_nv_counters(self) -> Node:
+        nv = self.get_nv_counters()
+        return nv.children
+
+    def get_all_pks(self) -> Node:
+        pk = self.get_rot_keys()
+        if not pk:
+            return []
+        return pk.children
+
+    def validate_cert(self, node:Node) -> bool:
+        valid = True
+        if not node.has_field("image-id"):
+            print("{} missing mandatory attribute image-id".format(node.name))
+            valid = False
+
+        if not node.has_field("root-certificate"):
+            if not node.has_field("parent"):
+                print("{} missing mandatory attribute parent".format(node.name))
+                valid = False
+            else:
+                # check if refer to non existing parent
+                certs = self.get_all_certificates()
+                found = False
+                for c in certs:
+                    if c.name == self.extract_label(node.get_fields("parent")):
+                        found = True
+
+                if not found:
+                    print("{} refer to non existing parent".format(node.name))
+                    valid = False
+
+        else:
+            self.has_root = True
+
+        child = node.children
+        if child:
+            for c in child:
+                if not c.has_field("oid"):
+                    print("{} missing mandatory attribute oid".format(c.name))
+                    valid = False
+
+        return valid
+
+    def validate_img(self, node:Node) -> bool:
+        valid = True
+        if not node.has_field("image-id"):
+            print("{} missing mandatory attribute image-id".format(node.name))
+            valid = False
+
+        if not node.has_field("parent"):
+            print("{} missing mandatory attribute parent".format(node.name))
+            valid = False
+
+        if not node.has_field("hash"):
+            print("{} missing mandatory attribute hash".format(node.name))
+            valid = False
+
+        # check if refer to non existing parent
+        certs = self.get_all_certificates()
+        found = False
+        for c in certs:
+            if c.name == self.extract_label(node.get_fields("parent")):
+                found = True
+
+        if not found:
+            print("{} refer to non existing parent".format(node.name))
+            valid = False
+
+        return valid
+
+    def validate_nodes(self) -> bool:
+        valid = True
+
+        certs = self.get_all_certificates()
+        images = self.get_all_images()
+
+        for n in certs:
+            node_valid = self.validate_cert(n)
+            valid = valid and node_valid
+
+        for i in images:
+            node_valid = self.validate_img(i)
+            valid = valid and node_valid
+
+        if not self.has_root:
+            print("missing root certificate")
+
+        return valid
+
+    def include_to_c(self, f):
+        f.write("#include <stddef.h>\n")
+        f.write("#include <mbedtls/version.h>\n")
+        f.write("#include <common/tbbr/cot_def.h>\n")
+        f.write("#include <drivers/auth/auth_mod.h>\n")
+        f.write("#include <platform_def.h>\n\n")
+        return
+
+    def generate_header(self, output):
+        self.include_to_c(output)
+
+    def all_cert_to_c(self, f):
+        certs = self.get_all_certificates()
+        for c in certs:
+            self.cert_to_c(c, f)
+
+        f.write("\n")
+
+    def cert_to_c(self, node: Node, f):
+        node_image_id: int = node.get_field("image-id")
+
+        f.write(f"static const auth_img_desc_t {node.name} = {{\n")
+        f.write(f"\t.img_id = {node_image_id},\n")
+        f.write("\t.img_type = IMG_CERT,\n")
+
+        if not self.if_root(node):
+            node_parent: Node = node.get_field("parent")
+
+            f.write(f"\t.parent = &{node_parent.label.name},\n")
+        else:
+            f.write("\t.parent = NULL,\n")
+
+        sign = self.get_sign_key(node)
+        nv_ctr = self.get_nv_ctr(node)
+
+        if sign or nv_ctr:
+            f.write("\t.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {\n")
+
+        if sign:
+            f.write("\t\t[0] = {\n")
+            f.write("\t\t\t.type = AUTH_METHOD_SIG,\n")
+            f.write("\t\t\t.param.sig = {\n")
+
+            f.write("\t\t\t\t.pk = &{},\n".format(self.extract_label(sign)))
+            f.write("\t\t\t\t.sig = &sig,\n")
+            f.write("\t\t\t\t.alg = &sig_alg,\n")
+            f.write("\t\t\t\t.data = &raw_data\n")
+            f.write("\t\t\t}\n")
+            f.write("\t\t}}{}\n".format("," if nv_ctr else ""))
+
+        if nv_ctr:
+            f.write("\t\t[1] = {\n")
+            f.write("\t\t\t.type = AUTH_METHOD_NV_CTR,\n")
+            f.write("\t\t\t.param.nv_ctr = {\n")
+
+            f.write("\t\t\t\t.cert_nv_ctr = &{},\n".format(self.extract_label(nv_ctr)))
+            f.write("\t\t\t\t.plat_nv_ctr = &{}\n".format(self.extract_label(nv_ctr)))
+
+            f.write("\t\t\t}\n")
+            f.write("\t\t}\n")
+
+        f.write("\t},\n")
+
+        auth_data = self.get_auth_data(node)
+        if auth_data:
+            f.write("\t.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {\n")
+
+            for i, d in enumerate(auth_data):
+                type_desc, ptr, data_len = self.format_auth_data_val(d, node)
+
+                f.write("\t\t[{}] = {{\n".format(i))
+                f.write("\t\t\t.type_desc = &{},\n".format(type_desc))
+                f.write("\t\t\t.data = {\n")
+
+                f.write("\t\t\t\t.ptr = (void *){},\n".format(ptr))
+
+                f.write("\t\t\t\t.len = (unsigned int){}\n".format(data_len))
+                f.write("\t\t\t}\n")
+
+                f.write("\t\t}}{}\n".format("," if i != len(auth_data) - 1 else ""))
+
+            f.write("\t}\n")
+
+        f.write("};\n\n")
+
+        return
+
+
+    def img_to_c(self, node:Node, f):
+        node_image_id: int = node.get_field("image-id")
+        node_parent: Node = node.get_field("parent")
+        node_hash: Node = node.get_field("hash")
+
+        f.write(f"static const auth_img_desc_t {node.name} = {{\n")
+        f.write(f"\t.img_id = {node_image_id},\n")
+        f.write("\t.img_type = IMG_RAW,\n")
+        f.write(f"\t.parent = &{node_parent.label.name},\n")
+        f.write("\t.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {\n")
+
+        f.write("\t\t[0] = {\n")
+        f.write("\t\t\t.type = AUTH_METHOD_HASH,\n")
+        f.write("\t\t\t.param.hash = {\n")
+        f.write("\t\t\t\t.data = &raw_data,\n")
+        f.write(f"\t\t\t\t.hash = &{node_hash.label.name}\n")
+        f.write("\t\t\t}\n")
+
+        f.write("\t\t}\n")
+        f.write("\t}\n")
+        f.write("};\n\n")
+
+        return
+
+    def all_img_to_c(self, f):
+        images = self.get_all_images()
+        for i in images:
+            self.img_to_c(i, f)
+
+        f.write("\n")
+
+    def nv_to_c(self, f):
+        nv_ctr = self.get_all_nv_counters()
+
+        for nv in nv_ctr:
+            nv_oid: str = nv.get_field("oid")
+
+            f.write(f"static auth_param_type_desc_t {nv.name} = "\
+                    f"AUTH_PARAM_TYPE_DESC(AUTH_PARAM_NV_CTR, \"{nv_oid}\");\n")
+
+        f.write("\n")
+
+        return
+
+    def pk_to_c(self, f):
+        pks = self.get_all_pks()
+
+        for p in pks:
+            pk_oid: str = p.get_field("oid")
+
+            f.write(f"static auth_param_type_desc_t {p.name} = "\
+                    f"AUTH_PARAM_TYPE_DESC(AUTH_PARAM_PUB_KEY, \"{pk_oid}\");\n")
+
+        f.write("\n")
+        return
+
+    def buf_to_c(self, f):
+        certs = self.get_all_certificates()
+
+        buffers = set()
+
+        for c in certs:
+            auth_data = self.get_auth_data(c)
+
+            for a in auth_data:
+                type_desc, ptr, data_len = self.format_auth_data_val(a, c)
+
+                if not ptr in buffers:
+                    f.write(f"static unsigned char {ptr}[{data_len}];\n")
+                    buffers.add(ptr)
+
+        f.write("\n")
+
+    def param_to_c(self, f):
+        f.write("static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(AUTH_PARAM_PUB_KEY, 0);\n")
+        f.write("static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(AUTH_PARAM_SIG, 0);\n")
+        f.write("static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(AUTH_PARAM_SIG_ALG, 0);\n")
+        f.write("static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(AUTH_PARAM_RAW_DATA, 0);\n")
+        f.write("\n")
+
+        certs = self.get_all_certificates()
+        for c in certs:
+            hash = c.children
+            for h in hash:
+                name = h.name
+                oid = h.get_field("oid")
+
+                if re.search("_pk$", name):
+                    ty = "AUTH_PARAM_PUB_KEY"
+                elif re.search("_hash$", name):
+                    ty = "AUTH_PARAM_HASH"
+
+                f.write(f"static auth_param_type_desc_t {name} = "\
+                    f"AUTH_PARAM_TYPE_DESC({ty}, \"{oid}\");\n")
+
+        f.write("\n")
+
+    def cot_to_c(self, f):
+        certs = self.get_all_certificates()
+        images = self.get_all_images()
+
+        f.write("static const auth_img_desc_t * const cot_desc[] = {\n")
+
+        for i, c in enumerate(certs):
+            c_image_id: int = c.get_field("image-id")
+
+            f.write(f"\t[{c_image_id}]	=	&{c.name},\n")
+
+        for i, c in enumerate(images):
+            c_image_id: int = c.get_field("image-id")
+
+            f.write(f"\t[{c_image_id}]	=	&{c.name},\n")
+
+        f.write("};\n\n")
+        f.write("REGISTER_COT(cot_desc);\n")
+        return
+
+    def generate_c_file(self):
+        filename = Path(self.output)
+        filename.parent.mkdir(exist_ok=True, parents=True)
+
+        with open(self.output, 'w+') as output:
+            self.generate_header(output)
+            self.buf_to_c(output)
+            self.param_to_c(output)
+            self.nv_to_c(output)
+            self.pk_to_c(output)
+            self.all_cert_to_c(output)
+            self.all_img_to_c(output)
+            self.cot_to_c(output)
+
+        return
diff --git a/tools/cot_dt2c/cot_dt2c/dt_validator.py b/tools/cot_dt2c/cot_dt2c/dt_validator.py
new file mode 100644
index 0000000..ade037c
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/dt_validator.py
@@ -0,0 +1,130 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import sys
+from os import path, walk, mkdir
+import subprocess
+from pydevicetree import Devicetree
+
+class bcolors:
+    HEADER = '\033[95m'
+    OKBLUE = '\033[94m'
+    OKCYAN = '\033[96m'
+    OKGREEN = '\033[92m'
+    WARNING = '\033[93m'
+    FAIL = '\033[91m'
+    ENDC = '\033[0m'
+    BOLD = '\033[1m'
+    UNDERLINE = '\033[4m'
+
+class DTTree:
+    def __init__(self, input):
+        self.input = input
+        self.test_dir = "./tmp"
+        self.logging_file = self.test_dir + "/result.log"
+
+    def dtValidate(self):
+        subprocess.run(["rm", "-rf", self.test_dir])
+
+        if not path.exists(self.test_dir):
+            mkdir(self.test_dir)
+
+        if path.isfile(self.input):
+            self.dtValidateFile(self.input, printInfo=True)
+            return
+
+        if path.isdir(self.input):
+            self.dtValidateFiles()
+            return
+
+    def dtValidateFile(self, input, printInfo=False):
+        valid, tree = self.dtParseFile(input, printInfo)
+
+        if not valid:
+            return False
+
+        if input.rfind("/") != -1:
+            filename = self.test_dir + input[input.rfind("/"):]
+        else:
+            filename = self.test_dir + "/" + input
+
+        f = open(filename, "w+")
+        if "/dts-v1/;" not in str(tree):
+            f.write("/dts-v1/;\n\n")
+        f.write(str(tree))
+        f.close()
+
+        if str(tree) == "":
+            return valid
+
+        return valid
+
+    def dtParseFile(self, input, printInfo=False):
+        with open(input, 'r') as f:
+            contents = f.read()
+
+        pos = contents.find("/ {")
+        if pos != -1:
+            contents = contents[pos:]
+
+        try:
+            tree = Devicetree.parseStr(contents)
+            if printInfo:
+                print(bcolors.OKGREEN + "{} parse tree successfully".format(input) + bcolors.ENDC)
+        except Exception as e:
+            if printInfo:
+                print(bcolors.FAIL + "{} parse tree failed:\t{}".format(input, str(e)) + bcolors.ENDC)
+            else:
+                f = open(self.logging_file, "a")
+                f.write("=====================================================================================\n")
+                f.write("{} result:\n".format(input))
+                f.write("{} INVALID:\t{}\n".format(input, str(e)))
+                f.close()
+            return False, None
+
+        return True, tree
+
+    def dtValidateFiles(self):
+        f = []
+        for (dirpath, dirnames, filenames) in walk(self.input):
+            f.extend(filenames)
+
+        allFile = len(f)
+        dtsiFile = 0
+        validFile = 0
+        invalidFile = 0
+
+        for i in f:
+            if (".dtsi" in i or ".dts" in i) and "cot" not in i and "fw-config" not in i:
+                dtsiFile += 1
+                valid = True
+
+                if self.input[-1] == "/":
+                    valid = self.dtValidateFile(self.input + i)
+                else:
+                    valid = self.dtValidateFile(self.input + "/" + i)
+
+                if valid:
+                    validFile += 1
+                else:
+                    invalidFile += 1
+
+        print("=====================================================")
+        print("Total File: " + str(allFile))
+        print("Total DT File: " + str(dtsiFile))
+        print("Total Valid File: " + str(validFile))
+        print("Total Invalid File: " + str(invalidFile))
+
+def dtValidatorMain(input):
+    dt = DTTree(input)
+    dt.dtValidate()
+
+if __name__=="__main__":
+    if (len(sys.argv) < 2):
+        print("usage: python3 " + sys.argv[0] + " [dtsi file path] or [dtsi folder path]")
+        exit()
+    if len(sys.argv) == 2:
+        dtValidatorMain(sys.argv[1])
diff --git a/tools/cot_dt2c/poetry.lock b/tools/cot_dt2c/poetry.lock
new file mode 100644
index 0000000..df58d54
--- /dev/null
+++ b/tools/cot_dt2c/poetry.lock
@@ -0,0 +1,334 @@
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+
+[[package]]
+name = "atomicwrites"
+version = "1.4.1"
+description = "Atomic file writes."
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+    {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"},
+]
+
+[[package]]
+name = "attrs"
+version = "24.2.0"
+description = "Classes Without Boilerplate"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"},
+    {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"},
+]
+
+[package.extras]
+benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
+tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
+
+[[package]]
+name = "click"
+version = "8.1.7"
+description = "Composable command line interface toolkit"
+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 = "igraph"
+version = "0.11.6"
+description = "High performance graph data structures and algorithms"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "igraph-0.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3f8b837181e8e87676be3873ce87cc92cc234efd58a2da2f6b4e050db150fcf4"},
+    {file = "igraph-0.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:245c4b7d7657849eff80416f5df4525c8fc44c74a981ee4d44f0ef2612c3bada"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdb7be3d165073c0136295c0808e9edc57ba096cdb26e94086abb04561f7a292"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58974e20df2986a1ae52a16e51ecb387cc0cbeb41c5c0ddff4d373a1bbf1d9c5"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bef14de5e8ab70724a43808b1ed14aaa6fe1002f87e592289027a3827a8f44a"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:86c1e98de2e32d074df8510bf18abfa1f4c5fda4cb28a009985a5d746b0c0125"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ebc5b3d702158abeb2e4d2414374586a2b932e1a07e48352b470600e1733d528"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0efe6d0fb22d3987a800eb3857ed04df9eb4c5dddd0998be05232cb646f1c337"},
+    {file = "igraph-0.11.6-cp38-cp38-win32.whl", hash = "sha256:f4e68b27497b1c8ada2fb2bc35ef3fa7b0d72e84306b3d648d3de240fc618c32"},
+    {file = "igraph-0.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:5665b33dfbfca5f54ce9b4fea6b97903bd0e99fb1b02acf5e57e600bdfa5a355"},
+    {file = "igraph-0.11.6-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8aabef03d787b519d1075dfc0da4a1109fb113b941334883e3e7947ac30a459e"},
+    {file = "igraph-0.11.6-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1f2cc4a518d99cdf6cae514f85e93e56852bc8c325b3abb96037d1d690b5975f"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e859238be52ab8ccc614d18f9362942bc88ce543afc12548f81ae99b10801d"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d61fbe5e85eb4ae9efe08c461f9bdeedb02a2b5739fbc223d324a71f40a28be2"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6620ba39df29fd42151becf82309b54e57148233c9c3ef890eed62e25eed8a5"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59666589bb3d07f310cda2c5106a8adeeb77c2ef27fecf1c6438b6091f4ca69d"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:8750b6d6caebf199cf7dc41c931f58e330153779707391e30f0a29f02666fb6e"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:967d6f2c30fe94317da15e459374d0fb8ca3e56020412f201ecd07dd5b5352f2"},
+    {file = "igraph-0.11.6-cp39-abi3-win32.whl", hash = "sha256:9744f95a67319eb6cb487ceabf30f5d7940de34bada51f0ba63adbd23e0f94ad"},
+    {file = "igraph-0.11.6-cp39-abi3-win_amd64.whl", hash = "sha256:b80e69eb11faa9c57330a9ffebdde5808966efe1c1f638d4d4827ea04df7aca8"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0329c16092e2ea7930d5f8368666ce7cb704900cc0ea04e4afe9ea1dd46e44af"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:21752313f449bd8688e5688e95ea7231cea5e9199c7162535029be0d9af848ac"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea25e136c6c4161f53ff58868b23ff6c845193050ab0e502236d68e5d4174e32"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac84433a03aef15e4b810010b08882b09854a3669450ccf31e392dbe295d2a66"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac697a44e3573169fa2b28c9c37dcf9cf01e0f558b845dd7123860d4c7c8fb89"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bdeae8bf35316eb1fb27bf667dcf5ecf5fcfb0b8f51831bc1b00c39c09c2d73b"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ad7e4aa442935de72554b96733bf6d7f09eac5cee97988a2562bdd3ca173cfa3"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d2818780358a686178866d01568b9df1f29678581734ad7a78882bab54df004"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2352276a20d979f1dea360af4202bb9f0c9a7d2c77f51815c0e625165e82013d"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:687fdab543b507d622fa3043f4227e5b26dc61dcf8ff8c0919fccddcc655f8b8"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f7f8214cd48c9a4d97f7346a4152ba2d4ac95fb5ee0df4ecf224fce4ba3d14"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2b9cc69ede53f76ffae03b066609aa90184dd68ef15da8c104a97cebb9210838"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:591e1e447c3f0092daf7613a3eaedab83f9a0b0adbaf7702724c5117ded038a5"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ca558eb331bc687bc33e5cd23717e22676e9412f8cda3a31d30c996a0487610d"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf43c30e08debb087c9e3da69aa5cf1b6732968da34d55a614e3421b9a452146"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d38e8d7db72b187d9d2211d0d06b3271fa9f32b04d49d789e2859b5480db0d0"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a318b059051ff78144a1c3cb880f4d933c812bcdb3d833a49cd7168d0427672"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2c54027add809b3c5b6685b8deca4ea4763fd000b9ea45c7ee46b7c9d61ff15e"},
+    {file = "igraph-0.11.6.tar.gz", hash = "sha256:837f233256c3319f2a35a6a80d94eafe47b43791ef4c6f9e9871061341ac8e28"},
+]
+
+[package.dependencies]
+texttable = ">=1.6.2"
+
+[package.extras]
+cairo = ["cairocffi (>=1.2.0)"]
+doc = ["Sphinx (>=7.0.0)", "pydoctor (>=23.4.0)", "sphinx-gallery (>=0.14.0)", "sphinx-rtd-theme (>=1.3.0)"]
+matplotlib = ["matplotlib (>=3.6.0)"]
+plotly = ["plotly (>=5.3.0)"]
+plotting = ["cairocffi (>=1.2.0)"]
+test = ["Pillow (>=9)", "cairocffi (>=1.2.0)", "matplotlib (>=3.6.0)", "networkx (>=2.5)", "numpy (>=1.19.0)", "pandas (>=1.1.0)", "plotly (>=5.3.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "scipy (>=1.5.0)"]
+test-musl = ["cairocffi (>=1.2.0)", "networkx (>=2.5)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)"]
+
+[[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 = "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 = "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 = "plotly"
+version = "5.23.0"
+description = "An open-source, interactive data visualization library for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "plotly-5.23.0-py3-none-any.whl", hash = "sha256:76cbe78f75eddc10c56f5a4ee3e7ccaade7c0a57465546f02098c0caed6c2d1a"},
+    {file = "plotly-5.23.0.tar.gz", hash = "sha256:89e57d003a116303a34de6700862391367dd564222ab71f8531df70279fc0193"},
+]
+
+[package.dependencies]
+packaging = "*"
+tenacity = ">=6.2.0"
+
+[[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 = "py"
+version = "1.11.0"
+description = "library with cross-python path, ini-parsing, io, code, log facilities"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+    {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
+    {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
+]
+
+[[package]]
+name = "pydevicetree"
+version = "0.0.13"
+description = "A library for parsing Devicetree Source v1"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "pydevicetree-0.0.13-py3-none-any.whl", hash = "sha256:d61c695cec925b90a8b5740053f4b604e51154a9b36e62a2f12ed9ceaf2f8c38"},
+    {file = "pydevicetree-0.0.13.tar.gz", hash = "sha256:5700c05df89bad8fd729c11aa6f764a3323bcb3796f13b32481ae34445cfc1b7"},
+]
+
+[package.dependencies]
+pyparsing = "*"
+
+[[package]]
+name = "pyparsing"
+version = "3.1.2"
+description = "pyparsing module - Classes and methods to define and execute parsing grammars"
+optional = false
+python-versions = ">=3.6.8"
+files = [
+    {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"},
+    {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"},
+]
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
+
+[[package]]
+name = "pytest"
+version = "6.2.5"
+description = "pytest: simple powerful testing with Python"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
+    {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
+]
+
+[package.dependencies]
+atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
+attrs = ">=19.2.0"
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+iniconfig = "*"
+packaging = "*"
+pluggy = ">=0.12,<2.0"
+py = ">=1.8.2"
+toml = "*"
+
+[package.extras]
+testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
+
+[[package]]
+name = "tenacity"
+version = "9.0.0"
+description = "Retry code until it succeeds"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"},
+    {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"},
+]
+
+[package.extras]
+doc = ["reno", "sphinx"]
+test = ["pytest", "tornado (>=4.5)", "typeguard"]
+
+[[package]]
+name = "texttable"
+version = "1.7.0"
+description = "module to create simple ASCII tables"
+optional = false
+python-versions = "*"
+files = [
+    {file = "texttable-1.7.0-py2.py3-none-any.whl", hash = "sha256:72227d592c82b3d7f672731ae73e4d1f88cd8e2ef5b075a7a7f01a23a3743917"},
+    {file = "texttable-1.7.0.tar.gz", hash = "sha256:2d2068fb55115807d3ac77a4ca68fa48803e84ebb0ee2340f858107a36522638"},
+]
+
+[[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 = "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"},
+]
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.8"
+content-hash = "afa5cb49be96467a848bab753a630c6f5ec42d6750d67d29920c3e3971774e36"
diff --git a/tools/cot_dt2c/pyproject.toml b/tools/cot_dt2c/pyproject.toml
new file mode 100644
index 0000000..73251d7
--- /dev/null
+++ b/tools/cot_dt2c/pyproject.toml
@@ -0,0 +1,63 @@
+# 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 = "cot_dt2c"
+version = "0.1.0"
+description = "CoT-dt2c Tool is a python script to convert CoT DT file into corresponding C file"
+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"
+
+# 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.dependencies]
+python = "^3.8"
+click = "^8.1.7"
+plotly = "^5.23.0"
+pydevicetree = "0.0.13"
+igraph = "^0.11.6"
+pyparsing = "^3.1.2"
+
+[tool.poetry.group.dev]
+optional = true
+
+[tool.poetry.group.dev.dependencies]
+mypy = "^0.910"
+pytest = "^6.2.5"
+
+[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
+
+[[tool.mypy.overrides]]
+module = ["igraph", "pydevicetree", "pydevicetree.ast", "plotly", "plotly.graph_objects"]
+ignore_missing_imports = true
+
+[tool.coverage.run]
+source = ["tests"]
+
+[tool.coverage.paths]
+source = "cot_dt2c"
+
+[tool.poetry.scripts]
+# Entry points for the package https://python-poetry.org/docs/pyproject/#scripts
+# "cot-dt2c" = "cot_dt2c.__main__:cli"
+"cot-dt2c" = "cot_dt2c.__main__:cli"
diff --git a/tools/cot_dt2c/tests/test.dtsi b/tools/cot_dt2c/tests/test.dtsi
new file mode 100644
index 0000000..ee744e6
--- /dev/null
+++ b/tools/cot_dt2c/tests/test.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a valid CoT DT file
+ *
+ */
+
+#include <example/example.h>
+#include <example/example/example.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+#if defined(test)
+		example_cert: example_cert {
+			root-certificate;
+			image-id =<EXAMPLE_ID>;
+			antirollback-counter = <&example_ctr>;
+
+			example_hash: example_hash
+			{
+				oid = EXAMPLE_HASH_ID;
+			};
+		};
+#endif
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		example {
+			image-id = <EXAMPLE_ID>;
+			parent = <&example_cert>;
+			hash = <&example_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	example_ctr: example_ctr {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = CCA_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys {
+	example_pk: example_pk {
+		oid = EXAMPLE_PK_OID;
+	};
+};
diff --git a/tools/cot_dt2c/tests/test2.dtsi b/tools/cot_dt2c/tests/test2.dtsi
new file mode 100644
index 0000000..c4dbf83
--- /dev/null
+++ b/tools/cot_dt2c/tests/test2.dtsi
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a valid CoT DT file
+ *
+ */
+
+#if test
+#include <example/example.h>
+#include <example/example/example.h>
+#endif
+
+cot
+{
+	manifests
+	{
+		compatible = "arm, cert-descs";
+#if defined (test)
+		example_cert: example_cert
+		{
+			root-certificate;
+			image-id =<EXAMPLE_ID>;
+			antirollback-counter = <&example_ctr>;
+
+			example_hash: example_hash
+			{
+				oid = EXAMPLE_HASH_ID;
+			};
+
+		};
+#endif
+	};
+
+	images
+	{
+		compatible = "arm, img-descs";
+
+		example
+		{
+			image-id = <EXAMPLE_ID>;
+			parent = <&example_cert>;
+			hash = <&example_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters
+{
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	example_ctr: example_ctr
+	{
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = CCA_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys
+{
+	example_pk: example_pk
+	{
+		oid = EXAMPLE_PK_OID;
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_bracket.dtsi b/tools/cot_dt2c/tests/test_invalid_bracket.dtsi
new file mode 100644
index 0000000..9752ecf
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_bracket.dtsi
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there is
+ * unmatching bracket
+ *
+ */
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		example_cert: example_cert {
+			root-certificate;
+			image-id =<2>;
+			antirollback-counter = <&example_ctr>;
+
+			example_hash: example_hash
+			{
+				oid = "1.3.6.1.4.1.4128.2100.101";
+			};
+
+		};
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		example {
+			image-id = <2>;
+			parent = <&example_cert>;
+			hash = <&example_hash>;
+		};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	example_ctr: example_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.3";
+	};
+};
+
+rot_keys {
+	example_pk: example_pk {
+		oid = "1.3.6.1.4.1.4128.2100.101";
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_missing_attribute.dtsi b/tools/cot_dt2c/tests/test_invalid_missing_attribute.dtsi
new file mode 100644
index 0000000..e35ab73
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_missing_attribute.dtsi
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there
+ * are image/certificate that missing mandantory attributes
+ *
+ */
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		cca_content_cert: cca_content_cert {
+			root-certificate;
+			antirollback-counter = <&cca_nv_ctr>;
+
+			hw_config_hash: hw_config_hash {
+			};
+
+			soc_fw_config_hash: soc_fw_config_hash {
+				oid = "1.3.6.1.4.1.4128.2100.604";
+			};
+		};
+
+		plat_key_cert: plat_key_cert {
+			root-certificate;
+			image-id = <38>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			plat_pk: plat_pk {
+				oid = "1.3.6.1.4.1.4128.2100.1105";
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			image-id = <15>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = "1.3.6.1.4.1.4128.2100.1201";
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid =  "1.3.6.1.4.1.4128.2100.1202";
+			};
+		};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <23>;
+			hash = <&hw_config_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <25>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <5>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <27>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_fw_config_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	cca_nv_ctr: cca_nv_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.3";
+	};
+
+	trusted_nv_ctr: trusted_nv_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.1";
+	};
+
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
+		id  = <1>;
+		oid = "1.3.6.1.4.1.4128.2100.2";
+	};
+};
+
+rot_keys {
+	swd_rot_pk: swd_rot_pk {
+		oid = "1.3.6.1.4.1.4128.2100.1103";
+	};
+	prot_pk: prot_pk {
+		oid = "1.3.6.1.4.1.4128.2100.1102";
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_missing_ctr.dtsi b/tools/cot_dt2c/tests/test_invalid_missing_ctr.dtsi
new file mode 100644
index 0000000..c572b1a
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_missing_ctr.dtsi
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there
+ * are image/certificate that missing definition of
+ * nv counters
+ *
+ */
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		example_cert: example_cert {
+			root-certificate;
+			image-id =<2>;
+			signing-key = <&swd_rot_pk>;
+			antirollback-counter = <&example_ctr>;
+
+			example_hash: example_hash
+			{
+				oid = "1.3.6.1.4.1.4128.2100.104";
+			};
+
+		};
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		example {
+			image-id = <2>;
+			parent = <&example_cert>;
+			hash = <&example_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+};
+
+rot_keys {
+	example_pk: example_pk {
+		oid = "1.3.6.1.4.1.4128.2100.104";
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_missing_root.dtsi b/tools/cot_dt2c/tests/test_invalid_missing_root.dtsi
new file mode 100644
index 0000000..465a4c6
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_missing_root.dtsi
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there
+ * are image/certificate that missing root certificate
+ *
+ */
+
+#include <tools_share/cca_oid.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <common/nv_cntr_ids.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		core_swd_key_cert: core_swd_key_cert {
+			image-id = <CORE_SWD_KEY_CERT_ID>;
+			signing-key = <&swd_rot_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			core_swd_pk: core_swd_pk {
+				oid = CORE_SWD_PK_OID;
+			};
+		};
+
+		trusted_os_fw_content_cert: trusted_os_fw_content_cert {
+			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
+			parent = <&core_swd_key_cert>;
+			signing-key = <&core_swd_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			tos_fw_hash: tos_fw_hash {
+				oid = TRUSTED_OS_FW_HASH_OID;
+			};
+			tos_fw_config_hash: tos_fw_config_hash {
+				oid = TRUSTED_OS_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		plat_key_cert: plat_key_cert {
+			image-id = <PLAT_KEY_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			plat_pk: plat_pk {
+				oid = PLAT_PK_OID;
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			parent = <&plat_key_cert>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			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 = <&core_swd_key_cert>;
+			signing-key = <&core_swd_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			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 {
+			image-id = <PLAT_SP_CONTENT_CERT_ID>;
+			parent = <&plat_key_cert>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			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 = <&cca_content_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		bl31_image {
+			image-id = <BL31_IMAGE_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <SOC_FW_CONFIG_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		rmm_image {
+			image-id = <RMM_IMAGE_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&rmm_hash>;
+		};
+
+		bl32_image {
+			image-id = <BL32_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_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>;
+
+	cca_nv_ctr: cca_nv_ctr {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = CCA_FW_NVCOUNTER_OID;
+	};
+
+	trusted_nv_ctr: trusted_nv_ctr {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = TRUSTED_FW_NVCOUNTER_OID;
+	};
+
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
+		id  = <NON_TRUSTED_NV_CTR_ID>;
+		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys {
+	swd_rot_pk: swd_rot_pk {
+		oid = SWD_ROT_PK_OID;
+	};
+	prot_pk: prot_pk {
+		oid = PROT_PK_OID;
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_undefined_parent.dtsi b/tools/cot_dt2c/tests/test_invalid_undefined_parent.dtsi
new file mode 100644
index 0000000..b6056ca
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_undefined_parent.dtsi
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there
+ * are image/certificate that points to invalid parent
+ *
+ */
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		cca_content_cert: cca_content_cert {
+			root-certificate;
+			image-id =<36>;
+			antirollback-counter = <&cca_nv_ctr>;
+
+			hw_config_hash: hw_config_hash {
+				oid = "1.3.6.1.4.1.4128.2100.203";
+			};
+			soc_fw_config_hash: soc_fw_config_hash {
+				oid = "1.3.6.1.4.1.4128.2100.604";
+			};
+		};
+
+		plat_key_cert: plat_key_cert {
+			root-certificate;
+			image-id = <38>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			plat_pk: plat_pk {
+				oid =  "1.3.6.1.4.1.4128.2100.1105";
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			parent = <&wrong_parent>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = "1.3.6.1.4.1.4128.2100.1201";
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid = "1.3.6.1.4.1.4128.2100.1202";
+			};
+		};
+
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <23>;
+			parent = <&cca_content_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <25>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <5>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <27>;
+			hash = <&nt_fw_config_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	cca_nv_ctr: cca_nv_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.3";
+	};
+
+	trusted_nv_ctr: trusted_nv_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.1";
+	};
+
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
+		id  = <1>;
+		oid = "1.3.6.1.4.1.4128.2100.2";
+	};
+};
+
+rot_keys {
+	swd_rot_pk: swd_rot_pk {
+		oid = "1.3.6.1.4.1.4128.2100.1103";
+	};
+
+	prot_pk: prot_pk {
+		oid = "1.3.6.1.4.1.4128.2100.1102";
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_util.py b/tools/cot_dt2c/tests/test_util.py
new file mode 100644
index 0000000..b8e44d4
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_util.py
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import os
+import sys
+
+from cot_dt2c.cli import *
+from click.testing import CliRunner
+
+def get_script_path():
+    return os.path.dirname(os.path.realpath(sys.argv[0]))
+
+def test_convert():
+    runner = CliRunner()
+    test_file = get_script_path() + "/test.dtsi"
+    test_output = get_script_path() + "/test.c"
+
+    result = runner.invoke(convert_to_c, [test_file, test_output])
+    try:
+        assert result.output == ""
+    except:
+        print("test convert fail")
+
+    try:
+        os.remove(test_output)
+    except OSError:
+        pass
+
+if __name__=="__main__":
+    test_convert()
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 0210c36..50b0fa2 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -11,8 +11,6 @@
 BINARY		:= $(notdir ${ENCTOOL})
 OPENSSL_DIR	:= /usr
 
-toolchains := host
-
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 23c8e64..54dee87 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-toolchains := host
-
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 6c566ef..27119a1 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -1,12 +1,13 @@
 /*
- * 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
  */
 
-#ifndef _MSC_VER
+#ifdef __linux__
 #include <sys/mount.h>
 #endif
+
 #include <sys/types.h>
 #include <sys/stat.h>
 
diff --git a/tools/marvell/doimage/Makefile b/tools/marvell/doimage/Makefile
index 488b768..a4f7a1d 100644
--- a/tools/marvell/doimage/Makefile
+++ b/tools/marvell/doimage/Makefile
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier:     BSD-3-Clause
 # https://spdx.org/licenses
 
-toolchains := host
-
 include ../../../make_helpers/common.mk
 include ../../../make_helpers/toolchain.mk
 
diff --git a/tools/nxp/cert_create_helper/src/pdef_tbb_key.c b/tools/nxp/cert_create_helper/src/pdef_tbb_key.c
index cf2ebda..cd48866 100644
--- a/tools/nxp/cert_create_helper/src/pdef_tbb_key.c
+++ b/tools/nxp/cert_create_helper/src/pdef_tbb_key.c
@@ -6,7 +6,7 @@
 
 #include <pdef_tbb_key.h>
 
-static key_t pdef_tbb_keys[] = {
+static cert_key_t pdef_tbb_keys[] = {
 	[DDR_FW_CONTENT_KEY - DDR_FW_CONTENT_KEY] = {
 		.id = DDR_FW_CONTENT_KEY,
 		.opt = "ddr-fw-key",
diff --git a/tools/nxp/create_pbl/Makefile b/tools/nxp/create_pbl/Makefile
index 7648b7f..22aa921 100644
--- a/tools/nxp/create_pbl/Makefile
+++ b/tools/nxp/create_pbl/Makefile
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-toolchains := host
-
 MAKE_HELPERS_DIRECTORY := ../../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
diff --git a/tools/renesas/rcar_layout_create/makefile b/tools/renesas/rcar_layout_create/makefile
index 8c2c054..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,7 @@
 
 toolchains := aarch64
 
+include ../../../make_helpers/build-rules.mk
 include ../../../make_helpers/common.mk
 include ../../../make_helpers/toolchain.mk
 
@@ -85,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 		\
+
+$(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
 
-	$(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).bin: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
 
-$(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 		\
+$(OUTPUT_FILE_SA0): $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0) | $$(@D)/
+	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
 
-	$(aarch64-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
+$(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 d2a54ea..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,7 @@
 
 toolchains := aarch64
 
+include ../../../make_helpers/build-rules.mk
 include ../../../make_helpers/common.mk
 include ../../../make_helpers/toolchain.mk
 
@@ -82,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 		\
+
+$(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
 
-	$(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).bin: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
 
-$(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 		\
+$(OUTPUT_FILE_SA0): $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0) | $$(@D)/
+	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
 
-	$(aarch64-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
+$(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 e336a0c..0da5c09 100644
--- a/tools/sptool/Makefile
+++ b/tools/sptool/Makefile
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-toolchains := host
-
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
diff --git a/tools/stm32image/Makefile b/tools/stm32image/Makefile
index 2b34ef8..453daae 100644
--- a/tools/stm32image/Makefile
+++ b/tools/stm32image/Makefile
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-toolchains := host
-
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
diff --git a/tools/tlc/.gitignore b/tools/tlc/.gitignore
new file mode 100644
index 0000000..ad4a1f1
--- /dev/null
+++ b/tools/tlc/.gitignore
@@ -0,0 +1,176 @@
+# Created by https://www.toptal.com/developers/gitignore/api/python
+# Edit at https://www.toptal.com/developers/gitignore?templates=python
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+#   in version control.
+#   https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+### Python Patch ###
+# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
+poetry.toml
+
+# ruff
+.ruff_cache/
+
+# LSP config files
+pyrightconfig.json
+
+# End of https://www.toptal.com/developers/gitignore/api/python
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..decec59
--- /dev/null
+++ b/tools/tlc/poetry.lock
@@ -0,0 +1,1434 @@
+# 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.8.0"
+description = "The uncompromising code formatter."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"},
+    {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"},
+    {file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"},
+    {file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"},
+    {file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"},
+    {file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"},
+    {file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"},
+    {file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"},
+    {file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"},
+    {file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"},
+    {file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"},
+    {file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"},
+    {file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"},
+    {file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"},
+    {file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"},
+    {file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"},
+    {file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"},
+    {file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"},
+    {file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"},
+    {file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"},
+    {file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"},
+    {file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"},
+]
+
+[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 = "cachetools"
+version = "5.5.0"
+description = "Extensible memoizing collections and decorators"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"},
+    {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"},
+]
+
+[[package]]
+name = "certifi"
+version = "2024.8.30"
+description = "Python package for providing Mozilla's CA Bundle."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
+    {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
+]
+
+[[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 = "chardet"
+version = "5.2.0"
+description = "Universal encoding detector for Python 3"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
+    {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
+]
+
+[[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.2"
+description = "Generate coverage badges for Coverage.py."
+optional = false
+python-versions = "*"
+files = [
+    {file = "coverage_badge-1.1.2-py2.py3-none-any.whl", hash = "sha256:d8413ce51c91043a1692b943616b450868cbeeb0ea6a0c54a32f8318c9c96ff7"},
+    {file = "coverage_badge-1.1.2.tar.gz", hash = "sha256:fe7ed58a3b72dad85a553b64a99e963dea3847dcd0b8ddd2b38a00333618642c"},
+]
+
+[package.dependencies]
+coverage = "*"
+setuptools = "*"
+
+[[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.16.1"
+description = "A platform independent file lock."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
+    {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
+]
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
+typing = ["typing-extensions (>=4.12.2)"]
+
+[[package]]
+name = "identify"
+version = "2.6.1"
+description = "File identification library for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"},
+    {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"},
+]
+
+[package.extras]
+license = ["ukkonen"]
+
+[[package]]
+name = "idna"
+version = "3.10"
+description = "Internationalized Domain Names in Applications (IDNA)"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
+    {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
+]
+
+[package.extras]
+all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
+
+[[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.1.0"
+description = "Python Build Reasonableness"
+optional = false
+python-versions = ">=2.6"
+files = [
+    {file = "pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"},
+    {file = "pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24"},
+]
+
+[[package]]
+name = "platformdirs"
+version = "4.3.6"
+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.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
+    {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
+]
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"]
+type = ["mypy (>=1.11.2)"]
+
+[[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 = "pyproject-api"
+version = "1.8.0"
+description = "API to interact with the python pyproject.toml based projects"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pyproject_api-1.8.0-py3-none-any.whl", hash = "sha256:3d7d347a047afe796fd5d1885b1e391ba29be7169bd2f102fcd378f04273d228"},
+    {file = "pyproject_api-1.8.0.tar.gz", hash = "sha256:77b8049f2feb5d33eefcc21b57f1e279636277a8ac8ad6b5871037b243778496"},
+]
+
+[package.dependencies]
+packaging = ">=24.1"
+tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx-autodoc-typehints (>=2.4.1)"]
+testing = ["covdefaults (>=2.3)", "pytest (>=8.3.3)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "setuptools (>=75.1)"]
+
+[[package]]
+name = "pytest"
+version = "8.3.3"
+description = "pytest: simple powerful testing with Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"},
+    {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
+iniconfig = "*"
+packaging = "*"
+pluggy = ">=1.5,<2"
+tomli = {version = ">=1", markers = "python_version < \"3.11\""}
+
+[package.extras]
+dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
+
+[[package]]
+name = "pytest-cov"
+version = "5.0.0"
+description = "Pytest plugin for measuring coverage."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"},
+    {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"},
+]
+
+[package.dependencies]
+coverage = {version = ">=5.2.1", extras = ["toml"]}
+pytest = ">=4.6"
+
+[package.extras]
+testing = ["fields", "hunter", "process-tests", "pytest-xdist", "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.2"
+description = "YAML parser and emitter for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
+    {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
+    {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
+    {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
+    {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
+    {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
+    {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
+    {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
+    {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
+    {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
+    {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
+    {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
+    {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
+    {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
+    {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
+    {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
+    {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
+    {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
+    {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
+    {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
+    {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
+    {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
+    {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
+    {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
+    {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
+    {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
+    {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
+    {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
+    {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
+    {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
+    {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
+    {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
+    {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
+    {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
+    {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
+]
+
+[[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 = "75.1.0"
+description = "Easily download, build, install, upgrade, and uninstall Python packages"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"},
+    {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"},
+]
+
+[package.extras]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
+core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+cover = ["pytest-cov"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
+enabler = ["pytest-enabler (>=2.2)"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
+type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
+
+[[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.3.0"
+description = "Manage dynamic plugins for Python applications"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "stevedore-5.3.0-py3-none-any.whl", hash = "sha256:1efd34ca08f474dad08d9b19e934a22c68bb6fe416926479ba29e5013bcc8f78"},
+    {file = "stevedore-5.3.0.tar.gz", hash = "sha256:9a64265f4060312828151c204efbe9b7a9852a0d9228756344dbc7e4023e375a"},
+]
+
+[package.dependencies]
+pbr = ">=2.0.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.2"
+description = "Style preserving TOML library"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"},
+    {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"},
+]
+
+[[package]]
+name = "tox"
+version = "4.20.0"
+description = "tox is a generic virtualenv management and test command line tool"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tox-4.20.0-py3-none-any.whl", hash = "sha256:21a8005e3d3fe5658a8e36b8ca3ed13a4230429063c5cc2a2fdac6ee5aa0de34"},
+    {file = "tox-4.20.0.tar.gz", hash = "sha256:5b78a49b6eaaeab3ae4186415e7c97d524f762ae967c63562687c3e5f0ec23d5"},
+]
+
+[package.dependencies]
+cachetools = ">=5.5"
+chardet = ">=5.2"
+colorama = ">=0.4.6"
+filelock = ">=3.15.4"
+packaging = ">=24.1"
+platformdirs = ">=4.2.2"
+pluggy = ">=1.5"
+pyproject-api = ">=1.7.1"
+tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
+virtualenv = ">=20.26.3"
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-argparse-cli (>=1.17)", "sphinx-autodoc-typehints (>=2.4)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=24.8)"]
+testing = ["build[virtualenv] (>=1.2.2)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.2)", "devpi-process (>=1)", "diff-cover (>=9.1.1)", "distlib (>=0.3.8)", "flaky (>=3.8.1)", "hatch-vcs (>=0.4)", "hatchling (>=1.25)", "psutil (>=6)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-xdist (>=3.6.1)", "re-assert (>=1.1)", "setuptools (>=74.1.2)", "time-machine (>=2.15)", "wheel (>=0.44)"]
+
+[[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.3"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
+    {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
+]
+
+[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.5"
+description = "Virtual Python Environment builder"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "virtualenv-20.26.5-py3-none-any.whl", hash = "sha256:4f3ac17b81fba3ce3bd6f4ead2749a72da5929c01774948e243db9ba41df4ff6"},
+    {file = "virtualenv-20.26.5.tar.gz", hash = "sha256:ce489cac131aa58f4b25e321d6d186171f78e6cb13fafbf32a840cee67733ff4"},
+]
+
+[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 = "aac9123f3fa544b8c3e9b085f41f5a1c6c4ed2d59ce3236dcda6ea2aef5a694c"
diff --git a/tools/tlc/pyproject.toml b/tools/tlc/pyproject.toml
new file mode 100644
index 0000000..b606238
--- /dev/null
+++ b/tools/tlc/pyproject.toml
@@ -0,0 +1,151 @@
+# 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"
+tox = "^4.18.0"
+jinja2 = "^3.1.4"
+
+[tool.poetry.group.dev]
+optional = true
+
+[tool.poetry.group.dev.dependencies]
+bandit = "^1.7.1"
+tox = "^4.18.0"
+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 = "^8.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 = "5.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"]
+branch = true
+
+[tool.coverage.paths]
+source = ["tlc"]
+
+[tool.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..a5ef30e
--- /dev/null
+++ b/tools/tlc/tests/test_cli.py
@@ -0,0 +1,476 @@
+#!/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 math import ceil, log2
+from pathlib import Path
+from re import findall, search
+from unittest import mock
+
+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
+
+
+@pytest.mark.parametrize("option", ["-O", "--output"])
+def test_gen_tl_header_with_output_name(tlcrunner, tmptlstr, option, filename="test.h"):
+    with tlcrunner.isolated_filesystem():
+        result = tlcrunner.invoke(
+            cli,
+            [
+                "gen-header",
+                option,
+                filename,
+                tmptlstr,
+            ],
+        )
+
+        assert result.exit_code == 0
+        assert Path(filename).exists()
+
+
+def test_gen_tl_with_fdt_header(tmptlstr, tmpfdt):
+    tlcrunner = CliRunner()
+
+    with tlcrunner.isolated_filesystem():
+        tlcrunner.invoke(cli, ["create", "--size", 1000, "--fdt", tmpfdt, tmptlstr])
+
+        result = tlcrunner.invoke(
+            cli,
+            [
+                "gen-header",
+                tmptlstr,
+            ],
+        )
+
+        assert result.exit_code == 0
+        assert Path("header.h").exists()
+
+        with open("header.h", "r") as f:
+            dtb_match = search(r"DTB_OFFSET\s+(\d+)", "".join(f.readlines()))
+            assert dtb_match and dtb_match[1].isnumeric()
+
+
+def test_gen_empty_tl_c_header(tlcrunner, tmptlstr):
+    with tlcrunner.isolated_filesystem():
+        result = tlcrunner.invoke(
+            cli,
+            [
+                "gen-header",
+                tmptlstr,
+            ],
+        )
+
+        assert result.exit_code == 0
+        assert Path("header.h").exists()
+
+        with open("header.h", "r") as f:
+            lines = "".join(f.readlines())
+
+            assert TransferList.hdr_size == int(
+                findall(r"SIZE\s+(0x[0-9a-fA-F]+|\d+)", lines)[0], 16
+            )
+            assert TransferList.version == int(
+                findall(r"VERSION.+(0x[0-9a-fA-F]+|\d+)", lines)[0]
+            )
+
+
+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..3d60938
--- /dev/null
+++ b/tools/tlc/tlc/cli.py
@@ -0,0 +1,201 @@
+#!/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 jinja2
+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))
+@click.option(
+    "--output",
+    "-O",
+    type=click.Path(exists=False),
+    help="Output filename for the header",
+    default=Path("header.h"),
+)
+def gen_header(filename, output):
+    """Generate a header with common definitions."""
+    tl = TransferList.fromfile(filename)
+    tmp_keys = tl.__dict__
+    tmp_keys["header_guard"] = Path(output).name.replace(".", "_").upper()
+
+    dtb_te = tl.get_entry(1)
+
+    if dtb_te:
+        tmp_keys["dtb_offset"] = dtb_te.offset + dtb_te.hdr_size
+
+    env = jinja2.Environment(
+        loader=jinja2.PackageLoader("tlc", "templates"),
+    )
+    template = env.get_template("header.h.j2")
+    with open(output, "w") as f:
+        f.write(template.render(tmp_keys))
+
+
+@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/templates/header.h.j2 b/tools/tlc/tlc/templates/header.h.j2
new file mode 100644
index 0000000..87707ce
--- /dev/null
+++ b/tools/tlc/tlc/templates/header.h.j2
@@ -0,0 +1,16 @@
+/*
+ * Auto-generated by TLC, this file includes declarations and macros
+ * derived from a Transfer List input.
+ */
+
+#ifndef {{ header_guard }}
+#define {{ header_guard }}
+
+{% if dtb_offset -%}
+#define TRANSFER_LIST_DTB_OFFSET	{{ "0x%x" % dtb_offset }}
+{%- endif %}
+#define TRANSFER_LIST_CONVENTION_VERSION	{{ version }}
+#define TRANSFER_LIST_HEADER_SIZE	{{ "0x%x" % hdr_size }}
+#define TRANSFER_LIST_SIZE		{{ "0x%x" % size }}
+
+#endif /* {{ header_guard }} */
diff --git a/tools/tlc/tlc/tl.py b/tools/tlc/tlc/tl.py
new file mode 100644
index 0000000..98d2205
--- /dev/null
+++ b/tools/tlc/tlc/tl.py
@@ -0,0 +1,363 @@
+#!/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."""
+
+from typing import Any, Dict, List, Optional
+
+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: Dict[int, Any] = {
+    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: 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[str, Any]) -> "TransferList":
+        """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(self, tag_id: int) -> Optional[TransferEntry]:
+        for te in self.entries:
+            if te.id == tag_id:
+                return te
+
+        return None
+
+    def get_entry_data_offset(self, tag_id: int) -> int:
+        """Returns offset of data of a TE from the base of the TL."""
+        te = self.get_entry(tag_id)
+
+        if not te:
+            raise ValueError(f"Tag {tag_id} not found in TL!")
+
+        return te.offset + te.hdr_size
+
+    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: Any
+    ) -> TransferEntry:
+        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[str, Any]
+    ) -> 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[str, Any],
+    ) -> 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)
diff --git a/tools/tlc/tox.ini b/tools/tlc/tox.ini
new file mode 100644
index 0000000..4fd141f
--- /dev/null
+++ b/tools/tlc/tox.ini
@@ -0,0 +1,26 @@
+[tox]
+envlist = py38, py39, py310, py311, py312, lint
+
+[testenv]
+allowlist_externals = poetry
+commands =
+    poetry install -v --with dev
+    poetry run pytest
+
+[testenv:format]
+description = Run linters and type checks
+skip_install = true
+allowlist_externals = poetry
+commands =
+    poetry run black .
+    poetry run isort .
+
+[testenv:lint]
+description = Run linters and type checks
+skip_install = true
+allowlist_externals = poetry
+commands =
+    poetry run black --check .
+    poetry run isort --check-only .
+    poetry run mypy .
+    poetry run darglint tlc tests