Merge "fix(gicv3): fixed bug in the initialization of GICv3 SGIs/(E)PPIs interrupt priorities" into integration
diff --git a/.gitignore b/.gitignore
index 1f4efb6..ab2c0c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,8 @@
 tools/stm32image/stm32image
 tools/stm32image/stm32image.exe
 tools/sptool/__pycache__/
+tools/encrypt_fw/encrypt_fw
+tools/encrypt_fw/encrypt_fw.exe
 
 # GNU GLOBAL files
 GPATH
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 0000000..afcb1f6
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# shellcheck source=./_/husky.sh
+. "$(dirname "$0")/_/husky.sh"
+
+"$(dirname "$0")/pre-commit.copyright" "$@"
diff --git a/.husky/pre-commit.copyright b/.husky/pre-commit.copyright
new file mode 100755
index 0000000..b5087a7
--- /dev/null
+++ b/.husky/pre-commit.copyright
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+# A hook script that checks if files staged for commit have updated Arm copyright year.
+# In case they are not - updates the years and prompts user to add them to the change.
+# This hook is called on "git commit" after changes have been staged, but before commit
+# message has to be provided.
+
+RED="\033[00;31m"
+YELLOW="\033[00;33m"
+BLANK="\033[00;00m"
+
+FILES=`git diff --cached --name-only HEAD`
+YEAR_NOW=`date +"%Y"`
+
+YEAR_RGX="[0-9][0-9][0-9][0-9]"
+ARM_RGX="\(ARM\|Arm\|arm\)"
+
+exit_code=0
+
+function user_warning() {
+	echo -e "Copyright of $RED$FILE$BLANK is out of date"
+	echo -e "Updated copyright to"
+	grep -nr "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE"
+	echo
+}
+
+while read -r FILE; do
+	if [ -z "$FILE" ]
+	then
+		break
+	fi
+	# Check if correct copyright notice is in file.
+	# To reduce false positives, we assume files with no
+	# copyright notice do not require it.
+	if ! grep "opyright.*$YEAR_NOW.*$ARM_RGX" "$FILE">/dev/null 2>&1
+	then
+		# If it is "from_date - to_date" type of entry - change to_date entry.
+		if grep "opyright.*$YEAR_RGX.*-.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
+		then
+			exit_code=1
+			sed -i "s/\(opyright.*\)$YEAR_RGX\(.*$ARM_RGX\)/\1$(date +"%Y")\2/" $FILE
+			user_warning
+		# If it is single "date" type of entry - add the copyright extension to current year.
+		elif grep "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
+		then
+			exit_code=1
+			sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$ARM_RGX\)/\1-$(date +"%Y")\2/" $FILE
+			user_warning
+		fi
+	fi
+done <<< "$FILES"
+
+if [ $exit_code -eq 1 ]
+then
+	echo -e "$RED""Please stage updated files$BLANK before commiting or use$YELLOW git commit --no-verify$BLANK to skip copyright check"
+fi
+exit $exit_code
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644
index 0000000..3663f37
--- /dev/null
+++ b/.readthedocs.yaml
@@ -0,0 +1,27 @@
+# Copyright (c) 2023, Arm Limited. All rights reserved
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Configuration file for the readthedocs deploy
+# Available at https://trustedfirmware-a.readthedocs.io/en/latest/
+
+
+# readthedocs config version
+version: 2
+
+build:
+  os: ubuntu-22.04 # Ubuntu Jammy LTS
+  tools:
+    python: "3.10"
+
+python:
+  install:
+    - requirements: docs/requirements.txt
+
+sphinx:
+  configuration: docs/conf.py
+
+# Auxiliary formats to export to (in addition to the default HTML output).
+formats:
+  - pdf
+
diff --git a/Makefile b/Makefile
index c4350dc..5780832 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -153,6 +153,9 @@
 ENABLE_FEAT_ECV = 1
 ENABLE_FEAT_FGT = 1
 
+# RME enables CSV2_2 extension by default.
+ENABLE_FEAT_CSV2_2 = 1
+
 endif
 
 # USE_SPINLOCK_CAS requires AArch64 build
@@ -350,27 +353,53 @@
 # General warnings
 WARNINGS		:=	-Wall -Wmissing-include-dirs -Wunused	\
 				-Wdisabled-optimization -Wvla -Wshadow	\
-				-Wno-unused-parameter -Wredundant-decls
+				-Wredundant-decls
+# stricter warnings
+WARNINGS		+=	-Wextra -Wno-trigraphs
+# too verbose for generic build
+WARNINGS		+=	-Wno-missing-field-initializers \
+				-Wno-type-limits -Wno-sign-compare \
+# on clang this flag gets reset if -Wextra is set after it. No difference on gcc
+WARNINGS		+=	-Wno-unused-parameter
 
 # Additional warnings
-# Level 1
-WARNING1 := -Wextra
-WARNING1 += -Wmissing-format-attribute
-WARNING1 += -Wmissing-prototypes
-WARNING1 += -Wold-style-definition
+# Level 1 - infrequent warnings we should have none of
+# full -Wextra
+WARNING1 += -Wsign-compare
+WARNING1 += -Wtype-limits
+WARNING1 += -Wmissing-field-initializers
 
-# Level 2
-WARNING2 := -Waggregate-return
-WARNING2 += -Wcast-align
-WARNING2 += -Wnested-externs
+# Level 2 - problematic warnings that we want
+# zlib, compiler-rt, coreboot, and mbdedtls blow up with these
+# TODO: disable just for them and move into default build
+WARNING2 += -Wold-style-definition
+WARNING2 += -Wmissing-prototypes
+WARNING2 += -Wmissing-format-attribute
+# TF-A aims to comply with this eventually. Effort too large at present
+WARNING2 += -Wundef
+# currently very involved and many platforms set this off
+WARNING2 += -Wunused-const-variable=2
 
+# Level 3 - very pedantic, frequently ignored
 WARNING3 := -Wbad-function-cast
+WARNING3 += -Waggregate-return
+WARNING3 += -Wnested-externs
+WARNING3 += -Wcast-align
 WARNING3 += -Wcast-qual
 WARNING3 += -Wconversion
 WARNING3 += -Wpacked
 WARNING3 += -Wpointer-arith
 WARNING3 += -Wswitch-default
 
+# Setting W is quite verbose and most warnings will be pre-existing issues
+# outside of the contributor's control. Don't fail the build on them so warnings
+# can be seen and hopefully addressed
+ifdef W
+ifneq (${W},0)
+E	 ?= 0
+endif
+endif
+
 ifeq (${W},1)
 WARNINGS += $(WARNING1)
 else ifeq (${W},2)
@@ -442,12 +471,14 @@
 
 # LD = gcc-ld (ld) or llvm-ld (ld.lld) or other
 else
-TF_LDFLAGS		+=	--fatal-warnings -O1
+TF_LDFLAGS		+=	-O1
 TF_LDFLAGS		+=	--gc-sections
 # ld.lld doesn't recognize the errata flags,
-# therefore don't add those in that case
+# therefore don't add those in that case.
+# ld.lld reports section type mismatch warnings,
+# therefore don't add --fatal-warnings to it.
 ifeq ($(findstring ld.lld,$(notdir $(LD))),)
-TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
+TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH)) --fatal-warnings
 endif
 endif
 
@@ -625,12 +656,16 @@
 ifeq ($(ENABLE_PIE),1)
 ifeq ($(BL2_AT_EL3),1)
 ifneq ($(BL2_IN_XIP_MEM),1)
+	BL2_CPPFLAGS	+=	-fpie
 	BL2_CFLAGS	+=	-fpie
 	BL2_LDFLAGS	+=	$(PIE_LDFLAGS)
 endif
 endif
-	BL31_CFLAGS	+=	-fpie
+	BL31_CPPFLAGS	+=	-fpie
+	BL31_CFLAGS 	+=	-fpie
 	BL31_LDFLAGS	+=	$(PIE_LDFLAGS)
+
+	BL32_CPPFLAGS	+=	-fpie
 	BL32_CFLAGS	+=	-fpie
 	BL32_LDFLAGS	+=	$(PIE_LDFLAGS)
 endif
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index c4ec5fe..124358c 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -5,9 +5,8 @@
  */
 
 /*
- * The .data section gets copied from ROM to RAM at runtime.
- * Its LMA should be 16-byte aligned to allow efficient copying of 16-bytes
- * aligned regions in it.
+ * The .data section gets copied from ROM to RAM at runtime. Its LMA should be
+ * 16-byte aligned to allow efficient copying of 16-bytes aligned regions in it.
  * Its VMA must be page-aligned as it marks the first read/write page.
  */
 #define DATA_ALIGN	16
@@ -24,23 +23,26 @@
     RAM (rwx): ORIGIN = BL1_RW_BASE, LENGTH = BL1_RW_LIMIT - BL1_RW_BASE
 }
 
-SECTIONS
-{
+SECTIONS {
     . = BL1_RO_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL1_RO_BASE address is not aligned on a page boundary.")
+        "BL1_RO_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *bl1_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >ROM
 
-    /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
     .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
     } >ROM
@@ -51,51 +53,57 @@
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         /*
          * No need to pad out the .rodata section to a page boundary. Next is
          * the .data section, which can mapped in ROM with the same memory
          * attributes as the .rodata section.
          *
-         * Pad out to 16 bytes though as .data section needs to be 16 byte
-         * aligned and lld does not align the LMA to the aligment specified
+         * Pad out to 16 bytes though as .data section needs to be 16-byte
+         * aligned and lld does not align the LMA to the alignment specified
          * on the .data section.
          */
         __RODATA_END__ = .;
-         . = ALIGN(16);
+
+        . = ALIGN(16);
     } >ROM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *bl1_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END__ = .;
 
         /*
-         * Pad out to 16 bytes as .data section needs to be 16 byte aligned and
-         * lld does not align the LMA to the aligment specified on the .data
-         * section.
+         * Pad out to 16 bytes as the .data section needs to be 16-byte aligned
+         * and lld does not align the LMA to the alignment specified on the
+         * .data section.
          */
-         . = ALIGN(16);
+        . = ALIGN(16);
     } >ROM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
+        "cpu_ops not defined for this platform.")
 
     . = BL1_RW_BASE;
+
     ASSERT(BL1_RW_BASE == ALIGN(PAGE_SIZE),
-           "BL1_RW_BASE address is not aligned on a page boundary.")
+        "BL1_RW_BASE address is not aligned on a page boundary.")
 
     DATA_SECTION >RAM AT>ROM
+
     __DATA_RAM_START__ = __DATA_START__;
     __DATA_RAM_END__ = __DATA_END__;
 
@@ -105,24 +113,26 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
-     * memory attributes for the coherent data page tables.
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data. This is required to set up the correct memory
+     * attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
     __BL1_RAM_START__ = ADDR(.data);
     __BL1_RAM_END__ = .;
@@ -135,15 +145,16 @@
      * of BL1's actual content in Trusted ROM.
      */
     __BL1_ROM_END__ =  __DATA_ROM_START__ + __DATA_SIZE__;
+
     ASSERT(__BL1_ROM_END__ <= BL1_RO_LIMIT,
-           "BL1's ROM content has exceeded its limit.")
+        "BL1's ROM content has exceeded its limit.")
 
     __BSS_SIZE__ = SIZEOF(.bss);
 
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL1_RW_LIMIT, "BL1's RW section has exceeded its limit.")
 }
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index 9f63fd5..0c43f13 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -29,4 +29,4 @@
 BL1_SOURCES		+=	bl1/bl1_fwu.c
 endif
 
-BL1_LINKERFILE		:=	bl1/bl1.ld.S
+BL1_DEFAULT_LINKER_SCRIPT_SOURCE := bl1/bl1.ld.S
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 80cf7db..3df8f07 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -15,28 +15,31 @@
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
 }
 
-
-SECTIONS
-{
+SECTIONS {
     . = BL2_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2_BASE address is not aligned on a page boundary.")
+        "BL2_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
 #if ENABLE_RME
         *bl2_rme_entrypoint.o(.text*)
 #else /* ENABLE_RME */
         *bl2_entrypoint.o(.text*)
 #endif /* ENABLE_RME */
+
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
-    /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
     .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
     } >RAM
@@ -47,39 +50,41 @@
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *bl2_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     STACK_SECTION >RAM
@@ -88,29 +93,27 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL2_END__ = .;
 
@@ -119,7 +122,7 @@
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
 }
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
index 7a973e5..a18abab 100644
--- a/bl2/bl2.mk
+++ b/bl2/bl2.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -23,12 +23,12 @@
 				bl2/${ARCH}/bl2_el3_exceptions.S	\
 				bl2/${ARCH}/bl2_run_next_image.S	\
 				${GPT_LIB_SRCS}
-BL2_LINKERFILE		:=	bl2/bl2.ld.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2.ld.S
 
 else ifeq (${BL2_AT_EL3},0)
 # Normal operation, no RME, no BL2 at EL3
 BL2_SOURCES		+=	bl2/${ARCH}/bl2_entrypoint.S
-BL2_LINKERFILE		:=	bl2/bl2.ld.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2.ld.S
 
 else
 # BL2 at EL3, no RME
@@ -46,5 +46,5 @@
 BL2_SOURCES		+=	lib/cpus/aarch64/dsu_helpers.S
 endif
 
-BL2_LINKERFILE		:=	bl2/bl2_el3.ld.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2_el3.ld.S
 endif
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index c95706c..0c2764e 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -15,140 +15,158 @@
 #if BL2_IN_XIP_MEM
     ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
     RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
-#else
+#else /* BL2_IN_XIP_MEM */
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
-#endif
+#endif /* BL2_IN_XIP_MEM */
+
 #if SEPARATE_BL2_NOLOAD_REGION
     RAM_NOLOAD (rw!a): ORIGIN = BL2_NOLOAD_START, LENGTH = BL2_NOLOAD_LIMIT - BL2_NOLOAD_START
-#else
-#define RAM_NOLOAD RAM
-#endif
+#else /* SEPARATE_BL2_NOLOAD_REGION */
+#   define RAM_NOLOAD RAM
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
 }
 
 #if !BL2_IN_XIP_MEM
-#define ROM RAM
-#endif
+#   define ROM RAM
+#endif /* !BL2_IN_XIP_MEM */
 
-SECTIONS
-{
+SECTIONS {
 #if BL2_IN_XIP_MEM
     . = BL2_RO_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2_RO_BASE address is not aligned on a page boundary.")
-#else
+        "BL2_RO_BASE address is not aligned on a page boundary.")
+#else /* BL2_IN_XIP_MEM */
     . = BL2_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2_BASE address is not aligned on a page boundary.")
-#endif
+        "BL2_BASE address is not aligned on a page boundary.")
+#endif /* BL2_IN_XIP_MEM */
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
-	__TEXT_RESIDENT_START__ = .;
-	*bl2_el3_entrypoint.o(.text*)
-	*(.text.asm.*)
-	__TEXT_RESIDENT_END__ = .;
+        __TEXT_RESIDENT_START__ = .;
+
+        *bl2_el3_entrypoint.o(.text*)
+        *(.text.asm.*)
+
+        __TEXT_RESIDENT_END__ = .;
+
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
-     } >ROM
+    } >ROM
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >ROM
 
     ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
-          "Resident part of BL2 has exceeded its limit.")
-#else
+        "Resident part of BL2 has exceeded its limit.")
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
-	__TEXT_RESIDENT_START__ = .;
-	*bl2_el3_entrypoint.o(.text*)
-	*(.text.asm.*)
-	__TEXT_RESIDENT_END__ = .;
+        __TEXT_RESIDENT_START__ = .;
+
+        *bl2_el3_entrypoint.o(.text*)
+        *(.text.asm.*)
+
+        __TEXT_RESIDENT_END__ = .;
+
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
 
         __RO_END__ = .;
     } >ROM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-          "cpu_ops not defined for this platform.")
+        "cpu_ops not defined for this platform.")
 
 #if BL2_IN_XIP_MEM
     . = BL2_RW_BASE;
+
     ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
            "BL2_RW_BASE address is not aligned on a page boundary.")
-#endif
+#endif /* BL2_IN_XIP_MEM */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM AT>ROM
+
     __DATA_RAM_START__ = __DATA_START__;
     __DATA_RAM_END__ = __DATA_END__;
 
     RELA_SECTION >RAM
+
 #if SEPARATE_BL2_NOLOAD_REGION
     SAVED_ADDR = .;
+
     . = BL2_NOLOAD_START;
+
     __BL2_NOLOAD_START__ = .;
-#endif
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
+
     STACK_SECTION >RAM_NOLOAD
     BSS_SECTION >RAM_NOLOAD
     XLAT_TABLE_SECTION >RAM_NOLOAD
+
 #if SEPARATE_BL2_NOLOAD_REGION
     __BL2_NOLOAD_END__ = .;
+
     . = SAVED_ADDR;
-#endif
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
+
         *(tzfw_coherent_mem)
+
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL2_END__ = .;
 
@@ -165,23 +183,24 @@
 
     /*
      * The .data section is the last PROGBITS section so its end marks the end
-     * of BL2's RO content in XIP memory..
+     * of BL2's RO content in XIP memory.
      */
     __BL2_ROM_END__ =  __DATA_ROM_START__ + __DATA_SIZE__;
+
     ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
            "BL2's RO content has exceeded its limit.")
-#endif
-    __BSS_SIZE__ = SIZEOF(.bss);
+#endif /* BL2_IN_XIP_MEM */
 
+    __BSS_SIZE__ = SIZEOF(.bss);
 
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
 #if BL2_IN_XIP_MEM
     ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
-#else
+#else /* BL2_IN_XIP_MEM */
     ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
-#endif
+#endif /* BL2_IN_XIP_MEM */
 }
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index a7752a4..0f06dfd 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -17,67 +17,69 @@
     RAM (rwx): ORIGIN = BL2U_BASE, LENGTH = BL2U_LIMIT - BL2U_BASE
 }
 
-
-SECTIONS
-{
+SECTIONS {
     . = BL2U_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2U_BASE address is not aligned on a page boundary.")
+        "BL2U_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *bl2u_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
-     } >RAM
+    } >RAM
 
-     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
-     .ARM.extab . : {
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
+    .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
-     } >RAM
+    } >RAM
 
-     .ARM.exidx . : {
+    .ARM.exidx . : {
         *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-     } >RAM
+    } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *bl2u_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     STACK_SECTION >RAM
@@ -86,29 +88,27 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL2U_END__ = .;
 
diff --git a/bl2u/bl2u.mk b/bl2u/bl2u.mk
index b4d7634..9f29bde 100644
--- a/bl2u/bl2u.mk
+++ b/bl2u/bl2u.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,4 +12,4 @@
 BL2U_SOURCES		+=	common/aarch64/early_exceptions.S
 endif
 
-BL2U_LINKERFILE		:=	bl2u/bl2u.ld.S
+BL2U_DEFAULT_LINKER_SCRIPT_SOURCE := bl2u/bl2u.ld.S
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index dbb3234..83e4582 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -16,9 +16,8 @@
 #include <context.h>
 
 	.globl	handle_lower_el_ea_esb
-	.globl  handle_lower_el_async_ea
-	.globl	enter_lower_el_sync_ea
-	.globl	enter_lower_el_async_ea
+	.globl	handle_lower_el_sync_ea
+	.globl	handle_lower_el_async_ea
 
 
 /*
@@ -42,17 +41,12 @@
  * Implementation Defined Exceptions. If any other kind of exception is detected,
  * then this function reports unhandled exception.
  *
- * Since it's part of exception vector, this function doesn't expect any GP
- * registers to have been saved. It delegates the handling of the EA to platform
- * handler, and upon successfully handling the EA, exits EL3; otherwise panics.
+ * It delegates the handling of the EA to platform handler, and upon successfully
+ * handling the EA, exits EL3; otherwise panics.
+ *
+ * This function assumes x30 has been saved.
  */
-func enter_lower_el_sync_ea
-	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching.
-	 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-
+func handle_lower_el_sync_ea
 	mrs	x30, esr_el3
 	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
 
@@ -114,24 +108,19 @@
 	/* Synchronous exceptions other than the above are assumed to be EA */
 	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 	no_ret	report_unhandled_exception
-endfunc enter_lower_el_sync_ea
+endfunc handle_lower_el_sync_ea
 
 
 /*
  * This function handles SErrors from lower ELs.
  *
- * Since it's part of exception vector, this function doesn't expect any GP
- * registers to have been saved. It delegates the handling of the EA to platform
- * handler, and upon successfully handling the EA, exits EL3; otherwise panics.
+ * It delegates the handling of the EA to platform handler, and upon successfully
+ * handling the EA, exits EL3; otherwise panics.
+ *
+ * This function assumes x30 has been saved.
  */
-func enter_lower_el_async_ea
-	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching
-	 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+func handle_lower_el_async_ea
 
-handle_lower_el_async_ea:
 	/*
 	 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
 	 * If Secure Cycle Counter is not disabled in MDCR_EL3 when
@@ -153,7 +142,7 @@
 	/* el3_exit assumes SP_EL0 on entry */
 	msr	spsel, #MODE_SP_EL0
 	b	el3_exit
-endfunc enter_lower_el_async_ea
+endfunc handle_lower_el_async_ea
 
 
 /*
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 614ea71..4cbcddc 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -10,6 +10,7 @@
 #include <asm_macros.S>
 #include <bl31/ea_handle.h>
 #include <bl31/interrupt_mgmt.h>
+#include <bl31/sync_handle.h>
 #include <common/runtime_svc.h>
 #include <context.h>
 #include <el3_common_macros.S>
@@ -39,6 +40,14 @@
 	.globl	serror_aarch32
 
 	/*
+	 * Save LR and make x30 available as most of the routines in vector entry
+	 * need a free register
+	 */
+	.macro save_x30
+	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	.endm
+
+	/*
 	 * Macro that prepares entry to EL3 upon taking an exception.
 	 *
 	 * With RAS_EXTENSION, this macro synchronizes pending errors with an ESB
@@ -57,12 +66,6 @@
 	/* Unmask the SError interrupt */
 	msr	daifclr, #DAIF_ABT_BIT
 
-	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching
-	 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-
 	/* Check for SErrors synchronized by the ESB instruction */
 	mrs	x30, DISR_EL1
 	tbz	x30, #DISR_A_BIT, 1f
@@ -82,31 +85,6 @@
 1:
 #else
 	/*
-	 * For SoCs which do not implement RAS, use DSB as a barrier to
-	 * synchronize pending external aborts.
-	 */
-	dsb	sy
-
-	/* Unmask the SError interrupt */
-	msr	daifclr, #DAIF_ABT_BIT
-
-	/* Use ISB for the above unmask operation to take effect immediately */
-	isb
-
-	/*
-	 * Refer Note 1. No need to restore X30 as both handle_sync_exception
-	 * and handle_interrupt_exception macro which follow this macro modify
-	 * X30 anyway.
-	 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-	mov 	x30, #1
-	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
-	dmb	sy
-#endif
-	.endm
-
-#if !RAS_EXTENSION
-	/*
 	 * Note 1: The explicit DSB at the entry of various exception vectors
 	 * for handling exceptions from lower ELs can inadvertently trigger an
 	 * SError exception in EL3 due to pending asynchronous aborts in lower
@@ -120,13 +98,9 @@
 	 * flag execute without causing further exceptions.
 	 */
 
-	/* ---------------------------------------------------------------------
-	 * This macro handles Asynchronous External Aborts.
-	 * ---------------------------------------------------------------------
-	 */
-	.macro	handle_async_ea
 	/*
-	 * Use a barrier to synchronize pending external aborts.
+	 * For SoCs which do not implement RAS, use DSB as a barrier to
+	 * synchronize pending external aborts.
 	 */
 	dsb	sy
 
@@ -136,33 +110,12 @@
 	/* Use ISB for the above unmask operation to take effect immediately */
 	isb
 
-	/* Refer Note 1 */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	/* Refer Note 1. */
 	mov 	x30, #1
 	str	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
 	dmb	sy
-
-	b	handle_lower_el_async_ea
-	.endm
-
-	/*
-	 * This macro checks if the exception was taken due to SError in EL3 or
-	 * because of pending asynchronous external aborts from lower EL that got
-	 * triggered due to explicit synchronization in EL3. Refer Note 1.
-	 */
-	.macro check_if_serror_from_EL3
-	/* Assumes SP_EL3 on entry */
-	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
-	cbnz	x30, exp_from_EL3
-
-	/* Handle asynchronous external abort from lower EL */
-	b	handle_lower_el_async_ea
-
-exp_from_EL3:
-	/* Jump to plat_handle_el3_ea which does not return */
-	.endm
 #endif
+	.endm
 
 	/* ---------------------------------------------------------------------
 	 * This macro handles Synchronous exceptions.
@@ -191,11 +144,14 @@
 	b.eq	smc_handler32
 
 	cmp	x30, #EC_AARCH64_SMC
-	b.eq	smc_handler64
+	b.eq	sync_handler64
+
+	cmp	x30, #EC_AARCH64_SYS
+	b.eq	sync_handler64
 
 	/* Synchronous exceptions other than the above are assumed to be EA */
 	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-	b	enter_lower_el_sync_ea
+	b	handle_lower_el_sync_ea
 	.endm
 
 
@@ -352,7 +308,19 @@
 
 vector_entry serror_sp_elx
 #if !RAS_EXTENSION
-	check_if_serror_from_EL3
+	/*
+	 * This will trigger if the exception was taken due to SError in EL3 or
+	 * because of pending asynchronous external aborts from lower EL that got
+	 * triggered due to explicit synchronization in EL3. Refer Note 1.
+	 */
+	/* Assumes SP_EL3 on entry */
+	save_x30
+	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
+	cbnz	x30, 1f
+
+	/* Handle asynchronous external abort from lower EL */
+	b	handle_lower_el_async_ea
+1:
 #endif
 	no_ret	plat_handle_el3_ea
 end_vector_entry serror_sp_elx
@@ -368,31 +336,36 @@
 	 * to a valid cpu context where the general purpose and system register
 	 * state can be saved.
 	 */
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch64
 
 vector_entry irq_aarch64
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception irq_aarch64
 end_vector_entry irq_aarch64
 
 vector_entry fiq_aarch64
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception fiq_aarch64
 end_vector_entry fiq_aarch64
 
 vector_entry serror_aarch64
+	save_x30
 	apply_at_speculative_wa
 #if RAS_EXTENSION
 	msr	daifclr, #DAIF_ABT_BIT
-	b	enter_lower_el_async_ea
 #else
-	handle_async_ea
+	check_and_unmask_ea
 #endif
+	b	handle_lower_el_async_ea
+
 end_vector_entry serror_aarch64
 
 	/* ---------------------------------------------------------------------
@@ -406,31 +379,36 @@
 	 * to a valid cpu context where the general purpose and system register
 	 * state can be saved.
 	 */
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch32
 
 vector_entry irq_aarch32
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception irq_aarch32
 end_vector_entry irq_aarch32
 
 vector_entry fiq_aarch32
+	save_x30
 	apply_at_speculative_wa
 	check_and_unmask_ea
 	handle_interrupt_exception fiq_aarch32
 end_vector_entry fiq_aarch32
 
 vector_entry serror_aarch32
+	save_x30
 	apply_at_speculative_wa
 #if RAS_EXTENSION
 	msr	daifclr, #DAIF_ABT_BIT
-	b	enter_lower_el_async_ea
 #else
-	handle_async_ea
+	check_and_unmask_ea
 #endif
+	b	handle_lower_el_async_ea
+
 end_vector_entry serror_aarch32
 
 #ifdef MONITOR_TRAPS
@@ -452,12 +430,12 @@
 	 * Note that x30 has been explicitly saved and can be used here
 	 * ---------------------------------------------------------------------
 	 */
-func smc_handler
+func sync_exception_handler
 smc_handler32:
 	/* Check whether aarch32 issued an SMC64 */
 	tbnz	x0, #FUNCID_CC_SHIFT, smc_prohibited
 
-smc_handler64:
+sync_handler64:
 	/* NOTE: The code below must preserve x0-x4 */
 
 	/*
@@ -504,6 +482,12 @@
 	/* Load SCR_EL3 */
 	mrs	x18, scr_el3
 
+	/* check for system register traps */
+	mrs	x16, esr_el3
+	ubfx	x17, x16, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+	cmp	x17, #EC_AARCH64_SYS
+	b.eq	sysreg_handler64
+
 	/* Clear flag register */
 	mov	x7, xzr
 
@@ -567,6 +551,32 @@
 #endif
 	blr	x15
 
+	b	el3_exit
+
+sysreg_handler64:
+	mov	x0, x16		/* ESR_EL3, containing syndrome information */
+	mov	x1, x6		/* lower EL's context */
+	mov	x19, x6		/* save context pointer for after the call */
+	mov	sp, x12		/* EL3 runtime stack, as loaded above */
+
+	/* int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx); */
+	bl	handle_sysreg_trap
+	/*
+	 * returns:
+	 *   -1: unhandled trap, panic
+	 *    0: handled trap, return to the trapping instruction (repeating it)
+	 *    1: handled trap, return to the next instruction
+	 */
+
+	tst	w0, w0
+	b.mi	do_panic	/* negative return value: panic */
+	b.eq	1f		/* zero: do not change ELR_EL3 */
+
+	/* advance the PC to continue after the instruction */
+	ldr	x1, [x19, #CTX_EL3STATE_OFFSET + CTX_ELR_EL3]
+	add	x1, x1, #4
+	str	x1, [x19, #CTX_EL3STATE_OFFSET + CTX_ELR_EL3]
+1:
 	b	el3_exit
 
 smc_unknown:
@@ -593,7 +603,7 @@
 	msr	spsel, #MODE_SP_ELX
 	no_ret	report_unhandled_exception
 #endif
-endfunc smc_handler
+endfunc sync_exception_handler
 
 	/* ---------------------------------------------------------------------
 	 * The following code handles exceptions caused by BRK instructions.
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 309e752..5d3139b 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -11,137 +11,145 @@
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(bl31_entrypoint)
 
-
 MEMORY {
     RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE
+
 #if SEPARATE_NOBITS_REGION
     NOBITS (rw!a): ORIGIN = BL31_NOBITS_BASE, LENGTH = BL31_NOBITS_LIMIT - BL31_NOBITS_BASE
-#else
-#define NOBITS RAM
-#endif
+#else /* SEPARATE_NOBITS_REGION */
+#   define NOBITS RAM
+#endif /* SEPARATE_NOBITS_REGION */
 }
 
 #ifdef PLAT_EXTRA_LD_SCRIPT
-#include <plat.ld.S>
-#endif
+#   include <plat.ld.S>
+#endif /* PLAT_EXTRA_LD_SCRIPT */
 
-SECTIONS
-{
+SECTIONS {
     . = BL31_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL31_BASE address is not aligned on a page boundary.")
+        "BL31_BASE address is not aligned on a page boundary.")
 
     __BL31_START__ = .;
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *bl31_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(SORT(.text*)))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-#if PLAT_EXTRA_RODATA_INCLUDES
-#include <plat.ld.rodata.inc>
-#endif
+#   if PLAT_EXTRA_RODATA_INCLUDES
+#       include <plat.ld.rodata.inc>
+#   endif /* PLAT_EXTRA_RODATA_INCLUDES */
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *bl31_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
          * Memory page(s) mapped to this section will be marked as read-only,
-         * executable.  No RW data from the next section must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
+        "cpu_ops not defined for this platform.")
 
 #if SPM_MM
-#ifndef SPM_SHIM_EXCEPTIONS_VMA
-#define SPM_SHIM_EXCEPTIONS_VMA         RAM
-#endif
+#   ifndef SPM_SHIM_EXCEPTIONS_VMA
+#       define SPM_SHIM_EXCEPTIONS_VMA RAM
+#   endif /* SPM_SHIM_EXCEPTIONS_VMA */
 
     /*
      * Exception vectors of the SPM shim layer. They must be aligned to a 2K
-     * address, but we need to place them in a separate page so that we can set
-     * individual permissions to them, so the actual alignment needed is 4K.
+     * address but we need to place them in a separate page so that we can set
+     * individual permissions on them, so the actual alignment needed is the
+     * page size.
      *
      * There's no need to include this into the RO section of BL31 because it
      * doesn't need to be accessed by BL31.
      */
     spm_shim_exceptions : ALIGN(PAGE_SIZE) {
         __SPM_SHIM_EXCEPTIONS_START__ = .;
+
         *(.spm_shim_exceptions)
+
         . = ALIGN(PAGE_SIZE);
+
         __SPM_SHIM_EXCEPTIONS_END__ = .;
     } >SPM_SHIM_EXCEPTIONS_VMA AT>RAM
 
     PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(spm_shim_exceptions));
+
     . = LOADADDR(spm_shim_exceptions) + SIZEOF(spm_shim_exceptions);
-#endif
+#endif /* SPM_MM */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
 
 #ifdef BL31_PROGBITS_LIMIT
     ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
-#endif
+#endif /* BL31_PROGBITS_LIMIT */
 
 #if SEPARATE_NOBITS_REGION
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     . = ALIGN(PAGE_SIZE);
+
     __RW_END__ = .;
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
 
     . = BL31_NOBITS_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL31 NOBITS base address is not aligned on a page boundary.")
+        "BL31 NOBITS base address is not aligned on a page boundary.")
 
     __NOBITS_START__ = .;
-#endif
+#endif /* SEPARATE_NOBITS_REGION */
 
     STACK_SECTION >NOBITS
     BSS_SECTION >NOBITS
@@ -149,49 +157,44 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
+
         /*
-         * Bakery locks are stored in coherent memory
-         *
-         * Each lock's data is contiguous and fully allocated by the compiler
+         * Bakery locks are stored in coherent memory. Each lock's data is
+         * contiguous and fully allocated by the compiler.
          */
         *(bakery_lock)
         *(tzfw_coherent_mem)
+
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >NOBITS
-#endif
+#endif /* USE_COHERENT_MEM */
 
 #if SEPARATE_NOBITS_REGION
-    /*
-     * Define a linker symbol to mark end of the NOBITS memory area for this
-     * image.
-     */
     __NOBITS_END__ = .;
 
     ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
-#else
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
+#else /* SEPARATE_NOBITS_REGION */
     __RW_END__ = .;
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
-#endif
+#endif /* SEPARATE_NOBITS_REGION */
 
     /DISCARD/ : {
         *(.dynsym .dynstr .hash .gnu.hash)
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 4c93a55..e6609fe 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -42,6 +42,7 @@
 				bl31/aarch64/ea_delegate.S			\
 				bl31/aarch64/runtime_exceptions.S		\
 				bl31/bl31_context_mgmt.c			\
+				bl31/bl31_traps.c				\
 				common/runtime_svc.c				\
 				lib/cpus/aarch64/dsu_helpers.S			\
 				plat/common/aarch64/platform_mp_stack.S		\
@@ -156,7 +157,7 @@
 				${MBEDTLS_SOURCES}
 endif
 
-BL31_LINKERFILE		:=	bl31/bl31.ld.S
+BL31_DEFAULT_LINKER_SCRIPT_SOURCE := bl31/bl31.ld.S
 
 # Flag used to indicate if Crash reporting via console should be included
 # in BL31. This defaults to being present in DEBUG builds only
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 2a3d838..e70eb55 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -93,15 +93,6 @@
 	/* Perform late platform-specific setup */
 	bl31_plat_arch_setup();
 
-#if ENABLE_FEAT_HCX
-	/*
-	 * Assert that FEAT_HCX is supported on this system, without this check
-	 * an exception would occur during context save/restore if enabled but
-	 * not supported.
-	 */
-	assert(is_feat_hcx_present());
-#endif /* ENABLE_FEAT_HCX */
-
 #if CTX_INCLUDE_PAUTH_REGS
 	/*
 	 * Assert that the ARMv8.3-PAuth registers are present or an access
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
new file mode 100644
index 0000000..b12185d
--- /dev/null
+++ b/bl31/bl31_traps.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Dispatch synchronous system register traps from lower ELs.
+ */
+
+#include <bl31/sync_handle.h>
+#include <context.h>
+
+int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx)
+{
+	switch (esr_el3 & ISS_SYSREG_OPCODE_MASK) {
+#if ENABLE_FEAT_RNG_TRAP
+	case ISS_SYSREG_OPCODE_RNDR:
+	case ISS_SYSREG_OPCODE_RNDRRS:
+		return plat_handle_rng_trap(esr_el3, ctx);
+#endif
+	default:
+		return TRAP_RET_UNHANDLED;
+	}
+}
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 475affa..59e164a 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -16,130 +16,132 @@
 }
 
 #ifdef PLAT_SP_MIN_EXTRA_LD_SCRIPT
-#include <plat_sp_min.ld.S>
-#endif
+#   include <plat_sp_min.ld.S>
+#endif /* PLAT_SP_MIN_EXTRA_LD_SCRIPT */
 
-SECTIONS
-{
+SECTIONS {
     . = BL32_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL32_BASE address is not aligned on a page boundary.")
+        "BL32_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
-     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
-     .ARM.extab . : {
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
+    .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
-     } >RAM
+    } >RAM
 
-     .ARM.exidx . : {
+    .ARM.exidx . : {
         *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-     } >RAM
+    } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
 
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure that the rest
+         * of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+        "cpu_ops not defined for this platform.")
+
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
 
 #ifdef BL32_PROGBITS_LIMIT
     ASSERT(. <= BL32_PROGBITS_LIMIT, "BL32 progbits has exceeded its limit.")
-#endif
+#endif /* BL32_PROGBITS_LIMIT */
 
     STACK_SECTION >RAM
     BSS_SECTION >RAM
     XLAT_TABLE_SECTION >RAM
 
-     __BSS_SIZE__ = SIZEOF(.bss);
+    __BSS_SIZE__ = SIZEOF(.bss);
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
+
         /*
-         * Bakery locks are stored in coherent memory
-         *
-         * Each lock's data is contiguous and fully allocated by the compiler
+         * Bakery locks are stored in coherent memory. Each lock's data is
+         * contiguous and fully allocated by the compiler.
          */
         *(bakery_lock)
         *(tzfw_coherent_mem)
+
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure that the rest
+         * of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
 
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark the end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
-
     __BL32_END__ = .;
 
     /DISCARD/ : {
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index ab1287d..b2f4e4c 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -54,7 +54,7 @@
 BL32_SOURCES		+=	lib/extensions/trf/aarch32/trf.c
 endif
 
-BL32_LINKERFILE	:=	bl32/sp_min/sp_min.ld.S
+BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/sp_min/sp_min.ld.S
 
 # Include the platform-specific SP_MIN Makefile
 # If no platform-specific SP_MIN Makefile exists, it means SP_MIN is not supported
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index d86ae55..1e9cb88 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -11,71 +11,73 @@
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(tsp_entrypoint)
 
-
 MEMORY {
     RAM (rwx): ORIGIN = TSP_SEC_MEM_BASE, LENGTH = TSP_SEC_MEM_SIZE
 }
 
-
-SECTIONS
-{
+SECTIONS {
     . = BL32_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL32_BASE address is not aligned on a page boundary.")
+        "BL32_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(.rodata*)
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.rodata*)
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
 
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
 
 #ifdef TSP_PROGBITS_LIMIT
     ASSERT(. <= TSP_PROGBITS_LIMIT, "TSP progbits has exceeded its limit.")
-#endif
+#endif /* TSP_PROGBITS_LIMIT */
 
     STACK_SECTION >RAM
     BSS_SECTION >RAM
@@ -83,29 +85,27 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
-     * memory attributes for the coherent data page tables.
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data. This is required to set up the correct memory
+     * attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure that the rest
+         * of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark the end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL32_END__ = .;
 
@@ -114,10 +114,11 @@
     }
 
     __BSS_SIZE__ = SIZEOF(.bss);
+
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL32_LIMIT, "BL32 image has exceeded its limit.")
 }
diff --git a/bl32/tsp/tsp.mk b/bl32/tsp/tsp.mk
index c31b9b5..cfffbdb 100644
--- a/bl32/tsp/tsp.mk
+++ b/bl32/tsp/tsp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -22,7 +22,7 @@
 				common/aarch64/early_exceptions.S	\
 				lib/locks/exclusive/aarch64/spinlock.S
 
-BL32_LINKERFILE		:=	bl32/tsp/tsp.ld.S
+BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/tsp/tsp.ld.S
 
 # This flag determines if the TSPD initializes BL32 in tspd_init() (synchronous
 # method) or configures BL31 to pass control to BL32 instead of BL33
diff --git a/bl32/tsp/tsp_ffa_main.c b/bl32/tsp/tsp_ffa_main.c
index 2c53977..268d329 100644
--- a/bl32/tsp/tsp_ffa_main.c
+++ b/bl32/tsp/tsp_ffa_main.c
@@ -201,7 +201,7 @@
 	/* Only expecting to be sent memory from NWd so map accordingly. */
 	mem_attrs |= MT_NS;
 
-	for (uint32_t i = 0U; i < composite->address_range_count; i++) {
+	for (int32_t i = 0; i < (int32_t)composite->address_range_count; i++) {
 		size_t size = composite->address_range_array[i].page_count * PAGE_SIZE;
 
 		ptr = (char *) composite->address_range_array[i].address;
@@ -211,7 +211,7 @@
 				size, mem_attrs);
 
 		if (ret != 0) {
-			ERROR("Failed [%u] mmap_add_dynamic_region %u (%lx) (%lx) (%x)!\n",
+			ERROR("Failed [%d] mmap_add_dynamic_region %u (%lx) (%lx) (%x)!\n",
 				i, ret,
 				(uint64_t)composite->address_range_array[i].address,
 				size, mem_attrs);
diff --git a/changelog.yaml b/changelog.yaml
index cfb2bb5..e100f82 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -101,6 +101,9 @@
       - title: Extended Cache Index (FEAT_CCIDX)
         scope: ccidx
 
+      - title: CPU feature / ID register handling in general
+        scope: cpufeat
+
       - title: Support for the `HCRX_EL2` register (FEAT_HCX)
         scope: hcx
 
@@ -744,6 +747,9 @@
           - title: mbedTLS
             scope: mbedtls
 
+      - title: Console
+        scope: console
+
       - title: Generic Clock
         scope: clk
 
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 1b065b1..783b660 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -206,9 +206,9 @@
 	assert(cells <= 2U);
 
 	if (cells == 2U)
-		*(uint64_t *)value = cpu_to_fdt64(*(uint64_t *)value);
+		*(fdt64_t *)value = cpu_to_fdt64(*(uint64_t *)value);
 	else
-		*(uint32_t *)value = cpu_to_fdt32(*(uint32_t *)value);
+		*(fdt32_t *)value = cpu_to_fdt32(*(uint32_t *)value);
 
 	len = (int)cells * 4;
 
@@ -392,7 +392,7 @@
  * to a global address with help of various helper functions.
  ******************************************************************************/
 
-static bool fdtw_xlat_hit(const uint32_t *value, int child_addr_size,
+static bool fdtw_xlat_hit(const fdt32_t *value, int child_addr_size,
 		int parent_addr_size, int range_size, uint64_t base_address,
 		uint64_t *translated_addr)
 {
@@ -427,7 +427,7 @@
 				int local_bus, uint64_t base_address)
 {
 	uint64_t translated_addr;
-	const uint32_t *next_entry;
+	const fdt32_t *next_entry;
 	int parent_bus_node, nxlat_entries, length;
 	int self_addr_cells, parent_addr_cells, self_size_cells, ncells_xlat;
 
@@ -460,7 +460,7 @@
 
 	assert(nxlat_entries > 0);
 
-	next_entry = (const uint32_t *)ranges_prop->data;
+	next_entry = (const fdt32_t *)ranges_prop->data;
 
 	/* Iterate over the entries in the "ranges" */
 	for (int i = 0; i < nxlat_entries; i++) {
diff --git a/common/feat_detect.c b/common/feat_detect.c
index ee34588..a8c40f7 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -4,24 +4,59 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arch_features.h>
+#include <common/debug.h>
 #include <common/feat_detect.h>
 
+static bool tainted;
+
 /*******************************************************************************
  * This section lists the wrapper modules for each feature to evaluate the
- * feature states (FEAT_STATE_1 and FEAT_STATE_2) and perform necessary action
- * as below:
+ * feature states (FEAT_STATE_ALWAYS and FEAT_STATE_CHECK) and perform
+ * necessary action as below:
  *
  * It verifies whether the FEAT_XXX (eg: FEAT_SB) is supported by the PE or not.
  * Without this check an exception would occur during context save/restore
  * routines, if the feature is enabled but not supported by PE.
  ******************************************************************************/
+
+#define feat_detect_panic(a, b)		((a) ? (void)0 : feature_panic(b))
+
+/*******************************************************************************
+ * Function : feature_panic
+ * Customised panic function with error logging mechanism to list the feature
+ * not supported by the PE.
+ ******************************************************************************/
+static inline void feature_panic(char *feat_name)
+{
+	ERROR("FEAT_%s not supported by the PE\n", feat_name);
+	panic();
+}
+
+/*******************************************************************************
+ * Function : check_feature
+ * Check for a valid combination of build time flags (ENABLE_FEAT_xxx) and
+ * feature availability on the hardware.
+ * Panics if a feature is forcefully enabled, but not available on the PE.
+ *
+ * We force inlining here to let the compiler optimise away the whole check
+ * if the feature is disabled at build time (FEAT_STATE_DISABLED).
+ ******************************************************************************/
+static inline void __attribute((__always_inline__))
+check_feature(int state, unsigned long field, const char *feat_name)
+{
+	if (state == FEAT_STATE_ALWAYS && field == 0U) {
+		ERROR("FEAT_%s not supported by the PE\n", feat_name);
+		tainted = true;
+	}
+}
 
 /******************************************
  * Feature : FEAT_SB (Speculation Barrier)
  *****************************************/
 static void read_feat_sb(void)
 {
-#if (ENABLE_FEAT_SB == FEAT_STATE_1)
+#if (ENABLE_FEAT_SB == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_0_feat_sb_present(), "SB");
 #endif
 }
@@ -31,7 +66,7 @@
  *****************************************************/
 static void read_feat_csv2_2(void)
 {
-#if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_1)
+#if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_0_feat_csv2_2_present(), "CSV2_2");
 #endif
 }
@@ -41,7 +76,7 @@
  **********************************************/
 static void read_feat_pan(void)
 {
-#if (ENABLE_FEAT_PAN == FEAT_STATE_1)
+#if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_1_pan_present(), "PAN");
 #endif
 }
@@ -51,7 +86,7 @@
  *****************************************************/
 static void read_feat_vhe(void)
 {
-#if (ENABLE_FEAT_VHE == FEAT_STATE_1)
+#if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_1_vhe_present(), "VHE");
 #endif
 }
@@ -61,7 +96,7 @@
  ******************************************************************************/
 static void read_feat_ras(void)
 {
-#if (RAS_EXTENSION == FEAT_STATE_1)
+#if (RAS_EXTENSION == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS");
 #endif
 }
@@ -71,7 +106,7 @@
  ***********************************************/
 static void read_feat_pauth(void)
 {
-#if (ENABLE_PAUTH == FEAT_STATE_1) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_1)
+#if (ENABLE_PAUTH == FEAT_STATE_ALWAYS) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_3_pauth_present(), "PAUTH");
 #endif
 }
@@ -81,27 +116,17 @@
  ***********************************************************/
 static void read_feat_dit(void)
 {
-#if (ENABLE_FEAT_DIT == FEAT_STATE_1)
+#if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT");
 #endif
 }
 
-/*********************************************************
- * Feature : FEAT_AMUv1 (Activity Monitors Extensions v1)
- ********************************************************/
-static void read_feat_amuv1(void)
-{
-#if (ENABLE_FEAT_AMUv1 == FEAT_STATE_1)
-	feat_detect_panic(is_armv8_4_feat_amuv1_present(), "AMUv1");
-#endif
-}
-
 /****************************************************************************
  * Feature : FEAT_MPAM (Memory Partitioning and Monitoring (MPAM) Extension)
  ***************************************************************************/
 static void read_feat_mpam(void)
 {
-#if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_1)
+#if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS)
 	feat_detect_panic(get_mpam_version() != 0U, "MPAM");
 #endif
 }
@@ -111,7 +136,7 @@
  *************************************************************/
 static void read_feat_nv2(void)
 {
-#if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_1)
+#if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_ALWAYS)
 	unsigned int nv = get_armv8_4_feat_nv_support();
 
 	feat_detect_panic((nv == ID_AA64MMFR2_EL1_NV2_SUPPORTED), "NV2");
@@ -123,7 +148,7 @@
  **********************************/
 static void read_feat_sel2(void)
 {
-#if (ENABLE_FEAT_SEL2 == FEAT_STATE_1)
+#if (ENABLE_FEAT_SEL2 == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_4_sel2_present(), "SEL2");
 #endif
 }
@@ -133,7 +158,7 @@
  ***************************************************/
 static void read_feat_trf(void)
 {
-#if (ENABLE_TRF_FOR_NS == FEAT_STATE_1)
+#if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_arm8_4_feat_trf_present(), "TRF");
 #endif
 }
@@ -143,7 +168,7 @@
  ***********************************************/
 static void read_feat_mte(void)
 {
-#if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_1)
+#if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_ALWAYS)
 	unsigned int mte = get_armv8_5_mte_support();
 
 	feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE");
@@ -155,7 +180,7 @@
  **********************************************/
 static void read_feat_rng(void)
 {
-#if (ENABLE_FEAT_RNG == FEAT_STATE_1)
+#if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_5_rng_present(), "RNG");
 #endif
 }
@@ -165,27 +190,17 @@
  ***************************************************/
 static void read_feat_bti(void)
 {
-#if (ENABLE_BTI == FEAT_STATE_1)
+#if (ENABLE_BTI == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_5_bti_present(), "BTI");
 #endif
 }
 
-/****************************************
- * Feature : FEAT_FGT (Fine Grain Traps)
- ***************************************/
-static void read_feat_fgt(void)
-{
-#if (ENABLE_FEAT_FGT == FEAT_STATE_1)
-	feat_detect_panic(is_armv8_6_fgt_present(), "FGT");
-#endif
-}
-
 /***********************************************
  * Feature : FEAT_AMUv1p1 (AMU Extensions v1.1)
  **********************************************/
 static void read_feat_amuv1p1(void)
 {
-#if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_1)
+#if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_6_feat_amuv1p1_present(), "AMUv1p1");
 #endif
 }
@@ -195,7 +210,7 @@
  ******************************************************/
 static void read_feat_ecv(void)
 {
-#if (ENABLE_FEAT_ECV == FEAT_STATE_1)
+#if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS)
 	unsigned int ecv = get_armv8_6_ecv_support();
 
 	feat_detect_panic(((ecv == ID_AA64MMFR0_EL1_ECV_SUPPORTED) ||
@@ -208,27 +223,17 @@
  **********************************************************/
 static void read_feat_twed(void)
 {
-#if (ENABLE_FEAT_TWED == FEAT_STATE_1)
+#if (ENABLE_FEAT_TWED == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_armv8_6_twed_present(), "TWED");
 #endif
 }
 
-/******************************************************************
- * Feature : FEAT_HCX (Extended Hypervisor Configuration Register)
- *****************************************************************/
-static void read_feat_hcx(void)
-{
-#if (ENABLE_FEAT_HCX == FEAT_STATE_1)
-	feat_detect_panic(is_feat_hcx_present(), "HCX");
-#endif
-}
-
 /**************************************************
  * Feature : FEAT_RME (Realm Management Extension)
  *************************************************/
 static void read_feat_rme(void)
 {
-#if (ENABLE_RME == FEAT_STATE_1)
+#if (ENABLE_RME == FEAT_STATE_ALWAYS)
 	feat_detect_panic((get_armv9_2_feat_rme_support() !=
 			ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME");
 #endif
@@ -239,7 +244,7 @@
  *****************************************************/
 static void read_feat_brbe(void)
 {
-#if (ENABLE_BRBE_FOR_NS == FEAT_STATE_1)
+#if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_feat_brbe_present(), "BRBE");
 #endif
 }
@@ -249,7 +254,7 @@
  *****************************************************/
 static void read_feat_trbe(void)
 {
-#if (ENABLE_TRBE_FOR_NS == FEAT_STATE_1)
+#if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_feat_trbe_present(), "TRBE");
 #endif
 }
@@ -259,7 +264,7 @@
  *****************************************************************/
 static void read_feat_rng_trap(void)
 {
-#if (ENABLE_FEAT_RNG_TRAP == FEAT_STATE_1)
+#if (ENABLE_FEAT_RNG_TRAP == FEAT_STATE_ALWAYS)
 	feat_detect_panic(is_feat_rng_trap_present(), "RNG_TRAP");
 #endif
 }
@@ -283,11 +288,14 @@
  * ENABLE_FEAT_xxx = 2 : The feature is enabled but dynamically enabled at runtime
  *                       depending on hardware capability.
  *
- * For better readability, state values are defined with macros namely:
- * { FEAT_STATE_0, FEAT_STATE_1, FEAT_STATE_2 } taking values as their naming.
+ * For better readability, state values are defined with macros, namely:
+ * { FEAT_STATE_DISABLED, FEAT_STATE_ALWAYS, FEAT_STATE_CHECK }, taking values
+ * { 0, 1, 2 }, respectively, as their naming.
  **********************************************************************************/
 void detect_arch_features(void)
 {
+	tainted = false;
+
 	/* v8.0 features */
 	read_feat_sb();
 	read_feat_csv2_2();
@@ -304,7 +312,7 @@
 
 	/* v8.4 features */
 	read_feat_dit();
-	read_feat_amuv1();
+	check_feature(ENABLE_FEAT_AMUv1, read_feat_amu_id_field(), "AMUv1");
 	read_feat_mpam();
 	read_feat_nv2();
 	read_feat_sel2();
@@ -318,12 +326,12 @@
 
 	/* v8.6 features */
 	read_feat_amuv1p1();
-	read_feat_fgt();
+	check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT");
 	read_feat_ecv();
 	read_feat_twed();
 
 	/* v8.7 features */
-	read_feat_hcx();
+	check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX");
 
 	/* v9.0 features */
 	read_feat_brbe();
@@ -331,4 +339,8 @@
 
 	/* v9.2 features */
 	read_feat_rme();
+
+	if (tainted) {
+		panic();
+	}
 }
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 9a2ae73..914c959 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -506,8 +506,10 @@
 
 Arm Total Compute platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Anders Dellien <anders.dellien@arm.com>
-:|G|: `andersdellien-arm`_
+:|M|: Vishnu Banavath <vishnu.banavath@arm.com>
+:|G|: `vishnu-banavath`_
+:|M|: Rupinderjit Singh <rupinderjit.singh@arm.com>
+:|G|: `rupsin01`_
 :|F|: plat/arm/board/tc
 
 HiSilicon HiKey and HiKey960 platform ports
@@ -956,5 +958,6 @@
 .. _marcbonnici: https://github.com/marcbonnici
 .. _jayanthchidanand-arm: https://github.com/jayanthchidanand-arm
 .. _bytefire: https://github.com/bytefire
+.. _rupsin01: https://github.com/rupsin01
 
 .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index ddfc081..f99b7ff 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -69,6 +69,8 @@
 +================================+=============+=========+=========================================================+
 | plat_convert_pk() function     |   Nov'22    |   2.9   | Platform conversion to manage specific PK hash          |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
+| io_dummy driver                |   Nov'22    |   2.9   | No more used by any upstream platform                   |
++--------------------------------+-------------+---------+---------------------------------------------------------+
 
 --------------
 
diff --git a/docs/components/fconf/fconf_properties.rst b/docs/components/fconf/fconf_properties.rst
index 20cc758..3479576 100644
--- a/docs/components/fconf/fconf_properties.rst
+++ b/docs/components/fconf/fconf_properties.rst
@@ -20,7 +20,9 @@
 
 - load-address [mandatory]
     - value type: <u64>
-    - Physical loading base address of the configuration.
+    - Physical loading base address of the configuration. 
+      If secondary-load-address is also provided (see below), then this is the
+      primary load address.
 
 - max-size [mandatory]
     - value type: <u32>
@@ -30,10 +32,11 @@
     - value type: <u32>
     - Image ID of the configuration.
 
-- ns-load-address [optional]
+- secondary-load-address [optional]
     - value type: <u64>
-    - Physical loading base address of the configuration in the non-secure
-      memory.
-      Only needed by those configuration files which require being loaded
-      in secure memory (at load-address) as well as in non-secure memory
-      e.g. HW_CONFIG
+    - A platform uses this physical address to copy the configuration to
+      another location during the boot-flow.
+
+--------------
+
+*Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index 2ea8012..919eea5 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -13,7 +13,7 @@
 The following diagram shows an Arm CCA software architecture with TF-A as the
 EL3 firmware. In the Arm CCA architecture there are two additional security
 states and address spaces: ``Root`` and ``Realm``. TF-A firmware runs in the
-Root world. In the realm world, a Realm Management Monitor firmware (RMM)
+Root world. In the realm world, a Realm Management Monitor firmware (`RMM`_)
 manages the execution of Realm VMs and their interaction with the hypervisor.
 
 .. image:: ../resources/diagrams/arm-cca-software-arch.png
@@ -44,7 +44,7 @@
 In a typical TF-A boot flow, BL2 runs at Secure-EL1. However when RME is
 enabled, TF-A runs in the Root world at EL3. Therefore, the boot flow is
 modified to run BL2 at EL3 when RME is enabled. In addition to this, a
-Realm-world firmware (RMM) is loaded by BL2 in the Realm physical address
+Realm-world firmware (`RMM`_) is loaded by BL2 in the Realm physical address
 space.
 
 The boot flow when RME is enabled looks like the following:
@@ -70,57 +70,85 @@
 RMM Dispatcher (RMMD)
 ************************
 RMMD is a new standard runtime service that handles the switch to the Realm
-world. It initializes the RMM and handles Realm Management Interface (RMI)
-SMC calls from Non-secure and Realm worlds.
+world. It initializes the `RMM`_ and handles Realm Management Interface (RMI)
+SMC calls from Non-secure.
 
-There is a contract between RMM and RMMD that defines the arguments that the
+There is a contract between `RMM`_ and RMMD that defines the arguments that the
 former needs to take in order to initialize and also the possible return values.
-This contract is defined in the RMM Boot Interface, which can be found at
+This contract is defined in the `RMM`_ Boot Interface, which can be found at
 :ref:`rmm_el3_boot_interface`.
 
 There is also a specification of the runtime services provided by TF-A
-to RMM. This can be found at :ref:`runtime_services_and_interface`.
+to `RMM`_. This can be found at :ref:`runtime_services_and_interface`.
 
 Test Realm Payload (TRP)
 *************************
 TRP is a small test payload that runs at R-EL2 and implements a subset of
 the Realm Management Interface (RMI) commands to primarily test EL3 firmware
 and the interface between R-EL2 and EL3. When building TF-A with RME enabled,
-if a path to an RMM image is not provided, TF-A builds the TRP by default
-and uses it as RMM image.
+if the path to an RMM image is not provided, TF-A builds the TRP by default
+and uses it as the R-EL2 payload.
 
 Building and running TF-A with RME
-------------------------------------
+----------------------------------
 
 This section describes how you can build and run TF-A with RME enabled.
-We assume you have all the :ref:`Prerequisites` to build TF-A.
+We assume you have read the :ref:`Prerequisites` to build TF-A.
 
 The following instructions show you how to build and run TF-A with RME
-for two scenarios:
+on FVP for two scenarios:
 
-- Three-world execution: TF-A with TF-A Tests or Linux.
+- Three-world execution:  This is the configuration to use if Secure
+  world functionality is not needed. TF-A is tested with the following
+  software entities in each world as listed below:
 
-  - NS (TF-A Test or Linux),
+  - NS Host (RME capable Linux or TF-A Tests),
   - Root (TF-A)
-  - Realm (RMM or TRP)
+  - R-EL2 (`RMM`_ or TRP)
 
-- Four-world execution: TF-A, Hafnium and TF-A Tests or Linux.
+- Four-world execution: This is the configuration to use if both Secure
+  and Realm world functionality is needed. TF-A is tested with the following
+  software entities in each world as listed below:
 
-  - NS (TF-A Test or Linux),
+  - NS Host (RME capable Linux or TF-A Tests),
   - Root (TF-A)
-  - Realm (RMM or TRP)
-  - SPM (Hafnium)
+  - R-EL2 (`RMM`_ or TRP)
+  - S-EL2 (Hafnium SPM)
 
 To run the tests, you need an FVP model. Please use the :ref:`latest version
-<Arm Fixed Virtual Platforms (FVP)>` of *FVP_Base_RevC-2xAEMvA* model.
+<Arm Fixed Virtual Platforms (FVP)>` of *FVP_Base_RevC-2xAEMvA* model. If NS
+Host is Linux, then the below instructions assume that a suitable RME enabled
+kernel image and associated root filesystem are available.
 
-Three World Testing with TF-A Tests
-*************************************
+Three-world execution
+*********************
 
-**1. Obtain and build TF-A Tests with Realm Payload**
+**1. Clone and build RMM Image**
 
-The full set of instructions to setup build host and build options for
-TF-A-Tests can be found in the `TFTF Getting Started`_.
+Please refer to the `RMM Getting Started`_ on how to setup
+Host Environment and build `RMM`_. The build commands assume that
+an AArch64 toolchain and CMake executable are available in the
+shell PATH variable and CROSS_COMPILE variable has been setup
+appropriately.
+
+To clone `RMM`_ and build using the default build options for FVP:
+
+.. code:: shell
+
+ git clone --recursive https://git.trustedfirmware.org/TF-RMM/tf-rmm.git
+ cd tf-rmm
+ cmake -DRMM_CONFIG=fvp_defcfg -S . -B build
+ cmake --build build
+
+This will generate **rmm.img** in **build/Release** folder.
+
+**2. Clone and build TF-A Tests with Realm Payload**
+
+This step is only needed if NS Host is TF-A Tests. The full set
+of instructions to setup build host and build options for
+TF-A-Tests can be found in the `TFTF Getting Started`_. TF-A Tests
+can test Realm world with either `RMM`_ or TRP in R-EL2. In the TRP case,
+some tests which are not applicable will be skipped.
 
 Use the following instructions to build TF-A with `TF-A Tests`_ as the
 non-secure payload (BL33).
@@ -134,37 +162,23 @@
 This produces a TF-A Tests binary (**tftf.bin**) with Realm payload packaged
 and **sp_layout.json** in the **build/fvp/debug** directory.
 
-**2. Obtain and build RMM Image**
-
-Please refer to the `RMM Getting Started`_ on how to setup
-Host Environment and build RMM.
-
-The below command shows how to build RMM using the default build options for FVP.
-
-.. code:: shell
-
- git clone --recursive https://git.trustedfirmware.org/TF-RMM/tf-rmm.git
- cd tf-rmm
- cmake -DRMM_CONFIG=fvp_defcfg -S . -B build
- cmake --build build
-
-This will generate **rmm.img** in **build** folder.
 
-**3. Build TF-A**
+**3. Build RME Enabled TF-A**
 
 The `TF-A Getting Started`_ has the necessary instructions to setup Host
 machine and build TF-A.
 
 To build for RME, set ``ENABLE_RME`` build option to 1 and provide the path to
-the RMM binary using the ``RMM`` build option.
-Currently, this feature is only supported for the FVP platform.
+the `RMM`_ binary ``rmm.img`` using ``RMM`` build option.
 
 .. note::
 
  ENABLE_RME build option is currently experimental.
 
+.. note::
+
-If the ``RMM`` option is not used, then the Test Realm Payload (TRP) in TF-A
-will be built and used as the RMM.
+ If the ``RMM`` option is not specified, TF-A builds the TRP to load and
+ run at R-EL2.
 
 .. code:: shell
 
@@ -176,16 +190,42 @@
  RMM=<path/to/rmm.img> \
  FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
  DEBUG=1 \
- BL33=<path/to/tftf.bin> \
+ BL33=<path/to/bl33> \
+ all fip
+
+``BL33`` can point to a Non Secure Bootloader like UEFI/U-Boot or
+the TF-A Tests binary(**tftf.bin**) from the previous step.
+
+This produces **bl1.bin** and **fip.bin** binaries in the **build/fvp/debug**
+directory.
+
+TF-A can also directly boot Linux kernel on the FVP. The kernel needs to be
+`preloaded` to a suitable memory location and this needs to be specified via
+``PRELOADED_BL33_BASE`` build option. Also TF-A should implement the Linux
+kernel register conventions for boot and this can be set using the
+``ARM_LINUX_KERNEL_AS_BL33`` option.
+
+.. code-block:: shell
+
+ cd trusted-firmware-a
+ make CROSS_COMPILE=aarch64-none-elf- \
+ PLAT=fvp \
+ ENABLE_RME=1 \
+ RMM=<path/to/rmm.img> \
+ FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
+ DEBUG=1 \
+ ARM_LINUX_KERNEL_AS_BL33=1 \
+ PRELOADED_BL33_BASE=0x84000000 \
  all fip
 
+The above command assumes that the Linux kernel will be placed in FVP
+memory at 0x84000000 via suitable FVP option (see the next step).
+
-This produces **bl1.bin** and **fip.bin** binaries in the **build/fvp/debug** directory.
+.. _fvp_3_world_cmd:
 
-Running the tests for a 3 world FVP setup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**4. Running FVP for 3 world setup**
 
-Use the following command to run the tests on FVP. TF-A Tests should boot
-and run the default tests including Realm world tests.
+Use the following command to run the tests on FVP.
 
 .. code:: shell
 
@@ -239,12 +279,33 @@
  -C cluster1.restriction_on_speculative_execution_aarch32=2     \
  -C pctl.startup=0.0.0.0                                        \
  -C bp.smsc_91c111.enabled=1                                    \
- -C bp.hostbridge.userNetworking=1
+ -C bp.hostbridge.userNetworking=1                              \
+ -C bp.virtioblockdevice.image_path=<path/to/rootfs.ext4>
 
-The bottom of the output from *uart0* should look something like the following.
+The ``bp.virtioblockdevice.image_path`` option presents the rootfs as a
+virtio block device to Linux kernel. It can be ignored if NS Host is
+TF-A-Tests or rootfs is accessed by some other mechanism.
+
+If TF-A was built to expect a preloaded Linux kernel, then use the following
+FVP argument to load the kernel image at the expected address.
 
 .. code-block:: shell
 
+ --data cluster0.cpu0=<path_to_kernel_Image>@0x84000000         \
+
+
+.. tip::
+ Tips to boot and run Linux faster on the FVP :
+  1. Set the FVP option ``cache_state_modelled`` to 0.
+  2. Disable the CPU Idle driver in Linux either by setting the kernel command line
+     parameter "cpuidle.off=1" or by disabling the ``CONFIG_CPU_IDLE`` kernel config.
+
+If the NS Host is TF-A-Tests, then the default test suite in TFTF
+will execute on the FVP and this includes Realm world tests. The
+tail of the output from *uart0* should look something like the following.
+
+.. code-block:: shell
+
  ...
 
  > Test suite 'FF-A Interrupt'
@@ -263,52 +324,19 @@
                                                                 Passed
  ...
 
-Building TF-A with RME enabled Linux Kernel
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If an RME enabled Linux kernel and filesystem is available for testing,
-and a suitable NS boot loader is not available, then this option can be used to
-launch kernel directly after BL31:
-
-.. code-block:: shell
-
- cd trusted-firmware-a
- make CROSS_COMPILE=aarch64-none-elf- \
- PLAT=fvp \
- ENABLE_RME=1 \
- RMM=<path/to/rmm.img> \
- FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
- DEBUG=1 \
- ARM_LINUX_KERNEL_AS_BL33=1 \
- PRELOADED_BL33_BASE=0x84000000 \
- all fip
-
-Boot and run the RME enabled Linux Kernel
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Use the following additional arguments to boot the kernel on FVP.
-
-.. code-block:: shell
-
- --data cluster0.cpu0=<path_to_kernel_Image>@0x84000000         \
- -C bp.virtioblockdevice.image_path=<path_to_rootfs.ext4>
-
-.. tip::
-
- Set the FVP option `cache_state_modelled=0` to run Linux based tests much faster.
-
-Four-world execution with Hafnium and TF-A Tests
-*************************************************
+Four-world execution
+********************
 
 Four-world execution involves software components in each security state: root,
 secure, realm and non-secure. This section describes how to build TF-A
 with four-world support.
 
-We use TF-A as the root firmware, `Hafnium SPM`_ is the reference Secure world component
-and the software components for the other 2 worlds (Realm and Non-Secure)
-are as described in the previous section.
+We use TF-A as the root firmware, `Hafnium SPM`_ is the reference Secure world
+component running at S-EL2. `RMM`_ can be built as described in previous
+section. The examples below assume TF-A-Tests as the NS Host and utilize SPs
+from TF-A-Tests.
 
-**1. Obtain and build Hafnium**
+**1. Obtain and build Hafnium SPM**
 
 .. code:: shell
 
@@ -342,11 +370,12 @@
 The Hafnium binary should be located at
 *out/reference/secure_aem_v8a_fvp_clang/hafnium.bin*
 
-**2. Build TF-A**
+**2. Build RME enabled TF-A with SPM**
 
 Build TF-A with RME as well as SPM enabled.
 
-Use sp_layout.json previously generated in tf-a-test build.
+Use the ``sp_layout.json`` previously generated in TF-A Tests
+build to run SP tests.
 
 .. code:: shell
 
@@ -355,7 +384,6 @@
  ENABLE_RME=1 \
  FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
  SPD=spmd \
- SPMD_SPM_AT_SEL2=1 \
  BRANCH_PROTECTION=1 \
  CTX_INCLUDE_PAUTH_REGS=1 \
  DEBUG=1 \
@@ -365,11 +393,11 @@
  RMM=<path/to/rmm.img> \
  all fip
 
-Running the tests for a 4 world FVP setup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**3. Running the FVP for a 4 world setup**
 
-Use the following arguments in addition to
-`Running the tests for a 3 world FVP setup`_ to run tests for 4 world setup.
+Use the following arguments in addition to the FVP options mentioned in
+:ref:`4. Running FVP for 3 world setup <fvp_3_world_cmd>` to run tests for
+4 world setup.
 
 .. code:: shell
 
@@ -388,4 +416,5 @@
 .. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io/en/latest
 .. _TFTF Getting Started: https://trustedfirmware-a-tests.readthedocs.io/en/latest/getting_started/index.html
 .. _Hafnium SPM: https://www.trustedfirmware.org/projects/hafnium
-.. _RMM Getting Started: https://git.trustedfirmware.org/TF-RMM/tf-rmm.git/tree/docs/getting_started/index.rst
+.. _RMM Getting Started: https://tf-rmm.readthedocs.io/en/latest/getting_started/index.html
+.. _RMM: https://www.trustedfirmware.org/projects/tf-rmm/
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 25c4269..6b57c0e 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -53,7 +53,7 @@
     consistency with the versioning schemes used in other parts of RMM.
 
 This document specifies the 0.1 version of Boot Interface ABI and RMM-EL3
-services specification and the 0.1 version of the Boot Manifest.
+services specification and the 0.2 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
 
@@ -71,7 +71,7 @@
 
 The Boot Interface ABI defines a set of register conventions and
 also a memory based manifest file to pass information from EL3 to RMM. The
-boot manifest and the associated platform data in it can be dynamically created
+Boot Manifest and the associated platform data in it can be dynamically created
 by EL3 and there is no restriction on how the data can be obtained (e.g by DTB,
 hoblist or other).
 
@@ -99,7 +99,7 @@
    x0,Linear index of this PE. This index starts from 0 and must be less than the maximum number of CPUs to be supported at runtime (see x2).
    x1,Version for this Boot Interface as defined in :ref:`rmm_el3_ifc_versioning`.
    x2,Maximum number of CPUs to be supported at runtime. RMM should ensure that it can support this maximum number.
-   x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The boot manifest must be present at the base of this shared buffer during cold boot.
+   x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The Boot Manifest must be present at the base of this shared buffer during cold boot.
 
 During cold boot, EL3 firmware needs to allocate a 4KB page that will be
 passed to RMM in x3. This memory will be used as shared buffer for communication
@@ -162,8 +162,8 @@
    ``E_RMM_BOOT_CPUS_OUT_OF_RAGE``,Number of CPUs reported by EL3 larger than maximum supported by RMM,-3
    ``E_RMM_BOOT_CPU_ID_OUT_OF_RAGE``,Current CPU Id is higher or equal than the number of CPUs supported by RMM,-4
    ``E_RMM_BOOT_INVALID_SHARED_BUFFER``,Invalid pointer to shared memory area,-5
-   ``E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED``,Version reported by the boot manifest not supported by RMM,-6
-   ``E_RMM_BOOT_MANIFEST_DATA_ERROR``,Error parsing core boot manifest,-7
+   ``E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED``,Version reported by the Boot Manifest not supported by RMM,-6
+   ``E_RMM_BOOT_MANIFEST_DATA_ERROR``,Error parsing core Boot Manifest,-7
 
 For any error detected in RMM during cold or warm boot, RMM will return back to
 EL3 using ``RMM_BOOT_COMPLETE`` SMC with an appropriate error code. It is
@@ -177,25 +177,28 @@
 Boot Manifest
 ~~~~~~~~~~~~~
 
-During cold boot, EL3 Firmware passes a memory boot manifest to RMM containing
+During cold boot, EL3 Firmware passes a memory Boot Manifest to RMM containing
 platform information.
 
-This boot manifest is versioned independently of the boot interface, to help
-evolve the boot manifest independent of the rest of Boot Manifest.
-The current version for the boot manifest is ``v0.1`` and the rules explained
+This Boot Manifest is versioned independently of the Boot Interface, to help
+evolve the former independent of the latter.
+The current version for the Boot Manifest is ``v0.2`` and the rules explained
 in :ref:`rmm_el3_ifc_versioning` apply on this version as well.
 
-The boot manifest is divided into two different components:
+The Boot Manifest v0.2 has the following fields:
 
-   - Core Manifest: This is the generic parameters passed to RMM by EL3 common to all platforms.
-   - Platform data: This is defined by the platform owner and contains information specific to that platform.
+   - version : Version of the Manifest (v0.2)
+   - plat_data : Pointer to the platform specific data and not specified by this
+     document. These data are optional and can be NULL.
+   - plat_dram : Structure encoding the NS DRAM information on the platform. This
+     field is also optional and platform can choose to zero out this structure if
+     RMM does not need EL3 to send this information during the boot.
 
-For the current version of the manifest, the core manifest contains a pointer
-to the platform data. EL3 must ensure that the whole boot manifest,
-including the platform data, if available, fits inside the RMM EL3 shared
-buffer.
+For the current version of the Boot Manifest, the core manifest contains a pointer
+to the platform data. EL3 must ensure that the whole Boot Manifest, including
+the platform data, if available, fits inside the RMM EL3 shared buffer.
 
-For the type specification of the RMM Boot Manifest v0.1, refer to
+For the data structure specification of Boot Manifest, refer to
 :ref:`rmm_el3_manifest_struct`
 
 .. _runtime_services_and_interface:
@@ -525,19 +528,59 @@
 RMM-EL3 Boot Manifest structure
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The RMM-EL3 Boot Manifest structure contains platform boot information passed
-from EL3 to RMM. The width of the Boot Manifest is 128 bits
-
-.. image:: ../resources/diagrams/rmm_el3_manifest_struct.png
+The RMM-EL3 Boot Manifest v0.2 structure contains platform boot information passed
+from EL3 to RMM. The size of the Boot Manifest is 40 bytes.
 
 The members of the RMM-EL3 Boot Manifest structure are shown in the following
 table:
 
-.. csv-table::
-   :header: "Name", "Range", "Type", Description
-   :widths: 2 1 1 4
++-----------+--------+----------------+----------------------------------------+
+|   Name    | Offset |     Type       |               Description              |
++===========+========+================+========================================+
+| version   |   0    |   uint32_t     | Boot Manifest version                  |
++-----------+--------+----------------+----------------------------------------+
+| padding   |   4    |   uint32_t     | Reserved, set to 0                     |
++-----------+--------+----------------+----------------------------------------+
+| plat_data |   8    |   uintptr_t    | Pointer to Platform Data section       |
++-----------+--------+----------------+----------------------------------------+
+| plat_dram |   16   | ns_dram_info   | NS DRAM Layout Info structure          |
++-----------+--------+----------------+----------------------------------------+
+
+.. _ns_dram_info_struct:
+
+NS DRAM Layout Info structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+NS DRAM Layout Info structure contains information about platform Non-secure
+DRAM layout. The members of this structure are shown in the table below:
+
++-----------+--------+----------------+----------------------------------------+
+|   Name    | Offset |     Type       |               Description              |
++===========+========+================+========================================+
+| num_banks |   0    |   uint64_t     | Number of NS DRAM banks                |
++-----------+--------+----------------+----------------------------------------+
+| banks     |   8    | ns_dram_bank * | Pointer to 'ns_dram_bank'[] array      |
++-----------+--------+----------------+----------------------------------------+
+| checksum  |   16   |   uint64_t     | Checksum                               |
++-----------+--------+----------------+----------------------------------------+
+
+Checksum is calculated as two's complement sum of 'num_banks', 'banks' pointer
+and DRAM banks data array pointed by it.
+
+.. _ns_dram_bank_struct:
+
+NS DRAM Bank structure
+~~~~~~~~~~~~~~~~~~~~~~
+
+NS DRAM Bank structure contains information about each Non-secure DRAM bank:
+
++-----------+--------+----------------+----------------------------------------+
+|   Name    | Offset |     Type       |               Description              |
++===========+========+================+========================================+
+|   base    |   0    |   uintptr_t    | Base address                           |
++-----------+--------+----------------+----------------------------------------+
+|   size    |   8    |   uint64_t     | Size of bank in bytes                  |
++-----------+--------+----------------+----------------------------------------+
+
+
 
-   ``Version Minor``,15:0,uint16_t,Version Minor part of the Boot Manifest Version.
-   ``Version Major``,30:16,uint16_t,Version Major part of the Boot Manifest Version.
-   ``RES0``,31,bit,Reserved. Set to 0.
-   ``Platform Data``,127:64,Address,Pointer to the Platform Data section of the Boot Manifest.
diff --git a/docs/components/spd/optee-dispatcher.rst b/docs/components/spd/optee-dispatcher.rst
index 63baccc..81476f1 100644
--- a/docs/components/spd/optee-dispatcher.rst
+++ b/docs/components/spd/optee-dispatcher.rst
@@ -6,9 +6,26 @@
 To build and execute OP-TEE follow the instructions at
 `OP-TEE build.git`_
 
+There are two different modes for loading the OP-TEE OS. The default mode will
+load it as the BL32 payload during boot, and is the recommended technique for
+platforms to use. There is also another technique that will load OP-TEE OS after
+boot via an SMC call by enabling the option for OPTEE_ALLOW_SMC_LOAD that was
+specifically added for ChromeOS. Loading OP-TEE via an SMC call may be insecure
+depending upon the platform configuration. If using that option, be sure to
+understand the risks involved with allowing the Trusted OS to be loaded this
+way. ChromeOS uses a boot flow where it verifies the signature of the firmware
+before executing it, and then only if the signature is valid will the 'secrets'
+used by the TEE become accessible. The firmware then verifies the signature of
+the kernel using depthcharge, and the kernel verifies the rootfs using
+dm-verity.  The SMC call to load OP-TEE is then invoked immediately after the
+kernel finishes loading and before any attack vectors can be opened up by
+mounting writable filesystems or opening network/device connections. this
+ensures the platform is 'closed' and running signed code through the point where
+OP-TEE is loaded.
+
 --------------
 
-*Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _OP-TEE OS: https://github.com/OP-TEE/build
 .. _OP-TEE build.git: https://github.com/OP-TEE/build
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index c07a0aa..9db29e6 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -317,6 +317,14 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
    it is still open.
 
+-  ``ERRATA_A78_2772019``: This applies errata 2772019 workaround to Cortex-A78
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
+   it is still open.
+
+-  ``ERRATA_A78_2779479``: This applies erratum 2779479 workaround to Cortex-A78
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 and
+   it is still open.
+
 For Cortex-A78 AE, the following errata build flags are defined :
 
 - ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to
@@ -353,6 +361,10 @@
   Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
   erratum is still open.
 
+- ``ERRATA_A78C_2772121`` : This applies errata 2772121 workaround to
+  Cortex-A78C CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2.
+  This erratum is still open.
+
 For Cortex-X1 CPU, the following errata build flags are defined:
 
 - ``ERRATA_X1_1821534`` : This applies errata 1821534 workaround to Cortex-X1
@@ -460,6 +472,14 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0 and r1p1 of the CPU.
    It is still open.
 
+-  ``ERRATA_V1_2743093``: This applies errata 2743093 workaround to Neoverse-V1
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 of the
+   CPU. It is still open.
+
+-  ``ERRATA_V1_2779461``: This applies erratum 2779461 workaround to Neoverse-V1
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, r1p2 of the
+   CPU. It is still open.
+
 For Cortex-A710, the following errata build flags are defined :
 
 -  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -503,8 +523,8 @@
    of the CPU and is fixed in r2p1.
 
 -  ``ERRATA_A710_2282622``: This applies errata 2282622 workaround to
-   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
-   of the CPU and is fixed in r2p1.
+   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
+   r2p1 of the CPU and is still open.
 
 - ``ERRATA_A710_2291219``: This applies errata 2291219 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
@@ -566,6 +586,10 @@
    CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
    r0p1.
 
+-  ``ERRATA_N2_2743089``: This applies errata 2743089 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is fixed
+   in r0p3.
+
 For Cortex-X2, the following errata build flags are defined :
 
 -  ``ERRATA_X2_2002765``: This applies errata 2002765 workaround to Cortex-X2
@@ -579,29 +603,33 @@
 -  ``ERRATA_X2_2083908``: This applies errata 2083908 workaround to Cortex-X2
    CPU. This needs to be enabled for revision r2p0 of the CPU, it is still open.
 
--  ``ERRATA_X2_2017096``: This applies errata 2017096 workaround to
-   Cortex-X2 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
-   r2p0 of the CPU, it is fixed in r2p1.
+-  ``ERRATA_X2_2017096``: This applies errata 2017096 workaround to Cortex-X2
+   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r2p0 of the
+   CPU, it is fixed in r2p1.
 
--  ``ERRATA_X2_2081180``: This applies errata 2081180 workaround to
-   Cortex-X2 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
-   r2p0 of the CPU, it is fixed in r2p1.
+-  ``ERRATA_X2_2081180``: This applies errata 2081180 workaround to Cortex-X2
+   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r2p0 of the
+   CPU, it is fixed in r2p1.
 
--  ``ERRATA_X2_2216384``: This applies errata 2216384 workaround to
-   Cortex-X2 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
-   r2p0 of the CPU, it is fixed in r2p1.
+-  ``ERRATA_X2_2216384``: This applies errata 2216384 workaround to Cortex-X2
+   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r2p0 of the
+   CPU, it is fixed in r2p1.
 
--  ``ERRATA_X2_2147715``: This applies errata 2147715 workaround to
-   Cortex-X2 CPU. This needs to be enabled only for revision r2p0 of the CPU,
-   it is fixed in r2p1.
+-  ``ERRATA_X2_2147715``: This applies errata 2147715 workaround to Cortex-X2
+   CPU. This needs to be enabled only for revision r2p0 of the CPU, it is fixed
+   in r2p1.
 
--  ``ERRATA_X2_2371105``: This applies errata 2371105 workaround to
-   Cortex-X2 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
-   of the CPU and is fixed in r2p1.
+-  ``ERRATA_X2_2282622``: This applies errata 2282622 workaround to Cortex-X2
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
+   CPU and is still open.
+
+-  ``ERRATA_X2_2371105``: This applies errata 2371105 workaround to Cortex-X2
+   CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0 of the CPU
+   and is fixed in r2p1.
 
--  ``ERRATA_X2_2768515``: This applies errata 2768515 workaround to
-   Cortex-X2 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0
-   and r2p1 of the CPU and is still open.
+-  ``ERRATA_X2_2768515``: This applies errata 2768515 workaround to Cortex-X2
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
+   CPU and is still open.
 
 For Cortex-X3, the following errata build flags are defined :
 
@@ -645,7 +673,7 @@
    Cortex-A510 CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2,
    r0p3 and r1p0, it is fixed in r1p1.
 
-- ``ERRATA_A510_2347730``: This applies errata 2347730 workaround to
+-  ``ERRATA_A510_2347730``: This applies errata 2347730 workaround to
    Cortex-A510 CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2,
    r0p3, r1p0 and r1p1. It is fixed in r1p2.
 
@@ -657,6 +685,10 @@
    Cortex-A510 CPU. This needs to applied for revisions r0p0, r0p1, r0p2,
    r0p3, r1p0, r1p1. It is fixed in r1p2.
 
+-  ``ERRATA_A510_2684597``: This applies erratum 2684597 workaround to
+   Cortex-A510 CPU. This needs to be applied to revision r0p0, r0p1, r0p2,
+   r0p3, r1p0, r1p1 and r1p2. It is fixed in r1p3.
+
 DSU Errata Workarounds
 ----------------------
 
@@ -742,7 +774,7 @@
 
 --------------
 
-*Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
 .. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index 3e20c07..3d82e69 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -9,6 +9,7 @@
    context_mgmt_rework
    measured_boot_poc
    drtm_poc
+   rss
 
 --------------
 
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
index 3ae539b..2e25057 100644
--- a/docs/design_documents/measured_boot_poc.rst
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -6,7 +6,7 @@
 security state can be attested later.
 
 The current implementation of the driver included in Trusted Firmware-A
-(TF-A) stores the measurements into a `TGC event log`_ in secure
+(TF-A) stores the measurements into a `TCG event log`_ in secure
 memory. No other means of recording measurements (such as a discrete TPM) is
 supported right now.
 
@@ -24,7 +24,7 @@
    platforms might have different needs and configurations (e.g. different
    SHA algorithms) and they might also use different types of TPM services
    (or even a different type of service to provide the attestation)
-   and therefore the instuctions given here might not apply in such scenarios.
+   and therefore the instructions given here might not apply in such scenarios.
 
 Components
 ~~~~~~~~~~
@@ -497,11 +497,11 @@
 
 --------------
 
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 .. _OP-TEE Toolkit: https://github.com/OP-TEE/build
 .. _ms-tpm-20-ref: https://github.com/microsoft/ms-tpm-20-ref
 .. _Get and build the solution: https://optee.readthedocs.io/en/latest/building/gits/build.html#get-and-build-the-solution
 .. _Armv8-A Foundation Platform (For Linux Hosts Only): https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models
 .. _tpm2-tools: https://github.com/tpm2-software/tpm2-tools
-.. _TGC event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/
+.. _TCG event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/
diff --git a/docs/design_documents/rss.rst b/docs/design_documents/rss.rst
new file mode 100644
index 0000000..2be8067
--- /dev/null
+++ b/docs/design_documents/rss.rst
@@ -0,0 +1,611 @@
+Runtime Security Subsystem (RSS)
+================================
+
+This document focuses on the relationship between the Runtime Security Subsystem
+(RSS) and the application processor (AP). According to the ARM reference design
+the RSS is an independent core next to the AP and the SCP on the same die. It
+provides fundamental security guarantees and runtime services for the rest of
+the system (e.g.: trusted boot, measured boot, platform attestation,
+key management, and key derivation).
+
+At power up RSS boots first from its private ROM code. It validates and loads
+its own images and the initial images of SCP and AP. When AP and SCP are
+released from reset and their initial code is loaded then they continue their
+own boot process, which is the same as on non-RSS systems. Please refer to the
+``RSS documentation`` [1]_ for more details about the RSS boot flow.
+
+The last stage of the RSS firmware is a persistent, runtime component. Much
+like AP_BL31, this is a passive entity which has no periodical task to do and
+just waits for external requests from other subsystems. RSS and other
+subsystems can communicate with each other over message exchange. RSS waits
+in idle for the incoming request, handles them, and sends a response then goes
+back to idle.
+
+RSS communication layer
+-----------------------
+
+The communication between RSS and other subsystems are primarily relying on the
+Message Handling Unit (MHU) module. The number of MHU interfaces between RSS
+and other cores is IMPDEF. Besides MHU other modules also could take part in
+the communication. RSS is capable of mapping the AP memory to its address space.
+Thereby either RSS core itself or a DMA engine if it is present, can move the
+data between memory belonging to RSS or AP. In this way, a bigger amount of data
+can be transferred in a short time.
+
+The MHU comes in pairs. There is a sender and receiver side. They are connected
+to each other. An MHU interface consists of two pairs of MHUs, one sender and
+one receiver on both sides. Bidirectional communication is possible over an
+interface. One pair provides message sending from AP to RSS and the other pair
+from RSS to AP. The sender and receiver are connected via channels. There is an
+IMPDEF number of channels (e.g: 4-16) between a sender and a receiver module.
+
+The RSS communication layer provides two ways for message exchange:
+
+- ``Embedded messaging``: The full message, including header and payload, are
+  exchanged over the MHU channels. A channel is capable of delivering a single
+  word. The sender writes the data to the channel register on its side and the
+  receiver can read the data from the channel on the other side. One dedicated
+  channel is used for signalling. It does not deliver any payload it is just
+  meant for signalling that the sender loaded the data to the channel registers
+  so the receiver can read them. The receiver uses the same channel to signal
+  that data was read. Signalling happens via IRQ. If the message is longer than
+  the data fit to the channel registers then the message is sent over in
+  multiple rounds. Both, sender and receiver allocate a local buffer for the
+  messages. Data is copied from/to these buffers to/from the channel registers.
+- ``Pointer-access messaging``: The message header and the payload are
+  separated and they are conveyed in different ways. The header is sent
+  over the channels, similar to the embedded messaging but the payload is
+  copied over by RSS core (or by DMA) between the sender and the receiver. This
+  could be useful in the case of long messages because transaction time is less
+  compared to the embedded messaging mode. Small payloads are copied by the RSS
+  core because setting up DMA would require more CPU cycles. The payload is
+  either copied into an internal buffer or directly read-written by RSS. Actual
+  behavior depends on RSS setup, whether the partition supports memory-mapped
+  ``iovec``. Therefore, the sender must handle both cases and prevent access to
+  the memory, where payload data lives, while the RSS handles the request.
+
+The RSS communication layer supports both ways of messaging in parallel. It is
+decided at runtime based on the message size which way to transfer the message.
+
+.. code-block:: bash
+
+    +----------------------------------------------+       +-------------------+
+    |                                              |       |                   |
+    |                      AP                      |       |                   |
+    |                                              |  +--->|       SRAM        |
+    +----------------------------------------------|  |    |                   |
+    |              BL1 / BL2 / BL31                |  |    |                   |
+    +----------------------------------------------+  |    +-------------------+
+             |                           ^            |        ^           ^
+             |  send                 IRQ | receive    |direct  |           |
+             V                           |            |access  |           |
+    +--------------------+    +--------------------+  |        |           |
+    |      MHU sender    |    |    MHU receiver    |  |        | Copy data |
+    +--------------------+    +--------------------+  |        |           |
+       | |           | |          | |           | |   |        |           |
+       | | channels  | |          | | channels  | |   |        |           |
+       | | e.g: 4-16 | |          | | e.g: 4-16 | |   |        V           |
+    +--------------------+    +--------------------+  |    +-------+       |
+    |     MHU receiver   |    |     MHU sender     |  | +->|  DMA  |       |
+    +--------------------+    +--------------------+  | |  +-------+       |
+             |                           ^            | |      ^           |
+        IRQ  |  receive                  | send       | |      | Copy data |
+             V                           |            | |      V           V
+    +----------------------------------------------+  | |  +-------------------+
+    |                                              |--+-+  |                   |
+    |                  RSS                         |       |      SRAM         |
+    |                                              |       |                   |
+    +----------------------------------------------+       +-------------------+
+
+.. Note::
+
+    The RSS communication layer is not prepared for concurrent execution. The
+    current use case only requires message exchange during the boot phase. In
+    the boot phase, only a single core is running and the rest of the cores are
+    in reset.
+
+Message structure
+^^^^^^^^^^^^^^^^^
+A description of the message format can be found in the ``RSS communication
+design`` [2]_ document.
+
+Source files
+^^^^^^^^^^^^
+- RSS comms:  ``drivers/arm/rss``
+- MHU driver: ``drivers/arm/mhu``
+
+
+API for communication over MHU
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The API is defined in these header files:
+
+- ``include/drivers/arm/rss_comms.h``
+- ``include/drivers/arm/mhu.h``
+
+RSS provided runtime services
+-----------------------------
+
+RSS provides the following runtime services:
+
+- ``Measured boot``: Securely store the firmware measurements which were
+  computed during the boot process and the associated metadata (image
+  description, measurement algorithm, etc.). More info on measured boot service
+  in RSS can be found in the ``measured_boot_integration_guide`` [3]_ .
+- ``Delegated attestation``: Query the platform attestation token and derive a
+  delegated attestation key. More info on the delegated attestation service
+  in RSS can be found in the ``delegated_attestation_integration_guide`` [4]_ .
+- ``OTP assets management``: RSS provides access for AP to assets in OTP.
+  These are keys for image signature verification and non-volatile counters
+  for anti-rollback protection. Only RSS has direct access to the OTP. Public
+  keys used by AP during the trusted boot process can be requested from RSS.
+  Furthermore, AP can request RSS to increase a non-volatile counter. Please
+  refer to the ``RSS key management`` [5]_ document for more details.
+
+Runtime service API
+^^^^^^^^^^^^^^^^^^^
+The RSS provided runtime services implement a PSA aligned API. The parameter
+encoding follows the PSA client protocol described in the
+``Firmware Framework for M`` [6]_ document in chapter 4.4. The implementation is
+restricted to the static handle use case therefore only the ``psa_call`` API is
+implemented.
+
+
+Software and API layers
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+    +----------------+         +---------------------+
+    |   BL1 / BL2    |         |       BL31          |
+    +----------------+         +---------------------+
+      |                         |
+      | extend_measurement()    | get_delegated_key()
+      |                         | get_platform_token()
+      V                         V
+    +----------------+         +---------------------+
+    |  PSA protocol  |         |    PSA protocol     |
+    +----------------+         +---------------------+
+         |                               |
+         | psa_call()                    | psa_call()
+         |                               |
+         V                               V
+    +------------------------------------------------+
+    |         RSS communication protocol             |
+    +------------------------------------------------+
+         |                     ^
+         | mhu_send_data()     | mhu_receive_data()
+         |                     |
+         V                     |
+    +------------------------------------------------+
+    |                 MHU driver                     |
+    +------------------------------------------------+
+               |                      ^
+               | Register access      | IRQ
+               V                      |
+    +------------------------------------------------+
+    |             MHU HW on AP side                  |
+    +------------------------------------------------+
+                         ^
+                         | Physical wires
+                         |
+                         V
+    +------------------------------------------------+
+    |             MHU HW on RSS side                 |
+    +------------------------------------------------+
+             |                        ^
+             | IRQ                    | Register access
+             V                        |
+    +------------------------------------------------+
+    |                 MHU driver                     |
+    +------------------------------------------------+
+             |                        |
+             V                        V
+    +---------------+       +------------------------+
+    | Measured boot |       | Delegated attestation  |
+    | service       |       | service                |
+    +---------------+       +------------------------+
+
+
+RSS based Measured Boot
+-----------------------
+
+Measured Boot is the process of cryptographically measuring (computing the hash
+value of a binary) the code and critical data used at boot time. The
+measurement must be stored in a tamper-resistant way, so the security state
+of the device can be attested later to an external party. RSS provides a runtime
+service which is meant to store measurements and associated metadata alongside.
+
+Data is stored in internal SRAM which is only accessible by the secure runtime
+firmware of RSS. Data is stored in so-called measurement slots. A platform has
+IMPDEF number of measurement slots. The measurement storage follows extend
+semantics. This means that measurements are not stored directly (as it was
+taken) instead they contribute to the current value of the measurement slot.
+The extension implements this logic, where ``||`` stands for concatenation:
+
+.. code-block:: bash
+
+    new_value_of_measurement_slot = Hash(old_value_of_measurement_slot || measurement)
+
+Supported hash algorithms: sha-256, sha-512
+
+Measured Boot API
+^^^^^^^^^^^^^^^^^
+
+Defined here:
+
+- ``include/lib/psa/measured_boot.h``
+
+.. code-block:: c
+
+    psa_status_t
+    rss_measured_boot_extend_measurement(uint8_t        index,
+                                         const uint8_t *signer_id,
+                                         size_t         signer_id_size,
+                                         const uint8_t *version,
+                                         size_t         version_size,
+                                         uint32_t       measurement_algo,
+                                         const uint8_t *sw_type,
+                                         size_t         sw_type_size,
+                                         const uint8_t *measurement_value,
+                                         size_t         measurement_value_size,
+                                         bool           lock_measurement);
+
+Measured Boot Metadata
+^^^^^^^^^^^^^^^^^^^^^^
+
+The following metadata can be stored alongside the measurement:
+
+- ``Signer-id``: Mandatory. The hash of the firmware image signing public key.
+- ``Measurement algorithm``: Optional. The hash algorithm which was used to
+  compute the measurement (e.g.: sha-256, etc.).
+- ``Version info``: Optional. The firmware version info (e.g.: 2.7).
+- ``SW type``: Optional. Short text description (e.g.: BL1, BL2, BL31, etc.)
+
+.. Note::
+    Signer-id and version info is not implemented in TF-A yet.
+
+The caller must specify in which measurement slot to extend a certain
+measurement and metadata. A measurement slot can be extended by multiple
+measurements. The default value is IMPDEF. All measurement slot is cleared at
+reset, there is no other way to clear them. In the reference implementation,
+the measurement slots are initialized to 0. At the first call to extend the
+measurement in a slot, the extend operation uses the default value of the
+measurement slot. All upcoming extend operation on the same slot contributes
+to the previous value of that measurement slot.
+
+The following rules are kept when a slot is extended multiple times:
+
+- ``Signer-id`` must be the same as the previous call(s), otherwise a
+  PSA_ERROR_NOT_PERMITTED error code is returned.
+
+- ``Measurement algorithm``: must be the same as the previous call(s),
+  otherwise, a PSA_ERROR_NOT_PERMITTED error code is returned.
+
+In case of error no further action is taken (slot is not locked). If there is
+a valid data in a sub-sequent call then measurement slot will be extended. The
+rest of the metadata is handled as follows when a measurement slot is extended
+multiple times:
+
+- ``SW type``: Cleared.
+- ``Version info``: Cleared.
+
+.. Note::
+
+    Extending multiple measurements in the same slot leads to some metadata
+    information loss. Since RSS is not constrained on special HW resources to
+    store the measurements and metadata, therefore it is worth considering to
+    store all of them one by one in distinct slots. However, they are one-by-one
+    included in the platform attestation token. So, the number of distinct
+    firmware image measurements has an impact on the size of the attestation
+    token.
+
+The allocation of the measurement slot among RSS, Root and Realm worlds is
+platform dependent. The platform must provide an allocation of the measurement
+slot at build time. An example can be found in
+``tf-a/plat/arm/board/tc/tc_bl1_measured_boot.c``
+Furthermore, the memory, which holds the metadata is also statically allocated
+in RSS memory. Some of the fields have a static value (measurement algorithm),
+and some of the values have a dynamic value (measurement value) which is updated
+by the bootloaders when the firmware image is loaded and measured. The metadata
+structure is defined in
+``include/drivers/measured_boot/rss/rss_measured_boot.h``.
+
+.. code-block:: c
+
+    struct rss_mboot_metadata {
+            unsigned int id;
+            uint8_t slot;
+            uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+            size_t  signer_id_size;
+            uint8_t version[VERSION_MAX_SIZE];
+            size_t  version_size;
+            uint8_t sw_type[SW_TYPE_MAX_SIZE];
+            size_t  sw_type_size;
+            bool    lock_measurement;
+    };
+
+Build time config options
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``MEASURED_BOOT``: Enable measured boot. It depends on the platform
+  implementation whether RSS or TPM (or both) backend based measured boot is
+  enabled.
+- ``MBOOT_RSS_HASH_ALG``: Determine the hash algorithm to measure the images.
+  The default value is sha-256.
+
+Measured boot flow
+^^^^^^^^^^^^^^^^^^
+
+.. figure:: ../resources/diagrams/rss_measured_boot_flow.svg
+  :align: center
+
+Sample console log
+^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 6
+    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : FW_CONFIG
+    INFO:     - sw_type_size: 10
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : aa ea d3 a7 a8 e2 ab 7d 13 a6 cb 34 99 10 b9 a1
+    INFO:                   : 1b 9f a0 52 c5 a8 b1 d7 76 f2 c1 c1 ef ca 1a df
+    INFO:     - locking     : true
+    INFO:    FCONF: Config file with image ID:31 loaded at address = 0x4001010
+    INFO:    Loading image id=24 at address 0x4001300
+    INFO:    Image id=24 loaded: 0x4001300 - 0x400153a
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 7
+    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : TB_FW_CONFIG
+    INFO:     - sw_type_size: 13
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : 05 b9 dc 98 62 26 a7 1c 2d e5 bb af f0 90 52 28
+    INFO:                   : f2 24 15 8a 3a 56 60 95 d6 51 3a 7a 1a 50 9b b7
+    INFO:     - locking     : true
+    INFO:    FCONF: Config file with image ID:24 loaded at address = 0x4001300
+    INFO:    BL1: Loading BL2
+    INFO:    Loading image id=1 at address 0x404d000
+    INFO:    Image id=1 loaded: 0x404d000 - 0x406412a
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 8
+    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : BL_2
+    INFO:     - sw_type_size: 5
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : 53 a1 51 75 25 90 fb a1 d9 b8 c8 34 32 3a 01 16
+    INFO:                   : c9 9e 74 91 7d 28 02 56 3f 5c 40 94 37 58 50 68
+    INFO:     - locking     : true
+
+Delegated Attestation
+---------------------
+
+Delegated Attestation Service was mainly developed to support the attestation
+flow on the ``ARM Confidential Compute Architecture`` (ARM CCA) [7]_.
+The detailed description of the delegated attestation service can be found in
+the ``Delegated Attestation Service Integration Guide`` [4]_ document.
+
+In the CCA use case, the Realm Management Monitor (RMM) relies on the delegated
+attestation service of the RSS to get a realm attestation key and the CCA
+platform token. BL31 does not use the service for its own purpose, only calls
+it on behalf of RMM. The access to MHU interface and thereby to RSS is
+restricted to BL31 only. Therefore, RMM does not have direct access, all calls
+need to go through BL31. The RMM dispatcher module of the BL31 is responsible
+for delivering the calls between the two parties.
+
+.. Note::
+     Currently the connection between the RMM dispatcher and the PSA/RSS layer
+     is not yet implemented. RMM dispatcher just returns hard coded data.
+
+Delegated Attestation API
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Defined here:
+
+- ``include/lib/psa/delegated_attestation.h``
+
+.. code-block:: c
+
+    psa_status_t
+    rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+                                           uint32_t  key_bits,
+                                           uint8_t  *key_buf,
+                                           size_t    key_buf_size,
+                                           size_t   *key_size,
+                                           uint32_t  hash_algo);
+
+    psa_status_t
+    rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+                                   size_t         dak_pub_hash_size,
+                                   uint8_t       *token_buf,
+                                   size_t         token_buf_size,
+                                   size_t        *token_size);
+
+Attestation flow
+^^^^^^^^^^^^^^^^
+
+.. figure:: ../resources/diagrams/rss_attestation_flow.svg
+  :align: center
+
+Sample attestation token
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Binary format:
+
+.. code-block:: bash
+
+    INFO:    DELEGATED ATTEST TEST START
+    INFO:    Get delegated attestation key start
+    INFO:    Get delegated attest key succeeds, len: 48
+    INFO:    Delegated attest key:
+    INFO:            0d 2a 66 61 d4 89 17 e1 70 c6 73 56 df f4 11 fd
+    INFO:            7d 1f 3b 8a a3 30 3d 70 4c d9 06 c3 c7 ef 29 43
+    INFO:            0f ee b5 e7 56 e0 71 74 1b c4 39 39 fd 85 f6 7b
+    INFO:    Get platform token start
+    INFO:    Get platform token succeeds, len: 1086
+    INFO:    Platform attestation token:
+    INFO:            d2 84 44 a1 01 38 22 a0 59 03 d1 a9 0a 58 20 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19
+    INFO:            01 00 58 21 01 cb 8c 79 f7 a0 0a 6c ce 12 66 f8
+    INFO:            64 45 48 42 0e c5 10 bf 84 ee 22 18 b9 8f 11 04
+    INFO:            c7 22 31 9d fb 19 09 5c 58 20 aa aa aa aa aa aa
+    INFO:            aa aa bb bb bb bb bb bb bb bb cc cc cc cc cc cc
+    INFO:            cc cc dd dd dd dd dd dd dd dd 19 09 5b 19 30 00
+    INFO:            19 09 5f 89 a4 05 58 20 bf e6 d8 6f 88 26 f4 ff
+    INFO:            97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d a2 6a
+    INFO:            df 34 c3 29 48 9a dc 38 04 67 31 2e 36 2e 30 2b
+    INFO:            30 01 64 52 54 5f 30 02 58 20 90 27 f2 46 ab 31
+    INFO:            85 36 46 c4 d7 c6 60 ed 31 0d 3c f0 14 de f0 6c
+    INFO:            24 0b de b6 7a 84 fc 3f 5b b7 a4 05 58 20 b3 60
+    INFO:            ca f5 c9 8c 6b 94 2a 48 82 fa 9d 48 23 ef b1 66
+    INFO:            a9 ef 6a 6e 4a a3 7c 19 19 ed 1f cc c0 49 04 67
+    INFO:            30 2e 30 2e 30 2b 30 01 64 52 54 5f 31 02 58 20
+    INFO:            52 13 15 d4 9d b2 cf 54 e4 99 37 44 40 68 f0 70
+    INFO:            7d 73 64 ae f7 08 14 b0 f7 82 ad c6 17 db a3 91
+    INFO:            a4 05 58 20 bf e6 d8 6f 88 26 f4 ff 97 fb 96 c4
+    INFO:            e6 fb c4 99 3e 46 19 fc 56 5d a2 6a df 34 c3 29
+    INFO:            48 9a dc 38 04 67 31 2e 35 2e 30 2b 30 01 64 52
+    INFO:            54 5f 32 02 58 20 8e 5d 64 7e 6f 6c c6 6f d4 4f
+    INFO:            54 b6 06 e5 47 9a cc 1b f3 7f ce 87 38 49 c5 92
+    INFO:            d8 2f 85 2e 85 42 a4 05 58 20 bf e6 d8 6f 88 26
+    INFO:            f4 ff 97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d
+    INFO:            a2 6a df 34 c3 29 48 9a dc 38 04 67 31 2e 35 2e
+    INFO:            30 2b 30 01 60 02 58 20 b8 01 65 a7 78 8b c6 59
+    INFO:            42 8d 33 10 85 d1 49 0a dc 9e c3 ee df 85 1b d2
+    INFO:            f0 73 73 6a 0c 07 11 b8 a4 05 58 20 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 04 60 01 6a
+    INFO:            46 57 5f 43 4f 4e 46 49 47 00 02 58 20 21 9e a0
+    INFO:            13 82 e6 d7 97 5a 11 13 a3 5f 45 39 68 b1 d9 a3
+    INFO:            ea 6a ab 84 23 3b 8c 06 16 98 20 ba b9 a4 05 58
+    INFO:            20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 04 60 01 6d 54 42 5f 46 57 5f 43 4f 4e 46 49
+    INFO:            47 00 02 58 20 41 39 f6 c2 10 84 53 c5 17 ae 9a
+    INFO:            e5 be c1 20 7b cc 24 24 f3 9d 20 a8 fb c7 b3 10
+    INFO:            e3 ee af 1b 05 a4 05 58 20 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 04 60 01 65 42 4c 5f
+    INFO:            32 00 02 58 20 5c 96 20 e1 e3 3b 0f 2c eb c1 8e
+    INFO:            1a 02 a6 65 86 dd 34 97 a7 4c 98 13 bf 74 14 45
+    INFO:            2d 30 28 05 c3 a4 05 58 20 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 04 60 01 6e 53 45 43
+    INFO:            55 52 45 5f 52 54 5f 45 4c 33 00 02 58 20 f6 fb
+    INFO:            62 99 a5 0c df db 02 0b 72 5b 1c 0b 63 6e 94 ee
+    INFO:            66 50 56 3a 29 9c cb 38 f0 ec 59 99 d4 2e a4 05
+    INFO:            58 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 04 60 01 6a 48 57 5f 43 4f 4e 46 49 47 00
+    INFO:            02 58 20 98 5d 87 21 84 06 33 9d c3 1f 91 f5 68
+    INFO:            8d a0 5a f0 d7 7e 20 51 ce 3b f2 a5 c3 05 2e 3c
+    INFO:            8b 52 31 19 01 09 78 1c 68 74 74 70 3a 2f 2f 61
+    INFO:            72 6d 2e 63 6f 6d 2f 43 43 41 2d 53 53 44 2f 31
+    INFO:            2e 30 2e 30 19 09 62 71 6e 6f 74 2d 68 61 73 68
+    INFO:            2d 65 78 74 65 6e 64 65 64 19 09 61 44 ef be ad
+    INFO:            de 19 09 60 77 77 77 77 2e 74 72 75 73 74 65 64
+    INFO:            66 69 72 6d 77 61 72 65 2e 6f 72 67 58 60 29 4e
+    INFO:            4a d3 98 1e 3b 70 9f b6 66 ed 47 33 0e 99 f0 b1
+    INFO:            c3 f2 bc b2 1d b0 ae 90 0c c4 82 ff a2 6f ae 45
+    INFO:            f6 87 09 4a 09 21 77 ec 36 1c 53 b8 a7 9b 8e f7
+    INFO:            27 eb 7a 09 da 6f fb bf cb fd b3 e5 e9 36 91 b1
+    INFO:            92 13 c1 30 16 b4 5c 49 5e c0 c1 b9 01 5c 88 2c
+    INFO:            f8 2f 3e a4 a2 6d e4 9d 31 6a 06 f7 a7 73
+    INFO:    DELEGATED ATTEST TEST END
+
+JSON format:
+
+.. code-block:: JSON
+
+    {
+        "CCA_PLATFORM_CHALLENGE": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+        "CCA_PLATFORM_INSTANCE_ID": "b'01CB8C79F7A00A6CCE1266F8644548420EC510BF84EE2218B98F1104C722319DFB'",
+        "CCA_PLATFORM_IMPLEMENTATION_ID": "b'AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD'",
+        "CCA_PLATFORM_LIFECYCLE": "secured_3000",
+        "CCA_PLATFORM_SW_COMPONENTS": [
+            {
+                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
+                "SW_COMPONENT_VERSION": "1.6.0+0",
+                "SW_COMPONENT_TYPE": "RT_0",
+                "MEASUREMENT_VALUE": "b'9027F246AB31853646C4D7C660ED310D3CF014DEF06C240BDEB67A84FC3F5BB7'"
+            },
+            {
+                "SIGNER_ID": "b'B360CAF5C98C6B942A4882FA9D4823EFB166A9EF6A6E4AA37C1919ED1FCCC049'",
+                "SW_COMPONENT_VERSION": "0.0.0+0",
+                "SW_COMPONENT_TYPE": "RT_1",
+                "MEASUREMENT_VALUE": "b'521315D49DB2CF54E49937444068F0707D7364AEF70814B0F782ADC617DBA391'"
+            },
+            {
+                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
+                "SW_COMPONENT_VERSION": "1.5.0+0",
+                "SW_COMPONENT_TYPE": "RT_2",
+                "MEASUREMENT_VALUE": "b'8E5D647E6F6CC66FD44F54B606E5479ACC1BF37FCE873849C592D82F852E8542'"
+            },
+            {
+                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
+                "SW_COMPONENT_VERSION": "1.5.0+0",
+                "SW_COMPONENT_TYPE": "",
+                "MEASUREMENT_VALUE": "b'B80165A7788BC659428D331085D1490ADC9EC3EEDF851BD2F073736A0C0711B8'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "FW_CONFIG\u0000",
+                "MEASUREMENT_VALUE": "b'219EA01382E6D7975A1113A35F453968B1D9A3EA6AAB84233B8C06169820BAB9'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "TB_FW_CONFIG\u0000",
+                "MEASUREMENT_VALUE": "b'4139F6C2108453C517AE9AE5BEC1207BCC2424F39D20A8FBC7B310E3EEAF1B05'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "BL_2\u0000",
+                "MEASUREMENT_VALUE": "b'5C9620E1E33B0F2CEBC18E1A02A66586DD3497A74C9813BF7414452D302805C3'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "SECURE_RT_EL3\u0000",
+                "MEASUREMENT_VALUE": "b'F6FB6299A50CDFDB020B725B1C0B636E94EE6650563A299CCB38F0EC5999D42E'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "HW_CONFIG\u0000",
+                "MEASUREMENT_VALUE": "b'985D87218406339DC31F91F5688DA05AF0D77E2051CE3BF2A5C3052E3C8B5231'"
+            }
+        ],
+        "CCA_ATTESTATION_PROFILE": "http://arm.com/CCA-SSD/1.0.0",
+        "CCA_PLATFORM_HASH_ALGO_ID": "not-hash-extended",
+        "CCA_PLATFORM_CONFIG": "b'EFBEADDE'",
+        "CCA_PLATFORM_VERIFICATION_SERVICE": "www.trustedfirmware.org"
+    }
+
+References
+----------
+
+.. [1] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/readme.html
+.. [2] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_comms.html
+.. [3] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/measured_boot/measured_boot_integration_guide.rst
+.. [4] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/delegated_attestation/delegated_attest_integration_guide.rst
+.. [5] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_key_management.html
+.. [6] https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4&hash=3BFD6F3E687F324672F18E5BE9F08EDC48087C93
+.. [7] https://developer.arm.com/documentation/DEN0096/A_a/?lang=en
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index e54ff41..d5ded5e 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -213,6 +213,12 @@
 
 -  ``E``: Boolean option to make warnings into errors. Default is 1.
 
+   When specifying higher warnings levels (``W=1`` and higher), this option
+   defaults to 0. This is done to encourage contributors to use them, as they
+   are expected to produce warnings that would otherwise fail the build. New
+   contributions are still expected to build with ``W=0`` and ``E=1`` (the
+   default).
+
 -  ``EL3_PAYLOAD_BASE``: This option enables booting an EL3 payload instead of
    the normal boot flow. It must specify the entry point address of the EL3
    payload. Please refer to the "Booting an EL3 payload" section for more
@@ -954,6 +960,43 @@
    regrouped and put in the root Makefile. This flag can take the values 0 to 3,
    each level enabling more warning options. Default is 0.
 
+   This option is closely related to the ``E`` option, which enables
+   ``-Werror``.
+
+   - ``W=0`` (default)
+
+     Enables a wide assortment of warnings, most notably ``-Wall`` and
+     ``-Wextra``, as well as various bad practices and things that are likely to
+     result in errors. Includes some compiler specific flags. No warnings are
+     expected at this level for any build.
+
+   - ``W=1``
+
+     Enables warnings we want the generic build to include but are too time
+     consuming to fix at the moment. It re-enables warnings taken out for
+     ``W=0`` builds (a few of the ``-Wextra`` additions). This level is expected
+     to eventually be merged into ``W=0``. Some warnings are expected on some
+     builds, but new contributions should not introduce new ones.
+
+   - ``W=2`` (recommended)
+
+    Enables warnings we want the generic build to include but cannot be enabled
+    due to external libraries. This level is expected to eventually be merged
+    into ``W=0``. Lots of warnings are expected, primarily from external
+    libraries like zlib and compiler-rt, but new controbutions should not
+    introduce new ones.
+
+   - ``W=3``
+
+     Enables warnings that are informative but not necessary and generally too
+     verbose and frequently ignored. A very large number of warnings are
+     expected.
+
+   The exact set of warning flags depends on the compiler and TF-A warning
+   level, however they are all succinctly set in the top-level Makefile. Please
+   refer to the `GCC`_ or `Clang`_ documentation for more information on the
+   individual flags.
+
 -  ``WARMBOOT_ENABLE_DCACHE_EARLY`` : Boolean option to enable D-cache early on
    the CPU after warm boot. This is applicable for platforms which do not
    require interconnect programming to enable cache coherency (eg: single
@@ -1161,3 +1204,5 @@
 .. _DEN0115: https://developer.arm.com/docs/den0115/latest
 .. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
 .. _PSA DRTM specification: https://developer.arm.com/documentation/den0113/a
+.. _GCC: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
+.. _Clang: https://clang.llvm.org/docs/DiagnosticsReference.html
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index aa57e1d..80b72e5 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -2135,7 +2135,7 @@
 
 #. Providing runtime firmware services. Currently, BL31 only implements a
    subset of the Power State Coordination Interface (PSCI) API as a runtime
-   service. See Section 3.3 below for details of porting the PSCI
+   service. See :ref:`psci_in_bl31` below for details of porting the PSCI
    implementation.
 
 #. Optionally passing control to the BL32 image, pre-loaded at a platform-
@@ -2544,6 +2544,8 @@
 This function writes entropy into storage provided by the caller. If no entropy
 is available, it must return false and the storage must not be written.
 
+.. _psci_in_bl31:
+
 Power State Coordination Interface (in BL31)
 --------------------------------------------
 
@@ -3396,6 +3398,39 @@
 The default implementation of this function calls
 ``report_unhandled_exception``.
 
+Function : plat_handle_rng_trap
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uint64_t
+    Argument : cpu_context_t *
+    Return   : int
+
+This function is invoked by BL31's exception handler when there is a synchronous
+system register trap caused by access to the RNDR or RNDRRS registers. It allows
+platforms implementing ``FEAT_RNG_TRAP`` and enabling ``ENABLE_FEAT_RNG_TRAP`` to
+emulate those system registers by returing back some entropy to the lower EL.
+
+The first parameter (``uint64_t esr_el3``) contains the content of the ESR_EL3
+syndrome register, which encodes the instruction that was trapped. The interesting
+information in there is the target register (``get_sysreg_iss_rt()``).
+
+The second parameter (``cpu_context_t *ctx``) represents the CPU state in the
+lower exception level, at the time when the execution of the ``mrs`` instruction
+was trapped. Its content can be changed, to put the entropy into the target
+register.
+
+The return value indicates how to proceed:
+
+-  When returning ``TRAP_RET_UNHANDLED`` (-1), the machine will panic.
+-  When returning ``TRAP_RET_REPEAT`` (0), the exception handler will return
+   to the same instruction, so its execution will be repeated.
+-  When returning ``TRAP_RET_CONTINUE`` (1), the exception handler will return
+   to the next instruction.
+
+This function needs to be implemented by a platform if it enables FEAT_RNG_TRAP.
+
 Build flags
 -----------
 
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 3723294..5b49d2e 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -31,12 +31,18 @@
    You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for
    AArch32 and AArch64 builds respectively.
 
-- Clang >= 14.0.0
-- Arm Compiler >= 6.18
+- Clang == 14.0.0
+- Arm Compiler == 6.18
 
 In addition, a native compiler is required to build the supporting tools.
 
 .. note::
+   Versions greater than the ones specified are likely but not guaranteed to
+   work. This is predominantly because TF-A carries its own copy of compiler-rt,
+   which may be older than the version expected by the compiler. Fixes and bug
+   reports are always welcome.
+
+.. note::
    The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
    Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain.
 
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index eab3e4d..7418669 100644
--- a/docs/perf/psci-performance-juno.rst
+++ b/docs/perf/psci-performance-juno.rst
@@ -286,7 +286,7 @@
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.*
 
-.. _Juno R1 platform: https://static.docs.arm.com/100122/0100/arm_versatile_express_juno_r1_development_platform_(v2m_juno_r1)_technical_reference_manual_100122_0100_05_en.pdf
+.. _Juno R1 platform: https://developer.arm.com/documentation/100122/latest/
 .. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index 91e681f..d741d58 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -241,7 +241,7 @@
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
 
 .. _Linaro release software stack: http://releases.linaro.org/members/arm/platforms/
 .. _Juno platform software user guide: https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/juno/user-guide.rst
@@ -250,4 +250,3 @@
 .. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
 .. _Juno Getting Started Guide: https://developer.arm.com/documentation/den0928/f/?lang=en
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
-.. _Juno Arm Development Platform: http://www.arm.com/products/tools/development-boards/versatile-express/juno-arm-development-platform.php
diff --git a/docs/plat/qemu.rst b/docs/plat/qemu.rst
index 6986326..f2a39e9 100644
--- a/docs/plat/qemu.rst
+++ b/docs/plat/qemu.rst
@@ -44,7 +44,7 @@
 Then, you will get ``Build/ArmVirtQemuKernel-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd``
 
 Please note you do not need to use GCC 5 in spite of the environment variable
-``GCC5_AARCH64_PREFIX``
+``GCC5_AARCH64_PREFIX``.
 
 The rootfs can be built by using Buildroot as follows:
 
@@ -88,54 +88,73 @@
         -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios bl1.bin   \
         -d unimp -semihosting-config enable,target=native
 
-Booting via flash based firmwares
----------------------------------
+Booting via flash based firmware
+--------------------------------
 
-Boot firmwares are loaded via secure FLASH0 device so ``bl1.bin`` and
-``fip.bin`` should be concatenated to create a ``flash.bin`` that is flashed
-onto secure FLASH0.
+An alternate approach to deploy a full system stack on QEMU is to load the
+firmware via a secure flash device.  This involves concatenating ``bl1.bin`` and
+``fip.bin`` to create a boot ROM that is flashed onto secure FLASH0 with the
+``-bios`` option.
 
--  ``bl32.bin`` -> BL32 (``tee-header_v2.bin``)
--  ``bl32_extra1.bin`` -> BL32 Extra1 (``tee-pager_v2.bin``)
--  ``bl32_extra2.bin`` -> BL32 Extra2 (``tee-pageable_v2.bin``)
--  ``bl33.bin`` -> BL33 (``QEMU_EFI.fd``)
+For example, to test the following firmware stack:
+
+
+-  BL32 - ``bl32.bin`` -> ``tee-header_v2.bin``
+-  BL32 Extra1 - ``bl32_extra1.bin`` -> ``tee-pager_v2.bin``
+-  BL32 Extra2 - ``bl32_extra2.bin`` -> ``tee-pageable_v2.bin``
+-  BL33 - ``bl33.bin`` -> ``QEMU_EFI.fd`` (EDK II)
 -  ``Image`` -> linux/arch/arm64/boot/Image
 
-To build:
 
-.. code:: shell
+1.  Compile TF-A
 
-    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
-        BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
-        BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip
+  .. code:: shell
 
-To build with TBBR enabled, BL31 and BL32 encrypted with test key:
+      make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
+          BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
+          BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip
 
-.. code:: shell
+  Or, alternatively, to build with TBBR enabled, as well as, BL31 and BL32 encrypted with
+  test key:
 
-    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
-        BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
-        BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip \
-        MBEDTLS_DIR=<path-to-mbedtls-repo> TRUSTED_BOARD_BOOT=1 \
-        GENERATE_COT=1 DECRYPTION_SUPPORT=aes_gcm FW_ENC_STATUS=0 \
-        ENCRYPT_BL31=1 ENCRYPT_BL32=1
+  .. code:: shell
 
-To build flash.bin:
+      make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \
+          BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \
+          BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip \
+          MBEDTLS_DIR=<path-to-mbedtls-repo> TRUSTED_BOARD_BOOT=1 \
+          GENERATE_COT=1 DECRYPTION_SUPPORT=aes_gcm FW_ENC_STATUS=0 \
+          ENCRYPT_BL31=1 ENCRYPT_BL32=1
 
-.. code:: shell
+2.  Concatenate ``bl1.bin`` and ``fip.bin`` to create the boot ROM
 
-    dd if=build/qemu/release/bl1.bin of=flash.bin bs=4096 conv=notrunc
-    dd if=build/qemu/release/fip.bin of=flash.bin seek=64 bs=4096 conv=notrunc
+  .. code:: shell
 
-To start (QEMU v5.0.0):
+      dd if=build/qemu/release/bl1.bin of=flash.bin bs=4096 conv=notrunc
+      dd if=build/qemu/release/fip.bin of=flash.bin seek=64 bs=4096 conv=notrunc
 
-.. code:: shell
+3.  Launch QEMU
 
-    qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57  \
-        -kernel Image -no-acpi                     \
-        -append 'console=ttyAMA0,38400 keep_bootcon'  \
-        -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios flash.bin   \
-        -d unimp
+  .. code:: shell
+
+      qemu-system-aarch64 -nographic -machine virt,secure=on
+          -cpu cortex-a57  -kernel Image   \
+          -append 'console=ttyAMA0,38400 keep_bootcon'  \
+          -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios flash.bin   \
+          -d unimp
+
+The ``-bios`` option abstracts the loading of raw bare metal binaries into flash
+or ROM memory. QEMU loads the binary into the region corresponding to
+the hardware's entrypoint, from which the binary is executed upon a platform
+"reset". In addition to this, it places the information about the kernel
+provided with option ``-kernel``, and the RamDisk provided with ``-initrd``,
+into the firmware configuration ``fw_cfg``. In this setup, EDK II is responsible
+for extracting and launching these from ``fw_cfg``.
+
+.. note::
+    QEMU may be launched with or without ACPI (``-acpi``/``-no-acpi``). In
+    either case, ensure that the kernel build options are aligned with the
+    parameters passed to QEMU.
 
 Running QEMU in OpenCI
 -----------------------
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 5d2e663..5d04639 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -14,6 +14,11 @@
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net bl31
 ```
 
+To build TF-A for JTAG DCC console:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net VERSAL_NET_CONSOLE=dcc bl31
+```
+
 Xilinx Versal NET platform specific build options
 -------------------------------------------------
 
@@ -23,8 +28,9 @@
 *   `VERSAL_NET_BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary.
 
 *   `VERSAL_NET_CONSOLE`: Select the console driver. Options:
-    -   `pl011`, `pl011_0`: ARM pl011 UART 0
+    -   `pl011`, `pl011_0`: ARM pl011 UART 0 (default)
     -   `pl011_1`         : ARM pl011 UART 1
+    -   `dcc`             : JTAG Debug Communication Channel(DCC)
 
 *   `TFA_NO_PM` : Platform Management support.
     -    0 : Enable Platform Management (Default)
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index af1cb22..b2871df 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -41,6 +41,21 @@
    -  ``cadence``, ``cadence0``: Cadence UART 0
    -  ``cadence1`` : Cadence UART 1
 
+ZynqMP Debug behavior
+---------------------
+
+With DEBUG=1, TF-A for ZynqMP uses DDR memory range instead of OCM memory range
+due to size constraints.
+For DEBUG=1 configuration for ZynqMP the BL31_BASE is set to the DDR location
+of 0x1000 and BL31_LIMIT is set to DDR location of 0x7FFFF.
+
+If the user wants to move the bl31 to a different DDR location, user can provide
+the DDR address location in the build command as follows,
+
+make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 DEBUG=1 \
+	ZYNQMP_ATF_MEM_BASE=<DDR address> ZYNQMP_ATF_MEM_SIZE=<size> bl31
+
+
 FSBL->TF-A Parameter Passing
 ----------------------------
 
@@ -71,3 +86,40 @@
 
 The 4 leaf power domains represent the individual A53 cores, while resources
 common to the cluster are grouped in the power domain on the top.
+
+CUSTOM SIP service support
+--------------------------
+
+- Dedicated SMC FID ZYNQMP_SIP_SVC_CUSTOM(0x82002000)(32-bit)/
+  (0xC2002000)(64-bit) to be used by a custom package for
+  providing CUSTOM SIP service.
+
+- by default platform provides bare minimum definition for
+  custom_smc_handler in this service.
+
+- to use this service, custom package should implement their
+  smc handler with the name custom_smc_handler. once custom package is
+  included in TF-A build, their definition of custom_smc_handler is
+  enabled.
+
+Custom package makefile fragment inclusion in TF-A build
+--------------------------------------------------------
+
+- custom package is not directly part of TF-A source.
+
+- <CUSTOM_PKG_PATH> is the location at which user clones a
+  custom package locally.
+
+- custom package needs to implement makefile fragment named
+  custom_pkg.mk so as to get included in TF-A build.
+
+- custom_pkg.mk specify all the rules to include custom package
+  specific header files, dependent libs, source files that are
+  supposed to be included in TF-A build.
+
+- when <CUSTOM_PKG_PATH> is specified in TF-A build command,
+  custom_pkg.mk is included from <CUSTOM_PKG_PATH> in TF-A build.
+
+- TF-A build command:
+  make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1
+  bl31 CUSTOM_PKG_PATH=<...>
diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst
index 507046f..f9618db 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -131,38 +131,9 @@
   overflows.
 
 - The ``W`` build flag can be used to enable a number of compiler warning
-  options to detect potentially incorrect code.
-
-  - W=0 (default value)
-
-    The ``Wunused`` with ``Wno-unused-parameter``, ``Wdisabled-optimization``
-    and ``Wvla`` flags are enabled.
-
-    The ``Wunused-but-set-variable``, ``Wmaybe-uninitialized`` and
-    ``Wpacked-bitfield-compat`` are GCC specific flags that are also enabled.
-
-  - W=1
-
-    Adds ``Wextra``, ``Wmissing-format-attribute``, ``Wmissing-prototypes``,
-    ``Wold-style-definition`` and ``Wunused-const-variable``.
-
-  - W=2
-
-    Adds ``Waggregate-return``, ``Wcast-align``, ``Wnested-externs``,
-    ``Wshadow``, ``Wlogical-op``.
-
-  - W=3
-
-    Adds ``Wbad-function-cast``, ``Wcast-qual``, ``Wconversion``, ``Wpacked``,
-    ``Wpointer-arith``, ``Wredundant-decls`` and
-    ``Wswitch-default``.
-
-  Refer to the GCC or Clang documentation for more information on the individual
-  options: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html and
-  https://clang.llvm.org/docs/DiagnosticsReference.html.
-
-  NB: The ``Werror`` flag is enabled by default in TF-A and can be disabled by
-  setting the ``E`` build flag to 0.
+  options to detect potentially incorrect code. TF-A is tested with ``W=0`` but
+  it is recommended to develop against ``W=2`` (which will eventually become the
+  default).
 
 .. rubric:: References
 
diff --git a/docs/process/security.rst b/docs/process/security.rst
index e15783b..c6429ad 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -9,10 +9,8 @@
 vulnerabilities and inform users as best we can about all possible issues.
 
 We disclose TF-A vulnerabilities as Security Advisories, all of which are listed
-at the bottom of this page. Any new ones will, additionally, be announced as
-issues in the project's `issue tracker`_ with the ``security-advisory`` tag. You
-can receive notification emails for these by watching the "Trusted Firmware-A"
-project at https://developer.trustedfirmware.org/.
+at the bottom of this page. Any new ones will, additionally, be announced on the
+TF-A project's `mailing list`_.
 
 Found a Security Issue?
 -----------------------
@@ -69,6 +67,12 @@
 |  |TFV-8|  | Not saving x0 to x3 registers can leak information from one      |
 |           | Normal World SMC client to another                               |
 +-----------+------------------------------------------------------------------+
+|  |TFV-9|  | Trusted Firmware-A exposure to speculative processor             |
+|           | vulnerabilities with branch prediction target reuse              |
++-----------+------------------------------------------------------------------+
+|  |TFV-10| | Incorrect validation of X.509 certificate extensions can result  |
+|           | in an out-of-bounds read                                         |
++-----------+------------------------------------------------------------------+
 
 .. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
 .. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
@@ -81,9 +85,11 @@
 .. |TFV-6| replace:: :ref:`Advisory TFV-6 (CVE-2017-5753, CVE-2017-5715, CVE-2017-5754)`
 .. |TFV-7| replace:: :ref:`Advisory TFV-7 (CVE-2018-3639)`
 .. |TFV-8| replace:: :ref:`Advisory TFV-8 (CVE-2018-19440)`
+.. |TFV-9| replace:: :ref:`Advisory TFV-9 (CVE-2022-23960)`
+.. |TFV-10| replace:: :ref:`Advisory TFV-10 (CVE-2022-47630)`
 
 .. _TrustedFirmware.org security incident process: https://developer.trustedfirmware.org/w/collaboration/security_center/
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
diff --git a/docs/requirements.in b/docs/requirements.in
index 5d771e5..ae20b7d 100644
--- a/docs/requirements.in
+++ b/docs/requirements.in
@@ -1,5 +1,5 @@
-myst-parser==0.15.2
+myst-parser==0.18.1
 pip-tools==6.4.0
-sphinx==4.2.0
-sphinx-rtd-theme==1.0.0
-sphinxcontrib-plantuml==0.22
+sphinx==5.3.0
+sphinx-rtd-theme==1.1.1
+sphinxcontrib-plantuml==0.24.1
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 03b1189..1ed78d0 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,71 +1,71 @@
 #
-# This file is autogenerated by pip-compile with python 3.8
-# To update, run:
+# This file is autogenerated by pip-compile with Python 3.8
+# by the following command:
 #
-#    pip-compile
+#    pip-compile docs/requirements.in
 #
 alabaster==0.7.12
     # via sphinx
-attrs==21.2.0
-    # via markdown-it-py
-babel==2.9.1
+babel==2.11.0
     # via sphinx
-certifi==2021.5.30
+certifi==2022.12.7
     # via requests
-charset-normalizer==2.0.4
+charset-normalizer==2.1.1
     # via requests
-click==8.0.1
+click==8.1.3
     # via pip-tools
-docutils==0.16
+docutils==0.17.1
     # via
     #   myst-parser
     #   sphinx
     #   sphinx-rtd-theme
-idna==3.2
+idna==3.4
     # via requests
-imagesize==1.2.0
+imagesize==1.4.1
+    # via sphinx
+importlib-metadata==6.0.0
     # via sphinx
-jinja2==3.0.1
+jinja2==3.1.2
     # via
     #   myst-parser
     #   sphinx
-markdown-it-py==1.1.0
+markdown-it-py==2.1.0
     # via
     #   mdit-py-plugins
     #   myst-parser
-markupsafe==2.0.1
+markupsafe==2.1.1
     # via jinja2
-mdit-py-plugins==0.2.8
+mdit-py-plugins==0.3.3
     # via myst-parser
-myst-parser==0.15.2
-    # via -r requirements.in
-packaging==21.0
+mdurl==0.1.2
+    # via markdown-it-py
+myst-parser==0.18.1
+    # via -r docs/requirements.in
+packaging==23.0
     # via sphinx
-pep517==0.11.0
+pep517==0.13.0
     # via pip-tools
 pip-tools==6.4.0
-    # via -r requirements.in
-pygments==2.10.0
+    # via -r docs/requirements.in
+pygments==2.14.0
     # via sphinx
-pyparsing==2.4.7
-    # via packaging
-pytz==2021.1
+pytz==2022.7
     # via babel
 pyyaml==6.0
     # via myst-parser
-requests==2.26.0
+requests==2.28.1
     # via sphinx
-snowballstemmer==2.1.0
+snowballstemmer==2.2.0
     # via sphinx
-sphinx==4.2.0
+sphinx==5.3.0
     # via
-    #   -r requirements.in
+    #   -r docs/requirements.in
     #   myst-parser
     #   sphinx-rtd-theme
     #   sphinxcontrib-plantuml
-sphinx-rtd-theme==1.0.0
-    # via -r requirements.in
-sphinxcontrib-applehelp==1.0.2
+sphinx-rtd-theme==1.1.1
+    # via -r docs/requirements.in
+sphinxcontrib-applehelp==1.0.3
     # via sphinx
 sphinxcontrib-devhelp==1.0.2
     # via sphinx
@@ -73,18 +73,22 @@
     # via sphinx
 sphinxcontrib-jsmath==1.0.1
     # via sphinx
-sphinxcontrib-plantuml==0.22
-    # via -r requirements.in
+sphinxcontrib-plantuml==0.24.1
+    # via -r docs/requirements.in
 sphinxcontrib-qthelp==1.0.3
     # via sphinx
 sphinxcontrib-serializinghtml==1.1.5
     # via sphinx
-tomli==1.2.1
+tomli==2.0.1
     # via pep517
-urllib3==1.26.6
+typing-extensions==4.4.0
+    # via myst-parser
+urllib3==1.26.13
     # via requests
-wheel==0.37.0
+wheel==0.38.4
     # via pip-tools
+zipp==3.11.0
+    # via importlib-metadata
 
 # The following packages are considered to be unsafe in a requirements file:
 # pip
diff --git a/docs/resources/diagrams/plantuml/rss_attestation_flow.puml b/docs/resources/diagrams/plantuml/rss_attestation_flow.puml
new file mode 100644
index 0000000..aca5c01
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/rss_attestation_flow.puml
@@ -0,0 +1,39 @@
+@startuml
+skinparam ParticipantPadding 10
+skinparam BoxPadding 10
+box AP
+participant RMM
+participant BL31
+endbox
+box RSS
+participant DelegAttest
+participant InitAttest
+participant MeasuredBoot
+participant Crypto
+endbox
+
+== RMM Boot phase ==
+
+RMM -> BL31: get_realm_key(\n\t**hash_algo**, ...)
+BL31 -> DelegAttest: get_delegated_key
+DelegAttest -> MeasuredBoot: read_measurement
+Rnote over DelegAttest: Compute input\n\ for key derivation\n\ (hash of measurements)
+DelegAttest -> Crypto: derive_key
+Rnote over DelegAttest: Compute public key\n\ hash with **hash_algo**.
+Rnote over Crypto: Seed is provisioned\n\ in the factory.
+DelegAttest --> BL31: get_delegated_key
+BL31 --> RMM: get_realm_key
+Rnote over RMM: Only private key\n\ is returned. Public\n\ key and its hash\n\ must be computed.\n\
+Public key is included\n\ in the realm token.\n\ Its hash is the input\n\ for get_platform_token
+RMM -> BL31: get_platform_token(\n\t**pub_key_hash**, ...)
+BL31 -> DelegAttest: get_delegated_token
+Rnote over DelegAttest: Check **pub_key_hash**\n\ against derived key.
+DelegAttest -> InitAttest: get_initial_token
+Rnote over InitAttest: Create the token including\n\ the **pub_key_hash** as the\n\ challenge claim
+InitAttest -> MeasuredBoot: read_measurement
+InitAttest -> Crypto: sign_token
+InitAttest --> DelegAttest:  get_initial_token
+DelegAttest --> BL31: get_delegated_token
+BL31 --> RMM: get_platform_token
+Rnote over RMM: Platform token is\n\ cached. It is not\n\ changing within\n\ a power cycle.
+@enduml
diff --git a/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml b/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
new file mode 100644
index 0000000..1aeb1a9
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
@@ -0,0 +1,79 @@
+@startuml
+skinparam ParticipantPadding 10
+skinparam BoxPadding 10
+box RSS
+participant RSS_BL1_1
+participant RSS_BL1_2
+participant RSS_BL2
+participant RSS_S
+endbox
+box SCP
+participant SCP_BL1
+endbox
+box AP
+participant AP_BL1
+participant AP_BL2
+participant AP_BL31
+endbox
+
+== RSS Boot phase ==
+-> RSS_BL1_1: Reset
+Rnote over RSS_BL1_1: ROM code, XIP
+Rnote over RSS_BL1_2: OTP code, XIP
+Rnote over RSS_BL2, AP_BL31: Stored in flash, loaded and executed in RAM
+activate RSS_BL1_1 #Green
+RSS_BL1_1 -->> RSS_BL1_2: Validate, measure
+Rnote over RSS_BL1_1: BL1_2 measurement\n\ saved to a shared buffer
+RSS_BL1_1 -> RSS_BL1_2: Pass execution
+deactivate RSS_BL1_1
+activate RSS_BL1_2 #Green
+RSS_BL1_2 -->> RSS_BL2: Validate, measure, load
+Rnote over RSS_BL1_2: RSS_BL2 measurement\n\ saved to a shared buffer
+RSS_BL1_2 -> RSS_BL2: Pass execution
+deactivate RSS_BL1_2
+activate RSS_BL2 #Green
+RSS_BL2 -->> RSS_S: Validate, measure, load
+RSS_BL2 -->> SCP_BL1: Validate, measure, load
+Rnote over RSS_BL2: RSS_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer
+RSS_BL2 -> SCP_BL1: Release from reset
+activate SCP_BL1 #Green
+Rnote over RSS_BL2, SCP_BL1: MHU init between RSS and SCP
+Rnote over SCP_BL1: Configure memory
+Rnote over RSS_BL2: Waits for SCP
+SCP_BL1 --> RSS_BL2: Done
+RSS_BL2 -->> AP_BL1: Validate, measure, load
+Rnote over RSS_BL2: AP_BL1 measurement\n\ saved to a shared buffer
+RSS_BL2 -> AP_BL1: Release from reset
+activate AP_BL1 #Green
+RSS_BL2 -> RSS_S: Pass execution
+deactivate RSS_BL2
+activate RSS_S #Green
+Rnote over RSS_S: Measurements read from\n\ shared buffer and saved by\n\
+Measured Boot service to\n\ measurement slots.
+
+== RSS Runtime / AP Boot phase ==
+Rnote over RSS_S, AP_BL1: MHU init between RSS and AP
+Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG
+AP_BL1 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL1 -->> AP_BL2: Validate, measure,load
+AP_BL1 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL1 -> AP_BL2: Pass execution
+deactivate AP_BL1
+activate AP_BL2 #Green
+Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG
+AP_BL2 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL2 -->> AP_BL31: Validate, measure,load
+Rnote over AP_BL2: Measure and load:\n\ BL31
+AP_BL2 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+Rnote over AP_BL2: Measure and load:\n\ RMM
+AP_BL2 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL2 -> AP_BL31: Pass execution
+deactivate AP_BL2
+activate AP_BL31 #Green
+== RSS / AP Runtime ==
+@enduml
diff --git a/docs/resources/diagrams/rmm_el3_manifest_struct.dia b/docs/resources/diagrams/rmm_el3_manifest_struct.dia
deleted file mode 100644
index 7b7a9c2..0000000
--- a/docs/resources/diagrams/rmm_el3_manifest_struct.dia
+++ /dev/null
Binary files differ
diff --git a/docs/resources/diagrams/rmm_el3_manifest_struct.png b/docs/resources/diagrams/rmm_el3_manifest_struct.png
deleted file mode 100644
index 8b5776c..0000000
--- a/docs/resources/diagrams/rmm_el3_manifest_struct.png
+++ /dev/null
Binary files differ
diff --git a/docs/resources/diagrams/rss_attestation_flow.svg b/docs/resources/diagrams/rss_attestation_flow.svg
new file mode 100644
index 0000000..3728c6f
--- /dev/null
+++ b/docs/resources/diagrams/rss_attestation_flow.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1087px" preserveAspectRatio="none" style="width:900px;height:1087px;background:#FFFFFF;" version="1.1" viewBox="0 0 900 1087" width="900px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="261.5" x="44" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="164.75" y="18.0669">AP</text><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="502" x="364" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="601" y="18.0669">RSS</text><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="82" x2="82" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="266.5" x2="266.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="426" x2="426" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="553.5" x2="553.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="705" x2="705" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="822" x2="822" y1="56.4297" y2="1046.875"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="45.1279">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="1065.8701">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="45.1279">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="1065.8701">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="45.1279">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="1065.8701">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="45.1279">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="1065.8701">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="45.1279">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="1065.8701">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="45.1279">Crypto</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="1065.8701">Crypto</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="893" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="144" x="374.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="125" x="380.5" y="92.4966">RMM Boot phase</text><polygon fill="#181818" points="255,141.8281,265,145.8281,255,149.8281,259,145.8281" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="145.8281" y2="145.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="89" y="125.6294">get_realm_key(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="121" y="140.7622">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="195" y="140.7622">, ...)</text><polygon fill="#181818" points="414,170.9609,424,174.9609,414,178.9609,418,174.9609" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="174.9609" y2="174.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="274" y="169.895">get_delegated_key</text><polygon fill="#181818" points="693,200.0938,703,204.0938,693,208.0938,697,204.0938" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="699" y1="204.0938" y2="204.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="433" y="199.0278">read_measurement</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="167" x="342" y="217.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="95" x="346" y="233.1606">Compute input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="110" x="346" y="248.2935">for key derivation</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="159" x="346" y="263.4263">(hash of measurements)</text><polygon fill="#181818" points="810.5,292.625,820.5,296.625,810.5,300.625,814.5,296.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="816.5" y1="296.625" y2="296.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="68" x="433" y="291.5591">derive_key</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="150" x="351" y="309.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="355" y="325.6919">Compute public key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="60" x="355" y="340.8247">hash with</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="419" y="340.8247">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="4" x="493" y="340.8247">.</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="132" x="756" y="357.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="124" x="760" y="373.9575">Seed is provisioned</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="760" y="389.0903">in the factory.</text><polygon fill="#181818" points="278,418.2891,268,422.2891,278,426.2891,274,422.2891" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="422.2891" y2="422.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="284" y="417.2231">get_delegated_key</text><polygon fill="#181818" points="93,447.4219,83,451.4219,93,455.4219,89,451.4219" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="451.4219" y2="451.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="94" x="99" y="446.356">get_realm_key</text><rect fill="#FEFFDD" height="129" style="stroke:#181818;stroke-width:0.5;" width="154" x="5" y="464.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="102" x="9" y="480.4888">Only private key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="9" y="495.6216">is returned. Public</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="9" y="510.7544">key and its hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="9" y="525.8872">must be computed.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="541.02">Public key is included</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="9" y="556.1528">in the realm token.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="9" y="571.2856">Its hash is the input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="146" x="9" y="586.4185">for get_platform_token</text><polygon fill="#181818" points="255,630.75,265,634.75,255,638.75,259,634.75" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="634.75" y2="634.75"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="130" x="89" y="614.5513">get_platform_token(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="121" y="629.6841">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="225" y="629.6841">, ...)</text><polygon fill="#181818" points="414,659.8828,424,663.8828,414,667.8828,418,663.8828" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="663.8828" y2="663.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="274" y="658.8169">get_delegated_token</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="155" x="348" y="676.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="39" x="352" y="692.9497">Check</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="395" y="692.9497">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="352" y="708.0825">against derived key.</text><polygon fill="#181818" points="542,737.2813,552,741.2813,542,745.2813,546,741.2813" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="548" y1="741.2813" y2="741.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="433" y="736.2153">get_initial_token</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="181" x="463" y="754.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="168" x="467" y="770.3481">Create the token including</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="21" x="467" y="785.481">the</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="492" y="785.481">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="40" x="600" y="785.481">as the</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="467" y="800.6138">challenge claim</text><polygon fill="#181818" points="693,829.8125,703,833.8125,693,837.8125,697,833.8125" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="699" y1="833.8125" y2="833.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="561" y="828.7466">read_measurement</text><polygon fill="#181818" points="810.5,858.9453,820.5,862.9453,810.5,866.9453,814.5,862.9453" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="816.5" y1="862.9453" y2="862.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="69" x="561" y="857.8794">sign_token</text><polygon fill="#181818" points="437,888.0781,427,892.0781,437,896.0781,433,892.0781" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="431" x2="553" y1="892.0781" y2="892.0781"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="443" y="887.0122">get_initial_token</text><polygon fill="#181818" points="278,917.2109,268,921.2109,278,925.2109,274,921.2109" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="921.2109" y2="921.2109"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="284" y="916.145">get_delegated_token</text><polygon fill="#181818" points="93,946.3438,83,950.3438,93,954.3438,89,950.3438" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="950.3438" y2="950.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="99" y="945.2778">get_platform_token</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="116" x="24" y="963.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="108" x="28" y="979.4106">Platform token is</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="28" y="994.5435">cached. It is not</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="98" x="28" y="1009.6763">changing within</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="90" x="28" y="1024.8091">a power cycle.</text><!--MD5=[84fabec568a656165bea957fac178b53]
+@startuml

+skinparam ParticipantPadding 10

+skinparam BoxPadding 10

+box AP

+participant RMM

+participant BL31

+endbox

+box RSS

+participant DelegAttest

+participant InitAttest

+participant MeasuredBoot

+participant Crypto

+endbox

+

+== RMM Boot phase ==

+

+RMM -> BL31: get_realm_key(\n\t**hash_algo**, ...)

+BL31 -> DelegAttest: get_delegated_key

+DelegAttest -> MeasuredBoot: read_measurement

+Rnote over DelegAttest: Compute input\n\ for key derivation\n\ (hash of measurements)

+DelegAttest -> Crypto: derive_key

+Rnote over DelegAttest: Compute public key\n\ hash with **hash_algo**.

+Rnote over Crypto: Seed is provisioned\n\ in the factory.

+DelegAttest - -> BL31: get_delegated_key

+BL31 - -> RMM: get_realm_key

+Rnote over RMM: Only private key\n\ is returned. Public\n\ key and its hash\n\ must be computed.\nPublic key is included\n\ in the realm token.\n\ Its hash is the input\n\ for get_platform_token

+RMM -> BL31: get_platform_token(\n\t**pub_key_hash**, ...)

+BL31 -> DelegAttest: get_delegated_token

+Rnote over DelegAttest: Check **pub_key_hash**\n\ against derived key.

+DelegAttest -> InitAttest: get_initial_token

+Rnote over InitAttest: Create the token including\n\ the **pub_key_hash** as the\n\ challenge claim

+InitAttest -> MeasuredBoot: read_measurement

+InitAttest -> Crypto: sign_token

+InitAttest - -> DelegAttest:  get_initial_token

+DelegAttest - -> BL31: get_delegated_token

+BL31 - -> RMM: get_platform_token

+Rnote over RMM: Platform token is\n\ cached. It is not\n\ changing within\n\ a power cycle.

+@enduml

+
+PlantUML version 1.2022.7(Mon Aug 22 19:01:30 CEST 2022)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: hu
+Country: HU
+--></g></svg>
\ No newline at end of file
diff --git a/docs/resources/diagrams/rss_measured_boot_flow.svg b/docs/resources/diagrams/rss_measured_boot_flow.svg
new file mode 100644
index 0000000..f5bf311
--- /dev/null
+++ b/docs/resources/diagrams/rss_measured_boot_flow.svg
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1826px" preserveAspectRatio="none" style="width:1254px;height:1826px;background:#FFFFFF;" version="1.1" viewBox="0 0 1254 1826" width="1254px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="610.5" x="27" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="318.25" y="18.0669">RSS</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="103" x="659.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="29" x="696.5" y="18.0669">SCP</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="451.5" x="784.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="1000.25" y="18.0669">AP</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="86" x2="86" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="232" x2="232" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="413" x2="413" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="594.5" x2="594.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="710.5" x2="710.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="830.5" x2="830.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1007.5" x2="1007.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1185" x2="1185" y1="56.4297" y2="1785.7969"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="45.1279">RSS_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="1804.792">RSS_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="45.1279">RSS_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="1804.792">RSS_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="45.1279">RSS_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="1804.792">RSS_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="45.1279">RSS_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="1804.792">RSS_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="45.1279">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="1804.792">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="45.1279">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="1804.792">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="45.1279">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="1804.792">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="45.1279">AP_BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="1804.792">AP_BL31</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="136" x="555.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="117" x="561.5" y="92.4966">RSS Boot phase</text><polygon fill="#181818" points="69.5,126.6953,79.5,130.6953,69.5,134.6953,73.5,130.6953" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="0" x2="75.5" y1="130.6953" y2="130.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="36" x="7" y="125.6294">Reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="99" x="37" y="143.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="91" x="41" y="159.7622">ROM code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="95" x="185" y="176.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="87" x="189" y="192.895">OTP code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="861" x="368" y="209.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="281" x="658" y="226.0278">Stored in flash, loaded and executed in RAM</text><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="255.2266"/><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="263.2266"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="91.5" x2="231.5" y1="259.2266" y2="259.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="117" x="98.5" y="254.1606">Validate, measure</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="5" y="272.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="288.2935">BL1_2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="9" y="303.4263">saved to a shared buffer</text><polygon fill="#181818" points="215.5,332.625,225.5,336.625,215.5,340.625,219.5,336.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="86.5" x2="221.5" y1="336.625" y2="336.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="93.5" y="331.5591">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="361.7578"/><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="369.7578"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="237.5" x2="412.5" y1="365.7578" y2="365.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="244.5" y="360.6919">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="150" y="378.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="154" y="394.8247">RSS_BL2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="154" y="409.9575">saved to a shared buffer</text><polygon fill="#181818" points="396.5,439.1563,406.5,443.1563,396.5,447.1563,400.5,443.1563" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="232.5" x2="402.5" y1="443.1563" y2="443.1563"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="239.5" y="438.0903">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="468.2891"/><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="476.2891"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="593.5" y1="472.2891" y2="472.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="467.2231">Validate, measure, load</text><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="497.4219"/><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="505.4219"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="710" y1="501.4219" y2="501.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="496.356">Validate, measure, load</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="148" x="339" y="514.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="131" x="343" y="530.4888">RSS_S and SCP_BL1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="140" x="343" y="545.6216">measurements saved</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="343" y="560.7544">to a shared buffer</text><polygon fill="#181818" points="694,589.9531,704,593.9531,694,597.9531,698,593.9531" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="700" y1="593.9531" y2="593.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="588.8872">Release from reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="387" x="368" y="606.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="200" x="461.75" y="623.02">MHU init between RSS and SCP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="127" x="647" y="640.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="119" x="651" y="656.1528">Configure memory</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="93" x="367" y="673.2188"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="85" x="371" y="689.2856">Waits for SCP</text><polygon fill="#181818" points="429.5,718.4844,419.5,722.4844,429.5,726.4844,425.5,722.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="423.5" x2="705" y1="722.4844" y2="722.4844"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="34" x="435.5" y="717.4185">Done</text><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="747.6172"/><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="755.6172"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="830" y1="751.6172" y2="751.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="746.5513">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="331" y="764.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="143" x="335" y="780.6841">AP_BL1 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="335" y="795.8169">saved to a shared buffer</text><polygon fill="#181818" points="814,825.0156,824,829.0156,814,833.0156,818,829.0156" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="820" y1="829.0156" y2="829.0156"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="823.9497">Release from reset</text><polygon fill="#181818" points="577.5,854.1484,587.5,858.1484,577.5,862.1484,581.5,858.1484" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="413.5" x2="583.5" y1="858.1484" y2="858.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="420.5" y="853.0825">Pass execution</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="182" x="503" y="871.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="887.2153">Measurements read from</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="174" x="507" y="902.3481">shared buffer and saved by</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="917.481">Measured Boot service to</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="129" x="507" y="932.6138">measurement slots.</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="965.2461" y2="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="968.2461" y2="968.2461"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="237" x="505" y="954.6797"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="218" x="511" y="970.7466">RSS Runtime / AP Boot phase</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="313" x="556" y="992.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="191" x="617" y="1008.8794">MHU init between RSS and AP</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="126" x="768" y="1025.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="772" y="1042.0122">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="74" x="772" y="1057.145">FW_CONFIG</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="97" x="772" y="1072.2778">TB_FW_CONFIG</text><polygon fill="#181818" points="610.5,1101.4766,600.5,1105.4766,610.5,1109.4766,606.5,1105.4766" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1105.4766" y2="1105.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1100.4106">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1118.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1134.5435">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1149.6763">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1178.875"/><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1186.875"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="836" x2="1007" y1="1182.875" y2="1182.875"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="843" y="1177.8091">Validate, measure,load</text><polygon fill="#181818" points="610.5,1208.0078,600.5,1212.0078,610.5,1216.0078,606.5,1212.0078" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1212.0078" y2="1212.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1206.9419">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1225.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1241.0747">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1256.2075">store measurement</text><polygon fill="#181818" points="991,1285.4063,1001,1289.4063,991,1293.4063,995,1289.4063" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="831" x2="997" y1="1289.4063" y2="1289.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="838" y="1284.3403">Pass execution</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1302.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1318.4731">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="77" x="949" y="1333.606">HW_CONFIG</text><polygon fill="#181818" points="610.5,1362.8047,600.5,1366.8047,610.5,1370.8047,606.5,1366.8047" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1366.8047" y2="1366.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1361.7388">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1379.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1395.8716">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1411.0044">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1440.2031"/><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1448.2031"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="1013" x2="1184" y1="1444.2031" y2="1444.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="1020" y="1439.1372">Validate, measure,load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1457.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1473.27">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="32" x="949" y="1488.4028">BL31</text><polygon fill="#181818" points="610.5,1517.6016,600.5,1521.6016,610.5,1525.6016,606.5,1521.6016" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1521.6016" y2="1521.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1516.5356">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1534.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1550.6685">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1565.8013">store measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1582.8672"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1598.9341">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="30" x="949" y="1614.0669">RMM</text><polygon fill="#181818" points="610.5,1643.2656,600.5,1647.2656,610.5,1651.2656,606.5,1647.2656" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1647.2656" y2="1647.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1642.1997">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1660.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1676.3325">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1691.4653">store measurement</text><polygon fill="#181818" points="1168,1720.6641,1178,1724.6641,1168,1728.6641,1172,1724.6641" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="1008" x2="1174" y1="1724.6641" y2="1724.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="1015" y="1719.5981">Pass execution</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1753.2305" y2="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1756.2305" y2="1756.2305"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="148" x="549.5" y="1742.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="129" x="555.5" y="1758.731">RSS / AP Runtime</text><!--MD5=[e3f0ee259d2a4aa9c2a97ff856de0312]
+@startuml

+skinparam ParticipantPadding 10

+skinparam BoxPadding 10

+box RSS

+participant RSS_BL1_1

+participant RSS_BL1_2

+participant RSS_BL2

+participant RSS_S

+endbox

+box SCP

+participant SCP_BL1

+endbox

+box AP

+participant AP_BL1

+participant AP_BL2

+participant AP_BL31

+endbox

+

+== RSS Boot phase ==

+-> RSS_BL1_1: Reset

+Rnote over RSS_BL1_1: ROM code, XIP

+Rnote over RSS_BL1_2: OTP code, XIP

+Rnote over RSS_BL2, AP_BL31: Stored in flash, loaded and executed in RAM

+activate RSS_BL1_1 #Green

+RSS_BL1_1 - ->> RSS_BL1_2: Validate, measure

+Rnote over RSS_BL1_1: BL1_2 measurement\n\ saved to a shared buffer

+RSS_BL1_1 -> RSS_BL1_2: Pass execution

+deactivate RSS_BL1_1

+activate RSS_BL1_2 #Green

+RSS_BL1_2 - ->> RSS_BL2: Validate, measure, load

+Rnote over RSS_BL1_2: RSS_BL2 measurement\n\ saved to a shared buffer

+RSS_BL1_2 -> RSS_BL2: Pass execution

+deactivate RSS_BL1_2

+activate RSS_BL2 #Green

+RSS_BL2 - ->> RSS_S: Validate, measure, load

+RSS_BL2 - ->> SCP_BL1: Validate, measure, load

+Rnote over RSS_BL2: RSS_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer

+RSS_BL2 -> SCP_BL1: Release from reset

+activate SCP_BL1 #Green

+Rnote over RSS_BL2, SCP_BL1: MHU init between RSS and SCP

+Rnote over SCP_BL1: Configure memory

+Rnote over RSS_BL2: Waits for SCP

+SCP_BL1 - -> RSS_BL2: Done

+RSS_BL2 - ->> AP_BL1: Validate, measure, load

+Rnote over RSS_BL2: AP_BL1 measurement\n\ saved to a shared buffer

+RSS_BL2 -> AP_BL1: Release from reset

+activate AP_BL1 #Green

+RSS_BL2 -> RSS_S: Pass execution

+deactivate RSS_BL2

+activate RSS_S #Green

+Rnote over RSS_S: Measurements read from\n\ shared buffer and saved by\nMeasured Boot service to\n\ measurement slots.

+

+== RSS Runtime / AP Boot phase ==

+Rnote over RSS_S, AP_BL1: MHU init between RSS and AP

+Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG

+AP_BL1 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL1 - ->> AP_BL2: Validate, measure,load

+AP_BL1 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL1 -> AP_BL2: Pass execution

+deactivate AP_BL1

+activate AP_BL2 #Green

+Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG

+AP_BL2 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL2 - ->> AP_BL31: Validate, measure,load

+Rnote over AP_BL2: Measure and load:\n\ BL31

+AP_BL2 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+Rnote over AP_BL2: Measure and load:\n\ RMM

+AP_BL2 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL2 -> AP_BL31: Pass execution

+deactivate AP_BL2

+activate AP_BL31 #Green

+== RSS / AP Runtime ==

+@enduml

+
+PlantUML version 1.2022.7(Mon Aug 22 19:01:30 CEST 2022)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: hu
+Country: HU
+--></g></svg>
\ No newline at end of file
diff --git a/docs/security_advisories/index.rst b/docs/security_advisories/index.rst
index b80ba34..c9b0f78 100644
--- a/docs/security_advisories/index.rst
+++ b/docs/security_advisories/index.rst
@@ -14,3 +14,4 @@
    security-advisory-tfv-7.rst
    security-advisory-tfv-8.rst
    security-advisory-tfv-9.rst
+   security-advisory-tfv-10.rst
diff --git a/docs/security_advisories/security-advisory-tfv-10.rst b/docs/security_advisories/security-advisory-tfv-10.rst
new file mode 100644
index 0000000..91dba07
--- /dev/null
+++ b/docs/security_advisories/security-advisory-tfv-10.rst
@@ -0,0 +1,159 @@
+Advisory TFV-10 (CVE-2022-47630)
+================================
+
++----------------+-------------------------------------------------------------+
+| Title          | Incorrect validation of X.509 certificate extensions can    |
+|                | result in an out-of-bounds read.                            |
++================+=============================================================+
+| CVE ID         | `CVE-2022-47630`_                                           |
++----------------+-------------------------------------------------------------+
+| Date           | Reported on 12 Dec 2022                                     |
++----------------+-------------------------------------------------------------+
+| Versions       | v1.2 to v2.8                                                |
+| Affected       |                                                             |
++----------------+-------------------------------------------------------------+
+| Configurations | BL1 and BL2 with Trusted Boot enabled with custom,          |
+| Affected       | downstream usages of ``get_ext()`` and/or ``auth_nvctr()``  |
+|                | interfaces. Not exploitable in upstream TF-A code.          |
++----------------+-------------------------------------------------------------+
+| Impact         | Out-of-bounds read.                                         |
++----------------+-------------------------------------------------------------+
+| Fix Version    | - `fd37982a19a4a291`_ "fix(auth): forbid junk after         |
+|                |   extensions"                                               |
+|                |                                                             |
+|                | - `72460f50e2437a85`_ "fix(auth): require at least one      |
+|                |   extension to be present"                                  |
+|                |                                                             |
+|                | - `f5c51855d36e399e`_ "fix(auth): properly validate X.509   |
+|                |   extensions"                                               |
+|                |                                                             |
+|                | - `abb8f936fd0ad085`_ "fix(auth): avoid out-of-bounds read  |
+|                |   in auth_nvctr()"                                          |
+|                |                                                             |
+|                | Note that `72460f50e2437a85`_ is not fixing any             |
+|                | vulnerability per se but it is required for                 |
+|                | `f5c51855d36e399e`_ to apply cleanly.                       |
++----------------+-------------------------------------------------------------+
+| Credit         | Demi Marie Obenour, Invisible Things Lab                    |
++----------------+-------------------------------------------------------------+
+
+This security advisory describes a vulnerability in the X.509 parser used to
+parse boot certificates in TF-A trusted boot: it is possible for a crafted
+certificate to cause an out-of-bounds memory read.
+
+Note that upstream platforms are **not** affected by this. Only downstream
+platforms may be, if (and only if) the interfaces described below are used in a
+different context than seen in upstream code. Details of such context is
+described in the rest of this document.
+
+To fully understand this security advisory, it is recommended to refer to the
+following standards documents:
+
+ - `RFC 5280`_, *Internet X.509 Public Key Infrastructure Certificate and
+   Certificate Revocation List (CRL) Profile*.
+
+ - `ITU-T X.690`_, *ASN.1 encoding rules: Specification of Basic Encoding Rules
+   (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules
+   (DER).*
+
+Bug 1: Insufficient certificate validation
+------------------------------------------
+
+The vulnerability lies in the following source file:
+``drivers/auth/mbedtls/mbedtls_x509_parser.c``. By design, ``get_ext()`` does
+not check the return value of the various ``mbedtls_*()`` functions, as
+``cert_parse()`` is assumed to have guaranteed that they will always succeed.
+However, it passes the end of an extension as the end pointer to these
+functions, whereas ``cert_parse()`` passes the end of the ``TBSCertificate``.
+Furthermore, ``cert_parse()`` does not check that the contents of the extension
+have the same length as the extension itself. It also does not check that the
+extension block extends to the end of the ``TBSCertificate``.
+
+This is a problem, as ``mbedtls_asn1_get_tag()`` leaves ``*p`` and ``*len``
+undefined on failure.  In practice, this results in ``get_ext()`` continuing to
+parse at different offsets than were used (and validated) by ``cert_parse()``,
+which means that the in-bounds guarantee provided by ``cert_parse()`` no longer
+holds.  The result is that it is possible for ``get_ext()`` to read memory past
+the end of the certificate.  This could potentially access memory with dangerous
+read side effects, or leak microarchitectural state that could theoretically be
+retrieved through some side-channel attacks as part of a more complex attack.
+
+Bug 2: Missing bounds check in ``auth_nvctr()``
+-----------------------------------------------
+``auth_nvctr()`` does not check that the buffer provided is
+long enough to hold an ``ASN.1 INTEGER``.  Since ``auth_nvctr()`` will only ever
+read 6 bytes, it is possible to read up to 6 bytes past the end of the buffer.
+
+Exploitability Analysis
+-----------------------
+
+Upstream TF-A Code
+~~~~~~~~~~~~~~~~~~
+
+In upstream TF-A code, the only caller of ``auth_nvctr()`` takes its input from
+``get_ext()``, which means that the second bug is exploitable, so is the first.
+Therefore, only the first bug need be considered.
+
+All standard chains of trust provided in TF-A source tree (that is, under
+``drivers/auth/``) require that the certificate's signature has already been
+validated prior to calling ``get_ext()``, or any function that calls ``get_ext()``.
+Platforms taking their chain of trust from a dynamic configuration file (such as
+``fdts/cot_descriptors.dtsi``) are also safe, as signature verification will
+always be done prior to any calls to ``get_ext()`` or ``auth_nvctr()`` in this
+case, no matter the order of the properties in the file.  Therefore, it is not
+possible to exploit this vulnerability pre-authentication in upstream TF-A.
+
+Furthermore, the data read through ``get_ext()`` only
+ever gets used by the authentication framework (``drivers/auth/auth_mod.c``),
+which greatly reduces the range of inputs it will ever receive and thus the
+impact this has. Specifically, the authentication framework uses ``get_ext()``
+in three cases:
+
+ 1. Retrieving a hash from an X.509 certificate to check the integrity of a
+    child certificate (see ``auth_hash()``).
+
+ 2. Retrieving the signature details from an X.509 certificate to check its
+    authenticity and integrity (see ``auth_signature()``).
+
+ 3. Retrieving the security counter value from an X.509 certificate to protect
+    it from unauthorized rollback to a previous version (see ``auth_nvctr()``).
+
+None of these uses authentication framework write to the out-of-bounds memory,
+so no memory corruption is possible.
+
+In summary, there are 2 separate issues - one in ``get_ext()`` and another one
+in ``auth_nvctr()`` - but neither of these can be exploited in the context of
+TF-A upstream code.
+
+Only in the following 2 cases do we expect this vulnerability to be triggerable
+prior to authentication:
+
+ - The platform uses a custom chain of trust which uses the non-volatile counter
+   authentication method (``AUTH_METHOD_NV_CTR``) before the cryptographic
+   authentication method (``AUTH_METHOD_SIG``).
+
+ - The chain of trust uses a custom authentication method that calls
+   ``get_ext()`` before cryptographic authentication.
+
+Custom Image Parsers
+~~~~~~~~~~~~~~~~~~~~
+
+If the platform uses a custom image parser instead of the certificate parser,
+the bug in the certificate parser is obviously not relevant.  The bug in
+``auth_nvctr()`` *may* be relevant, but only if the returned data is:
+
+- Taken from an untrusted source (meaning that it is read prior to
+  authentication).
+
+- Not already checked to be a primitively-encoded ASN.1 tag.
+
+In particular, if the custom image parser implementation wraps a 32-bit integer
+in an ASN.1 ``INTEGER``, it is not affected.
+
+.. _CVE-2022-47630: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-47630
+.. _fd37982a19a4a291: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=fd37982a19a4a291
+.. _72460f50e2437a85: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=72460f50e2437a85
+.. _f5c51855d36e399e: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=f5c51855d36e399e
+.. _abb8f936fd0ad085: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=abb8f936fd0ad085
+.. _RFC 5280: https://www.ietf.org/rfc/rfc5280.txt
+.. _ITU-T X.690: https://www.itu.int/ITU-T/studygroups/com10/languages/X.690_1297.pdf
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 99bbb3a..940cad5 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -918,9 +918,54 @@
 | Mitigations            | | Yes / Platform specific                           |
 +------------------------+-----------------------------------------------------+
 
++------------------------+-----------------------------------------------------+
+| ID                     | 14                                                  |
++========================+=====================================================+
+| Threat                 | | **Attacker wants to execute an arbitrary or       |
+|                        |   untrusted binary as the secure OS.**              |
+|                        |                                                     |
+|                        | | When the option OPTEE_ALLOW_SMC_LOAD is enabled,  |
+|                        |   this trusts the non-secure world up until the     |
+|                        |   point it issues the SMC call to load the Secure   |
+|                        |   BL32 payload. If a compromise occurs before the   |
+|                        |   SMC call is invoked, then arbitrary code execution|
+|                        |   in S-EL1 can occur or arbitrary memory in EL3 can |
+|                        |   be overwritten.                                   |
++------------------------+-----------------------------------------------------+
+| Diagram Elements       | DF5                                                 |
++------------------------+-----------------------------------------------------+
+| Affected TF-A          | BL31, BL32                                          |
+| Components             |                                                     |
++------------------------+-----------------------------------------------------+
+| Assets                 | Code Execution, Sensitive Data                      |
++------------------------+-----------------------------------------------------+
+| Threat Agent           | NSCode                                              |
++------------------------+-----------------------------------------------------+
+| Threat Type            | Tampering, Information Disclosure,                  |
+|                        | Elevation of privilege                              |
++------------------------+-----------------+-----------------+-----------------+
+| Application            | Server          | IoT             | Mobile          |
++------------------------+-----------------+-----------------+-----------------+
+| Impact                 | Critical (5)    | Critical (5)    | Critical (5)    |
++------------------------+-----------------+-----------------+-----------------+
+| Likelihood             | High (4)        | High (4)        | High (4)        |
++------------------------+-----------------+-----------------+-----------------+
+| Total Risk Rating      | Critical (20)   | Critical (20)   | Critical (20)   |
++------------------------+-----------------+-----------------+-----------------+
+| Mitigations            | When enabling the option OPTEE_ALLOW_SMC_LOAD,      |
+|                        | the non-secure OS must be considered a closed       |
+|                        | platform up until the point the SMC can be invoked  |
+|                        | to load OP-TEE.                                     |
++------------------------+-----------------------------------------------------+
+| Mitigations            | | None in TF-A itself. This option is only used by  |
+| implemented?           |   ChromeOS currently which has other mechanisms to  |
+|                        |   to mitigate this threat which are described in    |
+|                        |   `OP-TEE Dispatcher`_.                             |
++------------------------+-----------------------------------------------------+
+
 --------------
 
-*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 
 .. _STRIDE threat analysis technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
@@ -932,3 +977,4 @@
 .. _TF-A error handling policy: https://trustedfirmware-a.readthedocs.io/en/latest/process/coding-guidelines.html#error-handling-and-robustness
 .. _Secure Development Guidelines: https://trustedfirmware-a.readthedocs.io/en/latest/process/security-hardening.html#secure-development-guidelines
 .. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
+.. _OP-TEE Dispatcher: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/spd/optee-dispatcher.rst
diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
index f1250b0..79f9089 100644
--- a/drivers/allwinner/axp/common.c
+++ b/drivers/allwinner/axp/common.c
@@ -9,6 +9,7 @@
 #include <libfdt.h>
 
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/allwinner/axp.h>
 
 int axp_check_id(void)
@@ -97,19 +98,9 @@
 	return 0;
 }
 
-static bool is_node_disabled(const void *fdt, int node)
-{
-	const char *cell;
-	cell = fdt_getprop(fdt, node, "status", NULL);
-	if (cell == NULL) {
-		return false;
-	}
-	return strcmp(cell, "okay") != 0;
-}
-
 static bool should_enable_regulator(const void *fdt, int node)
 {
-	if (is_node_disabled(fdt, node)) {
+	if (!fdt_node_is_enabled(fdt, node)) {
 		return false;
 	}
 	if (fdt_getprop(fdt, node, "phandle", NULL) != NULL) {
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index fa9509a..1bf03d4 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -243,7 +243,7 @@
 		      unsigned int *cert_nv_ctr,
 		      bool *need_nv_ctr_upgrade)
 {
-	char *p;
+	unsigned char *p;
 	void *data_ptr = NULL;
 	unsigned int data_len, len, i;
 	unsigned int plat_nv_ctr;
@@ -258,16 +258,24 @@
 
 	/* Parse the DER encoded integer */
 	assert(data_ptr);
-	p = (char *)data_ptr;
-	if (*p != ASN1_INTEGER) {
+	p = (unsigned char *)data_ptr;
+
+	/*
+	 * Integers must be at least 3 bytes: 1 for tag, 1 for length, and 1
+	 * for value.  The first byte (tag) must be ASN1_INTEGER.
+	 */
+	if ((data_len < 3) || (*p != ASN1_INTEGER)) {
 		/* Invalid ASN.1 integer */
 		return 1;
 	}
 	p++;
 
-	/* NV-counters are unsigned integers up to 32-bit */
-	len = (unsigned int)(*p & 0x7f);
-	if ((*p & 0x80) || (len > 4)) {
+	/*
+	 * NV-counters are unsigned integers up to 31 bits.  Trailing
+	 * padding is not allowed.
+	 */
+	len = (unsigned int)*p;
+	if ((len > 4) || (data_len - 2 != len)) {
 		return 1;
 	}
 	p++;
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index d231179..42a0925 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -115,7 +115,7 @@
 	end = (unsigned char *)(p + sig_len);
 	signature.tag = *p;
 	rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len);
-	if (rc != 0) {
+	if ((rc != 0) || ((size_t)(end - p) != signature.len)) {
 		rc = CRYPTO_ERR_SIGNATURE;
 		goto end1;
 	}
@@ -170,12 +170,15 @@
 	size_t len;
 	int rc;
 
-	/* Digest info should be an MBEDTLS_ASN1_SEQUENCE */
+	/*
+	 * Digest info should be an MBEDTLS_ASN1_SEQUENCE
+	 * and consume all bytes.
+	 */
 	p = (unsigned char *)digest_info_ptr;
 	end = p + digest_info_len;
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0) {
+	if (rc != 0 || ((size_t)(end - p) != len)) {
 		return CRYPTO_ERR_HASH;
 	}
 
@@ -195,9 +198,9 @@
 		return CRYPTO_ERR_HASH;
 	}
 
-	/* Hash should be octet string type */
+	/* Hash should be octet string type and consume all bytes */
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
-	if (rc != 0) {
+	if ((rc != 0) || ((size_t)(end - p) != len)) {
 		return CRYPTO_ERR_HASH;
 	}
 
diff --git a/drivers/auth/mbedtls/mbedtls_x509_parser.c b/drivers/auth/mbedtls/mbedtls_x509_parser.c
index 993ef12..bbabd9b 100644
--- a/drivers/auth/mbedtls/mbedtls_x509_parser.c
+++ b/drivers/auth/mbedtls/mbedtls_x509_parser.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -85,9 +85,6 @@
 	p = v3_ext.p;
 	end = v3_ext.p + v3_ext.len;
 
-	mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
-			     MBEDTLS_ASN1_SEQUENCE);
-
 	while (p < end) {
 		zeromem(&extn_oid, sizeof(extn_oid));
 		is_critical = 0; /* DEFAULT FALSE */
@@ -144,8 +141,23 @@
 {
 	int ret, is_critical;
 	size_t len;
-	unsigned char *p, *end, *crt_end;
-	mbedtls_asn1_buf sig_alg1, sig_alg2;
+	unsigned char *p, *end, *crt_end, *pk_end;
+	mbedtls_asn1_buf sig_alg1;
+	/*
+	 * The unique ASN.1 DER encoding of [0] EXPLICIT INTEGER { v3(2} }.
+	 */
+	static const char v3[] = {
+		/* The outer CONTEXT SPECIFIC 0 tag */
+		MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0,
+		/* The number bytes used to encode the inner INTEGER */
+		3,
+		/* The tag of the inner INTEGER */
+		MBEDTLS_ASN1_INTEGER,
+		/* The number of bytes needed to represent 2 */
+		1,
+		/* The actual value 2 */
+		2,
+	};
 
 	p = (unsigned char *)img;
 	len = img_len;
@@ -163,7 +175,7 @@
 		return IMG_PARSER_ERR_FORMAT;
 	}
 
-	if (len > (size_t)(end - p)) {
+	if (len != (size_t)(end - p)) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
 	crt_end = p + len;
@@ -181,15 +193,14 @@
 	tbs.len = end - tbs.p;
 
 	/*
-	 * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+	 * Version  ::=  [0] EXPLICIT INTEGER {  v1(0), v2(1), v3(2)  }
+	 * -- only v3 accepted
 	 */
-	ret = mbedtls_asn1_get_tag(&p, end, &len,
-				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
-				   MBEDTLS_ASN1_CONSTRUCTED | 0);
-	if (ret != 0) {
+	if (((end - p) <= (ptrdiff_t)sizeof(v3)) ||
+	    (memcmp(p, v3, sizeof(v3)) != 0)) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	p += len;
+	p += sizeof(v3);
 
 	/*
 	 * CertificateSerialNumber  ::=  INTEGER
@@ -257,9 +268,24 @@
 	if (ret != 0) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
+	pk_end = p + len;
+	pk.len = pk_end - pk.p;
+
+	/* algorithm */
+	ret = mbedtls_asn1_get_tag(&p, pk_end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+				   MBEDTLS_ASN1_SEQUENCE);
+	if (ret != 0) {
+		return IMG_PARSER_ERR_FORMAT;
+	}
-	pk.len = (p + len) - pk.p;
 	p += len;
 
+	/* Key is a BIT STRING and must use all bytes in SubjectPublicKeyInfo */
+	ret = mbedtls_asn1_get_bitstring_null(&p, pk_end, &len);
+	if ((ret != 0) || (p + len != pk_end)) {
+		return IMG_PARSER_ERR_FORMAT;
+	}
+	p = pk_end;
+
 	/*
 	 * issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
 	 */
@@ -290,57 +316,79 @@
 
 	/*
 	 * extensions      [3]  EXPLICIT Extensions OPTIONAL
+	 * }
+	 *
+	 * X.509 and RFC5280 allow omitting the extensions entirely.
+	 * However, in TF-A, a certificate with no extensions would
+	 * always fail later on, as the extensions contain the
+	 * information needed to authenticate the next stage in the
+	 * boot chain.  Furthermore, get_ext() assumes that the
+	 * extensions have been parsed into v3_ext, and allowing
+	 * there to be no extensions would pointlessly complicate
+	 * the code.  Therefore, just reject certificates without
+	 * extensions.  This is also why version 1 and 2 certificates
+	 * are rejected above.
 	 */
 	ret = mbedtls_asn1_get_tag(&p, end, &len,
 				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
 				   MBEDTLS_ASN1_CONSTRUCTED | 3);
-	if (ret != 0) {
+	if ((ret != 0) || (len != (size_t)(end - p))) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
 
 	/*
 	 * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+	 * -- must use all remaining bytes in TBSCertificate
 	 */
-	v3_ext.p = p;
 	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				   MBEDTLS_ASN1_SEQUENCE);
-	if (ret != 0) {
+	if ((ret != 0) || (len != (size_t)(end - p))) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	v3_ext.len = (p + len) - v3_ext.p;
+	v3_ext.p = p;
+	v3_ext.len = len;
 
 	/*
-	 * Check extensions integrity
+	 * Check extensions integrity.  At least one extension is
+	 * required: the ASN.1 specifies a minimum size of 1, and at
+	 * least one extension is needed to authenticate the next stage
+	 * in the boot chain.
 	 */
-	while (p < end) {
+	do {
+		unsigned char *end_ext_data;
+
 		ret = mbedtls_asn1_get_tag(&p, end, &len,
 					   MBEDTLS_ASN1_CONSTRUCTED |
 					   MBEDTLS_ASN1_SEQUENCE);
 		if (ret != 0) {
 			return IMG_PARSER_ERR_FORMAT;
 		}
+		end_ext_data = p + len;
 
 		/* Get extension ID */
-		ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID);
+		ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len, MBEDTLS_ASN1_OID);
 		if (ret != 0) {
 			return IMG_PARSER_ERR_FORMAT;
 		}
 		p += len;
 
 		/* Get optional critical */
-		ret = mbedtls_asn1_get_bool(&p, end, &is_critical);
+		ret = mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical);
 		if ((ret != 0) && (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
 			return IMG_PARSER_ERR_FORMAT;
 		}
 
-		/* Data should be octet string type */
-		ret = mbedtls_asn1_get_tag(&p, end, &len,
+		/*
+		 * Data should be octet string type and must use all bytes in
+		 * the Extension.
+		 */
+		ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len,
 					   MBEDTLS_ASN1_OCTET_STRING);
-		if (ret != 0) {
+		if ((ret != 0) || ((p + len) != end_ext_data)) {
 			return IMG_PARSER_ERR_FORMAT;
 		}
-		p += len;
-	}
+		p = end_ext_data;
+	} while (p < end);
 
 	if (p != end) {
 		return IMG_PARSER_ERR_FORMAT;
@@ -353,33 +401,22 @@
 	 *  -- end of TBSCertificate
 	 *
 	 *  signatureAlgorithm   AlgorithmIdentifier
+	 *  -- Does not need to be parsed.  Ensuring it is bitwise
+	 *  -- identical (including the tag!) with the first signature
+	 *  -- algorithm is sufficient.
 	 */
-	sig_alg2.p = p;
-	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
-				   MBEDTLS_ASN1_SEQUENCE);
-	if (ret != 0) {
+	if ((sig_alg1.len >= (size_t)(end - p)) ||
+	    (0 != memcmp(sig_alg1.p, p, sig_alg1.len))) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	if ((end - p) < 1) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
-	sig_alg2.len = (p + len) - sig_alg2.p;
-	p += len;
-
-	/* Compare both signature algorithms */
-	if (sig_alg1.len != sig_alg2.len) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
-	if (0 != memcmp(sig_alg1.p, sig_alg2.p, sig_alg1.len)) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
+	p += sig_alg1.len;
 	memcpy(&sig_alg, &sig_alg1, sizeof(sig_alg));
 
 	/*
 	 * signatureValue       BIT STRING
 	 */
 	signature.p = p;
-	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_BIT_STRING);
+	ret = mbedtls_asn1_get_bitstring_null(&p, end, &len);
 	if (ret != 0) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
@@ -447,7 +484,7 @@
 		rc = get_ext(type_desc->cookie, param, param_len);
 		break;
 	case AUTH_PARAM_PUB_KEY:
-		if (type_desc->cookie != 0) {
+		if (type_desc->cookie != NULL) {
 			/* Get public key from extension */
 			rc = get_ext(type_desc->cookie, param, param_len);
 		} else {
diff --git a/drivers/brcm/emmc/emmc_csl_sdcard.c b/drivers/brcm/emmc/emmc_csl_sdcard.c
index 9e2c618..40bc4a0 100644
--- a/drivers/brcm/emmc/emmc_csl_sdcard.c
+++ b/drivers/brcm/emmc/emmc_csl_sdcard.c
@@ -479,10 +479,11 @@
 			handle->device->cfg.blockSize = 512;
 		}
 
-		if (handle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
+		if (handle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
 			EMMC_TRACE("Sector addressing\n");
-		else
+		} else {
 			EMMC_TRACE("Byte addressing\n");
+		}
 
 		EMMC_TRACE("Ext_CSD_storage[162]: 0x%02X  Ext_CSD_storage[179]: 0x%02X\n",
 			   emmc_global_buf_ptr->u.Ext_CSD_storage[162],
diff --git a/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c b/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
index 68f93e7..fcd499f 100644
--- a/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
+++ b/drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
@@ -278,8 +278,9 @@
 
 	SDIO_base = EMMC_CTRL_REGS_BASE_ADDR;
 
-	if (SDIO_base == SDIO0_EMMCSDXC_SYSADDR)
+	if (SDIO_base == SDIO0_EMMCSDXC_SYSADDR) {
 		EMMC_TRACE(" ---> for SDIO 0 Controller\n\n");
+	}
 
 	memset(p_sdhandle, 0, sizeof(struct sd_handle));
 
@@ -290,8 +291,9 @@
 	memset(p_sdhandle->card, 0, sizeof(struct sd_card_info));
 
 	if (chal_sd_start((CHAL_HANDLE *) p_sdhandle->device,
-			  SD_PIO_MODE, SDIO_base, SDIO_base) != SD_OK)
+			  SD_PIO_MODE, SDIO_base, SDIO_base) != SD_OK) {
 		return NULL;
+	}
 
 	set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, SD_DMA_OFF,
 		   SD_DMA_BOUNDARY_4K, EMMC_BLOCK_SIZE, EMMC_WFE_RETRY);
@@ -330,14 +332,16 @@
 	VERBOSE("EMMC READ: dst=0x%lx, src=0x%lx, size=0x%lx\n",
 			storage_addr, mem_addr, bytes_to_read);
 
-	if (storage_size < bytes_to_read)
+	if (storage_size < bytes_to_read) {
 		/* Don't have sufficient storage to complete the operation */
 		return 0;
+	}
 
 	/* Range check non high capacity memory */
 	if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) {
-		if (mem_addr > 0x80000000)
+		if (mem_addr > 0x80000000) {
 			return 0;
+		}
 	}
 
 	/* High capacity card use block address mode */
@@ -384,10 +388,11 @@
 			/* Update Physical address */
 			outputBuf += manual_copy_size;
 
-			if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
+			if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
 				blockAddr++;
-			else
+			} else {
 				blockAddr += blockSize;
+			}
 		} else {
 			return 0;
 		}
@@ -395,10 +400,11 @@
 
 	while (remSize >= blockSize) {
 
-		if (remSize >= SD_MAX_BLK_TRANSFER_LENGTH)
+		if (remSize >= SD_MAX_BLK_TRANSFER_LENGTH) {
 			readLen = SD_MAX_BLK_TRANSFER_LENGTH;
-		else
+		} else {
 			readLen = (remSize / blockSize) * blockSize;
+		}
 
 		/* Check for overflow */
 		if ((rdCount + readLen) > storage_size ||
@@ -409,10 +415,11 @@
 		}
 
 		if (!read_block(p_sdhandle, outputBuf, blockAddr, readLen)) {
-			if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
+			if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
 				blockAddr += (readLen / blockSize);
-			else
+			} else {
 				blockAddr += readLen;
+			}
 
 			remSize -= readLen;
 			rdCount += readLen;
@@ -463,8 +470,9 @@
 
 	/* range check non high capacity memory */
 	if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) {
-		if (mem_addr > 0x80000000)
+		if (mem_addr > 0x80000000) {
 			return 0;
+		}
 	}
 
 	/* the high capacity card use block address mode */
@@ -491,11 +499,12 @@
 				blockAddr, p_sdhandle->device->cfg.blockSize)) {
 
 			if (remSize <
-			    (p_sdhandle->device->cfg.blockSize - offset))
+			    (p_sdhandle->device->cfg.blockSize - offset)) {
 				manual_copy_size = remSize;
-			else
+			} else {
 				manual_copy_size =
 				    p_sdhandle->device->cfg.blockSize - offset;
+			}
 
 			memcpy((void *)((uintptr_t)
 				(emmc_global_buf_ptr->u.tempbuf + offset)),
@@ -530,11 +539,12 @@
 				inputBuf += manual_copy_size;
 
 				if (p_sdhandle->device->ctrl.ocr &
-				    SD_CARD_HIGH_CAPACITY)
+				    SD_CARD_HIGH_CAPACITY) {
 					blockAddr++;
-				else
+				} else {
 					blockAddr +=
 					    p_sdhandle->device->cfg.blockSize;
+				}
 			} else
 				return 0;
 		} else {
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index e3fb749..93c38d8 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
 #include <drivers/console.h>
 
 console_t *console_list;
-uint8_t console_state = CONSOLE_FLAG_BOOT;
+static uint8_t console_state = CONSOLE_FLAG_BOOT;
 
 IMPORT_SYM(console_t *, __STACKS_START__, stacks_start)
 IMPORT_SYM(console_t *, __STACKS_END__, stacks_end)
diff --git a/drivers/imx/usdhc/imx_usdhc.c b/drivers/imx/usdhc/imx_usdhc.c
index 07f55b7..49dfc07 100644
--- a/drivers/imx/usdhc/imx_usdhc.c
+++ b/drivers/imx/usdhc/imx_usdhc.c
@@ -136,7 +136,8 @@
 		break;
 	case MMC_CMD(18):
 		multiple = 1;
-		/* fall thru for read op */
+		/* for read op */
+		/* fallthrough */
 	case MMC_CMD(17):
 	case MMC_CMD(8):
 		mixctl |= MIXCTRL_DTDSEL;
@@ -144,7 +145,8 @@
 		break;
 	case MMC_CMD(25):
 		multiple = 1;
-		/* fall thru for data op flag */
+		/* for data op flag */
+		/* fallthrough */
 	case MMC_CMD(24):
 		data = 1;
 		break;
diff --git a/drivers/io/io_block.c b/drivers/io/io_block.c
index 5d45c2f..b5e0e5f 100644
--- a/drivers/io/io_block.c
+++ b/drivers/io/io_block.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -271,7 +271,7 @@
 	block_size = cur->dev_spec->block_size;
 	assert((length <= cur->size) &&
 	       (length > 0U) &&
-	       (ops->read != 0));
+	       (ops->read != NULL));
 
 	/*
 	 * We don't know the number of bytes that we are going
@@ -383,8 +383,8 @@
 	block_size = cur->dev_spec->block_size;
 	assert((length <= cur->size) &&
 	       (length > 0U) &&
-	       (ops->read != 0) &&
-	       (ops->write != 0));
+	       (ops->read != NULL) &&
+	       (ops->write != NULL));
 
 	/*
 	 * We don't know the number of bytes that we are going
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 8e83464..2b727d4 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -69,8 +69,7 @@
 		int i;
 
 		for (i = 0; i < 4; i++) {
-			*r_data = cmd.resp_data[i];
-			r_data++;
+			r_data[i] = cmd.resp_data[i];
 		}
 	}
 
@@ -112,7 +111,7 @@
 	return MMC_GET_STATE(resp_data[0]);
 }
 
-static int mmc_send_part_switch_cmd(unsigned int part_config)
+static int mmc_send_part_switch_cmd(unsigned char part_config)
 {
 	int ret;
 	unsigned int part_time = 0;
@@ -760,9 +759,9 @@
 	return size;
 }
 
-static int mmc_part_switch(unsigned int part_type)
+static int mmc_part_switch(unsigned char part_type)
 {
-	uint8_t part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG];
+	unsigned char part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG];
 
 	part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
 	part_config |= part_type;
@@ -780,8 +779,7 @@
 	unsigned char current_boot_part = mmc_current_boot_part();
 	int ret;
 
-	if (current_boot_part != 1U &&
-	    current_boot_part != 2U) {
+	if ((current_boot_part != 1U) && (current_boot_part != 2U)) {
 		ERROR("Got unexpected value for active boot partition, %u\n", current_boot_part);
 		return -EIO;
 	}
diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.c b/drivers/nxp/ddr/nxp-ddr/ddr.c
index c051b3b..faf20e9 100644
--- a/drivers/nxp/ddr/nxp-ddr/ddr.c
+++ b/drivers/nxp/ddr/nxp-ddr/ddr.c
@@ -269,7 +269,7 @@
 	unsigned int i;
 	const struct dynamic_odt *pdodt = NULL;
 
-	const static struct dynamic_odt *table[2][5] = {
+	static const struct dynamic_odt *table[2][5] = {
 		{single_S, single_D, NULL, NULL},
 		{dual_SS, dual_DD, NULL, NULL},
 	};
diff --git a/drivers/nxp/ddr/phy-gen2/messages.h b/drivers/nxp/ddr/phy-gen2/messages.h
index 7dec7df..a2310f2 100644
--- a/drivers/nxp/ddr/phy-gen2/messages.h
+++ b/drivers/nxp/ddr/phy-gen2/messages.h
@@ -13,7 +13,7 @@
 	const char *msg;
 };
 
-const static struct phy_msg messages_1d[] = {
+static const struct phy_msg messages_1d[] = {
 	{0x00000001,
 	 "PMU1:prbsGenCtl:%x\n"
 	},
@@ -1239,7 +1239,7 @@
 	},
 };
 
-const static struct phy_msg messages_2d[] = {
+static const struct phy_msg messages_2d[] = {
 	{0x00000001,
 	 "PMU0: Converting %d into an MR\n"
 	},
diff --git a/drivers/partition/gpt.c b/drivers/partition/gpt.c
index 4fe8322..8b1046d 100644
--- a/drivers/partition/gpt.c
+++ b/drivers/partition/gpt.c
@@ -26,14 +26,16 @@
 
 	/* check whether the unicode string is valid */
 	for (i = 1; i < (EFI_NAMELEN << 1); i += 2) {
-		if (name[i] != '\0')
+		if (name[i] != '\0') {
 			return -EINVAL;
+		}
 	}
 	/* convert the unicode string to ascii string */
 	for (i = 0; i < (EFI_NAMELEN << 1); i += 2) {
 		str_out[i >> 1] = name[i];
-		if (name[i] == '\0')
+		if (name[i] == '\0') {
 			break;
+		}
 	}
 	return 0;
 }
diff --git a/drivers/renesas/common/emmc/emmc_cmd.c b/drivers/renesas/common/emmc/emmc_cmd.c
index d255bff..02fc26b 100644
--- a/drivers/renesas/common/emmc/emmc_cmd.c
+++ b/drivers/renesas/common/emmc/emmc_cmd.c
@@ -254,8 +254,7 @@
 				(SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
 
 			state = ESTATE_ISSUE_CMD;
-			/* through */
-
+			/* fallthrough */
 		case ESTATE_ISSUE_CMD:
 			/* ARG */
 			SETR_32(SD_ARG, mmc_drv_obj.cmd_info.arg);
@@ -454,8 +453,8 @@
 				SETR_32(SD_STOP, 0x00000000U);
 				mmc_drv_obj.during_dma_transfer = FALSE;
 			}
-			/* through */
 
+			/* fallthrough */
 		case ESTATE_ERROR:
 			if (err_not_care_flag == TRUE) {
 				mmc_drv_obj.during_cmd_processing = FALSE;
diff --git a/drivers/renesas/common/rom/rom_api.c b/drivers/renesas/common/rom/rom_api.c
index fda2815..4eede17 100644
--- a/drivers/renesas/common/rom/rom_api.c
+++ b/drivers/renesas/common/rom/rom_api.c
@@ -11,7 +11,7 @@
 #include "rcar_def.h"
 #include "rom_api.h"
 
-typedef uint32_t(*rom_secure_boot_api_f) (uint32_t *key, uint32_t *cert,
+typedef uint32_t(*rom_secure_boot_api_f) (uint32_t key, uint32_t cert,
 					  rom_read_flash_f pFuncReadFlash);
 
 typedef uint32_t(*rom_get_lcs_api_f) (uint32_t *lcs);
@@ -68,7 +68,7 @@
 	return index;
 }
 
-uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert,
+uint32_t rcar_rom_secure_boot_api(uint32_t key, uint32_t cert,
 			     rom_read_flash_f read_flash)
 {
 	static const uintptr_t rom_api_table[API_TABLE_MAX] = {
diff --git a/drivers/renesas/common/rom/rom_api.h b/drivers/renesas/common/rom/rom_api.h
index 1d5b03d..4b10080 100644
--- a/drivers/renesas/common/rom/rom_api.h
+++ b/drivers/renesas/common/rom/rom_api.h
@@ -24,7 +24,7 @@
 #define LCS_FA					(0x7U)
 
 typedef uint32_t(*rom_read_flash_f) (uint64_t src, uint8_t *dst, uint32_t len);
-uint32_t rcar_rom_secure_boot_api(uint32_t *key, uint32_t *cert,
+uint32_t rcar_rom_secure_boot_api(uint32_t key, uint32_t cert,
 				  rom_read_flash_f f);
 uint32_t rcar_rom_get_lcs(uint32_t *lcs);
 
diff --git a/drivers/st/crypto/stm32_pka.c b/drivers/st/crypto/stm32_pka.c
index e03cf0f..2bbb31d 100644
--- a/drivers/st/crypto/stm32_pka.c
+++ b/drivers/st/crypto/stm32_pka.c
@@ -254,13 +254,6 @@
 
 static struct stm32_pka_platdata pka_pdata;
 
-#pragma weak stm32_pka_get_platdata
-
-int stm32_pka_get_platdata(struct stm32_pka_platdata *pdata)
-{
-	return -ENODEV;
-}
-
 static int stm32_pka_parse_fdt(void)
 {
 	int node;
@@ -583,10 +576,7 @@
 
 	err = stm32_pka_parse_fdt();
 	if (err != 0) {
-		err = stm32_pka_get_platdata(&pka_pdata);
-		if (err != 0) {
-			return err;
-		}
+		return err;
 	}
 
 	clk_enable(pka_pdata.clock_id);
diff --git a/drivers/st/crypto/stm32_saes.c b/drivers/st/crypto/stm32_saes.c
index 02baf21..f4da571 100644
--- a/drivers/st/crypto/stm32_saes.c
+++ b/drivers/st/crypto/stm32_saes.c
@@ -139,15 +139,8 @@
 #define SET_CHAINING_MODE(mod, cr) \
 	mmio_clrsetbits_32((cr), _SAES_CR_CHMOD_MASK, _SAES_CR_CHMOD_##mod << _SAES_CR_CHMOD_SHIFT)
 
-#define pragma weak stm32_saes_get_platdata
-
 static struct stm32_saes_platdata saes_pdata;
 
-int stm32_saes_get_platdata(struct stm32_saes_platdata *pdata)
-{
-	return -ENODEV;
-}
-
 static int stm32_saes_parse_fdt(struct stm32_saes_platdata *pdata)
 {
 	int node;
@@ -389,10 +382,7 @@
 
 	err = stm32_saes_parse_fdt(&saes_pdata);
 	if (err != 0) {
-		err = stm32_saes_get_platdata(&saes_pdata);
-		if (err != 0) {
-			return err;
-		}
+		return err;
 	}
 
 	clk_enable(saes_pdata.clock_id);
diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c
deleted file mode 100644
index 2bf88e6..0000000
--- a/drivers/st/io/io_mmc.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-
-#include <common/debug.h>
-#include <drivers/io/io_driver.h>
-#include <drivers/io/io_storage.h>
-#include <drivers/mmc.h>
-#include <drivers/st/io_mmc.h>
-#include <drivers/st/stm32_sdmmc2.h>
-
-/* SDMMC device functions */
-static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info);
-static int mmc_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
-			  io_entity_t *entity);
-static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
-static int mmc_block_seek(io_entity_t *entity, int mode,
-			  signed long long offset);
-static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
-			  size_t *length_read);
-static int mmc_block_close(io_entity_t *entity);
-static int mmc_dev_close(io_dev_info_t *dev_info);
-static io_type_t device_type_mmc(void);
-
-static signed long long seek_offset;
-static size_t (*_read_blocks)(int lba, uintptr_t buf, size_t size);
-
-static const io_dev_connector_t mmc_dev_connector = {
-	.dev_open = mmc_dev_open
-};
-
-static const io_dev_funcs_t mmc_dev_funcs = {
-	.type = device_type_mmc,
-	.open = mmc_block_open,
-	.seek = mmc_block_seek,
-	.size = NULL,
-	.read = mmc_block_read,
-	.write = NULL,
-	.close = mmc_block_close,
-	.dev_init = mmc_dev_init,
-	.dev_close = mmc_dev_close,
-};
-
-static const io_dev_info_t mmc_dev_info = {
-	.funcs = &mmc_dev_funcs,
-	.info = 0,
-};
-
-/* Identify the device type as mmc device */
-static io_type_t device_type_mmc(void)
-{
-	return IO_TYPE_MMC;
-}
-
-/* Open a connection to the mmc device */
-static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info)
-{
-	struct io_mmc_dev_spec *device_spec =
-		(struct io_mmc_dev_spec *)init_params;
-
-	assert(dev_info != NULL);
-	*dev_info = (io_dev_info_t *)&mmc_dev_info;
-
-	_read_blocks = !device_spec->use_boot_part ?
-		mmc_read_blocks : mmc_boot_part_read_blocks;
-
-	return 0;
-}
-
-static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params)
-{
-	return 0;
-}
-
-/* Close a connection to the mmc device */
-static int mmc_dev_close(io_dev_info_t *dev_info)
-{
-	return 0;
-}
-
-/* Open a file on the mmc device */
-static int mmc_block_open(io_dev_info_t *dev_info, const  uintptr_t spec,
-			  io_entity_t *entity)
-{
-	seek_offset = 0;
-	return 0;
-}
-
-/* Seek to a particular file offset on the mmc device */
-static int mmc_block_seek(io_entity_t *entity, int mode,
-			  signed long long offset)
-{
-	seek_offset = offset;
-	return 0;
-}
-
-/* Read data from a file on the mmc device */
-static int mmc_block_read(io_entity_t *entity, uintptr_t buffer,
-			  size_t length, size_t *length_read)
-{
-	uint8_t retries;
-
-	for (retries = 0U; retries < 3U; retries++) {
-		*length_read = _read_blocks(seek_offset / MMC_BLOCK_SIZE,
-					    buffer, length);
-
-		if (*length_read == length) {
-			return 0;
-		}
-		WARN("%s: length_read = %lu (!= %lu), retry %u\n", __func__,
-		     (unsigned long)*length_read, (unsigned long)length,
-		     retries + 1U);
-	}
-
-	return -EIO;
-}
-
-/* Close a file on the mmc device */
-static int mmc_block_close(io_entity_t *entity)
-{
-	return 0;
-}
-
-/* Register the mmc driver with the IO abstraction */
-int register_io_dev_mmc(const io_dev_connector_t **dev_con)
-{
-	int result;
-
-	assert(dev_con != NULL);
-
-	result = io_register_device(&mmc_dev_info);
-	if (result == 0) {
-		*dev_con = &mmc_dev_connector;
-	}
-
-	return result;
-}
diff --git a/drivers/st/usb/stm32mp1_usb.c b/drivers/st/usb/stm32mp1_usb.c
index 9a49690..78890f5 100644
--- a/drivers/st/usb/stm32mp1_usb.c
+++ b/drivers/st/usb/stm32mp1_usb.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <stdint.h>
 
 #include <arch_helpers.h>
@@ -794,7 +795,7 @@
 	uint32_t epint;
 	uint32_t epnum;
 	uint32_t temp;
-	enum usb_status ret;
+	enum usb_status __unused ret;
 
 	if (usb_dwc2_get_mode(handle) != USB_OTG_MODE_DEVICE) {
 		return USB_NOTHING;
@@ -947,9 +948,7 @@
 
 		/* Setup EP0 to receive SETUP packets */
 		ret = usb_dwc2_ep0_out_start(handle);
-		if (ret != USBD_OK) {
-			return ret;
-		}
+		assert(ret == USBD_OK);
 
 		mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_USBRST);
 
@@ -959,9 +958,7 @@
 	/* Handle enumeration done interrupt */
 	if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_ENUMDNE) != 0U) {
 		ret = usb_dwc2_activate_setup(handle);
-		if (ret != USBD_OK) {
-			return ret;
-		}
+		assert(ret == USBD_OK);
 
 		mmio_clrbits_32(usb_base_addr + OTG_GUSBCFG, OTG_GUSBCFG_TRDT);
 
diff --git a/fdts/morello-soc.dts b/fdts/morello-soc.dts
index 5f147b7..e87b617 100644
--- a/fdts/morello-soc.dts
+++ b/fdts/morello-soc.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -213,6 +213,29 @@
 		clock-output-names = "aclk";
 	};
 
+	gpu@2d000000 {
+		compatible = "arm,mali-bifrost";
+		reg = <0x0 0x2d000000 0x0 0x4000>;
+		interrupts =
+			<GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names =
+			"gpu",
+			"job",
+			"mmu";
+		clocks = <&clk_gpu>;
+		clock-names = "clk_mali";
+		status = "okay";
+	};
+
+	clk_gpu: clk_gpu {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <650000000>;
+		clock-output-names = "clk_mali";
+	};
+
 	firmware {
 		scmi {
 			compatible = "arm,scmi";
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index a938edc..869b912 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -127,8 +127,8 @@
 			compatible = "st,stm32mp15-i2c";
 			reg = <0x40013000 0x400>;
 			interrupt-names = "event", "error";
-			interrupts = <&exti 22 IRQ_TYPE_LEVEL_HIGH>,
-				     <&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+			interrupts-extended = <&exti 22 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&rcc I2C2_K>;
 			resets = <&rcc I2C2_R>;
 			#address-cells = <1>;
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index d928563..63753bd 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -169,23 +169,12 @@
 
 			vbus_otg: pwr_sw1 {
 				regulator-name = "vbus_otg";
-			 };
+			};
 
-			 vbus_sw: pwr_sw2 {
+			vbus_sw: pwr_sw2 {
 				regulator-name = "vbus_sw";
 				regulator-active-discharge = <1>;
-			 };
-		};
-
-		onkey {
-			compatible = "st,stpmic1-onkey";
-			power-off-time-sec = <10>;
-			status = "okay";
-		};
-
-		watchdog {
-			compatible = "st,stpmic1-wdt";
-			status = "disabled";
+			};
 		};
 	};
 };
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 5a8792e..4f27589 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -213,9 +213,9 @@
 			linux,cma-default;
 		};
 
-		optee@0xfce00000 {
-			reg = <0x00000000 0xfce00000 0 0x00200000>;
-			no-map;
+		optee@0xf8e00000 {
+			compatible = "restricted-dma-pool";
+			reg = <0x00000000 0xf8e00000 0 0x00200000>;
 		};
 	};
 
@@ -456,24 +456,49 @@
 		clock-names = "mclk", "apb_pclk";
 	};
 
+	gpu_clk: gpu_clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000000>;
+	};
+
+	gpu_core_clk: gpu_core_clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000000>;
+	};
+
 	gpu: gpu@2d000000 {
 		compatible = "arm,mali-midgard";
 		reg = <0x0 0x2d000000 0x0 0x200000>;
 		interrupts = <0 66 4>, <0 67 4>, <0 65 4>;
 		interrupt-names = "JOB", "MMU", "GPU";
-		clocks = <&soc_refclk100mhz>;
-		clock-names = "clk_mali";
+		clocks = <&gpu_clk>, <&gpu_core_clk>;
+		clock-names = "clk_mali", "shadercores";
+		iommus = <&smmu_700 0x200>;
 		operating-points = <
 			/* KHz uV */
 			50000 820000
 		>;
 	};
 
+	power_model@simple {
+		/*
+		 * Numbers used are irrelevant to Titan,
+		 * it helps suppressing the kernel warnings.
+		 */
+		compatible = "arm,mali-simple-power-model";
+		static-coefficient = <2427750>;
+		dynamic-coefficient = <4687>;
+		ts = <20000 2000 (-20) 2>;
+		thermal-zone = "";
+	};
+
-	smmu: smmu@2ce00000 {
+	smmu_700: smmu_700@3f000000 {
 		#iommu-cells = <1>;
 		compatible = "arm,smmu-v3";
-		reg = <0x0 0x2ce00000 0x0 0x20000>;
-		status = "okay";
+		reg = <0x0 0x3f000000 0x0 0x5000000>;
+		dma-coherent;
 	};
 
 	dp0: display@2cc00000 {
@@ -485,9 +510,7 @@
 		interrupt-names = "DPU";
 		clocks = <&scmi_clk 0>;
 		clock-names = "aclk";
-		iommus = <&smmu 0>, <&smmu 1>, <&smmu 2>, <&smmu 3>,
-			<&smmu 4>, <&smmu 5>, <&smmu 6>, <&smmu 7>,
-			<&smmu 8>, <&smmu 9>;
+		iommus = <&smmu_700 0x100>;
 		pl0: pipeline@0 {
 			reg = <0>;
 			clocks = <&scmi_clk 1>;
@@ -520,6 +543,15 @@
 		};
 	};
 
+	/*
+	 * L3 cache in the DSU is the Memory System Component (MSC)
+	 * The MPAM registers are accessed through utility bus in the DSU
+	 */
+	msc0 {
+		compatible = "arm,mpam-msc";
+		reg = <0x1 0x00010000 0x0 0x2000>;
+	};
+
 	ete0 {
 		compatible = "arm,embedded-trace-extension";
 		cpu = <&CPU0>;
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index f63e923..9e4a3b7 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -1063,13 +1063,17 @@
 #define PMBLIMITR_EL1		S3_0_C9_C10_0
 
 /*******************************************************************************
- * Definitions for system register interface to MPAM
+ * Definitions for system register interface, shifts and masks for MPAM
  ******************************************************************************/
 #define MPAMIDR_EL1		S3_0_C10_C4_4
 #define MPAM2_EL2		S3_4_C10_C5_0
 #define MPAMHCR_EL2		S3_4_C10_C4_0
 #define MPAM3_EL3		S3_6_C10_C5_0
 
+#define MPAMIDR_EL1_HAS_HCR_SHIFT	ULL(0x11)
+#define MPAMIDR_EL1_VPMR_MAX_SHIFT	ULL(0x12)
+#define MPAMIDR_EL1_VPMR_MAX_WIDTH	ULL(0x3)
+#define MPAMIDR_EL1_VPMR_MAX_POSSIBLE	ULL(0x7)
 /*******************************************************************************
  * Definitions for system register interface to AMU for FEAT_AMUv1
  ******************************************************************************/
@@ -1282,6 +1286,12 @@
 #define GCR_EL1			S3_0_C1_C0_6
 
 /*******************************************************************************
+ * Armv8.5 - Random Number Generator Registers
+ ******************************************************************************/
+#define RNDR			S3_3_C2_C4_0
+#define RNDRRS			S3_3_C2_C4_1
+
+/*******************************************************************************
  * FEAT_HCX - Extended Hypervisor Configuration Register
  ******************************************************************************/
 #define HCRX_EL2		S3_4_C1_C2_2
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 932e885..2b801ac 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -10,6 +10,7 @@
 #include <stdbool.h>
 
 #include <arch_helpers.h>
+#include <common/feat_detect.h>
 
 static inline bool is_armv7_gentimer_present(void)
 {
@@ -97,12 +98,25 @@
 		ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED);
 }
 
-static inline bool is_armv8_6_fgt_present(void)
+static unsigned int read_feat_fgt_id_field(void)
 {
-	return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) &
-		ID_AA64MMFR0_EL1_FGT_MASK) != 0U;
+	return (read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) &
+		ID_AA64MMFR0_EL1_FGT_MASK;
 }
 
+static inline bool is_feat_fgt_supported(void)
+{
+	if (ENABLE_FEAT_FGT == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_FGT == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_fgt_id_field() != 0U;
+}
+
 static inline unsigned long int get_armv8_6_ecv_support(void)
 {
 	return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_ECV_SHIFT) &
@@ -115,10 +129,31 @@
 		ID_AA64ISAR0_RNDR_MASK);
 }
 
+/*******************************************************************************
+ * Functions to identify the presence of the Activity Monitors Extension
+ ******************************************************************************/
+static unsigned int read_feat_amu_id_field(void)
+{
+	return (read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) &
+		ID_AA64PFR0_AMU_MASK;
+}
+
+static inline bool is_feat_amu_supported(void)
+{
+	if (ENABLE_FEAT_AMUv1 == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_AMUv1 == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1;
+}
+
 static inline bool is_armv8_6_feat_amuv1p1_present(void)
 {
-	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) &
-		ID_AA64PFR0_AMU_MASK) >= ID_AA64PFR0_AMU_V1P1);
+	return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1P1;
 }
 
 /*
@@ -138,10 +173,23 @@
 		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
 }
 
+static inline unsigned int read_feat_hcx_id_field(void)
+{
+	return (read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) &
+		ID_AA64MMFR1_EL1_HCX_MASK;
+}
+
-static inline bool is_feat_hcx_present(void)
+static inline bool is_feat_hcx_supported(void)
 {
-	return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) &
-		ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED);
+	if (ENABLE_FEAT_HCX == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_HCX == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_hcx_id_field() != 0U;
 }
 
 static inline bool is_feat_rng_trap_present(void)
@@ -226,16 +274,6 @@
 		ID_AA64DFR0_TRACEFILT_MASK) == ID_AA64DFR0_TRACEFILT_SUPPORTED);
 }
 
-/*******************************************************************************
- * Function to identify the presence of FEAT_AMUv1 (Activity Monitors-
- * Extension v1)
- ******************************************************************************/
-static inline bool is_armv8_4_feat_amuv1_present(void)
-{
-	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) &
-		ID_AA64PFR0_AMU_MASK) >= ID_AA64PFR0_AMU_V1);
-}
-
 /********************************************************************************
  * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
  * Support)
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 50a5ad4..86c1dbe 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -27,6 +27,14 @@
 	return v;						\
 }
 
+#define _DEFINE_SYSREG_READ_FUNC_NV(_name, _reg_name)		\
+static inline u_register_t read_ ## _name(void)			\
+{								\
+	u_register_t v;						\
+	__asm__ ("mrs %0, " #_reg_name : "=r" (v));		\
+	return v;						\
+}
+
 #define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)			\
 static inline void write_ ## _name(u_register_t v)			\
 {									\
@@ -58,6 +66,14 @@
 #define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name)	\
 	_DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)
 
+/* Define read function for ID register (w/o volatile qualifier) */
+#define DEFINE_IDREG_READ_FUNC(_name)			\
+	_DEFINE_SYSREG_READ_FUNC_NV(_name, _name)
+
+/* Define read function for renamed ID register (w/o volatile qualifier) */
+#define DEFINE_RENAME_IDREG_READ_FUNC(_name, _reg_name)	\
+	_DEFINE_SYSREG_READ_FUNC_NV(_name, _reg_name)
+
 /**********************************************************************
  * Macros to create inline functions for system instructions
  *********************************************************************/
@@ -247,14 +263,14 @@
 #define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
 
 DEFINE_SYSREG_RW_FUNCS(par_el1)
-DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
-DEFINE_SYSREG_READ_FUNC(id_aa64isar0_el1)
-DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
-DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1)
-DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
-DEFINE_SYSREG_READ_FUNC(id_aa64pfr1_el1)
-DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
-DEFINE_SYSREG_READ_FUNC(id_afr0_el1)
+DEFINE_IDREG_READ_FUNC(id_pfr1_el1)
+DEFINE_IDREG_READ_FUNC(id_aa64isar0_el1)
+DEFINE_IDREG_READ_FUNC(id_aa64isar1_el1)
+DEFINE_RENAME_IDREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1)
+DEFINE_IDREG_READ_FUNC(id_aa64pfr0_el1)
+DEFINE_IDREG_READ_FUNC(id_aa64pfr1_el1)
+DEFINE_IDREG_READ_FUNC(id_aa64dfr0_el1)
+DEFINE_IDREG_READ_FUNC(id_afr0_el1)
 DEFINE_SYSREG_READ_FUNC(CurrentEl)
 DEFINE_SYSREG_READ_FUNC(ctr_el0)
 DEFINE_SYSREG_RW_FUNCS(daif)
@@ -367,10 +383,10 @@
 /*******************************************************************************
  * System register accessor prototypes
  ******************************************************************************/
-DEFINE_SYSREG_READ_FUNC(midr_el1)
+DEFINE_IDREG_READ_FUNC(midr_el1)
 DEFINE_SYSREG_READ_FUNC(mpidr_el1)
-DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1)
-DEFINE_SYSREG_READ_FUNC(id_aa64mmfr1_el1)
+DEFINE_IDREG_READ_FUNC(id_aa64mmfr0_el1)
+DEFINE_IDREG_READ_FUNC(id_aa64mmfr1_el1)
 
 DEFINE_SYSREG_RW_FUNCS(scr_el3)
 DEFINE_SYSREG_RW_FUNCS(hcr_el2)
@@ -516,7 +532,7 @@
 DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3)
 DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el2, ZCR_EL2)
 
-DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64smfr0_el1, ID_AA64SMFR0_EL1)
+DEFINE_RENAME_IDREG_READ_FUNC(id_aa64smfr0_el1, ID_AA64SMFR0_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(smcr_el3, SMCR_EL3)
 
 DEFINE_RENAME_SYSREG_READ_FUNC(erridr_el1, ERRIDR_EL1)
@@ -530,7 +546,7 @@
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
 
 /* Armv8.2 Registers */
-DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
+DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
 
 /* Armv8.3 Pointer Authentication Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeyhi_el1, APIAKeyHi_EL1)
@@ -546,8 +562,16 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1)
 
 /* Armv8.5 FEAT_RNG Registers */
-DEFINE_SYSREG_READ_FUNC(rndr)
-DEFINE_SYSREG_READ_FUNC(rndrrs)
+DEFINE_RENAME_SYSREG_READ_FUNC(rndr, RNDR)
+DEFINE_RENAME_SYSREG_READ_FUNC(rndrrs, RNDRRS)
+
+/* Armv8.6 FEAT_FGT Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgrtr_el2, HDFGRTR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hafgrtr_el2, HAFGRTR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgwtr_el2, HDFGWTR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgitr_el2, HFGITR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgrtr_el2, HFGRTR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgwtr_el2, HFGWTR_EL2)
 
 /* FEAT_HCX Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)
diff --git a/include/arch/aarch64/el2_common_macros.S b/include/arch/aarch64/el2_common_macros.S
index 7bf4806..b3b85e6 100644
--- a/include/arch/aarch64/el2_common_macros.S
+++ b/include/arch/aarch64/el2_common_macros.S
@@ -384,13 +384,12 @@
 	.macro	apply_at_speculative_wa
 #if ERRATA_SPECULATIVE_AT
 	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching and also, save x29 which will be used in the called
-	 * function
+	 * This function expects x30 has been saved.
+	 * Also, save x29 which will be used in the called function.
 	 */
-	stp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	str	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
 	bl	save_and_update_ptw_el1_sys_regs
-	ldp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	ldr	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
 #endif
 	.endm
 
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index de2b931..40ff056 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -532,13 +532,12 @@
 	.macro	apply_at_speculative_wa
 #if ERRATA_SPECULATIVE_AT
 	/*
-	 * Explicitly save x30 so as to free up a register and to enable
-	 * branching and also, save x29 which will be used in the called
-	 * function
+	 * This function expects x30 has been saved.
+	 * Also, save x29 which will be used in the called function.
 	 */
-	stp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	str	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
 	bl	save_and_update_ptw_el1_sys_regs
-	ldp	x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	ldr	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
 #endif
 	.endm
 
diff --git a/include/arch/aarch64/smccc_helpers.h b/include/arch/aarch64/smccc_helpers.h
index 920f294..950a811 100644
--- a/include/arch/aarch64/smccc_helpers.h
+++ b/include/arch/aarch64/smccc_helpers.h
@@ -75,6 +75,24 @@
 #define SMC_SET_GP(_h, _g, _v)					\
 	write_ctx_reg((get_gpregs_ctx(_h)), (_g), (_v))
 
+
+/* Useful for SMCCCv1.2 */
+#define SMC_RET18(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6, _x7, _x8, _x9, \
+		_x10, _x11, _x12, _x13, _x14, _x15, _x16, _x17) {	\
+	SMC_SET_GP(_h, CTX_GPREG_X8, _x8);				\
+	SMC_SET_GP(_h, CTX_GPREG_X9, _x9);				\
+	SMC_SET_GP(_h, CTX_GPREG_X10, _x10);				\
+	SMC_SET_GP(_h, CTX_GPREG_X11, _x11);				\
+	SMC_SET_GP(_h, CTX_GPREG_X12, _x12);				\
+	SMC_SET_GP(_h, CTX_GPREG_X13, _x13);				\
+	SMC_SET_GP(_h, CTX_GPREG_X14, _x14);				\
+	SMC_SET_GP(_h, CTX_GPREG_X15, _x15);				\
+	SMC_SET_GP(_h, CTX_GPREG_X16, _x16);				\
+	SMC_SET_GP(_h, CTX_GPREG_X17, _x17);				\
+	SMC_RET8(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5), (_x6),	\
+		(_x7));							\
+}
+
 /*
  * Convenience macros to access EL3 context registers using handle provided to
  * SMC handler. These take the offset values defined in context.h
diff --git a/include/bl31/sync_handle.h b/include/bl31/sync_handle.h
new file mode 100644
index 0000000..e211575
--- /dev/null
+++ b/include/bl31/sync_handle.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRAP_HANDLE_H
+#define TRAP_HANDLE_H
+
+#include <stdbool.h>
+#include <context.h>
+
+#define ISS_SYSREG_OPCODE_MASK		0x3ffc1eUL
+#define ISS_SYSREG_REG_MASK		0x0003e0UL
+#define ISS_SYSREG_REG_SHIFT		5U
+#define ISS_SYSREG_DIRECTION_MASK	0x000001UL
+
+#define ISS_SYSREG_OPCODE_RNDR		0x30c808U
+#define ISS_SYSREG_OPCODE_RNDRRS	0x32c808U
+
+#define TRAP_RET_UNHANDLED		-1
+#define TRAP_RET_REPEAT			0
+#define TRAP_RET_CONTINUE		1
+
+#ifndef __ASSEMBLER__
+static inline unsigned int get_sysreg_iss_rt(uint64_t esr)
+{
+	return (esr & ISS_SYSREG_REG_MASK) >> ISS_SYSREG_REG_SHIFT;
+}
+
+static inline bool is_sysreg_iss_write(uint64_t esr)
+{
+	return !(esr & ISS_SYSREG_DIRECTION_MASK);
+}
+
+/**
+ * handle_sysreg_trap() - Handle AArch64 system register traps from lower ELs
+ * @esr_el3: The content of ESR_EL3, containing the trap syndrome information
+ * @ctx: Pointer to the lower EL context, containing saved registers
+ *
+ * Called by the exception handler when a synchronous trap identifies as a
+ * system register trap (EC=0x18). ESR contains the encoding of the op[x] and
+ * CRm/CRn fields, to identify the system register, and the target/source
+ * GPR plus the direction (MRS/MSR). The lower EL's context can be altered
+ * by the function, to inject back the result of the emulation.
+ *
+ * Return: indication how to proceed with the trap:
+ *   TRAP_RET_UNHANDLED(-1): trap is unhandled, trigger panic
+ *   TRAP_RET_REPEAT(0): trap was handled, return to the trapping instruction
+ *			 (repeating it)
+ *   TRAP_RET_CONTINUE(1): trap was handled, return to the next instruction
+ *		           (continuing after it)
+ */
+int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx);
+
+/* Prototypes for system register emulation handlers provided by platforms. */
+int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx);
+
+#endif /* __ASSEMBLER__ */
+
+#endif
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 2929fc2..b16510f 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -10,6 +10,7 @@
 #define FDT_WRAPPERS_H
 
 #include <libfdt_env.h>
+#include <libfdt.h>
 
 /* Number of cells, given total length in bytes. Each cell is 4 bytes long */
 #define NCELLS(len) ((len) / 4U)
@@ -53,6 +54,15 @@
 	return fdt32_to_cpu(dtb_header[1]);
 }
 
+static inline bool fdt_node_is_enabled(const void *fdt, int node)
+{
+	int len;
+	const void *prop = fdt_getprop(fdt, node, "status", &len);
+
+	/* A non-existing status property means the device is enabled. */
+	return (prop == NULL) || (len == 5 && strcmp(prop, "okay") == 0);
+}
+
 #define fdt_for_each_compatible_node(dtb, node, compatible_str)       \
 for (node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);   \
      node >= 0;                                                       \
diff --git a/include/common/feat_detect.h b/include/common/feat_detect.h
index 0f0f105..788dfb3 100644
--- a/include/common/feat_detect.h
+++ b/include/common/feat_detect.h
@@ -7,26 +7,12 @@
 #ifndef FEAT_DETECT_H
 #define FEAT_DETECT_H
 
-#include <arch_features.h>
-#include <common/debug.h>
-
 /* Function Prototypes */
 void detect_arch_features(void);
 
 /* Macro Definitions */
-#define FEAT_STATE_1	1
-#define FEAT_STATE_2	2
-#define feat_detect_panic(a, b)		((a) ? (void)0 : feature_panic(b))
-
-/*******************************************************************************
- * Function : feature_panic
- * Customised panic module with error logging mechanism to list the feature
- * not supported by the PE.
- ******************************************************************************/
-static inline void feature_panic(char *feat_name)
-{
-	ERROR("FEAT_%s not supported by the PE\n", feat_name);
-	panic();
-}
+#define FEAT_STATE_DISABLED	0
+#define FEAT_STATE_ALWAYS	1
+#define FEAT_STATE_CHECK	2
 
 #endif /* FEAT_DETECT_H */
diff --git a/include/drivers/console.h b/include/drivers/console.h
index 99bf960..f499571 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -48,6 +48,8 @@
 	/* Additional private driver data may follow here. */
 } console_t;
 
+extern console_t *console_list;
+
 /* offset macro assertions for console_t */
 #include <drivers/console_assertions.h>
 
diff --git a/include/drivers/partition/efi.h b/include/drivers/partition/efi.h
index e463f96..96c2857 100644
--- a/include/drivers/partition/efi.h
+++ b/include/drivers/partition/efi.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2021, Linaro Limited
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -25,13 +26,13 @@
 }
 
 #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
-	{ (a) & 0xffffffff,		\
-	  (b) & 0xffff,			\
-	  (c) & 0xffff,			\
+	{ (a) & 0xffffffffU,		\
+	  (b) & 0xffffU,			\
+	  (c) & 0xffffU,			\
 	  { (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } }
 
 #define NULL_GUID \
-	EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, \
-		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
+	EFI_GUID(0x00000000U, 0x0000U, 0x0000U, 0x00U, 0x00U, \
+		 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U)
 
 #endif /* DRIVERS_PARTITION_EFI_H */
diff --git a/include/drivers/st/io_mmc.h b/include/drivers/st/io_mmc.h
deleted file mode 100644
index 6179e89..0000000
--- a/include/drivers/st/io_mmc.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef IO_MMC_H
-#define IO_MMC_H
-
-#include <drivers/io/io_driver.h>
-
-struct io_mmc_dev_spec {
-	bool use_boot_part;
-};
-
-int register_io_dev_mmc(const io_dev_connector_t **dev_con);
-
-#endif /* IO_MMC_H */
diff --git a/include/lib/cpus/aarch32/cortex_a72.h b/include/lib/cpus/aarch32/cortex_a72.h
index 4b1af61..954f736 100644
--- a/include/lib/cpus/aarch32/cortex_a72.h
+++ b/include/lib/cpus/aarch32/cortex_a72.h
@@ -37,16 +37,21 @@
 #define CORTEX_A72_CPUACTLR_NO_ALLOC_WBWA		(ULL(1) << 49)
 #define CORTEX_A72_CPUACTLR_DCC_AS_DCCI			(ULL(1) << 44)
 #define CORTEX_A72_CPUACTLR_DIS_INSTR_PREFETCH		(ULL(1) << 32)
+#define CORTEX_A72_CPUACTLR_DELAY_EXCLUSIVE_SNOOP	(ULL(1) << 31)
 
 /*******************************************************************************
  * L2 Control register specific definitions.
  ******************************************************************************/
 #define CORTEX_A72_L2CTLR				p15, 1, c9, c0, 2
 
+#define CORTEX_A72_L2CTLR_EL1_ECC_AND_PARITY_ENABLE	(ULL(1) << 21)
+#define CORTEX_A72_L2CTLR_EL1_DATA_INLINE_ECC_ENABLE	(ULL(1) << 20)
+
 #define CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT	U(0)
 #define CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT		U(6)
 
 #define CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES		U(0x2)
+#define CORTEX_A72_L2_DATA_RAM_LATENCY_4_CYCLES		U(0x3)
 #define CORTEX_A72_L2_TAG_RAM_LATENCY_2_CYCLES		U(0x1)
 #define CORTEX_A72_L2_TAG_RAM_LATENCY_3_CYCLES		U(0x2)
 
diff --git a/include/lib/cpus/aarch64/cortex_a72.h b/include/lib/cpus/aarch64/cortex_a72.h
index 1777645..bef9337 100644
--- a/include/lib/cpus/aarch64/cortex_a72.h
+++ b/include/lib/cpus/aarch64/cortex_a72.h
@@ -40,6 +40,7 @@
 #define CORTEX_A72_CPUACTLR_EL1_NO_ALLOC_WBWA			(ULL(1) << 49)
 #define CORTEX_A72_CPUACTLR_EL1_DCC_AS_DCCI			(ULL(1) << 44)
 #define CORTEX_A72_CPUACTLR_EL1_DIS_INSTR_PREFETCH		(ULL(1) << 32)
+#define CORTEX_A72_CPUACTLR_EL1_DELAY_EXCLUSIVE_SNOOP		(ULL(1) << 31)
 
 /*******************************************************************************
  *  L2 Auxiliary Control register specific definitions.
@@ -60,6 +61,9 @@
  ******************************************************************************/
 #define CORTEX_A72_L2CTLR_EL1				S3_1_C11_C0_2
 
+#define CORTEX_A72_L2CTLR_EL1_ECC_AND_PARITY_ENABLE	(ULL(1) << 21)
+#define CORTEX_A72_L2CTLR_EL1_DATA_INLINE_ECC_ENABLE	(ULL(1) << 20)
+
 #define CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT	U(0)
 #define CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT		U(5)
 #define CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT		U(6)
@@ -68,6 +72,7 @@
 #define CORTEX_A72_L2_DATA_RAM_LATENCY_MASK		U(0x7)
 #define CORTEX_A72_L2_TAG_RAM_LATENCY_MASK		U(0x7)
 #define CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES		U(0x2)
+#define CORTEX_A72_L2_DATA_RAM_LATENCY_4_CYCLES		U(0x3)
 #define CORTEX_A72_L2_TAG_RAM_LATENCY_2_CYCLES		U(0x1)
 #define CORTEX_A72_L2_TAG_RAM_LATENCY_3_CYCLES		U(0x2)
 
diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h
index 31da99e..fb325b6 100644
--- a/include/lib/cpus/aarch64/cortex_a78.h
+++ b/include/lib/cpus/aarch64/cortex_a78.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,6 +40,8 @@
 #define CORTEX_A78_ACTLR2_EL1_BIT_2			(ULL(1) << 2)
 #define CORTEX_A78_ACTLR2_EL1_BIT_40			(ULL(1) << 40)
 
+#define CORTEX_A78_ACTLR3_EL1				S3_0_C15_C1_2
+
 /*******************************************************************************
  * CPU Activity Monitor Unit register specific definitions.
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h
index 9c7e967..4c10484 100644
--- a/include/lib/cpus/aarch64/neoverse_v1.h
+++ b/include/lib/cpus/aarch64/neoverse_v1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,4 +41,6 @@
 #define NEOVERSE_V1_ACTLR2_EL1_BIT_28				(ULL(1) << 28)
 #define NEOVERSE_V1_ACTLR2_EL1_BIT_40				(ULL(1) << 40)
 
+#define NEOVERSE_V1_ACTLR3_EL1					S3_0_C15_C1_2
+
 #endif /* NEOVERSE_V1_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 6c13166..6986e0e 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -523,10 +523,6 @@
 void el2_sysregs_context_save_mpam(el2_sysregs_t *regs);
 void el2_sysregs_context_restore_mpam(el2_sysregs_t *regs);
 #endif /* ENABLE_MPAM_FOR_LOWER_ELS */
-#if ENABLE_FEAT_FGT
-void el2_sysregs_context_save_fgt(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_fgt(el2_sysregs_t *regs);
-#endif /* ENABLE_FEAT_FGT */
 #if ENABLE_FEAT_ECV
 void el2_sysregs_context_save_ecv(el2_sysregs_t *regs);
 void el2_sysregs_context_restore_ecv(el2_sysregs_t *regs);
@@ -551,10 +547,6 @@
 void el2_sysregs_context_save_csv2(el2_sysregs_t *regs);
 void el2_sysregs_context_restore_csv2(el2_sysregs_t *regs);
 #endif /* ENABLE_FEAT_CSV2_2 */
-#if ENABLE_FEAT_HCX
-void el2_sysregs_context_save_hcx(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_hcx(el2_sysregs_t *regs);
-#endif /* ENABLE_FEAT_HCX */
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 #if CTX_INCLUDE_FPREGS
diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h
index 131c542..3762021 100644
--- a/include/lib/fconf/fconf.h
+++ b/include/lib/fconf/fconf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,7 +21,7 @@
  */
 #define FCONF_REGISTER_POPULATOR(config, name, callback)			\
 	__attribute__((used, section(".fconf_populator")))			\
-	const struct fconf_populator (name##__populator) = {			\
+	static const struct fconf_populator (name##__populator) = {		\
 		.config_type = (#config),					\
 		.info = (#name),						\
 		.populate = (callback)						\
diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h
index 43f298e..3554673 100644
--- a/include/lib/fconf/fconf_dyn_cfg_getter.h
+++ b/include/lib/fconf/fconf_dyn_cfg_getter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,12 +19,11 @@
 	uint32_t config_max_size;
 	unsigned int config_id;
 	/*
-	 * Load address in non-secure memory. Only needed by those
-	 * configuration files which require being loaded in secure
-	 * memory (at config_addr) as well as in non-secure memory
+	 * A platform uses this address to copy the configuration
+	 * to another location during the boot-flow.
 	 * - e.g. HW_CONFIG
 	 */
-	uintptr_t ns_config_addr;
+	uintptr_t secondary_config_addr;
 };
 
 unsigned int dyn_cfg_dtb_info_get_index(unsigned int config_id);
@@ -32,7 +31,7 @@
 int fconf_populate_dtb_registry(uintptr_t config);
 
 /* Set config information in global DTB array */
-void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+void set_config_info(uintptr_t config_addr, uintptr_t secondary_config_addr,
 		     uint32_t config_max_size,
 		     unsigned int config_id);
 
diff --git a/include/lib/libc/aarch32/limits_.h b/include/lib/libc/aarch32/limits_.h
index 26cec17..a67ec53 100644
--- a/include/lib/libc/aarch32/limits_.h
+++ b/include/lib/libc/aarch32/limits_.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #define SCHAR_MAX  0x7F
-#define SCHAR_MIN  (-SCHAR_MIN - 1)
+#define SCHAR_MIN  (-SCHAR_MAX - 1)
 #define CHAR_MAX   0x7F
 #define CHAR_MIN   (-CHAR_MAX - 1)
 #define UCHAR_MAX  0xFFU
diff --git a/include/lib/libc/aarch64/limits_.h b/include/lib/libc/aarch64/limits_.h
index e36cfe7..1bb0681 100644
--- a/include/lib/libc/aarch64/limits_.h
+++ b/include/lib/libc/aarch64/limits_.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #define SCHAR_MAX  0x7F
-#define SCHAR_MIN  (-SCHAR_MIN - 1)
+#define SCHAR_MIN  (-SCHAR_MAX - 1)
 #define CHAR_MAX   0x7F
 #define CHAR_MIN   (-CHAR_MAX - 1)
 #define UCHAR_MAX  0xFFU
diff --git a/include/lib/optee_utils.h b/include/lib/optee_utils.h
index 06378eb..8224d50 100644
--- a/include/lib/optee_utils.h
+++ b/include/lib/optee_utils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,4 +17,40 @@
 	image_info_t *pager_image_info,
 	image_info_t *paged_image_info);
 
+/*
+ * load_addr_hi and load_addr_lo: image load address.
+ * image_id: 0 - pager, 1 - paged
+ * size: image size in bytes.
+ */
+typedef struct optee_image {
+	uint32_t load_addr_hi;
+	uint32_t load_addr_lo;
+	uint32_t image_id;
+	uint32_t size;
+} optee_image_t;
+
+#define OPTEE_PAGER_IMAGE_ID		0
+#define OPTEE_PAGED_IMAGE_ID		1
+
+#define OPTEE_MAX_NUM_IMAGES		2u
+
+#define TEE_MAGIC_NUM_OPTEE		0x4554504f
+/*
+ * magic: header magic number.
+ * version: OPTEE header version:
+ *		1 - not supported
+ *		2 - supported
+ * arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64.
+ * flags: unused currently.
+ * nb_images: number of images.
+ */
+typedef struct optee_header {
+	uint32_t magic;
+	uint8_t version;
+	uint8_t arch;
+	uint16_t flags;
+	uint32_t nb_images;
+	optee_image_t optee_image_list[];
+} optee_header_t;
+
 #endif /* OPTEE_UTILS_H */
diff --git a/include/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h
index 0bdeed4..be78bae 100644
--- a/include/lib/psa/psa_manifest/sid.h
+++ b/include/lib/psa/psa_manifest/sid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,6 +8,9 @@
 #ifndef PSA_MANIFEST_SID_H
 #define PSA_MANIFEST_SID_H
 
+/******** RSS_SP_PLATFORM ********/
+#define RSS_PLATFORM_SERVICE_HANDLE			(0x40000105U)
+
 /******** PSA_SP_MEASURED_BOOT ********/
 #define RSS_MEASURED_BOOT_HANDLE			(0x40000110U)
 
diff --git a/include/lib/psa/rss_platform_api.h b/include/lib/psa/rss_platform_api.h
new file mode 100644
index 0000000..1dd7d05
--- /dev/null
+++ b/include/lib/psa/rss_platform_api.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef RSS_PLATFORM_API_H
+#define RSS_PLATFORM_API_H
+
+#include <stdint.h>
+
+#include "psa/error.h"
+
+#define RSS_PLATFORM_API_ID_NV_READ       (1010)
+#define RSS_PLATFORM_API_ID_NV_INCREMENT  (1011)
+
+/*
+ * Increments the given non-volatile (NV) counter by one
+ *
+ * counter_id	NV counter ID.
+ *
+ * PSA_SUCCESS if the value is read correctly. Otherwise,
+ *	it returns a PSA_ERROR.
+ */
+psa_status_t
+rss_platform_nv_counter_increment(uint32_t counter_id);
+
+/*
+ * Reads the given non-volatile (NV) counter
+ *
+ * counter_id	NV counter ID.
+ * size		Size of the buffer to store NV counter value
+ *			in bytes.
+ * val		Pointer to store the current NV counter value.
+ *
+ * PSA_SUCCESS if the value is read correctly. Otherwise,
+ *	it returns a PSA_ERROR.
+ */
+psa_status_t
+rss_platform_nv_counter_read(uint32_t counter_id,
+		uint32_t size, uint8_t *val);
+
+#endif /* RSS_PLATFORM_API_H */
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 198b890..63eda63 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -68,14 +68,14 @@
 	__typeof__(x) _x = (x);		\
 	__typeof__(y) _y = (y);		\
 	(void)(&_x == &_y);		\
-	_x < _y ? _x : _y;		\
+	(_x < _y) ? _x : _y;		\
 })
 
 #define MAX(x, y) __extension__ ({	\
 	__typeof__(x) _x = (x);		\
 	__typeof__(y) _y = (y);		\
 	(void)(&_x == &_y);		\
-	_x > _y ? _x : _y;		\
+	(_x > _y) ? _x : _y;		\
 })
 
 #define CLAMP(x, min, max) __extension__ ({ \
@@ -84,7 +84,7 @@
 	__typeof__(max) _max = (max); \
 	(void)(&_x == &_min); \
 	(void)(&_x == &_max); \
-	(_x > _max ? _max : (_x < _min ? _min : _x)); \
+	((_x > _max) ? _max : ((_x < _min) ? _min : _x)); \
 })
 
 /*
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 36b1bdb..7cd32b1 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -235,6 +235,8 @@
 #define ARM_DRAM2_SIZE			PLAT_ARM_DRAM2_SIZE
 #define ARM_DRAM2_END			(ARM_DRAM2_BASE +		\
 					 ARM_DRAM2_SIZE - 1U)
+/* Number of DRAM banks */
+#define ARM_DRAM_NUM_BANKS		2UL
 
 #define ARM_IRQ_SEC_PHY_TIMER		29
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 3351036..8543ac7 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -11,7 +11,7 @@
 
 #include <lib/psci/psci.h>
 #if defined(SPD_spmd)
- #include <services/spm_core_manifest.h>
+#include <services/spm_core_manifest.h>
 #endif
 #if ENABLE_RME
 #include <services/rmm_core_manifest.h>
@@ -37,6 +37,7 @@
 struct mmap_region;
 struct spm_mm_boot_info;
 struct sp_res_desc;
+struct rmm_manifest;
 enum fw_enc_status_t;
 
 /*******************************************************************************
@@ -322,7 +323,7 @@
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type);
 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
-int plat_rmmd_load_manifest(rmm_manifest_t *manifest);
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
 #endif
 
 /*******************************************************************************
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index da016fd..8bc911a 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -24,7 +24,7 @@
 
 /* The macros below are used to identify FFA calls from the SMC function ID */
 #define FFA_FNUM_MIN_VALUE	U(0x60)
-#define FFA_FNUM_MAX_VALUE	U(0x87)
+#define FFA_FNUM_MAX_VALUE	U(0x8B)
 #define is_ffa_fid(fid) __extension__ ({		\
 	__typeof__(fid) _fid = (fid);			\
 	((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&	\
@@ -117,6 +117,7 @@
 #define FFA_FNUM_SPM_ID_GET			U(0x85)
 #define FFA_FNUM_MSG_SEND2			U(0x86)
 #define FFA_FNUM_SECONDARY_EP_REGISTER		U(0x87)
+#define FFA_FNUM_PARTITION_INFO_GET_REGS	U(0x8B)
 
 /* FFA SMC32 FIDs */
 #define FFA_ERROR		FFA_FID(SMC_32, FFA_FNUM_ERROR)
@@ -180,6 +181,8 @@
 	FFA_FID(SMC_64, FFA_FNUM_SECONDARY_EP_REGISTER)
 #define FFA_NOTIFICATION_INFO_GET_SMC64 \
 	FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
+#define FFA_PARTITION_INFO_GET_REGS_SMC64 \
+	FFA_FID(SMC_64, FFA_FNUM_PARTITION_INFO_GET_REGS)
 
 /*
  * FF-A partition properties values.
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
index 7edef46..b89de9f 100644
--- a/include/services/rmm_core_manifest.h
+++ b/include/services/rmm_core_manifest.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,7 @@
 #include <lib/cassert.h>
 
 #define RMMD_MANIFEST_VERSION_MAJOR		U(0)
-#define RMMD_MANIFEST_VERSION_MINOR		U(1)
+#define RMMD_MANIFEST_VERSION_MINOR		U(2)
 
 /*
  * Manifest version encoding:
@@ -22,29 +22,57 @@
  *	- Bits [30:16] Major version
  *	- Bits [15:0] Minor version
  */
-#define _RMMD_MANIFEST_VERSION(_major, _minor)				\
+#define SET_RMMD_MANIFEST_VERSION(_major, _minor)		\
 	((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF))
 
-#define RMMD_MANIFEST_VERSION _RMMD_MANIFEST_VERSION(			\
-				RMMD_MANIFEST_VERSION_MAJOR,		\
+#define RMMD_MANIFEST_VERSION	SET_RMMD_MANIFEST_VERSION(	\
+				RMMD_MANIFEST_VERSION_MAJOR,	\
 				RMMD_MANIFEST_VERSION_MINOR)
 
-#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version)			\
+#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version)		\
 	((_version >> 16) & 0x7FFF)
 
-#define RMMD_GET_MANIFEST_VERSION_MINOR(_version)			\
+#define RMMD_GET_MANIFEST_VERSION_MINOR(_version)		\
 	(_version & 0xFFFF)
 
-/* Boot manifest core structure as per v0.1 */
-typedef struct rmm_manifest {
-	uint32_t version;	/* Manifest version */
-	uint32_t padding;	/* RES0 */
-	uintptr_t plat_data;	/* Manifest platform data */
-} rmm_manifest_t;
+/* NS DRAM bank structure */
+struct ns_dram_bank {
+	uintptr_t base;			/* Base address */
+	uint64_t size;			/* Size of bank */
+};
+
+CASSERT(offsetof(struct ns_dram_bank, base) == 0UL,
+			rmm_manifest_base_unaligned);
+CASSERT(offsetof(struct ns_dram_bank, size) == 8UL,
+			rmm_manifest_size_unaligned);
+
+/* NS DRAM layout info structure */
+struct ns_dram_info {
+	uint64_t num_banks;		/* Number of NS DRAM banks */
+	struct ns_dram_bank *banks;	/* Pointer to ns_dram_bank[] */
+	uint64_t checksum;		/* Checksum of ns_dram_info data */
+};
+
+CASSERT(offsetof(struct ns_dram_info, num_banks) == 0UL,
+			rmm_manifest_num_banks_unaligned);
+CASSERT(offsetof(struct ns_dram_info, banks) == 8UL,
+			rmm_manifest_dram_data_unaligned);
+CASSERT(offsetof(struct ns_dram_info, checksum) == 16UL,
+			rmm_manifest_checksum_unaligned);
+
+/* Boot manifest core structure as per v0.2 */
+struct rmm_manifest {
+	uint32_t version;		/* Manifest version */
+	uint32_t padding;		/* RES0 */
+	uintptr_t plat_data;		/* Manifest platform data */
+	struct ns_dram_info plat_dram;	/* Platform NS DRAM data */
+};
 
-CASSERT(offsetof(rmm_manifest_t, version) == 0,
-				rmm_manifest_t_version_unaligned);
-CASSERT(offsetof(rmm_manifest_t, plat_data) == 8,
-				rmm_manifest_t_plat_data_unaligned);
+CASSERT(offsetof(struct rmm_manifest, version) == 0UL,
+			rmm_manifest_version_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_data) == 8UL,
+			rmm_manifest_plat_data_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_dram) == 16UL,
+			rmm_manifest_plat_dram_unaligned);
 
 #endif /* RMM_CORE_MANIFEST_H */
diff --git a/include/services/trp/platform_trp.h b/include/services/trp/platform_trp.h
index 1c963c8..756e9db 100644
--- a/include/services/trp/platform_trp.h
+++ b/include/services/trp/platform_trp.h
@@ -9,9 +9,11 @@
 
 #include <services/rmm_core_manifest.h>
 
+struct rmm_manifest;
+
 /*******************************************************************************
  * Mandatory TRP functions (only if platform contains a TRP)
  ******************************************************************************/
-void trp_early_platform_setup(rmm_manifest_t *manifest);
+void trp_early_platform_setup(struct rmm_manifest *manifest);
 
 #endif /* PLATFORM_TRP_H */
diff --git a/lib/compiler-rt/builtins/arm/aeabi_memset.S b/lib/compiler-rt/builtins/arm/aeabi_memset.S
new file mode 100644
index 0000000..2aa8ec0
--- /dev/null
+++ b/lib/compiler-rt/builtins/arm/aeabi_memset.S
@@ -0,0 +1,49 @@
+//===-- aeabi_memset.S - EABI memset implementation -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//  void __aeabi_memset(void *dest, size_t n, int c) { memset(dest, c, n); }
+//  void __aeabi_memclr(void *dest, size_t n) { __aeabi_memset(dest, n, 0); }
+
+        .syntax unified
+        .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memset)
+        mov     r3, r1
+        mov     r1, r2
+        mov     r2, r3
+#ifdef USE_THUMB_1
+        push    {r7, lr}
+        bl      memset
+        pop     {r7, pc}
+#else
+        b       memset
+#endif
+END_COMPILERRT_FUNCTION(__aeabi_memset)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset4, __aeabi_memset)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset8, __aeabi_memset)
+
+        .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memclr)
+        mov     r2, r1
+        movs    r1, #0
+#ifdef USE_THUMB_1
+        push    {r7, lr}
+        bl      memset
+        pop     {r7, pc}
+#else
+        b       memset
+#endif
+END_COMPILERRT_FUNCTION(__aeabi_memclr)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)
+
+NO_EXEC_STACK_DIRECTIVE
+
diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk
index 2338908..b41c4d0 100644
--- a/lib/compiler-rt/compiler-rt.mk
+++ b/lib/compiler-rt/compiler-rt.mk
@@ -35,6 +35,7 @@
 COMPILER_RT_SRCS	+=	lib/compiler-rt/builtins/arm/aeabi_ldivmod.S	\
 				lib/compiler-rt/builtins/arm/aeabi_uldivmod.S	\
 				lib/compiler-rt/builtins/arm/aeabi_memcpy.S	\
+				lib/compiler-rt/builtins/arm/aeabi_memset.S	\
 				lib/compiler-rt/builtins/ctzdi2.c		\
 				lib/compiler-rt/builtins/divdi3.c		\
 				lib/compiler-rt/builtins/divmoddi4.c		\
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index f7f8027..886e1f3 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -361,6 +361,45 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2666669
 
+/* ------------------------------------------------------
+ * Errata Workaround for Cortex-A510 Erratum 2684597.
+ * This erratum applies to revision r0p0, r0p1, r0p2,
+ * r0p3, r1p0, r1p1 and r1p2 of the Cortex-A510 cpu and
+ * is fixed in r1p3.
+ * Shall clobber: x0-x17
+ * ------------------------------------------------------
+ */
+	.globl	errata_cortex_a510_2684597_wa
+func errata_cortex_a510_2684597_wa
+	mov	x17, x30
+	/* Ensure this errata is only applied to Cortex-A510 cores */
+	jump_if_cpu_midr	CORTEX_A510_MIDR,	1f
+	b	2f
+
+1:
+	/* Check workaround compatibility. */
+	mov	x0, x18
+	bl	check_errata_2684597
+	cbz	x0, 2f
+
+	tsb	csync
+2:
+	ret	x17
+endfunc errata_cortex_a510_2684597_wa
+/* ------------------------------------------------------
+ * Errata Workaround for Cortex-A510 Erratum 2684597.
+ * This erratum applies to revision r0p0, r0p1, r0p2,
+ * r0p3, r1p0, r1p1 and r1p2 of the Cortex-A510 cpu and
+ * is fixed in r1p3.
+ * Shall clobber: x0-x17
+ * ------------------------------------------------------
+ */
+func check_errata_2684597
+	/* Applies to revision < r1p3 */
+	mov	x1, #0x12
+	b	cpu_rev_var_ls
+endfunc check_errata_2684597
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -401,6 +440,7 @@
 	report_errata ERRATA_A510_2347730, cortex_a510, 2347730
 	report_errata ERRATA_A510_2371937, cortex_a510, 2371937
 	report_errata ERRATA_A510_2666669, cortex_a510, 2666669
+	report_errata ERRATA_A510_2684597, cortex_a510, 2684597
 	report_errata ERRATA_DSU_2313941, cortex_a510, dsu_2313941
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 3ea55df..cebd6f0 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -355,22 +355,22 @@
 
 /* ---------------------------------------------------------------
  * Errata Workaround for Cortex-A710 Erratum 2282622.
- * This applies to revision r0p0, r1p0 and r2p0.
- * It is fixed in r2p1.
+ * This applies to revision r0p0, r1p0, r2p0 and r2p1.
+ * It is still open.
  * Inputs:
  * x0: variant[4:7] and revision[0:3] of current cpu.
  * Shall clobber: x0, x1, x17
  * ---------------------------------------------------------------
  */
 func errata_a710_2282622_wa
-	/* Compare x0 against revision r2p0 */
+	/* Compare x0 against revision r2p1 */
 	mov     x17, x30
 	bl      check_errata_2282622
 	cbz     x0, 1f
 
 	/* Apply the workaround */
 	mrs     x1, CORTEX_A710_CPUACTLR2_EL1
-	orr     x1, x1, BIT(0)
+	orr     x1, x1, #BIT(0)
 	msr     CORTEX_A710_CPUACTLR2_EL1, x1
 
 1:
@@ -378,8 +378,8 @@
 endfunc errata_a710_2282622_wa
 
 func check_errata_2282622
-	/* Applies to r0p0, r1p0 and r2p0 */
-	mov     x1, #0x20
+	/* Applies to r0p0, r1p0, r2p0 and r2p1 */
+	mov     x1, #0x21
 	b       cpu_rev_var_ls
 endfunc check_errata_2282622
 
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index dd3487a..a3932e8 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -326,6 +326,60 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2395406
 
+/* ----------------------------------------------------
+ * Errata Workaround for Cortex-A78 Errata 2772019
+ * This applies to revisions <= r1p2 and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ----------------------------------------------------
+ */
+func errata_a78_2772019_wa
+	mov	x17, x30
+	bl	check_errata_2772019
+	cbz	x0, 1f
+
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_a78_2772019_wa
+
+func check_errata_2772019
+	/* Applies to all revisions <= r1p2 */
+	mov	x1, #0x12
+	b	cpu_rev_var_ls
+endfunc check_errata_2772019
+
+/* ----------------------------------------------------
+ * Errata Workaround for Cortex A78 Errata 2779479.
+ * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
+ * It is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * ----------------------------------------------------
+ */
+func errata_a78_2779479_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2779479
+	cbz	x0, 1f
+
+	/* Apply the workaround */
+	mrs	x1, CORTEX_A78_ACTLR3_EL1
+	orr	x1, x1, #BIT(47)
+	msr	CORTEX_A78_ACTLR3_EL1, x1
+
+1:
+	ret	x17
+endfunc errata_a78_2779479_wa
+
+func check_errata_2779479
+	/* Applies to r0p0, r1p0, r1p1, r1p2 */
+	mov	x1, #CPU_REV(1, 2)
+	b	cpu_rev_var_ls
+endfunc check_errata_2779479
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -389,6 +443,11 @@
 	bl	errata_a78_2395406_wa
 #endif
 
+#if ERRATA_A78_2779479
+	mov	x0, x18
+	bl	errata_a78_2779479_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
@@ -434,6 +493,12 @@
 	mrs	x0, CORTEX_A78_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 	msr	CORTEX_A78_CPUPWRCTLR_EL1, x0
+#if ERRATA_A78_2772019
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a78_2772019_wa
+	mov	x30, x15
+#endif /* ERRATA_A78_2772019 */
 	isb
 	ret
 endfunc cortex_a78_core_pwr_dwn
@@ -461,6 +526,8 @@
 	report_errata ERRATA_A78_2242635, cortex_a78, 2242635
 	report_errata ERRATA_A78_2376745, cortex_a78, 2376745
 	report_errata ERRATA_A78_2395406, cortex_a78, 2395406
+	report_errata ERRATA_A78_2772019, cortex_a78, 2772019
+	report_errata ERRATA_A78_2779479, cortex_a78, 2779479
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a78, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 49cebfe..5cdce89 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -117,13 +117,13 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2132064
 
-/* --------------------------------------------------------------------
+/* ----------------------------------------------------------
  * Errata Workaround for A78C Erratum 2242638.
  * This applies to revisions r0p1 and r0p2 of the Cortex A78C
  * processor and is still open.
  * x0: variant[4:7] and revision[0:3] of current cpu.
  * Shall clobber: x0-x17
- * --------------------------------------------------------------------
+ * ----------------------------------------------------------
  */
 func errata_a78c_2242638_wa
 	/* Compare x0 against revisions r0p1 - r0p2 */
@@ -152,6 +152,31 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2242638
 
+/* ----------------------------------------------------------------
+ * Errata Workaround for A78C Erratum 2772121.
+ * This applies to revisions r0p0, r0p1 and r0p2 of the Cortex A78C
+ * processor and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ----------------------------------------------------------------
+ */
+func errata_a78c_2772121_wa
+	mov	x17, x30
+	bl	check_errata_2772121
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_a78c_2772121_wa
+
+func check_errata_2772121
+	/* Applies to all revisions <= r0p2 */
+	mov	x1, #0x02
+	b	cpu_rev_var_ls
+endfunc check_errata_2772121
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -215,6 +240,12 @@
 	mrs	x0, CORTEX_A78C_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 	msr	CORTEX_A78C_CPUPWRCTLR_EL1, x0
+#if ERRATA_A78C_2772121
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a78c_2772121_wa
+	mov	x30, x15
+#endif /* ERRATA_A78C_2772121 */
 	isb
 	ret
 endfunc cortex_a78c_core_pwr_dwn
@@ -237,6 +268,7 @@
 	report_errata ERRATA_A78C_2242638, cortex_a78c, 2242638
 	report_errata ERRATA_A78C_2376749, cortex_a78c, 2376749
 	report_errata ERRATA_A78C_2395411, cortex_a78c, 2395411
+	report_errata ERRATA_A78C_2772121, cortex_a78c, 2772121
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a78c, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index f56d50a..497bd52 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -267,13 +267,43 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2147715
 
-/* -------------------------------------------------------
- * Errata Workaround for Cortex-X2 Erratum 2371105.
- * This applies to revisions <= r2p0 and is fixed in r2p1.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * -------------------------------------------------------
- */
+	/* ---------------------------------------------------------------
+	 * Errata Workaround for Cortex-X2 Erratum 2282622.
+	 * This applies to revision r0p0, r1p0, r2p0 and r2p1.
+	 * It is still open.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0, x1, x17
+	 * ---------------------------------------------------------------
+	 */
+func errata_x2_2282622_wa
+	/* Compare x0 against revision r2p1 */
+	mov     x17, x30
+	bl      check_errata_2282622
+	cbz     x0, 1f
+
+	/* Apply the workaround */
+	mrs     x1, CORTEX_X2_CPUACTLR2_EL1
+	orr     x1, x1, #BIT(0)
+	msr     CORTEX_X2_CPUACTLR2_EL1, x1
+
+1:
+	ret     x17
+endfunc errata_x2_2282622_wa
+
+func check_errata_2282622
+	/* Applies to r0p0, r1p0, r2p0 and r2p1 */
+	mov     x1, #0x21
+	b       cpu_rev_var_ls
+endfunc check_errata_2282622
+
+	/* -------------------------------------------------------
+	 * Errata Workaround for Cortex-X2 Erratum 2371105.
+	 * This applies to revisions <= r2p0 and is fixed in r2p1.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * -------------------------------------------------------
+	 */
 func errata_x2_2371105_wa
 	/* Check workaround compatibility. */
 	mov	x17, x30
@@ -295,13 +325,13 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2371105
 
-/* ----------------------------------------------------
- * Errata Workaround for Cortex-X2 Errata #2768515
- * This applies to revisions <= r2p1 and is still open.
- * x0: variant[4:7] and revision[0:3] of current cpu.
- * Shall clobber: x0-x17
- * ----------------------------------------------------
- */
+	/* ----------------------------------------------------
+	 * Errata Workaround for Cortex-X2 Errata #2768515
+	 * This applies to revisions <= r2p1 and is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * ----------------------------------------------------
+	 */
 func errata_x2_2768515_wa
 	mov	x17, x30
 	bl	check_errata_2768515
@@ -362,6 +392,7 @@
 	report_errata ERRATA_X2_2083908, cortex_x2, 2083908
 	report_errata ERRATA_X2_2147715, cortex_x2, 2147715
 	report_errata ERRATA_X2_2216384, cortex_x2, 2216384
+	report_errata ERRATA_X2_2282622, cortex_x2, 2282622
 	report_errata ERRATA_X2_2371105, cortex_x2, 2371105
 	report_errata ERRATA_X2_2768515, cortex_x2, 2768515
 	report_errata WORKAROUND_CVE_2022_23960, cortex_x2, cve_2022_23960
@@ -421,6 +452,11 @@
 	bl	errata_x2_2147715_wa
 #endif
 
+#if ERRATA_X2_2282622
+	mov	x0, x18
+	bl	errata_x2_2282622_wa
+#endif
+
 #if ERRATA_X2_2371105
 	mov	x0, x18
 	bl	errata_x2_2371105_wa
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 5861dec..dbf5941 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -428,6 +428,30 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2388450
 
+/* -------------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2743089.
+ * This applies to revisions <= r0p2 and is fixed in r0p3.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * -------------------------------------------------------
+ */
+func errata_n2_2743089_wa
+	mov	x17, x30
+	bl	check_errata_2743089
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_n2_2743089_wa
+
+func check_errata_2743089
+	/* Applies to all revisions <= r0p2 */
+	mov	x1, #0x02
+	b	cpu_rev_var_ls
+endfunc check_errata_2743089
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -576,6 +600,12 @@
 	mrs	x0, NEOVERSE_N2_CPUPWRCTLR_EL1
 	orr	x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT
 	msr	NEOVERSE_N2_CPUPWRCTLR_EL1, x0
+#if ERRATA_N2_2743089
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_n2_2743089_wa
+	mov	x30, x15
+#endif /* ERRATA_N2_2743089 */
 	isb
 	ret
 endfunc neoverse_n2_core_pwr_dwn
@@ -607,6 +637,7 @@
 	report_errata ERRATA_N2_2326639, neoverse_n2, 2326639
 	report_errata ERRATA_N2_2376738, neoverse_n2, 2376738
 	report_errata ERRATA_N2_2388450, neoverse_n2, 2388450
+	report_errata ERRATA_N2_2743089, neoverse_n2, 2743089
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_n2, cve_2022_23960
 	report_errata ERRATA_DSU_2313941, neoverse_n2, dsu_2313941
 
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 3282fbc..f9a5789 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -462,6 +462,59 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2372203
 
+	/* ----------------------------------------------------
+	 * Errata Workaround for Neoverse V1 Errata #2743093.
+	 * This applies to revisions <= r1p2 and is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * ----------------------------------------------------
+	 */
+func errata_neoverse_v1_2743093_wa
+	mov	x17, x30
+	bl	check_errata_2743093
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_neoverse_v1_2743093_wa
+
+func check_errata_2743093
+	/* Applies to all revisions <= r1p2 */
+	mov	x1, #0x12
+	b	cpu_rev_var_ls
+endfunc check_errata_2743093
+
+	/* ----------------------------------------------------
+ 	 * Errata Workaround for Neoverse V1 Errata #2779461.
+	 * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
+	 * It is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x1, x17
+	 * ----------------------------------------------------
+	 */
+func errata_neoverse_v1_2779461_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2779461
+	cbz	x0, 1f
+
+	/* Apply the workaround */
+	mrs	x1, NEOVERSE_V1_ACTLR3_EL1
+	orr	x1, x1, #BIT(47)
+	msr	NEOVERSE_V1_ACTLR3_EL1, x1
+
+1:
+	ret	x17
+endfunc errata_neoverse_v1_2779461_wa
+
+func check_errata_2779461
+	/* Applies to r0p0, r1p0, r1p1, r1p2 */
+	mov	x1, #CPU_REV(1, 2)
+	b	cpu_rev_var_ls
+endfunc check_errata_2779461
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -483,6 +536,12 @@
 	mrs	x0, NEOVERSE_V1_CPUPWRCTLR_EL1
 	orr	x0, x0, #NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	msr	NEOVERSE_V1_CPUPWRCTLR_EL1, x0
+#if ERRATA_V1_2743093
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_neoverse_v1_2743093_wa
+	mov	x30, x15
+#endif /* ERRATA_V1_2743093 */
 	isb
 	ret
 endfunc neoverse_v1_core_pwr_dwn
@@ -513,6 +572,8 @@
 	report_errata ERRATA_V1_2216392, neoverse_v1, 2216392
 	report_errata ERRATA_V1_2294912, neoverse_v1, 2294912
 	report_errata ERRATA_V1_2372203, neoverse_v1, 2372203
+	report_errata ERRATA_V1_2743093, neoverse_v1, 2743093
+	report_errata ERRATA_V1_2779461, neoverse_v1, 2779461
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_v1, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
@@ -591,6 +652,11 @@
 	bl	errata_neoverse_v1_2372203_wa
 #endif
 
+#if ERRATA_V1_2779461
+	mov	x0, x18
+	bl	errata_neoverse_v1_2779461_wa
+#endif
+
 #if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
 	/*
 	 * The Neoverse-V1 generic vectors are overridden to apply errata
diff --git a/lib/cpus/aarch64/runtime_errata.S b/lib/cpus/aarch64/runtime_errata.S
new file mode 100644
index 0000000..8d46691
--- /dev/null
+++ b/lib/cpus/aarch64/runtime_errata.S
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <cortex_a510.h>
+#include <cpu_macros.S>
+
+/*
+ * void apply_cpu_pwr_dwn_errata(void);
+ *
+ * This function applies various CPU errata during power down.
+ */
+	.globl apply_cpu_pwr_dwn_errata
+func apply_cpu_pwr_dwn_errata
+	mov	x19, x30
+	bl      cpu_get_rev_var
+	mov	x18, x0
+
+#if ERRATA_A510_2684597
+	bl errata_cortex_a510_2684597_wa
+#endif
+
+	ret	x19
+endfunc apply_cpu_pwr_dwn_errata
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 527a82f..4582f28 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -357,6 +357,15 @@
 # to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
 ERRATA_A78_2395406	?=0
 
+# Flag to apply erratum 2772019 workaround during powerdown. This erratum
+# applies to revisions r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still
+# open.
+ERRATA_A78_2772019	?=0
+
+# Flag to apply erratum 2779479 workaround during reset. This erratum applies
+# to revision r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still open.
+ERRATA_A78_2779479	?=0
+
 # Flag to apply erratum 1941500 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
 ERRATA_A78_AE_1941500	?=0
@@ -389,6 +398,10 @@
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
 ERRATA_A78C_2395411 	?=0
 
+# Flag to apply erratum 2772121 workaround during powerdown. This erratum
+# applies to revisions r0p0, r0p1 and r0p2 of the A78C cpu. It is still open.
+ERRATA_A78C_2772121 	?=0
+
 # Flag to apply erratum 1821534 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
 ERRATA_X1_1821534	?=0
@@ -462,10 +475,6 @@
 # applies to all revisions <= r4p1 of the Neoverse N1 cpu and is still open.
 ERRATA_N1_2743102	?=0
 
-# Flag to apply erratum 2002655 workaround during reset. This erratum applies
-# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
-ERRATA_N2_2002655	?=0
-
 # Flag to apply erratum 1618635 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse V1 cpu and was fixed in the revision r1p0.
 ERRATA_V1_1618635	?=0
@@ -516,6 +525,16 @@
 # to revisions r0p0, r1p0 and r1p1 of the Neoverse V1 cpu and is still open.
 ERRATA_V1_2372203	?=0
 
+# Flag to apply erratum 2743093 workaround during powerdown. This erratum
+# applies to revisions r0p0, r1p0, r1p1 and r1p2  of the Neoverse V1 cpu and is
+# still open.
+ERRATA_V1_2743093	?=0
+
+# Flag to apply erratum 2779461 workaround during powerdown. This erratum
+# applies to revisions r0p0, r1p0, r1p1 and r1p2  of the Neoverse V1 cpu and is
+# still open.
+ERRATA_V1_2779461       ?=0
+
 # Flag to apply erratum 1987031 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
 ERRATA_A710_1987031	?=0
@@ -557,7 +576,8 @@
 ERRATA_A710_2216384	?=0
 
 # Flag to apply erratum 2282622 workaround during reset. This erratum applies
-# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
+# to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is still
+# open.
 ERRATA_A710_2282622	?=0
 
 # Flag to apply erratum 2291219 workaround during reset. This erratum applies
@@ -577,6 +597,10 @@
 # still open.
 ERRATA_A710_2768515	?=0
 
+# Flag to apply erratum 2002655 workaround during reset. This erratum applies
+# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
+ERRATA_N2_2002655	?=0
+
 # Flag to apply erratum 2067956 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
 ERRATA_N2_2067956	?=0
@@ -625,6 +649,10 @@
 # to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
 ERRATA_N2_2388450	?=0
 
+# Flag to apply erratum 2743089 workaround during during powerdown. This erratum
+# applies to all revisions <= r0p2 of the Neoverse N2 cpu, it is fixed in r0p3.
+ERRATA_N2_2743089	?=0
+
 # Flag to apply erratum 2002765 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
 ERRATA_X2_2002765	?=0
@@ -656,6 +684,11 @@
 # only to revision r2p0 of the Cortex-X2 cpu, it is fixed in r2p1.
 ERRATA_X2_2147715	?=0
 
+# Flag to apply erratum 2282622 workaround during reset. This erratum applies
+# to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is still
+# open.
+ERRATA_X2_2282622	?=0
+
 # Flag to apply erratum 2371105 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-X2 cpu and is fixed in r2p1.
 ERRATA_X2_2371105	?=0
@@ -716,6 +749,11 @@
 # to revisions r0p0, r0p1, r0p2, r0p3, r1p0, and r1p1. It is fixed in r1p2.
 ERRATA_A510_2666669	?=0
 
+# Flag to apply erratum 2684597 workaround during powerdown. This erratum
+# applies to revision r0p0, r0p1, r0p2, r0p3, r1p0, r1p1 and r1p2 of the
+# Cortex-A510 cpu and is fixed in r1p3.
+ERRATA_A510_2684597	?=0
+
 # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
 # Applying the workaround results in higher DSU power consumption on idle.
 ERRATA_DSU_798953	?=0
@@ -1006,6 +1044,14 @@
 $(eval $(call assert_boolean,ERRATA_A78_2395406))
 $(eval $(call add_define,ERRATA_A78_2395406))
 
+# Process ERRATA_A78_2772019 flag
+$(eval $(call assert_boolean,ERRATA_A78_2772019))
+$(eval $(call add_define,ERRATA_A78_2772019))
+
+# Process ERRATA_A78_2779479 flag
+$(eval $(call assert_boolean,ERRATA_A78_2779479))
+$(eval $(call add_define,ERRATA_A78_2779479))
+
 # Process ERRATA_A78_AE_1941500 flag
 $(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
 $(eval $(call add_define,ERRATA_A78_AE_1941500))
@@ -1038,6 +1084,10 @@
 $(eval $(call assert_boolean,ERRATA_A78C_2395411))
 $(eval $(call add_define,ERRATA_A78C_2395411))
 
+# Process ERRATA_A78C_2772121 flag
+$(eval $(call assert_boolean,ERRATA_A78C_2772121))
+$(eval $(call add_define,ERRATA_A78C_2772121))
+
 # Process ERRATA_X1_1821534 flag
 $(eval $(call assert_boolean,ERRATA_X1_1821534))
 $(eval $(call add_define,ERRATA_X1_1821534))
@@ -1109,10 +1159,6 @@
 # Process ERRATA_N1_2743102 flag
 $(eval $(call assert_boolean,ERRATA_N1_2743102))
 $(eval $(call add_define,ERRATA_N1_2743102))
-#
-# Process ERRATA_N2_2002655 flag
-$(eval $(call assert_boolean,ERRATA_N2_2002655))
-$(eval $(call add_define,ERRATA_N2_2002655))
 
 # Process ERRATA_V1_1618635 flag
 $(eval $(call assert_boolean,ERRATA_V1_1618635))
@@ -1162,6 +1208,14 @@
 $(eval $(call assert_boolean,ERRATA_V1_2372203))
 $(eval $(call add_define,ERRATA_V1_2372203))
 
+# Process ERRATA_V1_2743093 flag
+$(eval $(call assert_boolean,ERRATA_V1_2743093))
+$(eval $(call add_define,ERRATA_V1_2743093))
+
+# Process ERRATA_V1_2779461 flag
+$(eval $(call assert_boolean,ERRATA_V1_2779461))
+$(eval $(call add_define,ERRATA_V1_2779461))
+
 # Process ERRATA_A710_1987031 flag
 $(eval $(call assert_boolean,ERRATA_A710_1987031))
 $(eval $(call add_define,ERRATA_A710_1987031))
@@ -1222,6 +1276,10 @@
 $(eval $(call assert_boolean,ERRATA_A710_2768515))
 $(eval $(call add_define,ERRATA_A710_2768515))
 
+# Process ERRATA_N2_2002655 flag
+$(eval $(call assert_boolean,ERRATA_N2_2002655))
+$(eval $(call add_define,ERRATA_N2_2002655))
+
 # Process ERRATA_N2_2067956 flag
 $(eval $(call assert_boolean,ERRATA_N2_2067956))
 $(eval $(call add_define,ERRATA_N2_2067956))
@@ -1270,6 +1328,10 @@
 $(eval $(call assert_boolean,ERRATA_N2_2388450))
 $(eval $(call add_define,ERRATA_N2_2388450))
 
+# Process ERRATA_N2_2743089 flag
+$(eval $(call assert_boolean,ERRATA_N2_2743089))
+$(eval $(call add_define,ERRATA_N2_2743089))
+
 # Process ERRATA_X2_2002765 flag
 $(eval $(call assert_boolean,ERRATA_X2_2002765))
 $(eval $(call add_define,ERRATA_X2_2002765))
@@ -1298,6 +1360,10 @@
 $(eval $(call assert_boolean,ERRATA_X2_2147715))
 $(eval $(call add_define,ERRATA_X2_2147715))
 
+# Process ERRATA_X2_2282622 flag
+$(eval $(call assert_boolean,ERRATA_X2_2282622))
+$(eval $(call add_define,ERRATA_X2_2282622))
+
 # Process ERRATA_X2_2371105 flag
 $(eval $(call assert_boolean,ERRATA_X2_2371105))
 $(eval $(call add_define,ERRATA_X2_2371105))
@@ -1354,6 +1420,10 @@
 $(eval $(call assert_boolean,ERRATA_A510_2666669))
 $(eval $(call add_define,ERRATA_A510_2666669))
 
+# Process ERRATA_A510_2684597 flag
+$(eval $(call assert_boolean,ERRATA_A510_2684597))
+$(eval $(call add_define,ERRATA_A510_2684597))
+
 #Process ERRATA_DSU_798953 flag
 $(eval $(call assert_boolean,ERRATA_DSU_798953))
 $(eval $(call add_define,ERRATA_DSU_798953))
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 60501f6..722b8ae 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,10 +25,6 @@
 	.global	el2_sysregs_context_save_mpam
 	.global	el2_sysregs_context_restore_mpam
 #endif /* ENABLE_MPAM_FOR_LOWER_ELS */
-#if ENABLE_FEAT_FGT
-	.global	el2_sysregs_context_save_fgt
-	.global	el2_sysregs_context_restore_fgt
-#endif /* ENABLE_FEAT_FGT */
 #if ENABLE_FEAT_ECV
 	.global	el2_sysregs_context_save_ecv
 	.global	el2_sysregs_context_restore_ecv
@@ -53,10 +49,6 @@
 	.global	el2_sysregs_context_save_csv2
 	.global	el2_sysregs_context_restore_csv2
 #endif /* ENABLE_FEAT_CSV2_2 */
-#if ENABLE_FEAT_HCX
-	.global	el2_sysregs_context_save_hcx
-	.global	el2_sysregs_context_restore_hcx
-#endif /* ENABLE_FEAT_HCX */
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 	.global	el1_sysregs_context_save
@@ -265,93 +257,202 @@
 	mrs	x10, MPAM2_EL2
 	str	x10, [x0, #CTX_MPAM2_EL2]
 
+	mrs	x10, MPAMIDR_EL1
+
+	/*
+	 * The context registers that we intend to save would be part of the
+	 * PE's system register frame only if MPAMIDR_EL1.HAS_HCR == 1.
+	 */
+	tbz	w10, #MPAMIDR_EL1_HAS_HCR_SHIFT, 3f
+
+	/*
+	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 would be present in the
+	 * system register frame if MPAMIDR_EL1.HAS_HCR == 1. Proceed to save
+	 * the context of these registers.
+	 */
 	mrs	x11, MPAMHCR_EL2
 	mrs	x12, MPAMVPM0_EL2
 	stp	x11, x12, [x0, #CTX_MPAMHCR_EL2]
 
-	mrs	x13, MPAMVPM1_EL2
-	mrs	x14, MPAMVPM2_EL2
-	stp	x13, x14, [x0, #CTX_MPAMVPM1_EL2]
+	mrs	x13, MPAMVPMV_EL2
+	str	x13, [x0, #CTX_MPAMVPMV_EL2]
 
-	mrs	x15, MPAMVPM3_EL2
-	mrs	x16, MPAMVPM4_EL2
-	stp	x15, x16, [x0, #CTX_MPAMVPM3_EL2]
+	/*
+	 * MPAMIDR_EL1.VPMR_MAX has to be probed to obtain the maximum supported
+	 * VPMR value. Proceed to save the context of registers from
+	 * MPAMVPM1_EL2 to MPAMVPM<x>_EL2 where x is VPMR_MAX. From MPAM spec,
+	 * VPMR_MAX should not be zero if HAS_HCR == 1.
+	 */
+	ubfx	x10, x10, #MPAMIDR_EL1_VPMR_MAX_SHIFT, \
+		#MPAMIDR_EL1_VPMR_MAX_WIDTH
+
+	/*
+	 * Once VPMR_MAX has been identified, calculate the offset relative to
+	 * PC to jump to so that relevant context can be saved. The offset is
+	 * calculated as (VPMR_POSSIBLE_MAX - VPMR_MAX) * (instruction size for
+	 * saving one VPM register) + (absolute address of label "1").
+	 */
+	mov	w11, #MPAMIDR_EL1_VPMR_MAX_POSSIBLE
+	sub	w10, w11, w10
 
-	mrs	x9, MPAMVPM5_EL2
-	mrs	x10, MPAMVPM6_EL2
-	stp	x9, x10, [x0, #CTX_MPAMVPM5_EL2]
+	/* Calculate the size of one block of MPAMVPM*_EL2 save */
+	adr	x11, 1f
+	adr	x12, 2f
+	sub	x12, x12, x11
 
-	mrs	x11, MPAMVPM7_EL2
-	mrs	x12, MPAMVPMV_EL2
-	stp	x11, x12, [x0, #CTX_MPAMVPM7_EL2]
-	ret
-endfunc func el2_sysregs_context_save_mpam
+	madd	x10, x10, x12, x11
+	br	x10
+
+	/*
+	 * The branch above would land properly on one of the blocks following
+	 * label "1". Make sure that the order of save is retained.
+	 */
+1:
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x10, MPAMVPM7_EL2
+	str	x10, [x0, #CTX_MPAMVPM7_EL2]
+2:
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x11, MPAMVPM6_EL2
+	str	x11, [x0, #CTX_MPAMVPM6_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x12, MPAMVPM5_EL2
+	str	x12, [x0, #CTX_MPAMVPM5_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x13, MPAMVPM4_EL2
+	str	x13, [x0, #CTX_MPAMVPM4_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x14, MPAMVPM3_EL2
+	str	x14, [x0, #CTX_MPAMVPM3_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x15, MPAMVPM2_EL2
+	str	x15, [x0, #CTX_MPAMVPM2_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x16, MPAMVPM1_EL2
+	str	x16, [x0, #CTX_MPAMVPM1_EL2]
+
+3:	ret
+endfunc el2_sysregs_context_save_mpam
 
 func el2_sysregs_context_restore_mpam
 	ldr	x10, [x0, #CTX_MPAM2_EL2]
 	msr	MPAM2_EL2, x10
 
+	mrs	x10, MPAMIDR_EL1
+	/*
+	 * The context registers that we intend to restore would be part of the
+	 * PE's system register frame only if MPAMIDR_EL1.HAS_HCR == 1.
+	 */
+	tbz	w10, #MPAMIDR_EL1_HAS_HCR_SHIFT, 3f
+
+	/*
+	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 would be present in the
+	 * system register frame if MPAMIDR_EL1.HAS_HCR == 1. Proceed to restore
+	 * the context of these registers
+	 */
 	ldp	x11, x12, [x0, #CTX_MPAMHCR_EL2]
 	msr	MPAMHCR_EL2, x11
 	msr	MPAMVPM0_EL2, x12
 
-	ldp	x13, x14, [x0, #CTX_MPAMVPM1_EL2]
-	msr	MPAMVPM1_EL2, x13
-	msr	MPAMVPM2_EL2, x14
+	ldr	x13, [x0, #CTX_MPAMVPMV_EL2]
+	msr	MPAMVPMV_EL2, x13
 
-	ldp	x15, x16, [x0, #CTX_MPAMVPM3_EL2]
-	msr	MPAMVPM3_EL2, x15
-	msr	MPAMVPM4_EL2, x16
+	/*
+	 * MPAMIDR_EL1.VPMR_MAX has to be probed to obtain the maximum supported
+	 * VPMR value. Proceed to restore the context of registers from
+	 * MPAMVPM1_EL2 to MPAMVPM<x>_EL2 where x is VPMR_MAX. from MPAM spec,
+	 * VPMR_MAX should not be zero if HAS_HCR == 1.
+	 */
+	ubfx	x10, x10, #MPAMIDR_EL1_VPMR_MAX_SHIFT,	\
+		#MPAMIDR_EL1_VPMR_MAX_WIDTH
 
-	ldp	x9, x10, [x0, #CTX_MPAMVPM5_EL2]
-	msr	MPAMVPM5_EL2, x9
-	msr	MPAMVPM6_EL2, x10
+	/*
+	 * Once VPMR_MAX has been identified, calculate the offset relative to
+	 * PC to jump to so that relevant context can be restored. The offset is
+	 * calculated as (VPMR_POSSIBLE_MAX - VPMR_MAX) * (instruction size for
+	 * restoring one VPM register) + (absolute address of label "1").
+	 */
+	mov	w11, #MPAMIDR_EL1_VPMR_MAX_POSSIBLE
+	sub	w10, w11, w10
 
-	ldp	x11, x12, [x0, #CTX_MPAMVPM7_EL2]
-	msr	MPAMVPM7_EL2, x11
-	msr	MPAMVPMV_EL2, x12
-	ret
-endfunc el2_sysregs_context_restore_mpam
-#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
+	/* Calculate the size of one block of MPAMVPM*_EL2 restore */
+	adr	x11, 1f
+	adr	x12, 2f
+	sub	x12, x12, x11
 
-#if ENABLE_FEAT_FGT
-func el2_sysregs_context_save_fgt
-	mrs	x13, HDFGRTR_EL2
-#if ENABLE_FEAT_AMUv1
-	mrs	x14, HAFGRTR_EL2
-	stp	x13, x14, [x0, #CTX_HDFGRTR_EL2]
-#else
-	str	x13, [x0, #CTX_HDFGRTR_EL2]
-#endif /* ENABLE_FEAT_AMUv1 */
-	mrs	x15, HDFGWTR_EL2
-	mrs	x16, HFGITR_EL2
-	stp	x15, x16, [x0, #CTX_HDFGWTR_EL2]
+	madd	x10, x10, x12, x11
+	br	x10
 
-	mrs	x9, HFGRTR_EL2
-	mrs	x10, HFGWTR_EL2
-	stp	x9, x10, [x0, #CTX_HFGRTR_EL2]
-	ret
-endfunc el2_sysregs_context_save_fgt
+	/*
+	 * The branch above would land properly on one of the blocks following
+	 * label "1". Make sure that the order of restore is retained.
+	 */
+1:
 
-func el2_sysregs_context_restore_fgt
-	#if ENABLE_FEAT_AMUv1
-	ldp	x13, x14, [x0, #CTX_HDFGRTR_EL2]
-	msr	HAFGRTR_EL2, x14
-#else
-	ldr	x13, [x0, #CTX_HDFGRTR_EL2]
-#endif /* ENABLE_FEAT_AMUv1 */
-	msr	HDFGRTR_EL2, x13
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x10, [x0, #CTX_MPAMVPM7_EL2]
+	msr	MPAMVPM7_EL2, x10
+2:
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x11, [x0, #CTX_MPAMVPM6_EL2]
+	msr	MPAMVPM6_EL2, x11
 
-	ldp	x15, x16, [x0, #CTX_HDFGWTR_EL2]
-	msr	HDFGWTR_EL2, x15
-	msr	HFGITR_EL2, x16
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x12, [x0, #CTX_MPAMVPM5_EL2]
+	msr	MPAMVPM5_EL2, x12
 
-	ldp	x9, x10, [x0, #CTX_HFGRTR_EL2]
-	msr	HFGRTR_EL2, x9
-	msr	HFGWTR_EL2, x10
-	ret
-endfunc el2_sysregs_context_restore_fgt
-#endif /* ENABLE_FEAT_FGT */
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x13, [x0, #CTX_MPAMVPM4_EL2]
+	msr	MPAMVPM4_EL2, x13
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x14, [x0, #CTX_MPAMVPM3_EL2]
+	msr	MPAMVPM3_EL2, x14
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x15, [x0, #CTX_MPAMVPM2_EL2]
+	msr	MPAMVPM2_EL2, x15
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x16, [x0, #CTX_MPAMVPM1_EL2]
+	msr	MPAMVPM1_EL2, x16
+
+3:	ret
+endfunc el2_sysregs_context_restore_mpam
+#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
 
 #if ENABLE_FEAT_ECV
 func el2_sysregs_context_save_ecv
@@ -475,19 +576,6 @@
 endfunc el2_sysregs_context_restore_csv2
 #endif /* ENABLE_FEAT_CSV2_2 */
 
-#if ENABLE_FEAT_HCX
-func el2_sysregs_context_save_hcx
-	mrs	x14, hcrx_el2
-	str	x14, [x0, #CTX_HCRX_EL2]
-	ret
-endfunc el2_sysregs_context_save_hcx
-
-func el2_sysregs_context_restore_hcx
-	ldr	x14, [x0, #CTX_HCRX_EL2]
-	msr	hcrx_el2, x14
-	ret
-endfunc el2_sysregs_context_restore_hcx
-#endif /* ENABLE_FEAT_HCX */
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 /* ------------------------------------------------------------------
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 866ac41..dab25d6 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -169,7 +169,12 @@
 	state = get_el3state_ctx(ctx);
 	scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
 
-	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT;
+	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT;
+
+#if ENABLE_FEAT_CSV2_2
+	/* Enable access to the SCXTNUM_ELx registers. */
+	scr_el3 |= SCR_EnSCXT_BIT;
+#endif
 
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 }
@@ -222,6 +227,11 @@
 	scr_el3 |= SCR_TERR_BIT;
 #endif
 
+#if ENABLE_FEAT_CSV2_2
+	/* Enable access to the SCXTNUM_ELx registers. */
+	scr_el3 |= SCR_EnSCXT_BIT;
+#endif
+
 #ifdef IMAGE_BL31
 	/*
 	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
@@ -320,9 +330,9 @@
 	 * If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting
 	 * SCR_EL3.HXEn.
 	 */
-#if ENABLE_FEAT_HCX
-	scr_el3 |= SCR_HXEn_BIT;
-#endif
+	if (is_feat_hcx_supported()) {
+		scr_el3 |= SCR_HXEn_BIT;
+	}
 
 	/*
 	 * If FEAT_RNG_TRAP is enabled, all reads of the RNDR and RNDRRS
@@ -359,7 +369,7 @@
 		&& (GET_M32(ep->spsr) == MODE32_hyp))) {
 		scr_el3 |= SCR_HCE_BIT;
 
-		if (is_armv8_6_fgt_present()) {
+		if (is_feat_fgt_supported()) {
 			scr_el3 |= SCR_FGTEN_BIT;
 		}
 
@@ -792,6 +802,35 @@
 }
 
 #if CTX_INCLUDE_EL2_REGS
+
+static void el2_sysregs_context_save_fgt(el2_sysregs_t *ctx)
+{
+	if (is_feat_fgt_supported()) {
+		write_ctx_reg(ctx, CTX_HDFGRTR_EL2, read_hdfgrtr_el2());
+		if (is_feat_amu_supported()) {
+			write_ctx_reg(ctx, CTX_HAFGRTR_EL2, read_hafgrtr_el2());
+		}
+		write_ctx_reg(ctx, CTX_HDFGWTR_EL2, read_hdfgwtr_el2());
+		write_ctx_reg(ctx, CTX_HFGITR_EL2, read_hfgitr_el2());
+		write_ctx_reg(ctx, CTX_HFGRTR_EL2, read_hfgrtr_el2());
+		write_ctx_reg(ctx, CTX_HFGWTR_EL2, read_hfgwtr_el2());
+	}
+}
+
+static void el2_sysregs_context_restore_fgt(el2_sysregs_t *ctx)
+{
+	if (is_feat_fgt_supported()) {
+		write_hdfgrtr_el2(read_ctx_reg(ctx, CTX_HDFGRTR_EL2));
+		if (is_feat_amu_supported()) {
+			write_hafgrtr_el2(read_ctx_reg(ctx, CTX_HAFGRTR_EL2));
+		}
+		write_hdfgwtr_el2(read_ctx_reg(ctx, CTX_HDFGWTR_EL2));
+		write_hfgitr_el2(read_ctx_reg(ctx, CTX_HFGITR_EL2));
+		write_hfgrtr_el2(read_ctx_reg(ctx, CTX_HFGRTR_EL2));
+		write_hfgwtr_el2(read_ctx_reg(ctx, CTX_HFGWTR_EL2));
+	}
+}
+
 /*******************************************************************************
  * Save EL2 sysreg context
  ******************************************************************************/
@@ -823,9 +862,9 @@
 #if ENABLE_MPAM_FOR_LOWER_ELS
 		el2_sysregs_context_save_mpam(el2_sysregs_ctx);
 #endif
-#if ENABLE_FEAT_FGT
+
 		el2_sysregs_context_save_fgt(el2_sysregs_ctx);
-#endif
+
 #if ENABLE_FEAT_ECV
 		el2_sysregs_context_save_ecv(el2_sysregs_ctx);
 #endif
@@ -844,9 +883,9 @@
 #if ENABLE_FEAT_CSV2_2
 		el2_sysregs_context_save_csv2(el2_sysregs_ctx);
 #endif
-#if ENABLE_FEAT_HCX
-		el2_sysregs_context_save_hcx(el2_sysregs_ctx);
-#endif
+		if (is_feat_hcx_supported()) {
+			write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2());
+		}
 	}
 }
 
@@ -881,9 +920,9 @@
 #if ENABLE_MPAM_FOR_LOWER_ELS
 		el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
 #endif
-#if ENABLE_FEAT_FGT
+
 		el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
-#endif
+
 #if ENABLE_FEAT_ECV
 		el2_sysregs_context_restore_ecv(el2_sysregs_ctx);
 #endif
@@ -902,9 +941,9 @@
 #if ENABLE_FEAT_CSV2_2
 		el2_sysregs_context_restore_csv2(el2_sysregs_ctx);
 #endif
-#if ENABLE_FEAT_HCX
-		el2_sysregs_context_restore_hcx(el2_sysregs_ctx);
-#endif
+		if (is_feat_hcx_supported()) {
+			write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2));
+		}
 	}
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
index 351772e..13081b0 100644
--- a/lib/fconf/fconf_dyn_cfg_getter.c
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,7 +31,7 @@
  * This function is used to alloc memory for config information from
  * global pool and set the configuration information.
  */
-void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+void set_config_info(uintptr_t config_addr, uintptr_t secondary_config_addr,
 		     uint32_t config_max_size,
 		     unsigned int config_id)
 {
@@ -39,7 +39,7 @@
 
 	dtb_info = pool_alloc(&dtb_info_pool);
 	dtb_info->config_addr = config_addr;
-	dtb_info->ns_config_addr = ns_config_addr;
+	dtb_info->secondary_config_addr = secondary_config_addr;
 	dtb_info->config_max_size = config_max_size;
 	dtb_info->config_id = config_id;
 }
@@ -106,7 +106,7 @@
 	fdt_for_each_subnode(child, dtb, node) {
 		uint32_t config_max_size, config_id;
 		uintptr_t config_addr;
-		uintptr_t ns_config_addr = ~0UL;
+		uintptr_t secondary_config_addr = ~0UL;
 		uint64_t val64;
 
 		/* Read configuration dtb information */
@@ -134,14 +134,16 @@
 		VERBOSE("\tmax-size = 0x%x\n", config_max_size);
 		VERBOSE("\tconfig-id = %u\n", config_id);
 
-		rc = fdt_read_uint64(dtb, child, "ns-load-address", &val64);
+		rc = fdt_read_uint64(dtb, child, "secondary-load-address",
+				     &val64);
 		if (rc == 0) {
-			ns_config_addr = (uintptr_t)val64;
-			VERBOSE("\tns-load-address = %lx\n", ns_config_addr);
+			secondary_config_addr = (uintptr_t)val64;
+			VERBOSE("\tsecondary-load-address = %lx\n",
+				secondary_config_addr);
 		}
 
-		set_config_info(config_addr, ns_config_addr, config_max_size,
-				config_id);
+		set_config_info(config_addr, secondary_config_addr,
+				config_max_size, config_id);
 	}
 
 	if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
diff --git a/lib/libc/putchar.c b/lib/libc/putchar.c
index 3472b24..340bdd8 100644
--- a/lib/libc/putchar.c
+++ b/lib/libc/putchar.c
@@ -1,14 +1,13 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdio.h>
 
-int __putchar(int c)
+#pragma weak putchar
+int putchar(int c)
 {
 	return c;
 }
-
-int putchar(int c) __attribute__((weak,alias("__putchar")));
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
index 6a2f0ba..0e3256c 100644
--- a/lib/libc/snprintf.c
+++ b/lib/libc/snprintf.c
@@ -209,6 +209,7 @@
 				break;
 			case 'X':
 				capitalise = true;
+				/* fallthrough */
 			case 'x':
 				unum = get_unum_va_args(args, l_count);
 				unsigned_num_print(&s, n, &chars_printed,
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index 6c87b0d..25272fc 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,42 +11,6 @@
 
 #include <platform_def.h>
 
-/*
- * load_addr_hi and load_addr_lo: image load address.
- * image_id: 0 - pager, 1 - paged
- * size: image size in bytes.
- */
-typedef struct optee_image {
-	uint32_t load_addr_hi;
-	uint32_t load_addr_lo;
-	uint32_t image_id;
-	uint32_t size;
-} optee_image_t;
-
-#define OPTEE_PAGER_IMAGE_ID		0
-#define OPTEE_PAGED_IMAGE_ID		1
-
-#define OPTEE_MAX_NUM_IMAGES		2u
-
-#define TEE_MAGIC_NUM_OPTEE		0x4554504f
-/*
- * magic: header magic number.
- * version: OPTEE header version:
- *		1 - not supported
- *		2 - supported
- * arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64.
- * flags: unused currently.
- * nb_images: number of images.
- */
-typedef struct optee_header {
-	uint32_t magic;
-	uint8_t version;
-	uint8_t arch;
-	uint16_t flags;
-	uint32_t nb_images;
-	optee_image_t optee_image_list[];
-} optee_header_t;
-
 /*******************************************************************************
  * Check if it is a valid tee header
  * Return true if valid
diff --git a/lib/psa/rss_platform.c b/lib/psa/rss_platform.c
new file mode 100644
index 0000000..359f894
--- /dev/null
+++ b/lib/psa/rss_platform.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+#include <psa/client.h>
+#include <psa_manifest/sid.h>
+#include <rss_platform_api.h>
+
+psa_status_t
+rss_platform_nv_counter_increment(uint32_t counter_id)
+{
+	struct psa_invec in_vec[1];
+
+	in_vec[0].base = &counter_id;
+	in_vec[0].len = sizeof(counter_id);
+
+	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
+			RSS_PLATFORM_API_ID_NV_INCREMENT,
+			in_vec, 1, NULL, 0);
+}
+
+psa_status_t
+rss_platform_nv_counter_read(uint32_t counter_id,
+		uint32_t size, uint8_t *val)
+{
+	struct psa_invec in_vec[1];
+	struct psa_outvec out_vec[1];
+
+	in_vec[0].base = &counter_id;
+	in_vec[0].len = sizeof(counter_id);
+
+	out_vec[0].base = val;
+	out_vec[0].len = size;
+
+	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
+			RSS_PLATFORM_API_ID_NV_READ,
+			in_vec, 1, out_vec, 1);
+}
diff --git a/lib/psci/aarch32/psci_helpers.S b/lib/psci/aarch32/psci_helpers.S
index 5cc192e..d28d469 100644
--- a/lib/psci/aarch32/psci_helpers.S
+++ b/lib/psci/aarch32/psci_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -143,6 +143,7 @@
  */
 func psci_power_down_wfi
 	dsb	sy		// ensure write buffer empty
+1:
 	wfi
-	no_ret	plat_panic_handler
+	b	1b
 endfunc psci_power_down_wfi
diff --git a/lib/psci/aarch64/psci_helpers.S b/lib/psci/aarch64/psci_helpers.S
index add968a..61f31e5 100644
--- a/lib/psci/aarch64/psci_helpers.S
+++ b/lib/psci/aarch64/psci_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -124,7 +124,11 @@
  * -----------------------------------------------------------------------
  */
 func psci_power_down_wfi
+#if ERRATA_A510_2684597
+	bl apply_cpu_pwr_dwn_errata
+#endif
 	dsb	sy		// ensure write buffer empty
+1:
 	wfi
-	no_ret	plat_panic_handler
+	b	1b
 endfunc psci_power_down_wfi
diff --git a/lib/psci/psci_lib.mk b/lib/psci/psci_lib.mk
index 1d4aac4..6864202 100644
--- a/lib/psci/psci_lib.mk
+++ b/lib/psci/psci_lib.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -21,7 +21,8 @@
 				lib/psci/${ARCH}/psci_helpers.S
 
 ifeq (${ARCH}, aarch64)
-PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S
+PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S	\
+				lib/cpus/aarch64/runtime_errata.S
 endif
 
 ifeq (${USE_COHERENT_MEM}, 1)
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 1901c17..6ca9ef6 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -304,6 +304,9 @@
  */
 void prepare_cpu_pwr_dwn(unsigned int power_level);
 
+/* This function applies various CPU errata during power down. */
+void apply_cpu_pwr_dwn_errata(void);
+
 /* Private exported functions from psci_on.c */
 int psci_cpu_on_start(u_register_t target_cpu,
 		      const entry_point_info_t *ep);
diff --git a/lib/romlib/romlib.ld.S b/lib/romlib/romlib.ld.S
index 2aac4ad..d54a684 100644
--- a/lib/romlib/romlib.ld.S
+++ b/lib/romlib/romlib.ld.S
@@ -8,37 +8,42 @@
 #include <platform_def.h>
 
 MEMORY {
-	ROM (rx): ORIGIN = ROMLIB_RO_BASE, LENGTH = ROMLIB_RO_LIMIT - ROMLIB_RO_BASE
-	RAM (rwx): ORIGIN = ROMLIB_RW_BASE, LENGTH = ROMLIB_RW_END - ROMLIB_RW_BASE
+    ROM (rx): ORIGIN = ROMLIB_RO_BASE, LENGTH = ROMLIB_RO_LIMIT - ROMLIB_RO_BASE
+    RAM (rwx): ORIGIN = ROMLIB_RW_BASE, LENGTH = ROMLIB_RW_END - ROMLIB_RW_BASE
 }
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(jmptbl)
 
-SECTIONS
-{
-	. = ROMLIB_RO_BASE;
-	.text : {
-		*jmptbl.o(.text)
-		*(.text*)
-		*(.rodata*)
-	} >ROM
+SECTIONS {
+    . = ROMLIB_RO_BASE;
 
-	__DATA_ROM_START__ = LOADADDR(.data);
+    .text : {
+        *jmptbl.o(.text)
+        *(.text*)
+        *(.rodata*)
+    } >ROM
 
-	.data : {
-		__DATA_RAM_START__ = .;
-		*(.data*)
-		__DATA_RAM_END__ = .;
-	} >RAM AT>ROM
+    __DATA_ROM_START__ = LOADADDR(.data);
 
-	__DATA_SIZE__ = SIZEOF(.data);
+    .data : {
+        __DATA_RAM_START__ = .;
+
+        *(.data*)
+
+        __DATA_RAM_END__ = .;
+    } >RAM AT>ROM
+
+    __DATA_SIZE__ = SIZEOF(.data);
+
+    .bss : {
+        __BSS_START__ = .;
+
+        *(.bss*)
+
+        __BSS_END__ = .;
+     } >RAM
 
-	.bss : {
-		__BSS_START__ = .;
-		*(.bss*)
-		__BSS_END__ = .;
-	 } >RAM
-	__BSS_SIZE__ = SIZEOF(.bss);
+    __BSS_SIZE__ = SIZEOF(.bss);
 }
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 426e344..a6b1d52 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -13,6 +13,7 @@
 # Some utility macros for manipulating awkward (whitespace) characters.
 blank			:=
 space			:=${blank} ${blank}
+comma			:= ,
 
 # A user defined function to recursively search for a filename below a directory
 #    $1 is the directory root of the recursive search (blank for current directory).
@@ -97,12 +98,6 @@
 )
 endef
 
-# IMG_LINKERFILE defines the linker script corresponding to a BL stage
-#   $(1) = BL stage
-define IMG_LINKERFILE
-    ${BUILD_DIR}/$(1).ld
-endef
-
 # IMG_MAPFILE defines the output file describing the memory map corresponding
 # to a BL stage
 #   $(1) = BL stage
@@ -457,6 +452,15 @@
 	$$(Q)$$(AR) cr $$@ $$?
 endef
 
+# Generate the path to one or more preprocessed linker scripts given the paths
+# of their sources.
+#
+# Arguments:
+#   $(1) = path to one or more linker script sources
+define linker_script_path
+        $(patsubst %.S,$(BUILD_DIR)/%,$(1))
+endef
+
 # MAKE_BL macro defines the targets and options to build each BL image.
 # Arguments:
 #   $(1) = BL stage
@@ -468,17 +472,22 @@
         $(eval BL_SOURCES := $($(call uppercase,$(1))_SOURCES))
         $(eval SOURCES    := $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
-        $(eval LINKERFILE := $(call IMG_LINKERFILE,$(1)))
         $(eval MAPFILE    := $(call IMG_MAPFILE,$(1)))
         $(eval ELF        := $(call IMG_ELF,$(1)))
         $(eval DUMP       := $(call IMG_DUMP,$(1)))
         $(eval BIN        := $(call IMG_BIN,$(1)))
         $(eval ENC_BIN    := $(call IMG_ENC_BIN,$(1)))
-        $(eval BL_LINKERFILE := $($(call uppercase,$(1))_LINKERFILE))
         $(eval BL_LIBS    := $($(call uppercase,$(1))_LIBS))
+
+        $(eval DEFAULT_LINKER_SCRIPT_SOURCE := $($(call uppercase,$(1))_DEFAULT_LINKER_SCRIPT_SOURCE))
+        $(eval DEFAULT_LINKER_SCRIPT := $(call linker_script_path,$(DEFAULT_LINKER_SCRIPT_SOURCE)))
+
+        $(eval LINKER_SCRIPT_SOURCES := $($(call uppercase,$(1))_LINKER_SCRIPT_SOURCES))
+        $(eval LINKER_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} ${LINKERFILE})))
+        $(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)))
@@ -487,7 +496,8 @@
 
 $(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
 
-$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
+$(eval $(foreach objd,${OBJ_DIRS},
+        $(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
 
 .PHONY : ${1}_dirs
 
@@ -496,7 +506,11 @@
 ${1}_dirs: | ${OBJ_DIRS}
 
 $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
-$(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE),$(1)))
+
+# Generate targets to preprocess each required linker script
+$(eval $(foreach source,$(DEFAULT_LINKER_SCRIPT_SOURCE) $(LINKER_SCRIPT_SOURCES), \
+        $(call MAKE_LD,$(call linker_script_path,$(source)),$(source),$(1))))
+
 $(eval BL_LDFLAGS := $($(call uppercase,$(1))_LDFLAGS))
 
 ifeq ($(USE_ROMLIB),1)
@@ -507,7 +521,7 @@
 # object file path, and prebuilt object file path.
 $(eval OBJS += $(MODULE_OBJS))
 
-$(ELF): $(OBJS) $(LINKERFILE) | $(1)_dirs libraries $(BL_LIBS)
+$(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $(1)_dirs libraries $(BL_LIBS)
 	$$(ECHO) "  LD      $$@"
 ifdef MAKE_BUILD_STRINGS
 	$(call MAKE_BUILD_STRINGS, $(BUILD_DIR)/build_message.o)
@@ -526,11 +540,13 @@
 		$(BUILD_DIR)/build_message.o $(OBJS)
 else ifneq ($(findstring gcc,$(notdir $(LD))),)
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
-		-Wl,-dT $(LINKERFILE) $(EXTRA_LINKERFILE) $(BUILD_DIR)/build_message.o \
+		$(addprefix -Wl$(comma)--script$(comma),$(LINKER_SCRIPTS)) -Wl,--script,$(DEFAULT_LINKER_SCRIPT) \
+		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 else
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
-		--script $(LINKERFILE) $(BUILD_DIR)/build_message.o \
+		$(addprefix -T ,$(LINKER_SCRIPTS)) --script $(DEFAULT_LINKER_SCRIPT) \
+		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 endif
 ifeq ($(DISABLE_BIN_GENERATION),1)
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index d298e6b..1257076 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -8,8 +8,10 @@
 #include <errno.h>
 
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/allwinner/axp.h>
 #include <drivers/allwinner/sunxi_rsb.h>
+#include <libfdt.h>
 #include <lib/mmio.h>
 
 #include <sunxi_cpucfg.h>
@@ -63,7 +65,12 @@
 
 int sunxi_pmic_setup(uint16_t socid, const void *fdt)
 {
-	int ret;
+	int node, ret;
+
+	node = fdt_node_offset_by_compatible(fdt, 0, "allwinner,sun8i-a23-rsb");
+	if ((node < 0) || !fdt_node_is_enabled(fdt, node)) {
+		return -ENODEV;
+	}
 
 	INFO("PMIC: Probing AXP805 on RSB\n");
 
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
index 45e3b7e..43dc17b 100644
--- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,15 @@
 struct hw_topology_t soc_topology;
 struct uart_serial_config_t uart_serial_config;
 struct cpu_timer_t cpu_timer;
+struct ns_dram_layout dram_layout;
+
+/*
+ * Each NS DRAM bank entry is 'reg' node property which is
+ * a sequence of (address, length) pairs of 32-bit values.
+ */
+#define DRAM_ENTRY_SIZE		(4UL * sizeof(uint32_t))
+
+CASSERT(ARM_DRAM_NUM_BANKS == 2UL, ARM_DRAM_NUM_BANKS_mismatch);
 
 #define ILLEGAL_ADDR	ULL(~0)
 
@@ -293,7 +302,58 @@
 	return 0;
 }
 
+int fconf_populate_dram_layout(uintptr_t config)
+{
+	int node, len;
+	const uint32_t *reg;
+
+	/* Necessary to work with libfdt APIs */
+	const void *hw_config_dtb = (const void *)config;
+
+	/* Find 'memory' node */
+	node = fdt_node_offset_by_prop_value(hw_config_dtb, -1, "device_type",
+					     "memory", sizeof("memory"));
+	if (node < 0) {
+		WARN("FCONF: Unable to locate 'memory' node\n");
+		return node;
+	}
+
+	reg = fdt_getprop(hw_config_dtb, node, "reg", &len);
+	if (reg == NULL) {
+		ERROR("FCONF failed to read 'reg' property\n");
+		return len;
+	}
+
+	switch (len) {
+	case DRAM_ENTRY_SIZE:
+		/* 1 DRAM bank */
+		dram_layout.num_banks = 1UL;
+		break;
+	case 2UL * DRAM_ENTRY_SIZE:
+		/* 2 DRAM banks */
+		dram_layout.num_banks = 2UL;
+		break;
+	default:
+		ERROR("FCONF: Invalid 'memory' node\n");
+		return -FDT_ERR_BADLAYOUT;
+	}
+
+	for (unsigned long i = 0UL; i < dram_layout.num_banks; i++) {
+		int err = fdt_get_reg_props_by_index(
+				hw_config_dtb, node, (int)i,
+				&dram_layout.dram_bank[i].base,
+				(size_t *)&dram_layout.dram_bank[i].size);
+		if (err < 0) {
+			ERROR("FCONF: Failed to read 'reg' property #%lu of 'memory' node\n", i);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
 FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, cpu_timer, fconf_populate_cpu_timer);
+FCONF_REGISTER_POPULATOR(HW_CONFIG, dram_layout, fconf_populate_dram_layout);
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index 577ac74..4adf5d5 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,7 +22,7 @@
 			load-address = <0x0 0x07f00000>;
 			max-size = <0x00100000>;
 			id = <HW_CONFIG_ID>;
-			ns-load-address = <0x0 0x82000000>;
+			secondary-load-address = <0x0 0x82000000>;
 		};
 
 		/*
@@ -40,7 +40,11 @@
 /* If required, SPD should enable loading of trusted OS fw config */
 #if defined(SPD_tspd) || defined(SPD_spmd)
 		tos_fw-config {
+
 			load-address = <0x0 0x04001500>;
+#if ENABLE_RME
+			secondary-load-address = <0x0 0x7e00000>;
+#endif /* ENABLE_RME */
 			max-size = <0xB00>;
 			id = <TOS_FW_CONFIG_ID>;
 		};
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 74e5d72..4c71d81 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -82,7 +82,7 @@
 	assert(param_node != NULL);
 
 	/* Copy HW config from Secure address to NS address */
-	memcpy((void *)hw_config_info->ns_config_addr,
+	memcpy((void *)hw_config_info->secondary_config_addr,
 	       (void *)hw_config_info->config_addr,
 	       (size_t)param_node->image_info.image_size);
 
@@ -91,14 +91,14 @@
 	 * a possibility to use HW-config without cache and MMU enabled
 	 * at BL33
 	 */
-	flush_dcache_range(hw_config_info->ns_config_addr,
+	flush_dcache_range(hw_config_info->secondary_config_addr,
 			   param_node->image_info.image_size);
 
 	param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
 	assert(param_node != NULL);
 
 	/* Update BL33's ep info with NS HW config address  */
-	param_node->ep_info.args.arg1 = hw_config_info->ns_config_addr;
+	param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr;
 #endif /* !BL2_AT_EL3 && !EL3_PAYLOAD_BASE */
 
 	return arm_bl_params;
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index dd90965..57865eb 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,8 +45,8 @@
 	 */
 	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 	assert(hw_config_info != NULL);
-	assert(hw_config_info->ns_config_addr != 0UL);
-	arg2 = hw_config_info->ns_config_addr;
+	assert(hw_config_info->secondary_config_addr != 0UL);
+	arg2 = hw_config_info->secondary_config_addr;
 #endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */
 
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index f5d9940..c7bf93e 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,19 +12,19 @@
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/sp804_delay_timer.h>
 #include <drivers/generic_delay_timer.h>
+#include <fconf_hw_config_getter.h>
 #include <lib/mmio.h>
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <platform_def.h>
 #include <services/arm_arch_svc.h>
-#if ENABLE_RME
 #include <services/rmm_core_manifest.h>
-#endif
 #if SPM_MM
 #include <services/spm_mm_partition.h>
 #endif
 
 #include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/arm_pas_def.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -531,15 +531,73 @@
 	return (size_t)RMM_SHARED_SIZE;
 }
 
-int plat_rmmd_load_manifest(rmm_manifest_t *manifest)
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
+	uint64_t checksum, num_banks;
+	struct ns_dram_bank *bank_ptr;
+
 	assert(manifest != NULL);
 
+	/* Get number of DRAM banks */
+	num_banks = FCONF_GET_PROPERTY(hw_config, dram_layout, num_banks);
+	assert(num_banks <= ARM_DRAM_NUM_BANKS);
+
 	manifest->version = RMMD_MANIFEST_VERSION;
 	manifest->padding = 0U; /* RES0 */
 	manifest->plat_data = (uintptr_t)NULL;
+	manifest->plat_dram.num_banks = num_banks;
+
+	/*
+	 * Array ns_dram_banks[] follows ns_dram_info structure:
+	 *
+	 * +-----------------------------------+
+	 * |  offset  |   field   |  comment   |
+	 * +----------+-----------+------------+
+	 * |    0     |  version  | 0x00000002 |
+	 * +----------+-----------+------------+
+	 * |    4     |  padding  | 0x00000000 |
+	 * +----------+-----------+------------+
+	 * |    8     | plat_data |    NULL    |
+	 * +----------+-----------+------------+
+	 * |    16    | num_banks |            |
+	 * +----------+-----------+            |
+	 * |    24    |   banks   | plat_dram  |
+	 * +----------+-----------+            |
+	 * |    32    | checksum  |            |
+	 * +----------+-----------+------------+
+	 * |    40    |  base 0   |            |
+	 * +----------+-----------+   bank[0]  |
+	 * |    48    |  size 0   |            |
+	 * +----------+-----------+------------+
+	 * |    56    |  base 1   |            |
+	 * +----------+-----------+   bank[1]  |
+	 * |    64    |  size 1   |            |
+	 * +----------+-----------+------------+
+	 */
+	bank_ptr = (struct ns_dram_bank *)
+			((uintptr_t)&manifest->plat_dram.checksum +
+			sizeof(manifest->plat_dram.checksum));
+
+	manifest->plat_dram.banks = bank_ptr;
+
+	/* Calculate checksum of plat_dram structure */
+	checksum = num_banks + (uint64_t)bank_ptr;
+
+	/* Store FVP DRAM banks data in Boot Manifest */
+	for (unsigned long i = 0UL; i < num_banks; i++) {
+		uintptr_t base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base);
+		uint64_t size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size);
+
+		bank_ptr[i].base = base;
+		bank_ptr[i].size = size;
+
+		/* Update checksum */
+		checksum += base + size;
+	}
+
+	/* Checksum must be 0 */
+	manifest->plat_dram.checksum = ~checksum + 1UL;
 
 	return 0;
 }
-
-#endif
+#endif	/* ENABLE_RME */
diff --git a/plat/arm/board/fvp/fvp_sync_traps.c b/plat/arm/board/fvp/fvp_sync_traps.c
new file mode 100644
index 0000000..91240f7
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_sync_traps.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2022, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file just contains demonstration code, to "handle" RNG traps.
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <bl31/sync_handle.h>
+#include <context.h>
+
+/*
+ * SCR_EL3.SCR_TRNDR_BIT also affects execution in EL3, so allow to disable
+ * the trap temporarily.
+ */
+static void enable_rng_trap(bool enable)
+{
+	uint64_t scr_el3 = read_scr_el3();
+
+	if (enable) {
+		scr_el3 |= SCR_TRNDR_BIT;
+	} else {
+		scr_el3 &= ~SCR_TRNDR_BIT;
+	}
+
+	write_scr_el3(scr_el3);
+	isb();
+}
+
+/*
+ * This emulation code here is not very meaningful: enabling the RNG
+ * trap typically happens for a reason, so just calling the actual
+ * hardware instructions might not be useful or even possible.
+ */
+int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx)
+{
+	/* extract the target register number from the exception syndrome */
+	unsigned int rt = get_sysreg_iss_rt(esr_el3);
+
+	/* ignore XZR accesses and writes to the register */
+	if (rt == 31 || is_sysreg_iss_write(esr_el3)) {
+		return TRAP_RET_CONTINUE;
+	}
+
+	enable_rng_trap(false);
+	if ((esr_el3 & ISS_SYSREG_OPCODE_MASK) == ISS_SYSREG_OPCODE_RNDR) {
+		ctx->gpregs_ctx.ctx_regs[rt] = read_rndr();
+	} else {
+		ctx->gpregs_ctx.ctx_regs[rt] = read_rndrrs();
+	}
+	enable_rng_trap(true);
+
+	/*
+	 * We successfully handled the trap, continue with the next
+	 * instruction.
+	 */
+	return TRAP_RET_CONTINUE;
+}
diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
index ca85f7a..b7a1247 100644
--- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h
+++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,12 +8,16 @@
 #define FCONF_HW_CONFIG_GETTER_H
 
 #include <lib/fconf/fconf.h>
+#include <services/rmm_core_manifest.h>
+
+#include <plat/arm/common/arm_def.h>
 
 /* Hardware Config related getter */
 #define hw_config__gicv3_config_getter(prop) gicv3_config.prop
 #define hw_config__topology_getter(prop) soc_topology.prop
 #define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop
 #define hw_config__cpu_timer_getter(prop) cpu_timer.prop
+#define hw_config__dram_layout_getter(prop) dram_layout.prop
 
 struct gicv3_config_t {
 	uint64_t gicd_base;
@@ -36,13 +40,21 @@
 	uint32_t clock_freq;
 };
 
+struct ns_dram_layout {
+	uint64_t num_banks;
+	struct ns_dram_bank dram_bank[ARM_DRAM_NUM_BANKS];
+};
+
 int fconf_populate_gicv3_config(uintptr_t config);
 int fconf_populate_topology(uintptr_t config);
 int fconf_populate_uart_config(uintptr_t config);
 int fconf_populate_cpu_timer(uintptr_t config);
+int fconf_populate_dram_layout(uintptr_t config);
 
 extern struct gicv3_config_t gicv3_config;
 extern struct hw_topology_t soc_topology;
 extern struct uart_serial_config_t uart_serial_config;
 extern struct cpu_timer_t cpu_timer;
+extern struct ns_dram_layout dram_layout;
+
 #endif /* FCONF_HW_CONFIG_GETTER_H */
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 85e6e3a..927ffef 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -21,6 +21,7 @@
 fdt     fdt_setprop_inplace
 fdt     fdt_check_header
 fdt     fdt_node_offset_by_compatible
+fdt     fdt_node_offset_by_prop_value
 fdt     fdt_setprop_inplace_namelen_partial
 fdt     fdt_first_subnode
 fdt     fdt_next_subnode
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 51ba035..efbf68f 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -198,6 +198,10 @@
 				plat/arm/board/fvp/fvp_realm_attest_key.c
 endif
 
+ifeq (${ENABLE_FEAT_RNG_TRAP},1)
+BL31_SOURCES		+=	plat/arm/board/fvp/fvp_sync_traps.c
+endif
+
 ifeq (${BL2_AT_EL3},1)
 BL2_SOURCES		+=	plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
 				plat/arm/board/fvp/fvp_bl2_el3_setup.c		\
@@ -459,6 +463,10 @@
 # enable trace filter control registers access to NS by default
 ENABLE_TRF_FOR_NS		:= 1
 
+# Linux relies on EL3 enablement if those features are present
+ENABLE_FEAT_FGT			:= 2
+ENABLE_FEAT_HCX			:= 2
+
 ifeq (${SPMC_AT_EL3}, 1)
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/board/fvp/fvp_el3_spmc.c
 endif
diff --git a/plat/arm/board/morello/fdts/morello_fw_config.dts b/plat/arm/board/morello/fdts/morello_fw_config.dts
index c47bae5..a63d7eb 100644
--- a/plat/arm/board/morello/fdts/morello_fw_config.dts
+++ b/plat/arm/board/morello/fdts/morello_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,8 +19,14 @@
 
 		nt_fw-config {
 			load-address = <0x0 0xFEF00000>;
-			max-size = <0x0100000>;
+			max-size = <0xF8000>;
 			id = <NT_FW_CONFIG_ID>;
 		};
+
+		hw-config {
+			load-address = <0x0 0xFEFF8000>;
+			max-size = <0x8000>;
+			id = <HW_CONFIG_ID>;
+		};
 	};
 };
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
index 156b7ea..0f0cabb 100644
--- a/plat/arm/board/morello/platform.mk
+++ b/plat/arm/board/morello/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -59,11 +59,14 @@
 				${MORELLO_BASE}/fdts/morello_nt_fw_config.dts
 
 FW_CONFIG		:=	${BUILD_PLAT}/fdts/morello_fw_config.dtb
+HW_CONFIG		:=	${BUILD_PLAT}/fdts/morello-${TARGET_PLATFORM}.dtb
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/morello_tb_fw_config.dtb
 NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/morello_nt_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index 3474016..8e63de5 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -92,6 +92,8 @@
 
 #if (CSS_SGI_PLATFORM_VARIANT == 1)
 #define PLAT_ARM_GICR_BASE		UL(0x30100000)
+#elif (CSS_SGI_PLATFORM_VARIANT == 3)
+#define PLAT_ARM_GICR_BASE		UL(0x30300000)
 #else
 #define PLAT_ARM_GICR_BASE		UL(0x301C0000)
 #endif
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index 7492fe5..b30e3fc 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -1,13 +1,13 @@
-# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-RD_N2_VARIANTS	:= 0 1 2
+RD_N2_VARIANTS	:= 0 1 2 3
 ifneq ($(CSS_SGI_PLATFORM_VARIANT),\
 	$(filter $(CSS_SGI_PLATFORM_VARIANT),$(RD_N2_VARIANTS)))
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-N2 should be 0, 1 or 2, currently set \
-     to ${CSS_SGI_PLATFORM_VARIANT}.")
+ $(error "CSS_SGI_PLATFORM_VARIANT for RD-N2 should be 0, 1, 2 or 3, currently \
+	set to ${CSS_SGI_PLATFORM_VARIANT}.")
 endif
 
 $(eval $(call CREATE_SEQ,SEQ,4))
diff --git a/plat/arm/board/rdn2/rdn2_topology.c b/plat/arm/board/rdn2/rdn2_topology.c
index 89300f8..24acc4d 100644
--- a/plat/arm/board/rdn2/rdn2_topology.c
+++ b/plat/arm/board/rdn2/rdn2_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,19 +16,22 @@
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-#if (CSS_SGI_PLATFORM_VARIANT != 2 || (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1))
+#if (PLAT_ARM_CLUSTER_COUNT > 4 || \
+	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1))
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 #endif
-#if (CSS_SGI_PLATFORM_VARIANT == 0 || (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 2))
+#if (PLAT_ARM_CLUSTER_COUNT > 8 || \
+	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 2))
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 #endif
-#if (CSS_SGI_PLATFORM_VARIANT == 0 || (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 3))
+#if (PLAT_ARM_CLUSTER_COUNT > 8 || \
+	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 3))
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
@@ -83,7 +86,7 @@
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
-#if (CSS_SGI_PLATFORM_VARIANT == 0)
+#if (PLAT_ARM_CLUSTER_COUNT > 8)
 	(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)),
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 0fe4a0a..a3b7839 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -25,13 +25,28 @@
  * The top 16MB of ARM_DRAM1 is configured as secure access only using the TZC,
  * its base is ARM_AP_TZC_DRAM1_BASE.
  *
- * Reserve 32MB below ARM_AP_TZC_DRAM1_BASE for:
+ * Reserve 96 MB below ARM_AP_TZC_DRAM1_BASE for:
  *   - BL32_BASE when SPD_spmd is enabled
- *   - Region to load Trusted OS
+ *   - Region to load secure partitions
+ *
+ *
+ *  0xF900_0000  ------------------   TC_TZC_DRAM1_BASE
+ *               |                |
+ *               |      SPMC      |
+ *               |       SP       |
+ *               |     (96MB)     |
+ *  0xFF00_0000  ------------------   ARM_AP_TZC_DRAM1_BASE
+ *               |       AP       |
+ *               |   EL3 Monitor  |
+ *               |       SCP      |
+ *               |     (16MB)     |
+ *  0xFFFF_FFFF  ------------------
+ *
+ *
  */
 #define TC_TZC_DRAM1_BASE		(ARM_AP_TZC_DRAM1_BASE -	\
 					 TC_TZC_DRAM1_SIZE)
-#define TC_TZC_DRAM1_SIZE		UL(0x02000000)	/* 32 MB */
+#define TC_TZC_DRAM1_SIZE		96 * SZ_1M	/* 96 MB */
 #define TC_TZC_DRAM1_END		(TC_TZC_DRAM1_BASE +		\
 					 TC_TZC_DRAM1_SIZE - 1)
 
@@ -68,7 +83,9 @@
  * max size of BL32 image.
  */
 #if defined(SPD_spmd)
-#define PLAT_ARM_SPMC_BASE		TC_TZC_DRAM1_BASE
+#define TC_EL2SPMC_LOAD_ADDR		(TC_TZC_DRAM1_BASE + 0x04000000)
+
+#define PLAT_ARM_SPMC_BASE		TC_EL2SPMC_LOAD_ADDR
 #define PLAT_ARM_SPMC_SIZE		UL(0x200000)  /* 2 MB */
 #endif
 
@@ -276,8 +293,8 @@
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT))
 
 /*
- * The first region below, TC_TZC_DRAM1_BASE (0xfd000000) to
- * ARM_SCP_TZC_DRAM1_END (0xffffffff) will mark the last 48 MB of DRAM as
+ * The first region below, TC_TZC_DRAM1_BASE (0xf9000000) to
+ * ARM_SCP_TZC_DRAM1_END (0xffffffff) will mark the last 112 MB of DRAM as
  * secure. The second and third regions gives non secure access to rest of DRAM.
  */
 #define TC_TZC_REGIONS_DEF	\
diff --git a/plat/arm/board/tc/plat_def_fip_uuid.h b/plat/arm/board/tc/plat_def_fip_uuid.h
new file mode 100644
index 0000000..631f7c9
--- /dev/null
+++ b/plat/arm/board/tc/plat_def_fip_uuid.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PLAT_DEF_FIP_UUID__
+#define __PLAT_DEF_FIP_UUID__
+
+#include "uuid.h"
+
+#define UUID_RSS_FIRMWARE_BL1_2 \
+	{{0x0a, 0xa5, 0xb1, 0xbe}, {0xe7, 0x84}, {0x41, 0xc5}, 0x81, 0xb8, {0x4a, 0x41, 0xcb, 0x4a, 0xd2, 0xdf}}
+
+#define UUID_RSS_FIRMWARE_BL2 \
+	{{0xa3, 0xb3, 0xb3, 0x0d}, {0xeb, 0xc9}, {0x40, 0x48}, 0xb4, 0x80, {0x15, 0x53, 0x61, 0xc1, 0x70, 0x48}}
+
+#define UUID_RSS_FIRMWARE_SCP_BL1 \
+	{{0xbf, 0xd5, 0x09, 0x8d}, {0xa7, 0x07}, {0x4f, 0x15}, 0x89, 0x1c, {0x37, 0x22, 0x10, 0xcb, 0x51, 0xe2}}
+
+#define UUID_RSS_FIRMWARE_AP_BL1 \
+	{{0x12, 0x4c, 0x50, 0xe0}, {0xf2, 0xda}, {0x45, 0xe9}, 0x85, 0xc8, {0xda, 0xd9, 0x60, 0x9b, 0x7a, 0x11}}
+
+#define UUID_RSS_FIRMWARE_NS \
+	{{0x8d, 0x95, 0x9f, 0x72}, {0xb8, 0xb1}, {0x42, 0x11}, 0x9a, 0xe6, {0x4b, 0x80, 0x97, 0x47, 0x5a, 0xd9}}
+
+#define UUID_RSS_FIRMWARE_S \
+	{{0x22, 0xea, 0x33, 0x85}, {0xf8, 0x6e}, {0x47, 0x93}, 0x96, 0x8a, {0x2f, 0xe3, 0xdd, 0x50, 0x33, 0xcc}}
+
+#define UUID_RSS_SIC_TABLES_NS \
+	{{0xd9, 0x10, 0x00, 0x72}, {0x6a, 0x28}, {0x4b, 0xec}, 0xb0, 0xd6, {0x8c, 0xed, 0xc4, 0x15, 0x7c, 0xe0}}
+
+#define UUID_RSS_SIC_TABLES_S \
+	{{0xc7, 0x38, 0xd0, 0xde}, {0x8c, 0x26}, {0x48, 0x51}, 0x93, 0x36, {0xf3, 0xdb, 0xe2, 0x96, 0x65, 0x18}}
+
+#endif /* __PLAT_DEF_FIP_UUID__ */
diff --git a/plat/arm/board/tc/plat_def_uuid_config.c b/plat/arm/board/tc/plat_def_uuid_config.c
new file mode 100644
index 0000000..903310b
--- /dev/null
+++ b/plat/arm/board/tc/plat_def_uuid_config.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stddef.h>
+
+#include <firmware_image_package.h>
+
+#include "tbbr_config.h"
+
+toc_entry_t plat_def_toc_entries[] = {
+	{
+		.name = "RSS Firmware BL1_2 image",
+		.uuid = UUID_RSS_FIRMWARE_BL1_2,
+		.cmdline_name = "rss-bl1_2"
+	},
+	{
+		.name = "RSS Firmware BL2 image",
+		.uuid = UUID_RSS_FIRMWARE_BL2,
+		.cmdline_name = "rss-bl2"
+	},
+	{
+		.name = "RSS Firmware SCP BL1 image",
+		.uuid = UUID_RSS_FIRMWARE_SCP_BL1,
+		.cmdline_name = "rss-scp-bl1"
+	},
+	{
+		.name = "RSS Firmware AP BL1 image",
+		.uuid = UUID_RSS_FIRMWARE_AP_BL1,
+		.cmdline_name = "rss-ap-bl1"
+	},
+	{
+		.name = "RSS Firmware non-secure image",
+		.uuid = UUID_RSS_FIRMWARE_NS,
+		.cmdline_name = "rss-ns"
+	},
+	{
+		.name = "RSS Firmware secure image",
+		.uuid = UUID_RSS_FIRMWARE_S,
+		.cmdline_name = "rss-s"
+	},
+	{
+		.name = "RSS Firmware non-secure SIC tables",
+		.uuid = UUID_RSS_SIC_TABLES_NS,
+		.cmdline_name = "rss-sic-tables-ns"
+	},
+	{
+		.name = "RSS Firmware secure SIC tables",
+		.uuid = UUID_RSS_SIC_TABLES_S,
+		.cmdline_name = "rss-sic-tables-s"
+	},
+
+	{
+		.name = NULL,
+		.uuid = { {0} },
+		.cmdline_name = NULL,
+	}
+};
diff --git a/plat/arm/board/tc/plat_fiptool.mk b/plat/arm/board/tc/plat_fiptool.mk
new file mode 100644
index 0000000..0e13556
--- /dev/null
+++ b/plat/arm/board/tc/plat_fiptool.mk
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2021, NXP. All rights reserved.
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Name of the platform defined source file name,
+# which contains platform defined UUID entries populated
+# in the plat_def_toc_entries[].
+PLAT_DEF_UUID_CONFIG_FILE_NAME	:= plat_def_uuid_config
+
+PLAT_DEF_UUID_CONFIG_FILE_PATH := ../../plat/arm/board/tc
+
+PLAT_DEF_UUID := yes
+PLAT_DEF_UUID_OID_CONFIG_PATH := ../../plat/arm/board/tc
+
+
+INCLUDE_PATHS += -I${PLAT_DEF_UUID_OID_CONFIG_PATH} \
+		 -I./
+# Clean the stale object file.
+$(shell rm ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o)
+
+ifeq (${PLAT_DEF_OID},yes)
+HOSTCCFLAGS += -DPLAT_DEF_OID
+endif
+
+ifeq (${PLAT_DEF_UUID},yes)
+HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
+PLAT_OBJECTS += ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o
+endif
+
+OBJECTS += ${PLAT_OBJECTS}
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 74c0f17..2182477 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -53,6 +53,9 @@
 # enable trace filter control registers access to NS by default
 ENABLE_TRF_FOR_NS               := 1
 
+# Enable RSS-required FIP UUIDs
+$(shell cp plat/arm/board/tc/plat_fiptool.mk ${PLAT_DIR})
+
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 02e419a..b142b62 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,16 +18,14 @@
 #include <drivers/partition/partition.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
-#if ENABLE_RME
 #include <lib/gpt_rme/gpt_rme.h>
-#endif /* ENABLE_RME */
 #ifdef SPD_opteed
 #include <lib/optee_utils.h>
 #endif
 #include <lib/utils.h>
 #if ENABLE_RME
 #include <plat/arm/common/arm_pas_def.h>
-#endif /* ENABLE_RME */
+#endif
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -131,7 +129,6 @@
 }
 
 #if ENABLE_RME
-
 static void arm_bl2_plat_gpt_setup(void)
 {
 	/*
@@ -171,7 +168,6 @@
 		panic();
 	}
 }
-
 #endif /* ENABLE_RME */
 
 /*******************************************************************************
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index cf403b1..19efdd3 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -13,9 +13,7 @@
 #include <drivers/console.h>
 #include <lib/debugfs.h>
 #include <lib/extensions/ras.h>
-#if ENABLE_RME
 #include <lib/gpt_rme/gpt_rme.h>
-#endif
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/arm/common/plat_arm.h>
diff --git a/plat/arm/common/fconf/fconf_ethosn_getter.c b/plat/arm/common/fconf/fconf_ethosn_getter.c
index 0b48a98..251471e 100644
--- a/plat/arm/common/fconf/fconf_ethosn_getter.c
+++ b/plat/arm/common/fconf/fconf_ethosn_getter.c
@@ -20,21 +20,6 @@
 	uint32_t stream_id;
 };
 
-static bool fdt_node_is_enabled(const void *fdt, int node)
-{
-	int len;
-	const char *node_status;
-
-	node_status = fdt_getprop(fdt, node, "status", &len);
-	if (node_status == NULL ||
-	    (len == 5 && /* Includes null character */
-	     strncmp(node_status, "okay", 4U) == 0)) {
-		return true;
-	}
-
-	return false;
-}
-
 static bool fdt_node_has_reserved_memory(const void *fdt, int dev_node)
 {
 	return fdt_get_property(fdt, dev_node, "memory-region", NULL) != NULL;
diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c
index aeacd10..0406321 100644
--- a/plat/arm/common/trp/arm_trp_setup.c
+++ b/plat/arm/common/trp/arm_trp_setup.c
@@ -26,7 +26,7 @@
  ******************************************************************************/
 static console_t arm_trp_runtime_console;
 
-static int arm_trp_process_manifest(rmm_manifest_t *manifest)
+static int arm_trp_process_manifest(struct rmm_manifest *manifest)
 {
 	/* padding field on the manifest must be RES0 */
 	assert(manifest->padding == 0U);
@@ -38,12 +38,12 @@
 	}
 
 	trp_boot_manifest_version = manifest->version;
-	flush_dcache_range((uintptr_t)manifest, sizeof(rmm_manifest_t));
+	flush_dcache_range((uintptr_t)manifest, sizeof(struct rmm_manifest));
 
 	return 0;
 }
 
-void arm_trp_early_platform_setup(rmm_manifest_t *manifest)
+void arm_trp_early_platform_setup(struct rmm_manifest *manifest)
 {
 	int rc;
 
@@ -66,10 +66,9 @@
 
 	console_set_scope(&arm_trp_runtime_console,
 			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
-
 }
 
-void trp_early_platform_setup(rmm_manifest_t *manifest)
+void trp_early_platform_setup(struct rmm_manifest *manifest)
 {
 	arm_trp_early_platform_setup(manifest);
 }
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 9b2639c..3222226 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -130,9 +130,6 @@
 	/* Prevent interrupts from spuriously waking up this cpu */
 	plat_arm_gic_cpuif_disable();
 
-	/* Turn redistributor off */
-	plat_arm_gic_redistif_off();
-
 	/* Cluster is to be turned off, so disable coherency */
 	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
 		plat_arm_interconnect_exit_coherency();
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
index 223ac3e..8f9529a 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/css/sgi/include/sgi_variant.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,7 @@
 
 /* SID Version values for RD-N2 variants */
 #define RD_N2_CFG1_SID_VER_PART_NUM		0x07B6
+#define RD_N2_CFG3_SID_VER_PART_NUM		0x07F1
 
 /* SID Version values for RD-V2 */
 #define RD_V2_SID_VER_PART_NUM			0x07F2
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 9adcb7c..df2ce38 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,7 +80,8 @@
 		sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_V2_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM) {
+		sgi_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM ||
+		sgi_plat_info.platform_id == RD_N2_CFG3_SID_VER_PART_NUM) {
 		if (channel_id >= ARRAY_SIZE(plat_rd_scmi_info))
 			panic();
 		return &plat_rd_scmi_info[channel_id];
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index b1fc13c..5f7d142 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -150,7 +150,7 @@
 	rc = mmap_add_dynamic_region((unsigned long long)pm_base_align,
 				     pm_base_align,
 				     PAGE_SIZE,
-				     MT_RO_DATA);
+				     MT_RO_DATA | EL3_PAS);
 	if (rc != 0) {
 		ERROR("Error while mapping SPM Core manifest (%d).\n", rc);
 		return rc;
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index d4b3425..ec8631a 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -20,7 +20,7 @@
 #if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
 
 #ifdef PLAT_imx8qm
-const static int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = {
+static const int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = {
 	SC_R_A53, SC_R_A72,
 };
 #endif
diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S
index ceeb3a7..4d17288 100644
--- a/plat/imx/common/imx_uart_console.S
+++ b/plat/imx/common/imx_uart_console.S
@@ -12,6 +12,7 @@
 
 #define URXD  0x0  /* Receiver Register */
 #define UTXD  0x40 /* Transmitter Register */
+#define USR2  0x98 /* UART Status Register 2 */
 #define UTS   0xb4 /* UART Test Register (mx31) */
 #define  URXD_RX_DATA    (0xFF)
 
@@ -53,13 +54,13 @@
 1:
 	/* Check if the transmit FIFO is full */
 	ldr	w2, [x1, #UTS]
-	tbz	w2, #6, 1b
+	tbnz	w2, #4, 1b
 	mov	w2, #0xD
 	str	w2, [x1, #UTXD]
 2:
 	/* Check if the transmit FIFO is full */
 	ldr	w2, [x1, #UTS]
-	tbz	w2, #6, 2b
+	tbnz	w2, #4, 2b
 	str	w0, [x1, #UTXD]
 	ret
 putc_error:
@@ -84,5 +85,13 @@
 endfunc console_imx_uart_getc
 
 func console_imx_uart_flush
+	ldr	x0, [x0, #CONSOLE_T_BASE]
+	cbz	x0, flush_exit
+1:
+	/* Wait for the transmit complete bit */
+	ldr	w1, [x0, #USR2]
+	tbz	w1, #3, 1b
+
+flush_exit:
 	ret
 endfunc console_imx_uart_flush
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index 68eb534..bd7896a 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -62,7 +62,7 @@
 #error "Provide proper UART number in IMX_DEBUG_UART"
 #endif
 
-const static int imx8qm_cci_map[] = {
+static const int imx8qm_cci_map[] = {
 	CLUSTER0_CCI_SLVAE_IFACE,
 	CLUSTER1_CCI_SLVAE_IFACE
 };
diff --git a/plat/imx/imx8qm/imx8qm_psci.c b/plat/imx/imx8qm/imx8qm_psci.c
index bdba37c..dcc502f 100644
--- a/plat/imx/imx8qm/imx8qm_psci.c
+++ b/plat/imx/imx8qm/imx8qm_psci.c
@@ -26,7 +26,7 @@
 #define SYSTEM_PWR_STATE(state) \
 	((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
 
-const static int ap_core_index[PLATFORM_CORE_COUNT] = {
+static const int ap_core_index[PLATFORM_CORE_COUNT] = {
 	SC_R_A53_0, SC_R_A53_1, SC_R_A53_2,
 	SC_R_A53_3, SC_R_A72_0, SC_R_A72_1,
 };
diff --git a/plat/imx/imx8qx/imx8qx_psci.c b/plat/imx/imx8qx/imx8qx_psci.c
index aab3a2d..5f05566 100644
--- a/plat/imx/imx8qx/imx8qx_psci.c
+++ b/plat/imx/imx8qx/imx8qx_psci.c
@@ -18,7 +18,7 @@
 
 #include "../../common/sci/imx8_mu.h"
 
-const static int ap_core_index[PLATFORM_CORE_COUNT] = {
+static const int ap_core_index[PLATFORM_CORE_COUNT] = {
 	SC_R_A35_0, SC_R_A35_1, SC_R_A35_2, SC_R_A35_3
 };
 
diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk
index 160e98f..752ab41 100644
--- a/plat/marvell/armada/a8k/common/ble/ble.mk
+++ b/plat/marvell/armada/a8k/common/ble/ble.mk
@@ -21,7 +21,7 @@
 				-I$(CURDIR)/include/lib/libc			\
 				-I$(CURDIR)/include/lib/libc/aarch64
 
-BLE_LINKERFILE		:=	$(BLE_PATH)/ble.ld.S
+BLE_DEFAULT_LINKER_SCRIPT_SOURCE := $(BLE_PATH)/ble.ld.S
 
 BLE_OBJS := $(addprefix $(BUILD_PLAT)/ble/,$(call SOURCES_TO_OBJS,$(BLE_SOURCES)))
 $(BLE_OBJS): PLAT_INCLUDES += -I$(MV_DDR_PATH)
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
index fc3876e..83a4dd2 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -61,31 +61,6 @@
 $(eval $(call uppercase,$(2))_SOURCES += $(1))
 endef
 
-# MAKE_LINKERFILE change linker script source file name to
-# target linker script
-#   $(1) = linker script source file
-#   $(2) = BL stage
-define MAKE_LINKERFILE
-$(eval EXTRA_GENERATED_LINKER_SCRIPT += $(BUILD_PLAT)/$(2)/$(patsubst %.ld.S,%.ld,$(notdir $(1))))
-endef
-
-# MAKE_LINKERFILE_ITER call MAKE_LINKERFILE iteratively
-#   $(1) = linker script source file
-#   $(2) = BL stage
-define MAKE_LINKERFILE_ITER
-$(eval $(foreach link_src,$(1),$(call MAKE_LINKERFILE,$(link_src),$(2))))
-endef
-
-# MAKE_LD_ITER generate the linker scripts using the C preprocessor iteratively
-#   $(1) = output linker script
-#   $(2) = input template
-#   $(3) = BL stage (1, 2, 2u, 31, 32)
-define MAKE_LD_ITER
-$(eval index_list=$(shell seq $(words $(1))))
-$(eval $(foreach i, $(index_list), \
-$(call MAKE_LD,$(word $(i), $(1)), $(word $(i), $(2)),$(3))))
-endef
-
 # MAKE_MODULE reference MAKE_OBJS.
 # Create module folder under out/bl$(BL)/$(module)
 # Arguments:
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
index 22a546c..4fed41f 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
@@ -9,22 +9,7 @@
 
 # Make next section align to page size
 ifneq ($(MTK_EXTRA_LINKERFILE),)
-$(eval $(call MAKE_LINKERFILE_ITER,$(MTK_LINKERFILE_SOURCE),bl31))
-
-# EXTRA_GENERATED_LINKER_SCRIPT is a global variable of derived linker
-# script list(from MTK_LINKERFILE_SOURCE) after MAKE_LINKERFILE_ITER
-# function call
-EXTRA_LINKERFILE += ${EXTRA_GENERATED_LINKER_SCRIPT}
-
-# Expand derived linker script as build target
-$(eval $(call MAKE_LD_ITER, $(EXTRA_GENERATED_LINKER_SCRIPT),$(MTK_LINKERFILE_SOURCE),bl31))
-
-# mtk_align.ld MUST BE THE LAST LINKER SCRIPT!
-EXTRA_LINKERFILE += ${MTK_PLAT}/include/mtk_align.ld
-
-# bl31.ld should depend on EXTRA_LINKERFILE
-$(eval ${BUILD_PLAT}/bl31/bl31.ld: ${EXTRA_LINKERFILE})
-EXTRA_LINKERFILE := $(addprefix -T,$(EXTRA_LINKERFILE))
-else
-EXTRA_LINKERFILE :=
+        # mtk_align.ld MUST BE THE LAST LINKER SCRIPT!
+        BL31_LINKER_SCRIPT_SOURCES += $(MTK_LINKERFILE_SOURCE)
+        BL31_LINKER_SCRIPT_SOURCES += ${MTK_PLAT}/include/mtk_align.ld
 endif
diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk
index 0279648..128b14f 100644
--- a/plat/mediatek/build_helpers/options.mk
+++ b/plat/mediatek/build_helpers/options.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+# Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -23,3 +23,4 @@
 $(eval $(call add_defined_option,CONFIG_MTK_CPU_SUSPEND_EN))
 $(eval $(call add_defined_option,CONFIG_MTK_PM_ARCH))
 $(eval $(call add_defined_option,CONFIG_MTK_CPU_PM_ARCH))
+$(eval $(call add_defined_option,CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND))
diff --git a/plat/mediatek/common/lpm/mt_lp_api.c b/plat/mediatek/common/lpm/mt_lp_api.c
new file mode 100644
index 0000000..2a1da6a
--- /dev/null
+++ b/plat/mediatek/common/lpm/mt_lp_api.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lpm/mt_lp_api.h>
+
+int mt_audio_update(int type)
+{
+	int ret, val;
+
+	switch (type) {
+	case AUDIO_AFE_ENTER:
+	case AUDIO_AFE_LEAVE:
+		val = (type == AUDIO_AFE_ENTER) ? 1 : 0;
+		ret = mt_lp_rm_do_update(-1, PLAT_RC_IS_FMAUDIO, &val);
+		break;
+	case AUDIO_DSP_ENTER:
+	case AUDIO_DSP_LEAVE:
+		val = (type == AUDIO_DSP_ENTER) ? 1 : 0;
+		ret = mt_lp_rm_do_update(-1, PLAT_RC_IS_ADSP, &val);
+		break;
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+int mtk_usb_update(int type)
+{
+	int ret, val;
+
+	switch (type) {
+	case LPM_USB_ENTER:
+	case LPM_USB_LEAVE:
+		val = (type == LPM_USB_ENTER) ? 1 : 0;
+		ret = mt_lp_rm_do_update(-1, PLAT_RC_IS_USB_INFRA, &val);
+		break;
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/plat/mediatek/common/lpm/mt_lp_rm.c b/plat/mediatek/common/lpm/mt_lp_rm.c
index 0bafc66..9f07968 100644
--- a/plat/mediatek/common/lpm/mt_lp_rm.c
+++ b/plat/mediatek/common/lpm/mt_lp_rm.c
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <mt_lp_rm.h>
 #include <stddef.h>
+#include <lpm/mt_lp_rm.h>
 
 struct platform_mt_resource_manager {
 	unsigned int count;
@@ -36,12 +36,11 @@
 	return MT_RM_STATUS_OK;
 }
 
-int mt_lp_rm_reset_constraint(int idx, unsigned int cpuid, int stateid)
+int mt_lp_rm_reset_constraint(unsigned int idx, unsigned int cpuid, int stateid)
 {
 	struct mt_resource_constraint const *rc = NULL;
 
-	if ((plat_mt_rm.plat_rm == NULL) || (idx < 0) ||
-	    (idx >= plat_mt_rm.count)) {
+	if ((plat_mt_rm.plat_rm == NULL) || (idx >= plat_mt_rm.count)) {
 		return MT_RM_STATUS_BAD;
 	}
 
@@ -54,39 +53,92 @@
 	return rc->reset(cpuid, stateid);
 }
 
-int mt_lp_rm_find_and_run_constraint(int idx, unsigned int cpuid,
-				     int stateid, void *priv)
+int mt_lp_rm_get_status(unsigned int type, void *priv)
+{
+	int res = 0;
+	struct mt_resource_constraint *const *con;
+	struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
+
+	if ((rm == NULL) || (type >= PLAT_RC_MAX)) {
+		return -1;
+	}
+
+	for (con = rm->consts; *con != NULL; con++) {
+		if ((*con)->get_status == NULL) {
+			continue;
+		}
+		res = (*con)->get_status(type, priv);
+		if (res == MT_RM_STATUS_STOP) {
+			break;
+		}
+	}
+
+	return res;
+}
+
+int mt_lp_rm_do_constraint(unsigned int constraint_id, unsigned int cpuid, int stateid)
+{
+	int res = MT_RM_STATUS_BAD;
+	struct mt_resource_constraint const *rc;
+	struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
+
+	if ((rm == NULL) || (constraint_id >= plat_mt_rm.count)) {
+		return res;
+	}
+
+	rc = rm->consts[constraint_id];
+	if ((rc != NULL) && (rc->run != NULL)) {
+		res = rc->run(cpuid, stateid);
+	}
+
+	return res;
+}
+
+int mt_lp_rm_find_constraint(unsigned int idx, unsigned int cpuid,
+			     int stateid, void *priv)
 {
-	int i, res = MT_RM_STATUS_BAD;
+	unsigned int i;
+	int res = MT_RM_STATUS_BAD;
 	struct mt_resource_constraint *const *rc;
 	struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
 
-	if ((rm == NULL) || (idx < 0) || (idx >= plat_mt_rm.count)) {
+	if ((rm == NULL) || (idx >= plat_mt_rm.count)) {
 		return res;
 	}
 
 	/* If subsys clk/mtcmos is on, add block-resource-off flag */
 	if (rm->update != NULL) {
-		res = rm->update(rm->consts, stateid, priv);
+		res = rm->update(rm->consts, plat_mt_rm.count, stateid, priv);
 		if (res != 0) {
-			return res;
+			return MT_RM_STATUS_BAD;
 		}
 	}
 
+	res = MT_RM_STATUS_BAD;
 	for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) {
 		if (((*rc)->is_valid != NULL) &&
 		    ((*rc)->is_valid(cpuid, stateid))) {
-			if (((*rc)->run != NULL) &&
-			    ((*rc)->run(cpuid, stateid) == 0)) {
-				res = i;
-				break;
-			}
+			res = i;
+			break;
 		}
 	}
 
 	return res;
 }
 
+int mt_lp_rm_find_and_run_constraint(unsigned int idx, unsigned int cpuid,
+				     int stateid, void *priv)
+{
+	int res = MT_RM_STATUS_BAD;
+
+	res = mt_lp_rm_find_constraint(idx, cpuid, stateid, priv);
+	if (res != MT_RM_STATUS_BAD) {
+		mt_lp_rm_do_constraint(res, cpuid, stateid);
+	}
+
+	return res;
+}
+
 int mt_lp_rm_do_update(int stateid, int type, void const *p)
 {
 	int res = MT_RM_STATUS_BAD;
diff --git a/plat/mediatek/common/lpm/mt_lp_rm.h b/plat/mediatek/common/lpm/mt_lp_rm.h
deleted file mode 100644
index e93dac3..0000000
--- a/plat/mediatek/common/lpm/mt_lp_rm.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MT_LP_RM_H
-#define MT_LP_RM_H
-
-#include <stdbool.h>
-
-#define MT_RM_STATUS_OK		0
-#define MT_RM_STATUS_BAD	-1
-
-enum PLAT_MT_LPM_RC_TYPE {
-	PLAT_RC_UPDATE_CONDITION,
-	PLAT_RC_UPDATE_REMAIN_IRQS
-};
-
-struct mt_resource_constraint {
-	int level;
-	int (*init)(void);
-	bool (*is_valid)(unsigned int cpu, int stateid);
-	int (*update)(int stateid, int type, const void *p);
-	int (*run)(unsigned int cpu, int stateid);
-	int (*reset)(unsigned int cpu, int stateid);
-	unsigned int (*allow)(int stateid);
-};
-
-struct mt_resource_manager {
-	int (*update)(struct mt_resource_constraint **con,
-		      int stateid, void *priv);
-	struct mt_resource_constraint **consts;
-};
-
-extern int mt_lp_rm_register(struct mt_resource_manager *rm);
-extern int mt_lp_rm_find_and_run_constraint(int idx, unsigned int cpuid,
-					    int stateid, void *priv);
-extern int mt_lp_rm_reset_constraint(int constraint_id, unsigned int cpuid,
-				     int stateid);
-extern int mt_lp_rm_do_update(int stateid, int type, void const *p);
-#endif /* MT_LP_RM_H */
diff --git a/plat/mediatek/common/lpm/mt_lp_rq.c b/plat/mediatek/common/lpm/mt_lp_rq.c
new file mode 100644
index 0000000..7b83fed
--- /dev/null
+++ b/plat/mediatek/common/lpm/mt_lp_rq.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <lib/spinlock.h>
+#include <lpm/mt_lp_rqm.h>
+
+struct mt_lp_res_req_m {
+	unsigned int uname[MT_LP_RQ_USER_MAX];
+	unsigned int user_num;
+	unsigned int user_valid;
+	unsigned int resource_num;
+	unsigned int generic_resource_req;
+	unsigned int flag;
+	struct mt_resource_req_manager *plat_rqm;
+};
+
+static struct mt_lp_res_req_m plat_mt_rqm;
+static spinlock_t mt_lp_rq_lock;
+
+static int mt_lp_resource_request(struct mt_lp_resource_user *this, unsigned int resource)
+{
+	int i;
+	struct mt_lp_res_req *const *rs;
+
+	if ((this == NULL) || (resource == 0) || (resource > MT_LP_RQ_ALL)) {
+		ERROR("invalid request(%x)\n", resource);
+		return MT_LP_RQ_STA_BAD;
+	}
+
+	spin_lock(&mt_lp_rq_lock);
+
+	rs = (plat_mt_rqm.plat_rqm)->res;
+	for (i = 0; i < plat_mt_rqm.resource_num; i++) {
+		if ((resource & rs[i]->res_id) != 0) {
+			rs[i]->res_usage |= this->umask;
+		}
+	}
+
+	plat_mt_rqm.flag = MT_LP_RQ_FLAG_NEED_UPDATE;
+	spin_unlock(&mt_lp_rq_lock);
+
+	return MT_LP_RQ_STA_OK;
+}
+
+static int mt_lp_resource_release(struct mt_lp_resource_user *this)
+{
+	int i;
+	struct mt_lp_res_req *const *rs;
+
+	if (this == NULL) {
+		return MT_LP_RQ_STA_BAD;
+	}
+
+	spin_lock(&mt_lp_rq_lock);
+
+	rs = (plat_mt_rqm.plat_rqm)->res;
+	for (i = 0; i < plat_mt_rqm.resource_num; i++) {
+		rs[i]->res_usage &= ~(this->umask);
+	}
+
+	plat_mt_rqm.flag = MT_LP_RQ_FLAG_NEED_UPDATE;
+	spin_unlock(&mt_lp_rq_lock);
+
+	return MT_LP_RQ_STA_OK;
+}
+
+int mt_lp_resource_request_manager_register(struct mt_resource_req_manager *rqm)
+{
+	unsigned int count;
+	struct mt_lp_res_req *const *rs;
+
+	if ((rqm == NULL) || (rqm->res == NULL) || (plat_mt_rqm.plat_rqm != NULL)) {
+		return MT_LP_RQ_STA_BAD;
+	}
+
+	rs = rqm->res;
+	count = 0;
+	while (*rs != NULL) {
+		count++;
+		rs++;
+	}
+
+	plat_mt_rqm.plat_rqm = rqm;
+	plat_mt_rqm.resource_num = count;
+
+	return MT_LP_RQ_STA_OK;
+}
+
+int mt_lp_resource_user_register(char *user, struct mt_lp_resource_user *ru)
+{
+	int i, len;
+	unsigned int uname;
+
+	if ((plat_mt_rqm.plat_rqm == NULL) || (plat_mt_rqm.user_num >= MT_LP_RQ_USER_MAX) ||
+	    (user == NULL)) {
+		ru->uid = MT_LP_RQ_USER_INVALID;
+		ru->umask = 0;
+		ru->request = NULL;
+		ru->release = NULL;
+		ERROR("rqm register user invalid\n");
+		return MT_LP_RQ_STA_BAD;
+	}
+
+	len = strnlen(user, MT_LP_RQ_USER_NAME_LEN);
+
+	uname = 0;
+	for (i = 0; i < len; i++) {
+		uname |= (user[i] << (MT_LP_RQ_USER_CHAR_U * i));
+	}
+
+	spin_lock(&mt_lp_rq_lock);
+	i = plat_mt_rqm.user_num;
+	plat_mt_rqm.user_num += 1;
+	plat_mt_rqm.uname[i] = uname;
+	plat_mt_rqm.user_valid |= BIT(i);
+	spin_unlock(&mt_lp_rq_lock);
+
+	ru->umask = BIT(i);
+	ru->uid = i;
+	ru->request = mt_lp_resource_request;
+	ru->release = mt_lp_resource_release;
+	INFO("%s register by %s, uid = %d\n", __func__, user, ru->uid);
+
+	return MT_LP_RQ_STA_OK;
+}
+
+int mt_lp_rq_get_status(int type, void *p)
+{
+	int i;
+	unsigned int update_sta;
+	struct mt_lp_res_req *const *rs;
+	struct resource_req_status *rq_sta = (struct resource_req_status *)p;
+
+	if (plat_mt_rqm.flag != 0) {
+		spin_lock(&mt_lp_rq_lock);
+
+		update_sta = 0;
+		rs = (plat_mt_rqm.plat_rqm)->res;
+		for (i = 0; i < plat_mt_rqm.resource_num; i++) {
+			update_sta |= ((rs[i]->res_usage & plat_mt_rqm.user_valid) != 0) ?
+				      rs[i]->res_rq : 0;
+		}
+
+		plat_mt_rqm.generic_resource_req = update_sta;
+		plat_mt_rqm.flag = MT_LP_RQ_FLAG_DONE;
+		spin_unlock(&mt_lp_rq_lock);
+	}
+
+	switch (type) {
+	case PLAT_RQ_REQ_USAGE:
+		rs = (plat_mt_rqm.plat_rqm)->res;
+		rq_sta->val = (rq_sta->id < plat_mt_rqm.resource_num) ?
+			      rs[rq_sta->id]->res_usage : plat_mt_rqm.generic_resource_req;
+		break;
+	case PLAT_RQ_USER_NUM:
+		rq_sta->val = plat_mt_rqm.user_num;
+		break;
+	case PLAT_RQ_USER_VALID:
+		rq_sta->val = plat_mt_rqm.user_valid;
+		break;
+	case PLAT_RQ_PER_USER_NAME:
+		rq_sta->val = (rq_sta->id < plat_mt_rqm.user_num) ?
+			      plat_mt_rqm.uname[rq_sta->id] : 0;
+		break;
+	case PLAT_RQ_REQ_NUM:
+		rq_sta->val = plat_mt_rqm.resource_num;
+		break;
+	default:
+		break;
+	}
+
+	return MT_LP_RQ_STA_OK;
+}
+
+int mt_lp_rq_update_status(int type, void *p)
+{
+	unsigned int user_mask;
+	struct resource_req_status *rq_sta = (struct resource_req_status *)p;
+
+	switch (type) {
+	case PLAT_RQ_USER_VALID:
+		if (rq_sta->id < plat_mt_rqm.user_num) {
+			user_mask = BIT(rq_sta->id);
+			spin_lock(&mt_lp_rq_lock);
+			plat_mt_rqm.user_valid = (rq_sta->val == 0) ?
+						 (plat_mt_rqm.user_valid & ~(user_mask)) :
+						 (plat_mt_rqm.user_valid | user_mask);
+			plat_mt_rqm.flag = MT_LP_RQ_FLAG_NEED_UPDATE;
+			spin_unlock(&mt_lp_rq_lock);
+		}
+		break;
+	default:
+		break;
+	}
+
+	return MT_LP_RQ_STA_OK;
+}
diff --git a/plat/mediatek/common/lpm/rules.mk b/plat/mediatek/common/lpm/rules.mk
index 87a212a..eb68e03 100644
--- a/plat/mediatek/common/lpm/rules.mk
+++ b/plat/mediatek/common/lpm/rules.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+# Copyright (c) 2023, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,7 +7,10 @@
 LOCAL_DIR := $(call GET_LOCAL_DIR)
 
 MODULE := lpm
-LOCAL_SRCS-y := $(LOCAL_DIR)/mt_lp_rm.c
+
+LOCAL_SRCS-y := $(LOCAL_DIR)/mt_lp_api.c
+LOCAL_SRCS-y += $(LOCAL_DIR)/mt_lp_rm.c
+LOCAL_SRCS-y += $(LOCAL_DIR)/mt_lp_rq.c
 
 PLAT_INCLUDES += -I${LOCAL_DIR}
 
diff --git a/plat/mediatek/common/mtk_smc_handlers.c b/plat/mediatek/common/mtk_smc_handlers.c
index 51a960f..92b3873 100644
--- a/plat/mediatek/common/mtk_smc_handlers.c
+++ b/plat/mediatek/common/mtk_smc_handlers.c
@@ -51,6 +51,7 @@
 		x3 = x3 & MASK_32_BIT; \
 		x4 = x4 & MASK_32_BIT; \
 	} \
+	/* fallthrough */ \
 	case _smc_id##_AARCH64: \
 	{ \
 		if (_smc_id##_descriptor_index < 0) { \
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c
index 313ad47..6281cc0 100644
--- a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,10 +11,10 @@
 
 #include <lib/mtk_init/mtk_init.h>
 #include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lp_rm.h>
 #include "mt_cpu_pm.h"
 #include "mt_cpu_pm_cpc.h"
 #include "mt_cpu_pm_mbox.h"
-#include <mt_lp_rm.h>
 #include "mt_smp.h"
 #include <mtk_mmap_pool.h>
 #include <platform_def.h>
diff --git a/plat/mediatek/drivers/iommu/mtk_iommu_smc.c b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
index 9762d0b..e998725 100644
--- a/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
+++ b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -75,25 +75,32 @@
 	return MTK_SIP_E_SUCCESS;
 }
 
-static int mtk_infra_master_config_sec(uint32_t dev_id, uint32_t enable)
+static int mtk_infra_master_config_sec(uint32_t dev_id_msk, uint32_t enable)
 {
 	const struct mtk_ifr_mst_config *ifr_cfg;
-	uint32_t reg_addr;
+	uint32_t dev_id, reg_addr, reg_mask;
 
 	mtk_infra_iommu_enable_protect();
 
-	if (dev_id >= MMU_DEV_NUM) {
-		return MTK_SIP_E_NOT_SUPPORTED;
+	if (dev_id_msk >= BIT(MMU_DEV_NUM)) {
+		return MTK_SIP_E_INVALID_PARAM;
 	}
 
-	ifr_cfg = &g_ifr_mst_cfg[dev_id];
-	reg_addr = g_ifr_mst_cfg_base[(ifr_cfg->cfg_addr_idx)] +
-		   g_ifr_mst_cfg_offs[(ifr_cfg->cfg_addr_idx)];
+	for (dev_id = 0U; dev_id < MMU_DEV_NUM; dev_id++) {
+		if ((dev_id_msk & BIT(dev_id)) == 0U) {
+			continue;
+		}
 
-	if (enable > 0U) {
-		mmio_setbits_32(reg_addr, IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit));
-	} else {
-		mmio_clrbits_32(reg_addr, IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit));
+		ifr_cfg = &g_ifr_mst_cfg[dev_id];
+		reg_addr = g_ifr_mst_cfg_base[(ifr_cfg->cfg_addr_idx)] +
+			   g_ifr_mst_cfg_offs[(ifr_cfg->cfg_addr_idx)];
+		reg_mask = IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit);
+
+		if (enable > 0U) {
+			mmio_setbits_32(reg_addr, reg_mask);
+		} else {
+			mmio_clrbits_32(reg_addr, reg_mask);
+		}
 	}
 
 	return MTK_SIP_E_SUCCESS;
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.c
new file mode 100644
index 0000000..257caa3
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lpm/mt_lpm_smc.h>
+#include <mt_spm.h>
+#include "mt_spm_rc_api.h"
+#include "mt_spm_rc_internal.h"
+
+int spm_rc_condition_modifier(unsigned int id, unsigned int act,
+			      const void *val,
+			      enum mt_spm_rm_rc_type dest_rc_id,
+			      struct mt_spm_cond_tables * const tlb)
+{
+	unsigned int rc_id, cond_id, cond;
+	int res = 0;
+
+	spin_lock(&spm_lock);
+	rc_id = SPM_RC_UPDATE_COND_RC_ID_GET(id);
+	cond_id = SPM_RC_UPDATE_COND_ID_GET(id);
+
+	do {
+		if ((dest_rc_id != rc_id) || (val == NULL) || (tlb == NULL)) {
+			res = -1;
+			break;
+		}
+
+		cond = *((unsigned int *)val);
+
+		if (cond_id < PLAT_SPM_COND_MAX) {
+			if ((act & MT_LPM_SMC_ACT_SET) > 0U) {
+				SPM_RC_BITS_SET(tlb->table_cg[cond_id], cond);
+			} else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) {
+				SPM_RC_BITS_CLR(tlb->table_cg[cond_id], cond);
+			} else {
+				res = -1;
+			}
+		} else if ((cond_id - PLAT_SPM_COND_MAX) < PLAT_SPM_COND_PLL_MAX) {
+			unsigned int pll_idx = cond_id - PLAT_SPM_COND_MAX;
+
+			cond = !!cond;
+			if ((act & MT_LPM_SMC_ACT_SET) > 0U) {
+				SPM_RC_BITS_SET(tlb->table_pll, (cond << pll_idx));
+			} else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) {
+				SPM_RC_BITS_CLR(tlb->table_pll, (cond << pll_idx));
+			} else {
+				res = -1;
+			}
+		} else {
+			res = -1;
+		}
+	} while (0);
+
+	spin_unlock(&spm_lock);
+
+	return res;
+}
+
+int spm_rc_constraint_status_get(unsigned int id, unsigned int type,
+				 unsigned int act,
+				 enum mt_spm_rm_rc_type dest_rc_id,
+				 struct constraint_status * const src,
+				 struct constraint_status * const dest)
+{
+	if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL) ||
+	    (src == NULL)) {
+		return -1;
+	}
+	spin_lock(&spm_lock);
+
+	switch (type) {
+	case CONSTRAINT_GET_ENTER_CNT:
+		if (id == MT_RM_CONSTRAINT_ID_ALL) {
+			dest->enter_cnt += src->enter_cnt;
+		} else {
+			dest->enter_cnt = src->enter_cnt;
+		}
+		break;
+	case CONSTRAINT_GET_VALID:
+		dest->is_valid = src->is_valid;
+		break;
+	case CONSTRAINT_COND_BLOCK:
+		dest->is_cond_block = src->is_cond_block;
+		dest->all_pll_dump = src->all_pll_dump;
+		break;
+	case CONSTRAINT_GET_COND_BLOCK_DETAIL:
+		dest->cond_res = src->cond_res;
+		break;
+	case CONSTRAINT_GET_RESIDNECY:
+		dest->residency = src->residency;
+		if (act & MT_LPM_SMC_ACT_CLR) {
+			src->residency = 0;
+		}
+		break;
+	default:
+		break;
+	}
+
+	spin_unlock(&spm_lock);
+	return 0;
+}
+
+int spm_rc_constraint_status_set(unsigned int id, unsigned int type,
+				 unsigned int act,
+				 enum mt_spm_rm_rc_type dest_rc_id,
+				 struct constraint_status * const src,
+				 struct constraint_status * const dest)
+{
+	if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) {
+		return -1;
+	}
+
+	spin_lock(&spm_lock);
+
+	switch (type) {
+	case CONSTRAINT_UPDATE_VALID:
+		if (src != NULL) {
+			if ((act & MT_LPM_SMC_ACT_SET) > 0U) {
+				SPM_RC_BITS_SET(dest->is_valid, src->is_valid);
+			} else if ((act & MT_LPM_SMC_ACT_CLR) > 0U) {
+				SPM_RC_BITS_CLR(dest->is_valid, src->is_valid);
+			}
+		}
+		break;
+	case CONSTRAINT_RESIDNECY:
+		if (act & MT_LPM_SMC_ACT_CLR) {
+			dest->residency = 0;
+		}
+		break;
+	default:
+		break;
+	}
+
+	spin_unlock(&spm_lock);
+
+	return 0;
+}
+
+int spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id,
+				enum mt_spm_rm_rc_type dest_rc_id,
+				unsigned int valid,
+				struct constraint_status * const dest)
+{
+	if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) {
+		return -1;
+	}
+
+	spin_lock(&spm_lock);
+	SPM_RC_BITS_SET(dest->is_valid, valid);
+	spin_unlock(&spm_lock);
+
+	return 0;
+}
+
+int spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id,
+				enum mt_spm_rm_rc_type dest_rc_id,
+				unsigned int valid,
+				struct constraint_status * const dest)
+{
+	if (((id != MT_RM_CONSTRAINT_ID_ALL) && (id != dest_rc_id)) || (dest == NULL)) {
+		return -1;
+	}
+
+	spin_lock(&spm_lock);
+	SPM_RC_BITS_CLR(dest->is_valid, valid);
+	spin_unlock(&spm_lock);
+
+	return 0;
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.h b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.h
new file mode 100644
index 0000000..0736ca3
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_api.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_RC_API_H
+#define MT_SPM_RC_API_H
+
+#include <mt_spm.h>
+#include <mt_spm_cond.h>
+#include <mt_spm_constraint.h>
+#include <mt_spm_internal.h>
+
+#define SPM_RC_BITS_SET(dest, src) ({ (dest) |= (src); })
+#define SPM_RC_BITS_CLR(dest, src) ({ (dest) &= (~src); })
+
+int spm_rc_condition_modifier(unsigned int id, unsigned int act,
+			      const void *val,
+			      enum mt_spm_rm_rc_type dest_rc_id,
+			      struct mt_spm_cond_tables * const tlb);
+
+int spm_rc_constraint_status_get(unsigned int id, unsigned int type,
+				 unsigned int act,
+				 enum mt_spm_rm_rc_type dest_rc_id,
+				 struct constraint_status * const src,
+				 struct constraint_status * const dest);
+
+int spm_rc_constraint_status_set(unsigned int id, unsigned int type,
+				 unsigned int act,
+				 enum mt_spm_rm_rc_type dest_rc_id,
+				 struct constraint_status * const src,
+				 struct constraint_status * const dest);
+
+int spm_rc_constraint_valid_set(enum mt_spm_rm_rc_type id,
+				enum mt_spm_rm_rc_type dest_rc_id,
+				unsigned int valid,
+				struct constraint_status * const dest);
+
+int spm_rc_constraint_valid_clr(enum mt_spm_rm_rc_type id,
+				enum mt_spm_rm_rc_type dest_rc_id,
+				unsigned int valid,
+				struct constraint_status * const dest);
+
+#endif
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
new file mode 100644
index 0000000..0b792ab
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#ifndef MTK_PLAT_CIRQ_UNSUPPORT
+#include <mtk_cirq.h>
+#endif
+#include <drivers/spm/mt_spm_resource_req.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lp_rm.h>
+#include <mt_spm.h>
+#include <mt_spm_cond.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_constraint.h>
+#include <mt_spm_idle.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_notifier.h>
+#include "mt_spm_rc_api.h"
+#include "mt_spm_rc_internal.h"
+#include <mt_spm_reg.h>
+#include <mt_spm_suspend.h>
+
+#define CONSTRAINT_BUS26M_ALLOW (MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF | \
+				 MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \
+				 MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \
+				 MT_RM_CONSTRAINT_ALLOW_VCORE_LP | \
+				 MT_RM_CONSTRAINT_ALLOW_LVTS_STATE | \
+				 MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF)
+
+#define CONSTRAINT_BUS26M_PCM_FLAG (SPM_FLAG_DISABLE_INFRA_PDN | \
+				    SPM_FLAG_DISABLE_VCORE_DVS | \
+				    SPM_FLAG_DISABLE_VCORE_DFS | \
+				    SPM_FLAG_SRAM_SLEEP_CTRL | \
+				    SPM_FLAG_ENABLE_LVTS_WORKAROUND | \
+				    SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \
+				    SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP)
+
+#define CONSTRAINT_BUS26M_PCM_FLAG1 (SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH)
+
+/* If sspm sram won't enter sleep voltage then vcore couldn't enter low power mode */
+#if defined(MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT) && SPM_SRAM_SLEEP_RC_RES_RESTRICT
+#define CONSTRAINT_BUS26M_RESOURCE_REQ	(MT_SPM_26M)
+#else
+#define CONSTRAINT_BUS26M_RESOURCE_REQ	(0)
+#endif
+
+static unsigned int bus26m_ext_opand;
+static unsigned int bus26m_ext_opand2;
+
+static struct mt_irqremain *refer2remain_irq;
+
+static struct mt_spm_cond_tables cond_bus26m = {
+	.table_cg = {
+		0xFF5DD002,	/* MTCMOS1 */
+		0x0000003C,	/* MTCMOS2 */
+		0x27AF8000,	/* INFRA0  */
+		0x22010876,	/* INFRA1  */
+		0x86000650,	/* INFRA2  */
+		0x30008020,	/* INFRA3  */
+		0x80000000,	/* INFRA4  */
+		0x01002A3B,	/* PERI0   */
+		0x00090000,	/* VPPSYS0_0  */
+		0x38FF3E69,     /* VPPSYS0_1  */
+		0xF0081450,	/* VPPSYS1_0  */
+		0x00003000,     /* VPPSYS1_1  */
+		0x00000000,	/* VDOSYS0_0  */
+		0x00000000,     /* VDOSYS0_1  */
+		0x000001FF,	/* VDOSYS1_0  */
+		0x000001E0,     /* VDOSYS1_1  */
+		0x00FB0007,	/* VDOSYS1_2  */
+	},
+	.table_pll = (PLL_BIT_UNIVPLL |
+		      PLL_BIT_MFGPLL |
+		      PLL_BIT_MSDCPLL |
+		      PLL_BIT_TVDPLL1 |
+		      PLL_BIT_TVDPLL2 |
+		      PLL_BIT_MMPLL |
+		      PLL_BIT_ETHPLL |
+		      PLL_BIT_IMGPLL |
+		      PLL_BIT_APLL1 |
+		      PLL_BIT_APLL2 |
+		      PLL_BIT_APLL3 |
+		      PLL_BIT_APLL4 |
+		      PLL_BIT_APLL5),
+};
+
+static struct mt_spm_cond_tables cond_bus26m_res = {
+	.table_cg = { 0U },
+	.table_pll = 0U,
+};
+
+static struct constraint_status status = {
+	.id = MT_RM_CONSTRAINT_ID_BUS26M,
+	.is_valid = (MT_SPM_RC_VALID_SW |
+		     MT_SPM_RC_VALID_COND_CHECK |
+		     MT_SPM_RC_VALID_COND_LATCH |
+		     MT_SPM_RC_VALID_TRACE_TIME),
+	.is_cond_block = 0U,
+	.enter_cnt = 0U,
+	.all_pll_dump = 0U,
+	.cond_res = &cond_bus26m_res,
+	.residency = 0ULL,
+};
+
+#ifdef MTK_PLAT_CIRQ_UNSUPPORT
+#define do_irqs_delivery()
+#else
+static void mt_spm_irq_remain_dump(struct mt_irqremain *irqs,
+				   unsigned int irq_index,
+				   struct wake_status *wakeup)
+{
+	if ((irqs == NULL) || (wakeup == NULL)) {
+		return;
+	}
+
+	INFO("[SPM] r12=0x%08x(0x%08x), flag=0x%08x 0x%08x 0x%08x, irq:%u(0x%08x) set pending\n",
+	     wakeup->tr.comm.r12,
+	     wakeup->md32pcm_wakeup_sta,
+	     wakeup->tr.comm.debug_flag,
+	     wakeup->tr.comm.b_sw_flag0,
+	     wakeup->tr.comm.b_sw_flag1,
+	     irqs->wakeupsrc[irq_index],
+	     irqs->irqs[irq_index]);
+}
+
+static void do_irqs_delivery(void)
+{
+	unsigned int idx;
+	struct wake_status *wakeup = NULL;
+	struct mt_irqremain *irqs = refer2remain_irq;
+
+	if (irqs == NULL) {
+		return;
+	}
+
+	if (spm_conservation_get_result(&wakeup) == 0) {
+		if (wakeup != NULL) {
+			for (idx = 0; idx < irqs->count; idx++) {
+				if (((wakeup->tr.comm.r12 & irqs->wakeupsrc[idx]) != 0U) ||
+				    ((wakeup->tr.comm.raw_sta & irqs->wakeupsrc[idx]) != 0U)) {
+					if ((irqs->wakeupsrc_cat[idx] &
+					     MT_IRQ_REMAIN_CAT_LOG) != 0U) {
+						mt_spm_irq_remain_dump(irqs, idx, wakeup);
+					}
+					mt_irq_set_pending(irqs->irqs[idx]);
+				}
+			}
+		}
+	}
+}
+#endif
+
+int spm_bus26m_conduct(int state_id, struct spm_lp_scen *spm_lp, unsigned int *resource_req)
+{
+	unsigned int res_req = CONSTRAINT_BUS26M_RESOURCE_REQ;
+
+	if ((spm_lp == NULL) || (resource_req == NULL)) {
+		return -1;
+	}
+
+	spm_lp->pwrctrl->pcm_flags = (uint32_t)CONSTRAINT_BUS26M_PCM_FLAG;
+	spm_lp->pwrctrl->pcm_flags1 = (uint32_t)CONSTRAINT_BUS26M_PCM_FLAG1;
+
+	*resource_req |= res_req;
+	return 0;
+}
+
+bool spm_is_valid_rc_bus26m(unsigned int cpu, int state_id)
+{
+	return (!(status.is_cond_block && (status.is_valid & MT_SPM_RC_VALID_COND_CHECK) > 0) &&
+		IS_MT_RM_RC_READY(status.is_valid) &&
+		(IS_PLAT_SUSPEND_ID(state_id) || (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
+}
+
+static int update_rc_condition(const void *val)
+{
+	const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val;
+	const struct mt_spm_cond_tables *tlb_check =
+		(const struct mt_spm_cond_tables *)&cond_bus26m;
+
+	if (tlb == NULL) {
+		return MT_RM_STATUS_BAD;
+	}
+
+	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
+						 &cond_bus26m_res : NULL);
+	status.all_pll_dump = mt_spm_dump_all_pll(tlb, tlb_check,
+						  (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
+						  &cond_bus26m_res : NULL);
+	return MT_RM_STATUS_OK;
+}
+
+static void update_rc_remain_irqs(const void *val)
+{
+	refer2remain_irq = (struct mt_irqremain *)val;
+}
+
+static void update_rc_fmaudio_adsp(int type, const void *val)
+{
+	int *flag = (int *)val;
+	unsigned int ext_op = (type == PLAT_RC_IS_ADSP) ?
+			      (MT_SPM_EX_OP_SET_IS_ADSP | MT_SPM_EX_OP_SET_SUSPEND_MODE) :
+			      MT_SPM_EX_OP_SET_SUSPEND_MODE;
+
+	if (flag == NULL) {
+		return;
+	}
+
+	if (*flag != 0) {
+		SPM_RC_BITS_SET(bus26m_ext_opand, ext_op);
+	} else {
+		SPM_RC_BITS_CLR(bus26m_ext_opand, ext_op);
+	}
+}
+
+static void update_rc_usb_peri(const void *val)
+{
+	int *flag = (int *)val;
+
+	if (flag == NULL) {
+		return;
+	}
+
+	if (*flag != 0) {
+		SPM_RC_BITS_SET(bus26m_ext_opand2, MT_SPM_EX_OP_PERI_ON);
+	} else {
+		SPM_RC_BITS_CLR(bus26m_ext_opand2, MT_SPM_EX_OP_PERI_ON);
+	}
+}
+
+static void update_rc_usb_infra(const void *val)
+{
+	int *flag = (int *)val;
+
+	if (flag == NULL) {
+		return;
+	}
+
+	if (*flag != 0) {
+		SPM_RC_BITS_SET(bus26m_ext_opand2, MT_SPM_EX_OP_INFRA_ON);
+	} else {
+		SPM_RC_BITS_CLR(bus26m_ext_opand2, MT_SPM_EX_OP_INFRA_ON);
+	}
+}
+
+static void update_rc_status(const void *val)
+{
+	const struct rc_common_state *st;
+
+	st = (const struct rc_common_state *)val;
+
+	if (st == NULL) {
+		return;
+	}
+
+	if (st->type == CONSTRAINT_UPDATE_COND_CHECK) {
+		struct mt_spm_cond_tables * const tlb = &cond_bus26m;
+
+		spm_rc_condition_modifier(st->id, st->act, st->value,
+					  MT_RM_CONSTRAINT_ID_BUS26M, tlb);
+	} else if ((st->type == CONSTRAINT_UPDATE_VALID) ||
+		   (st->type == CONSTRAINT_RESIDNECY)) {
+		spm_rc_constraint_status_set(st->id, st->type, st->act,
+					     MT_RM_CONSTRAINT_ID_BUS26M,
+					     (struct constraint_status * const)st->value,
+					     (struct constraint_status * const)&status);
+	} else {
+		INFO("[%s:%d] - Unknown type: 0x%x\n", __func__, __LINE__, st->type);
+	}
+}
+
+int spm_update_rc_bus26m(int state_id, int type, const void *val)
+{
+	int res = MT_RM_STATUS_OK;
+
+	switch (type) {
+	case PLAT_RC_UPDATE_CONDITION:
+		res = update_rc_condition(val);
+		break;
+	case PLAT_RC_UPDATE_REMAIN_IRQS:
+		update_rc_remain_irqs(val);
+		break;
+	case PLAT_RC_IS_FMAUDIO:
+	case PLAT_RC_IS_ADSP:
+		update_rc_fmaudio_adsp(type, val);
+		break;
+	case PLAT_RC_IS_USB_PERI:
+		update_rc_usb_peri(val);
+		break;
+	case PLAT_RC_IS_USB_INFRA:
+		update_rc_usb_infra(val);
+		break;
+	case PLAT_RC_STATUS:
+		update_rc_status(val);
+		break;
+	default:
+		INFO("[%s:%d] - Do nothing for type: %d\n", __func__, __LINE__, type);
+		break;
+	}
+	return res;
+}
+
+unsigned int spm_allow_rc_bus26m(int state_id)
+{
+	return CONSTRAINT_BUS26M_ALLOW;
+}
+
+int spm_run_rc_bus26m(unsigned int cpu, int state_id)
+{
+	unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT;
+
+#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
+	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_ENTER, CONSTRAINT_BUS26M_ALLOW |
+			       (IS_PLAT_SUSPEND_ID(state_id) ?
+				MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND : 0));
+#endif
+	if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME) {
+		ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
+	}
+
+	if (IS_PLAT_SUSPEND_ID(state_id)) {
+		mt_spm_suspend_enter(state_id,
+				     (MT_SPM_EX_OP_CLR_26M_RECORD |
+				      MT_SPM_EX_OP_SET_WDT |
+				      MT_SPM_EX_OP_HW_S1_DETECT |
+				      bus26m_ext_opand |
+				      bus26m_ext_opand2),
+				     CONSTRAINT_BUS26M_RESOURCE_REQ);
+	} else {
+		mt_spm_idle_generic_enter(state_id, ext_op, spm_bus26m_conduct);
+	}
+	return MT_RM_STATUS_OK;
+}
+
+int spm_reset_rc_bus26m(unsigned int cpu, int state_id)
+{
+	unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT;
+
+#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
+	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_LEAVE, 0);
+#endif
+	if (status.is_valid & MT_SPM_RC_VALID_TRACE_TIME) {
+		ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
+	}
+
+	if (IS_PLAT_SUSPEND_ID(state_id)) {
+		mt_spm_suspend_resume(state_id,
+				      (bus26m_ext_opand | bus26m_ext_opand2 |
+				       MT_SPM_EX_OP_SET_WDT | ext_op),
+				      NULL);
+		bus26m_ext_opand = 0;
+	} else {
+		struct wake_status *waken = NULL;
+
+		if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_TRACE_EVENT)) {
+			ext_op |= MT_SPM_EX_OP_TRACE_LP;
+		}
+
+		mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL);
+		status.enter_cnt++;
+
+		if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY)) {
+			status.residency += (waken != NULL) ? waken->tr.comm.timer_out : 0;
+		}
+	}
+
+	do_irqs_delivery();
+
+	return MT_RM_STATUS_OK;
+}
+
+int spm_get_status_rc_bus26m(unsigned int type, void *priv)
+{
+	int ret = MT_RM_STATUS_OK;
+
+	if (type == PLAT_RC_STATUS) {
+		int res = 0;
+		struct rc_common_state *st = (struct rc_common_state *)priv;
+
+		if (st == NULL) {
+			return MT_RM_STATUS_BAD;
+		}
+
+		res = spm_rc_constraint_status_get(st->id, st->type,
+						   st->act, MT_RM_CONSTRAINT_ID_BUS26M,
+						   (struct constraint_status * const)&status,
+						   (struct constraint_status * const)st->value);
+		if ((res == 0) && (st->id != MT_RM_CONSTRAINT_ID_ALL)) {
+			ret = MT_RM_STATUS_STOP;
+		}
+	}
+	return ret;
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_cpu_buck_ldo.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_cpu_buck_ldo.c
new file mode 100644
index 0000000..1bcd509
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_cpu_buck_ldo.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/spm/mt_spm_resource_req.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lpm_smc.h>
+#include <mt_spm.h>
+#include <mt_spm_cond.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_constraint.h>
+#include <mt_spm_idle.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_notifier.h>
+#include "mt_spm_rc_api.h"
+#include "mt_spm_rc_internal.h"
+#include <mt_spm_reg.h>
+#include <mt_spm_suspend.h>
+
+#define CONSTRAINT_CPU_BUCK_PCM_FLAG (SPM_FLAG_DISABLE_INFRA_PDN | \
+				      SPM_FLAG_DISABLE_VCORE_DVS | \
+				      SPM_FLAG_DISABLE_VCORE_DFS | \
+				      SPM_FLAG_SRAM_SLEEP_CTRL | \
+				      SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \
+				      SPM_FLAG_KEEP_CSYSPWRACK_HIGH)
+
+#define CONSTRAINT_CPU_BUCK_PCM_FLAG1 (0)
+
+#define CONSTRAINT_CPU_BUCK_RESOURCE_REQ (MT_SPM_DRAM_S1 | \
+					  MT_SPM_DRAM_S0 | \
+					  MT_SPM_SYSPLL | \
+					  MT_SPM_INFRA | \
+					  MT_SPM_26M | \
+					  MT_SPM_XO_FPM)
+
+static unsigned int cpubuckldo_status = (MT_SPM_RC_VALID_SW | MT_SPM_RC_VALID_TRACE_TIME);
+static unsigned int cpubuckldo_enter_cnt;
+
+int spm_cpu_bcuk_ldo_conduct(int state_id,
+			     struct spm_lp_scen *spm_lp,
+			     unsigned int *resource_req)
+{
+	unsigned int res_req = CONSTRAINT_CPU_BUCK_RESOURCE_REQ;
+
+	if ((spm_lp == NULL) || (resource_req == NULL)) {
+		return -1;
+	}
+
+	spm_lp->pwrctrl->pcm_flags = (uint32_t)CONSTRAINT_CPU_BUCK_PCM_FLAG;
+	spm_lp->pwrctrl->pcm_flags1 = (uint32_t)CONSTRAINT_CPU_BUCK_PCM_FLAG1;
+
+	*resource_req |= res_req;
+	return 0;
+}
+
+bool spm_is_valid_rc_cpu_buck_ldo(unsigned int cpu, int state_id)
+{
+	return IS_MT_RM_RC_READY(cpubuckldo_status);
+}
+
+static void update_rc_status(const void *val)
+{
+	const struct rc_common_state *st = (const struct rc_common_state *)val;
+
+	if (st == NULL) {
+		return;
+	}
+
+	if ((st->type == CONSTRAINT_UPDATE_VALID) && st->value) {
+		if ((st->id == MT_RM_CONSTRAINT_ID_ALL) ||
+		    (st->id == MT_RM_CONSTRAINT_ID_CPU_BUCK_LDO)) {
+			struct constraint_status *con = (struct constraint_status *)st->value;
+
+			if ((st->act & MT_LPM_SMC_ACT_CLR) > 0U) {
+				SPM_RC_BITS_CLR(cpubuckldo_status, con->is_valid);
+			} else {
+				SPM_RC_BITS_SET(cpubuckldo_status, con->is_valid);
+			}
+		}
+	}
+}
+
+int spm_update_rc_cpu_buck_ldo(int state_id, int type, const void *val)
+{
+	if (type == PLAT_RC_STATUS) {
+		update_rc_status(val);
+	}
+	return MT_RM_STATUS_OK;
+}
+
+unsigned int spm_allow_rc_cpu_buck_ldo(int state_id)
+{
+	return MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF;
+}
+
+int spm_run_rc_cpu_buck_ldo(unsigned int cpu, int state_id)
+{
+	(void)cpu;
+	unsigned int ext_op = 0U;
+
+#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
+	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_ENTER,
+			       (IS_PLAT_SUSPEND_ID(state_id) ?
+				MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND : (0U)));
+#endif
+	if (cpubuckldo_status & MT_SPM_RC_VALID_TRACE_TIME) {
+		ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
+	}
+
+	if (IS_PLAT_SUSPEND_ID(state_id)) {
+		mt_spm_suspend_enter(state_id,
+				     (MT_SPM_EX_OP_CLR_26M_RECORD |
+				      MT_SPM_EX_OP_SET_SUSPEND_MODE |
+				      MT_SPM_EX_OP_SET_WDT),
+				     CONSTRAINT_CPU_BUCK_RESOURCE_REQ);
+	} else {
+		mt_spm_idle_generic_enter(state_id, ext_op, spm_cpu_bcuk_ldo_conduct);
+	}
+
+	cpubuckldo_enter_cnt++;
+
+	return 0;
+}
+
+int spm_reset_rc_cpu_buck_ldo(unsigned int cpu, int state_id)
+{
+	(void)cpu;
+	unsigned int ext_op = 0U;
+
+#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
+	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_LEAVE, 0U);
+#endif
+	if (cpubuckldo_status & MT_SPM_RC_VALID_TRACE_TIME) {
+		ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
+	}
+
+	if (IS_PLAT_SUSPEND_ID(state_id)) {
+		mt_spm_suspend_resume(state_id, MT_SPM_EX_OP_SET_WDT, NULL);
+	} else {
+		mt_spm_idle_generic_resume(state_id, ext_op, NULL, NULL);
+	}
+
+	return 0;
+}
+
+int spm_get_status_rc_cpu_buck_ldo(unsigned int type, void *priv)
+{
+	int ret = MT_RM_STATUS_OK;
+
+	if (type != PLAT_RC_STATUS) {
+		return ret;
+	}
+
+	struct rc_common_state *st = (struct rc_common_state *)priv;
+
+	if (st == NULL) {
+		return MT_RM_STATUS_BAD;
+	}
+
+	if ((st->id == MT_RM_CONSTRAINT_ID_ALL) ||
+	    (st->id == MT_RM_CONSTRAINT_ID_CPU_BUCK_LDO)) {
+		struct constraint_status *dest;
+
+		dest = (struct constraint_status *)st->value;
+		do {
+			if (dest == NULL) {
+				break;
+			}
+			if (st->type == CONSTRAINT_GET_VALID) {
+				dest->is_valid = cpubuckldo_status;
+			} else if (st->type == CONSTRAINT_COND_BLOCK) {
+				dest->is_cond_block = 0;
+			} else if (st->type == CONSTRAINT_GET_ENTER_CNT) {
+				if (st->id == MT_RM_CONSTRAINT_ID_ALL) {
+					dest->enter_cnt += cpubuckldo_enter_cnt;
+				} else {
+					dest->enter_cnt = cpubuckldo_enter_cnt;
+				}
+			} else {
+				break;
+			}
+			if (st->id != MT_RM_CONSTRAINT_ID_ALL) {
+				ret = MT_RM_STATUS_STOP;
+			}
+		} while (0);
+	}
+	return ret;
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
new file mode 100644
index 0000000..d1a2435
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/spm/mt_spm_resource_req.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lp_api.h>
+#include <lpm/mt_lp_rm.h>
+#include <mt_spm.h>
+#include <mt_spm_cond.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_constraint.h>
+#include <mt_spm_idle.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_notifier.h>
+#include "mt_spm_rc_api.h"
+#include "mt_spm_rc_internal.h"
+#include <mt_spm_reg.h>
+#include <mt_spm_suspend.h>
+
+#define CONSTRAINT_DRAM_ALLOW (MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \
+			       MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \
+			       MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF)
+
+#define CONSTRAINT_DRAM_PCM_FLAG (SPM_FLAG_DISABLE_INFRA_PDN | \
+				  SPM_FLAG_DISABLE_VCORE_DVS | \
+				  SPM_FLAG_DISABLE_VCORE_DFS | \
+				  SPM_FLAG_SRAM_SLEEP_CTRL | \
+				  SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \
+				  SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP)
+
+#define CONSTRAINT_DRAM_PCM_FLAG1 (0)
+
+#define CONSTRAINT_DRAM_RESOURCE_REQ (MT_SPM_SYSPLL | MT_SPM_INFRA | MT_SPM_26M)
+
+static struct mt_spm_cond_tables cond_dram = {
+	.table_cg = {
+		0xFF5DD002,	/* MTCMOS1 */
+		0x0000003C,	/* MTCMOS2 */
+		0x27AF8000,	/* INFRA0  */
+		0x20010876,	/* INFRA1  */
+		0x86000640,	/* INFRA2  */
+		0x00000000,	/* INFRA3  */
+		0x80000000,	/* INFRA4  */
+		0x01002A00,	/* PERI0   */
+		0x00080000,	/* VPPSYS0_0  */
+		0x38803000,     /* VPPSYS0_1  */
+		0x00081450,	/* VPPSYS1_0  */
+		0x00003000,     /* VPPSYS1_1  */
+		0x00000000,	/* VDOSYS0_0  */
+		0x00000000,     /* VDOSYS0_1  */
+		0x000001F8,	/* VDOSYS1_0  */
+		0x000001E0,     /* VDOSYS1_1  */
+		0x00FB0007,	/* VDOSYS1_2  */
+	},
+	.table_pll = 0U,
+};
+
+static struct mt_spm_cond_tables cond_dram_res = {
+	.table_cg = { 0U },
+	.table_pll = 0U,
+};
+
+static struct constraint_status status = {
+	.id = MT_RM_CONSTRAINT_ID_DRAM,
+	.is_valid = (MT_SPM_RC_VALID_SW |
+		     MT_SPM_RC_VALID_COND_CHECK |
+		     MT_SPM_RC_VALID_COND_LATCH |
+		     MT_SPM_RC_VALID_XSOC_BBLPM |
+		     MT_SPM_RC_VALID_TRACE_TIME),
+	.is_cond_block = 0U,
+	.enter_cnt = 0U,
+	.cond_res = &cond_dram_res,
+	.residency = 0ULL,
+};
+
+static unsigned short ext_status_dram;
+
+int spm_dram_conduct(int state_id, struct spm_lp_scen *spm_lp, unsigned int *resource_req)
+{
+	unsigned int res_req = CONSTRAINT_DRAM_RESOURCE_REQ;
+
+	if ((spm_lp == NULL) || (resource_req == NULL)) {
+		return -1;
+	}
+
+	spm_lp->pwrctrl->pcm_flags = (uint32_t)CONSTRAINT_DRAM_PCM_FLAG;
+	spm_lp->pwrctrl->pcm_flags1 = (uint32_t)CONSTRAINT_DRAM_PCM_FLAG1;
+
+	*resource_req |= res_req;
+	return 0;
+}
+
+bool spm_is_valid_rc_dram(unsigned int cpu, int state_id)
+{
+	return (!(status.is_cond_block && (status.is_valid & MT_SPM_RC_VALID_COND_CHECK)) &&
+		IS_MT_RM_RC_READY(status.is_valid) &&
+		(IS_PLAT_SUSPEND_ID(state_id) ||
+		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_MEM) ||
+		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_PLL) ||
+		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
+}
+
+static int update_rc_condition(const void *val)
+{
+	const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val;
+	const struct mt_spm_cond_tables *tlb_check = (const struct mt_spm_cond_tables *)&cond_dram;
+
+	if (tlb == NULL) {
+		return MT_RM_STATUS_BAD;
+	}
+
+	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
+						  &cond_dram_res : NULL);
+	return MT_RM_STATUS_OK;
+}
+
+static void update_rc_clkbuf_status(const void *val)
+{
+	unsigned int is_flight = (val) ? !!(*((unsigned int *)val) == FLIGHT_MODE_ON) : 0;
+
+	if (is_flight != 0U) {
+		spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_DRAM,
+					    MT_RM_CONSTRAINT_ID_DRAM,
+					    MT_SPM_RC_VALID_FLIGHTMODE,
+					    (struct constraint_status * const)&status);
+	} else {
+		spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_DRAM,
+					    MT_RM_CONSTRAINT_ID_DRAM,
+					    MT_SPM_RC_VALID_FLIGHTMODE,
+					    (struct constraint_status * const)&status);
+	}
+}
+
+static void update_rc_ufs_status(const void *val)
+{
+	unsigned int is_ufs_h8 = (val) ? !!(*((unsigned int *)val) == UFS_REF_CLK_OFF) : 0;
+
+	if (is_ufs_h8 != 0U) {
+		spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_DRAM,
+					    MT_RM_CONSTRAINT_ID_DRAM,
+					    MT_SPM_RC_VALID_UFS_H8,
+					    (struct constraint_status * const)&status);
+	} else {
+		spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_DRAM,
+					    MT_RM_CONSTRAINT_ID_DRAM,
+					    MT_SPM_RC_VALID_UFS_H8,
+					    (struct constraint_status * const)&status);
+	}
+}
+
+static void update_rc_status(const void *val)
+{
+	const struct rc_common_state *st;
+
+	st = (const struct rc_common_state *)val;
+
+	if (st == NULL) {
+		return;
+	}
+
+	if (st->type == CONSTRAINT_UPDATE_COND_CHECK) {
+		struct mt_spm_cond_tables * const tlb = &cond_dram;
+
+		spm_rc_condition_modifier(st->id, st->act, st->value,
+					  MT_RM_CONSTRAINT_ID_DRAM, tlb);
+	} else if ((st->type == CONSTRAINT_UPDATE_VALID) ||
+		   (st->type == CONSTRAINT_RESIDNECY)) {
+		spm_rc_constraint_status_set(st->id, st->type, st->act,
+					     MT_RM_CONSTRAINT_ID_DRAM,
+					     (struct constraint_status * const)st->value,
+					     (struct constraint_status * const)&status);
+	} else {
+		INFO("[%s:%d] - Unknown type: 0x%x\n", __func__, __LINE__, st->type);
+	}
+}
+
+int spm_update_rc_dram(int state_id, int type, const void *val)
+{
+	int res = MT_RM_STATUS_OK;
+
+	switch (type) {
+	case PLAT_RC_UPDATE_CONDITION:
+		res = update_rc_condition(val);
+		break;
+	case PLAT_RC_CLKBUF_STATUS:
+		update_rc_clkbuf_status(val);
+		break;
+	case PLAT_RC_UFS_STATUS:
+		update_rc_ufs_status(val);
+		break;
+	case PLAT_RC_STATUS:
+		update_rc_status(val);
+		break;
+	default:
+		INFO("[%s:%d] - Do nothing for type: %d\n", __func__, __LINE__, type);
+		break;
+	}
+
+	return res;
+}
+
+unsigned int spm_allow_rc_dram(int state_id)
+{
+	return CONSTRAINT_DRAM_ALLOW;
+}
+
+int spm_run_rc_dram(unsigned int cpu, int state_id)
+{
+	unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT;
+	unsigned int allows = CONSTRAINT_DRAM_ALLOW;
+
+	ext_status_dram = status.is_valid;
+
+	if (IS_MT_SPM_RC_BBLPM_MODE(ext_status_dram)) {
+#ifdef MT_SPM_USING_SRCLKEN_RC
+		ext_op |= MT_SPM_EX_OP_SRCLKEN_RC_BBLPM;
+#else
+		allows |= MT_RM_CONSTRAINT_ALLOW_BBLPM;
+#endif
+	}
+
+#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
+	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_ENTER, allows | (IS_PLAT_SUSPEND_ID(state_id) ?
+			       (MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND) : (0U)));
+#else
+	(void)allows;
+#endif
+
+	if (ext_status_dram & MT_SPM_RC_VALID_TRACE_TIME) {
+		ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
+	}
+
+	if (IS_PLAT_SUSPEND_ID(state_id)) {
+		mt_spm_suspend_enter(state_id,
+				     (MT_SPM_EX_OP_CLR_26M_RECORD |
+				      MT_SPM_EX_OP_SET_WDT |
+				      MT_SPM_EX_OP_SET_SUSPEND_MODE |
+				      MT_SPM_EX_OP_HW_S1_DETECT),
+				     CONSTRAINT_DRAM_RESOURCE_REQ);
+	} else {
+		mt_spm_idle_generic_enter(state_id, ext_op, spm_dram_conduct);
+	}
+
+	return 0;
+}
+
+int spm_reset_rc_dram(unsigned int cpu, int state_id)
+{
+	unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT;
+	unsigned int allows = CONSTRAINT_DRAM_ALLOW;
+
+	if (IS_MT_SPM_RC_BBLPM_MODE(ext_status_dram)) {
+#ifdef MT_SPM_USING_SRCLKEN_RC
+		ext_op |= MT_SPM_EX_OP_SRCLKEN_RC_BBLPM;
+#else
+		allows |= MT_RM_CONSTRAINT_ALLOW_BBLPM;
+#endif
+	}
+
+#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
+	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_LEAVE, allows);
+#else
+	(void)allows;
+#endif
+
+	if (ext_status_dram & MT_SPM_RC_VALID_TRACE_TIME) {
+		ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
+	}
+
+	if (IS_PLAT_SUSPEND_ID(state_id)) {
+		mt_spm_suspend_resume(state_id,
+				      (MT_SPM_EX_OP_SET_WDT | MT_SPM_EX_OP_HW_S1_DETECT),
+				      NULL);
+	} else {
+		struct wake_status *waken = NULL;
+
+		if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_TRACE_EVENT)) {
+			ext_op |= MT_SPM_EX_OP_TRACE_LP;
+		}
+		mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL);
+		status.enter_cnt++;
+
+		if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY)) {
+			status.residency += (waken != NULL) ? waken->tr.comm.timer_out : 0;
+		}
+	}
+
+	return 0;
+}
+
+int spm_get_status_rc_dram(unsigned int type, void *priv)
+{
+	int ret = MT_RM_STATUS_OK;
+
+	if (type == PLAT_RC_STATUS) {
+		int res = 0;
+		struct rc_common_state *st = (struct rc_common_state *)priv;
+
+		if (st == NULL) {
+			return MT_RM_STATUS_BAD;
+		}
+
+		res = spm_rc_constraint_status_get(st->id, st->type,
+						   st->act, MT_RM_CONSTRAINT_ID_DRAM,
+						   (struct constraint_status * const)&status,
+						   (struct constraint_status * const)st->value);
+		if ((res == 0) && (st->id != MT_RM_CONSTRAINT_ID_ALL)) {
+			ret = MT_RM_STATUS_STOP;
+		}
+	}
+	return ret;
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_internal.h b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_internal.h
new file mode 100644
index 0000000..7763152
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_internal.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_RC_INTERNAL_H
+#define MT_SPM_RC_INTERNAL_H
+
+#ifdef MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT
+#define SPM_FLAG_SRAM_SLEEP_CTRL (SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP)
+#define SPM_SRAM_SLEEP_RC_RES_RESTRICT	(0)
+#else
+#define SPM_FLAG_SRAM_SLEEP_CTRL	(0)
+#define SPM_SRAM_SLEEP_RC_RES_RESTRICT	(0)
+#endif
+
+#define SPM_RC_UPDATE_COND_ID_MASK	(0xffff)
+#define SPM_RC_UPDATE_COND_RC_ID_MASK	(0xffff)
+#define SPM_RC_UPDATE_COND_RC_ID_SHIFT	(16)
+
+#define SPM_RC_UPDATE_COND_RC_ID_GET(val) \
+	((val >> SPM_RC_UPDATE_COND_RC_ID_SHIFT) & SPM_RC_UPDATE_COND_RC_ID_MASK)
+
+#define SPM_RC_UPDATE_COND_ID_GET(val) (val & SPM_RC_UPDATE_COND_ID_MASK)
+
+/* cpu buck/ldo constraint function */
+bool spm_is_valid_rc_cpu_buck_ldo(unsigned int cpu, int state_id);
+int spm_update_rc_cpu_buck_ldo(int state_id, int type, const void *val);
+unsigned int spm_allow_rc_cpu_buck_ldo(int state_id);
+int spm_run_rc_cpu_buck_ldo(unsigned int cpu, int state_id);
+int spm_reset_rc_cpu_buck_ldo(unsigned int cpu, int state_id);
+int spm_get_status_rc_cpu_buck_ldo(unsigned int type, void *priv);
+
+/* spm resource dram constraint function */
+bool spm_is_valid_rc_dram(unsigned int cpu, int state_id);
+int spm_update_rc_dram(int state_id, int type, const void *val);
+unsigned int spm_allow_rc_dram(int state_id);
+int spm_run_rc_dram(unsigned int cpu, int state_id);
+int spm_reset_rc_dram(unsigned int cpu, int state_id);
+int spm_get_status_rc_dram(unsigned int type, void *priv);
+
+/* spm resource syspll constraint function */
+bool spm_is_valid_rc_syspll(unsigned int cpu, int state_id);
+int spm_update_rc_syspll(int state_id, int type, const void *val);
+unsigned int spm_allow_rc_syspll(int state_id);
+int spm_run_rc_syspll(unsigned int cpu, int state_id);
+int spm_reset_rc_syspll(unsigned int cpu, int state_id);
+int spm_get_status_rc_syspll(unsigned int type, void *priv);
+
+/* spm resource bus26m constraint function */
+bool spm_is_valid_rc_bus26m(unsigned int cpu, int state_id);
+int spm_update_rc_bus26m(int state_id, int type, const void *val);
+unsigned int spm_allow_rc_bus26m(int state_id);
+int spm_run_rc_bus26m(unsigned int cpu, int state_id);
+int spm_reset_rc_bus26m(unsigned int cpu, int state_id);
+int spm_get_status_rc_bus26m(unsigned int type, void *priv);
+
+#endif
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
new file mode 100644
index 0000000..700f500
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <drivers/spm/mt_spm_resource_req.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lp_api.h>
+#include <lpm/mt_lp_rm.h>
+#include <mt_spm.h>
+#include <mt_spm_cond.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_constraint.h>
+#include <mt_spm_idle.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_notifier.h>
+#include "mt_spm_rc_api.h"
+#include "mt_spm_rc_internal.h"
+#include <mt_spm_reg.h>
+#include <mt_spm_suspend.h>
+
+#define CONSTRAINT_SYSPLL_ALLOW (MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF | \
+				 MT_RM_CONSTRAINT_ALLOW_DRAM_S0 | \
+				 MT_RM_CONSTRAINT_ALLOW_DRAM_S1 | \
+				 MT_RM_CONSTRAINT_ALLOW_VCORE_LP)
+
+#define CONSTRAINT_SYSPLL_PCM_FLAG (SPM_FLAG_DISABLE_INFRA_PDN | \
+				    SPM_FLAG_DISABLE_VCORE_DVS | \
+				    SPM_FLAG_DISABLE_VCORE_DFS | \
+				    SPM_FLAG_SRAM_SLEEP_CTRL | \
+				    SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \
+				    SPM_FLAG_ENABLE_6315_CTRL | \
+				    SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \
+				    SPM_FLAG_USE_SRCCLKENO2)
+
+#define CONSTRAINT_SYSPLL_PCM_FLAG1 (0)
+
+/* If sspm sram won't enter sleep voltage then vcore couldn't enter low power mode */
+#if defined(MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT) && SPM_SRAM_SLEEP_RC_RES_RESTRICT
+#define CONSTRAINT_SYSPLL_RESOURCE_REQ	(MT_SPM_26M)
+#else
+#define CONSTRAINT_SYSPLL_RESOURCE_REQ	(MT_SPM_26M)
+#endif
+
+static unsigned int syspll_ext_opand2;
+static unsigned short ext_status_syspll;
+
+static struct mt_spm_cond_tables cond_syspll = {
+	.table_cg = {
+		0xFF5DD002,	/* MTCMOS1 */
+		0x0000003C,	/* MTCMOS2 */
+		0x27AF8000,	/* INFRA0  */
+		0x20010876,	/* INFRA1  */
+		0x86000640,	/* INFRA2  */
+		0x30008020,	/* INFRA3  */
+		0x80000000,	/* INFRA4  */
+		0x01002A0B,	/* PERI0   */
+		0x00090000,	/* VPPSYS0_0  */
+		0x38FF3E69,     /* VPPSYS0_1  */
+		0xF0081450,	/* VPPSYS1_0  */
+		0x00003000,     /* VPPSYS1_1  */
+		0x00000000,	/* VDOSYS0_0  */
+		0x00000000,     /* VDOSYS0_1  */
+		0x000001FF,	/* VDOSYS1_0  */
+		0x008001E0,     /* VDOSYS1_1  */
+		0x00FB0007,	/* VDOSYS1_2  */
+	},
+	.table_pll = 0U,
+};
+
+static struct mt_spm_cond_tables cond_syspll_res = {
+	.table_cg = { 0U },
+	.table_pll = 0U,
+};
+
+static struct constraint_status status = {
+	.id = MT_RM_CONSTRAINT_ID_SYSPLL,
+	.is_valid = (MT_SPM_RC_VALID_SW |
+		     MT_SPM_RC_VALID_COND_CHECK |
+		     MT_SPM_RC_VALID_COND_LATCH |
+		     MT_SPM_RC_VALID_XSOC_BBLPM |
+		     MT_SPM_RC_VALID_TRACE_TIME),
+	.is_cond_block = 0U,
+	.enter_cnt = 0U,
+	.cond_res = &cond_syspll_res,
+	.residency = 0ULL,
+};
+
+int spm_syspll_conduct(int state_id, struct spm_lp_scen *spm_lp, unsigned int *resource_req)
+{
+	unsigned int res_req = CONSTRAINT_SYSPLL_RESOURCE_REQ;
+
+	if ((spm_lp == NULL) || (resource_req == NULL)) {
+		return -1;
+	}
+
+	spm_lp->pwrctrl->pcm_flags = (uint32_t)CONSTRAINT_SYSPLL_PCM_FLAG;
+	spm_lp->pwrctrl->pcm_flags1 = (uint32_t)CONSTRAINT_SYSPLL_PCM_FLAG1;
+
+	*resource_req |= res_req;
+	return 0;
+}
+
+bool spm_is_valid_rc_syspll(unsigned int cpu, int state_id)
+{
+	return (!(status.is_cond_block && (status.is_valid & MT_SPM_RC_VALID_COND_CHECK) > 0) &&
+		IS_MT_RM_RC_READY(status.is_valid) &&
+		(IS_PLAT_SUSPEND_ID(state_id) ||
+		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_PLL) ||
+		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
+}
+
+static int update_rc_condition(const void *val)
+{
+	int res = MT_RM_STATUS_OK;
+
+	const struct mt_spm_cond_tables * const tlb =
+		(const struct mt_spm_cond_tables * const)val;
+	const struct mt_spm_cond_tables *tlb_check =
+		(const struct mt_spm_cond_tables *)&cond_syspll;
+
+	if (tlb == NULL) {
+		return MT_RM_STATUS_BAD;
+	}
+
+	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
+						 &cond_syspll_res : NULL);
+	return res;
+}
+
+static void update_rc_clkbuf_status(const void *val)
+{
+	unsigned int is_flight = (val) ? !!(*((unsigned int *)val) == FLIGHT_MODE_ON) : 0;
+
+	if (is_flight != 0U) {
+		spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_SYSPLL,
+					    MT_RM_CONSTRAINT_ID_SYSPLL,
+					    MT_SPM_RC_VALID_FLIGHTMODE,
+					    (struct constraint_status * const)&status);
+	} else {
+		spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_SYSPLL,
+					    MT_RM_CONSTRAINT_ID_SYSPLL,
+					    MT_SPM_RC_VALID_FLIGHTMODE,
+					    (struct constraint_status * const)&status);
+	}
+}
+
+static void update_rc_ufs_status(const void *val)
+{
+	unsigned int is_ufs_h8 = (val) ? !!(*((unsigned int *)val) == UFS_REF_CLK_OFF) : 0;
+
+	if (is_ufs_h8 != 0U) {
+		spm_rc_constraint_valid_set(MT_RM_CONSTRAINT_ID_SYSPLL,
+					    MT_RM_CONSTRAINT_ID_SYSPLL,
+					    MT_SPM_RC_VALID_UFS_H8,
+					    (struct constraint_status * const)&status);
+	} else {
+		spm_rc_constraint_valid_clr(MT_RM_CONSTRAINT_ID_SYSPLL,
+					    MT_RM_CONSTRAINT_ID_SYSPLL,
+					    MT_SPM_RC_VALID_UFS_H8,
+					    (struct constraint_status * const)&status);
+	}
+}
+
+static void update_rc_usb_peri(const void *val)
+{
+	int *flag = (int *)val;
+
+	if (flag == NULL) {
+		return;
+	}
+
+	if (*flag != 0) {
+		SPM_RC_BITS_SET(syspll_ext_opand2, MT_SPM_EX_OP_PERI_ON);
+	} else {
+		SPM_RC_BITS_CLR(syspll_ext_opand2, MT_SPM_EX_OP_PERI_ON);
+	}
+}
+
+static void update_rc_usb_infra(const void *val)
+{
+	int *flag = (int *)val;
+
+	if (flag == NULL) {
+		return;
+	}
+
+	if (*flag != 0) {
+		SPM_RC_BITS_SET(syspll_ext_opand2, MT_SPM_EX_OP_INFRA_ON);
+	} else {
+		SPM_RC_BITS_CLR(syspll_ext_opand2, MT_SPM_EX_OP_INFRA_ON);
+	}
+}
+
+static void update_rc_status(const void *val)
+{
+	const struct rc_common_state *st;
+
+	st = (const struct rc_common_state *)val;
+
+	if (st == NULL) {
+		return;
+	}
+
+	if (st->type == CONSTRAINT_UPDATE_COND_CHECK) {
+		struct mt_spm_cond_tables * const tlb = &cond_syspll;
+
+		spm_rc_condition_modifier(st->id, st->act, st->value,
+					  MT_RM_CONSTRAINT_ID_SYSPLL, tlb);
+	} else if ((st->type == CONSTRAINT_UPDATE_VALID) ||
+		   (st->type == CONSTRAINT_RESIDNECY)) {
+		spm_rc_constraint_status_set(st->id, st->type, st->act,
+					     MT_RM_CONSTRAINT_ID_SYSPLL,
+					     (struct constraint_status * const)st->value,
+					     (struct constraint_status * const)&status);
+	} else {
+		INFO("[%s:%d] - Unknown type: 0x%x\n", __func__, __LINE__, st->type);
+	}
+}
+
+int spm_update_rc_syspll(int state_id, int type, const void *val)
+{
+	int res = MT_RM_STATUS_OK;
+
+	switch (type) {
+	case PLAT_RC_UPDATE_CONDITION:
+		res = update_rc_condition(val);
+		break;
+	case PLAT_RC_CLKBUF_STATUS:
+		update_rc_clkbuf_status(val);
+		break;
+	case PLAT_RC_UFS_STATUS:
+		update_rc_ufs_status(val);
+		break;
+	case PLAT_RC_IS_USB_PERI:
+		update_rc_usb_peri(val);
+		break;
+	case PLAT_RC_IS_USB_INFRA:
+		update_rc_usb_infra(val);
+		break;
+	case PLAT_RC_STATUS:
+		update_rc_status(val);
+		break;
+	default:
+		INFO("[%s:%d] - Do nothing for type: %d\n", __func__, __LINE__, type);
+		break;
+	}
+	return res;
+}
+
+unsigned int spm_allow_rc_syspll(int state_id)
+{
+	return CONSTRAINT_SYSPLL_ALLOW;
+}
+
+int spm_run_rc_syspll(unsigned int cpu, int state_id)
+{
+	unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT;
+	unsigned int allows = CONSTRAINT_SYSPLL_ALLOW;
+
+	ext_status_syspll = status.is_valid;
+
+	if (IS_MT_SPM_RC_BBLPM_MODE(ext_status_syspll)) {
+#ifdef MT_SPM_USING_SRCLKEN_RC
+		ext_op |= MT_SPM_EX_OP_SRCLKEN_RC_BBLPM;
+#else
+		allows |= MT_RM_CONSTRAINT_ALLOW_BBLPM;
+#endif
+	}
+
+#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
+	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_ENTER, allows | (IS_PLAT_SUSPEND_ID(state_id) ?
+			       MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND : 0));
+#else
+	(void)allows;
+#endif
+	if (ext_status_syspll & MT_SPM_RC_VALID_TRACE_TIME) {
+		ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
+	}
+
+	if (IS_PLAT_SUSPEND_ID(state_id)) {
+		mt_spm_suspend_enter(state_id,
+				     (syspll_ext_opand2 | MT_SPM_EX_OP_CLR_26M_RECORD |
+				      MT_SPM_EX_OP_SET_WDT | MT_SPM_EX_OP_HW_S1_DETECT |
+				      MT_SPM_EX_OP_SET_SUSPEND_MODE),
+				     CONSTRAINT_SYSPLL_RESOURCE_REQ);
+	} else {
+		mt_spm_idle_generic_enter(state_id, ext_op, spm_syspll_conduct);
+	}
+
+	return 0;
+}
+
+int spm_reset_rc_syspll(unsigned int cpu, int state_id)
+{
+	unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT;
+	unsigned int allows = CONSTRAINT_SYSPLL_ALLOW;
+
+	if (IS_MT_SPM_RC_BBLPM_MODE(ext_status_syspll)) {
+#ifdef MT_SPM_USING_SRCLKEN_RC
+		ext_op |= MT_SPM_EX_OP_SRCLKEN_RC_BBLPM;
+#else
+		allows |= MT_RM_CONSTRAINT_ALLOW_BBLPM;
+#endif
+	}
+
+#ifndef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
+	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_LEAVE, allows);
+#else
+	(void)allows;
+#endif
+	if (ext_status_syspll & MT_SPM_RC_VALID_TRACE_TIME) {
+		ext_op |= MT_SPM_EX_OP_TRACE_TIMESTAMP_EN;
+	}
+
+	if (IS_PLAT_SUSPEND_ID(state_id)) {
+		mt_spm_suspend_resume(state_id,
+				      (syspll_ext_opand2 | MT_SPM_EX_OP_SET_SUSPEND_MODE |
+				       MT_SPM_EX_OP_SET_WDT | MT_SPM_EX_OP_HW_S1_DETECT),
+				      NULL);
+	} else {
+		struct wake_status *waken = NULL;
+
+		if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_TRACE_EVENT)) {
+			ext_op |= MT_SPM_EX_OP_TRACE_LP;
+		}
+
+		mt_spm_idle_generic_resume(state_id, ext_op, &waken, NULL);
+		status.enter_cnt++;
+
+		if (spm_unlikely(status.is_valid & MT_SPM_RC_VALID_RESIDNECY)) {
+			status.residency += (waken != NULL) ? waken->tr.comm.timer_out : 0;
+		}
+	}
+
+	return 0;
+}
+
+int spm_get_status_rc_syspll(unsigned int type, void *priv)
+{
+	int ret = MT_RM_STATUS_OK;
+
+	if (type == PLAT_RC_STATUS) {
+		int res = 0;
+		struct rc_common_state *st = (struct rc_common_state *)priv;
+
+		if (st == NULL) {
+			return MT_RM_STATUS_BAD;
+		}
+
+		res = spm_rc_constraint_status_get(st->id, st->type, st->act,
+						   MT_RM_CONSTRAINT_ID_SYSPLL,
+						   (struct constraint_status * const)&status,
+						   (struct constraint_status * const)st->value);
+		if ((res == 0) && (st->id != MT_RM_CONSTRAINT_ID_ALL)) {
+			ret = MT_RM_STATUS_STOP;
+		}
+	}
+	return ret;
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm.c b/plat/mediatek/drivers/spm/mt8188/mt_spm.c
new file mode 100644
index 0000000..6c4e681
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <arch.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include "constraints/mt_spm_rc_internal.h"
+#include <drivers/spm/mt_spm_resource_req.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lp_rm.h>
+#include <lpm/mt_lp_rqm.h>
+#include <lpm/mt_lpm_smc.h>
+#include "mt_spm.h"
+#include "mt_spm_cond.h"
+#include "mt_spm_conservation.h"
+#include "mt_spm_constraint.h"
+#include "mt_spm_idle.h"
+#include "mt_spm_internal.h"
+#include "mt_spm_pmic_wrap.h"
+#include "mt_spm_reg.h"
+#include "mt_spm_suspend.h"
+#include <mtk_mmap_pool.h>
+#include <platform_def.h>
+#include "sleep_def.h"
+
+/*
+ * System Power Manager (SPM) is a hardware module which provides CPU idle
+ * and system suspend features.
+ */
+
+spinlock_t spm_lock;
+
+#ifdef MTK_PLAT_SPM_UNSUPPORT
+struct mt_resource_manager plat_mt8188_rm = {
+};
+#else
+struct mt_lp_res_req rq_xo_fpm = {
+	.res_id = MT_LP_RQ_XO_FPM,
+	.res_rq = MT_SPM_XO_FPM,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_26m = {
+	.res_id = MT_LP_RQ_26M,
+	.res_rq = MT_SPM_26M,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_infra = {
+	.res_id = MT_LP_RQ_INFRA,
+	.res_rq = MT_SPM_INFRA,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_syspll = {
+	.res_id = MT_LP_RQ_SYSPLL,
+	.res_rq = MT_SPM_SYSPLL,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_dram_s0 = {
+	.res_id = MT_LP_RQ_DRAM,
+	.res_rq = MT_SPM_DRAM_S0,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req rq_dram_s1 = {
+	.res_id = MT_LP_RQ_DRAM,
+	.res_rq = MT_SPM_DRAM_S1,
+	.res_usage = 0,
+};
+
+struct mt_lp_res_req *spm_resources[] = {
+	&rq_xo_fpm,
+	&rq_26m,
+	&rq_infra,
+	&rq_syspll,
+	&rq_dram_s0,
+	&rq_dram_s1,
+	NULL,
+};
+
+struct mt_resource_req_manager plat_mt8188_rq = {
+	.res = spm_resources,
+};
+
+struct mt_resource_constraint plat_constraint_bus26m = {
+	.is_valid = spm_is_valid_rc_bus26m,
+	.update = spm_update_rc_bus26m,
+	.allow = spm_allow_rc_bus26m,
+	.run = spm_run_rc_bus26m,
+	.reset = spm_reset_rc_bus26m,
+	.get_status = spm_get_status_rc_bus26m,
+};
+
+struct mt_resource_constraint plat_constraint_syspll = {
+	.is_valid = spm_is_valid_rc_syspll,
+	.update = spm_update_rc_syspll,
+	.allow = spm_allow_rc_syspll,
+	.run = spm_run_rc_syspll,
+	.reset = spm_reset_rc_syspll,
+	.get_status = spm_get_status_rc_syspll,
+};
+
+struct mt_resource_constraint plat_constraint_dram = {
+	.is_valid = spm_is_valid_rc_dram,
+	.update = spm_update_rc_dram,
+	.allow = spm_allow_rc_dram,
+	.run = spm_run_rc_dram,
+	.reset = spm_reset_rc_dram,
+	.get_status = spm_get_status_rc_dram,
+};
+
+struct mt_resource_constraint plat_constraint_cpu = {
+	.is_valid = spm_is_valid_rc_cpu_buck_ldo,
+	.update = spm_update_rc_cpu_buck_ldo,
+	.allow = spm_allow_rc_cpu_buck_ldo,
+	.run = spm_run_rc_cpu_buck_ldo,
+	.reset = spm_reset_rc_cpu_buck_ldo,
+	.get_status = spm_get_status_rc_cpu_buck_ldo,
+};
+
+struct mt_resource_constraint *plat_constraints[] = {
+	&plat_constraint_bus26m,
+	&plat_constraint_syspll,
+	&plat_constraint_dram,
+	&plat_constraint_cpu,
+	NULL,
+};
+
+struct mt_resource_manager plat_mt8188_rm = {
+	.update = mt_spm_cond_update,
+	.consts = plat_constraints,
+};
+#endif
+
+/* Determine for SPM software resource user */
+static struct mt_lp_resource_user spm_res_user;
+
+struct mt_lp_resource_user *get_spm_res_user(void)
+{
+	return &spm_res_user;
+}
+
+int spm_boot_init(void)
+{
+	mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE);
+	mt_lp_rm_register(&plat_mt8188_rm);
+
+	/* SPM service won't run when SPM not ready */
+#ifndef MTK_PLAT_SPM_UNSUPPORT
+	mt_lp_resource_request_manager_register(&plat_mt8188_rq);
+	mt_lp_resource_user_register("SPM", &spm_res_user);
+#endif
+
+	return 0;
+}
+MTK_ARCH_INIT(spm_boot_init);
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm.h b/plat/mediatek/drivers/spm/mt8188/mt_spm.h
new file mode 100644
index 0000000..0688b71
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_H
+#define MT_SPM_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <lib/spinlock.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lp_rq.h>
+
+/*
+ * ARM v8.2, the cache will turn off automatically when cpu
+ * power down. Therefore, there is no doubt to use the spin_lock here.
+ */
+extern spinlock_t spm_lock;
+
+#ifdef __GNUC__
+#define spm_likely(x)	__builtin_expect(!!(x), 1)
+#define spm_unlikely(x)	__builtin_expect(!!(x), 0)
+#else
+#define spm_likely(x)	(x)
+#define spm_unlikely(x)	(x)
+#endif
+
+#define MT_SPM_USING_SRCLKEN_RC
+/* spm extern operand definition */
+#define MT_SPM_EX_OP_CLR_26M_RECORD		BIT(0)
+#define MT_SPM_EX_OP_SET_WDT			BIT(1)
+#define MT_SPM_EX_OP_NON_GENERIC_RESOURCE_REQ	BIT(2)
+#define MT_SPM_EX_OP_SET_SUSPEND_MODE		BIT(3)
+#define MT_SPM_EX_OP_SET_IS_ADSP		BIT(4)
+#define MT_SPM_EX_OP_SRCLKEN_RC_BBLPM		BIT(5)
+#define MT_SPM_EX_OP_HW_S1_DETECT		BIT(6)
+#define MT_SPM_EX_OP_TRACE_LP			BIT(7)
+#define MT_SPM_EX_OP_TRACE_SUSPEND		BIT(8)
+#define MT_SPM_EX_OP_TRACE_TIMESTAMP_EN		BIT(9)
+#define MT_SPM_EX_OP_TIME_CHECK			BIT(10)
+#define MT_SPM_EX_OP_TIME_OBS			BIT(11)
+#define MT_SPM_EX_OP_PERI_ON			BIT(12)
+#define MT_SPM_EX_OP_INFRA_ON			BIT(13)
+
+typedef enum {
+	WR_NONE = 0,
+	WR_UART_BUSY = 1,
+	WR_ABORT = 2,
+	WR_PCM_TIMER = 3,
+	WR_WAKE_SRC = 4,
+	WR_DVFSRC = 5,
+	WR_TWAM = 6,
+	WR_PMSR = 7,
+	WR_SPM_ACK_CHK = 8,
+	WR_UNKNOWN = 9,
+} wake_reason_t;
+
+struct mt_lp_resource_user *get_spm_res_user(void);
+int spm_boot_init(void);
+
+#endif /* MT_SPM_H */
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
new file mode 100644
index 0000000..fe6e598
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <lib/mmio.h>
+#include <lib/pm/mtk_pm.h>
+#include <mt_spm_cond.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_constraint.h>
+#include <platform_def.h>
+
+#define TOPCKGEB_BASE			(IO_PHYS)
+
+#define MT_LP_TZ_INFRA_REG(ofs)		(INFRACFG_AO_BASE + ofs)
+
+#define MT_LP_TZ_SPM_REG(ofs)		(SPM_BASE + ofs)
+#define MT_LP_TZ_TOPCK_REG(ofs)		(TOPCKGEB_BASE + ofs)
+#define MT_LP_TZ_APMIXEDSYS(ofs)	(APMIXEDSYS + ofs)
+
+#define MT_LP_TZ_VPPSYS0_REG(ofs)	(VPPSYS0_BASE + ofs)
+#define MT_LP_TZ_VPPSYS1_REG(ofs)	(VPPSYS1_BASE + ofs)
+#define MT_LP_TZ_VDOSYS0_REG(ofs)	(VDOSYS0_BASE + ofs)
+#define MT_LP_TZ_VDOSYS1_REG(ofs)	(VDOSYS1_BASE + ofs)
+
+#define MT_LP_TZ_PERI_AO_REG(ofs)	(PERICFG_AO_BASE + ofs)
+
+#undef SPM_PWR_STATUS
+#define SPM_PWR_STATUS			MT_LP_TZ_SPM_REG(0x016C)
+#define SPM_PWR_STATUS_2ND		MT_LP_TZ_SPM_REG(0x0170)
+#define SPM_CPU_PWR_STATUS		MT_LP_TZ_SPM_REG(0x0174)
+#define	INFRA_SW_CG0			MT_LP_TZ_INFRA_REG(0x0090)
+#define	INFRA_SW_CG1			MT_LP_TZ_INFRA_REG(0x0094)
+#define	INFRA_SW_CG2			MT_LP_TZ_INFRA_REG(0x00AC)
+#define	INFRA_SW_CG3			MT_LP_TZ_INFRA_REG(0x00C8)
+#define	INFRA_SW_CG4			MT_LP_TZ_INFRA_REG(0x00E8)
+#define	TOP_SW_I2C_CG			MT_LP_TZ_TOPCK_REG(0x00A4)
+#define	PERI_SW_CG0			MT_LP_TZ_PERI_AO_REG(0x0018)
+#define	VPPSYS0_SW_CG0			MT_LP_TZ_VPPSYS0_REG(0x0020)
+#define	VPPSYS0_SW_CG1			MT_LP_TZ_VPPSYS0_REG(0x002C)
+#define	VPPSYS0_SW_CG2			MT_LP_TZ_VPPSYS0_REG(0x0038)
+#define	VPPSYS1_SW_CG0			MT_LP_TZ_VPPSYS1_REG(0x0100)
+#define	VPPSYS1_SW_CG1			MT_LP_TZ_VPPSYS1_REG(0x0110)
+#define	VDOSYS0_SW_CG0			MT_LP_TZ_VDOSYS0_REG(0x0100)
+#define	VDOSYS0_SW_CG1			MT_LP_TZ_VDOSYS0_REG(0x0110)
+#define	VDOSYS1_SW_CG0			MT_LP_TZ_VDOSYS1_REG(0x0100)
+#define	VDOSYS1_SW_CG1			MT_LP_TZ_VDOSYS1_REG(0x0120)
+#define	VDOSYS1_SW_CG2			MT_LP_TZ_VDOSYS1_REG(0x0130)
+
+#define CLK_CFG(id)			MT_LP_TZ_TOPCK_REG(0x2c + id * 0xc)
+
+enum {
+	/* CLK_CFG_0 1000_002c */
+	CLKMUX_VPP	= 0,
+	NF_CLKMUX,
+};
+
+#define CLK_CHECK BIT(31)
+
+static bool check_clkmux_pdn(unsigned int clkmux_id)
+{
+	unsigned int reg, val, idx;
+	bool ret = false;
+
+	if ((clkmux_id & CLK_CHECK) != 0U) {
+		clkmux_id = (clkmux_id & ~CLK_CHECK);
+		reg = clkmux_id / 4U;
+		val = mmio_read_32(CLK_CFG(reg));
+		idx = clkmux_id % 4U;
+		ret = (((val >> (idx * 8U)) & 0x80) != 0U);
+	}
+
+	return ret;
+}
+
+static struct mt_spm_cond_tables spm_cond_t;
+
+/* local definitions */
+struct idle_cond_info {
+	/* check SPM_PWR_STATUS for bit definition */
+	unsigned int subsys_mask;
+	/* cg address */
+	uintptr_t addr;
+	/* bitflip value from *addr ? */
+	bool bBitflip;
+	/* check clkmux if bit 31 = 1, id is bit[30:0] */
+	unsigned int clkmux_id;
+};
+
+#define IDLE_CG(mask, addr, bitflip, clkmux)	{mask, (uintptr_t)addr, bitflip, clkmux}
+
+static struct idle_cond_info idle_cg_info[PLAT_SPM_COND_MAX] = {
+	IDLE_CG(0xffffffff, SPM_PWR_STATUS, false, 0),
+	IDLE_CG(0xffffffff, SPM_CPU_PWR_STATUS, false, 0),
+	IDLE_CG(0xffffffff, INFRA_SW_CG0, true, 0),
+	IDLE_CG(0xffffffff, INFRA_SW_CG1, true, 0),
+	IDLE_CG(0xffffffff, INFRA_SW_CG2, true, 0),
+	IDLE_CG(0xffffffff, INFRA_SW_CG3, true, 0),
+	IDLE_CG(0xffffffff, INFRA_SW_CG4, true, 0),
+	IDLE_CG(0xffffffff, PERI_SW_CG0, true, 0),
+	IDLE_CG(0x00000800, VPPSYS0_SW_CG0, true, (CLK_CHECK | CLKMUX_VPP)),
+	IDLE_CG(0x00000800, VPPSYS0_SW_CG1, true, (CLK_CHECK | CLKMUX_VPP)),
+	IDLE_CG(0x00001000, VPPSYS1_SW_CG0, true, (CLK_CHECK | CLKMUX_VPP)),
+	IDLE_CG(0x00001000, VPPSYS1_SW_CG1, true, (CLK_CHECK | CLKMUX_VPP)),
+	IDLE_CG(0x00002000, VDOSYS0_SW_CG0, true, (CLK_CHECK | CLKMUX_VPP)),
+	IDLE_CG(0x00002000, VDOSYS0_SW_CG1, true, (CLK_CHECK | CLKMUX_VPP)),
+	IDLE_CG(0x00004000, VDOSYS1_SW_CG0, true, (CLK_CHECK | CLKMUX_VPP)),
+	IDLE_CG(0x00004000, VDOSYS1_SW_CG1, true, (CLK_CHECK | CLKMUX_VPP)),
+	IDLE_CG(0x00004000, VDOSYS1_SW_CG2, true, (CLK_CHECK | CLKMUX_VPP)),
+};
+
+/* check pll idle condition */
+#define PLL_MFGPLL	MT_LP_TZ_APMIXEDSYS(0x340)
+#define PLL_MMPLL	MT_LP_TZ_APMIXEDSYS(0x544)
+#define PLL_UNIVPLL	MT_LP_TZ_APMIXEDSYS(0x504)
+#define PLL_MSDCPLL	MT_LP_TZ_APMIXEDSYS(0x514)
+#define PLL_TVDPLL1	MT_LP_TZ_APMIXEDSYS(0x524)
+#define PLL_TVDPLL2	MT_LP_TZ_APMIXEDSYS(0x534)
+#define PLL_ETHPLL	MT_LP_TZ_APMIXEDSYS(0x44c)
+#define PLL_IMGPLL	MT_LP_TZ_APMIXEDSYS(0x554)
+#define PLL_APLL1	MT_LP_TZ_APMIXEDSYS(0x304)
+#define PLL_APLL2	MT_LP_TZ_APMIXEDSYS(0x318)
+#define PLL_APLL3	MT_LP_TZ_APMIXEDSYS(0x32c)
+#define PLL_APLL4	MT_LP_TZ_APMIXEDSYS(0x404)
+#define PLL_APLL5	MT_LP_TZ_APMIXEDSYS(0x418)
+
+unsigned int mt_spm_cond_check(const struct mt_spm_cond_tables *src,
+			       const struct mt_spm_cond_tables *dest,
+			       struct mt_spm_cond_tables *res)
+{
+	unsigned int b_res = 0U;
+	unsigned int i;
+
+	if ((src == NULL) || (dest == NULL)) {
+		return SPM_COND_CHECK_FAIL;
+	}
+
+	for (i = 0; i < PLAT_SPM_COND_MAX; i++) {
+		if (res != NULL) {
+			res->table_cg[i] = (src->table_cg[i] & dest->table_cg[i]);
+
+			if ((res->table_cg[i]) != 0U) {
+				b_res |= BIT(i);
+			}
+		} else if ((src->table_cg[i] & dest->table_cg[i]) != 0U) {
+			b_res |= BIT(i);
+			break;
+		}
+	}
+
+	if (res != NULL) {
+		res->table_pll = (src->table_pll & dest->table_pll);
+
+		if ((res->table_pll) != 0U) {
+			b_res |= (res->table_pll << SPM_COND_BLOCKED_PLL_IDX) |
+				 SPM_COND_CHECK_BLOCKED_PLL;
+		}
+	} else if ((src->table_pll & dest->table_pll) != 0U) {
+		b_res |= SPM_COND_CHECK_BLOCKED_PLL;
+	}
+
+	return b_res;
+}
+
+unsigned int mt_spm_dump_all_pll(const struct mt_spm_cond_tables *src,
+				 const struct mt_spm_cond_tables *dest,
+				 struct mt_spm_cond_tables *res)
+{
+	unsigned int b_res = 0U;
+
+	if (res != NULL) {
+		res->table_all_pll = src->table_all_pll;
+		if ((res->table_all_pll) != 0U) {
+			b_res |= (res->table_all_pll << SPM_COND_BLOCKED_PLL_IDX) |
+				 SPM_COND_CHECK_BLOCKED_PLL;
+		}
+	} else if ((src->table_pll & dest->table_pll) != 0U) {
+		b_res |= SPM_COND_CHECK_BLOCKED_PLL;
+	}
+
+	return b_res;
+}
+
+#define IS_MT_SPM_PWR_OFF(mask) \
+	(!(mmio_read_32(SPM_PWR_STATUS) & mask) && \
+	 !(mmio_read_32(SPM_PWR_STATUS_2ND) & mask))
+
+int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num,
+		       int stateid, void *priv)
+{
+	static const struct {
+		uintptr_t en_reg;
+		uint32_t pll_b;
+	} plls[] = {
+		{ PLL_MFGPLL, PLL_BIT_MFGPLL },
+		{ PLL_MMPLL, PLL_BIT_MMPLL },
+		{ PLL_UNIVPLL, PLL_BIT_UNIVPLL },
+		{ PLL_MSDCPLL, PLL_BIT_MSDCPLL },
+		{ PLL_TVDPLL1, PLL_BIT_TVDPLL1 },
+		{ PLL_TVDPLL2, PLL_BIT_TVDPLL2 },
+		{ PLL_ETHPLL, PLL_BIT_ETHPLL },
+		{ PLL_IMGPLL, PLL_BIT_IMGPLL },
+		{ PLL_APLL1, PLL_BIT_APLL1 },
+		{ PLL_APLL2, PLL_BIT_APLL2 },
+		{ PLL_APLL3, PLL_BIT_APLL3 },
+		{ PLL_APLL4, PLL_BIT_APLL4 },
+		{ PLL_APLL5, PLL_BIT_APLL5 },
+	};
+
+	int res;
+	unsigned int i;
+	struct mt_resource_constraint *const *_con;
+
+	/* read all cg state */
+	for (i = 0U; i < PLAT_SPM_COND_MAX; i++) {
+		spm_cond_t.table_cg[i] = 0U;
+
+		/* check mtcmos, if off set idle_value and clk to 0 disable */
+		if (IS_MT_SPM_PWR_OFF(idle_cg_info[i].subsys_mask)) {
+			continue;
+		}
+		/* check clkmux */
+		if (check_clkmux_pdn(idle_cg_info[i].clkmux_id)) {
+			continue;
+		}
+		spm_cond_t.table_cg[i] = idle_cg_info[i].bBitflip ?
+					 ~mmio_read_32(idle_cg_info[i].addr) :
+					 mmio_read_32(idle_cg_info[i].addr);
+	}
+
+	spm_cond_t.table_pll = 0U;
+	for (i = 0U; i < ARRAY_SIZE(plls); i++) {
+		if ((mmio_read_32(plls[i].en_reg) & BIT(9)) != 0U) {
+			spm_cond_t.table_pll |= plls[i].pll_b;
+		}
+	}
+
+	spm_cond_t.priv = priv;
+	for (i = 0U, _con = con; (*_con != NULL) && (i < num); _con++, i++) {
+		if ((*_con)->update == NULL) {
+			continue;
+		}
+		res = (*_con)->update(stateid, PLAT_RC_UPDATE_CONDITION,
+				      (void const *)&spm_cond_t);
+		if (res != MT_RM_STATUS_OK) {
+			break;
+		}
+	}
+
+	return 0;
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
new file mode 100644
index 0000000..793d5e8
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_COND_H
+#define MT_SPM_COND_H
+
+#include <lpm/mt_lp_rm.h>
+
+enum plat_spm_cond {
+	PLAT_SPM_COND_MTCMOS1 = 0,
+	PLAT_SPM_COND_MTCMOS2,
+	PLAT_SPM_COND_CG_INFRA_0,
+	PLAT_SPM_COND_CG_INFRA_1,
+	PLAT_SPM_COND_CG_INFRA_2,
+	PLAT_SPM_COND_CG_INFRA_3,
+	PLAT_SPM_COND_CG_INFRA_4,
+	PLAT_SPM_COND_CG_PERI_0,
+	PLAT_SPM_COND_CG_VPPSYS0_0,
+	PLAT_SPM_COND_CG_VPPSYS0_1,
+	PLAT_SPM_COND_CG_VPPSYS1_0,
+	PLAT_SPM_COND_CG_VPPSYS1_1,
+	PLAT_SPM_COND_CG_VDOSYS0_0,
+	PLAT_SPM_COND_CG_VDOSYS0_1,
+	PLAT_SPM_COND_CG_VDOSYS1_0,
+	PLAT_SPM_COND_CG_VDOSYS1_1,
+	PLAT_SPM_COND_CG_VDOSYS1_2,
+	PLAT_SPM_COND_MAX,
+};
+
+/* For PLL id >= PLAT_SPM_COND_PLL_MAX is not checked in idle condition  */
+enum plat_spm_cond_pll {
+	PLAT_SPM_COND_PLL_UNIVPLL = 0,
+	PLAT_SPM_COND_PLL_MFGPLL,
+	PLAT_SPM_COND_PLL_MSDCPLL,
+	PLAT_SPM_COND_PLL_TVDPLL1,
+	PLAT_SPM_COND_PLL_TVDPLL2,
+	PLAT_SPM_COND_PLL_MMPLL,
+	PLAT_SPM_COND_PLL_ETHPLL,
+	PLAT_SPM_COND_PLL_IMGPLL,
+	PLAT_SPM_COND_PLL_APLL1,
+	PLAT_SPM_COND_PLL_APLL2,
+	PLAT_SPM_COND_PLL_APLL3,
+	PLAT_SPM_COND_PLL_APLL4,
+	PLAT_SPM_COND_PLL_APLL5,
+	PLAT_SPM_COND_PLL_MAX,
+};
+
+#define PLL_BIT_MFGPLL	BIT(PLAT_SPM_COND_PLL_MFGPLL)
+#define PLL_BIT_MMPLL	BIT(PLAT_SPM_COND_PLL_MMPLL)
+#define PLL_BIT_UNIVPLL	BIT(PLAT_SPM_COND_PLL_UNIVPLL)
+#define PLL_BIT_MSDCPLL	BIT(PLAT_SPM_COND_PLL_MSDCPLL)
+#define PLL_BIT_TVDPLL1	BIT(PLAT_SPM_COND_PLL_TVDPLL1)
+#define PLL_BIT_TVDPLL2	BIT(PLAT_SPM_COND_PLL_TVDPLL2)
+#define PLL_BIT_ETHPLL	BIT(PLAT_SPM_COND_PLL_ETHPLL)
+#define PLL_BIT_IMGPLL	BIT(PLAT_SPM_COND_PLL_IMGPLL)
+#define PLL_BIT_APLL1	BIT(PLAT_SPM_COND_PLL_APLL1)
+#define PLL_BIT_APLL2	BIT(PLAT_SPM_COND_PLL_APLL2)
+#define PLL_BIT_APLL3   BIT(PLAT_SPM_COND_PLL_APLL3)
+#define PLL_BIT_APLL4	BIT(PLAT_SPM_COND_PLL_APLL4)
+#define PLL_BIT_APLL5	BIT(PLAT_SPM_COND_PLL_APLL5)
+
+/*
+ * Definition about SPM_COND_CHECK_BLOCKED
+ * bit[00:16]: cg blocking index
+ * bit[17:29]: pll blocking index
+ * bit[30]: pll blocking information
+ * bit[31]: idle condition check fail
+ */
+#define SPM_COND_BLOCKED_CG_IDX		(0)
+#define SPM_COND_BLOCKED_PLL_IDX	(17)
+#define SPM_COND_CHECK_BLOCKED_PLL	BIT(30)
+#define SPM_COND_CHECK_FAIL		BIT(31)
+
+struct mt_spm_cond_tables {
+	unsigned int table_cg[PLAT_SPM_COND_MAX];
+	unsigned int table_pll;
+	unsigned int table_all_pll;
+	void *priv;
+};
+
+unsigned int mt_spm_cond_check(const struct mt_spm_cond_tables *src,
+			       const struct mt_spm_cond_tables *dest,
+			       struct mt_spm_cond_tables *res);
+unsigned int mt_spm_dump_all_pll(const struct mt_spm_cond_tables *src,
+				 const struct mt_spm_cond_tables *dest,
+				 struct mt_spm_cond_tables *res);
+int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num,
+		       int stateid, void *priv);
+
+#endif
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
new file mode 100644
index 0000000..bcb2df6
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lp_rqm.h>
+#include "mt_spm.h"
+#include "mt_spm_conservation.h"
+#include "mt_spm_reg.h"
+#include <platform_def.h>
+
+#define INFRA_EMI_DCM_CFG0	U(0x10002028)
+
+static struct wake_status spm_wakesta; /* record last wakesta */
+static wake_reason_t spm_wake_reason = WR_NONE;
+static unsigned int emi_bak;
+
+static int go_to_spm_before_wfi(int state_id, unsigned int ext_opand,
+				struct spm_lp_scen *spm_lp,
+				unsigned int resource_req)
+{
+	int ret = 0;
+	struct pwr_ctrl *pwrctrl;
+	unsigned int cpu = plat_my_core_pos();
+
+	pwrctrl = spm_lp->pwrctrl;
+
+	/* EMI workaround */
+	emi_bak = mmio_read_32(INFRA_EMI_DCM_CFG0) & BIT(22);
+	mmio_setbits_32(INFRA_EMI_DCM_CFG0, BIT(22));
+
+	__spm_set_cpu_status(cpu);
+	__spm_set_power_control(pwrctrl);
+	__spm_set_wakeup_event(pwrctrl);
+
+	__spm_set_pcm_flags(pwrctrl);
+
+	__spm_src_req_update(pwrctrl, resource_req);
+
+	if ((ext_opand & MT_SPM_EX_OP_CLR_26M_RECORD) != 0U) {
+		__spm_clean_before_wfi();
+	}
+
+	if ((ext_opand & MT_SPM_EX_OP_SET_WDT) != 0U) {
+		__spm_set_pcm_wdt(1);
+	}
+
+	if ((ext_opand & MT_SPM_EX_OP_HW_S1_DETECT) != 0U) {
+		spm_hw_s1_state_monitor_resume();
+	}
+
+	__spm_send_cpu_wakeup_event();
+
+	return ret;
+}
+
+static void go_to_spm_after_wfi(int state_id, unsigned int ext_opand,
+				struct spm_lp_scen *spm_lp,
+				struct wake_status **status)
+{
+	unsigned int ext_status = 0U;
+
+	if ((ext_opand & MT_SPM_EX_OP_SET_WDT) != 0U) {
+		__spm_set_pcm_wdt(0);
+	}
+
+	if ((ext_opand & MT_SPM_EX_OP_HW_S1_DETECT) != 0U) {
+		spm_hw_s1_state_monitor_pause(&ext_status);
+	}
+
+	__spm_ext_int_wakeup_req_clr();
+
+	__spm_get_wakeup_status(&spm_wakesta, ext_status);
+
+	if (status != NULL) {
+		*status = &spm_wakesta;
+	}
+
+	__spm_clean_after_wakeup();
+	spm_wake_reason = __spm_output_wake_reason(&spm_wakesta);
+
+	/* EMI workaround */
+	if (emi_bak == 0U) {
+		mmio_clrbits_32(INFRA_EMI_DCM_CFG0, BIT(22));
+	}
+}
+
+int spm_conservation(int state_id, unsigned int ext_opand,
+		     struct spm_lp_scen *spm_lp,
+		     unsigned int resource_req)
+{
+	unsigned int rc_state = resource_req;
+
+	if (spm_lp == NULL) {
+		return -1;
+	}
+
+	spin_lock(&spm_lock);
+	go_to_spm_before_wfi(state_id, ext_opand, spm_lp, rc_state);
+	spin_unlock(&spm_lock);
+
+	return 0;
+}
+
+void spm_conservation_finish(int state_id, unsigned int ext_opand, struct spm_lp_scen *spm_lp,
+			     struct wake_status **status)
+{
+	spin_lock(&spm_lock);
+	go_to_spm_after_wfi(state_id, ext_opand, spm_lp, status);
+	spin_unlock(&spm_lock);
+}
+
+int spm_conservation_get_result(struct wake_status **res)
+{
+	if (res == NULL) {
+		return -1;
+	}
+	*res = &spm_wakesta;
+	return 0;
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.h
new file mode 100644
index 0000000..4be8567
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_CONSERVATION_H
+#define MT_SPM_CONSERVATION_H
+
+#include "mt_spm_internal.h"
+
+int spm_conservation(int state_id, unsigned int ext_opand,
+		     struct spm_lp_scen *spm_lp,
+		     unsigned int resource_req);
+void spm_conservation_finish(int state_id, unsigned int ext_opand,
+			     struct spm_lp_scen *spm_lp,
+			     struct wake_status **status);
+int spm_conservation_get_result(struct wake_status **res);
+
+#endif /* MT_SPM_CONSERVATION_H */
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_constraint.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_constraint.h
new file mode 100644
index 0000000..43bb76b
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_constraint.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_CONSTRAINT_H
+#define MT_SPM_CONSTRAINT_H
+
+#include <lpm/mt_lp_rm.h>
+
+#define MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF	BIT(0)
+#define MT_RM_CONSTRAINT_ALLOW_DRAM_S0		BIT(1)
+#define MT_RM_CONSTRAINT_ALLOW_DRAM_S1		BIT(2)
+#define MT_RM_CONSTRAINT_ALLOW_VCORE_LP		BIT(3)
+#define MT_RM_CONSTRAINT_ALLOW_INFRA_PDN	BIT(4)
+#define MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF	BIT(5)
+#define MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND	BIT(6)
+#define MT_RM_CONSTRAINT_ALLOW_BBLPM		BIT(7)
+#define MT_RM_CONSTRAINT_ALLOW_XO_UFS		BIT(8)
+#define MT_RM_CONSTRAINT_ALLOW_GPS_STATE	BIT(9)
+#define MT_RM_CONSTRAINT_ALLOW_LVTS_STATE	BIT(10)
+
+enum mt_spm_rm_rc_type {
+	MT_RM_CONSTRAINT_ID_BUS26M,
+	MT_RM_CONSTRAINT_ID_SYSPLL,
+	MT_RM_CONSTRAINT_ID_DRAM,
+	MT_RM_CONSTRAINT_ID_CPU_BUCK_LDO,
+	MT_RM_CONSTRAINT_ID_ALL,
+};
+
+#define MT_SPM_RC_INVALID		(0x0)
+#define MT_SPM_RC_VALID_SW		BIT(0)
+#define MT_SPM_RC_VALID_FW		BIT(1)
+#define MT_SPM_RC_VALID_RESIDNECY	BIT(2)
+#define MT_SPM_RC_VALID_COND_CHECK	BIT(3)
+#define MT_SPM_RC_VALID_COND_LATCH	BIT(4)
+#define MT_SPM_RC_VALID_UFS_H8		BIT(5)
+#define MT_SPM_RC_VALID_FLIGHTMODE	BIT(6)
+#define MT_SPM_RC_VALID_XSOC_BBLPM	BIT(7)
+#define MT_SPM_RC_VALID_TRACE_EVENT	BIT(8)
+#define MT_SPM_RC_VALID_TRACE_TIME	BIT(9)
+
+/* MT_RM_CONSTRAINT_SW_VALID | MT_RM_CONSTRAINT_FW_VALID */
+#define MT_SPM_RC_VALID	(MT_SPM_RC_VALID_SW)
+
+#define IS_MT_RM_RC_READY(status)	((status & MT_SPM_RC_VALID) == MT_SPM_RC_VALID)
+
+struct constraint_status {
+	uint16_t id;
+	uint16_t is_valid;
+	uint32_t is_cond_block;
+	uint32_t enter_cnt;
+	uint32_t all_pll_dump;
+	uint64_t residency;
+	struct mt_spm_cond_tables *cond_res;
+};
+
+enum constraint_status_update_type {
+	CONSTRAINT_UPDATE_VALID,
+	CONSTRAINT_UPDATE_COND_CHECK,
+	CONSTRAINT_RESIDNECY,
+};
+
+enum constraint_status_get_type {
+	CONSTRAINT_GET_VALID = 0xD0000000,
+	CONSTRAINT_GET_ENTER_CNT,
+	CONSTRAINT_GET_RESIDENCY,
+	CONSTRAINT_GET_COND_EN,
+	CONSTRAINT_COND_BLOCK,
+	CONSTRAINT_GET_COND_BLOCK_LATCH,
+	CONSTRAINT_GET_COND_BLOCK_DETAIL,
+	CONSTRAINT_GET_RESIDNECY,
+};
+
+struct rc_common_state {
+	unsigned int id;
+	unsigned int act;
+	unsigned int type;
+	void *value;
+};
+
+#define MT_SPM_RC_BBLPM_MODE	(MT_SPM_RC_VALID_UFS_H8 | \
+				 MT_SPM_RC_VALID_FLIGHTMODE | \
+				 MT_SPM_RC_VALID_XSOC_BBLPM)
+
+#define IS_MT_SPM_RC_BBLPM_MODE(st) ((st & (MT_SPM_RC_BBLPM_MODE)) == MT_SPM_RC_BBLPM_MODE)
+
+#endif /* MT_SPM_CONSTRAINT_H */
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.c
new file mode 100644
index 0000000..b4dc3f9
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <drivers/spm/mt_spm_resource_req.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lp_api.h>
+
+#include <mt_spm.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_idle.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_reg.h>
+
+#define SPM_BYPASS_SYSPWREQ_GENERIC (1)
+
+#define __WAKE_SRC_FOR_IDLE_COMMON__ ( \
+		(R12_PCM_TIMER) | \
+		(R12_KP_IRQ_B) | \
+		(R12_APWDT_EVENT_B) | \
+		(R12_APXGPT1_EVENT_B) | \
+		(R12_MSDC_WAKEUP_B) | \
+		(R12_EINT_EVENT_B) | \
+		(R12_SBD_INTR_WAKEUP_B) | \
+		(R12_SSPM2SPM_WAKEUP_B) | \
+		(R12_SCP2SPM_WAKEUP_B) | \
+		(R12_ADSP2SPM_WAKEUP_B) | \
+		(R12_USBX_CDSC_B) | \
+		(R12_USBX_POWERDWN_B) | \
+		(R12_SYS_TIMER_EVENT_B) | \
+		(R12_EINT_EVENT_SECURE_B) | \
+		(R12_ECE_INT_HDMI_B) | \
+		(R12_AFE_IRQ_MCU_B) | \
+		(R12_SYS_CIRQ_IRQ_B) | \
+		(R12_PCIE_WAKEUPEVENT_B) | \
+		(R12_SPM_CPU_WAKEUPEVENT_B) | \
+		(R12_APUSYS_WAKE_HOST_B))
+
+#if defined(CFG_MICROTRUST_TEE_SUPPORT)
+#define WAKE_SRC_FOR_IDLE	(__WAKE_SRC_FOR_IDLE_COMMON__)
+#else
+#define WAKE_SRC_FOR_IDLE	(__WAKE_SRC_FOR_IDLE_COMMON__ | R12_SEJ_EVENT_B)
+#endif
+
+static struct pwr_ctrl idle_spm_pwr = {
+	.wake_src = WAKE_SRC_FOR_IDLE,
+
+	/* SPM_AP_STANDBY_CON */
+	/* [0] */
+	.reg_wfi_op = 0,
+	/* [1] */
+	.reg_wfi_type = 0,
+	/* [2] */
+	.reg_mp0_cputop_idle_mask = 0,
+	/* [3] */
+	.reg_mp1_cputop_idle_mask = 0,
+	/* [4] */
+	.reg_mcusys_idle_mask = 0,
+	/* [25] */
+	.reg_md_apsrc_1_sel = 0,
+	/* [26] */
+	.reg_md_apsrc_0_sel = 0,
+	/* [29] */
+	.reg_conn_apsrc_sel = 0,
+
+	/* SPM_SRC_REQ */
+	/* [0] */
+	.reg_spm_apsrc_req = 0,
+	/* [1] */
+	.reg_spm_f26m_req = 0,
+	/* [3] */
+	.reg_spm_infra_req = 0,
+	/* [4] */
+	.reg_spm_vrf18_req = 0,
+	/* [7] */
+	.reg_spm_ddr_en_req = 0,
+	/* [8] */
+	.reg_spm_dvfs_req = 0,
+	/* [9] */
+	.reg_spm_sw_mailbox_req = 0,
+	/* [10] */
+	.reg_spm_sspm_mailbox_req = 0,
+	/* [11] */
+	.reg_spm_adsp_mailbox_req = 0,
+	/* [12] */
+	.reg_spm_scp_mailbox_req = 0,
+
+	/* SPM_SRC_MASK */
+	/* [0] */
+	.reg_sspm_srcclkena_0_mask_b = 1,
+	/* [1] */
+	.reg_sspm_infra_req_0_mask_b = 1,
+	/* [2] */
+	.reg_sspm_apsrc_req_0_mask_b = 1,
+	/* [3] */
+	.reg_sspm_vrf18_req_0_mask_b = 1,
+	/* [4] */
+	.reg_sspm_ddr_en_0_mask_b = 1,
+	/* [5] */
+	.reg_scp_srcclkena_mask_b = 1,
+	/* [6] */
+	.reg_scp_infra_req_mask_b = 1,
+	/* [7] */
+	.reg_scp_apsrc_req_mask_b = 1,
+	/* [8] */
+	.reg_scp_vrf18_req_mask_b = 1,
+	/* [9] */
+	.reg_scp_ddr_en_mask_b = 1,
+	/* [10] */
+	.reg_audio_dsp_srcclkena_mask_b = 1,
+	/* [11] */
+	.reg_audio_dsp_infra_req_mask_b = 1,
+	/* [12] */
+	.reg_audio_dsp_apsrc_req_mask_b = 1,
+	/* [13] */
+	.reg_audio_dsp_vrf18_req_mask_b = 1,
+	/* [14] */
+	.reg_audio_dsp_ddr_en_mask_b = 1,
+	/* [15] */
+	.reg_apu_srcclkena_mask_b = 1,
+	/* [16] */
+	.reg_apu_infra_req_mask_b = 1,
+	/* [17] */
+	.reg_apu_apsrc_req_mask_b = 1,
+	/* [18] */
+	.reg_apu_vrf18_req_mask_b = 1,
+	/* [19] */
+	.reg_apu_ddr_en_mask_b = 1,
+	/* [20] */
+	.reg_cpueb_srcclkena_mask_b = 1,
+	/* [21] */
+	.reg_cpueb_infra_req_mask_b = 1,
+	/* [22] */
+	.reg_cpueb_apsrc_req_mask_b = 1,
+	/* [23] */
+	.reg_cpueb_vrf18_req_mask_b = 1,
+	/* [24] */
+	.reg_cpueb_ddr_en_mask_b = 1,
+	/* [25] */
+	.reg_bak_psri_srcclkena_mask_b = 0,
+	/* [26] */
+	.reg_bak_psri_infra_req_mask_b = 0,
+	/* [27] */
+	.reg_bak_psri_apsrc_req_mask_b = 0,
+	/* [28] */
+	.reg_bak_psri_vrf18_req_mask_b = 0,
+	/* [29] */
+	.reg_bak_psri_ddr_en_mask_b = 0,
+	/* [30] */
+	.reg_cam_ddren_req_mask_b = 1,
+	/* [31] */
+	.reg_img_ddren_req_mask_b = 1,
+
+	/* SPM_SRC2_MASK */
+	/* [0] */
+	.reg_msdc0_srcclkena_mask_b = 1,
+	/* [1] */
+	.reg_msdc0_infra_req_mask_b = 1,
+	/* [2] */
+	.reg_msdc0_apsrc_req_mask_b = 1,
+	/* [3] */
+	.reg_msdc0_vrf18_req_mask_b = 1,
+	/* [4] */
+	.reg_msdc0_ddr_en_mask_b = 1,
+	/* [5] */
+	.reg_msdc1_srcclkena_mask_b = 1,
+	/* [6] */
+	.reg_msdc1_infra_req_mask_b = 1,
+	/* [7] */
+	.reg_msdc1_apsrc_req_mask_b = 1,
+	/* [8] */
+	.reg_msdc1_vrf18_req_mask_b = 1,
+	/* [9] */
+	.reg_msdc1_ddr_en_mask_b = 1,
+	/* [10] */
+	.reg_msdc2_srcclkena_mask_b = 1,
+	/* [11] */
+	.reg_msdc2_infra_req_mask_b = 1,
+	/* [12] */
+	.reg_msdc2_apsrc_req_mask_b = 1,
+	/* [13] */
+	.reg_msdc2_vrf18_req_mask_b = 1,
+	/* [14] */
+	.reg_msdc2_ddr_en_mask_b = 1,
+	/* [15] */
+	.reg_ufs_srcclkena_mask_b = 1,
+	/* [16] */
+	.reg_ufs_infra_req_mask_b = 1,
+	/* [17] */
+	.reg_ufs_apsrc_req_mask_b = 1,
+	/* [18] */
+	.reg_ufs_vrf18_req_mask_b = 1,
+	/* [19] */
+	.reg_ufs_ddr_en_mask_b = 1,
+	/* [20] */
+	.reg_usb_srcclkena_mask_b = 1,
+	/* [21] */
+	.reg_usb_infra_req_mask_b = 1,
+	/* [22] */
+	.reg_usb_apsrc_req_mask_b = 1,
+	/* [23] */
+	.reg_usb_vrf18_req_mask_b = 1,
+	/* [24] */
+	.reg_usb_ddr_en_mask_b = 1,
+	/* [25] */
+	.reg_pextp_p0_srcclkena_mask_b = 1,
+	/* [26] */
+	.reg_pextp_p0_infra_req_mask_b = 1,
+	/* [27] */
+	.reg_pextp_p0_apsrc_req_mask_b = 1,
+	/* [28] */
+	.reg_pextp_p0_vrf18_req_mask_b = 1,
+	/* [29] */
+	.reg_pextp_p0_ddr_en_mask_b = 1,
+
+	/* SPM_SRC3_MASK */
+	/* [0] */
+	.reg_pextp_p1_srcclkena_mask_b = 1,
+	/* [1] */
+	.reg_pextp_p1_infra_req_mask_b = 1,
+	/* [2] */
+	.reg_pextp_p1_apsrc_req_mask_b = 1,
+	/* [3] */
+	.reg_pextp_p1_vrf18_req_mask_b = 1,
+	/* [4] */
+	.reg_pextp_p1_ddr_en_mask_b = 1,
+	/* [5] */
+	.reg_gce0_infra_req_mask_b = 1,
+	/* [6] */
+	.reg_gce0_apsrc_req_mask_b = 1,
+	/* [7] */
+	.reg_gce0_vrf18_req_mask_b = 1,
+	/* [8] */
+	.reg_gce0_ddr_en_mask_b = 1,
+	/* [9] */
+	.reg_gce1_infra_req_mask_b = 1,
+	/* [10] */
+	.reg_gce1_apsrc_req_mask_b = 1,
+	/* [11] */
+	.reg_gce1_vrf18_req_mask_b = 1,
+	/* [12] */
+	.reg_gce1_ddr_en_mask_b = 1,
+	/* [13] */
+	.reg_spm_srcclkena_reserved_mask_b = 1,
+	/* [14] */
+	.reg_spm_infra_req_reserved_mask_b = 1,
+	/* [15] */
+	.reg_spm_apsrc_req_reserved_mask_b = 1,
+	/* [16] */
+	.reg_spm_vrf18_req_reserved_mask_b = 1,
+	/* [17] */
+	.reg_spm_ddr_en_reserved_mask_b = 1,
+	/* [18] */
+	.reg_disp0_apsrc_req_mask_b = 1,
+	/* [19] */
+	.reg_disp0_ddr_en_mask_b = 1,
+	/* [20] */
+	.reg_disp1_apsrc_req_mask_b = 1,
+	/* [21] */
+	.reg_disp1_ddr_en_mask_b = 1,
+	/* [22] */
+	.reg_disp2_apsrc_req_mask_b = 1,
+	/* [23] */
+	.reg_disp2_ddr_en_mask_b = 1,
+	/* [24] */
+	.reg_disp3_apsrc_req_mask_b = 1,
+	/* [25] */
+	.reg_disp3_ddr_en_mask_b = 1,
+	/* [26] */
+	.reg_infrasys_apsrc_req_mask_b = 0,
+	/* [27] */
+	.reg_infrasys_ddr_en_mask_b = 1,
+
+	/* [28] */
+	.reg_cg_check_srcclkena_mask_b = 1,
+	/* [29] */
+	.reg_cg_check_apsrc_req_mask_b = 1,
+	/* [30] */
+	.reg_cg_check_vrf18_req_mask_b = 1,
+	/* [31] */
+	.reg_cg_check_ddr_en_mask_b = 1,
+
+	/* SPM_SRC4_MASK */
+	/* [8:0] */
+	.reg_mcusys_merge_apsrc_req_mask_b = 0,
+	/* [17:9] */
+	.reg_mcusys_merge_ddr_en_mask_b = 0,
+	/* [19:18] */
+	.reg_dramc_md32_infra_req_mask_b = 3,
+	/* [21:20] */
+	.reg_dramc_md32_vrf18_req_mask_b = 3,
+	/* [23:22] */
+	.reg_dramc_md32_ddr_en_mask_b = 0,
+	/* [24] */
+	.reg_dvfsrc_event_trigger_mask_b = 1,
+
+	/* SPM_WAKEUP_EVENT_MASK2 */
+	/* [3:0] */
+	.reg_sc_sw2spm_wakeup_mask_b = 0,
+	/* [4] */
+	.reg_sc_adsp2spm_wakeup_mask_b = 0,
+	/* [8:5] */
+	.reg_sc_sspm2spm_wakeup_mask_b = 0,
+	/* [9] */
+	.reg_sc_scp2spm_wakeup_mask_b = 0,
+	/* [10] */
+	.reg_csyspwrup_ack_mask = 0,
+	/* [11] */
+	.reg_csyspwrup_req_mask = 1,
+
+	/* SPM_WAKEUP_EVENT_MASK */
+	/* [31:0] */
+	.reg_wakeup_event_mask = 0xC1282203,
+
+	/* SPM_WAKEUP_EVENT_EXT_MASK */
+	/* [31:0] */
+	.reg_ext_wakeup_event_mask = 0xFFFFFFFF,
+};
+
+struct spm_lp_scen idle_spm_lp = {
+	.pwrctrl = &idle_spm_pwr,
+};
+
+int mt_spm_idle_generic_enter(int state_id, unsigned int ext_opand, spm_idle_conduct fn)
+{
+	int ret = 0;
+	unsigned int src_req = 0U;
+
+	if (fn != NULL) {
+		fn(state_id, &idle_spm_lp, &src_req);
+	}
+
+	ret = spm_conservation(state_id, ext_opand, &idle_spm_lp, src_req);
+
+	if (ret == 0) {
+		struct mt_lp_publish_event event = {
+			.id = MT_LPM_PUBEVENTS_SYS_POWER_OFF,
+			.val.u32 = 0U,
+		};
+
+		MT_LP_PUBLISH_EVENT(&event);
+	}
+	return ret;
+}
+
+void mt_spm_idle_generic_resume(int state_id, unsigned int ext_opand,
+				struct wake_status **status,
+				spm_idle_conduct_restore fn)
+{
+	struct mt_lp_publish_event event = {
+		.id = MT_LPM_PUBEVENTS_SYS_POWER_ON,
+		.val.u32 = 0U,
+	};
+
+	ext_opand |= (MT_SPM_EX_OP_TIME_CHECK | MT_SPM_EX_OP_TIME_OBS);
+	spm_conservation_finish(state_id, ext_opand, &idle_spm_lp, status);
+
+	if (spm_unlikely(fn)) {
+		fn(state_id, &idle_spm_lp, *status);
+	}
+	MT_LP_PUBLISH_EVENT(&event);
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.h
new file mode 100644
index 0000000..4d78a28
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_idle.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_IDLE_H
+#define MT_SPM_IDLE_H
+
+#include "mt_spm_internal.h"
+
+typedef int (*spm_idle_conduct)(int state_id,
+				struct spm_lp_scen *spm_lp,
+				unsigned int *resource_req);
+typedef int (*spm_idle_conduct_restore)(int state_id,
+					struct spm_lp_scen *spm_lp,
+					struct wake_status *status);
+
+int mt_spm_idle_generic_enter(int state_id, unsigned int ext_opand, spm_idle_conduct fn);
+void mt_spm_idle_generic_resume(int state_id, unsigned int ext_opand,
+				struct wake_status **status,
+				spm_idle_conduct_restore fn);
+
+#endif
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
new file mode 100644
index 0000000..b38a6d0
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <drivers/spm/mt_spm_resource_req.h>
+#include "mt_spm.h"
+#include "mt_spm_internal.h"
+#include "mt_spm_pmic_wrap.h"
+#include "mt_spm_reg.h"
+#include <platform_def.h>
+
+#define SPM_INIT_DONE_US (20) /* Simulation result */
+
+wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta)
+{
+	wake_reason_t wr = WR_UNKNOWN;
+
+	if (wakesta == NULL) {
+		return wr;
+	}
+
+	if (wakesta->is_abort != 0U) {
+		VERBOSE("SPM EARLY WAKE r12 = 0x%x, debug_flag = 0x%x 0x%x\n",
+			wakesta->tr.comm.r12,
+			wakesta->tr.comm.debug_flag, wakesta->tr.comm.debug_flag1);
+		VERBOSE("SPM EARLY WAKE sw_flag = 0x%x 0x%x b_sw_flag = 0x%x 0x%x\n",
+			wakesta->sw_flag0, wakesta->sw_flag1,
+			wakesta->tr.comm.b_sw_flag0, wakesta->tr.comm.b_sw_flag1);
+	}
+
+	if ((wakesta->tr.comm.r12 & R12_PCM_TIMER) != 0U) {
+
+		if ((wakesta->wake_misc & WAKE_MISC_PCM_TIMER_EVENT) != 0U) {
+			wr = WR_PCM_TIMER;
+		}
+	}
+
+	return wr;
+}
+
+void __spm_set_cpu_status(unsigned int cpu)
+{
+	if (cpu >= 8) {
+		ERROR("%s: error cpu number %d\n", __func__, cpu);
+		return;
+	}
+	mmio_write_32(ROOT_CPUTOP_ADDR, BIT(cpu));
+	mmio_write_32(ROOT_CORE_ADDR, SPM_CPU0_PWR_CON + (cpu * 0x4) + 0x20000000);
+	/* Notify MCUPM to wake the target CPU up */
+	mmio_write_32(MCUPM_MBOX_WAKEUP_CPU, cpu);
+}
+
+void __spm_src_req_update(const struct pwr_ctrl *pwrctrl, unsigned int resource_usage)
+{
+
+	uint8_t reg_spm_apsrc_req = (resource_usage & MT_SPM_DRAM_S0) ?
+				    1 : pwrctrl->reg_spm_apsrc_req;
+	uint8_t reg_spm_ddr_en_req = (resource_usage & MT_SPM_DRAM_S1) ?
+				     1 : pwrctrl->reg_spm_ddr_en_req;
+	uint8_t reg_spm_vrf18_req = (resource_usage & MT_SPM_SYSPLL) ?
+				    1 : pwrctrl->reg_spm_vrf18_req;
+	uint8_t reg_spm_infra_req = (resource_usage & MT_SPM_INFRA) ?
+				    1 : pwrctrl->reg_spm_infra_req;
+	uint8_t reg_spm_f26m_req  = (resource_usage & (MT_SPM_26M | MT_SPM_XO_FPM)) ?
+				    1 : pwrctrl->reg_spm_f26m_req;
+
+	/* SPM_SRC_REQ */
+	mmio_write_32(SPM_SRC_REQ,
+		      ((reg_spm_apsrc_req & 0x1) << 0) |
+		      ((reg_spm_f26m_req & 0x1) << 1) |
+		      ((reg_spm_infra_req & 0x1) << 3) |
+		      ((reg_spm_vrf18_req & 0x1) << 4) |
+		      ((reg_spm_ddr_en_req & 0x1) << 7) |
+		      ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) |
+		      ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) |
+		      ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) |
+		      ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) |
+		      ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12));
+}
+
+void __spm_set_power_control(const struct pwr_ctrl *pwrctrl)
+{
+	/* SPM_AP_STANDBY_CON */
+	mmio_write_32(SPM_AP_STANDBY_CON,
+		      ((pwrctrl->reg_wfi_op & 0x1) << 0) |
+		      ((pwrctrl->reg_wfi_type & 0x1) << 1) |
+		      ((pwrctrl->reg_mp0_cputop_idle_mask & 0x1) << 2) |
+		      ((pwrctrl->reg_mp1_cputop_idle_mask & 0x1) << 3) |
+		      ((pwrctrl->reg_mcusys_idle_mask & 0x1) << 4) |
+		      ((pwrctrl->reg_md_apsrc_1_sel & 0x1) << 25) |
+		      ((pwrctrl->reg_md_apsrc_0_sel & 0x1) << 26) |
+		      ((pwrctrl->reg_conn_apsrc_sel & 0x1) << 29));
+
+	/* SPM_SRC_REQ */
+	mmio_write_32(SPM_SRC_REQ,
+		      ((pwrctrl->reg_spm_apsrc_req & 0x1) << 0) |
+		      ((pwrctrl->reg_spm_f26m_req & 0x1) << 1) |
+		      ((pwrctrl->reg_spm_infra_req & 0x1) << 3) |
+		      ((pwrctrl->reg_spm_vrf18_req & 0x1) << 4) |
+		      ((pwrctrl->reg_spm_ddr_en_req & 0x1) << 7) |
+		      ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) |
+		      ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) |
+		      ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) |
+		      ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) |
+		      ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12));
+
+	/* SPM_SRC_MASK */
+	mmio_write_32(SPM_SRC_MASK,
+		      ((pwrctrl->reg_sspm_srcclkena_0_mask_b & 0x1) << 0) |
+		      ((pwrctrl->reg_sspm_infra_req_0_mask_b & 0x1) << 1) |
+		      ((pwrctrl->reg_sspm_apsrc_req_0_mask_b & 0x1) << 2) |
+		      ((pwrctrl->reg_sspm_vrf18_req_0_mask_b & 0x1) << 3) |
+		      ((pwrctrl->reg_sspm_ddr_en_0_mask_b & 0x1) << 4) |
+		      ((pwrctrl->reg_scp_srcclkena_mask_b & 0x1) << 5) |
+		      ((pwrctrl->reg_scp_infra_req_mask_b & 0x1) << 6) |
+		      ((pwrctrl->reg_scp_apsrc_req_mask_b & 0x1) << 7) |
+		      ((pwrctrl->reg_scp_vrf18_req_mask_b & 0x1) << 8) |
+		      ((pwrctrl->reg_scp_ddr_en_mask_b & 0x1) << 9) |
+		      ((pwrctrl->reg_audio_dsp_srcclkena_mask_b & 0x1) << 10) |
+		      ((pwrctrl->reg_audio_dsp_infra_req_mask_b & 0x1) << 11) |
+		      ((pwrctrl->reg_audio_dsp_apsrc_req_mask_b & 0x1) << 12) |
+		      ((pwrctrl->reg_audio_dsp_vrf18_req_mask_b & 0x1) << 13) |
+		      ((pwrctrl->reg_audio_dsp_ddr_en_mask_b & 0x1) << 14) |
+		      ((pwrctrl->reg_apu_srcclkena_mask_b & 0x1) << 15) |
+		      ((pwrctrl->reg_apu_infra_req_mask_b & 0x1) << 16) |
+		      ((pwrctrl->reg_apu_apsrc_req_mask_b & 0x1) << 17) |
+		      ((pwrctrl->reg_apu_vrf18_req_mask_b & 0x1) << 18) |
+		      ((pwrctrl->reg_apu_ddr_en_mask_b & 0x1) << 19) |
+		      ((pwrctrl->reg_cpueb_srcclkena_mask_b & 0x1) << 20) |
+		      ((pwrctrl->reg_cpueb_infra_req_mask_b & 0x1) << 21) |
+		      ((pwrctrl->reg_cpueb_apsrc_req_mask_b & 0x1) << 22) |
+		      ((pwrctrl->reg_cpueb_vrf18_req_mask_b & 0x1) << 23) |
+		      ((pwrctrl->reg_cpueb_ddr_en_mask_b & 0x1) << 24) |
+		      ((pwrctrl->reg_bak_psri_srcclkena_mask_b & 0x1) << 25) |
+		      ((pwrctrl->reg_bak_psri_infra_req_mask_b & 0x1) << 26) |
+		      ((pwrctrl->reg_bak_psri_apsrc_req_mask_b & 0x1) << 27) |
+		      ((pwrctrl->reg_bak_psri_vrf18_req_mask_b & 0x1) << 28) |
+		      ((pwrctrl->reg_bak_psri_ddr_en_mask_b & 0x1) << 29) |
+		      ((pwrctrl->reg_cam_ddren_req_mask_b & 0x1) << 30) |
+		      ((pwrctrl->reg_img_ddren_req_mask_b & 0x1) << 31));
+
+	/* SPM_SRC2_MASK */
+	mmio_write_32(SPM_SRC2_MASK,
+		      ((pwrctrl->reg_msdc0_srcclkena_mask_b & 0x1) << 0) |
+		      ((pwrctrl->reg_msdc0_infra_req_mask_b & 0x1) << 1) |
+		      ((pwrctrl->reg_msdc0_apsrc_req_mask_b & 0x1) << 2) |
+		      ((pwrctrl->reg_msdc0_vrf18_req_mask_b & 0x1) << 3) |
+		      ((pwrctrl->reg_msdc0_ddr_en_mask_b & 0x1) << 4) |
+		      ((pwrctrl->reg_msdc1_srcclkena_mask_b & 0x1) << 5) |
+		      ((pwrctrl->reg_msdc1_infra_req_mask_b & 0x1) << 6) |
+		      ((pwrctrl->reg_msdc1_apsrc_req_mask_b & 0x1) << 7) |
+		      ((pwrctrl->reg_msdc1_vrf18_req_mask_b & 0x1) << 8) |
+		      ((pwrctrl->reg_msdc1_ddr_en_mask_b & 0x1) << 9) |
+		      ((pwrctrl->reg_msdc2_srcclkena_mask_b & 0x1) << 10) |
+		      ((pwrctrl->reg_msdc2_infra_req_mask_b & 0x1) << 11) |
+		      ((pwrctrl->reg_msdc2_apsrc_req_mask_b & 0x1) << 12) |
+		      ((pwrctrl->reg_msdc2_vrf18_req_mask_b & 0x1) << 13) |
+		      ((pwrctrl->reg_msdc2_ddr_en_mask_b & 0x1) << 14) |
+		      ((pwrctrl->reg_ufs_srcclkena_mask_b & 0x1) << 15) |
+		      ((pwrctrl->reg_ufs_infra_req_mask_b & 0x1) << 16) |
+		      ((pwrctrl->reg_ufs_apsrc_req_mask_b & 0x1) << 17) |
+		      ((pwrctrl->reg_ufs_vrf18_req_mask_b & 0x1) << 18) |
+		      ((pwrctrl->reg_ufs_ddr_en_mask_b & 0x1) << 19) |
+		      ((pwrctrl->reg_usb_srcclkena_mask_b & 0x1) << 20) |
+		      ((pwrctrl->reg_usb_infra_req_mask_b & 0x1) << 21) |
+		      ((pwrctrl->reg_usb_apsrc_req_mask_b & 0x1) << 22) |
+		      ((pwrctrl->reg_usb_vrf18_req_mask_b & 0x1) << 23) |
+		      ((pwrctrl->reg_usb_ddr_en_mask_b & 0x1) << 24) |
+		      ((pwrctrl->reg_pextp_p0_srcclkena_mask_b & 0x1) << 25) |
+		      ((pwrctrl->reg_pextp_p0_infra_req_mask_b & 0x1) << 26) |
+		      ((pwrctrl->reg_pextp_p0_apsrc_req_mask_b & 0x1) << 27) |
+		      ((pwrctrl->reg_pextp_p0_vrf18_req_mask_b & 0x1) << 28) |
+		      ((pwrctrl->reg_pextp_p0_ddr_en_mask_b & 0x1) << 29));
+
+	/* SPM_SRC3_MASK */
+	mmio_write_32(SPM_SRC3_MASK,
+		      ((pwrctrl->reg_pextp_p1_srcclkena_mask_b & 0x1) << 0) |
+		      ((pwrctrl->reg_pextp_p1_infra_req_mask_b & 0x1) << 1) |
+		      ((pwrctrl->reg_pextp_p1_apsrc_req_mask_b & 0x1) << 2) |
+		      ((pwrctrl->reg_pextp_p1_vrf18_req_mask_b & 0x1) << 3) |
+		      ((pwrctrl->reg_pextp_p1_ddr_en_mask_b & 0x1) << 4) |
+		      ((pwrctrl->reg_gce0_infra_req_mask_b & 0x1) << 5) |
+		      ((pwrctrl->reg_gce0_apsrc_req_mask_b & 0x1) << 6) |
+		      ((pwrctrl->reg_gce0_vrf18_req_mask_b & 0x1) << 7) |
+		      ((pwrctrl->reg_gce0_ddr_en_mask_b & 0x1) << 8) |
+		      ((pwrctrl->reg_gce1_infra_req_mask_b & 0x1) << 9) |
+		      ((pwrctrl->reg_gce1_apsrc_req_mask_b & 0x1) << 10) |
+		      ((pwrctrl->reg_gce1_vrf18_req_mask_b & 0x1) << 11) |
+		      ((pwrctrl->reg_gce1_ddr_en_mask_b & 0x1) << 12) |
+		      ((pwrctrl->reg_spm_srcclkena_reserved_mask_b & 0x1) << 13) |
+		      ((pwrctrl->reg_spm_infra_req_reserved_mask_b & 0x1) << 14) |
+		      ((pwrctrl->reg_spm_apsrc_req_reserved_mask_b & 0x1) << 15) |
+		      ((pwrctrl->reg_spm_vrf18_req_reserved_mask_b & 0x1) << 16) |
+		      ((pwrctrl->reg_spm_ddr_en_reserved_mask_b & 0x1) << 17) |
+		      ((pwrctrl->reg_disp0_ddr_en_mask_b & 0x1) << 18) |
+		      ((pwrctrl->reg_disp0_ddr_en_mask_b & 0x1) << 19) |
+		      ((pwrctrl->reg_disp1_apsrc_req_mask_b & 0x1) << 20) |
+		      ((pwrctrl->reg_disp1_ddr_en_mask_b & 0x1) << 21) |
+		      ((pwrctrl->reg_disp2_apsrc_req_mask_b & 0x1) << 22) |
+		      ((pwrctrl->reg_disp2_ddr_en_mask_b & 0x1) << 23) |
+		      ((pwrctrl->reg_disp3_apsrc_req_mask_b & 0x1) << 24) |
+		      ((pwrctrl->reg_disp3_ddr_en_mask_b & 0x1) << 25) |
+		      ((pwrctrl->reg_infrasys_apsrc_req_mask_b & 0x1) << 26) |
+		      ((pwrctrl->reg_infrasys_ddr_en_mask_b & 0x1) << 27));
+
+	/* SPM_SRC4_MASK */
+	mmio_write_32(SPM_SRC4_MASK,
+		      ((pwrctrl->reg_mcusys_merge_apsrc_req_mask_b & 0x1ff) << 0) |
+		      ((pwrctrl->reg_mcusys_merge_ddr_en_mask_b & 0x1ff) << 9) |
+		      ((pwrctrl->reg_dramc_md32_infra_req_mask_b & 0x3) << 18) |
+		      ((pwrctrl->reg_dramc_md32_vrf18_req_mask_b & 0x3) << 20) |
+		      ((pwrctrl->reg_dramc_md32_ddr_en_mask_b & 0x3) << 22) |
+		      ((pwrctrl->reg_dvfsrc_event_trigger_mask_b & 0x1) << 24));
+
+	/* SPM_WAKEUP_EVENT_MASK */
+	mmio_write_32(SPM_WAKEUP_EVENT_MASK,
+		      ((pwrctrl->reg_wakeup_event_mask & 0xffffffff) << 0));
+
+	/* SPM_WAKEUP_EVENT_EXT_MASK */
+	mmio_write_32(SPM_WAKEUP_EVENT_EXT_MASK,
+		      ((pwrctrl->reg_ext_wakeup_event_mask & 0xffffffff) << 0));
+}
+
+void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl)
+{
+	unsigned int val, mask;
+
+	/* toggle event counter clear */
+	mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | SPM_EVENT_COUNTER_CLR_LSB);
+	/* toggle for reset SYS TIMER start point */
+	mmio_setbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB);
+
+	if (pwrctrl->timer_val_cust == 0U) {
+		val = (pwrctrl->timer_val != 0U) ? pwrctrl->timer_val : PCM_TIMER_MAX;
+	} else {
+		val = pwrctrl->timer_val_cust;
+	}
+
+	mmio_write_32(PCM_TIMER_VAL, val);
+	mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | RG_PCM_TIMER_EN_LSB);
+
+	/* unmask AP wakeup source */
+	if (pwrctrl->wake_src_cust == 0U) {
+		mask = pwrctrl->wake_src;
+	} else {
+		mask = pwrctrl->wake_src_cust;
+	}
+
+	mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~mask);
+
+	/* unmask SPM ISR (keep TWAM setting) */
+	mmio_setbits_32(SPM_IRQ_MASK, ISRM_RET_IRQ_AUX);
+
+	/* toggle event counter clear */
+	mmio_clrsetbits_32(PCM_CON1, SPM_EVENT_COUNTER_CLR_LSB, SPM_REGWR_CFG_KEY);
+	/* toggle for reset SYS TIMER start point */
+	mmio_clrbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB);
+}
+
+void __spm_set_pcm_flags(struct pwr_ctrl *pwrctrl)
+{
+	/* set PCM flags and data */
+	if (pwrctrl->pcm_flags_cust_clr != 0U) {
+		pwrctrl->pcm_flags &= ~pwrctrl->pcm_flags_cust_clr;
+	}
+	if (pwrctrl->pcm_flags_cust_set != 0U) {
+		pwrctrl->pcm_flags |= pwrctrl->pcm_flags_cust_set;
+	}
+	if (pwrctrl->pcm_flags1_cust_clr != 0U) {
+		pwrctrl->pcm_flags1 &= ~pwrctrl->pcm_flags1_cust_clr;
+	}
+	if (pwrctrl->pcm_flags1_cust_set != 0U) {
+		pwrctrl->pcm_flags1 |= pwrctrl->pcm_flags1_cust_set;
+	}
+
+	mmio_write_32(SPM_SW_FLAG_0, pwrctrl->pcm_flags);
+
+	mmio_write_32(SPM_SW_FLAG_1, pwrctrl->pcm_flags1);
+
+	mmio_write_32(SPM_SW_RSV_7, pwrctrl->pcm_flags);
+
+	mmio_write_32(SPM_SW_RSV_8, pwrctrl->pcm_flags1);
+}
+
+void __spm_get_wakeup_status(struct wake_status *wakesta, unsigned int ext_status)
+{
+	/* get wakeup event */
+	wakesta->tr.comm.r12 = mmio_read_32(SPM_BK_WAKE_EVENT);	/* backup of PCM_REG12_DATA */
+	wakesta->r12_ext = mmio_read_32(SPM_WAKEUP_EXT_STA);
+	wakesta->tr.comm.raw_sta = mmio_read_32(SPM_WAKEUP_STA);
+	wakesta->raw_ext_sta = mmio_read_32(SPM_WAKEUP_EXT_STA);
+	wakesta->md32pcm_wakeup_sta = mmio_read_32(MD32PCM_WAKEUP_STA);
+	wakesta->md32pcm_event_sta = mmio_read_32(MD32PCM_EVENT_STA);
+	wakesta->wake_misc = mmio_read_32(SPM_BK_WAKE_MISC);	/* backup of SPM_WAKEUP_MISC */
+
+	/* get sleep time */
+	wakesta->tr.comm.timer_out =
+		mmio_read_32(SPM_BK_PCM_TIMER);	/* backup of PCM_TIMER_OUT */
+
+	/* get other SYS and co-clock status */
+	wakesta->tr.comm.r13 = mmio_read_32(PCM_REG13_DATA);
+	wakesta->idle_sta = mmio_read_32(SUBSYS_IDLE_STA);
+	wakesta->tr.comm.req_sta0 = mmio_read_32(SRC_REQ_STA_0);
+	wakesta->tr.comm.req_sta1 = mmio_read_32(SRC_REQ_STA_1);
+	wakesta->tr.comm.req_sta2 = mmio_read_32(SRC_REQ_STA_2);
+	wakesta->tr.comm.req_sta3 = mmio_read_32(SRC_REQ_STA_3);
+	wakesta->tr.comm.req_sta4 = mmio_read_32(SRC_REQ_STA_4);
+
+	/* get debug flag for PCM execution check */
+	wakesta->tr.comm.debug_flag = mmio_read_32(PCM_WDT_LATCH_SPARE_0);
+	wakesta->tr.comm.debug_flag1 = mmio_read_32(PCM_WDT_LATCH_SPARE_1);
+
+	if ((ext_status & SPM_INTERNAL_STATUS_HW_S1) != 0U) {
+		wakesta->tr.comm.debug_flag |= (SPM_DBG_DEBUG_IDX_DDREN_WAKE |
+						SPM_DBG_DEBUG_IDX_DDREN_SLEEP);
+		mmio_write_32(PCM_WDT_LATCH_SPARE_0, wakesta->tr.comm.debug_flag);
+	}
+
+	/* get backup SW flag status */
+	wakesta->tr.comm.b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7);	/* SPM_SW_RSV_7 */
+	wakesta->tr.comm.b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8);	/* SPM_SW_RSV_8 */
+
+	/* get ISR status */
+	wakesta->isr = mmio_read_32(SPM_IRQ_STA);
+
+	/* get SW flag status */
+	wakesta->sw_flag0 = mmio_read_32(SPM_SW_FLAG_0);
+	wakesta->sw_flag1 = mmio_read_32(SPM_SW_FLAG_1);
+
+	/* check abort */
+	wakesta->is_abort = wakesta->tr.comm.debug_flag & DEBUG_ABORT_MASK;
+	wakesta->is_abort |= wakesta->tr.comm.debug_flag1 & DEBUG_ABORT_MASK_1;
+}
+
+void __spm_clean_after_wakeup(void)
+{
+	/*
+	 * Copy SPM_WAKEUP_STA to SPM_BK_WAKE_EVENT before clear SPM_WAKEUP_STA
+	 *
+	 * CPU dormant driver @kernel will copy edge-trig IRQ pending
+	 * (recorded @SPM_BK_WAKE_EVENT) to GIC
+	 */
+	mmio_write_32(SPM_BK_WAKE_EVENT, mmio_read_32(SPM_WAKEUP_STA) |
+		      mmio_read_32(SPM_BK_WAKE_EVENT));
+
+	/* clean CPU wakeup event */
+	mmio_write_32(SPM_CPU_WAKEUP_EVENT, 0U);
+
+	/* clean wakeup event raw status (for edge trigger event) */
+	mmio_write_32(SPM_WAKEUP_EVENT_MASK, 0xefffffff);	/* bit[28] for cpu wake up event */
+
+	/* clean ISR status (except TWAM) */
+	mmio_setbits_32(SPM_IRQ_MASK,  ISRM_ALL_EXC_TWAM);
+	mmio_write_32(SPM_IRQ_STA, ISRC_ALL_EXC_TWAM);
+	mmio_write_32(SPM_SWINT_CLR, PCM_SW_INT_ALL);
+}
+
+void __spm_set_pcm_wdt(int en)
+{
+	/* enable PCM WDT (normal mode) to start count if needed */
+	if (en != 0) {
+		mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_WAKE_LSB, SPM_REGWR_CFG_KEY);
+
+		if (mmio_read_32(PCM_TIMER_VAL) > PCM_TIMER_MAX) {
+			mmio_write_32(PCM_TIMER_VAL, PCM_TIMER_MAX);
+		}
+		mmio_write_32(PCM_WDT_VAL, mmio_read_32(PCM_TIMER_VAL) + PCM_WDT_TIMEOUT);
+		mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | RG_PCM_WDT_EN_LSB);
+	} else {
+		mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_EN_LSB, SPM_REGWR_CFG_KEY);
+	}
+}
+
+void __spm_send_cpu_wakeup_event(void)
+{
+	mmio_write_32(SPM_CPU_WAKEUP_EVENT, 1);
+	/* SPM will clear SPM_CPU_WAKEUP_EVENT */
+}
+
+void __spm_ext_int_wakeup_req_clr(void)
+{
+	mmio_write_32(EXT_INT_WAKEUP_REQ_CLR, mmio_read_32(ROOT_CPUTOP_ADDR));
+
+	/* clear spm2mcupm wakeup interrupt status */
+	mmio_write_32(SPM2CPUEB_CON, 0);
+}
+
+void __spm_clean_before_wfi(void)
+{
+}
+
+void __spm_hw_s1_state_monitor(int en, unsigned int *status)
+{
+	unsigned int reg;
+
+	if (en != 0) {
+		mmio_clrsetbits_32(SPM_ACK_CHK_CON_3, SPM_ACK_CHK_3_CON_CLR_ALL,
+				   SPM_ACK_CHK_3_CON_EN);
+	} else {
+		reg = mmio_read_32(SPM_ACK_CHK_CON_3);
+
+		if ((reg & SPM_ACK_CHK_3_CON_RESULT) != 0U) {
+			if (status != NULL) {
+				*status |= SPM_INTERNAL_STATUS_HW_S1;
+			}
+		}
+
+		mmio_clrsetbits_32(SPM_ACK_CHK_CON_3, SPM_ACK_CHK_3_CON_EN,
+				   (SPM_ACK_CHK_3_CON_HW_MODE_TRIG | SPM_ACK_CHK_3_CON_CLR_ALL));
+	}
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
new file mode 100644
index 0000000..c719caf
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
@@ -0,0 +1,668 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_INTERNAL_H
+#define MT_SPM_INTERNAL_H
+
+#include <mt_spm.h>
+
+/* PCM_WDT_VAL */
+#define PCM_WDT_TIMEOUT		(30 * 32768)	/* 30s */
+/* PCM_TIMER_VAL */
+#define PCM_TIMER_MAX		(0xffffffff - PCM_WDT_TIMEOUT)
+
+/* PCM_PWR_IO_EN */
+#define PCM_PWRIO_EN_R0		BIT(0)
+#define PCM_PWRIO_EN_R7		BIT(7)
+#define PCM_RF_SYNC_R0		BIT(16)
+#define PCM_RF_SYNC_R6		BIT(22)
+#define PCM_RF_SYNC_R7		BIT(23)
+
+/* SPM_SWINT */
+#define PCM_SW_INT0		BIT(0)
+#define PCM_SW_INT1		BIT(1)
+#define PCM_SW_INT2		BIT(2)
+#define PCM_SW_INT3		BIT(3)
+#define PCM_SW_INT4		BIT(4)
+#define PCM_SW_INT5		BIT(5)
+#define PCM_SW_INT6		BIT(6)
+#define PCM_SW_INT7		BIT(7)
+#define PCM_SW_INT8		BIT(8)
+#define PCM_SW_INT9		BIT(9)
+#define PCM_SW_INT_ALL		(PCM_SW_INT9 | PCM_SW_INT8 | PCM_SW_INT7 | \
+				 PCM_SW_INT6 | PCM_SW_INT5 | PCM_SW_INT4 | \
+				 PCM_SW_INT3 | PCM_SW_INT2 | PCM_SW_INT1 | \
+				 PCM_SW_INT0)
+
+/* SPM_AP_STANDBY_CON */
+#define WFI_OP_AND		(1U)
+#define WFI_OP_OR		(0U)
+
+/* SPM_IRQ_MASK */
+#define ISRM_TWAM		BIT(2)
+#define ISRM_PCM_RETURN		BIT(3)
+#define ISRM_RET_IRQ0		BIT(8)
+#define ISRM_RET_IRQ1		BIT(9)
+#define ISRM_RET_IRQ2		BIT(10)
+#define ISRM_RET_IRQ3		BIT(11)
+#define ISRM_RET_IRQ4		BIT(12)
+#define ISRM_RET_IRQ5		BIT(13)
+#define ISRM_RET_IRQ6		BIT(14)
+#define ISRM_RET_IRQ7		BIT(15)
+#define ISRM_RET_IRQ8		BIT(16)
+#define ISRM_RET_IRQ9		BIT(17)
+#define ISRM_RET_IRQ_AUX	((ISRM_RET_IRQ9) | (ISRM_RET_IRQ8) | \
+				 (ISRM_RET_IRQ7) | (ISRM_RET_IRQ6) | \
+				 (ISRM_RET_IRQ5) | (ISRM_RET_IRQ4) | \
+				 (ISRM_RET_IRQ3) | (ISRM_RET_IRQ2) | \
+				 (ISRM_RET_IRQ1))
+#define ISRM_ALL_EXC_TWAM	ISRM_RET_IRQ_AUX
+#define ISRM_ALL		(ISRM_ALL_EXC_TWAM | ISRM_TWAM)
+
+/* SPM_IRQ_STA */
+#define ISRS_TWAM		BIT(2)
+#define ISRS_PCM_RETURN		BIT(3)
+#define ISRC_TWAM		ISRS_TWAM
+#define ISRC_ALL_EXC_TWAM	ISRS_PCM_RETURN
+#define ISRC_ALL		(ISRC_ALL_EXC_TWAM | ISRC_TWAM)
+
+/* SPM_WAKEUP_MISC */
+#define WAKE_MISC_GIC_WAKEUP			(0x3FF)
+#define WAKE_MISC_DVFSRC_IRQ			DVFSRC_IRQ_LSB
+#define WAKE_MISC_REG_CPU_WAKEUP		SPM_WAKEUP_MISC_REG_CPU_WAKEUP_LSB
+#define WAKE_MISC_PCM_TIMER_EVENT		PCM_TIMER_EVENT_LSB
+#define WAKE_MISC_TWAM_IRQ_B			TWAM_IRQ_B_LSB
+#define WAKE_MISC_PMSR_IRQ_B_SET0		PMSR_IRQ_B_SET0_LSB
+#define WAKE_MISC_PMSR_IRQ_B_SET1		PMSR_IRQ_B_SET1_LSB
+#define WAKE_MISC_PMSR_IRQ_B_SET2		PMSR_IRQ_B_SET2_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_0		SPM_ACK_CHK_WAKEUP_0_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_1		SPM_ACK_CHK_WAKEUP_1_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_2		SPM_ACK_CHK_WAKEUP_2_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_3		SPM_ACK_CHK_WAKEUP_3_LSB
+#define WAKE_MISC_SPM_ACK_CHK_WAKEUP_ALL	SPM_ACK_CHK_WAKEUP_ALL_LSB
+#define WAKE_MISC_PMIC_IRQ_ACK			PMIC_IRQ_ACK_LSB
+#define WAKE_MISC_PMIC_SCP_IRQ			PMIC_SCP_IRQ_LSB
+
+/* MD32PCM ADDR for SPM code fetch */
+#define MD32PCM_BASE			(SPM_BASE + 0x0A00)
+#define MD32PCM_CFGREG_SW_RSTN		(MD32PCM_BASE + 0x0000)
+#define MD32PCM_DMA0_SRC		(MD32PCM_BASE + 0x0200)
+#define MD32PCM_DMA0_DST		(MD32PCM_BASE + 0x0204)
+#define MD32PCM_DMA0_WPPT		(MD32PCM_BASE + 0x0208)
+#define MD32PCM_DMA0_WPTO		(MD32PCM_BASE + 0x020C)
+#define MD32PCM_DMA0_COUNT		(MD32PCM_BASE + 0x0210)
+#define MD32PCM_DMA0_CON		(MD32PCM_BASE + 0x0214)
+#define MD32PCM_DMA0_START		(MD32PCM_BASE + 0x0218)
+#define MD32PCM_DMA0_RLCT		(MD32PCM_BASE + 0x0224)
+#define MD32PCM_INTC_IRQ_RAW_STA	(MD32PCM_BASE + 0x033C)
+
+/* ABORT MASK for DEBUG FOORTPRINT */
+#define DEBUG_ABORT_MASK (SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_APSRC | \
+			  SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_DDREN)
+
+#define DEBUG_ABORT_MASK_1 (SPM_DBG1_DEBUG_IDX_VRCXO_SLEEP_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_LOW_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_HIGH_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_EMI_SLP_IDLE_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_LOW_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_HIGH_ABORT | \
+			    SPM_DBG1_DEBUG_IDX_SPM_DVFS_CMD_RDY_ABORT)
+
+#define MCUPM_MBOX_WAKEUP_CPU (0x0C55FD10)
+
+struct pcm_desc {
+	const char *version;	/* PCM code version */
+	uint32_t *base;		/* binary array base */
+	uintptr_t base_dma;	/* dma addr of base */
+	uint32_t pmem_words;
+	uint32_t total_words;
+	uint32_t pmem_start;
+	uint32_t dmem_start;
+};
+
+struct pwr_ctrl {
+	/* for SPM */
+	uint32_t pcm_flags;
+	/* can override pcm_flags */
+	uint32_t pcm_flags_cust;
+	/* set bit of pcm_flags, after pcm_flags_cust */
+	uint32_t pcm_flags_cust_set;
+	/* clr bit of pcm_flags, after pcm_flags_cust */
+	uint32_t pcm_flags_cust_clr;
+	uint32_t pcm_flags1;
+	/* can override pcm_flags1 */
+	uint32_t pcm_flags1_cust;
+	/* set bit of pcm_flags1, after pcm_flags1_cust */
+	uint32_t pcm_flags1_cust_set;
+	/* clr bit of pcm_flags1, after pcm_flags1_cust */
+	uint32_t pcm_flags1_cust_clr;
+	/* @ 1T 32K */
+	uint32_t timer_val;
+	/* @ 1T 32K, can override timer_val */
+	uint32_t timer_val_cust;
+	/* stress for dpidle */
+	uint32_t timer_val_ramp_en;
+	/* stress for suspend */
+	uint32_t timer_val_ramp_en_sec;
+	uint32_t wake_src;
+	/* can override wake_src */
+	uint32_t wake_src_cust;
+	/* disable wdt in suspend */
+	uint8_t wdt_disable;
+
+	/* SPM_AP_STANDBY_CON */
+	/* [0] */
+	uint8_t reg_wfi_op;
+	/* [1] */
+	uint8_t reg_wfi_type;
+	/* [2] */
+	uint8_t reg_mp0_cputop_idle_mask;
+	/* [3] */
+	uint8_t reg_mp1_cputop_idle_mask;
+	/* [4] */
+	uint8_t reg_mcusys_idle_mask;
+	/* [25] */
+	uint8_t reg_md_apsrc_1_sel;
+	/* [26] */
+	uint8_t reg_md_apsrc_0_sel;
+	/* [29] */
+	uint8_t reg_conn_apsrc_sel;
+
+	/* SPM_SRC_REQ */
+	/* [0] */
+	uint8_t reg_spm_apsrc_req;
+	/* [1] */
+	uint8_t reg_spm_f26m_req;
+	/* [3] */
+	uint8_t reg_spm_infra_req;
+	/* [4] */
+	uint8_t reg_spm_vrf18_req;
+	/* [7] */
+	uint8_t reg_spm_ddr_en_req;
+	/* [8] */
+	uint8_t reg_spm_dvfs_req;
+	/* [9] */
+	uint8_t reg_spm_sw_mailbox_req;
+	/* [10] */
+	uint8_t reg_spm_sspm_mailbox_req;
+	/* [11] */
+	uint8_t reg_spm_adsp_mailbox_req;
+	/* [12] */
+	uint8_t reg_spm_scp_mailbox_req;
+
+	/* SPM_SRC_MASK */
+	/* [0] */
+	uint8_t reg_sspm_srcclkena_0_mask_b;
+	/* [1] */
+	uint8_t reg_sspm_infra_req_0_mask_b;
+	/* [2] */
+	uint8_t reg_sspm_apsrc_req_0_mask_b;
+	/* [3] */
+	uint8_t reg_sspm_vrf18_req_0_mask_b;
+	/* [4] */
+	uint8_t reg_sspm_ddr_en_0_mask_b;
+	/* [5] */
+	uint8_t reg_scp_srcclkena_mask_b;
+	/* [6] */
+	uint8_t reg_scp_infra_req_mask_b;
+	/* [7] */
+	uint8_t reg_scp_apsrc_req_mask_b;
+	/* [8] */
+	uint8_t reg_scp_vrf18_req_mask_b;
+	/* [9] */
+	uint8_t reg_scp_ddr_en_mask_b;
+	/* [10] */
+	uint8_t reg_audio_dsp_srcclkena_mask_b;
+	/* [11] */
+	uint8_t reg_audio_dsp_infra_req_mask_b;
+	/* [12] */
+	uint8_t reg_audio_dsp_apsrc_req_mask_b;
+	/* [13] */
+	uint8_t reg_audio_dsp_vrf18_req_mask_b;
+	/* [14] */
+	uint8_t reg_audio_dsp_ddr_en_mask_b;
+	/* [15] */
+	uint8_t reg_apu_srcclkena_mask_b;
+	/* [16] */
+	uint8_t reg_apu_infra_req_mask_b;
+	/* [17] */
+	uint8_t reg_apu_apsrc_req_mask_b;
+	/* [18] */
+	uint8_t reg_apu_vrf18_req_mask_b;
+	/* [19] */
+	uint8_t reg_apu_ddr_en_mask_b;
+	/* [20] */
+	uint8_t reg_cpueb_srcclkena_mask_b;
+	/* [21] */
+	uint8_t reg_cpueb_infra_req_mask_b;
+	/* [22] */
+	uint8_t reg_cpueb_apsrc_req_mask_b;
+	/* [23] */
+	uint8_t reg_cpueb_vrf18_req_mask_b;
+	/* [24] */
+	uint8_t reg_cpueb_ddr_en_mask_b;
+	/* [25] */
+	uint8_t reg_bak_psri_srcclkena_mask_b;
+	/* [26] */
+	uint8_t reg_bak_psri_infra_req_mask_b;
+	/* [27] */
+	uint8_t reg_bak_psri_apsrc_req_mask_b;
+	/* [28] */
+	uint8_t reg_bak_psri_vrf18_req_mask_b;
+	/* [29] */
+	uint8_t reg_bak_psri_ddr_en_mask_b;
+	/* [30] */
+	uint8_t reg_cam_ddren_req_mask_b;
+	/* [31] */
+	uint8_t reg_img_ddren_req_mask_b;
+
+	/* SPM_SRC2_MASK */
+	/* [0] */
+	uint8_t reg_msdc0_srcclkena_mask_b;
+	/* [1] */
+	uint8_t reg_msdc0_infra_req_mask_b;
+	/* [2] */
+	uint8_t reg_msdc0_apsrc_req_mask_b;
+	/* [3] */
+	uint8_t reg_msdc0_vrf18_req_mask_b;
+	/* [4] */
+	uint8_t reg_msdc0_ddr_en_mask_b;
+	/* [5] */
+	uint8_t reg_msdc1_srcclkena_mask_b;
+	/* [6] */
+	uint8_t reg_msdc1_infra_req_mask_b;
+	/* [7] */
+	uint8_t reg_msdc1_apsrc_req_mask_b;
+	/* [8] */
+	uint8_t reg_msdc1_vrf18_req_mask_b;
+	/* [9] */
+	uint8_t reg_msdc1_ddr_en_mask_b;
+	/* [10] */
+	uint8_t reg_msdc2_srcclkena_mask_b;
+	/* [11] */
+	uint8_t reg_msdc2_infra_req_mask_b;
+	/* [12] */
+	uint8_t reg_msdc2_apsrc_req_mask_b;
+	/* [13] */
+	uint8_t reg_msdc2_vrf18_req_mask_b;
+	/* [14] */
+	uint8_t reg_msdc2_ddr_en_mask_b;
+	/* [15] */
+	uint8_t reg_ufs_srcclkena_mask_b;
+	/* [16] */
+	uint8_t reg_ufs_infra_req_mask_b;
+	/* [17] */
+	uint8_t reg_ufs_apsrc_req_mask_b;
+	/* [18] */
+	uint8_t reg_ufs_vrf18_req_mask_b;
+	/* [19] */
+	uint8_t reg_ufs_ddr_en_mask_b;
+	/* [20] */
+	uint8_t reg_usb_srcclkena_mask_b;
+	/* [21] */
+	uint8_t reg_usb_infra_req_mask_b;
+	/* [22] */
+	uint8_t reg_usb_apsrc_req_mask_b;
+	/* [23] */
+	uint8_t reg_usb_vrf18_req_mask_b;
+	/* [24] */
+	uint8_t reg_usb_ddr_en_mask_b;
+	/* [25] */
+	uint8_t reg_pextp_p0_srcclkena_mask_b;
+	/* [26] */
+	uint8_t reg_pextp_p0_infra_req_mask_b;
+	/* [27] */
+	uint8_t reg_pextp_p0_apsrc_req_mask_b;
+	/* [28] */
+	uint8_t reg_pextp_p0_vrf18_req_mask_b;
+	/* [29] */
+	uint8_t reg_pextp_p0_ddr_en_mask_b;
+
+	/* SPM_SRC3_MASK */
+	/* [0] */
+	uint8_t reg_pextp_p1_srcclkena_mask_b;
+	/* [1] */
+	uint8_t reg_pextp_p1_infra_req_mask_b;
+	/* [2] */
+	uint8_t reg_pextp_p1_apsrc_req_mask_b;
+	/* [3] */
+	uint8_t reg_pextp_p1_vrf18_req_mask_b;
+	/* [4] */
+	uint8_t reg_pextp_p1_ddr_en_mask_b;
+	/* [5] */
+	uint8_t reg_gce0_infra_req_mask_b;
+	/* [6] */
+	uint8_t reg_gce0_apsrc_req_mask_b;
+	/* [7] */
+	uint8_t reg_gce0_vrf18_req_mask_b;
+	/* [8] */
+	uint8_t reg_gce0_ddr_en_mask_b;
+	/* [9] */
+	uint8_t reg_gce1_infra_req_mask_b;
+	/* [10] */
+	uint8_t reg_gce1_apsrc_req_mask_b;
+	/* [11] */
+	uint8_t reg_gce1_vrf18_req_mask_b;
+	/* [12] */
+	uint8_t reg_gce1_ddr_en_mask_b;
+	/* [13] */
+	uint8_t reg_spm_srcclkena_reserved_mask_b;
+	/* [14] */
+	uint8_t reg_spm_infra_req_reserved_mask_b;
+	/* [15] */
+	uint8_t reg_spm_apsrc_req_reserved_mask_b;
+	/* [16] */
+	uint8_t reg_spm_vrf18_req_reserved_mask_b;
+	/* [17] */
+	uint8_t reg_spm_ddr_en_reserved_mask_b;
+	/* [18] */
+	uint8_t reg_disp0_apsrc_req_mask_b;
+	/* [19] */
+	uint8_t reg_disp0_ddr_en_mask_b;
+	/* [20] */
+	uint8_t reg_disp1_apsrc_req_mask_b;
+	/* [21] */
+	uint8_t reg_disp1_ddr_en_mask_b;
+	/* [22] */
+	uint8_t reg_disp2_apsrc_req_mask_b;
+	/* [23] */
+	uint8_t reg_disp2_ddr_en_mask_b;
+	/* [24] */
+	uint8_t reg_disp3_apsrc_req_mask_b;
+	/* [25] */
+	uint8_t reg_disp3_ddr_en_mask_b;
+	/* [26] */
+	uint8_t reg_infrasys_apsrc_req_mask_b;
+	/* [27] */
+	uint8_t reg_infrasys_ddr_en_mask_b;
+	/* [28] */
+	uint8_t reg_cg_check_srcclkena_mask_b;
+	/* [29] */
+	uint8_t reg_cg_check_apsrc_req_mask_b;
+	/* [30] */
+	uint8_t reg_cg_check_vrf18_req_mask_b;
+	/* [31] */
+	uint8_t reg_cg_check_ddr_en_mask_b;
+
+	/* SPM_SRC4_MASK */
+	/* [8:0] */
+	uint32_t reg_mcusys_merge_apsrc_req_mask_b;
+	/* [17:9] */
+	uint32_t reg_mcusys_merge_ddr_en_mask_b;
+	/* [19:18] */
+	uint8_t reg_dramc_md32_infra_req_mask_b;
+	/* [21:20] */
+	uint8_t reg_dramc_md32_vrf18_req_mask_b;
+	/* [23:22] */
+	uint8_t reg_dramc_md32_ddr_en_mask_b;
+	/* [24] */
+	uint8_t reg_dvfsrc_event_trigger_mask_b;
+
+	/* SPM_WAKEUP_EVENT_MASK2 */
+	/* [3:0] */
+	uint8_t reg_sc_sw2spm_wakeup_mask_b;
+	/* [4] */
+	uint8_t reg_sc_adsp2spm_wakeup_mask_b;
+	/* [8:5] */
+	uint8_t reg_sc_sspm2spm_wakeup_mask_b;
+	/* [9] */
+	uint8_t reg_sc_scp2spm_wakeup_mask_b;
+	/* [10] */
+	uint8_t reg_csyspwrup_ack_mask;
+	/* [11] */
+	uint8_t reg_csyspwrup_req_mask;
+
+	/* SPM_WAKEUP_EVENT_MASK */
+	/* [31:0] */
+	uint32_t reg_wakeup_event_mask;
+
+	/* SPM_WAKEUP_EVENT_EXT_MASK */
+	/* [31:0] */
+	uint32_t reg_ext_wakeup_event_mask;
+};
+
+/* code gen by spm_pwr_ctrl_atf.pl, need struct pwr_ctrl */
+enum pwr_ctrl_enum {
+	PW_PCM_FLAGS,
+	PW_PCM_FLAGS_CUST,
+	PW_PCM_FLAGS_CUST_SET,
+	PW_PCM_FLAGS_CUST_CLR,
+	PW_PCM_FLAGS1,
+	PW_PCM_FLAGS1_CUST,
+	PW_PCM_FLAGS1_CUST_SET,
+	PW_PCM_FLAGS1_CUST_CLR,
+	PW_TIMER_VAL,
+	PW_TIMER_VAL_CUST,
+	PW_TIMER_VAL_RAMP_EN,
+	PW_TIMER_VAL_RAMP_EN_SEC,
+	PW_WAKE_SRC,
+	PW_WAKE_SRC_CUST,
+	PW_WDT_DISABLE,
+
+	/* SPM_AP_STANDBY_CON */
+	PW_REG_WFI_OP,
+	PW_REG_WFI_TYPE,
+	PW_REG_MP0_CPUTOP_IDLE_MASK,
+	PW_REG_MP1_CPUTOP_IDLE_MASK,
+	PW_REG_MCUSYS_IDLE_MASK,
+	PW_REG_MD_APSRC_1_SEL,
+	PW_REG_MD_APSRC_0_SEL,
+	PW_REG_CONN_APSRC_SEL,
+
+	/* SPM_SRC_REQ */
+	PW_REG_SPM_APSRC_REQ,
+	PW_REG_SPM_F26M_REQ,
+	PW_REG_SPM_INFRA_REQ,
+	PW_REG_SPM_VRF18_REQ,
+	PW_REG_SPM_DDR_EN_REQ,
+	PW_REG_SPM_DVFS_REQ,
+	PW_REG_SPM_SW_MAILBOX_REQ,
+	PW_REG_SPM_SSPM_MAILBOX_REQ,
+	PW_REG_SPM_ADSP_MAILBOX_REQ,
+	PW_REG_SPM_SCP_MAILBOX_REQ,
+
+	/* SPM_SRC_MASK */
+	PW_REG_SSPM_SRCCLKENA_0_MASK_B,
+	PW_REG_SSPM_INFRA_REQ_0_MASK_B,
+	PW_REG_SSPM_APSRC_REQ_0_MASK_B,
+	PW_REG_SSPM_VRF18_REQ_0_MASK_B,
+	PW_REG_SSPM_DDR_EN_0_MASK_B,
+	PW_REG_SCP_SRCCLKENA_MASK_B,
+	PW_REG_SCP_INFRA_REQ_MASK_B,
+	PW_REG_SCP_APSRC_REQ_MASK_B,
+	PW_REG_SCP_VRF18_REQ_MASK_B,
+	PW_REG_SCP_DDR_EN_MASK_B,
+	PW_REG_AUDIO_DSP_SRCCLKENA_MASK_B,
+	PW_REG_AUDIO_DSP_INFRA_REQ_MASK_B,
+	PW_REG_AUDIO_DSP_APSRC_REQ_MASK_B,
+	PW_REG_AUDIO_DSP_VRF18_REQ_MASK_B,
+	PW_REG_AUDIO_DSP_DDR_EN_MASK_B,
+	PW_REG_APU_SRCCLKENA_MASK_B,
+	PW_REG_APU_INFRA_REQ_MASK_B,
+	PW_REG_APU_APSRC_REQ_MASK_B,
+	PW_REG_APU_VRF18_REQ_MASK_B,
+	PW_REG_APU_DDR_EN_MASK_B,
+	PW_REG_CPUEB_SRCCLKENA_MASK_B,
+	PW_REG_CPUEB_INFRA_REQ_MASK_B,
+	PW_REG_CPUEB_APSRC_REQ_MASK_B,
+	PW_REG_CPUEB_VRF18_REQ_MASK_B,
+	PW_REG_CPUEB_DDR_EN_MASK_B,
+	PW_REG_BAK_PSRI_SRCCLKENA_MASK_B,
+	PW_REG_BAK_PSRI_INFRA_REQ_MASK_B,
+	PW_REG_BAK_PSRI_APSRC_REQ_MASK_B,
+	PW_REG_BAK_PSRI_VRF18_REQ_MASK_B,
+	PW_REG_BAK_PSRI_DDR_EN_MASK_B,
+	PW_REG_CAM_DDREN_REQ_MASK_B,
+	PW_REG_IMG_DDREN_REQ_MASK_B,
+
+	/* SPM_SRC2_MASK */
+	PW_REG_MSDC0_SRCCLKENA_MASK_B,
+	PW_REG_MSDC0_INFRA_REQ_MASK_B,
+	PW_REG_MSDC0_APSRC_REQ_MASK_B,
+	PW_REG_MSDC0_VRF18_REQ_MASK_B,
+	PW_REG_MSDC0_DDR_EN_MASK_B,
+	PW_REG_MSDC1_SRCCLKENA_MASK_B,
+	PW_REG_MSDC1_INFRA_REQ_MASK_B,
+	PW_REG_MSDC1_APSRC_REQ_MASK_B,
+	PW_REG_MSDC1_VRF18_REQ_MASK_B,
+	PW_REG_MSDC1_DDR_EN_MASK_B,
+	PW_REG_MSDC2_SRCCLKENA_MASK_B,
+	PW_REG_MSDC2_INFRA_REQ_MASK_B,
+	PW_REG_MSDC2_APSRC_REQ_MASK_B,
+	PW_REG_MSDC2_VRF18_REQ_MASK_B,
+	PW_REG_MSDC2_DDR_EN_MASK_B,
+	PW_REG_UFS_SRCCLKENA_MASK_B,
+	PW_REG_UFS_INFRA_REQ_MASK_B,
+	PW_REG_UFS_APSRC_REQ_MASK_B,
+	PW_REG_UFS_VRF18_REQ_MASK_B,
+	PW_REG_UFS_DDR_EN_MASK_B,
+	PW_REG_USB_SRCCLKENA_MASK_B,
+	PW_REG_USB_INFRA_REQ_MASK_B,
+	PW_REG_USB_APSRC_REQ_MASK_B,
+	PW_REG_USB_VRF18_REQ_MASK_B,
+	PW_REG_USB_DDR_EN_MASK_B,
+	PW_REG_PEXTP_P0_SRCCLKENA_MASK_B,
+	PW_REG_PEXTP_P0_INFRA_REQ_MASK_B,
+	PW_REG_PEXTP_P0_APSRC_REQ_MASK_B,
+	PW_REG_PEXTP_P0_VRF18_REQ_MASK_B,
+	PW_REG_PEXTP_P0_DDR_EN_MASK_B,
+
+	/* SPM_SRC3_MASK */
+	PW_REG_PEXTP_P1_SRCCLKENA_MASK_B,
+	PW_REG_PEXTP_P1_INFRA_REQ_MASK_B,
+	PW_REG_PEXTP_P1_APSRC_REQ_MASK_B,
+	PW_REG_PEXTP_P1_VRF18_REQ_MASK_B,
+	PW_REG_PEXTP_P1_DDR_EN_MASK_B,
+	PW_REG_GCE0_INFRA_REQ_MASK_B,
+	PW_REG_GCE0_APSRC_REQ_MASK_B,
+	PW_REG_GCE0_VRF18_REQ_MASK_B,
+	PW_REG_GCE0_DDR_EN_MASK_B,
+	PW_REG_GCE1_INFRA_REQ_MASK_B,
+	PW_REG_GCE1_APSRC_REQ_MASK_B,
+	PW_REG_GCE1_VRF18_REQ_MASK_B,
+	PW_REG_GCE1_DDR_EN_MASK_B,
+	PW_REG_SPM_SRCCLKENA_RESERVED_MASK_B,
+	PW_REG_SPM_INFRA_REQ_RESERVED_MASK_B,
+	PW_REG_SPM_APSRC_REQ_RESERVED_MASK_B,
+	PW_REG_SPM_VRF18_REQ_RESERVED_MASK_B,
+	PW_REG_SPM_DDR_EN_RESERVED_MASK_B,
+	PW_REG_DISP0_APSRC_REQ_MASK_B,
+	PW_REG_DISP0_DDR_EN_MASK_B,
+	PW_REG_DISP1_APSRC_REQ_MASK_B,
+	PW_REG_DISP1_DDR_EN_MASK_B,
+	PW_REG_DISP2_APSRC_REQ_MASK_B,
+	PW_REG_DISP2_DDR_EN_MASK_B,
+	PW_REG_DISP3_APSRC_REQ_MASK_B,
+	PW_REG_DISP3_DDR_EN_MASK_B,
+	PW_REG_INFRASYS_APSRC_REQ_MASK_B,
+	PW_REG_INFRASYS_DDR_EN_MASK_B,
+	PW_REG_CG_CHECK_SRCCLKENA_MASK_B,
+	PW_REG_CG_CHECK_APSRC_REQ_MASK_B,
+	PW_REG_CG_CHECK_VRF18_REQ_MASK_B,
+	PW_REG_CG_CHECK_DDR_EN_MASK_B,
+
+	/* SPM_SRC4_MASK */
+	PW_REG_MCUSYS_MERGE_APSRC_REQ_MASK_B,
+	PW_REG_MCUSYS_MERGE_DDR_EN_MASK_B,
+	PW_REG_DRAMC_MD32_INFRA_REQ_MASK_B,
+	PW_REG_DRAMC_MD32_VRF18_REQ_MASK_B,
+	PW_REG_DRAMC_MD32_DDR_EN_MASK_B,
+	PW_REG_DVFSRC_EVENT_TRIGGER_MASK_B,
+
+	/* SPM_WAKEUP_EVENT_MASK2 */
+	PW_REG_SC_SW2SPM_WAKEUP_MASK_B,
+	PW_REG_SC_ADSP2SPM_WAKEUP_MASK_B,
+	PW_REG_SC_SSPM2SPM_WAKEUP_MASK_B,
+	PW_REG_SC_SCP2SPM_WAKEUP_MASK_B,
+	PW_REG_CSYSPWRUP_ACK_MASK,
+	PW_REG_CSYSPWRUP_REQ_MASK,
+
+	/* SPM_WAKEUP_EVENT_MASK */
+	PW_REG_WAKEUP_EVENT_MASK,
+
+	/* SPM_WAKEUP_EVENT_EXT_MASK */
+	PW_REG_EXT_WAKEUP_EVENT_MASK,
+	PW_MAX_COUNT,
+};
+
+/* spm_internal.c internal status */
+#define SPM_INTERNAL_STATUS_HW_S1	BIT(0)
+#define SPM_ACK_CHK_3_CON_HW_MODE_TRIG	(0x800)
+/* BIT[0]: SW_EN, BIT[4]: STA_EN, BIT[8]: HW_EN */
+#define SPM_ACK_CHK_3_CON_EN		(0x110)
+#define SPM_ACK_CHK_3_CON_CLR_ALL	(0x2)
+/* BIT[15]: RESULT */
+#define SPM_ACK_CHK_3_CON_RESULT	(0x8000)
+
+struct wake_status_trace_comm {
+	uint32_t debug_flag;	/* PCM_WDT_LATCH_SPARE_0 */
+	uint32_t debug_flag1;	/* PCM_WDT_LATCH_SPARE_1 */
+	uint32_t timer_out;	/* SPM_SW_RSV_6*/
+	uint32_t b_sw_flag0;	/* SPM_SW_RSV_7 */
+	uint32_t b_sw_flag1;	/* SPM_SW_RSV_7 */
+	uint32_t r12;		/* SPM_SW_RSV_0 */
+	uint32_t r13;		/* PCM_REG13_DATA */
+	uint32_t req_sta0;	/* SRC_REQ_STA_0 */
+	uint32_t req_sta1;	/* SRC_REQ_STA_1 */
+	uint32_t req_sta2;	/* SRC_REQ_STA_2 */
+	uint32_t req_sta3;	/* SRC_REQ_STA_3 */
+	uint32_t req_sta4;	/* SRC_REQ_STA_4 */
+	uint32_t raw_sta;	/* SPM_WAKEUP_STA */
+	uint32_t times_h;	/* timestamp high bits */
+	uint32_t times_l;	/* timestamp low bits */
+	uint32_t resumetime;	/* timestamp low bits */
+};
+
+struct wake_status_trace {
+	struct wake_status_trace_comm comm;
+};
+
+struct wake_status {
+	struct wake_status_trace tr;
+	uint32_t r12_ext;		/* SPM_WAKEUP_EXT_STA */
+	uint32_t raw_ext_sta;		/* SPM_WAKEUP_EXT_STA */
+	uint32_t md32pcm_wakeup_sta;	/* MD32PCM_WAKEUP_STA */
+	uint32_t md32pcm_event_sta;	/* MD32PCM_EVENT_STA */
+	uint32_t wake_misc;		/* SPM_SW_RSV_5 */
+	uint32_t idle_sta;		/* SUBSYS_IDLE_STA */
+	uint32_t sw_flag0;		/* SPM_SW_FLAG_0 */
+	uint32_t sw_flag1;		/* SPM_SW_FLAG_1 */
+	uint32_t isr;			/* SPM_IRQ_STA */
+	uint32_t log_index;
+	uint32_t is_abort;
+};
+
+struct spm_lp_scen {
+	struct pcm_desc *pcmdesc;
+	struct pwr_ctrl *pwrctrl;
+};
+
+void __spm_set_cpu_status(unsigned int cpu);
+void __spm_src_req_update(const struct pwr_ctrl *pwrctrl, unsigned int resource_usage);
+void __spm_set_power_control(const struct pwr_ctrl *pwrctrl);
+void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl);
+void __spm_set_pcm_flags(struct pwr_ctrl *pwrctrl);
+void __spm_send_cpu_wakeup_event(void);
+void __spm_get_wakeup_status(struct wake_status *wakesta, unsigned int ext_status);
+void __spm_clean_after_wakeup(void);
+wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta);
+void __spm_set_pcm_wdt(int en);
+void __spm_ext_int_wakeup_req_clr(void);
+void __spm_hw_s1_state_monitor(int en, unsigned int *status);
+
+static inline void spm_hw_s1_state_monitor_resume(void)
+{
+	__spm_hw_s1_state_monitor(1, NULL);
+}
+
+static inline void spm_hw_s1_state_monitor_pause(unsigned int *status)
+{
+	__spm_hw_s1_state_monitor(0, status);
+}
+
+void __spm_clean_before_wfi(void);
+
+#endif /* MT_SPM_INTERNAL */
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.c
new file mode 100644
index 0000000..97dedf9
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+
+#include <lib/pm/mtk_pm.h>
+#include "mt_spm.h"
+#include "mt_spm_internal.h"
+#include "mt_spm_pmic_wrap.h"
+#include "mt_spm_reg.h"
+#include <platform_def.h>
+
+/* BIT operation */
+#define _BITS_(h, l, v) ((GENMASK(h, l) & ((v) << (l))))
+
+/* PMIC_WRAP */
+#define VCORE_BASE_UV			(40000) /* PMIC MT6359 */
+#define VOLT_TO_PMIC_VAL(volt)		(((volt) - VCORE_BASE_UV + 625 - 1) / 625)
+
+#define NR_PMIC_WRAP_CMD		(NR_IDX_ALL)
+#define SPM_DATA_SHIFT			(16)
+
+#define BUCK_VGPU11_ELR0		(0x15B4)
+#define TOP_SPI_CON0			(0x0456)
+#define BUCK_TOP_CON1			(0x1443) /* PMIC MT6315 */
+#define TOP_CON				(0x0013) /* PMIC MT6315 */
+#define TOP_DIG_WPK			(0x03a9)
+#define TOP_CON_LOCK			(0x03a8)
+#define TOP_CLK_CON0			(0x0134) /* PMIC MT6359*/
+
+struct pmic_wrap_cmd {
+	uint32_t cmd_addr;
+	uint32_t cmd_wdata;
+};
+
+struct pmic_wrap_setting {
+	enum pmic_wrap_phase_id phase;
+	struct pmic_wrap_cmd addr[NR_PMIC_WRAP_CMD];
+	struct {
+		struct {
+			uint32_t cmd_addr;
+			uint32_t cmd_wdata;
+		} _[NR_PMIC_WRAP_CMD];
+		const int nr_idx;
+	} set[NR_PMIC_WRAP_PHASE];
+};
+
+static struct pmic_wrap_setting pw = {
+	.phase = NR_PMIC_WRAP_PHASE,	/* invalid setting for init */
+	.addr = {{0, 0} },
+	.set[PMIC_WRAP_PHASE_ALLINONE] = {
+		._[CMD_0]	= {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(75000)),},
+		._[CMD_1]	= {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(65000)),},
+		._[CMD_2]	= {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(60000)),},
+		._[CMD_3]	= {BUCK_VGPU11_ELR0, _BITS_(6, 0, VOLT_TO_PMIC_VAL(55000)),},
+		._[CMD_4]	= {TOP_SPI_CON0, _BITS_(0, 0, 1),},
+		._[CMD_5]	= {TOP_SPI_CON0, _BITS_(0, 0, 0),},
+		._[CMD_6]	= {BUCK_TOP_CON1, 0x0,},	/* MT6315-3: VMD NO LP */
+		._[CMD_7]	= {BUCK_TOP_CON1, 0xF,},	/* MT6315-3: VMD LP */
+		._[CMD_8]	= {TOP_CON, 0x3,},		/* MT6315-3: PMIC NO LP */
+		._[CMD_9]	= {TOP_CON, 0x0,},		/* MT6315-3: PMIC LP */
+		._[CMD_10]	= {TOP_DIG_WPK, 0x63,},		/* MT6315-2: PMIC_CON_DIG_WPK */
+		._[CMD_11]	= {TOP_CON_LOCK, 0x15,},	/* MT6315-2: PMIC_CON_UNLOCK */
+		._[CMD_12]	= {TOP_DIG_WPK, 0x0,},		/* MT6315-2: PMIC_CON_DIG_WPK */
+		._[CMD_13]	= {TOP_CON_LOCK, 0x0,},		/* MT6315-2: PMIC_CON_LOCK */
+		._[CMD_14]	= {TOP_CLK_CON0, 0x0040,},	/* MT6359: 6359_LDO_SW_SEL_H */
+		._[CMD_15]	= {TOP_CLK_CON0, 0x0000,},	/* MT6359: 6359_LDO_SW_SEL_L */
+		.nr_idx = NR_IDX_ALL,
+	},
+};
+
+void _mt_spm_pmic_table_init(void)
+{
+	struct pmic_wrap_cmd pwrap_cmd_default[NR_PMIC_WRAP_CMD] = {
+		{ (uint32_t)SPM_DVFS_CMD0, (uint32_t)SPM_DVFS_CMD0, },
+		{ (uint32_t)SPM_DVFS_CMD1, (uint32_t)SPM_DVFS_CMD1, },
+		{ (uint32_t)SPM_DVFS_CMD2, (uint32_t)SPM_DVFS_CMD2, },
+		{ (uint32_t)SPM_DVFS_CMD3, (uint32_t)SPM_DVFS_CMD3, },
+		{ (uint32_t)SPM_DVFS_CMD4, (uint32_t)SPM_DVFS_CMD4, },
+		{ (uint32_t)SPM_DVFS_CMD5, (uint32_t)SPM_DVFS_CMD5, },
+		{ (uint32_t)SPM_DVFS_CMD6, (uint32_t)SPM_DVFS_CMD6, },
+		{ (uint32_t)SPM_DVFS_CMD7, (uint32_t)SPM_DVFS_CMD7, },
+		{ (uint32_t)SPM_DVFS_CMD8, (uint32_t)SPM_DVFS_CMD8, },
+		{ (uint32_t)SPM_DVFS_CMD9, (uint32_t)SPM_DVFS_CMD9, },
+		{ (uint32_t)SPM_DVFS_CMD10, (uint32_t)SPM_DVFS_CMD10, },
+		{ (uint32_t)SPM_DVFS_CMD11, (uint32_t)SPM_DVFS_CMD11, },
+		{ (uint32_t)SPM_DVFS_CMD12, (uint32_t)SPM_DVFS_CMD12, },
+		{ (uint32_t)SPM_DVFS_CMD13, (uint32_t)SPM_DVFS_CMD13, },
+		{ (uint32_t)SPM_DVFS_CMD14, (uint32_t)SPM_DVFS_CMD14, },
+		{ (uint32_t)SPM_DVFS_CMD15, (uint32_t)SPM_DVFS_CMD15, },
+	};
+
+	memcpy(pw.addr, pwrap_cmd_default, sizeof(pwrap_cmd_default));
+}
+
+void mt_spm_pmic_wrap_set_phase(enum pmic_wrap_phase_id phase)
+{
+	int idx;
+
+	if ((phase >= NR_PMIC_WRAP_PHASE) || (pw.phase == phase)) {
+		return;
+	}
+
+	if (pw.addr[0].cmd_addr == 0) {
+		_mt_spm_pmic_table_init();
+	}
+
+	pw.phase = phase;
+
+	mmio_write_32(POWERON_CONFIG_EN, SPM_REGWR_CFG_KEY | BCLK_CG_EN_LSB);
+	for (idx = 0; idx < pw.set[phase].nr_idx; idx++) {
+		mmio_write_32(pw.addr[idx].cmd_addr,
+			      (pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT) |
+			      (pw.set[phase]._[idx].cmd_wdata));
+	}
+}
+
+void mt_spm_pmic_wrap_set_cmd(enum pmic_wrap_phase_id phase, unsigned int idx,
+			      unsigned int cmd_wdata)
+{
+	/* just set wdata value */
+	if ((phase >= NR_PMIC_WRAP_PHASE) || (idx >= pw.set[phase].nr_idx)) {
+		return;
+	}
+
+	pw.set[phase]._[idx].cmd_wdata = cmd_wdata;
+
+	mmio_write_32(POWERON_CONFIG_EN, SPM_REGWR_CFG_KEY | BCLK_CG_EN_LSB);
+	if (pw.phase == phase) {
+		mmio_write_32(pw.addr[idx].cmd_addr,
+			      (pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT) | cmd_wdata);
+	}
+}
+
+uint64_t mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase, unsigned int idx)
+{
+	/* just get wdata value */
+	if ((phase >= NR_PMIC_WRAP_PHASE) || (idx >= pw.set[phase].nr_idx)) {
+		return 0;
+	}
+
+	return pw.set[phase]._[idx].cmd_wdata;
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.h
new file mode 100644
index 0000000..3043d36
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_pmic_wrap.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/****************************************************************
+ * Auto generated by DE, please DO NOT modify this file directly.
+ *****************************************************************/
+
+#ifndef MT_SPM_PMIC_WRAP_H
+#define MT_SPM_PMIC_WRAP_H
+
+enum pmic_wrap_phase_id {
+	PMIC_WRAP_PHASE_ALLINONE = 0,
+	NR_PMIC_WRAP_PHASE,
+};
+
+/* IDX mapping */
+enum {
+	CMD_0 = 0,	/* PMIC_WRAP_PHASE_ALLINONE */
+	CMD_1,
+	CMD_2,
+	CMD_3,
+	CMD_4,
+	CMD_5,
+	CMD_6,
+	CMD_7,
+	CMD_8,
+	CMD_9,
+	CMD_10,
+	CMD_11,
+	CMD_12,
+	CMD_13,
+	CMD_14,
+	CMD_15,
+	NR_IDX_ALL,
+};
+
+/* APIs */
+void mt_spm_pmic_wrap_set_phase(enum pmic_wrap_phase_id phase);
+void mt_spm_pmic_wrap_set_cmd(enum pmic_wrap_phase_id phase, unsigned int idx,
+			      unsigned int cmd_wdata);
+uint64_t mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase, unsigned int idx);
+void mt_spm_dump_pmic_warp_reg(void);
+
+#endif /* MT_SPM_PMIC_WRAP_H */
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_reg.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_reg.h
new file mode 100644
index 0000000..2c29f75
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_reg.h
@@ -0,0 +1,2249 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/****************************************************************
+ * Auto generated by DE, please DO NOT modify this file directly.
+ ****************************************************************/
+
+#ifndef MT_SPM_REG_H
+#define MT_SPM_REG_H
+
+#include "pcm_def.h"
+#include "sleep_def.h"
+#include <spm_reg.h>
+
+/* Define and Declare */
+
+/* POWERON_CONFIG_EN (0x10006000+0x000) */
+#define BCLK_CG_EN_LSB                      (1U << 0)       /* 1b */
+#define PROJECT_CODE_LSB                    (1U << 16)      /* 16b */
+/* SPM_POWER_ON_VAL0 (0x10006000+0x004) */
+#define POWER_ON_VAL0_LSB                   (1U << 0)       /* 32b */
+/* SPM_POWER_ON_VAL1 (0x10006000+0x008) */
+#define POWER_ON_VAL1_LSB                   (1U << 0)       /* 32b */
+/* SPM_CLK_CON (0x10006000+0x00C) */
+#define REG_SRCCLKEN0_CTL_LSB               (1U << 0)       /* 2b */
+#define REG_SRCCLKEN1_CTL_LSB               (1U << 2)       /* 2b */
+#define SYS_SETTLE_SEL_LSB                  (1U << 4)       /* 1b */
+#define REG_SPM_LOCK_INFRA_DCM_LSB          (1U << 5)       /* 1b */
+#define REG_SRCCLKEN_MASK_LSB               (1U << 6)       /* 3b */
+#define REG_MD1_C32RM_EN_LSB                (1U << 9)       /* 1b */
+#define REG_MD2_C32RM_EN_LSB                (1U << 10)      /* 1b */
+#define REG_CLKSQ0_SEL_CTRL_LSB             (1U << 11)      /* 1b */
+#define REG_CLKSQ1_SEL_CTRL_LSB             (1U << 12)      /* 1b */
+#define REG_SRCCLKEN0_EN_LSB                (1U << 13)      /* 1b */
+#define REG_SRCCLKEN1_EN_LSB                (1U << 14)      /* 1b */
+#define SCP_DCM_EN_LSB                      (1U << 15)      /* 1b */
+#define REG_SYSCLK0_SRC_MASK_B_LSB          (1U << 16)      /* 8b */
+#define REG_SYSCLK1_SRC_MASK_B_LSB          (1U << 24)      /* 8b */
+/* SPM_CLK_SETTLE (0x10006000+0x010) */
+#define SYSCLK_SETTLE_LSB                   (1U << 0)       /* 28b */
+/* SPM_AP_STANDBY_CON (0x10006000+0x014) */
+#define REG_WFI_OP_LSB                      (1U << 0)       /* 1b */
+#define REG_WFI_TYPE_LSB                    (1U << 1)       /* 1b */
+#define REG_MP0_CPUTOP_IDLE_MASK_LSB        (1U << 2)       /* 1b */
+#define REG_MP1_CPUTOP_IDLE_MASK_LSB        (1U << 3)       /* 1b */
+#define REG_MCUSYS_IDLE_MASK_LSB            (1U << 4)       /* 1b */
+#define REG_MD_APSRC_1_SEL_LSB              (1U << 25)      /* 1b */
+#define REG_MD_APSRC_0_SEL_LSB              (1U << 26)      /* 1b */
+#define REG_CONN_APSRC_SEL_LSB              (1U << 29)      /* 1b */
+/* PCM_CON0 (0x10006000+0x018) */
+#define PCM_CK_EN_LSB                       (1U << 2)       /* 1b */
+#define RG_EN_IM_SLEEP_DVS_LSB              (1U << 3)       /* 1b */
+#define PCM_CK_FROM_CKSYS_LSB               (1U << 4)       /* 1b */
+#define PCM_SW_RESET_LSB                    (1U << 15)      /* 1b */
+#define PCM_CON0_PROJECT_CODE_LSB           (1U << 16)      /* 16b */
+/* PCM_CON1 (0x10006000+0x01C) */
+#define RG_IM_SLAVE_LSB                     (1U << 0)       /* 1b */
+#define RG_IM_SLEEP_LSB                     (1U << 1)       /* 1b */
+#define REG_SPM_SRAM_CTRL_MUX_LSB           (1U << 2)       /* 1b */
+#define RG_AHBMIF_APBEN_LSB                 (1U << 3)       /* 1b */
+#define RG_IM_PDN_LSB                       (1U << 4)       /* 1b */
+#define RG_PCM_TIMER_EN_LSB                 (1U << 5)       /* 1b */
+#define SPM_EVENT_COUNTER_CLR_LSB           (1U << 6)       /* 1b */
+#define RG_DIS_MIF_PROT_LSB                 (1U << 7)       /* 1b */
+#define RG_PCM_WDT_EN_LSB                   (1U << 8)       /* 1b */
+#define RG_PCM_WDT_WAKE_LSB                 (1U << 9)       /* 1b */
+#define REG_SPM_SRAM_SLEEP_B_LSB            (1U << 10)      /* 1b */
+#define REG_SPM_SRAM_ISOINT_B_LSB           (1U << 11)      /* 1b */
+#define REG_EVENT_LOCK_EN_LSB               (1U << 12)      /* 1b */
+#define REG_SRCCLKEN_FAST_RESP_LSB          (1U << 13)      /* 1b */
+#define REG_MD32_APB_INTERNAL_EN_LSB        (1U << 14)      /* 1b */
+#define RG_PCM_IRQ_MSK_LSB                  (1U << 15)      /* 1b */
+#define PCM_CON1_PROJECT_CODE_LSB           (1U << 16)      /* 16b */
+/* SPM_POWER_ON_VAL2 (0x10006000+0x020) */
+#define POWER_ON_VAL2_LSB                   (1U << 0)       /* 32b */
+/* SPM_POWER_ON_VAL3 (0x10006000+0x024) */
+#define POWER_ON_VAL3_LSB                   (1U << 0)       /* 32b */
+/* PCM_REG_DATA_INI (0x10006000+0x028) */
+#define PCM_REG_DATA_INI_LSB                (1U << 0)       /* 32b */
+/* PCM_PWR_IO_EN (0x10006000+0x02C) */
+#define PCM_PWR_IO_EN_LSB                   (1U << 0)       /* 8b */
+#define RG_RF_SYNC_EN_LSB                   (1U << 16)      /* 8b */
+/* PCM_TIMER_VAL (0x10006000+0x030) */
+#define REG_PCM_TIMER_VAL_LSB               (1U << 0)       /* 32b */
+/* PCM_WDT_VAL (0x10006000+0x034) */
+#define RG_PCM_WDT_VAL_LSB                  (1U << 0)       /* 32b */
+/* SPM_SW_RST_CON (0x10006000+0x040) */
+#define SPM_SW_RST_CON_LSB                  (1U << 0)       /* 16b */
+#define SPM_SW_RST_CON_PROJECT_CODE_LSB     (1U << 16)      /* 16b */
+/* SPM_SW_RST_CON_SET (0x10006000+0x044) */
+#define SPM_SW_RST_CON_SET_LSB              (1U << 0)       /* 16b */
+#define SPM_SW_RST_CON_SET_PROJECT_CODE_LSB (1U << 16)      /* 16b */
+/* SPM_SW_RST_CON_CLR (0x10006000+0x048) */
+#define SPM_SW_RST_CON_CLR_LSB              (1U << 0)       /* 16b */
+#define SPM_SW_RST_CON_CLR_PROJECT_CODE_LSB (1U << 16)      /* 16b */
+/* VS1_PSR_MASK_B (0x10006000+0x04C) */
+#define VS1_OPP0_PSR_MASK_B_LSB             (1U << 0)       /* 8b */
+#define VS1_OPP1_PSR_MASK_B_LSB             (1U << 8)       /* 8b */
+/* VS2_PSR_MASK_B (0x10006000+0x050) */
+#define VS2_OPP0_PSR_MASK_B_LSB             (1U << 0)       /* 8b */
+#define VS2_OPP1_PSR_MASK_B_LSB             (1U << 8)       /* 8b */
+#define VS2_OPP2_PSR_MASK_B_LSB             (1U << 16)      /* 8b */
+/* MD32_CLK_CON (0x10006000+0x084) */
+#define REG_MD32_26M_CK_SEL_LSB             (1U << 0)       /* 1b */
+#define REG_MD32_DCM_EN_LSB                 (1U << 1)       /* 1b */
+/* SPM_SRAM_RSV_CON (0x10006000+0x088) */
+#define SPM_SRAM_SLEEP_B_ECO_EN_LSB         (1U << 0)       /* 1b */
+/* SPM_SWINT (0x10006000+0x08C) */
+#define SPM_SWINT_LSB                       (1U << 0)       /* 32b */
+/* SPM_SWINT_SET (0x10006000+0x090) */
+#define SPM_SWINT_SET_LSB                   (1U << 0)       /* 32b */
+/* SPM_SWINT_CLR (0x10006000+0x094) */
+#define SPM_SWINT_CLR_LSB                   (1U << 0)       /* 32b */
+/* SPM_SCP_MAILBOX (0x10006000+0x098) */
+#define SPM_SCP_MAILBOX_LSB                 (1U << 0)       /* 32b */
+/* SCP_SPM_MAILBOX (0x10006000+0x09C) */
+#define SCP_SPM_MAILBOX_LSB                 (1U << 0)       /* 32b */
+/* SPM_TWAM_CON (0x10006000+0x0A0) */
+#define REG_TWAM_ENABLE_LSB                 (1U << 0)       /* 1b */
+#define REG_TWAM_SPEED_MODE_EN_LSB          (1U << 1)       /* 1b */
+#define REG_TWAM_SW_RST_LSB                 (1U << 2)       /* 1b */
+#define REG_TWAM_IRQ_MASK_LSB               (1U << 3)       /* 1b */
+#define REG_TWAM_MON_TYPE_0_LSB             (1U << 4)       /* 2b */
+#define REG_TWAM_MON_TYPE_1_LSB             (1U << 6)       /* 2b */
+#define REG_TWAM_MON_TYPE_2_LSB             (1U << 8)       /* 2b */
+#define REG_TWAM_MON_TYPE_3_LSB             (1U << 10)      /* 2b */
+/* SPM_TWAM_WINDOW_LEN (0x10006000+0x0A4) */
+#define REG_TWAM_WINDOW_LEN_LSB             (1U << 0)       /* 32b */
+/* SPM_TWAM_IDLE_SEL (0x10006000+0x0A8) */
+#define REG_TWAM_SIG_SEL_0_LSB              (1U << 0)       /* 7b */
+#define REG_TWAM_SIG_SEL_1_LSB              (1U << 8)       /* 7b */
+#define REG_TWAM_SIG_SEL_2_LSB              (1U << 16)      /* 7b */
+#define REG_TWAM_SIG_SEL_3_LSB              (1U << 24)      /* 7b */
+/* SPM_SCP_IRQ (0x10006000+0x0AC) */
+#define SC_SPM2SCP_WAKEUP_LSB               (1U << 0)       /* 1b */
+#define SC_SCP2SPM_WAKEUP_LSB               (1U << 4)       /* 1b */
+/* SPM_CPU_WAKEUP_EVENT (0x10006000+0x0B0) */
+#define REG_CPU_WAKEUP_LSB                  (1U << 0)       /* 1b */
+/* SPM_IRQ_MASK (0x10006000+0x0B4) */
+#define REG_SPM_IRQ_MASK_LSB                (1U << 0)       /* 32b */
+/* DDR_EN_DBC (0x10006000+0x0B4) */
+#define REG_ALL_DDR_EN_DBC_EN_LSB           (1U << 16)       /* 1b */
+/* SPM_SRC_REQ (0x10006000+0x0B8) */
+#define REG_SPM_APSRC_REQ_LSB               (1U << 0)       /* 1b */
+#define REG_SPM_F26M_REQ_LSB                (1U << 1)       /* 1b */
+#define REG_SPM_INFRA_REQ_LSB               (1U << 3)       /* 1b */
+#define REG_SPM_VRF18_REQ_LSB               (1U << 4)       /* 1b */
+#define REG_SPM_DDR_EN_REQ_LSB              (1U << 7)       /* 1b */
+#define REG_SPM_DVFS_REQ_LSB                (1U << 8)       /* 1b */
+#define REG_SPM_SW_MAILBOX_REQ_LSB          (1U << 9)       /* 1b */
+#define REG_SPM_SSPM_MAILBOX_REQ_LSB        (1U << 10)      /* 1b */
+#define REG_SPM_ADSP_MAILBOX_REQ_LSB        (1U << 11)      /* 1b */
+#define REG_SPM_SCP_MAILBOX_REQ_LSB         (1U << 12)      /* 1b */
+/* SPM_SRC_MASK (0x10006000+0x0BC) */
+#define REG_MD_SRCCLKENA_0_MASK_B_LSB       (1U << 0)       /* 1b */
+#define REG_MD_SRCCLKENA2INFRA_REQ_0_MASK_B_LSB (1U << 1)       /* 1b */
+#define REG_MD_APSRC2INFRA_REQ_0_MASK_B_LSB (1U << 2)       /* 1b */
+#define REG_MD_APSRC_REQ_0_MASK_B_LSB       (1U << 3)       /* 1b */
+#define REG_MD_VRF18_REQ_0_MASK_B_LSB       (1U << 4)       /* 1b */
+#define REG_MD_DDR_EN_0_MASK_B_LSB          (1U << 5)       /* 1b */
+#define REG_MD_SRCCLKENA_1_MASK_B_LSB       (1U << 6)       /* 1b */
+#define REG_MD_SRCCLKENA2INFRA_REQ_1_MASK_B_LSB (1U << 7)       /* 1b */
+#define REG_MD_APSRC2INFRA_REQ_1_MASK_B_LSB (1U << 8)       /* 1b */
+#define REG_MD_APSRC_REQ_1_MASK_B_LSB       (1U << 9)       /* 1b */
+#define REG_MD_VRF18_REQ_1_MASK_B_LSB       (1U << 10)      /* 1b */
+#define REG_MD_DDR_EN_1_MASK_B_LSB          (1U << 11)      /* 1b */
+#define REG_CONN_SRCCLKENA_MASK_B_LSB       (1U << 12)      /* 1b */
+#define REG_CONN_SRCCLKENB_MASK_B_LSB       (1U << 13)      /* 1b */
+#define REG_CONN_INFRA_REQ_MASK_B_LSB       (1U << 14)      /* 1b */
+#define REG_CONN_APSRC_REQ_MASK_B_LSB       (1U << 15)      /* 1b */
+#define REG_CONN_VRF18_REQ_MASK_B_LSB       (1U << 16)      /* 1b */
+#define REG_CONN_DDR_EN_MASK_B_LSB          (1U << 17)      /* 1b */
+#define REG_CONN_VFE28_MASK_B_LSB           (1U << 18)      /* 1b */
+#define REG_SRCCLKENI0_SRCCLKENA_MASK_B_LSB (1U << 19)      /* 1b */
+#define REG_SRCCLKENI0_INFRA_REQ_MASK_B_LSB (1U << 20)      /* 1b */
+#define REG_SRCCLKENI1_SRCCLKENA_MASK_B_LSB (1U << 21)      /* 1b */
+#define REG_SRCCLKENI1_INFRA_REQ_MASK_B_LSB (1U << 22)      /* 1b */
+#define REG_SRCCLKENI2_SRCCLKENA_MASK_B_LSB (1U << 23)      /* 1b */
+#define REG_SRCCLKENI2_INFRA_REQ_MASK_B_LSB (1U << 24)      /* 1b */
+#define REG_INFRASYS_APSRC_REQ_MASK_B_LSB   (1U << 25)      /* 1b */
+#define REG_INFRASYS_DDR_EN_MASK_B_LSB      (1U << 26)      /* 1b */
+#define REG_MD32_SRCCLKENA_MASK_B_LSB       (1U << 27)      /* 1b */
+#define REG_MD32_INFRA_REQ_MASK_B_LSB       (1U << 28)      /* 1b */
+#define REG_MD32_APSRC_REQ_MASK_B_LSB       (1U << 29)      /* 1b */
+#define REG_MD32_VRF18_REQ_MASK_B_LSB       (1U << 30)      /* 1b */
+#define REG_MD32_DDR_EN_MASK_B_LSB          (1U << 31)      /* 1b */
+/* SPM_SRC2_MASK (0x10006000+0x0C0) */
+#define REG_SCP_SRCCLKENA_MASK_B_LSB        (1U << 0)       /* 1b */
+#define REG_SCP_INFRA_REQ_MASK_B_LSB        (1U << 1)       /* 1b */
+#define REG_SCP_APSRC_REQ_MASK_B_LSB        (1U << 2)       /* 1b */
+#define REG_SCP_VRF18_REQ_MASK_B_LSB        (1U << 3)       /* 1b */
+#define REG_SCP_DDR_EN_MASK_B_LSB           (1U << 4)       /* 1b */
+#define REG_AUDIO_DSP_SRCCLKENA_MASK_B_LSB  (1U << 5)       /* 1b */
+#define REG_AUDIO_DSP_INFRA_REQ_MASK_B_LSB  (1U << 6)       /* 1b */
+#define REG_AUDIO_DSP_APSRC_REQ_MASK_B_LSB  (1U << 7)       /* 1b */
+#define REG_AUDIO_DSP_VRF18_REQ_MASK_B_LSB  (1U << 8)       /* 1b */
+#define REG_AUDIO_DSP_DDR_EN_MASK_B_LSB     (1U << 9)       /* 1b */
+#define REG_UFS_SRCCLKENA_MASK_B_LSB        (1U << 10)      /* 1b */
+#define REG_UFS_INFRA_REQ_MASK_B_LSB        (1U << 11)      /* 1b */
+#define REG_UFS_APSRC_REQ_MASK_B_LSB        (1U << 12)      /* 1b */
+#define REG_UFS_VRF18_REQ_MASK_B_LSB        (1U << 13)      /* 1b */
+#define REG_UFS_DDR_EN_MASK_B_LSB           (1U << 14)      /* 1b */
+#define REG_DISP0_APSRC_REQ_MASK_B_LSB      (1U << 15)      /* 1b */
+#define REG_DISP0_DDR_EN_MASK_B_LSB         (1U << 16)      /* 1b */
+#define REG_DISP1_APSRC_REQ_MASK_B_LSB      (1U << 17)      /* 1b */
+#define REG_DISP1_DDR_EN_MASK_B_LSB         (1U << 18)      /* 1b */
+#define REG_GCE_INFRA_REQ_MASK_B_LSB        (1U << 19)      /* 1b */
+#define REG_GCE_APSRC_REQ_MASK_B_LSB        (1U << 20)      /* 1b */
+#define REG_GCE_VRF18_REQ_MASK_B_LSB        (1U << 21)      /* 1b */
+#define REG_GCE_DDR_EN_MASK_B_LSB           (1U << 22)      /* 1b */
+#define REG_APU_SRCCLKENA_MASK_B_LSB        (1U << 23)      /* 1b */
+#define REG_APU_INFRA_REQ_MASK_B_LSB        (1U << 24)      /* 1b */
+#define REG_APU_APSRC_REQ_MASK_B_LSB        (1U << 25)      /* 1b */
+#define REG_APU_VRF18_REQ_MASK_B_LSB        (1U << 26)      /* 1b */
+#define REG_APU_DDR_EN_MASK_B_LSB           (1U << 27)      /* 1b */
+#define REG_CG_CHECK_SRCCLKENA_MASK_B_LSB   (1U << 28)      /* 1b */
+#define REG_CG_CHECK_APSRC_REQ_MASK_B_LSB   (1U << 29)      /* 1b */
+#define REG_CG_CHECK_VRF18_REQ_MASK_B_LSB   (1U << 30)      /* 1b */
+#define REG_CG_CHECK_DDR_EN_MASK_B_LSB      (1U << 31)      /* 1b */
+/* SPM_SRC3_MASK (0x10006000+0x0C4) */
+#define REG_DVFSRC_EVENT_TRIGGER_MASK_B_LSB (1U << 0)       /* 1b */
+#define REG_SW2SPM_INT0_MASK_B_LSB          (1U << 1)       /* 1b */
+#define REG_SW2SPM_INT1_MASK_B_LSB          (1U << 2)       /* 1b */
+#define REG_SW2SPM_INT2_MASK_B_LSB          (1U << 3)       /* 1b */
+#define REG_SW2SPM_INT3_MASK_B_LSB          (1U << 4)       /* 1b */
+#define REG_SC_ADSP2SPM_WAKEUP_MASK_B_LSB   (1U << 5)       /* 1b */
+#define REG_SC_SSPM2SPM_WAKEUP_MASK_B_LSB   (1U << 6)       /* 4b */
+#define REG_SC_SCP2SPM_WAKEUP_MASK_B_LSB    (1U << 10)      /* 1b */
+#define REG_CSYSPWRREQ_MASK_LSB             (1U << 11)      /* 1b */
+#define REG_SPM_SRCCLKENA_RESERVED_MASK_B_LSB (1U << 12)      /* 1b */
+#define REG_SPM_INFRA_REQ_RESERVED_MASK_B_LSB (1U << 13)      /* 1b */
+#define REG_SPM_APSRC_REQ_RESERVED_MASK_B_LSB (1U << 14)      /* 1b */
+#define REG_SPM_VRF18_REQ_RESERVED_MASK_B_LSB (1U << 15)      /* 1b */
+#define REG_SPM_DDR_EN_RESERVED_MASK_B_LSB  (1U << 16)      /* 1b */
+#define REG_MCUPM_SRCCLKENA_MASK_B_LSB      (1U << 17)      /* 1b */
+#define REG_MCUPM_INFRA_REQ_MASK_B_LSB      (1U << 18)      /* 1b */
+#define REG_MCUPM_APSRC_REQ_MASK_B_LSB      (1U << 19)      /* 1b */
+#define REG_MCUPM_VRF18_REQ_MASK_B_LSB      (1U << 20)      /* 1b */
+#define REG_MCUPM_DDR_EN_MASK_B_LSB         (1U << 21)      /* 1b */
+#define REG_MSDC0_SRCCLKENA_MASK_B_LSB      (1U << 22)      /* 1b */
+#define REG_MSDC0_INFRA_REQ_MASK_B_LSB      (1U << 23)      /* 1b */
+#define REG_MSDC0_APSRC_REQ_MASK_B_LSB      (1U << 24)      /* 1b */
+#define REG_MSDC0_VRF18_REQ_MASK_B_LSB      (1U << 25)      /* 1b */
+#define REG_MSDC0_DDR_EN_MASK_B_LSB         (1U << 26)      /* 1b */
+#define REG_MSDC1_SRCCLKENA_MASK_B_LSB      (1U << 27)      /* 1b */
+#define REG_MSDC1_INFRA_REQ_MASK_B_LSB      (1U << 28)      /* 1b */
+#define REG_MSDC1_APSRC_REQ_MASK_B_LSB      (1U << 29)      /* 1b */
+#define REG_MSDC1_VRF18_REQ_MASK_B_LSB      (1U << 30)      /* 1b */
+#define REG_MSDC1_DDR_EN_MASK_B_LSB         (1U << 31)      /* 1b */
+/* SPM_SRC4_MASK (0x10006000+0x0C8) */
+#define CCIF_EVENT_MASK_B_LSB               (1U << 0)       /* 16b */
+#define REG_BAK_PSRI_SRCCLKENA_MASK_B_LSB   (1U << 16)      /* 1b */
+#define REG_BAK_PSRI_INFRA_REQ_MASK_B_LSB   (1U << 17)      /* 1b */
+#define REG_BAK_PSRI_APSRC_REQ_MASK_B_LSB   (1U << 18)      /* 1b */
+#define REG_BAK_PSRI_VRF18_REQ_MASK_B_LSB   (1U << 19)      /* 1b */
+#define REG_BAK_PSRI_DDR_EN_MASK_B_LSB      (1U << 20)      /* 1b */
+#define REG_DRAMC0_MD32_INFRA_REQ_MASK_B_LSB (1U << 21)      /* 1b */
+#define REG_DRAMC0_MD32_VRF18_REQ_MASK_B_LSB (1U << 22)      /* 1b */
+#define REG_DRAMC1_MD32_INFRA_REQ_MASK_B_LSB (1U << 23)      /* 1b */
+#define REG_DRAMC1_MD32_VRF18_REQ_MASK_B_LSB (1U << 24)      /* 1b */
+#define REG_CONN_SRCCLKENB2PWRAP_MASK_B_LSB (1U << 25)      /* 1b */
+#define REG_DRAMC0_MD32_WAKEUP_MASK_LSB     (1U << 26)      /* 1b */
+#define REG_DRAMC1_MD32_WAKEUP_MASK_LSB     (1U << 27)      /* 1b */
+/* SPM_SRC5_MASK (0x10006000+0x0CC) */
+#define REG_MCUSYS_MERGE_APSRC_REQ_MASK_B_LSB (1U << 0)       /* 9b */
+#define REG_MCUSYS_MERGE_DDR_EN_MASK_B_LSB  (1U << 9)       /* 9b */
+/* SPM_WAKEUP_EVENT_MASK (0x10006000+0x0D0) */
+#define REG_WAKEUP_EVENT_MASK_LSB           (1U << 0)       /* 32b */
+/* SPM_WAKEUP_EVENT_EXT_MASK (0x10006000+0x0D4) */
+#define REG_EXT_WAKEUP_EVENT_MASK_LSB       (1U << 0)       /* 32b */
+/* SPM_TWAM_EVENT_CLEAR (0x10006000+0x0D8) */
+#define SPM_TWAM_EVENT_CLEAR_LSB            (1U << 0)       /* 1b */
+/* SCP_CLK_CON (0x10006000+0x0DC) */
+#define REG_SCP_26M_CK_SEL_LSB              (1U << 0)       /* 1b */
+#define REG_SCP_DCM_EN_LSB                  (1U << 1)       /* 1b */
+#define SCP_SECURE_V_REQ_MASK_LSB           (1U << 2)       /* 1b */
+#define SCP_SLP_REQ_LSB                     (1U << 3)       /* 1b */
+#define SCP_SLP_ACK_LSB                     (1U << 4)       /* 1b */
+/* SPM_RESOURCE_ACK_CON0 (0x10006000+0x0F0) */
+#define REG_MD_SRCCLKENA_ACK_0_MASK_LSB     (1U << 0)       /* 1b */
+#define REG_MD_INFRA_ACK_0_MASK_LSB         (1U << 1)       /* 1b */
+#define REG_MD_APSRC_ACK_0_MASK_LSB         (1U << 2)       /* 1b */
+#define REG_MD_VRF18_ACK_0_MASK_LSB         (1U << 3)       /* 1b */
+#define REG_MD_DDR_EN_ACK_0_MASK_LSB        (1U << 4)       /* 1b */
+#define REG_MD_SRCCLKENA_ACK_1_MASK_LSB     (1U << 5)       /* 1b */
+#define REG_MD_INFRA_ACK_1_MASK_LSB         (1U << 6)       /* 1b */
+#define REG_MD_APSRC_ACK_1_MASK_LSB         (1U << 7)       /* 1b */
+#define REG_MD_VRF18_ACK_1_MASK_LSB         (1U << 8)       /* 1b */
+#define REG_MD_DDR_EN_ACK_1_MASK_LSB        (1U << 9)       /* 1b */
+#define REG_CONN_SRCCLKENA_ACK_MASK_LSB     (1U << 10)      /* 1b */
+#define REG_CONN_INFRA_ACK_MASK_LSB         (1U << 11)      /* 1b */
+#define REG_CONN_APSRC_ACK_MASK_LSB         (1U << 12)      /* 1b */
+#define REG_CONN_VRF18_ACK_MASK_LSB         (1U << 13)      /* 1b */
+#define REG_CONN_DDR_EN_ACK_MASK_LSB        (1U << 14)      /* 1b */
+#define REG_MD32_SRCCLKENA_ACK_MASK_LSB     (1U << 15)      /* 1b */
+#define REG_MD32_INFRA_ACK_MASK_LSB         (1U << 16)      /* 1b */
+#define REG_MD32_APSRC_ACK_MASK_LSB         (1U << 17)      /* 1b */
+#define REG_MD32_VRF18_ACK_MASK_LSB         (1U << 18)      /* 1b */
+#define REG_MD32_DDR_EN_ACK_MASK_LSB        (1U << 19)      /* 1b */
+#define REG_SCP_SRCCLKENA_ACK_MASK_LSB      (1U << 20)      /* 1b */
+#define REG_SCP_INFRA_ACK_MASK_LSB          (1U << 21)      /* 1b */
+#define REG_SCP_APSRC_ACK_MASK_LSB          (1U << 22)      /* 1b */
+#define REG_SCP_VRF18_ACK_MASK_LSB          (1U << 23)      /* 1b */
+#define REG_SCP_DDR_EN_ACK_MASK_LSB         (1U << 24)      /* 1b */
+#define REG_AUDIO_DSP_SRCCLKENA_ACK_MASK_LSB (1U << 25)      /* 1b */
+#define REG_AUDIO_DSP_INFRA_ACK_MASK_LSB    (1U << 26)      /* 1b */
+#define REG_AUDIO_DSP_APSRC_ACK_MASK_LSB    (1U << 27)      /* 1b */
+#define REG_AUDIO_DSP_VRF18_ACK_MASK_LSB    (1U << 28)      /* 1b */
+#define REG_AUDIO_DSP_DDR_EN_ACK_MASK_LSB   (1U << 29)      /* 1b */
+#define REG_DISP0_DDR_EN_ACK_MASK_LSB       (1U << 30)      /* 1b */
+#define REG_DISP1_APSRC_ACK_MASK_LSB        (1U << 31)      /* 1b */
+/* SPM_RESOURCE_ACK_CON1 (0x10006000+0x0F4) */
+#define REG_UFS_SRCCLKENA_ACK_MASK_LSB      (1U << 0)       /* 1b */
+#define REG_UFS_INFRA_ACK_MASK_LSB          (1U << 1)       /* 1b */
+#define REG_UFS_APSRC_ACK_MASK_LSB          (1U << 2)       /* 1b */
+#define REG_UFS_VRF18_ACK_MASK_LSB          (1U << 3)       /* 1b */
+#define REG_UFS_DDR_EN_ACK_MASK_LSB         (1U << 4)       /* 1b */
+#define REG_APU_SRCCLKENA_ACK_MASK_LSB      (1U << 5)       /* 1b */
+#define REG_APU_INFRA_ACK_MASK_LSB          (1U << 6)       /* 1b */
+#define REG_APU_APSRC_ACK_MASK_LSB          (1U << 7)       /* 1b */
+#define REG_APU_VRF18_ACK_MASK_LSB          (1U << 8)       /* 1b */
+#define REG_APU_DDR_EN_ACK_MASK_LSB         (1U << 9)       /* 1b */
+#define REG_MCUPM_SRCCLKENA_ACK_MASK_LSB    (1U << 10)      /* 1b */
+#define REG_MCUPM_INFRA_ACK_MASK_LSB        (1U << 11)      /* 1b */
+#define REG_MCUPM_APSRC_ACK_MASK_LSB        (1U << 12)      /* 1b */
+#define REG_MCUPM_VRF18_ACK_MASK_LSB        (1U << 13)      /* 1b */
+#define REG_MCUPM_DDR_EN_ACK_MASK_LSB       (1U << 14)      /* 1b */
+#define REG_MSDC0_SRCCLKENA_ACK_MASK_LSB    (1U << 15)      /* 1b */
+#define REG_MSDC0_INFRA_ACK_MASK_LSB        (1U << 16)      /* 1b */
+#define REG_MSDC0_APSRC_ACK_MASK_LSB        (1U << 17)      /* 1b */
+#define REG_MSDC0_VRF18_ACK_MASK_LSB        (1U << 18)      /* 1b */
+#define REG_MSDC0_DDR_EN_ACK_MASK_LSB       (1U << 19)      /* 1b */
+#define REG_MSDC1_SRCCLKENA_ACK_MASK_LSB    (1U << 20)      /* 1b */
+#define REG_MSDC1_INFRA_ACK_MASK_LSB        (1U << 21)      /* 1b */
+#define REG_MSDC1_APSRC_ACK_MASK_LSB        (1U << 22)      /* 1b */
+#define REG_MSDC1_VRF18_ACK_MASK_LSB        (1U << 23)      /* 1b */
+#define REG_MSDC1_DDR_EN_ACK_MASK_LSB       (1U << 24)      /* 1b */
+#define REG_DISP0_APSRC_ACK_MASK_LSB        (1U << 25)      /* 1b */
+#define REG_DISP1_DDR_EN_ACK_MASK_LSB       (1U << 26)      /* 1b */
+#define REG_GCE_INFRA_ACK_MASK_LSB          (1U << 27)      /* 1b */
+#define REG_GCE_APSRC_ACK_MASK_LSB          (1U << 28)      /* 1b */
+#define REG_GCE_VRF18_ACK_MASK_LSB          (1U << 29)      /* 1b */
+#define REG_GCE_DDR_EN_ACK_MASK_LSB         (1U << 30)      /* 1b */
+/* SPM_RESOURCE_ACK_CON2 (0x10006000+0x0F8) */
+#define SPM_F26M_ACK_WAIT_CYCLE_LSB         (1U << 0)       /* 8b */
+#define SPM_INFRA_ACK_WAIT_CYCLE_LSB        (1U << 8)       /* 8b */
+#define SPM_APSRC_ACK_WAIT_CYCLE_LSB        (1U << 16)      /* 8b */
+#define SPM_VRF18_ACK_WAIT_CYCLE_LSB        (1U << 24)      /* 8b */
+/* SPM_RESOURCE_ACK_CON3 (0x10006000+0x0FC) */
+#define SPM_DDR_EN_ACK_WAIT_CYCLE_LSB       (1U << 0)       /* 8b */
+#define REG_BAK_PSRI_SRCCLKENA_ACK_MASK_LSB (1U << 8)       /* 1b */
+#define REG_BAK_PSRI_INFRA_ACK_MASK_LSB     (1U << 9)       /* 1b */
+#define REG_BAK_PSRI_APSRC_ACK_MASK_LSB     (1U << 10)      /* 1b */
+#define REG_BAK_PSRI_VRF18_ACK_MASK_LSB     (1U << 11)      /* 1b */
+#define REG_BAK_PSRI_DDR_EN_ACK_MASK_LSB    (1U << 12)      /* 1b */
+/* PCM_REG0_DATA (0x10006000+0x100) */
+#define PCM_REG0_RF_LSB                     (1U << 0)       /* 32b */
+/* PCM_REG2_DATA (0x10006000+0x104) */
+#define PCM_REG2_RF_LSB                     (1U << 0)       /* 32b */
+/* PCM_REG6_DATA (0x10006000+0x108) */
+#define PCM_REG6_RF_LSB                     (1U << 0)       /* 32b */
+/* PCM_REG7_DATA (0x10006000+0x10C) */
+#define PCM_REG7_RF_LSB                     (1U << 0)       /* 32b */
+/* PCM_REG13_DATA (0x10006000+0x110) */
+#define PCM_REG13_RF_LSB                    (1U << 0)       /* 32b */
+/* SRC_REQ_STA_0 (0x10006000+0x114) */
+#define MD_SRCCLKENA_0_LSB                  (1U << 0)       /* 1b */
+#define MD_SRCCLKENA2INFRA_REQ_0_LSB        (1U << 1)       /* 1b */
+#define MD_APSRC2INFRA_REQ_0_LSB            (1U << 2)       /* 1b */
+#define MD_APSRC_REQ_0_LSB                  (1U << 3)       /* 1b */
+#define MD_VRF18_REQ_0_LSB                  (1U << 4)       /* 1b */
+#define MD_DDR_EN_0_LSB                     (1U << 5)       /* 1b */
+#define MD_SRCCLKENA_1_LSB                  (1U << 6)       /* 1b */
+#define MD_SRCCLKENA2INFRA_REQ_1_LSB        (1U << 7)       /* 1b */
+#define MD_APSRC2INFRA_REQ_1_LSB            (1U << 8)       /* 1b */
+#define MD_APSRC_REQ_1_LSB                  (1U << 9)       /* 1b */
+#define MD_VRF18_REQ_1_LSB                  (1U << 10)      /* 1b */
+#define MD_DDR_EN_1_LSB                     (1U << 11)      /* 1b */
+#define CONN_SRCCLKENA_LSB                  (1U << 12)      /* 1b */
+#define CONN_SRCCLKENB_LSB                  (1U << 13)      /* 1b */
+#define CONN_INFRA_REQ_LSB                  (1U << 14)      /* 1b */
+#define CONN_APSRC_REQ_LSB                  (1U << 15)      /* 1b */
+#define CONN_VRF18_REQ_LSB                  (1U << 16)      /* 1b */
+#define CONN_DDR_EN_LSB                     (1U << 17)      /* 1b */
+#define SRCCLKENI_LSB                       (1U << 18)      /* 3b */
+#define MD32_SRCCLKENA_LSB                  (1U << 21)      /* 1b */
+#define MD32_INFRA_REQ_LSB                  (1U << 22)      /* 1b */
+#define MD32_APSRC_REQ_LSB                  (1U << 23)      /* 1b */
+#define MD32_VRF18_REQ_LSB                  (1U << 24)      /* 1b */
+#define MD32_DDR_EN_LSB                     (1U << 25)      /* 1b */
+#define DISP0_APSRC_REQ_LSB                 (1U << 26)      /* 1b */
+#define DISP0_DDR_EN_LSB                    (1U << 27)      /* 1b */
+#define DISP1_APSRC_REQ_LSB                 (1U << 28)      /* 1b */
+#define DISP1_DDR_EN_LSB                    (1U << 29)      /* 1b */
+#define DVFSRC_EVENT_TRIGGER_LSB            (1U << 30)      /* 1b */
+/* SRC_REQ_STA_1 (0x10006000+0x118) */
+#define SCP_SRCCLKENA_LSB                   (1U << 0)       /* 1b */
+#define SCP_INFRA_REQ_LSB                   (1U << 1)       /* 1b */
+#define SCP_APSRC_REQ_LSB                   (1U << 2)       /* 1b */
+#define SCP_VRF18_REQ_LSB                   (1U << 3)       /* 1b */
+#define SCP_DDR_EN_LSB                      (1U << 4)       /* 1b */
+#define AUDIO_DSP_SRCCLKENA_LSB             (1U << 5)       /* 1b */
+#define AUDIO_DSP_INFRA_REQ_LSB             (1U << 6)       /* 1b */
+#define AUDIO_DSP_APSRC_REQ_LSB             (1U << 7)       /* 1b */
+#define AUDIO_DSP_VRF18_REQ_LSB             (1U << 8)       /* 1b */
+#define AUDIO_DSP_DDR_EN_LSB                (1U << 9)       /* 1b */
+#define UFS_SRCCLKENA_LSB                   (1U << 10)      /* 1b */
+#define UFS_INFRA_REQ_LSB                   (1U << 11)      /* 1b */
+#define UFS_APSRC_REQ_LSB                   (1U << 12)      /* 1b */
+#define UFS_VRF18_REQ_LSB                   (1U << 13)      /* 1b */
+#define UFS_DDR_EN_LSB                      (1U << 14)      /* 1b */
+#define GCE_INFRA_REQ_LSB                   (1U << 15)      /* 1b */
+#define GCE_APSRC_REQ_LSB                   (1U << 16)      /* 1b */
+#define GCE_VRF18_REQ_LSB                   (1U << 17)      /* 1b */
+#define GCE_DDR_EN_LSB                      (1U << 18)      /* 1b */
+#define INFRASYS_APSRC_REQ_LSB              (1U << 19)      /* 1b */
+#define INFRASYS_DDR_EN_LSB                 (1U << 20)      /* 1b */
+#define MSDC0_SRCCLKENA_LSB                 (1U << 21)      /* 1b */
+#define MSDC0_INFRA_REQ_LSB                 (1U << 22)      /* 1b */
+#define MSDC0_APSRC_REQ_LSB                 (1U << 23)      /* 1b */
+#define MSDC0_VRF18_REQ_LSB                 (1U << 24)      /* 1b */
+#define MSDC0_DDR_EN_LSB                    (1U << 25)      /* 1b */
+#define MSDC1_SRCCLKENA_LSB                 (1U << 26)      /* 1b */
+#define MSDC1_INFRA_REQ_LSB                 (1U << 27)      /* 1b */
+#define MSDC1_APSRC_REQ_LSB                 (1U << 28)      /* 1b */
+#define MSDC1_VRF18_REQ_LSB                 (1U << 29)      /* 1b */
+#define MSDC1_DDR_EN_LSB                    (1U << 30)      /* 1b */
+/* SRC_REQ_STA_2 (0x10006000+0x11C) */
+#define MCUSYS_MERGE_DDR_EN_LSB             (1U << 0)       /* 9b */
+#define EMI_SELF_REFRESH_CH_LSB             (1U << 9)       /* 2b */
+#define SW2SPM_INT_LSB                      (1U << 11)      /* 4b */
+#define SC_ADSP2SPM_WAKEUP_LSB              (1U << 15)      /* 1b */
+#define SC_SSPM2SPM_WAKEUP_LSB              (1U << 16)      /* 4b */
+#define SRC_REQ_STA_2_SC_SCP2SPM_WAKEUP_LSB (1U << 20)      /* 1b */
+#define SPM_SRCCLKENA_RESERVED_LSB          (1U << 21)      /* 1b */
+#define SPM_INFRA_REQ_RESERVED_LSB          (1U << 22)      /* 1b */
+#define SPM_APSRC_REQ_RESERVED_LSB          (1U << 23)      /* 1b */
+#define SPM_VRF18_REQ_RESERVED_LSB          (1U << 24)      /* 1b */
+#define SPM_DDR_EN_RESERVED_LSB             (1U << 25)      /* 1b */
+#define MCUPM_SRCCLKENA_LSB                 (1U << 26)      /* 1b */
+#define MCUPM_INFRA_REQ_LSB                 (1U << 27)      /* 1b */
+#define MCUPM_APSRC_REQ_LSB                 (1U << 28)      /* 1b */
+#define MCUPM_VRF18_REQ_LSB                 (1U << 29)      /* 1b */
+#define MCUPM_DDR_EN_LSB                    (1U << 30)      /* 1b */
+/* PCM_TIMER_OUT (0x10006000+0x120) */
+#define PCM_TIMER_LSB                       (1U << 0)       /* 32b */
+/* PCM_WDT_OUT (0x10006000+0x124) */
+#define PCM_WDT_TIMER_VAL_OUT_LSB           (1U << 0)       /* 32b */
+/* SPM_IRQ_STA (0x10006000+0x128) */
+#define TWAM_IRQ_LSB                        (1U << 2)       /* 1b */
+#define PCM_IRQ_LSB                         (1U << 3)       /* 1b */
+/* SRC_REQ_STA_4 (0x10006000+0x12C) */
+#define APU_SRCCLKENA_LSB                   (1U << 0)       /* 1b */
+#define APU_INFRA_REQ_LSB                   (1U << 1)       /* 1b */
+#define APU_APSRC_REQ_LSB                   (1U << 2)       /* 1b */
+#define APU_VRF18_REQ_LSB                   (1U << 3)       /* 1b */
+#define APU_DDR_EN_LSB                      (1U << 4)       /* 1b */
+#define BAK_PSRI_SRCCLKENA_LSB              (1U << 5)       /* 1b */
+#define BAK_PSRI_INFRA_REQ_LSB              (1U << 6)       /* 1b */
+#define BAK_PSRI_APSRC_REQ_LSB              (1U << 7)       /* 1b */
+#define BAK_PSRI_VRF18_REQ_LSB              (1U << 8)       /* 1b */
+#define BAK_PSRI_DDR_EN_LSB                 (1U << 9)       /* 1b */
+/* MD32PCM_WAKEUP_STA (0x10006000+0x130) */
+#define MD32PCM_WAKEUP_STA_LSB              (1U << 0)       /* 32b */
+/* MD32PCM_EVENT_STA (0x10006000+0x134) */
+#define MD32PCM_EVENT_STA_LSB               (1U << 0)       /* 32b */
+/* SPM_WAKEUP_STA (0x10006000+0x138) */
+#define F32K_WAKEUP_EVENT_L_LSB             (1U << 0)       /* 16b */
+#define ASYN_WAKEUP_EVENT_L_LSB             (1U << 16)      /* 16b */
+/* SPM_WAKEUP_EXT_STA (0x10006000+0x13C) */
+#define EXT_WAKEUP_EVENT_LSB                (1U << 0)       /* 32b */
+/* SPM_WAKEUP_MISC (0x10006000+0x140) */
+#define GIC_WAKEUP_LSB                      (1U << 0)       /* 10b */
+#define DVFSRC_IRQ_LSB                      (1U << 16)      /* 1b */
+#define SPM_WAKEUP_MISC_REG_CPU_WAKEUP_LSB  (1U << 17)      /* 1b */
+#define PCM_TIMER_EVENT_LSB                 (1U << 18)      /* 1b */
+#define PMIC_EINT_OUT_B_LSB                 (1U << 19)      /* 2b */
+#define TWAM_IRQ_B_LSB                      (1U << 21)      /* 1b */
+#define PMSR_IRQ_B_SET0_LSB                 (1U << 22)      /* 1b */
+#define PMSR_IRQ_B_SET1_LSB                 (1U << 23)      /* 1b */
+#define PMSR_IRQ_B_SET2_LSB                 (1U << 24)      /* 1b */
+#define SPM_ACK_CHK_WAKEUP_0_LSB            (1U << 25)      /* 1b */
+#define SPM_ACK_CHK_WAKEUP_1_LSB            (1U << 26)      /* 1b */
+#define SPM_ACK_CHK_WAKEUP_2_LSB            (1U << 27)      /* 1b */
+#define SPM_ACK_CHK_WAKEUP_3_LSB            (1U << 28)      /* 1b */
+#define SPM_ACK_CHK_WAKEUP_ALL_LSB          (1U << 29)      /* 1b */
+#define PMIC_IRQ_ACK_LSB                    (1U << 30)      /* 1b */
+#define PMIC_SCP_IRQ_LSB                    (1U << 31)      /* 1b */
+/* MM_DVFS_HALT (0x10006000+0x144) */
+#define MM_DVFS_HALT_LSB                    (1U << 0)       /* 5b */
+/* BUS_PROTECT_RDY (0x10006000+0x150) */
+#define PROTECT_READY_LSB                   (1U << 0)       /* 32b */
+/* BUS_PROTECT1_RDY (0x10006000+0x154) */
+#define PROTECT1_READY_LSB                  (1U << 0)       /* 32b */
+/* BUS_PROTECT2_RDY (0x10006000+0x158) */
+#define PROTECT2_READY_LSB                  (1U << 0)       /* 32b */
+/* BUS_PROTECT3_RDY (0x10006000+0x15C) */
+#define PROTECT3_READY_LSB                  (1U << 0)       /* 32b */
+/* SUBSYS_IDLE_STA (0x10006000+0x160) */
+#define SUBSYS_IDLE_SIGNALS_LSB             (1U << 0)       /* 32b */
+/* PCM_STA (0x10006000+0x164) */
+#define PCM_CK_SEL_O_LSB                    (1U << 0)       /* 4b */
+#define EXT_SRC_STA_LSB                     (1U << 4)       /* 3b */
+/* SRC_REQ_STA_3 (0x10006000+0x168) */
+#define CCIF_EVENT_RAW_STATUS_LSB           (1U << 0)       /* 16b */
+#define F26M_STATE_LSB                      (1U << 16)      /* 1b */
+#define INFRA_STATE_LSB                     (1U << 17)      /* 1b */
+#define APSRC_STATE_LSB                     (1U << 18)      /* 1b */
+#define VRF18_STATE_LSB                     (1U << 19)      /* 1b */
+#define DDR_EN_STATE_LSB                    (1U << 20)      /* 1b */
+#define DVFS_STATE_LSB                      (1U << 21)      /* 1b */
+#define SW_MAILBOX_STATE_LSB                (1U << 22)      /* 1b */
+#define SSPM_MAILBOX_STATE_LSB              (1U << 23)      /* 1b */
+#define ADSP_MAILBOX_STATE_LSB              (1U << 24)      /* 1b */
+#define SCP_MAILBOX_STATE_LSB               (1U << 25)      /* 1b */
+/* PWR_STATUS (0x10006000+0x16C) */
+#define PWR_STATUS_LSB                      (1U << 0)       /* 32b */
+/* PWR_STATUS_2ND (0x10006000+0x170) */
+#define PWR_STATUS_2ND_LSB                  (1U << 0)       /* 32b */
+/* CPU_PWR_STATUS (0x10006000+0x174) */
+#define MP0_SPMC_PWR_ON_ACK_CPU0_LSB        (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_ACK_CPU1_LSB        (1U << 1)       /* 1b */
+#define MP0_SPMC_PWR_ON_ACK_CPU2_LSB        (1U << 2)       /* 1b */
+#define MP0_SPMC_PWR_ON_ACK_CPU3_LSB        (1U << 3)       /* 1b */
+#define MP0_SPMC_PWR_ON_ACK_CPU4_LSB        (1U << 4)       /* 1b */
+#define MP0_SPMC_PWR_ON_ACK_CPU5_LSB        (1U << 5)       /* 1b */
+#define MP0_SPMC_PWR_ON_ACK_CPU6_LSB        (1U << 6)       /* 1b */
+#define MP0_SPMC_PWR_ON_ACK_CPU7_LSB        (1U << 7)       /* 1b */
+#define MP0_SPMC_PWR_ON_ACK_CPUTOP_LSB      (1U << 8)       /* 1b */
+#define MCUSYS_SPMC_PWR_ON_ACK_LSB          (1U << 9)       /* 1b */
+/* OTHER_PWR_STATUS (0x10006000+0x178) */
+#define OTHER_PWR_STATUS_LSB                (1U << 0)       /* 32b */
+/* SPM_VTCXO_EVENT_COUNT_STA (0x10006000+0x17C) */
+#define SPM_VTCXO_SLEEP_COUNT_LSB           (1U << 0)       /* 16b */
+#define SPM_VTCXO_WAKE_COUNT_LSB            (1U << 16)      /* 16b */
+/* SPM_INFRA_EVENT_COUNT_STA (0x10006000+0x180) */
+#define SPM_INFRA_SLEEP_COUNT_LSB           (1U << 0)       /* 16b */
+#define SPM_INFRA_WAKE_COUNT_LSB            (1U << 16)      /* 16b */
+/* SPM_VRF18_EVENT_COUNT_STA (0x10006000+0x184) */
+#define SPM_VRF18_SLEEP_COUNT_LSB           (1U << 0)       /* 16b */
+#define SPM_VRF18_WAKE_COUNT_LSB            (1U << 16)      /* 16b */
+/* SPM_APSRC_EVENT_COUNT_STA (0x10006000+0x188) */
+#define SPM_APSRC_SLEEP_COUNT_LSB           (1U << 0)       /* 16b */
+#define SPM_APSRC_WAKE_COUNT_LSB            (1U << 16)      /* 16b */
+/* SPM_DDREN_EVENT_COUNT_STA (0x10006000+0x18C) */
+#define SPM_DDREN_SLEEP_COUNT_LSB           (1U << 0)       /* 16b */
+#define SPM_DDREN_WAKE_COUNT_LSB            (1U << 16)      /* 16b */
+/* MD32PCM_STA (0x10006000+0x190) */
+#define MD32PCM_HALT_LSB                    (1U << 0)       /* 1b */
+#define MD32PCM_GATED_LSB                   (1U << 1)       /* 1b */
+/* MD32PCM_PC (0x10006000+0x194) */
+#define MON_PC_LSB                          (1U << 0)       /* 32b */
+/* DVFSRC_EVENT_STA (0x10006000+0x1A4) */
+#define DVFSRC_EVENT_LSB                    (1U << 0)       /* 32b */
+/* BUS_PROTECT4_RDY (0x10006000+0x1A8) */
+#define PROTECT4_READY_LSB                  (1U << 0)       /* 32b */
+/* BUS_PROTECT5_RDY (0x10006000+0x1AC) */
+#define PROTECT5_READY_LSB                  (1U << 0)       /* 32b */
+/* BUS_PROTECT6_RDY (0x10006000+0x1B0) */
+#define PROTECT6_READY_LSB                  (1U << 0)       /* 32b */
+/* BUS_PROTECT7_RDY (0x10006000+0x1B4) */
+#define PROTECT7_READY_LSB                  (1U << 0)       /* 32b */
+/* BUS_PROTECT8_RDY (0x10006000+0x1B8) */
+#define PROTECT8_READY_LSB                  (1U << 0)       /* 32b */
+/* SPM_TWAM_LAST_STA0 (0x10006000+0x1D0) */
+#define LAST_IDLE_CNT_0_LSB                 (1U << 0)       /* 32b */
+/* SPM_TWAM_LAST_STA1 (0x10006000+0x1D4) */
+#define LAST_IDLE_CNT_1_LSB                 (1U << 0)       /* 32b */
+/* SPM_TWAM_LAST_STA2 (0x10006000+0x1D8) */
+#define LAST_IDLE_CNT_2_LSB                 (1U << 0)       /* 32b */
+/* SPM_TWAM_LAST_STA3 (0x10006000+0x1DC) */
+#define LAST_IDLE_CNT_3_LSB                 (1U << 0)       /* 32b */
+/* SPM_TWAM_CURR_STA0 (0x10006000+0x1E0) */
+#define CURRENT_IDLE_CNT_0_LSB              (1U << 0)       /* 32b */
+/* SPM_TWAM_CURR_STA1 (0x10006000+0x1E4) */
+#define CURRENT_IDLE_CNT_1_LSB              (1U << 0)       /* 32b */
+/* SPM_TWAM_CURR_STA2 (0x10006000+0x1E8) */
+#define CURRENT_IDLE_CNT_2_LSB              (1U << 0)       /* 32b */
+/* SPM_TWAM_CURR_STA3 (0x10006000+0x1EC) */
+#define CURRENT_IDLE_CNT_3_LSB              (1U << 0)       /* 32b */
+/* SPM_TWAM_TIMER_OUT (0x10006000+0x1F0) */
+#define TWAM_TIMER_LSB                      (1U << 0)       /* 32b */
+/* SPM_CG_CHECK_STA (0x10006000+0x1F4) */
+#define SPM_CG_CHECK_SLEEP_REQ_0_LSB        (1U << 0)       /* 1b */
+#define SPM_CG_CHECK_SLEEP_REQ_1_LSB        (1U << 1)       /* 1b */
+#define SPM_CG_CHECK_SLEEP_REQ_2_LSB        (1U << 2)       /* 1b */
+/* SPM_DVFS_STA (0x10006000+0x1F8) */
+#define TARGET_DVFS_LEVEL_LSB               (1U << 0)       /* 32b */
+/* SPM_DVFS_OPP_STA (0x10006000+0x1FC) */
+#define TARGET_DVFS_OPP_LSB                 (1U << 0)       /* 5b */
+#define CURRENT_DVFS_OPP_LSB                (1U << 5)       /* 5b */
+#define RELAY_DVFS_OPP_LSB                  (1U << 10)      /* 5b */
+/* SPM_MCUSYS_PWR_CON (0x10006000+0x200) */
+#define MCUSYS_SPMC_PWR_RST_B_LSB           (1U << 0)       /* 1b */
+#define MCUSYS_SPMC_PWR_ON_LSB              (1U << 2)       /* 1b */
+#define MCUSYS_SPMC_PWR_CLK_DIS_LSB         (1U << 4)       /* 1b */
+#define MCUSYS_SPMC_RESETPWRON_CONFIG_LSB   (1U << 5)       /* 1b */
+#define MCUSYS_SPMC_DORMANT_EN_LSB          (1U << 6)       /* 1b */
+#define MCUSYS_VPROC_EXT_OFF_LSB            (1U << 7)       /* 1b */
+#define SPM_MCUSYS_PWR_CON_MCUSYS_SPMC_PWR_ON_ACK_LSB (1U << 31)      /* 1b */
+/* SPM_CPUTOP_PWR_CON (0x10006000+0x204) */
+#define MP0_SPMC_PWR_RST_B_CPUTOP_LSB       (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_CPUTOP_LSB          (1U << 2)       /* 1b */
+#define MP0_SPMC_PWR_CLK_DIS_CPUTOP_LSB     (1U << 4)       /* 1b */
+#define MP0_SPMC_RESETPWRON_CONFIG_CPUTOP_LSB (1U << 5)       /* 1b */
+#define MP0_SPMC_DORMANT_EN_CPUTOP_LSB      (1U << 6)       /* 1b */
+#define MP0_VPROC_EXT_OFF_LSB               (1U << 7)       /* 1b */
+#define MP0_VSRAM_EXT_OFF_LSB               (1U << 8)       /* 1b */
+#define SPM_CPUTOP_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPUTOP_LSB (1U << 31)      /* 1b */
+/* SPM_CPU0_PWR_CON (0x10006000+0x208) */
+#define MP0_SPMC_PWR_RST_B_CPU0_LSB         (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_CPU0_LSB            (1U << 2)       /* 1b */
+#define MP0_SPMC_RESETPWRON_CONFIG_CPU0_LSB (1U << 5)       /* 1b */
+#define MP0_VPROC_EXT_OFF_CPU0_LSB          (1U << 7)       /* 1b */
+#define SPM_CPU0_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU0_LSB (1U << 31)      /* 1b */
+/* SPM_CPU1_PWR_CON (0x10006000+0x20C) */
+#define MP0_SPMC_PWR_RST_B_CPU1_LSB         (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_CPU1_LSB            (1U << 2)       /* 1b */
+#define MP0_SPMC_RESETPWRON_CONFIG_CPU1_LSB (1U << 5)       /* 1b */
+#define MP0_VPROC_EXT_OFF_CPU1_LSB          (1U << 7)       /* 1b */
+#define SPM_CPU1_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU1_LSB (1U << 31)      /* 1b */
+/* SPM_CPU2_PWR_CON (0x10006000+0x210) */
+#define MP0_SPMC_PWR_RST_B_CPU2_LSB         (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_CPU2_LSB            (1U << 2)       /* 1b */
+#define MP0_SPMC_RESETPWRON_CONFIG_CPU2_LSB (1U << 5)       /* 1b */
+#define MP0_VPROC_EXT_OFF_CPU2_LSB          (1U << 7)       /* 1b */
+#define SPM_CPU2_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU2_LSB (1U << 31)      /* 1b */
+/* SPM_CPU3_PWR_CON (0x10006000+0x214) */
+#define MP0_SPMC_PWR_RST_B_CPU3_LSB         (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_CPU3_LSB            (1U << 2)       /* 1b */
+#define MP0_SPMC_RESETPWRON_CONFIG_CPU3_LSB (1U << 5)       /* 1b */
+#define MP0_VPROC_EXT_OFF_CPU3_LSB          (1U << 7)       /* 1b */
+#define SPM_CPU3_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU3_LSB (1U << 31)      /* 1b */
+/* SPM_CPU4_PWR_CON (0x10006000+0x218) */
+#define MP0_SPMC_PWR_RST_B_CPU4_LSB         (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_CPU4_LSB            (1U << 2)       /* 1b */
+#define MP0_SPMC_RESETPWRON_CONFIG_CPU4_LSB (1U << 5)       /* 1b */
+#define MP0_VPROC_EXT_OFF_CPU4_LSB          (1U << 7)       /* 1b */
+#define SPM_CPU4_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU4_LSB (1U << 31)      /* 1b */
+/* SPM_CPU5_PWR_CON (0x10006000+0x21C) */
+#define MP0_SPMC_PWR_RST_B_CPU5_LSB         (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_CPU5_LSB            (1U << 2)       /* 1b */
+#define MP0_SPMC_RESETPWRON_CONFIG_CPU5_LSB (1U << 5)       /* 1b */
+#define MP0_VPROC_EXT_OFF_CPU5_LSB          (1U << 7)       /* 1b */
+#define SPM_CPU5_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU5_LSB (1U << 31)      /* 1b */
+/* SPM_CPU6_PWR_CON (0x10006000+0x220) */
+#define MP0_SPMC_PWR_RST_B_CPU6_LSB         (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_CPU6_LSB            (1U << 2)       /* 1b */
+#define MP0_SPMC_RESETPWRON_CONFIG_CPU6_LSB (1U << 5)       /* 1b */
+#define MP0_VPROC_EXT_OFF_CPU6_LSB          (1U << 7)       /* 1b */
+#define SPM_CPU6_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU6_LSB (1U << 31)      /* 1b */
+/* SPM_CPU7_PWR_CON (0x10006000+0x224) */
+#define MP0_SPMC_PWR_RST_B_CPU7_LSB         (1U << 0)       /* 1b */
+#define MP0_SPMC_PWR_ON_CPU7_LSB            (1U << 2)       /* 1b */
+#define MP0_SPMC_RESETPWRON_CONFIG_CPU7_LSB (1U << 5)       /* 1b */
+#define MP0_VPROC_EXT_OFF_CPU7_LSB          (1U << 7)       /* 1b */
+#define SPM_CPU7_PWR_CON_MP0_SPMC_PWR_ON_ACK_CPU7_LSB (1U << 31)      /* 1b */
+/* ARMPLL_CLK_CON (0x10006000+0x22C) */
+#define SC_ARM_FHC_PAUSE_LSB                (1U << 0)       /* 6b */
+#define SC_ARM_CK_OFF_LSB                   (1U << 6)       /* 6b */
+#define SC_ARMPLL_OFF_LSB                   (1U << 12)      /* 1b */
+#define SC_ARMBPLL_OFF_LSB                  (1U << 13)      /* 1b */
+#define SC_ARMBPLL1_OFF_LSB                 (1U << 14)      /* 1b */
+#define SC_ARMBPLL2_OFF_LSB                 (1U << 15)      /* 1b */
+#define SC_ARMBPLL3_OFF_LSB                 (1U << 16)      /* 1b */
+#define SC_CCIPLL_CKOFF_LSB                 (1U << 17)      /* 1b */
+#define SC_ARMDDS_OFF_LSB                   (1U << 18)      /* 1b */
+#define SC_ARMBPLL_S_OFF_LSB                (1U << 19)      /* 1b */
+#define SC_ARMBPLL1_S_OFF_LSB               (1U << 20)      /* 1b */
+#define SC_ARMBPLL2_S_OFF_LSB               (1U << 21)      /* 1b */
+#define SC_ARMBPLL3_S_OFF_LSB               (1U << 22)      /* 1b */
+#define SC_CCIPLL_PWROFF_LSB                (1U << 23)      /* 1b */
+#define SC_ARMPLLOUT_OFF_LSB                (1U << 24)      /* 1b */
+#define SC_ARMBPLLOUT_OFF_LSB               (1U << 25)      /* 1b */
+#define SC_ARMBPLLOUT1_OFF_LSB              (1U << 26)      /* 1b */
+#define SC_ARMBPLLOUT2_OFF_LSB              (1U << 27)      /* 1b */
+#define SC_ARMBPLLOUT3_OFF_LSB              (1U << 28)      /* 1b */
+#define SC_CCIPLL_OUT_OFF_LSB               (1U << 29)      /* 1b */
+/* MCUSYS_IDLE_STA (0x10006000+0x230) */
+#define ARMBUS_IDLE_TO_26M_LSB              (1U << 0)       /* 1b */
+#define MP0_CLUSTER_IDLE_TO_PWR_OFF_LSB     (1U << 1)       /* 1b */
+#define MCUSYS_DDR_EN_0_LSB                 (1U << 2)       /* 1b */
+#define MCUSYS_DDR_EN_1_LSB                 (1U << 3)       /* 1b */
+#define MCUSYS_DDR_EN_2_LSB                 (1U << 4)       /* 1b */
+#define MCUSYS_DDR_EN_3_LSB                 (1U << 5)       /* 1b */
+#define MCUSYS_DDR_EN_4_LSB                 (1U << 6)       /* 1b */
+#define MCUSYS_DDR_EN_5_LSB                 (1U << 7)       /* 1b */
+#define MCUSYS_DDR_EN_6_LSB                 (1U << 8)       /* 1b */
+#define MCUSYS_DDR_EN_7_LSB                 (1U << 9)       /* 1b */
+#define MP0_CPU_IDLE_TO_PWR_OFF_LSB         (1U << 16)      /* 8b */
+#define WFI_AF_SEL_LSB                      (1U << 24)      /* 8b */
+/* GIC_WAKEUP_STA (0x10006000+0x234) */
+#define GIC_WAKEUP_STA_GIC_WAKEUP_LSB       (1U << 10)      /* 10b */
+/* CPU_SPARE_CON (0x10006000+0x238) */
+#define CPU_SPARE_CON_LSB                   (1U << 0)       /* 32b */
+/* CPU_SPARE_CON_SET (0x10006000+0x23C) */
+#define CPU_SPARE_CON_SET_LSB               (1U << 0)       /* 32b */
+/* CPU_SPARE_CON_CLR (0x10006000+0x240) */
+#define CPU_SPARE_CON_CLR_LSB               (1U << 0)       /* 32b */
+/* ARMPLL_CLK_SEL (0x10006000+0x244) */
+#define ARMPLL_CLK_SEL_LSB                  (1U << 0)       /* 15b */
+/* EXT_INT_WAKEUP_REQ (0x10006000+0x248) */
+#define EXT_INT_WAKEUP_REQ_LSB              (1U << 0)       /* 10b */
+/* EXT_INT_WAKEUP_REQ_SET (0x10006000+0x24C) */
+#define EXT_INT_WAKEUP_REQ_SET_LSB          (1U << 0)       /* 10b */
+/* EXT_INT_WAKEUP_REQ_CLR (0x10006000+0x250) */
+#define EXT_INT_WAKEUP_REQ_CLR_LSB          (1U << 0)       /* 10b */
+/* MP0_CPU0_IRQ_MASK (0x10006000+0x260) */
+#define MP0_CPU0_IRQ_MASK_LSB               (1U << 0)       /* 1b */
+#define MP0_CPU0_AUX_LSB                    (1U << 8)       /* 11b */
+/* MP0_CPU1_IRQ_MASK (0x10006000+0x264) */
+#define MP0_CPU1_IRQ_MASK_LSB               (1U << 0)       /* 1b */
+#define MP0_CPU1_AUX_LSB                    (1U << 8)       /* 11b */
+/* MP0_CPU2_IRQ_MASK (0x10006000+0x268) */
+#define MP0_CPU2_IRQ_MASK_LSB               (1U << 0)       /* 1b */
+#define MP0_CPU2_AUX_LSB                    (1U << 8)       /* 11b */
+/* MP0_CPU3_IRQ_MASK (0x10006000+0x26C) */
+#define MP0_CPU3_IRQ_MASK_LSB               (1U << 0)       /* 1b */
+#define MP0_CPU3_AUX_LSB                    (1U << 8)       /* 11b */
+/* MP1_CPU0_IRQ_MASK (0x10006000+0x270) */
+#define MP1_CPU0_IRQ_MASK_LSB               (1U << 0)       /* 1b */
+#define MP1_CPU0_AUX_LSB                    (1U << 8)       /* 11b */
+/* MP1_CPU1_IRQ_MASK (0x10006000+0x274) */
+#define MP1_CPU1_IRQ_MASK_LSB               (1U << 0)       /* 1b */
+#define MP1_CPU1_AUX_LSB                    (1U << 8)       /* 11b */
+/* MP1_CPU2_IRQ_MASK (0x10006000+0x278) */
+#define MP1_CPU2_IRQ_MASK_LSB               (1U << 0)       /* 1b */
+#define MP1_CPU2_AUX_LSB                    (1U << 8)       /* 11b */
+/* MP1_CPU3_IRQ_MASK (0x10006000+0x27C) */
+#define MP1_CPU3_IRQ_MASK_LSB               (1U << 0)       /* 1b */
+#define MP1_CPU3_AUX_LSB                    (1U << 8)       /* 11b */
+/* MP0_CPU0_WFI_EN (0x10006000+0x280) */
+#define MP0_CPU0_WFI_EN_LSB                 (1U << 0)       /* 1b */
+/* MP0_CPU1_WFI_EN (0x10006000+0x284) */
+#define MP0_CPU1_WFI_EN_LSB                 (1U << 0)       /* 1b */
+/* MP0_CPU2_WFI_EN (0x10006000+0x288) */
+#define MP0_CPU2_WFI_EN_LSB                 (1U << 0)       /* 1b */
+/* MP0_CPU3_WFI_EN (0x10006000+0x28C) */
+#define MP0_CPU3_WFI_EN_LSB                 (1U << 0)       /* 1b */
+/* MP0_CPU4_WFI_EN (0x10006000+0x290) */
+#define MP0_CPU4_WFI_EN_LSB                 (1U << 0)       /* 1b */
+/* MP0_CPU5_WFI_EN (0x10006000+0x294) */
+#define MP0_CPU5_WFI_EN_LSB                 (1U << 0)       /* 1b */
+/* MP0_CPU6_WFI_EN (0x10006000+0x298) */
+#define MP0_CPU6_WFI_EN_LSB                 (1U << 0)       /* 1b */
+/* MP0_CPU7_WFI_EN (0x10006000+0x29C) */
+#define MP0_CPU7_WFI_EN_LSB                 (1U << 0)       /* 1b */
+/* ROOT_CPUTOP_ADDR (0x10006000+0x2A0) */
+#define ROOT_CPUTOP_ADDR_LSB                (1U << 0)       /* 32b */
+/* ROOT_CORE_ADDR (0x10006000+0x2A4) */
+#define ROOT_CORE_ADDR_LSB                  (1U << 0)       /* 32b */
+/* SPM2SW_MAILBOX_0 (0x10006000+0x2D0) */
+#define SPM2SW_MAILBOX_0_LSB                (1U << 0)       /* 32b */
+/* SPM2SW_MAILBOX_1 (0x10006000+0x2D4) */
+#define SPM2SW_MAILBOX_1_LSB                (1U << 0)       /* 32b */
+/* SPM2SW_MAILBOX_2 (0x10006000+0x2D8) */
+#define SPM2SW_MAILBOX_2_LSB                (1U << 0)       /* 32b */
+/* SPM2SW_MAILBOX_3 (0x10006000+0x2DC) */
+#define SPM2SW_MAILBOX_3_LSB                (1U << 0)       /* 32b */
+/* SW2SPM_INT (0x10006000+0x2E0) */
+#define SW2SPM_INT_SW2SPM_INT_LSB           (1U << 0)       /* 4b */
+/* SW2SPM_INT_SET (0x10006000+0x2E4) */
+#define SW2SPM_INT_SET_LSB                  (1U << 0)       /* 4b */
+/* SW2SPM_INT_CLR (0x10006000+0x2E8) */
+#define SW2SPM_INT_CLR_LSB                  (1U << 0)       /* 4b */
+/* SW2SPM_MAILBOX_0 (0x10006000+0x2EC) */
+#define SW2SPM_MAILBOX_0_LSB                (1U << 0)       /* 32b */
+/* SW2SPM_MAILBOX_1 (0x10006000+0x2F0) */
+#define SW2SPM_MAILBOX_1_LSB                (1U << 0)       /* 32b */
+/* SW2SPM_MAILBOX_2 (0x10006000+0x2F4) */
+#define SW2SPM_MAILBOX_2_LSB                (1U << 0)       /* 32b */
+/* SW2SPM_MAILBOX_3 (0x10006000+0x2F8) */
+#define SW2SPM_MAILBOX_3_LSB                (1U << 0)       /* 32b */
+/* SW2SPM_CFG (0x10006000+0x2FC) */
+#define SWU2SPM_INT_MASK_B_LSB              (1U << 0)       /* 4b */
+/* MD1_PWR_CON (0x10006000+0x300) */
+#define MD1_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define MD1_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define MD1_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define MD1_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define MD1_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define MD1_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_MD1_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* CONN_PWR_CON (0x10006000+0x304) */
+#define CONN_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define CONN_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define CONN_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define CONN_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define CONN_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+/* MFG0_PWR_CON (0x10006000+0x308) */
+#define MFG0_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define MFG0_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define MFG0_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define MFG0_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define MFG0_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define MFG0_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_MFG0_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* MFG1_PWR_CON (0x10006000+0x30C) */
+#define MFG1_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define MFG1_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define MFG1_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define MFG1_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define MFG1_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define MFG1_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_MFG1_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* MFG2_PWR_CON (0x10006000+0x310) */
+#define MFG2_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define MFG2_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define MFG2_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define MFG2_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define MFG2_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define MFG2_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_MFG2_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* MFG3_PWR_CON (0x10006000+0x314) */
+#define MFG3_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define MFG3_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define MFG3_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define MFG3_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define MFG3_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define MFG3_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_MFG3_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* MFG4_PWR_CON (0x10006000+0x318) */
+#define MFG4_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define MFG4_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define MFG4_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define MFG4_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define MFG4_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define MFG4_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_MFG4_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* MFG5_PWR_CON (0x10006000+0x31C) */
+#define MFG5_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define MFG5_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define MFG5_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define MFG5_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define MFG5_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define MFG5_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_MFG5_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* MFG6_PWR_CON (0x10006000+0x320) */
+#define MFG6_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define MFG6_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define MFG6_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define MFG6_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define MFG6_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define MFG6_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_MFG6_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* IFR_PWR_CON (0x10006000+0x324) */
+#define IFR_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define IFR_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define IFR_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define IFR_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define IFR_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define IFR_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_IFR_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* IFR_SUB_PWR_CON (0x10006000+0x328) */
+#define IFR_SUB_PWR_RST_B_LSB               (1U << 0)       /* 1b */
+#define IFR_SUB_PWR_ISO_LSB                 (1U << 1)       /* 1b */
+#define IFR_SUB_PWR_ON_LSB                  (1U << 2)       /* 1b */
+#define IFR_SUB_PWR_ON_2ND_LSB              (1U << 3)       /* 1b */
+#define IFR_SUB_PWR_CLK_DIS_LSB             (1U << 4)       /* 1b */
+#define IFR_SUB_SRAM_PDN_LSB                (1U << 8)       /* 1b */
+#define SC_IFR_SUB_SRAM_PDN_ACK_LSB         (1U << 12)      /* 1b */
+/* DPY_PWR_CON (0x10006000+0x32C) */
+#define DPY_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define DPY_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define DPY_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define DPY_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define DPY_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define DPY_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_DPY_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* ISP_PWR_CON (0x10006000+0x330) */
+#define ISP_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define ISP_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define ISP_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define ISP_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define ISP_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define ISP_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_ISP_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* ISP2_PWR_CON (0x10006000+0x334) */
+#define ISP2_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define ISP2_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define ISP2_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define ISP2_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define ISP2_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define ISP2_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_ISP2_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* IPE_PWR_CON (0x10006000+0x338) */
+#define IPE_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define IPE_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define IPE_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define IPE_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define IPE_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define IPE_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_IPE_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* VDE_PWR_CON (0x10006000+0x33C) */
+#define VDE_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define VDE_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define VDE_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define VDE_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define VDE_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define VDE_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_VDE_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* VDE2_PWR_CON (0x10006000+0x340) */
+#define VDE2_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define VDE2_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define VDE2_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define VDE2_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define VDE2_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define VDE2_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_VDE2_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* VEN_PWR_CON (0x10006000+0x344) */
+#define VEN_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define VEN_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define VEN_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define VEN_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define VEN_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define VEN_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_VEN_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* VEN_CORE1_PWR_CON (0x10006000+0x348) */
+#define VEN_CORE1_PWR_RST_B_LSB             (1U << 0)       /* 1b */
+#define VEN_CORE1_PWR_ISO_LSB               (1U << 1)       /* 1b */
+#define VEN_CORE1_PWR_ON_LSB                (1U << 2)       /* 1b */
+#define VEN_CORE1_PWR_ON_2ND_LSB            (1U << 3)       /* 1b */
+#define VEN_CORE1_PWR_CLK_DIS_LSB           (1U << 4)       /* 1b */
+#define VEN_CORE1_SRAM_PDN_LSB              (1U << 8)       /* 1b */
+#define SC_VEN_CORE1_SRAM_PDN_ACK_LSB       (1U << 12)      /* 1b */
+/* MDP_PWR_CON (0x10006000+0x34C) */
+#define MDP_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define MDP_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define MDP_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define MDP_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define MDP_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define MDP_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_MDP_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* DIS_PWR_CON (0x10006000+0x350) */
+#define DIS_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define DIS_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define DIS_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define DIS_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define DIS_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define DIS_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_DIS_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* AUDIO_PWR_CON (0x10006000+0x354) */
+#define AUDIO_PWR_RST_B_LSB                 (1U << 0)       /* 1b */
+#define AUDIO_PWR_ISO_LSB                   (1U << 1)       /* 1b */
+#define AUDIO_PWR_ON_LSB                    (1U << 2)       /* 1b */
+#define AUDIO_PWR_ON_2ND_LSB                (1U << 3)       /* 1b */
+#define AUDIO_PWR_CLK_DIS_LSB               (1U << 4)       /* 1b */
+#define AUDIO_SRAM_PDN_LSB                  (1U << 8)       /* 1b */
+#define SC_AUDIO_SRAM_PDN_ACK_LSB           (1U << 12)      /* 1b */
+/* ADSP_PWR_CON (0x10006000+0x358) */
+#define ADSP_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define ADSP_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define ADSP_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define ADSP_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define ADSP_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define ADSP_SRAM_CKISO_LSB                 (1U << 5)       /* 1b */
+#define ADSP_SRAM_ISOINT_B_LSB              (1U << 6)       /* 1b */
+#define ADSP_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define ADSP_SRAM_SLEEP_B_LSB               (1U << 9)       /* 1b */
+#define SC_ADSP_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+#define SC_ADSP_SRAM_SLEEP_B_ACK_LSB        (1U << 13)      /* 1b */
+/* CAM_PWR_CON (0x10006000+0x35C) */
+#define CAM_PWR_RST_B_LSB                   (1U << 0)       /* 1b */
+#define CAM_PWR_ISO_LSB                     (1U << 1)       /* 1b */
+#define CAM_PWR_ON_LSB                      (1U << 2)       /* 1b */
+#define CAM_PWR_ON_2ND_LSB                  (1U << 3)       /* 1b */
+#define CAM_PWR_CLK_DIS_LSB                 (1U << 4)       /* 1b */
+#define CAM_SRAM_PDN_LSB                    (1U << 8)       /* 1b */
+#define SC_CAM_SRAM_PDN_ACK_LSB             (1U << 12)      /* 1b */
+/* CAM_RAWA_PWR_CON (0x10006000+0x360) */
+#define CAM_RAWA_PWR_RST_B_LSB              (1U << 0)       /* 1b */
+#define CAM_RAWA_PWR_ISO_LSB                (1U << 1)       /* 1b */
+#define CAM_RAWA_PWR_ON_LSB                 (1U << 2)       /* 1b */
+#define CAM_RAWA_PWR_ON_2ND_LSB             (1U << 3)       /* 1b */
+#define CAM_RAWA_PWR_CLK_DIS_LSB            (1U << 4)       /* 1b */
+#define CAM_RAWA_SRAM_PDN_LSB               (1U << 8)       /* 1b */
+#define SC_CAM_RAWA_SRAM_PDN_ACK_LSB        (1U << 12)      /* 1b */
+/* CAM_RAWB_PWR_CON (0x10006000+0x364) */
+#define CAM_RAWB_PWR_RST_B_LSB              (1U << 0)       /* 1b */
+#define CAM_RAWB_PWR_ISO_LSB                (1U << 1)       /* 1b */
+#define CAM_RAWB_PWR_ON_LSB                 (1U << 2)       /* 1b */
+#define CAM_RAWB_PWR_ON_2ND_LSB             (1U << 3)       /* 1b */
+#define CAM_RAWB_PWR_CLK_DIS_LSB            (1U << 4)       /* 1b */
+#define CAM_RAWB_SRAM_PDN_LSB               (1U << 8)       /* 1b */
+#define SC_CAM_RAWB_SRAM_PDN_ACK_LSB        (1U << 12)      /* 1b */
+/* CAM_RAWC_PWR_CON (0x10006000+0x368) */
+#define CAM_RAWC_PWR_RST_B_LSB              (1U << 0)       /* 1b */
+#define CAM_RAWC_PWR_ISO_LSB                (1U << 1)       /* 1b */
+#define CAM_RAWC_PWR_ON_LSB                 (1U << 2)       /* 1b */
+#define CAM_RAWC_PWR_ON_2ND_LSB             (1U << 3)       /* 1b */
+#define CAM_RAWC_PWR_CLK_DIS_LSB            (1U << 4)       /* 1b */
+#define CAM_RAWC_SRAM_PDN_LSB               (1U << 8)       /* 1b */
+#define SC_CAM_RAWC_SRAM_PDN_ACK_LSB        (1U << 12)      /* 1b */
+/* SYSRAM_CON (0x10006000+0x36C) */
+#define SYSRAM_SRAM_CKISO_LSB               (1U << 0)       /* 1b */
+#define SYSRAM_SRAM_ISOINT_B_LSB            (1U << 1)       /* 1b */
+#define SYSRAM_SRAM_SLEEP_B_LSB             (1U << 4)       /* 4b */
+#define SYSRAM_SRAM_PDN_LSB                 (1U << 16)      /* 4b */
+/* SYSROM_CON (0x10006000+0x370) */
+#define SYSROM_SRAM_PDN_LSB                 (1U << 0)       /* 6b */
+/* SSPM_SRAM_CON (0x10006000+0x374) */
+#define SSPM_SRAM_CKISO_LSB                 (1U << 0)       /* 1b */
+#define SSPM_SRAM_ISOINT_B_LSB              (1U << 1)       /* 1b */
+#define SSPM_SRAM_SLEEP_B_LSB               (1U << 4)       /* 1b */
+#define SSPM_SRAM_PDN_LSB                   (1U << 16)      /* 1b */
+/* SCP_SRAM_CON (0x10006000+0x378) */
+#define SCP_SRAM_CKISO_LSB                  (1U << 0)       /* 1b */
+#define SCP_SRAM_ISOINT_B_LSB               (1U << 1)       /* 1b */
+#define SCP_SRAM_SLEEP_B_LSB                (1U << 4)       /* 1b */
+#define SCP_SRAM_PDN_LSB                    (1U << 16)      /* 1b */
+/* DPY_SHU_SRAM_CON (0x10006000+0x37C) */
+#define DPY_SHU_SRAM_CKISO_LSB              (1U << 0)       /* 1b */
+#define DPY_SHU_SRAM_ISOINT_B_LSB           (1U << 1)       /* 1b */
+#define DPY_SHU_SRAM_SLEEP_B_LSB            (1U << 4)       /* 2b */
+#define DPY_SHU_SRAM_PDN_LSB                (1U << 16)      /* 2b */
+/* UFS_SRAM_CON (0x10006000+0x380) */
+#define UFS_SRAM_CKISO_LSB                  (1U << 0)       /* 1b */
+#define UFS_SRAM_ISOINT_B_LSB               (1U << 1)       /* 1b */
+#define UFS_SRAM_SLEEP_B_LSB                (1U << 4)       /* 5b */
+#define UFS_SRAM_PDN_LSB                    (1U << 16)      /* 5b */
+/* DEVAPC_IFR_SRAM_CON (0x10006000+0x384) */
+#define DEVAPC_IFR_SRAM_CKISO_LSB           (1U << 0)       /* 1b */
+#define DEVAPC_IFR_SRAM_ISOINT_B_LSB        (1U << 1)       /* 1b */
+#define DEVAPC_IFR_SRAM_SLEEP_B_LSB         (1U << 4)       /* 6b */
+#define DEVAPC_IFR_SRAM_PDN_LSB             (1U << 16)      /* 6b */
+/* DEVAPC_SUBIFR_SRAM_CON (0x10006000+0x388) */
+#define DEVAPC_SUBIFR_SRAM_CKISO_LSB        (1U << 0)       /* 1b */
+#define DEVAPC_SUBIFR_SRAM_ISOINT_B_LSB     (1U << 1)       /* 1b */
+#define DEVAPC_SUBIFR_SRAM_SLEEP_B_LSB      (1U << 4)       /* 6b */
+#define DEVAPC_SUBIFR_SRAM_PDN_LSB          (1U << 16)      /* 6b */
+/* DEVAPC_ACP_SRAM_CON (0x10006000+0x38C) */
+#define DEVAPC_ACP_SRAM_CKISO_LSB           (1U << 0)       /* 1b */
+#define DEVAPC_ACP_SRAM_ISOINT_B_LSB        (1U << 1)       /* 1b */
+#define DEVAPC_ACP_SRAM_SLEEP_B_LSB         (1U << 4)       /* 6b */
+#define DEVAPC_ACP_SRAM_PDN_LSB             (1U << 16)      /* 6b */
+/* USB_SRAM_CON (0x10006000+0x390) */
+#define USB_SRAM_PDN_LSB                    (1U << 0)       /* 7b */
+/* DUMMY_SRAM_CON (0x10006000+0x394) */
+#define DUMMY_SRAM_CKISO_LSB                (1U << 0)       /* 1b */
+#define DUMMY_SRAM_ISOINT_B_LSB             (1U << 1)       /* 1b */
+#define DUMMY_SRAM_SLEEP_B_LSB              (1U << 4)       /* 8b */
+#define DUMMY_SRAM_PDN_LSB                  (1U << 16)      /* 8b */
+/* MD_EXT_BUCK_ISO_CON (0x10006000+0x398) */
+#define VMODEM_EXT_BUCK_ISO_LSB             (1U << 0)       /* 1b */
+#define VMD_EXT_BUCK_ISO_LSB                (1U << 1)       /* 1b */
+/* EXT_BUCK_ISO (0x10006000+0x39C) */
+#define VIMVO_EXT_BUCK_ISO_LSB              (1U << 0)       /* 1b */
+#define GPU_EXT_BUCK_ISO_LSB                (1U << 1)       /* 1b */
+#define IPU_EXT_BUCK_ISO_LSB                (1U << 5)       /* 3b */
+/* DXCC_SRAM_CON (0x10006000+0x3A0) */
+#define DXCC_SRAM_CKISO_LSB                 (1U << 0)       /* 1b */
+#define DXCC_SRAM_ISOINT_B_LSB              (1U << 1)       /* 1b */
+#define DXCC_SRAM_SLEEP_B_LSB               (1U << 4)       /* 1b */
+#define DXCC_SRAM_PDN_LSB                   (1U << 16)      /* 1b */
+/* MSDC_SRAM_CON (0x10006000+0x3A4) */
+#define MSDC_SRAM_CKISO_LSB                 (1U << 0)       /* 1b */
+#define MSDC_SRAM_ISOINT_B_LSB              (1U << 1)       /* 1b */
+#define MSDC_SRAM_SLEEP_B_LSB               (1U << 4)       /* 5b */
+#define MSDC_SRAM_PDN_LSB                   (1U << 16)      /* 5b */
+/* DEBUGTOP_SRAM_CON (0x10006000+0x3A8) */
+#define DEBUGTOP_SRAM_PDN_LSB               (1U << 0)       /* 1b */
+/* DP_TX_PWR_CON (0x10006000+0x3AC) */
+#define DP_TX_PWR_RST_B_LSB                 (1U << 0)       /* 1b */
+#define DP_TX_PWR_ISO_LSB                   (1U << 1)       /* 1b */
+#define DP_TX_PWR_ON_LSB                    (1U << 2)       /* 1b */
+#define DP_TX_PWR_ON_2ND_LSB                (1U << 3)       /* 1b */
+#define DP_TX_PWR_CLK_DIS_LSB               (1U << 4)       /* 1b */
+#define DP_TX_SRAM_PDN_LSB                  (1U << 8)       /* 1b */
+#define SC_DP_TX_SRAM_PDN_ACK_LSB           (1U << 12)      /* 1b */
+/* DPMAIF_SRAM_CON (0x10006000+0x3B0) */
+#define DPMAIF_SRAM_CKISO_LSB               (1U << 0)       /* 1b */
+#define DPMAIF_SRAM_ISOINT_B_LSB            (1U << 1)       /* 1b */
+#define DPMAIF_SRAM_SLEEP_B_LSB             (1U << 4)       /* 1b */
+#define DPMAIF_SRAM_PDN_LSB                 (1U << 16)      /* 1b */
+/* DPY_SHU2_SRAM_CON (0x10006000+0x3B4) */
+#define DPY_SHU2_SRAM_CKISO_LSB             (1U << 0)       /* 1b */
+#define DPY_SHU2_SRAM_ISOINT_B_LSB          (1U << 1)       /* 1b */
+#define DPY_SHU2_SRAM_SLEEP_B_LSB           (1U << 4)       /* 2b */
+#define DPY_SHU2_SRAM_PDN_LSB               (1U << 16)      /* 2b */
+/* DRAMC_MCU2_SRAM_CON (0x10006000+0x3B8) */
+#define DRAMC_MCU2_SRAM_CKISO_LSB           (1U << 0)       /* 1b */
+#define DRAMC_MCU2_SRAM_ISOINT_B_LSB        (1U << 1)       /* 1b */
+#define DRAMC_MCU2_SRAM_SLEEP_B_LSB         (1U << 4)       /* 1b */
+#define DRAMC_MCU2_SRAM_PDN_LSB             (1U << 16)      /* 1b */
+/* DRAMC_MCU_SRAM_CON (0x10006000+0x3BC) */
+#define DRAMC_MCU_SRAM_CKISO_LSB            (1U << 0)       /* 1b */
+#define DRAMC_MCU_SRAM_ISOINT_B_LSB         (1U << 1)       /* 1b */
+#define DRAMC_MCU_SRAM_SLEEP_B_LSB          (1U << 4)       /* 1b */
+#define DRAMC_MCU_SRAM_PDN_LSB              (1U << 16)      /* 1b */
+/* MCUPM_SRAM_CON (0x10006000+0x3C0) */
+#define MCUPM_SRAM_CKISO_LSB                (1U << 0)       /* 1b */
+#define MCUPM_SRAM_ISOINT_B_LSB             (1U << 1)       /* 1b */
+#define MCUPM_SRAM_SLEEP_B_LSB              (1U << 4)       /* 8b */
+#define MCUPM_SRAM_PDN_LSB                  (1U << 16)      /* 8b */
+/* DPY2_PWR_CON (0x10006000+0x3C4) */
+#define DPY2_PWR_RST_B_LSB                  (1U << 0)       /* 1b */
+#define DPY2_PWR_ISO_LSB                    (1U << 1)       /* 1b */
+#define DPY2_PWR_ON_LSB                     (1U << 2)       /* 1b */
+#define DPY2_PWR_ON_2ND_LSB                 (1U << 3)       /* 1b */
+#define DPY2_PWR_CLK_DIS_LSB                (1U << 4)       /* 1b */
+#define DPY2_SRAM_PDN_LSB                   (1U << 8)       /* 1b */
+#define SC_DPY2_SRAM_PDN_ACK_LSB            (1U << 12)      /* 1b */
+/* SPM_MEM_CK_SEL (0x10006000+0x400) */
+#define SC_MEM_CK_SEL_LSB                   (1U << 0)       /* 1b */
+#define SPM2CKSYS_MEM_CK_MUX_UPDATE_LSB     (1U << 1)       /* 1b */
+/* SPM_BUS_PROTECT_MASK_B (0x10006000+0X404) */
+#define SPM_BUS_PROTECT_MASK_B_LSB          (1U << 0)       /* 32b */
+/* SPM_BUS_PROTECT1_MASK_B (0x10006000+0x408) */
+#define SPM_BUS_PROTECT1_MASK_B_LSB         (1U << 0)       /* 32b */
+/* SPM_BUS_PROTECT2_MASK_B (0x10006000+0x40C) */
+#define SPM_BUS_PROTECT2_MASK_B_LSB         (1U << 0)       /* 32b */
+/* SPM_BUS_PROTECT3_MASK_B (0x10006000+0x410) */
+#define SPM_BUS_PROTECT3_MASK_B_LSB         (1U << 0)       /* 32b */
+/* SPM_BUS_PROTECT4_MASK_B (0x10006000+0x414) */
+#define SPM_BUS_PROTECT4_MASK_B_LSB         (1U << 0)       /* 32b */
+/* SPM_EMI_BW_MODE (0x10006000+0x418) */
+#define EMI_BW_MODE_LSB                     (1U << 0)       /* 1b */
+#define EMI_BOOST_MODE_LSB                  (1U << 1)       /* 1b */
+#define EMI_BW_MODE_2_LSB                   (1U << 2)       /* 1b */
+#define EMI_BOOST_MODE_2_LSB                (1U << 3)       /* 1b */
+/* AP2MD_PEER_WAKEUP (0x10006000+0x41C) */
+#define AP2MD_PEER_WAKEUP_LSB               (1U << 0)       /* 1b */
+/* ULPOSC_CON (0x10006000+0x420) */
+#define ULPOSC_EN_LSB                       (1U << 0)       /* 1b */
+#define ULPOSC_RST_LSB                      (1U << 1)       /* 1b */
+#define ULPOSC_CG_EN_LSB                    (1U << 2)       /* 1b */
+#define ULPOSC_CLK_SEL_LSB                  (1U << 3)       /* 1b */
+/* SPM2MM_CON (0x10006000+0x424) */
+#define SPM2MM_FORCE_ULTRA_LSB              (1U << 0)       /* 1b */
+#define SPM2MM_DBL_OSTD_ACT_LSB             (1U << 1)       /* 1b */
+#define SPM2MM_ULTRAREQ_LSB                 (1U << 2)       /* 1b */
+#define SPM2MD_ULTRAREQ_LSB                 (1U << 3)       /* 1b */
+#define SPM2ISP_ULTRAREQ_LSB                (1U << 4)       /* 1b */
+#define MM2SPM_FORCE_ULTRA_ACK_D2T_LSB      (1U << 16)      /* 1b */
+#define MM2SPM_DBL_OSTD_ACT_ACK_D2T_LSB     (1U << 17)      /* 1b */
+#define SPM2ISP_ULTRAACK_D2T_LSB            (1U << 18)      /* 1b */
+#define SPM2MM_ULTRAACK_D2T_LSB             (1U << 19)      /* 1b */
+#define SPM2MD_ULTRAACK_D2T_LSB             (1U << 20)      /* 1b */
+/* SPM_BUS_PROTECT5_MASK_B (0x10006000+0x428) */
+#define SPM_BUS_PROTECT5_MASK_B_LSB         (1U << 0)       /* 32b */
+/* SPM2MCUPM_CON (0x10006000+0x42C) */
+#define SPM2MCUPM_SW_RST_B_LSB              (1U << 0)       /* 1b */
+#define SPM2MCUPM_SW_INT_LSB                (1U << 1)       /* 1b */
+/* AP_MDSRC_REQ (0x10006000+0x430) */
+#define AP_MDSMSRC_REQ_LSB                  (1U << 0)       /* 1b */
+#define AP_L1SMSRC_REQ_LSB                  (1U << 1)       /* 1b */
+#define AP_MD2SRC_REQ_LSB                   (1U << 2)       /* 1b */
+#define AP_MDSMSRC_ACK_LSB                  (1U << 4)       /* 1b */
+#define AP_L1SMSRC_ACK_LSB                  (1U << 5)       /* 1b */
+#define AP_MD2SRC_ACK_LSB                   (1U << 6)       /* 1b */
+/* SPM2EMI_ENTER_ULPM (0x10006000+0x434) */
+#define SPM2EMI_ENTER_ULPM_LSB              (1U << 0)       /* 1b */
+/* SPM2MD_DVFS_CON (0x10006000+0x438) */
+#define SPM2MD_DVFS_CON_LSB                 (1U << 0)       /* 32b */
+/* MD2SPM_DVFS_CON (0x10006000+0x43C) */
+#define MD2SPM_DVFS_CON_LSB                 (1U << 0)       /* 32b */
+/* SPM_BUS_PROTECT6_MASK_B (0x10006000+0X440) */
+#define SPM_BUS_PROTECT6_MASK_B_LSB         (1U << 0)       /* 32b */
+/* SPM_BUS_PROTECT7_MASK_B (0x10006000+0x444) */
+#define SPM_BUS_PROTECT7_MASK_B_LSB         (1U << 0)       /* 32b */
+/* SPM_BUS_PROTECT8_MASK_B (0x10006000+0x448) */
+#define SPM_BUS_PROTECT8_MASK_B_LSB         (1U << 0)       /* 32b */
+/* SPM_PLL_CON (0x10006000+0x44C) */
+#define SC_MAINPLLOUT_OFF_LSB               (1U << 0)       /* 1b */
+#define SC_UNIPLLOUT_OFF_LSB                (1U << 1)       /* 1b */
+#define SC_MAINPLL_OFF_LSB                  (1U << 4)       /* 1b */
+#define SC_UNIPLL_OFF_LSB                   (1U << 5)       /* 1b */
+#define SC_MAINPLL_S_OFF_LSB                (1U << 8)       /* 1b */
+#define SC_UNIPLL_S_OFF_LSB                 (1U << 9)       /* 1b */
+#define SC_SMI_CK_OFF_LSB                   (1U << 16)      /* 1b */
+#define SC_MD32K_CK_OFF_LSB                 (1U << 17)      /* 1b */
+#define SC_CKSQ1_OFF_LSB                    (1U << 18)      /* 1b */
+#define SC_AXI_MEM_CK_OFF_LSB               (1U << 19)      /* 1b */
+/* CPU_DVFS_REQ (0x10006000+0x450) */
+#define CPU_DVFS_REQ_LSB                    (1U << 0)       /* 32b */
+/* SPM_DRAM_MCU_SW_CON_0 (0x10006000+0x454) */
+#define SW_DDR_PST_REQ_LSB                  (1U << 0)       /* 2b */
+#define SW_DDR_PST_ABORT_REQ_LSB            (1U << 2)       /* 2b */
+/* SPM_DRAM_MCU_SW_CON_1 (0x10006000+0x458) */
+#define SW_DDR_PST_CH0_LSB                  (1U << 0)       /* 32b */
+/* SPM_DRAM_MCU_SW_CON_2 (0x10006000+0x45C) */
+#define SW_DDR_PST_CH1_LSB                  (1U << 0)       /* 32b */
+/* SPM_DRAM_MCU_SW_CON_3 (0x10006000+0x460) */
+#define SW_DDR_RESERVED_CH0_LSB             (1U << 0)       /* 32b */
+/* SPM_DRAM_MCU_SW_CON_4 (0x10006000+0x464) */
+#define SW_DDR_RESERVED_CH1_LSB             (1U << 0)       /* 32b */
+/* SPM_DRAM_MCU_STA_0 (0x10006000+0x468) */
+#define SC_DDR_PST_ACK_LSB                  (1U << 0)       /* 2b */
+#define SC_DDR_PST_ABORT_ACK_LSB            (1U << 2)       /* 2b */
+/* SPM_DRAM_MCU_STA_1 (0x10006000+0x46C) */
+#define SC_DDR_CUR_PST_STA_CH0_LSB          (1U << 0)       /* 32b */
+/* SPM_DRAM_MCU_STA_2 (0x10006000+0x470) */
+#define SC_DDR_CUR_PST_STA_CH1_LSB          (1U << 0)       /* 32b */
+/* SPM_DRAM_MCU_SW_SEL_0 (0x10006000+0x474) */
+#define SW_DDR_PST_REQ_SEL_LSB              (1U << 0)       /* 2b */
+#define SW_DDR_PST_SEL_LSB                  (1U << 2)       /* 2b */
+#define SW_DDR_PST_ABORT_REQ_SEL_LSB        (1U << 4)       /* 2b */
+#define SW_DDR_RESERVED_SEL_LSB             (1U << 6)       /* 2b */
+#define SW_DDR_PST_ACK_SEL_LSB              (1U << 8)       /* 2b */
+#define SW_DDR_PST_ABORT_ACK_SEL_LSB        (1U << 10)      /* 2b */
+/* RELAY_DVFS_LEVEL (0x10006000+0x478) */
+#define RELAY_DVFS_LEVEL_LSB                (1U << 0)       /* 32b */
+/* DRAMC_DPY_CLK_SW_CON_0 (0x10006000+0x480) */
+#define SW_PHYPLL_EN_LSB                    (1U << 0)       /* 2b */
+#define SW_DPY_VREF_EN_LSB                  (1U << 2)       /* 2b */
+#define SW_DPY_DLL_CK_EN_LSB                (1U << 4)       /* 2b */
+#define SW_DPY_DLL_EN_LSB                   (1U << 6)       /* 2b */
+#define SW_DPY_2ND_DLL_EN_LSB               (1U << 8)       /* 2b */
+#define SW_MEM_CK_OFF_LSB                   (1U << 10)      /* 2b */
+#define SW_DMSUS_OFF_LSB                    (1U << 12)      /* 2b */
+#define SW_DPY_MODE_SW_LSB                  (1U << 14)      /* 2b */
+#define SW_EMI_CLK_OFF_LSB                  (1U << 16)      /* 2b */
+#define SW_DDRPHY_FB_CK_EN_LSB              (1U << 18)      /* 2b */
+#define SW_DR_GATE_RETRY_EN_LSB             (1U << 20)      /* 2b */
+#define SW_DPHY_PRECAL_UP_LSB               (1U << 24)      /* 2b */
+#define SW_DPY_BCLK_ENABLE_LSB              (1U << 26)      /* 2b */
+#define SW_TX_TRACKING_DIS_LSB              (1U << 28)      /* 2b */
+#define SW_DPHY_RXDLY_TRACKING_EN_LSB       (1U << 30)      /* 2b */
+/* DRAMC_DPY_CLK_SW_CON_1 (0x10006000+0x484) */
+#define SW_SHU_RESTORE_LSB                  (1U << 0)       /* 2b */
+#define SW_DMYRD_MOD_LSB                    (1U << 2)       /* 2b */
+#define SW_DMYRD_INTV_LSB                   (1U << 4)       /* 2b */
+#define SW_DMYRD_EN_LSB                     (1U << 6)       /* 2b */
+#define SW_DRS_DIS_REQ_LSB                  (1U << 8)       /* 2b */
+#define SW_DR_SRAM_LOAD_LSB                 (1U << 10)      /* 2b */
+#define SW_DR_SRAM_RESTORE_LSB              (1U << 12)      /* 2b */
+#define SW_DR_SHU_LEVEL_SRAM_LATCH_LSB      (1U << 14)      /* 2b */
+#define SW_TX_TRACK_RETRY_EN_LSB            (1U << 16)      /* 2b */
+#define SW_DPY_MIDPI_EN_LSB                 (1U << 18)      /* 2b */
+#define SW_DPY_PI_RESETB_EN_LSB             (1U << 20)      /* 2b */
+#define SW_DPY_MCK8X_EN_LSB                 (1U << 22)      /* 2b */
+#define SW_DR_SHU_LEVEL_SRAM_CH0_LSB        (1U << 24)      /* 4b */
+#define SW_DR_SHU_LEVEL_SRAM_CH1_LSB        (1U << 28)      /* 4b */
+/* DRAMC_DPY_CLK_SW_CON_2 (0x10006000+0x488) */
+#define SW_DR_SHU_LEVEL_LSB                 (1U << 0)       /* 2b */
+#define SW_DR_SHU_EN_LSB                    (1U << 2)       /* 1b */
+#define SW_DR_SHORT_QUEUE_LSB               (1U << 3)       /* 1b */
+#define SW_PHYPLL_MODE_SW_LSB               (1U << 4)       /* 1b */
+#define SW_PHYPLL2_MODE_SW_LSB              (1U << 5)       /* 1b */
+#define SW_PHYPLL_SHU_EN_LSB                (1U << 6)       /* 1b */
+#define SW_PHYPLL2_SHU_EN_LSB               (1U << 7)       /* 1b */
+#define SW_DR_RESERVED_0_LSB                (1U << 24)      /* 2b */
+#define SW_DR_RESERVED_1_LSB                (1U << 26)      /* 2b */
+#define SW_DR_RESERVED_2_LSB                (1U << 28)      /* 2b */
+#define SW_DR_RESERVED_3_LSB                (1U << 30)      /* 2b */
+/* DRAMC_DPY_CLK_SW_CON_3 (0x10006000+0x48C) */
+#define SC_DR_SHU_EN_ACK_LSB                (1U << 0)       /* 4b */
+#define SC_EMI_CLK_OFF_ACK_LSB              (1U << 4)       /* 4b */
+#define SC_DR_SHORT_QUEUE_ACK_LSB           (1U << 8)       /* 4b */
+#define SC_DRAMC_DFS_STA_LSB                (1U << 12)      /* 4b */
+#define SC_DRS_DIS_ACK_LSB                  (1U << 16)      /* 4b */
+#define SC_DR_SRAM_LOAD_ACK_LSB             (1U << 20)      /* 4b */
+#define SC_DR_SRAM_PLL_LOAD_ACK_LSB         (1U << 24)      /* 4b */
+#define SC_DR_SRAM_RESTORE_ACK_LSB          (1U << 28)      /* 4b */
+/* DRAMC_DPY_CLK_SW_SEL_0 (0x10006000+0x490) */
+#define SW_PHYPLL_EN_SEL_LSB                (1U << 0)       /* 2b */
+#define SW_DPY_VREF_EN_SEL_LSB              (1U << 2)       /* 2b */
+#define SW_DPY_DLL_CK_EN_SEL_LSB            (1U << 4)       /* 2b */
+#define SW_DPY_DLL_EN_SEL_LSB               (1U << 6)       /* 2b */
+#define SW_DPY_2ND_DLL_EN_SEL_LSB           (1U << 8)       /* 2b */
+#define SW_MEM_CK_OFF_SEL_LSB               (1U << 10)      /* 2b */
+#define SW_DMSUS_OFF_SEL_LSB                (1U << 12)      /* 2b */
+#define SW_DPY_MODE_SW_SEL_LSB              (1U << 14)      /* 2b */
+#define SW_EMI_CLK_OFF_SEL_LSB              (1U << 16)      /* 2b */
+#define SW_DDRPHY_FB_CK_EN_SEL_LSB          (1U << 18)      /* 2b */
+#define SW_DR_GATE_RETRY_EN_SEL_LSB         (1U << 20)      /* 2b */
+#define SW_DPHY_PRECAL_UP_SEL_LSB           (1U << 24)      /* 2b */
+#define SW_DPY_BCLK_ENABLE_SEL_LSB          (1U << 26)      /* 2b */
+#define SW_TX_TRACKING_DIS_SEL_LSB          (1U << 28)      /* 2b */
+#define SW_DPHY_RXDLY_TRACKING_EN_SEL_LSB   (1U << 30)      /* 2b */
+/* DRAMC_DPY_CLK_SW_SEL_1 (0x10006000+0x494) */
+#define SW_SHU_RESTORE_SEL_LSB              (1U << 0)       /* 2b */
+#define SW_DMYRD_MOD_SEL_LSB                (1U << 2)       /* 2b */
+#define SW_DMYRD_INTV_SEL_LSB               (1U << 4)       /* 2b */
+#define SW_DMYRD_EN_SEL_LSB                 (1U << 6)       /* 2b */
+#define SW_DRS_DIS_REQ_SEL_LSB              (1U << 8)       /* 2b */
+#define SW_DR_SRAM_LOAD_SEL_LSB             (1U << 10)      /* 2b */
+#define SW_DR_SRAM_RESTORE_SEL_LSB          (1U << 12)      /* 2b */
+#define SW_DR_SHU_LEVEL_SRAM_LATCH_SEL_LSB  (1U << 14)      /* 2b */
+#define SW_TX_TRACK_RETRY_EN_SEL_LSB        (1U << 16)      /* 2b */
+#define SW_DPY_MIDPI_EN_SEL_LSB             (1U << 18)      /* 2b */
+#define SW_DPY_PI_RESETB_EN_SEL_LSB         (1U << 20)      /* 2b */
+#define SW_DPY_MCK8X_EN_SEL_LSB             (1U << 22)      /* 2b */
+#define SW_DR_SHU_LEVEL_SRAM_SEL_LSB        (1U << 24)      /* 2b */
+/* DRAMC_DPY_CLK_SW_SEL_2 (0x10006000+0x498) */
+#define SW_DR_SHU_LEVEL_SEL_LSB             (1U << 0)       /* 1b */
+#define SW_DR_SHU_EN_SEL_LSB                (1U << 2)       /* 1b */
+#define SW_DR_SHORT_QUEUE_SEL_LSB           (1U << 3)       /* 1b */
+#define SW_PHYPLL_MODE_SW_SEL_LSB           (1U << 4)       /* 1b */
+#define SW_PHYPLL2_MODE_SW_SEL_LSB          (1U << 5)       /* 1b */
+#define SW_PHYPLL_SHU_EN_SEL_LSB            (1U << 6)       /* 1b */
+#define SW_PHYPLL2_SHU_EN_SEL_LSB           (1U << 7)       /* 1b */
+#define SW_DR_RESERVED_0_SEL_LSB            (1U << 24)      /* 2b */
+#define SW_DR_RESERVED_1_SEL_LSB            (1U << 26)      /* 2b */
+#define SW_DR_RESERVED_2_SEL_LSB            (1U << 28)      /* 2b */
+#define SW_DR_RESERVED_3_SEL_LSB            (1U << 30)      /* 2b */
+/* DRAMC_DPY_CLK_SW_SEL_3 (0x10006000+0x49C) */
+#define SC_DR_SHU_EN_ACK_SEL_LSB            (1U << 0)       /* 4b */
+#define SC_EMI_CLK_OFF_ACK_SEL_LSB          (1U << 4)       /* 4b */
+#define SC_DR_SHORT_QUEUE_ACK_SEL_LSB       (1U << 8)       /* 4b */
+#define SC_DRAMC_DFS_STA_SEL_LSB            (1U << 12)      /* 4b */
+#define SC_DRS_DIS_ACK_SEL_LSB              (1U << 16)      /* 4b */
+#define SC_DR_SRAM_LOAD_ACK_SEL_LSB         (1U << 20)      /* 4b */
+#define SC_DR_SRAM_PLL_LOAD_ACK_SEL_LSB     (1U << 24)      /* 4b */
+#define SC_DR_SRAM_RESTORE_ACK_SEL_LSB      (1U << 28)      /* 4b */
+/* DRAMC_DPY_CLK_SPM_CON (0x10006000+0x4A0) */
+#define SC_DMYRD_EN_MOD_SEL_PCM_LSB         (1U << 0)       /* 1b */
+#define SC_DMYRD_INTV_SEL_PCM_LSB           (1U << 1)       /* 1b */
+#define SC_DMYRD_EN_PCM_LSB                 (1U << 2)       /* 1b */
+#define SC_DRS_DIS_REQ_PCM_LSB              (1U << 3)       /* 1b */
+#define SC_DR_SHU_LEVEL_SRAM_PCM_LSB        (1U << 4)       /* 4b */
+#define SC_DR_GATE_RETRY_EN_PCM_LSB         (1U << 8)       /* 1b */
+#define SC_DR_SHORT_QUEUE_PCM_LSB           (1U << 9)       /* 1b */
+#define SC_DPY_MIDPI_EN_PCM_LSB             (1U << 10)      /* 1b */
+#define SC_DPY_PI_RESETB_EN_PCM_LSB         (1U << 11)      /* 1b */
+#define SC_DPY_MCK8X_EN_PCM_LSB             (1U << 12)      /* 1b */
+#define SC_DR_RESERVED_0_PCM_LSB            (1U << 13)      /* 1b */
+#define SC_DR_RESERVED_1_PCM_LSB            (1U << 14)      /* 1b */
+#define SC_DR_RESERVED_2_PCM_LSB            (1U << 15)      /* 1b */
+#define SC_DR_RESERVED_3_PCM_LSB            (1U << 16)      /* 1b */
+#define SC_DMDRAMCSHU_ACK_ALL_LSB           (1U << 24)      /* 1b */
+#define SC_EMI_CLK_OFF_ACK_ALL_LSB          (1U << 25)      /* 1b */
+#define SC_DR_SHORT_QUEUE_ACK_ALL_LSB       (1U << 26)      /* 1b */
+#define SC_DRAMC_DFS_STA_ALL_LSB            (1U << 27)      /* 1b */
+#define SC_DRS_DIS_ACK_ALL_LSB              (1U << 28)      /* 1b */
+#define SC_DR_SRAM_LOAD_ACK_ALL_LSB         (1U << 29)      /* 1b */
+#define SC_DR_SRAM_PLL_LOAD_ACK_ALL_LSB     (1U << 30)      /* 1b */
+#define SC_DR_SRAM_RESTORE_ACK_ALL_LSB      (1U << 31)      /* 1b */
+/* SPM_DVFS_LEVEL (0x10006000+0x4A4) */
+#define SPM_DVFS_LEVEL_LSB                  (1U << 0)       /* 32b */
+/* SPM_CIRQ_CON (0x10006000+0x4A8) */
+#define CIRQ_CLK_SEL_LSB                    (1U << 0)       /* 1b */
+/* SPM_DVFS_MISC (0x10006000+0x4AC) */
+#define MSDC_DVFS_REQUEST_LSB               (1U << 0)       /* 1b */
+#define SPM2EMI_SLP_PROT_EN_LSB             (1U << 1)       /* 1b */
+#define SPM_DVFS_FORCE_ENABLE_LSB           (1U << 2)       /* 1b */
+#define FORCE_DVFS_WAKE_LSB                 (1U << 3)       /* 1b */
+#define SPM_DVFSRC_ENABLE_LSB               (1U << 4)       /* 1b */
+#define SPM_DVFS_DONE_LSB                   (1U << 5)       /* 1b */
+#define DVFSRC_IRQ_WAKEUP_EVENT_MASK_LSB    (1U << 6)       /* 1b */
+#define SPM2RC_EVENT_ABORT_LSB              (1U << 7)       /* 1b */
+#define EMI_SLP_IDLE_LSB                    (1U << 14)      /* 1b */
+#define SDIO_READY_TO_SPM_LSB               (1U << 15)      /* 1b */
+/* SPM_VS1_VS2_RC_CON (0x10006000+0x4B0) */
+#define VS1_INIT_LEVEL_LSB                  (1U << 0)       /* 2b */
+#define VS1_INIT_LSB                        (1U << 2)       /* 1b */
+#define VS1_CURR_LEVEL_LSB                  (1U << 3)       /* 2b */
+#define VS1_NEXT_LEVEL_LSB                  (1U << 5)       /* 2b */
+#define VS1_VOTE_LEVEL_LSB                  (1U << 7)       /* 2b */
+#define VS1_TRIGGER_LSB                     (1U << 9)       /* 1b */
+#define VS2_INIT_LEVEL_LSB                  (1U << 10)      /* 3b */
+#define VS2_INIT_LSB                        (1U << 13)      /* 1b */
+#define VS2_CURR_LEVEL_LSB                  (1U << 14)      /* 3b */
+#define VS2_NEXT_LEVEL_LSB                  (1U << 17)      /* 3b */
+#define VS2_VOTE_LEVEL_LSB                  (1U << 20)      /* 3b */
+#define VS2_TRIGGER_LSB                     (1U << 23)      /* 1b */
+#define VS1_FORCE_LSB                       (1U << 24)      /* 1b */
+#define VS2_FORCE_LSB                       (1U << 25)      /* 1b */
+#define VS1_VOTE_LEVEL_FORCE_LSB            (1U << 26)      /* 2b */
+#define VS2_VOTE_LEVEL_FORCE_LSB            (1U << 28)      /* 3b */
+/* RG_MODULE_SW_CG_0_MASK_REQ_0 (0x10006000+0x4B4) */
+#define RG_MODULE_SW_CG_0_MASK_REQ_0_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_0_MASK_REQ_1 (0x10006000+0x4B8) */
+#define RG_MODULE_SW_CG_0_MASK_REQ_1_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_0_MASK_REQ_2 (0x10006000+0x4BC) */
+#define RG_MODULE_SW_CG_0_MASK_REQ_2_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_1_MASK_REQ_0 (0x10006000+0x4C0) */
+#define RG_MODULE_SW_CG_1_MASK_REQ_0_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_1_MASK_REQ_1 (0x10006000+0x4C4) */
+#define RG_MODULE_SW_CG_1_MASK_REQ_1_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_1_MASK_REQ_2 (0x10006000+0x4C8) */
+#define RG_MODULE_SW_CG_1_MASK_REQ_2_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_2_MASK_REQ_0 (0x10006000+0x4CC) */
+#define RG_MODULE_SW_CG_2_MASK_REQ_0_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_2_MASK_REQ_1 (0x10006000+0x4D0) */
+#define RG_MODULE_SW_CG_2_MASK_REQ_1_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_2_MASK_REQ_2 (0x10006000+0x4D4) */
+#define RG_MODULE_SW_CG_2_MASK_REQ_2_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_3_MASK_REQ_0 (0x10006000+0x4D8) */
+#define RG_MODULE_SW_CG_3_MASK_REQ_0_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_3_MASK_REQ_1 (0x10006000+0x4DC) */
+#define RG_MODULE_SW_CG_3_MASK_REQ_1_LSB    (1U << 0)       /* 32b */
+/* RG_MODULE_SW_CG_3_MASK_REQ_2 (0x10006000+0x4E0) */
+#define RG_MODULE_SW_CG_3_MASK_REQ_2_LSB    (1U << 0)       /* 32b */
+/* PWR_STATUS_MASK_REQ_0 (0x10006000+0x4E4) */
+#define PWR_STATUS_MASK_REQ_0_LSB           (1U << 0)       /* 32b */
+/* PWR_STATUS_MASK_REQ_1 (0x10006000+0x4E8) */
+#define PWR_STATUS_MASK_REQ_1_LSB           (1U << 0)       /* 32b */
+/* PWR_STATUS_MASK_REQ_2 (0x10006000+0x4EC) */
+#define PWR_STATUS_MASK_REQ_2_LSB           (1U << 0)       /* 32b */
+/* SPM_CG_CHECK_CON (0x10006000+0x4F0) */
+#define APMIXEDSYS_BUSY_MASK_REQ_0_LSB      (1U << 0)       /* 5b */
+#define APMIXEDSYS_BUSY_MASK_REQ_1_LSB      (1U << 8)       /* 5b */
+#define APMIXEDSYS_BUSY_MASK_REQ_2_LSB      (1U << 16)      /* 5b */
+#define AUDIOSYS_BUSY_MASK_REQ_0_LSB        (1U << 24)      /* 1b */
+#define AUDIOSYS_BUSY_MASK_REQ_1_LSB        (1U << 25)      /* 1b */
+#define AUDIOSYS_BUSY_MASK_REQ_2_LSB        (1U << 26)      /* 1b */
+#define SSUSB_BUSY_MASK_REQ_0_LSB           (1U << 27)      /* 1b */
+#define SSUSB_BUSY_MASK_REQ_1_LSB           (1U << 28)      /* 1b */
+#define SSUSB_BUSY_MASK_REQ_2_LSB           (1U << 29)      /* 1b */
+/* SPM_SRC_RDY_STA (0x10006000+0x4F4) */
+#define SPM_INFRA_INTERNAL_ACK_LSB          (1U << 0)       /* 1b */
+#define SPM_VRF18_INTERNAL_ACK_LSB          (1U << 1)       /* 1b */
+/* SPM_DVS_DFS_LEVEL (0x10006000+0x4F8) */
+#define SPM_DFS_LEVEL_LSB                   (1U << 0)       /* 16b */
+#define SPM_DVS_LEVEL_LSB                   (1U << 16)      /* 16b */
+/* SPM_FORCE_DVFS (0x10006000+0x4FC) */
+#define FORCE_DVFS_LEVEL_LSB                (1U << 0)       /* 32b */
+/* SRCLKEN_RC_CFG (0x10006000+0x500) */
+#define SRCLKEN_RC_CFG_LSB                  (1U << 0)       /* 32b */
+/* RC_CENTRAL_CFG1 (0x10006000+0x504) */
+#define RC_CENTRAL_CFG1_LSB                 (1U << 0)       /* 32b */
+/* RC_CENTRAL_CFG2 (0x10006000+0x508) */
+#define RC_CENTRAL_CFG2_LSB                 (1U << 0)       /* 32b */
+/* RC_CMD_ARB_CFG (0x10006000+0x50C) */
+#define RC_CMD_ARB_CFG_LSB                  (1U << 0)       /* 32b */
+/* RC_PMIC_RCEN_ADDR (0x10006000+0x510) */
+#define RC_PMIC_RCEN_ADDR_LSB               (1U << 0)       /* 16b */
+#define RC_PMIC_RCEN_RESERVE_LSB            (1U << 16)      /* 16b */
+/* RC_PMIC_RCEN_SET_CLR_ADDR (0x10006000+0x514) */
+#define RC_PMIC_RCEN_SET_ADDR_LSB           (1U << 0)       /* 16b */
+#define RC_PMIC_RCEN_CLR_ADDR_LSB           (1U << 16)      /* 16b */
+/* RC_DCXO_FPM_CFG (0x10006000+0x518) */
+#define RC_DCXO_FPM_CFG_LSB                 (1U << 0)       /* 32b */
+/* RC_CENTRAL_CFG3 (0x10006000+0x51C) */
+#define RC_CENTRAL_CFG3_LSB                 (1U << 0)       /* 32b */
+/* RC_M00_SRCLKEN_CFG (0x10006000+0x520) */
+#define RC_M00_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M01_SRCLKEN_CFG (0x10006000+0x524) */
+#define RC_M01_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M02_SRCLKEN_CFG (0x10006000+0x528) */
+#define RC_M02_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M03_SRCLKEN_CFG (0x10006000+0x52C) */
+#define RC_M03_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M04_SRCLKEN_CFG (0x10006000+0x530) */
+#define RC_M04_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M05_SRCLKEN_CFG (0x10006000+0x534) */
+#define RC_M05_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M06_SRCLKEN_CFG (0x10006000+0x538) */
+#define RC_M06_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M07_SRCLKEN_CFG (0x10006000+0x53C) */
+#define RC_M07_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M08_SRCLKEN_CFG (0x10006000+0x540) */
+#define RC_M08_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M09_SRCLKEN_CFG (0x10006000+0x544) */
+#define RC_M09_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M10_SRCLKEN_CFG (0x10006000+0x548) */
+#define RC_M10_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M11_SRCLKEN_CFG (0x10006000+0x54C) */
+#define RC_M11_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_M12_SRCLKEN_CFG (0x10006000+0x550) */
+#define RC_M12_SRCLKEN_CFG_LSB              (1U << 0)       /* 32b */
+/* RC_SRCLKEN_SW_CON_CFG (0x10006000+0x554) */
+#define RC_SRCLKEN_SW_CON_CFG_LSB           (1U << 0)       /* 32b */
+/* RC_CENTRAL_CFG4 (0x10006000+0x558) */
+#define RC_CENTRAL_CFG4_LSB                 (1U << 0)       /* 32b */
+/* RC_PROTOCOL_CHK_CFG (0x10006000+0x560) */
+#define RC_PROTOCOL_CHK_CFG_LSB             (1U << 0)       /* 32b */
+/* RC_DEBUG_CFG (0x10006000+0x564) */
+#define RC_DEBUG_CFG_LSB                    (1U << 0)       /* 32b */
+/* RC_MISC_0 (0x10006000+0x5B4) */
+#define SRCCLKENO_LSB                       (1U << 0)       /* 2b */
+#define PCM_SRCCLKENO_LSB                   (1U << 3)       /* 2b */
+#define RC_VREQ_LSB                         (1U << 5)       /* 1b */
+#define RC_SPM_SRCCLKENO_0_ACK_LSB          (1U << 6)       /* 1b */
+/* RC_SPM_CTRL (0x10006000+0x448) */
+#define SPM_AP_26M_RDY_LSB                  (1U << 0)       /* 1b */
+#define KEEP_RC_SPI_ACTIVE_LSB              (1U << 1)       /* 1b */
+#define SPM2RC_DMY_CTRL_LSB                 (1U << 2)       /* 6b */
+/* SUBSYS_INTF_CFG (0x10006000+0x5BC) */
+#define SRCLKEN_FPM_MASK_B_LSB              (1U << 0)       /* 13b */
+#define SRCLKEN_BBLPM_MASK_B_LSB            (1U << 16)      /* 13b */
+/* PCM_WDT_LATCH_25 (0x10006000+0x5C0) */
+#define PCM_WDT_LATCH_25_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_26 (0x10006000+0x5C4) */
+#define PCM_WDT_LATCH_26_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_27 (0x10006000+0x5C8) */
+#define PCM_WDT_LATCH_27_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_28 (0x10006000+0x5CC) */
+#define PCM_WDT_LATCH_28_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_29 (0x10006000+0x5D0) */
+#define PCM_WDT_LATCH_29_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_30 (0x10006000+0x5D4) */
+#define PCM_WDT_LATCH_30_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_31 (0x10006000+0x5D8) */
+#define PCM_WDT_LATCH_31_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_32 (0x10006000+0x5DC) */
+#define PCM_WDT_LATCH_32_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_33 (0x10006000+0x5E0) */
+#define PCM_WDT_LATCH_33_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_34 (0x10006000+0x5E4) */
+#define PCM_WDT_LATCH_34_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_35 (0x10006000+0x5EC) */
+#define PCM_WDT_LATCH_35_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_36 (0x10006000+0x5F0) */
+#define PCM_WDT_LATCH_36_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_37 (0x10006000+0x5F4) */
+#define PCM_WDT_LATCH_37_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_38 (0x10006000+0x5F8) */
+#define PCM_WDT_LATCH_38_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_39 (0x10006000+0x5FC) */
+#define PCM_WDT_LATCH_39_LSB                (1U << 0)       /* 32b */
+/* SPM_SW_FLAG_0 (0x10006000+0x600) */
+#define SPM_SW_FLAG_LSB                     (1U << 0)       /* 32b */
+/* SPM_SW_DEBUG_0 (0x10006000+0x604) */
+#define SPM_SW_DEBUG_0_LSB                  (1U << 0)       /* 32b */
+/* SPM_SW_FLAG_1 (0x10006000+0x608) */
+#define SPM_SW_FLAG_1_LSB                   (1U << 0)       /* 32b */
+/* SPM_SW_DEBUG_1 (0x10006000+0x60C) */
+#define SPM_SW_DEBUG_1_LSB                  (1U << 0)       /* 32b */
+/* SPM_SW_RSV_0 (0x10006000+0x610) */
+#define SPM_SW_RSV_0_LSB                    (1U << 0)       /* 32b */
+/* SPM_SW_RSV_1 (0x10006000+0x614) */
+#define SPM_SW_RSV_1_LSB                    (1U << 0)       /* 32b */
+/* SPM_SW_RSV_2 (0x10006000+0x618) */
+#define SPM_SW_RSV_2_LSB                    (1U << 0)       /* 32b */
+/* SPM_SW_RSV_3 (0x10006000+0x61C) */
+#define SPM_SW_RSV_3_LSB                    (1U << 0)       /* 32b */
+/* SPM_SW_RSV_4 (0x10006000+0x620) */
+#define SPM_SW_RSV_4_LSB                    (1U << 0)       /* 32b */
+/* SPM_SW_RSV_5 (0x10006000+0x624) */
+#define SPM_SW_RSV_5_LSB                    (1U << 0)       /* 32b */
+/* SPM_SW_RSV_6 (0x10006000+0x628) */
+#define SPM_SW_RSV_6_LSB                    (1U << 0)       /* 32b */
+/* SPM_SW_RSV_7 (0x10006000+0x62C) */
+#define SPM_SW_RSV_7_LSB                    (1U << 0)       /* 32b */
+/* SPM_SW_RSV_8 (0x10006000+0x630) */
+#define SPM_SW_RSV_8_LSB                    (1U << 0)       /* 32b */
+/* SPM_BK_WAKE_EVENT (0x10006000+0x634) */
+#define SPM_BK_WAKE_EVENT_LSB               (1U << 0)       /* 32b */
+/* SPM_BK_VTCXO_DUR (0x10006000+0x638) */
+#define SPM_BK_VTCXO_DUR_LSB                (1U << 0)       /* 32b */
+/* SPM_BK_WAKE_MISC (0x10006000+0x63C) */
+#define SPM_BK_WAKE_MISC_LSB                (1U << 0)       /* 32b */
+/* SPM_BK_PCM_TIMER (0x10006000+0x640) */
+#define SPM_BK_PCM_TIMER_LSB                (1U << 0)       /* 32b */
+/* SPM_RSV_CON_0 (0x10006000+0x650) */
+#define SPM_RSV_CON_0_LSB                   (1U << 0)       /* 32b */
+/* SPM_RSV_CON_1 (0x10006000+0x654) */
+#define SPM_RSV_CON_1_LSB                   (1U << 0)       /* 32b */
+/* SPM_RSV_STA_0 (0x10006000+0x658) */
+#define SPM_RSV_STA_0_LSB                   (1U << 0)       /* 32b */
+/* SPM_RSV_STA_1 (0x10006000+0x65C) */
+#define SPM_RSV_STA_1_LSB                   (1U << 0)       /* 32b */
+/* SPM_SPARE_CON (0x10006000+0x660) */
+#define SPM_SPARE_CON_LSB                   (1U << 0)       /* 32b */
+/* SPM_SPARE_CON_SET (0x10006000+0x664) */
+#define SPM_SPARE_CON_SET_LSB               (1U << 0)       /* 32b */
+/* SPM_SPARE_CON_CLR (0x10006000+0x668) */
+#define SPM_SPARE_CON_CLR_LSB               (1U << 0)       /* 32b */
+/* SPM_CROSS_WAKE_M00_REQ (0x10006000+0x66C) */
+#define SPM_CROSS_WAKE_M00_REQ_LSB          (1U << 0)       /* 4b */
+#define SPM_CROSS_WAKE_M00_CHK_LSB          (1U << 4)       /* 4b */
+/* SPM_CROSS_WAKE_M01_REQ (0x10006000+0x670) */
+#define SPM_CROSS_WAKE_M01_REQ_LSB          (1U << 0)       /* 4b */
+#define SPM_CROSS_WAKE_M01_CHK_LSB          (1U << 4)       /* 4b */
+/* SPM_CROSS_WAKE_M02_REQ (0x10006000+0x674) */
+#define SPM_CROSS_WAKE_M02_REQ_LSB          (1U << 0)       /* 4b */
+#define SPM_CROSS_WAKE_M02_CHK_LSB          (1U << 4)       /* 4b */
+/* SPM_CROSS_WAKE_M03_REQ (0x10006000+0x678) */
+#define SPM_CROSS_WAKE_M03_REQ_LSB          (1U << 0)       /* 4b */
+#define SPM_CROSS_WAKE_M03_CHK_LSB          (1U << 4)       /* 4b */
+/* SCP_VCORE_LEVEL (0x10006000+0x67C) */
+#define SCP_VCORE_LEVEL_LSB                 (1U << 0)       /* 16b */
+/* SC_MM_CK_SEL_CON (0x10006000+0x680) */
+#define SC_MM_CK_SEL_LSB                    (1U << 0)       /* 4b */
+#define SC_MM_CK_SEL_EN_LSB                 (1U << 4)       /* 1b */
+/* SPARE_ACK_MASK (0x10006000+0x684) */
+#define SPARE_ACK_MASK_B_LSB                (1U << 0)       /* 32b */
+/* SPM_DV_CON_0 (0x10006000+0x68C) */
+#define SPM_DV_CON_0_LSB                    (1U << 0)       /* 32b */
+/* SPM_DV_CON_1 (0x10006000+0x690) */
+#define SPM_DV_CON_1_LSB                    (1U << 0)       /* 32b */
+/* SPM_DV_STA (0x10006000+0x694) */
+#define SPM_DV_STA_LSB                      (1U << 0)       /* 32b */
+/* CONN_XOWCN_DEBUG_EN (0x10006000+0x698) */
+#define CONN_XOWCN_DEBUG_EN_LSB             (1U << 0)       /* 1b */
+/* SPM_SEMA_M0 (0x10006000+0x69C) */
+#define SPM_SEMA_M0_LSB                     (1U << 0)       /* 8b */
+/* SPM_SEMA_M1 (0x10006000+0x6A0) */
+#define SPM_SEMA_M1_LSB                     (1U << 0)       /* 8b */
+/* SPM_SEMA_M2 (0x10006000+0x6A4) */
+#define SPM_SEMA_M2_LSB                     (1U << 0)       /* 8b */
+/* SPM_SEMA_M3 (0x10006000+0x6A8) */
+#define SPM_SEMA_M3_LSB                     (1U << 0)       /* 8b */
+/* SPM_SEMA_M4 (0x10006000+0x6AC) */
+#define SPM_SEMA_M4_LSB                     (1U << 0)       /* 8b */
+/* SPM_SEMA_M5 (0x10006000+0x6B0) */
+#define SPM_SEMA_M5_LSB                     (1U << 0)       /* 8b */
+/* SPM_SEMA_M6 (0x10006000+0x6B4) */
+#define SPM_SEMA_M6_LSB                     (1U << 0)       /* 8b */
+/* SPM_SEMA_M7 (0x10006000+0x6B8) */
+#define SPM_SEMA_M7_LSB                     (1U << 0)       /* 8b */
+/* SPM2ADSP_MAILBOX (0x10006000+0x6BC) */
+#define SPM2ADSP_MAILBOX_LSB                (1U << 0)       /* 32b */
+/* ADSP2SPM_MAILBOX (0x10006000+0x6C0) */
+#define ADSP2SPM_MAILBOX_LSB                (1U << 0)       /* 32b */
+/* SPM_ADSP_IRQ (0x10006000+0x6C4) */
+#define SC_SPM2ADSP_WAKEUP_LSB              (1U << 0)       /* 1b */
+#define SPM_ADSP_IRQ_SC_ADSP2SPM_WAKEUP_LSB (1U << 4)       /* 1b */
+/* SPM_MD32_IRQ (0x10006000+0x6C8) */
+#define SC_SPM2SSPM_WAKEUP_LSB              (1U << 0)       /* 4b */
+#define SPM_MD32_IRQ_SC_SSPM2SPM_WAKEUP_LSB (1U << 4)       /* 4b */
+/* SPM2PMCU_MAILBOX_0 (0x10006000+0x6CC) */
+#define SPM2PMCU_MAILBOX_0_LSB              (1U << 0)       /* 32b */
+/* SPM2PMCU_MAILBOX_1 (0x10006000+0x6D0) */
+#define SPM2PMCU_MAILBOX_1_LSB              (1U << 0)       /* 32b */
+/* SPM2PMCU_MAILBOX_2 (0x10006000+0x6D4) */
+#define SPM2PMCU_MAILBOX_2_LSB              (1U << 0)       /* 32b */
+/* SPM2PMCU_MAILBOX_3 (0x10006000+0x6D8) */
+#define SPM2PMCU_MAILBOX_3_LSB              (1U << 0)       /* 32b */
+/* PMCU2SPM_MAILBOX_0 (0x10006000+0x6DC) */
+#define PMCU2SPM_MAILBOX_0_LSB              (1U << 0)       /* 32b */
+/* PMCU2SPM_MAILBOX_1 (0x10006000+0x6E0) */
+#define PMCU2SPM_MAILBOX_1_LSB              (1U << 0)       /* 32b */
+/* PMCU2SPM_MAILBOX_2 (0x10006000+0x6E4) */
+#define PMCU2SPM_MAILBOX_2_LSB              (1U << 0)       /* 32b */
+/* PMCU2SPM_MAILBOX_3 (0x10006000+0x6E8) */
+#define PMCU2SPM_MAILBOX_3_LSB              (1U << 0)       /* 32b */
+/* UFS_PSRI_SW (0x10006000+0x6EC) */
+#define UFS_PSRI_SW_LSB                     (1U << 0)       /* 1b */
+/* UFS_PSRI_SW_SET (0x10006000+0x6F0) */
+#define UFS_PSRI_SW_SET_LSB                 (1U << 0)       /* 1b */
+/* UFS_PSRI_SW_CLR (0x10006000+0x6F4) */
+#define UFS_PSRI_SW_CLR_LSB                 (1U << 0)       /* 1b */
+/* SPM_AP_SEMA (0x10006000+0x6F8) */
+#define SPM_AP_SEMA_LSB                     (1U << 0)       /* 1b */
+/* SPM_SPM_SEMA (0x10006000+0x6FC) */
+#define SPM_SPM_SEMA_LSB                    (1U << 0)       /* 1b */
+/* SPM_DVFS_CON (0x10006000+0x700) */
+#define SPM_DVFS_CON_LSB                    (1U << 0)       /* 32b */
+/* SPM_DVFS_CON_STA (0x10006000+0x704) */
+#define SPM_DVFS_CON_STA_LSB                (1U << 0)       /* 32b */
+/* SPM_PMIC_SPMI_CON (0x10006000+0x708) */
+#define SPM_PMIC_SPMI_CMD_LSB               (1U << 0)       /* 2b */
+#define SPM_PMIC_SPMI_SLAVEID_LSB           (1U << 2)       /* 4b */
+#define SPM_PMIC_SPMI_PMIFID_LSB            (1U << 6)       /* 1b */
+#define SPM_PMIC_SPMI_DBCNT_LSB             (1U << 7)       /* 1b */
+/* SPM_DVFS_CMD0 (0x10006000+0x710) */
+#define SPM_DVFS_CMD0_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD1 (0x10006000+0x714) */
+#define SPM_DVFS_CMD1_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD2 (0x10006000+0x718) */
+#define SPM_DVFS_CMD2_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD3 (0x10006000+0x71C) */
+#define SPM_DVFS_CMD3_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD4 (0x10006000+0x720) */
+#define SPM_DVFS_CMD4_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD5 (0x10006000+0x724) */
+#define SPM_DVFS_CMD5_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD6 (0x10006000+0x728) */
+#define SPM_DVFS_CMD6_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD7 (0x10006000+0x72C) */
+#define SPM_DVFS_CMD7_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD8 (0x10006000+0x730) */
+#define SPM_DVFS_CMD8_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD9 (0x10006000+0x734) */
+#define SPM_DVFS_CMD9_LSB                   (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD10 (0x10006000+0x738) */
+#define SPM_DVFS_CMD10_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD11 (0x10006000+0x73C) */
+#define SPM_DVFS_CMD11_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD12 (0x10006000+0x740) */
+#define SPM_DVFS_CMD12_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD13 (0x10006000+0x744) */
+#define SPM_DVFS_CMD13_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD14 (0x10006000+0x748) */
+#define SPM_DVFS_CMD14_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD15 (0x10006000+0x74C) */
+#define SPM_DVFS_CMD15_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD16 (0x10006000+0x750) */
+#define SPM_DVFS_CMD16_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD17 (0x10006000+0x754) */
+#define SPM_DVFS_CMD17_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD18 (0x10006000+0x758) */
+#define SPM_DVFS_CMD18_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD19 (0x10006000+0x75C) */
+#define SPM_DVFS_CMD19_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD20 (0x10006000+0x760) */
+#define SPM_DVFS_CMD20_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD21 (0x10006000+0x764) */
+#define SPM_DVFS_CMD21_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD22 (0x10006000+0x768) */
+#define SPM_DVFS_CMD22_LSB                  (1U << 0)       /* 32b */
+/* SPM_DVFS_CMD23 (0x10006000+0x76C) */
+#define SPM_DVFS_CMD23_LSB                  (1U << 0)       /* 32b */
+/* SYS_TIMER_VALUE_L (0x10006000+0x770) */
+#define SYS_TIMER_VALUE_L_LSB               (1U << 0)       /* 32b */
+/* SYS_TIMER_VALUE_H (0x10006000+0x774) */
+#define SYS_TIMER_VALUE_H_LSB               (1U << 0)       /* 32b */
+/* SYS_TIMER_START_L (0x10006000+0x778) */
+#define SYS_TIMER_START_L_LSB               (1U << 0)       /* 32b */
+/* SYS_TIMER_START_H (0x10006000+0x77C) */
+#define SYS_TIMER_START_H_LSB               (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_00 (0x10006000+0x780) */
+#define SYS_TIMER_LATCH_L_00_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_00 (0x10006000+0x784) */
+#define SYS_TIMER_LATCH_H_00_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_01 (0x10006000+0x788) */
+#define SYS_TIMER_LATCH_L_01_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_01 (0x10006000+0x78C) */
+#define SYS_TIMER_LATCH_H_01_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_02 (0x10006000+0x790) */
+#define SYS_TIMER_LATCH_L_02_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_02 (0x10006000+0x794) */
+#define SYS_TIMER_LATCH_H_02_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_03 (0x10006000+0x798) */
+#define SYS_TIMER_LATCH_L_03_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_03 (0x10006000+0x79C) */
+#define SYS_TIMER_LATCH_H_03_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_04 (0x10006000+0x7A0) */
+#define SYS_TIMER_LATCH_L_04_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_04 (0x10006000+0x7A4) */
+#define SYS_TIMER_LATCH_H_04_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_05 (0x10006000+0x7A8) */
+#define SYS_TIMER_LATCH_L_05_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_05 (0x10006000+0x7AC) */
+#define SYS_TIMER_LATCH_H_05_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_06 (0x10006000+0x7B0) */
+#define SYS_TIMER_LATCH_L_06_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_06 (0x10006000+0x7B4) */
+#define SYS_TIMER_LATCH_H_06_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_07 (0x10006000+0x7B8) */
+#define SYS_TIMER_LATCH_L_07_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_07 (0x10006000+0x7BC) */
+#define SYS_TIMER_LATCH_H_07_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_08 (0x10006000+0x7C0) */
+#define SYS_TIMER_LATCH_L_08_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_08 (0x10006000+0x7C4) */
+#define SYS_TIMER_LATCH_H_08_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_09 (0x10006000+0x7C8) */
+#define SYS_TIMER_LATCH_L_09_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_09 (0x10006000+0x7CC) */
+#define SYS_TIMER_LATCH_H_09_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_10 (0x10006000+0x7D0) */
+#define SYS_TIMER_LATCH_L_10_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_10 (0x10006000+0x7D4) */
+#define SYS_TIMER_LATCH_H_10_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_11 (0x10006000+0x7D8) */
+#define SYS_TIMER_LATCH_L_11_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_11 (0x10006000+0x7DC) */
+#define SYS_TIMER_LATCH_H_11_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_12 (0x10006000+0x7E0) */
+#define SYS_TIMER_LATCH_L_12_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_12 (0x10006000+0x7E4) */
+#define SYS_TIMER_LATCH_H_12_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_13 (0x10006000+0x7E8) */
+#define SYS_TIMER_LATCH_L_13_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_13 (0x10006000+0x7EC) */
+#define SYS_TIMER_LATCH_H_13_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_14 (0x10006000+0x7F0) */
+#define SYS_TIMER_LATCH_L_14_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_14 (0x10006000+0x7F4) */
+#define SYS_TIMER_LATCH_H_14_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_L_15 (0x10006000+0x7F8) */
+#define SYS_TIMER_LATCH_L_15_LSB            (1U << 0)       /* 32b */
+/* SYS_TIMER_LATCH_H_15 (0x10006000+0x7FC) */
+#define SYS_TIMER_LATCH_H_15_LSB            (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_0 (0x10006000+0x800) */
+#define PCM_WDT_LATCH_0_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_1 (0x10006000+0x804) */
+#define PCM_WDT_LATCH_1_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_2 (0x10006000+0x808) */
+#define PCM_WDT_LATCH_2_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_3 (0x10006000+0x80C) */
+#define PCM_WDT_LATCH_3_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_4 (0x10006000+0x810) */
+#define PCM_WDT_LATCH_4_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_5 (0x10006000+0x814) */
+#define PCM_WDT_LATCH_5_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_6 (0x10006000+0x818) */
+#define PCM_WDT_LATCH_6_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_7 (0x10006000+0x81C) */
+#define PCM_WDT_LATCH_7_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_8 (0x10006000+0x820) */
+#define PCM_WDT_LATCH_8_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_9 (0x10006000+0x824) */
+#define PCM_WDT_LATCH_9_LSB                 (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_10 (0x10006000+0x828) */
+#define PCM_WDT_LATCH_10_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_11 (0x10006000+0x82C) */
+#define PCM_WDT_LATCH_11_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_12 (0x10006000+0x830) */
+#define PCM_WDT_LATCH_12_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_13 (0x10006000+0x834) */
+#define PCM_WDT_LATCH_13_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_14 (0x10006000+0x838) */
+#define PCM_WDT_LATCH_14_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_15 (0x10006000+0x83C) */
+#define PCM_WDT_LATCH_15_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_16 (0x10006000+0x840) */
+#define PCM_WDT_LATCH_16_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_17 (0x10006000+0x844) */
+#define PCM_WDT_LATCH_17_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_18 (0x10006000+0x848) */
+#define PCM_WDT_LATCH_18_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_SPARE_0 (0x10006000+0x84C) */
+#define PCM_WDT_LATCH_SPARE_0_LSB           (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_SPARE_1 (0x10006000+0x850) */
+#define PCM_WDT_LATCH_SPARE_1_LSB           (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_SPARE_2 (0x10006000+0x854) */
+#define PCM_WDT_LATCH_SPARE_2_LSB           (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_CONN_0 (0x10006000+0x870) */
+#define PCM_WDT_LATCH_CONN_0_LSB            (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_CONN_1 (0x10006000+0x874) */
+#define PCM_WDT_LATCH_CONN_1_LSB            (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_CONN_2 (0x10006000+0x878) */
+#define PCM_WDT_LATCH_CONN_2_LSB            (1U << 0)       /* 32b */
+/* DRAMC_GATING_ERR_LATCH_CH0_0 (0x10006000+0x8A0) */
+#define DRAMC_GATING_ERR_LATCH_CH0_0_LSB    (1U << 0)       /* 32b */
+/* DRAMC_GATING_ERR_LATCH_CH0_1 (0x10006000+0x8A4) */
+#define DRAMC_GATING_ERR_LATCH_CH0_1_LSB    (1U << 0)       /* 32b */
+/* DRAMC_GATING_ERR_LATCH_CH0_2 (0x10006000+0x8A8) */
+#define DRAMC_GATING_ERR_LATCH_CH0_2_LSB    (1U << 0)       /* 32b */
+/* DRAMC_GATING_ERR_LATCH_CH0_3 (0x10006000+0x8AC) */
+#define DRAMC_GATING_ERR_LATCH_CH0_3_LSB    (1U << 0)       /* 32b */
+/* DRAMC_GATING_ERR_LATCH_CH0_4 (0x10006000+0x8B0) */
+#define DRAMC_GATING_ERR_LATCH_CH0_4_LSB    (1U << 0)       /* 32b */
+/* DRAMC_GATING_ERR_LATCH_CH0_5 (0x10006000+0x8B4) */
+#define DRAMC_GATING_ERR_LATCH_CH0_5_LSB    (1U << 0)       /* 32b */
+/* DRAMC_GATING_ERR_LATCH_CH0_6 (0x10006000+0x8B8) */
+#define DRAMC_GATING_ERR_LATCH_CH0_6_LSB    (1U << 0)       /* 32b */
+/* DRAMC_GATING_ERR_LATCH_SPARE_0 (0x10006000+0x8F4) */
+#define DRAMC_GATING_ERR_LATCH_SPARE_0_LSB  (1U << 0)       /* 32b */
+/* SPM_ACK_CHK_CON_0 (0x10006000+0x900) */
+#define SPM_ACK_CHK_SW_EN_0_LSB             (1U << 0)       /* 1b */
+#define SPM_ACK_CHK_CLR_ALL_0_LSB           (1U << 1)       /* 1b */
+#define SPM_ACK_CHK_CLR_TIMER_0_LSB         (1U << 2)       /* 1b */
+#define SPM_ACK_CHK_CLR_IRQ_0_LSB           (1U << 3)       /* 1b */
+#define SPM_ACK_CHK_STA_EN_0_LSB            (1U << 4)       /* 1b */
+#define SPM_ACK_CHK_WAKEUP_EN_0_LSB         (1U << 5)       /* 1b */
+#define SPM_ACK_CHK_WDT_EN_0_LSB            (1U << 6)       /* 1b */
+#define SPM_ACK_CHK_LOCK_PC_TRACE_EN_0_LSB  (1U << 7)       /* 1b */
+#define SPM_ACK_CHK_HW_EN_0_LSB             (1U << 8)       /* 1b */
+#define SPM_ACK_CHK_HW_MODE_0_LSB           (1U << 9)       /* 3b */
+#define SPM_ACK_CHK_FAIL_0_LSB              (1U << 15)      /* 1b */
+/* SPM_ACK_CHK_PC_0 (0x10006000+0x904) */
+#define SPM_ACK_CHK_HW_TRIG_PC_VAL_0_LSB    (1U << 0)       /* 16b */
+#define SPM_ACK_CHK_HW_TARG_PC_VAL_0_LSB    (1U << 16)      /* 16b */
+/* SPM_ACK_CHK_SEL_0 (0x10006000+0x908) */
+#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL_0_LSB (1U << 0)       /* 5b */
+#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL_0_LSB (1U << 5)       /* 3b */
+#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL_0_LSB (1U << 16)      /* 5b */
+#define SPM_ACK_CHK_HW_TARG_GROUP_SEL_0_LSB (1U << 21)      /* 3b */
+/* SPM_ACK_CHK_TIMER_0 (0x10006000+0x90C) */
+#define SPM_ACK_CHK_TIMER_VAL_0_LSB         (1U << 0)       /* 16b */
+#define SPM_ACK_CHK_TIMER_0_LSB             (1U << 16)      /* 16b */
+/* SPM_ACK_CHK_STA_0 (0x10006000+0x910) */
+#define SPM_ACK_CHK_STA_0_LSB               (1U << 0)       /* 32b */
+/* SPM_ACK_CHK_SWINT_0 (0x10006000+0x914) */
+#define SPM_ACK_CHK_SWINT_EN_0_LSB          (1U << 0)       /* 32b */
+/* SPM_ACK_CHK_CON_1 (0x10006000+0x920) */
+#define SPM_ACK_CHK_SW_EN_1_LSB             (1U << 0)       /* 1b */
+#define SPM_ACK_CHK_CLR_ALL_1_LSB           (1U << 1)       /* 1b */
+#define SPM_ACK_CHK_CLR_TIMER_1_LSB         (1U << 2)       /* 1b */
+#define SPM_ACK_CHK_CLR_IRQ_1_LSB           (1U << 3)       /* 1b */
+#define SPM_ACK_CHK_STA_EN_1_LSB            (1U << 4)       /* 1b */
+#define SPM_ACK_CHK_WAKEUP_EN_1_LSB         (1U << 5)       /* 1b */
+#define SPM_ACK_CHK_WDT_EN_1_LSB            (1U << 6)       /* 1b */
+#define SPM_ACK_CHK_LOCK_PC_TRACE_EN_1_LSB  (1U << 7)       /* 1b */
+#define SPM_ACK_CHK_HW_EN_1_LSB             (1U << 8)       /* 1b */
+#define SPM_ACK_CHK_HW_MODE_1_LSB           (1U << 9)       /* 3b */
+#define SPM_ACK_CHK_FAIL_1_LSB              (1U << 15)      /* 1b */
+/* SPM_ACK_CHK_PC_1 (0x10006000+0x924) */
+#define SPM_ACK_CHK_HW_TRIG_PC_VAL_1_LSB    (1U << 0)       /* 16b */
+#define SPM_ACK_CHK_HW_TARG_PC_VAL_1_LSB    (1U << 16)      /* 16b */
+/* SPM_ACK_CHK_SEL_1 (0x10006000+0x928) */
+#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL_1_LSB (1U << 0)       /* 5b */
+#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL_1_LSB (1U << 5)       /* 3b */
+#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL_1_LSB (1U << 16)      /* 5b */
+#define SPM_ACK_CHK_HW_TARG_GROUP_SEL_1_LSB (1U << 21)      /* 3b */
+/* SPM_ACK_CHK_TIMER_1 (0x10006000+0x92C) */
+#define SPM_ACK_CHK_TIMER_VAL_1_LSB         (1U << 0)       /* 16b */
+#define SPM_ACK_CHK_TIMER_1_LSB             (1U << 16)      /* 16b */
+/* SPM_ACK_CHK_STA_1 (0x10006000+0x930) */
+#define SPM_ACK_CHK_STA_1_LSB               (1U << 0)       /* 32b */
+/* SPM_ACK_CHK_SWINT_1 (0x10006000+0x934) */
+#define SPM_ACK_CHK_SWINT_EN_1_LSB          (1U << 0)       /* 32b */
+/* SPM_ACK_CHK_CON_2 (0x10006000+0x940) */
+#define SPM_ACK_CHK_SW_EN_2_LSB             (1U << 0)       /* 1b */
+#define SPM_ACK_CHK_CLR_ALL_2_LSB           (1U << 1)       /* 1b */
+#define SPM_ACK_CHK_CLR_TIMER_2_LSB         (1U << 2)       /* 1b */
+#define SPM_ACK_CHK_CLR_IRQ_2_LSB           (1U << 3)       /* 1b */
+#define SPM_ACK_CHK_STA_EN_2_LSB            (1U << 4)       /* 1b */
+#define SPM_ACK_CHK_WAKEUP_EN_2_LSB         (1U << 5)       /* 1b */
+#define SPM_ACK_CHK_WDT_EN_2_LSB            (1U << 6)       /* 1b */
+#define SPM_ACK_CHK_LOCK_PC_TRACE_EN_2_LSB  (1U << 7)       /* 1b */
+#define SPM_ACK_CHK_HW_EN_2_LSB             (1U << 8)       /* 1b */
+#define SPM_ACK_CHK_HW_MODE_2_LSB           (1U << 9)       /* 3b */
+#define SPM_ACK_CHK_FAIL_2_LSB              (1U << 15)      /* 1b */
+/* SPM_ACK_CHK_PC_2 (0x10006000+0x944) */
+#define SPM_ACK_CHK_HW_TRIG_PC_VAL_2_LSB    (1U << 0)       /* 16b */
+#define SPM_ACK_CHK_HW_TARG_PC_VAL_2_LSB    (1U << 16)      /* 16b */
+/* SPM_ACK_CHK_SEL_2 (0x10006000+0x948) */
+#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL_2_LSB (1U << 0)       /* 5b */
+#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL_2_LSB (1U << 5)       /* 3b */
+#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL_2_LSB (1U << 16)      /* 5b */
+#define SPM_ACK_CHK_HW_TARG_GROUP_SEL_2_LSB (1U << 21)      /* 3b */
+/* SPM_ACK_CHK_TIMER_2 (0x10006000+0x94C) */
+#define SPM_ACK_CHK_TIMER_VAL_2_LSB         (1U << 0)       /* 16b */
+#define SPM_ACK_CHK_TIMER_2_LSB             (1U << 16)      /* 16b */
+/* SPM_ACK_CHK_STA_2 (0x10006000+0x950) */
+#define SPM_ACK_CHK_STA_2_LSB               (1U << 0)       /* 32b */
+/* SPM_ACK_CHK_SWINT_2 (0x10006000+0x954) */
+#define SPM_ACK_CHK_SWINT_EN_2_LSB          (1U << 0)       /* 32b */
+/* SPM_ACK_CHK_CON_3 (0x10006000+0x960) */
+#define SPM_ACK_CHK_SW_EN_3_LSB             (1U << 0)       /* 1b */
+#define SPM_ACK_CHK_CLR_ALL_3_LSB           (1U << 1)       /* 1b */
+#define SPM_ACK_CHK_CLR_TIMER_3_LSB         (1U << 2)       /* 1b */
+#define SPM_ACK_CHK_CLR_IRQ_3_LSB           (1U << 3)       /* 1b */
+#define SPM_ACK_CHK_STA_EN_3_LSB            (1U << 4)       /* 1b */
+#define SPM_ACK_CHK_WAKEUP_EN_3_LSB         (1U << 5)       /* 1b */
+#define SPM_ACK_CHK_WDT_EN_3_LSB            (1U << 6)       /* 1b */
+#define SPM_ACK_CHK_LOCK_PC_TRACE_EN_3_LSB  (1U << 7)       /* 1b */
+#define SPM_ACK_CHK_HW_EN_3_LSB             (1U << 8)       /* 1b */
+#define SPM_ACK_CHK_HW_MODE_3_LSB           (1U << 9)       /* 3b */
+#define SPM_ACK_CHK_FAIL_3_LSB              (1U << 15)      /* 1b */
+/* SPM_ACK_CHK_PC_3 (0x10006000+0x964) */
+#define SPM_ACK_CHK_HW_TRIG_PC_VAL_3_LSB    (1U << 0)       /* 16b */
+#define SPM_ACK_CHK_HW_TARG_PC_VAL_3_LSB    (1U << 16)      /* 16b */
+/* SPM_ACK_CHK_SEL_3 (0x10006000+0x968) */
+#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL_3_LSB (1U << 0)       /* 5b */
+#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL_3_LSB (1U << 5)       /* 3b */
+#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL_3_LSB (1U << 16)      /* 5b */
+#define SPM_ACK_CHK_HW_TARG_GROUP_SEL_3_LSB (1U << 21)      /* 3b */
+/* SPM_ACK_CHK_TIMER_3 (0x10006000+0x96C) */
+#define SPM_ACK_CHK_TIMER_VAL_3_LSB         (1U << 0)       /* 16b */
+#define SPM_ACK_CHK_TIMER_3_LSB             (1U << 16)      /* 16b */
+/* SPM_ACK_CHK_STA_3 (0x10006000+0x970) */
+#define SPM_ACK_CHK_STA_3_LSB               (1U << 0)       /* 32b */
+/* SPM_ACK_CHK_SWINT_3 (0x10006000+0x974) */
+#define SPM_ACK_CHK_SWINT_EN_3_LSB          (1U << 0)       /* 32b */
+/* SPM_COUNTER_0 (0x10006000+0x978) */
+#define SPM_COUNTER_VAL_0_LSB               (1U << 0)       /* 14b */
+#define SPM_COUNTER_OUT_0_LSB               (1U << 14)      /* 14b */
+#define SPM_COUNTER_EN_0_LSB                (1U << 28)      /* 1b */
+#define SPM_COUNTER_CLR_0_LSB               (1U << 29)      /* 1b */
+#define SPM_COUNTER_TIMEOUT_0_LSB           (1U << 30)      /* 1b */
+#define SPM_COUNTER_WAKEUP_EN_0_LSB         (1U << 31)      /* 1b */
+/* SPM_COUNTER_1 (0x10006000+0x97C) */
+#define SPM_COUNTER_VAL_1_LSB               (1U << 0)       /* 14b */
+#define SPM_COUNTER_OUT_1_LSB               (1U << 14)      /* 14b */
+#define SPM_COUNTER_EN_1_LSB                (1U << 28)      /* 1b */
+#define SPM_COUNTER_CLR_1_LSB               (1U << 29)      /* 1b */
+#define SPM_COUNTER_TIMEOUT_1_LSB           (1U << 30)      /* 1b */
+#define SPM_COUNTER_WAKEUP_EN_1_LSB         (1U << 31)      /* 1b */
+/* SPM_COUNTER_2 (0x10006000+0x980) */
+#define SPM_COUNTER_VAL_2_LSB               (1U << 0)       /* 14b */
+#define SPM_COUNTER_OUT_2_LSB               (1U << 14)      /* 14b */
+#define SPM_COUNTER_EN_2_LSB                (1U << 28)      /* 1b */
+#define SPM_COUNTER_CLR_2_LSB               (1U << 29)      /* 1b */
+#define SPM_COUNTER_TIMEOUT_2_LSB           (1U << 30)      /* 1b */
+#define SPM_COUNTER_WAKEUP_EN_2_LSB         (1U << 31)      /* 1b */
+/* SYS_TIMER_CON (0x10006000+0x98C) */
+#define SYS_TIMER_START_EN_LSB              (1U << 0)       /* 1b */
+#define SYS_TIMER_LATCH_EN_LSB              (1U << 1)       /* 1b */
+#define SYS_TIMER_ID_LSB                    (1U << 8)       /* 8b */
+#define SYS_TIMER_VALID_LSB                 (1U << 31)      /* 1b */
+/* RC_FSM_STA_0 (0x10006000+0xE00) */
+#define RC_FSM_STA_0_LSB                    (1U << 0)       /* 32b */
+/* RC_CMD_STA_0 (0x10006000+0xE04) */
+#define RC_CMD_STA_0_LSB                    (1U << 0)       /* 32b */
+/* RC_CMD_STA_1 (0x10006000+0xE08) */
+#define RC_CMD_STA_1_LSB                    (1U << 0)       /* 32b */
+/* RC_SPI_STA_0 (0x10006000+0xE0C) */
+#define RC_SPI_STA_0_LSB                    (1U << 0)       /* 32b */
+/* RC_PI_PO_STA_0 (0x10006000+0xE10) */
+#define RC_PI_PO_STA_0_LSB                  (1U << 0)       /* 32b */
+/* RC_M00_REQ_STA_0 (0x10006000+0xE14) */
+#define RC_M00_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M01_REQ_STA_0 (0x10006000+0xE1C) */
+#define RC_M01_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M02_REQ_STA_0 (0x10006000+0xE20) */
+#define RC_M02_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M03_REQ_STA_0 (0x10006000+0xE24) */
+#define RC_M03_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M04_REQ_STA_0 (0x10006000+0xE28) */
+#define RC_M04_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M05_REQ_STA_0 (0x10006000+0xE2C) */
+#define RC_M05_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M06_REQ_STA_0 (0x10006000+0xE30) */
+#define RC_M06_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M07_REQ_STA_0 (0x10006000+0xE34) */
+#define RC_M07_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M08_REQ_STA_0 (0x10006000+0xE38) */
+#define RC_M08_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M09_REQ_STA_0 (0x10006000+0xE3C) */
+#define RC_M09_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M10_REQ_STA_0 (0x10006000+0xE40) */
+#define RC_M10_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M11_REQ_STA_0 (0x10006000+0xE44) */
+#define RC_M11_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_M12_REQ_STA_0 (0x10006000+0xE48) */
+#define RC_M12_REQ_STA_0_LSB                (1U << 0)       /* 32b */
+/* RC_DEBUG_STA_0 (0x10006000+0xE4C) */
+#define RC_DEBUG_STA_0_LSB                  (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_0_LSB (0x10006000+0xE50) */
+#define RO_PMRC_TRACE_00_LSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_0_MSB (0x10006000+0xE54) */
+#define RO_PMRC_TRACE_00_MSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_1_LSB (0x10006000+0xE5C) */
+#define RO_PMRC_TRACE_01_LSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_1_MSB (0x10006000+0xE60) */
+#define RO_PMRC_TRACE_01_MSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_2_LSB (0x10006000+0xE64) */
+#define RO_PMRC_TRACE_02_LSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_2_MSB (0x10006000+0xE6C) */
+#define RO_PMRC_TRACE_02_MSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_3_LSB (0x10006000+0xE70) */
+#define RO_PMRC_TRACE_03_LSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_3_MSB (0x10006000+0xE74) */
+#define RO_PMRC_TRACE_03_MSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_4_LSB (0x10006000+0xE78) */
+#define RO_PMRC_TRACE_04_LSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_4_MSB (0x10006000+0xE7C) */
+#define RO_PMRC_TRACE_04_MSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_5_LSB (0x10006000+0xE80) */
+#define RO_PMRC_TRACE_05_LSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_5_MSB (0x10006000+0xE84) */
+#define RO_PMRC_TRACE_05_MSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_6_LSB (0x10006000+0xE88) */
+#define RO_PMRC_TRACE_06_LSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_6_MSB (0x10006000+0xE8C) */
+#define RO_PMRC_TRACE_06_MSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_7_LSB (0x10006000+0xE90) */
+#define RO_PMRC_TRACE_07_LSB_LSB            (1U << 0)       /* 32b */
+/* RC_DEBUG_TRACE_7_MSB (0x10006000+0xE94) */
+#define RO_PMRC_TRACE_07_MSB_LSB            (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_0_LSB (0x10006000+0xE98) */
+#define RC_SYS_TIMER_LATCH_L_00_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_0_MSB (0x10006000+0xE9C) */
+#define RC_SYS_TIMER_LATCH_H_00_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_1_LSB (0x10006000+0xEA0) */
+#define RC_SYS_TIMER_LATCH_L_01_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_1_MSB (0x10006000+0xEA4) */
+#define RC_SYS_TIMER_LATCH_H_01_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_2_LSB (0x10006000+0xEA8) */
+#define RC_SYS_TIMER_LATCH_L_02_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_2_MSB (0x10006000+0xEAC) */
+#define RC_SYS_TIMER_LATCH_H_02_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_3_LSB (0x10006000+0xEB0) */
+#define RC_SYS_TIMER_LATCH_L_03_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_3_MSB (0x10006000+0xEB4) */
+#define RC_SYS_TIMER_LATCH_H_03_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_4_LSB (0x10006000+0xEB8) */
+#define RC_SYS_TIMER_LATCH_L_04_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_4_MSB (0x10006000+0xEBC) */
+#define RC_SYS_TIMER_LATCH_H_04_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_5_LSB (0x10006000+0xEC0) */
+#define RC_SYS_TIMER_LATCH_L_05_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_5_MSB (0x10006000+0xEC4) */
+#define RC_SYS_TIMER_LATCH_H_05_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_6_LSB (0x10006000+0xEC8) */
+#define RC_SYS_TIMER_LATCH_L_06_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_6_MSB (0x10006000+0xECC) */
+#define RC_SYS_TIMER_LATCH_H_06_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_7_LSB (0x10006000+0xED0) */
+#define RC_SYS_TIMER_LATCH_L_07_LSB         (1U << 0)       /* 32b */
+/* RC_SYS_TIMER_LATCH_7_MSB (0x10006000+0xED4) */
+#define RC_SYS_TIMER_LATCH_H_07_LSB         (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_19 (0x10006000+0xED8) */
+#define PCM_WDT_LATCH_19_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_20 (0x10006000+0xEDC) */
+#define PCM_WDT_LATCH_20_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_21 (0x10006000+0xEE0) */
+#define PCM_WDT_LATCH_21_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_22 (0x10006000+0xEE4) */
+#define PCM_WDT_LATCH_22_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_23 (0x10006000+0xEE8) */
+#define PCM_WDT_LATCH_23_LSB                (1U << 0)       /* 32b */
+/* PCM_WDT_LATCH_24 (0x10006000+0xEEC) */
+#define PCM_WDT_LATCH_24_LSB                (1U << 0)       /* 32b */
+/* PMSR_LAST_DAT (0x10006000+0xF00) */
+#define PMSR_LAST_DAT_LSB                   (1U << 0)       /* 32b */
+/* PMSR_LAST_CNT (0x10006000+0xF04) */
+#define PMSR_LAST_CMD_LSB                   (1U << 0)       /* 30b */
+#define PMSR_LAST_REQ_LSB                   (1U << 30)      /* 1b */
+/* PMSR_LAST_ACK (0x10006000+0xF08) */
+#define PMSR_LAST_ACK_LSB                   (1U << 0)       /* 1b */
+/* SPM_PMSR_SEL_CON0 (0x10006000+0xF10) */
+#define REG_PMSR_SIG_SEL_0_LSB              (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_1_LSB              (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_2_LSB              (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_3_LSB              (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON1 (0x10006000+0xF14) */
+#define REG_PMSR_SIG_SEL_4_LSB              (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_5_LSB              (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_6_LSB              (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_7_LSB              (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON2 (0x10006000+0xF18) */
+#define REG_PMSR_SIG_SEL_8_LSB              (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_9_LSB              (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_10_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_11_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON3 (0x10006000+0xF1C) */
+#define REG_PMSR_SIG_SEL_12_LSB             (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_13_LSB             (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_14_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_15_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON4 (0x10006000+0xF20) */
+#define REG_PMSR_SIG_SEL_16_LSB             (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_17_LSB             (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_18_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_19_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON5 (0x10006000+0xF24) */
+#define REG_PMSR_SIG_SEL_20_LSB             (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_21_LSB             (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_22_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_23_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON6 (0x10006000+0xF28) */
+#define REG_PMSR_SIG_SEL_24_LSB             (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_25_LSB             (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_26_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_27_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON7 (0x10006000+0xF2C) */
+#define REG_PMSR_SIG_SEL_28_LSB             (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_29_LSB             (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_30_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_31_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON8 (0x10006000+0xF30) */
+#define REG_PMSR_SIG_SEL_32_LSB             (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_33_LSB             (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_34_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_35_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON9 (0x10006000+0xF34) */
+#define REG_PMSR_SIG_SEL_36_LSB             (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_37_LSB             (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_38_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_39_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON10 (0x10006000+0xF3C) */
+#define REG_PMSR_SIG_SEL_40_LSB             (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_41_LSB             (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_42_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_43_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_SEL_CON11 (0x10006000+0xF40) */
+#define REG_PMSR_SIG_SEL_44_LSB             (1U << 0)       /* 8b */
+#define REG_PMSR_SIG_SEL_45_LSB             (1U << 8)       /* 8b */
+#define REG_PMSR_SIG_SEL_46_LSB             (1U << 16)      /* 8b */
+#define REG_PMSR_SIG_SEL_47_LSB             (1U << 24)      /* 8b */
+/* SPM_PMSR_TIEMR_STA0 (0x10006000+0xFB8) */
+#define PMSR_TIMER_SET0_LSB                 (1U << 0)       /* 32b */
+/* SPM_PMSR_TIEMR_STA1 (0x10006000+0xFBC) */
+#define PMSR_TIMER_SET1_LSB                 (1U << 0)       /* 32b */
+/* SPM_PMSR_TIEMR_STA2 (0x10006000+0xFC0) */
+#define PMSR_TIMER_SET2_LSB                 (1U << 0)       /* 32b */
+/* SPM_PMSR_GENERAL_CON0 (0x10006000+0xFC4) */
+#define PMSR_ENABLE_SET0_LSB                (1U << 0)       /* 1b */
+#define PMSR_ENABLE_SET1_LSB                (1U << 1)       /* 1b */
+#define PMSR_ENABLE_SET2_LSB                (1U << 2)       /* 1b */
+#define PMSR_IRQ_CLR_SET0_LSB               (1U << 3)       /* 1b */
+#define PMSR_IRQ_CLR_SET1_LSB               (1U << 4)       /* 1b */
+#define PMSR_IRQ_CLR_SET2_LSB               (1U << 5)       /* 1b */
+#define PMSR_SPEED_MODE_EN_SET0_LSB         (1U << 6)       /* 1b */
+#define PMSR_SPEED_MODE_EN_SET1_LSB         (1U << 7)       /* 1b */
+#define PMSR_SPEED_MODE_EN_SET2_LSB         (1U << 8)       /* 1b */
+#define PMSR_EVENT_CLR_SET0_LSB             (1U << 9)       /* 1b */
+#define PMSR_EVENT_CLR_SET1_LSB             (1U << 10)      /* 1b */
+#define PMSR_EVENT_CLR_SET2_LSB             (1U << 11)      /* 1b */
+#define REG_PMSR_IRQ_MASK_SET0_LSB          (1U << 12)      /* 1b */
+#define REG_PMSR_IRQ_MASK_SET1_LSB          (1U << 13)      /* 1b */
+#define REG_PMSR_IRQ_MASK_SET2_LSB          (1U << 14)      /* 1b */
+#define REG_PMSR_IRQ_WAKEUP_EVENT_MASK_SET0_LSB (1U << 15)      /* 1b */
+#define REG_PMSR_IRQ_WAKEUP_EVENT_MASK_SET1_LSB (1U << 16)      /* 1b */
+#define REG_PMSR_IRQ_WAKEUP_EVENT_MASK_SET2_LSB (1U << 17)      /* 1b */
+#define PMSR_GEN_SW_RST_EN_LSB              (1U << 18)      /* 1b */
+#define PMSR_MODULE_ENABLE_LSB              (1U << 19)      /* 1b */
+#define PMSR_MODE_LSB                       (1U << 20)      /* 2b */
+#define SPM_PMSR_GENERAL_CON0_PMSR_IRQ_B_SET0_LSB (1U << 29)      /* 1b */
+#define SPM_PMSR_GENERAL_CON0_PMSR_IRQ_B_SET1_LSB (1U << 30)      /* 1b */
+#define SPM_PMSR_GENERAL_CON0_PMSR_IRQ_B_SET2_LSB (1U << 31)      /* 1b */
+/* SPM_PMSR_GENERAL_CON1 (0x10006000+0xFC8) */
+#define PMSR_COUNTER_THRES_LSB              (1U << 0)       /* 32b */
+/* SPM_PMSR_GENERAL_CON2 (0x10006000+0xFCC) */
+#define PMSR_DEBUG_IN_0_MASK_B_LSB          (1U << 0)       /* 32b */
+/* SPM_PMSR_GENERAL_CON3 (0x10006000+0xFD0) */
+#define PMSR_DEBUG_IN_1_MASK_B_LSB          (1U << 0)       /* 32b */
+/* SPM_PMSR_GENERAL_CON4 (0x10006000+0xFD4) */
+#define PMSR_DEBUG_IN_2_MASK_B_LSB          (1U << 0)       /* 32b */
+/* SPM_PMSR_GENERAL_CON5 (0x10006000+0xFD8) */
+#define PMSR_DEBUG_IN_3_MASK_B_LSB          (1U << 0)       /* 32b */
+/* SPM_PMSR_SW_RESET (0x10006000+0xFDC) */
+#define PMSR_SW_RST_EN_SET0_LSB             (1U << 0)       /* 1b */
+#define PMSR_SW_RST_EN_SET1_LSB             (1U << 1)       /* 1b */
+#define PMSR_SW_RST_EN_SET2_LSB             (1U << 2)       /* 1b */
+/* SPM_PMSR_MON_CON0 (0x10006000+0xFE0) */
+#define REG_PMSR_MON_TYPE_0_LSB             (1U << 0)       /* 2b */
+#define REG_PMSR_MON_TYPE_1_LSB             (1U << 2)       /* 2b */
+#define REG_PMSR_MON_TYPE_2_LSB             (1U << 4)       /* 2b */
+#define REG_PMSR_MON_TYPE_3_LSB             (1U << 6)       /* 2b */
+#define REG_PMSR_MON_TYPE_4_LSB             (1U << 8)       /* 2b */
+#define REG_PMSR_MON_TYPE_5_LSB             (1U << 10)      /* 2b */
+#define REG_PMSR_MON_TYPE_6_LSB             (1U << 12)      /* 2b */
+#define REG_PMSR_MON_TYPE_7_LSB             (1U << 14)      /* 2b */
+#define REG_PMSR_MON_TYPE_8_LSB             (1U << 16)      /* 2b */
+#define REG_PMSR_MON_TYPE_9_LSB             (1U << 18)      /* 2b */
+#define REG_PMSR_MON_TYPE_10_LSB            (1U << 20)      /* 2b */
+#define REG_PMSR_MON_TYPE_11_LSB            (1U << 22)      /* 2b */
+#define REG_PMSR_MON_TYPE_12_LSB            (1U << 24)      /* 2b */
+#define REG_PMSR_MON_TYPE_13_LSB            (1U << 26)      /* 2b */
+#define REG_PMSR_MON_TYPE_14_LSB            (1U << 28)      /* 2b */
+#define REG_PMSR_MON_TYPE_15_LSB            (1U << 30)      /* 2b */
+/* SPM_PMSR_MON_CON1 (0x10006000+0xFE4) */
+#define REG_PMSR_MON_TYPE_16_LSB            (1U << 0)       /* 2b */
+#define REG_PMSR_MON_TYPE_17_LSB            (1U << 2)       /* 2b */
+#define REG_PMSR_MON_TYPE_18_LSB            (1U << 4)       /* 2b */
+#define REG_PMSR_MON_TYPE_19_LSB            (1U << 6)       /* 2b */
+#define REG_PMSR_MON_TYPE_20_LSB            (1U << 8)       /* 2b */
+#define REG_PMSR_MON_TYPE_21_LSB            (1U << 10)      /* 2b */
+#define REG_PMSR_MON_TYPE_22_LSB            (1U << 12)      /* 2b */
+#define REG_PMSR_MON_TYPE_23_LSB            (1U << 14)      /* 2b */
+#define REG_PMSR_MON_TYPE_24_LSB            (1U << 16)      /* 2b */
+#define REG_PMSR_MON_TYPE_25_LSB            (1U << 18)      /* 2b */
+#define REG_PMSR_MON_TYPE_26_LSB            (1U << 20)      /* 2b */
+#define REG_PMSR_MON_TYPE_27_LSB            (1U << 22)      /* 2b */
+#define REG_PMSR_MON_TYPE_28_LSB            (1U << 24)      /* 2b */
+#define REG_PMSR_MON_TYPE_29_LSB            (1U << 26)      /* 2b */
+#define REG_PMSR_MON_TYPE_30_LSB            (1U << 28)      /* 2b */
+#define REG_PMSR_MON_TYPE_31_LSB            (1U << 30)      /* 2b */
+/* SPM_PMSR_MON_CON2 (0x10006000+0xFE8) */
+#define REG_PMSR_MON_TYPE_32_LSB            (1U << 0)       /* 2b */
+#define REG_PMSR_MON_TYPE_33_LSB            (1U << 2)       /* 2b */
+#define REG_PMSR_MON_TYPE_34_LSB            (1U << 4)       /* 2b */
+#define REG_PMSR_MON_TYPE_35_LSB            (1U << 6)       /* 2b */
+#define REG_PMSR_MON_TYPE_36_LSB            (1U << 8)       /* 2b */
+#define REG_PMSR_MON_TYPE_37_LSB            (1U << 10)      /* 2b */
+#define REG_PMSR_MON_TYPE_38_LSB            (1U << 12)      /* 2b */
+#define REG_PMSR_MON_TYPE_39_LSB            (1U << 14)      /* 2b */
+#define REG_PMSR_MON_TYPE_40_LSB            (1U << 16)      /* 2b */
+#define REG_PMSR_MON_TYPE_41_LSB            (1U << 18)      /* 2b */
+#define REG_PMSR_MON_TYPE_42_LSB            (1U << 20)      /* 2b */
+#define REG_PMSR_MON_TYPE_43_LSB            (1U << 22)      /* 2b */
+#define REG_PMSR_MON_TYPE_44_LSB            (1U << 24)      /* 2b */
+#define REG_PMSR_MON_TYPE_45_LSB            (1U << 26)      /* 2b */
+#define REG_PMSR_MON_TYPE_46_LSB            (1U << 28)      /* 2b */
+#define REG_PMSR_MON_TYPE_47_LSB            (1U << 30)      /* 2b */
+/* SPM_PMSR_LEN_CON0 (0x10006000+0xFEC) */
+#define REG_PMSR_WINDOW_LEN_SET0_LSB        (1U << 0)       /* 32b */
+/* SPM_PMSR_LEN_CON1 (0x10006000+0xFF0) */
+#define REG_PMSR_WINDOW_LEN_SET1_LSB        (1U << 0)       /* 32b */
+/* SPM_PMSR_LEN_CON2 (0x10006000+0xFF4) */
+#define REG_PMSR_WINDOW_LEN_SET2_LSB        (1U << 0)       /* 32b */
+
+#define SPM_PROJECT_CODE	(0xb16)
+#define SPM_REGWR_CFG_KEY	(SPM_PROJECT_CODE << 16)
+
+#endif /* MT_SPM_REG_H */
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.c
new file mode 100644
index 0000000..18047e6
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#ifndef MTK_PLAT_SPM_UART_UNSUPPORT
+#include <drivers/uart.h>
+#endif
+#include <lib/mmio.h>
+#ifndef MTK_PLAT_CIRQ_UNSUPPORT
+#include <mtk_cirq.h>
+#endif
+#include <constraints/mt_spm_rc_internal.h>
+#include <drivers/spm/mt_spm_resource_req.h>
+#include <lib/pm/mtk_pm.h>
+#include <lpm/mt_lp_api.h>
+#include <mt_spm.h>
+#include <mt_spm_conservation.h>
+#include <mt_spm_internal.h>
+#include <mt_spm_reg.h>
+#include <mt_spm_suspend.h>
+#include <pcm_def.h>
+
+#define SPM_SUSPEND_SLEEP_PCM_FLAG \
+	(SPM_FLAG_DISABLE_INFRA_PDN | \
+	 SPM_FLAG_DISABLE_VCORE_DVS | \
+	 SPM_FLAG_DISABLE_VCORE_DFS | \
+	 SPM_FLAG_KEEP_CSYSPWRACK_HIGH | \
+	 SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \
+	 SPM_FLAG_SRAM_SLEEP_CTRL)
+
+#define SPM_SUSPEND_SLEEP_PCM_FLAG1	(SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH)
+
+#define SPM_SUSPEND_PCM_FLAG \
+	(SPM_FLAG_DISABLE_VCORE_DVS | \
+	 SPM_FLAG_DISABLE_VCORE_DFS | \
+	 SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP | \
+	 SPM_FLAG_SRAM_SLEEP_CTRL)
+
+#define SPM_SUSPEND_PCM_FLAG1	(SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH)
+
+/* Suspend spm power control */
+#define __WAKE_SRC_FOR_SUSPEND_COMMON__ ( \
+	(R12_PCM_TIMER) | \
+	(R12_KP_IRQ_B) | \
+	(R12_APWDT_EVENT_B) | \
+	(R12_MSDC_WAKEUP_B) | \
+	(R12_EINT_EVENT_B) | \
+	(R12_SBD_INTR_WAKEUP_B) | \
+	(R12_SSPM2SPM_WAKEUP_B) | \
+	(R12_SCP2SPM_WAKEUP_B) | \
+	(R12_ADSP2SPM_WAKEUP_B) | \
+	(R12_USBX_CDSC_B) | \
+	(R12_USBX_POWERDWN_B) | \
+	(R12_SYS_TIMER_EVENT_B) | \
+	(R12_EINT_EVENT_SECURE_B) | \
+	(R12_ECE_INT_HDMI_B) | \
+	(R12_SYS_CIRQ_IRQ_B) | \
+	(R12_PCIE_WAKEUPEVENT_B) | \
+	(R12_SPM_CPU_WAKEUPEVENT_B) | \
+	(R12_APUSYS_WAKE_HOST_B))
+
+#if defined(CFG_MICROTRUST_TEE_SUPPORT)
+#define WAKE_SRC_FOR_SUSPEND	(__WAKE_SRC_FOR_SUSPEND_COMMON__)
+#else
+#define WAKE_SRC_FOR_SUSPEND	(__WAKE_SRC_FOR_SUSPEND_COMMON__ | R12_SEJ_EVENT_B)
+#endif
+
+static struct pwr_ctrl suspend_ctrl = {
+	.wake_src = WAKE_SRC_FOR_SUSPEND,
+
+	/* SPM_AP_STANDBY_CON */
+	/* [0] */
+	.reg_wfi_op = 0,
+	/* [1] */
+	.reg_wfi_type = 0,
+	/* [2] */
+	.reg_mp0_cputop_idle_mask = 0,
+	/* [3] */
+	.reg_mp1_cputop_idle_mask = 0,
+	/* [4] */
+	.reg_mcusys_idle_mask = 0,
+	/* [25] */
+	.reg_md_apsrc_1_sel = 0,
+	/* [26] */
+	.reg_md_apsrc_0_sel = 0,
+	/* [29] */
+	.reg_conn_apsrc_sel = 0,
+
+	/* SPM_SRC_REQ */
+	/* [0] */
+	.reg_spm_apsrc_req = 0,
+	/* [1] */
+	.reg_spm_f26m_req = 0,
+	/* [3] */
+	.reg_spm_infra_req = 0,
+	/* [4] */
+	.reg_spm_vrf18_req = 0,
+	/* [7] */
+	.reg_spm_ddr_en_req = 0,
+	/* [8] */
+	.reg_spm_dvfs_req = 0,
+	/* [9] */
+	.reg_spm_sw_mailbox_req = 0,
+	/* [10] */
+	.reg_spm_sspm_mailbox_req = 0,
+	/* [11] */
+	.reg_spm_adsp_mailbox_req = 0,
+	/* [12] */
+	.reg_spm_scp_mailbox_req = 0,
+
+	/* SPM_SRC_MASK */
+	/* [0] */
+	.reg_sspm_srcclkena_0_mask_b = 1,
+	/* [1] */
+	.reg_sspm_infra_req_0_mask_b = 1,
+	/* [2] */
+	.reg_sspm_apsrc_req_0_mask_b = 0,
+	/* [3] */
+	.reg_sspm_vrf18_req_0_mask_b = 0,
+	/* [4] */
+	.reg_sspm_ddr_en_0_mask_b = 0,
+	/* [5] */
+	.reg_scp_srcclkena_mask_b = 1,
+	/* [6] */
+	.reg_scp_infra_req_mask_b = 1,
+	/* [7] */
+	.reg_scp_apsrc_req_mask_b = 1,
+	/* [8] */
+	.reg_scp_vrf18_req_mask_b = 1,
+	/* [9] */
+	.reg_scp_ddr_en_mask_b = 1,
+	/* [10] */
+	.reg_audio_dsp_srcclkena_mask_b = 1,
+	/* [11] */
+	.reg_audio_dsp_infra_req_mask_b = 1,
+	/* [12] */
+	.reg_audio_dsp_apsrc_req_mask_b = 1,
+	/* [13] */
+	.reg_audio_dsp_vrf18_req_mask_b = 1,
+	/* [14] */
+	.reg_audio_dsp_ddr_en_mask_b = 1,
+	/* [15] */
+	.reg_apu_srcclkena_mask_b = 1,
+	/* [16] */
+	.reg_apu_infra_req_mask_b = 1,
+	/* [17] */
+	.reg_apu_apsrc_req_mask_b = 0,
+	/* [18] */
+	.reg_apu_vrf18_req_mask_b = 1,
+	/* [19] */
+	.reg_apu_ddr_en_mask_b = 1,
+	/* [20] */
+	.reg_cpueb_srcclkena_mask_b = 1,
+	/* [21] */
+	.reg_cpueb_infra_req_mask_b = 1,
+	/* [22] */
+	.reg_cpueb_apsrc_req_mask_b = 1,
+	/* [23] */
+	.reg_cpueb_vrf18_req_mask_b = 1,
+	/* [24] */
+	.reg_cpueb_ddr_en_mask_b = 1,
+	/* [25] */
+	.reg_bak_psri_srcclkena_mask_b = 0,
+	/* [26] */
+	.reg_bak_psri_infra_req_mask_b = 0,
+	/* [27] */
+	.reg_bak_psri_apsrc_req_mask_b = 0,
+	/* [28] */
+	.reg_bak_psri_vrf18_req_mask_b = 0,
+	/* [29] */
+	.reg_bak_psri_ddr_en_mask_b = 0,
+	/* [30] */
+	.reg_cam_ddren_req_mask_b = 0,
+	/* [31] */
+	.reg_img_ddren_req_mask_b = 0,
+
+	/* SPM_SRC2_MASK */
+	/* [0] */
+	.reg_msdc0_srcclkena_mask_b = 1,
+	/* [1] */
+	.reg_msdc0_infra_req_mask_b = 1,
+	/* [2] */
+	.reg_msdc0_apsrc_req_mask_b = 1,
+	/* [3] */
+	.reg_msdc0_vrf18_req_mask_b = 1,
+	/* [4] */
+	.reg_msdc0_ddr_en_mask_b = 1,
+	/* [5] */
+	.reg_msdc1_srcclkena_mask_b = 1,
+	/* [6] */
+	.reg_msdc1_infra_req_mask_b = 1,
+	/* [7] */
+	.reg_msdc1_apsrc_req_mask_b = 1,
+	/* [8] */
+	.reg_msdc1_vrf18_req_mask_b = 1,
+	/* [9] */
+	.reg_msdc1_ddr_en_mask_b = 1,
+	/* [10] */
+	.reg_msdc2_srcclkena_mask_b = 1,
+	/* [11] */
+	.reg_msdc2_infra_req_mask_b = 1,
+	/* [12] */
+	.reg_msdc2_apsrc_req_mask_b = 1,
+	/* [13] */
+	.reg_msdc2_vrf18_req_mask_b = 1,
+	/* [14] */
+	.reg_msdc2_ddr_en_mask_b = 1,
+	/* [15] */
+	.reg_ufs_srcclkena_mask_b = 1,
+	/* [16] */
+	.reg_ufs_infra_req_mask_b = 1,
+	/* [17] */
+	.reg_ufs_apsrc_req_mask_b = 1,
+	/* [18] */
+	.reg_ufs_vrf18_req_mask_b = 1,
+	/* [19] */
+	.reg_ufs_ddr_en_mask_b = 1,
+	/* [20] */
+	.reg_usb_srcclkena_mask_b = 1,
+	/* [21] */
+	.reg_usb_infra_req_mask_b = 1,
+	/* [22] */
+	.reg_usb_apsrc_req_mask_b = 1,
+	/* [23] */
+	.reg_usb_vrf18_req_mask_b = 1,
+	/* [24] */
+	.reg_usb_ddr_en_mask_b = 1,
+	/* [25] */
+	.reg_pextp_p0_srcclkena_mask_b = 1,
+	/* [26] */
+	.reg_pextp_p0_infra_req_mask_b = 1,
+	/* [27] */
+	.reg_pextp_p0_apsrc_req_mask_b = 1,
+	/* [28] */
+	.reg_pextp_p0_vrf18_req_mask_b = 1,
+	/* [29] */
+	.reg_pextp_p0_ddr_en_mask_b = 1,
+
+	/* SPM_SRC3_MASK */
+	/* [0] */
+	.reg_pextp_p1_srcclkena_mask_b = 1,
+	/* [1] */
+	.reg_pextp_p1_infra_req_mask_b = 1,
+	/* [2] */
+	.reg_pextp_p1_apsrc_req_mask_b = 1,
+	/* [3] */
+	.reg_pextp_p1_vrf18_req_mask_b = 1,
+	/* [4] */
+	.reg_pextp_p1_ddr_en_mask_b = 1,
+	/* [5] */
+	.reg_gce0_infra_req_mask_b = 1,
+	/* [6] */
+	.reg_gce0_apsrc_req_mask_b = 1,
+	/* [7] */
+	.reg_gce0_vrf18_req_mask_b = 1,
+	/* [8] */
+	.reg_gce0_ddr_en_mask_b = 1,
+	/* [9] */
+	.reg_gce1_infra_req_mask_b = 1,
+	/* [10] */
+	.reg_gce1_apsrc_req_mask_b = 1,
+	/* [11] */
+	.reg_gce1_vrf18_req_mask_b = 1,
+	/* [12] */
+	.reg_gce1_ddr_en_mask_b = 1,
+	/* [13] */
+	.reg_spm_srcclkena_reserved_mask_b = 1,
+	/* [14] */
+	.reg_spm_infra_req_reserved_mask_b = 1,
+	/* [15] */
+	.reg_spm_apsrc_req_reserved_mask_b = 1,
+	/* [16] */
+	.reg_spm_vrf18_req_reserved_mask_b = 1,
+	/* [17] */
+	.reg_spm_ddr_en_reserved_mask_b = 1,
+	/* [18] */
+	.reg_disp0_apsrc_req_mask_b = 1,
+	/* [19] */
+	.reg_disp0_ddr_en_mask_b = 1,
+	/* [20] */
+	.reg_disp1_apsrc_req_mask_b = 1,
+	/* [21] */
+	.reg_disp1_ddr_en_mask_b = 1,
+	/* [22] */
+	.reg_disp2_apsrc_req_mask_b = 1,
+	/* [23] */
+	.reg_disp2_ddr_en_mask_b = 1,
+	/* [24] */
+	.reg_disp3_apsrc_req_mask_b = 1,
+	/* [25] */
+	.reg_disp3_ddr_en_mask_b = 1,
+	/* [26] */
+	.reg_infrasys_apsrc_req_mask_b = 0,
+	/* [27] */
+	.reg_infrasys_ddr_en_mask_b = 1,
+
+	/* [28] */
+	.reg_cg_check_srcclkena_mask_b = 1,
+	/* [29] */
+	.reg_cg_check_apsrc_req_mask_b = 1,
+	/* [30] */
+	.reg_cg_check_vrf18_req_mask_b = 1,
+	/* [31] */
+	.reg_cg_check_ddr_en_mask_b = 1,
+
+	/* SPM_SRC4_MASK */
+	/* [8:0] */
+	.reg_mcusys_merge_apsrc_req_mask_b = 0,
+	/* [17:9] */
+	.reg_mcusys_merge_ddr_en_mask_b = 0,
+	/* [19:18] */
+	.reg_dramc_md32_infra_req_mask_b = 3,
+	/* [21:20] */
+	.reg_dramc_md32_vrf18_req_mask_b = 3,
+	/* [23:22] */
+	.reg_dramc_md32_ddr_en_mask_b = 0,
+	/* [24] */
+	.reg_dvfsrc_event_trigger_mask_b = 1,
+
+	/* SPM_WAKEUP_EVENT_MASK2 */
+	/* [3:0] */
+	.reg_sc_sw2spm_wakeup_mask_b = 0,
+	/* [4] */
+	.reg_sc_adsp2spm_wakeup_mask_b = 0,
+	/* [8:5] */
+	.reg_sc_sspm2spm_wakeup_mask_b = 0,
+	/* [9] */
+	.reg_sc_scp2spm_wakeup_mask_b = 0,
+	/* [10] */
+	.reg_csyspwrup_ack_mask = 0,
+	/* [11] */
+	.reg_csyspwrup_req_mask = 1,
+
+	/* SPM_WAKEUP_EVENT_MASK */
+	/* [31:0] */
+	.reg_wakeup_event_mask = 0xC1382213,
+
+	/* SPM_WAKEUP_EVENT_EXT_MASK */
+	/* [31:0] */
+	.reg_ext_wakeup_event_mask = 0xFFFFFFFF,
+
+	/*sw flag setting */
+	.pcm_flags = SPM_SUSPEND_PCM_FLAG,
+	.pcm_flags1 = SPM_SUSPEND_PCM_FLAG1,
+};
+
+struct spm_lp_scen __spm_suspend = {
+	.pwrctrl = &suspend_ctrl,
+};
+
+int mt_spm_suspend_mode_set(int mode, void *prv)
+{
+	if (mode == MT_SPM_SUSPEND_SLEEP) {
+		suspend_ctrl.pcm_flags = SPM_SUSPEND_SLEEP_PCM_FLAG;
+		suspend_ctrl.pcm_flags1 = SPM_SUSPEND_SLEEP_PCM_FLAG1;
+	} else {
+		suspend_ctrl.pcm_flags = SPM_SUSPEND_PCM_FLAG;
+		suspend_ctrl.pcm_flags1 = SPM_SUSPEND_PCM_FLAG1;
+	}
+	return 0;
+}
+
+int mt_spm_suspend_enter(int state_id, unsigned int ext_opand, unsigned int reosuce_req)
+{
+	int ret = 0;
+
+	/* if FMAudio, ADSP is active, change to sleep suspend mode */
+	if ((ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) != 0U) {
+		mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SLEEP, NULL);
+	}
+
+	if ((ext_opand & MT_SPM_EX_OP_PERI_ON) != 0U) {
+		suspend_ctrl.pcm_flags |= SPM_FLAG_PERI_ON_IN_SUSPEND;
+	} else {
+		suspend_ctrl.pcm_flags &= ~SPM_FLAG_PERI_ON_IN_SUSPEND;
+	}
+
+	if ((ext_opand & MT_SPM_EX_OP_INFRA_ON) != 0U) {
+		suspend_ctrl.pcm_flags |= SPM_FLAG_DISABLE_INFRA_PDN;
+	} else {
+		suspend_ctrl.pcm_flags &= ~SPM_FLAG_DISABLE_INFRA_PDN;
+	}
+
+#ifndef MTK_PLAT_SPM_UART_UNSUPPORT
+	/* Notify UART to sleep */
+	mtk_uart_save();
+#endif
+
+	ret = spm_conservation(state_id, ext_opand, &__spm_suspend, reosuce_req);
+	if (ret == 0) {
+		struct mt_lp_publish_event event = {
+			.id = MT_LPM_PUBEVENTS_SYS_POWER_OFF,
+			.val.u32 = 0U,
+		};
+
+		MT_LP_SUSPEND_PUBLISH_EVENT(&event);
+	}
+	return ret;
+}
+
+void mt_spm_suspend_resume(int state_id, unsigned int ext_opand, struct wake_status **status)
+{
+	struct mt_lp_publish_event event = {
+		.id = MT_LPM_PUBEVENTS_SYS_POWER_ON,
+		.val.u32 = 0U,
+	};
+
+	struct wake_status *st = NULL;
+
+	spm_conservation_finish(state_id, ext_opand, &__spm_suspend, &st);
+
+#ifndef MTK_PLAT_SPM_UART_UNSUPPORT
+	/* Notify UART to wakeup */
+	mtk_uart_restore();
+#endif
+
+	/* If FMAudio, ADSP is active, change back to suspend mode and counting in resume */
+	if ((ext_opand & MT_SPM_EX_OP_SET_SUSPEND_MODE) != 0U) {
+		mt_spm_suspend_mode_set(MT_SPM_SUSPEND_SYSTEM_PDN, NULL);
+	}
+
+	if (status != NULL) {
+		*status = st;
+	}
+	MT_LP_SUSPEND_PUBLISH_EVENT(&event);
+}
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.h
new file mode 100644
index 0000000..37f621d
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_suspend.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_SUSPEND_H
+#define MT_SPM_SUSPEND_H
+
+#include <mt_spm_internal.h>
+
+struct suspend_dbg_ctrl {
+	uint32_t sleep_suspend_cnt;
+};
+
+enum mt_spm_suspend_mode {
+	MT_SPM_SUSPEND_SYSTEM_PDN = 0,
+	MT_SPM_SUSPEND_SLEEP,
+};
+
+int mt_spm_suspend_mode_set(int mode, void *prv);
+int mt_spm_suspend_enter(int state_id, unsigned int ext_opand, unsigned int reosuce_req);
+void mt_spm_suspend_resume(int state_id, unsigned int ext_opand, struct wake_status **status);
+
+#endif
diff --git a/plat/mediatek/drivers/spm/mt8188/pcm_def.h b/plat/mediatek/drivers/spm/mt8188/pcm_def.h
new file mode 100644
index 0000000..976c167
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/pcm_def.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PCM_DEF_H
+#define PCM_DEF_H
+
+/*
+ * Auto generated by DE, please DO NOT modify this file directly.
+ */
+
+/* --- R0 Define --- */
+#define R0_SC_26M_CK_OFF                      (1U << 0)
+#define R0_SC_TX_TRACK_RETRY_EN               (1U << 1)
+#define R0_SC_MEM_CK_OFF                      (1U << 2)
+#define R0_SC_AXI_CK_OFF                      (1U << 3)
+#define R0_SC_DR_SRAM_LOAD                    (1U << 4)
+#define R0_SC_MD26M_CK_OFF                    (1U << 5)
+#define R0_SC_DPY_MODE_SW                     (1U << 6)
+#define R0_SC_DMSUS_OFF                       (1U << 7)
+#define R0_SC_DPY_2ND_DLL_EN                  (1U << 8)
+#define R0_SC_DR_SRAM_RESTORE                 (1U << 9)
+#define R0_SC_MPLLOUT_OFF                     (1U << 10)
+#define R0_SC_TX_TRACKING_DIS                 (1U << 11)
+#define R0_SC_DPY_DLL_EN                      (1U << 12)
+#define R0_SC_DPY_DLL_CK_EN                   (1U << 13)
+#define R0_SC_DPY_VREF_EN                     (1U << 14)
+#define R0_SC_PHYPLL_EN                       (1U << 15)
+#define R0_SC_DDRPHY_FB_CK_EN                 (1U << 16)
+#define R0_SC_DPY_BCLK_ENABLE                 (1U << 17)
+#define R0_SC_MPLL_OFF                        (1U << 18)
+#define R0_SC_SHU_RESTORE                     (1U << 19)
+#define R0_SC_CKSQ0_OFF                       (1U << 20)
+#define R0_SC_DR_SHU_LEVEL_SRAM_LATCH         (1U << 21)
+#define R0_SC_DR_SHU_EN                       (1U << 22)
+#define R0_SC_DPHY_PRECAL_UP                  (1U << 23)
+#define R0_SC_MPLL_S_OFF                      (1U << 24)
+#define R0_SC_DPHY_RXDLY_TRACKING_EN             (1U << 25)
+#define R0_SC_PHYPLL_SHU_EN                   (1U << 26)
+#define R0_SC_PHYPLL2_SHU_EN                  (1U << 27)
+#define R0_SC_PHYPLL_MODE_SW                  (1U << 28)
+#define R0_SC_PHYPLL2_MODE_SW                 (1U << 29)
+#define R0_SC_DR_SHU_LEVEL0                   (1U << 30)
+#define R0_SC_DR_SHU_LEVEL1                   (1U << 31)
+/* --- R7 Define --- */
+#define R7_PWRAP_SLEEP_REQ                    (1U << 0)
+#define R7_EMI_CLK_OFF_REQ                    (1U << 1)
+#define R7_PCM_BUS_PROTECT_REQ                (1U << 2)
+#define R7_SPM_CK_UPDATE                      (1U << 3)
+#define R7_SPM_CK_SEL0                        (1U << 4)
+#define R7_SPM_CK_SEL1                        (1U << 5)
+#define R7_SPM_LEAVE_DEEPIDLE_REQ             (1U << 6)
+#define R7_SC_FHC_PAUSE_MPLL                  (1U << 7)
+#define R7_SC_26M_CK_SEL                      (1U << 8)
+#define R7_PCM_TIMER_SET                      (1U << 9)
+#define R7_PCM_TIMER_CLR                      (1U << 10)
+#define R7_SPM_LEAVE_SUSPEND_REQ              (1U << 11)
+#define R7_CSYSPWRUPACK                       (1U << 12)
+#define R7_PCM_IM_SLP_EN                      (1U << 13)
+#define R7_SRCCLKENO0                         (1U << 14)
+#define R7_FORCE_DDR_EN_WAKE                  (1U << 15)
+#define R7_SPM_APSRC_INTERNAL_ACK             (1U << 16)
+#define R7_CPU_SYS_TIMER_CLK_SEL              (1U << 17)
+#define R7_SC_AXI_DCM_DIS                     (1U << 18)
+#define R7_SC_FHC_PAUSE_MEM                   (1U << 19)
+#define R7_SC_FHC_PAUSE_MAIN                  (1U << 20)
+#define R7_SRCCLKENO1                         (1U << 21)
+#define R7_PCM_WDT_KICK_P                     (1U << 22)
+#define R7_SPM2EMI_S1_MODE_ASYNC              (1U << 23)
+#define R7_SC_DDR_PST_REQ_PCM                 (1U << 24)
+#define R7_SC_DDR_PST_ABORT_REQ_PCM           (1U << 25)
+#define R7_PMIC_IRQ_REQ_EN                    (1U << 26)
+#define R7_FORCE_F26M_WAKE                    (1U << 27)
+#define R7_FORCE_APSRC_WAKE                   (1U << 28)
+#define R7_FORCE_INFRA_WAKE                   (1U << 29)
+#define R7_FORCE_VRF18_WAKE                   (1U << 30)
+#define R7_SPM_DDR_EN_INTERNAL_ACK            (1U << 31)
+/* --- R12 Define --- */
+#define R12_PCM_TIMER                         (1U << 0)
+#define R12_TWAM_IRQ_B                        (1U << 1)
+#define R12_KP_IRQ_B                          (1U << 2)
+#define R12_APWDT_EVENT_B                     (1U << 3)
+#define R12_APXGPT1_EVENT_B                   (1U << 4)
+#define R12_MSDC_WAKEUP_B                     (1U << 5)
+#define R12_EINT_EVENT_B                      (1U << 6)
+#define R12_NOT_USED_7                        (1U << 7)
+#define R12_SBD_INTR_WAKEUP_B                 (1U << 8)
+#define R12_LOWBATTERY_IRQ_B                  (1U << 9)
+#define R12_SSPM2SPM_WAKEUP_B                 (1U << 10)
+#define R12_SCP2SPM_WAKEUP_B                  (1U << 11)
+#define R12_ADSP2SPM_WAKEUP_B                 (1U << 12)
+#define R12_PCM_WDT_WAKEUP_B                  (1U << 13)
+#define R12_USBX_CDSC_B                       (1U << 14)
+#define R12_USBX_POWERDWN_B                   (1U << 15)
+#define R12_SYS_TIMER_EVENT_B                 (1U << 16)
+#define R12_EINT_EVENT_SECURE_B               (1U << 17)
+#define R12_ECE_INT_HDMI_B                    (1U << 18)
+#define R12_I2C_IRQ_B                         (1U << 19)
+#define R12_AFE_IRQ_MCU_B                     (1U << 20)
+#define R12_THERM_CTRL_EVENT_B                (1U << 21)
+#define R12_SYS_CIRQ_IRQ_B                    (1U << 22)
+#define R12_NOT_USED_23                       (1U << 23)
+#define R12_CSYSPWREQ_B                       (1U << 24)
+#define R12_NOT_USED_25                       (1U << 25)
+#define R12_PCIE_WAKEUPEVENT_B                (1U << 26)
+#define R12_SEJ_EVENT_B                       (1U << 27)
+#define R12_SPM_CPU_WAKEUPEVENT_B             (1U << 28)
+#define R12_APUSYS_WAKE_HOST_B                (1U << 29)
+#define R12_NOT_USED_30                       (1U << 30)
+#define R12_NOT_USED_31                       (1U << 31)
+/* --- R12ext Define --- */
+#define R12EXT_26M_WAKE                       (1U << 0)
+#define R12EXT_26M_SLEEP                      (1U << 1)
+#define R12EXT_INFRA_WAKE                     (1U << 2)
+#define R12EXT_INFRA_SLEEP                    (1U << 3)
+#define R12EXT_APSRC_WAKE                     (1U << 4)
+#define R12EXT_APSRC_SLEEP                    (1U << 5)
+#define R12EXT_VRF18_WAKE                     (1U << 6)
+#define R12EXT_VRF18_SLEEP                    (1U << 7)
+#define R12EXT_DVFS_WAKE                      (1U << 8)
+#define R12EXT_DDREN_WAKE                     (1U << 9)
+#define R12EXT_DDREN_SLEEP                    (1U << 10)
+#define R12EXT_MCU_PM_WFI                     (1U << 11)
+#define R12EXT_SSPM_IDLE                      (1U << 12)
+#define R12EXT_CONN_SRCCLKENB                 (1U << 13)
+#define R12EXT_DRAMC_SSPM_WFI_MERGE           (1U << 14)
+#define R12EXT_SW_MAILBOX_WAKE                (1U << 15)
+#define R12EXT_SSPM_MAILBOX_WAKE              (1U << 16)
+#define R12EXT_ADSP_MAILBOX_WAKE              (1U << 17)
+#define R12EXT_SCP_MAILBOX_WAKE               (1U << 18)
+#define R12EXT_SPM_LEAVE_SUSPEND_ACK          (1U << 19)
+#define R12EXT_SPM_LEAVE_DEEPIDLE_ACK         (1U << 20)
+#define R12EXT_VS1_TRIGGER                    (1U << 21)
+#define R12EXT_VS2_TRIGGER                    (1U << 22)
+#define R12EXT_COROSS_REQ_APU                 (1U << 23)
+#define R12EXT_CROSS_REQ_L3                   (1U << 24)
+#define R12EXT_DDR_PST_ACK                    (1U << 25)
+#define R12EXT_BIT26                          (1U << 26)
+#define R12EXT_BIT27                          (1U << 27)
+#define R12EXT_BIT28                          (1U << 28)
+#define R12EXT_BIT29                          (1U << 29)
+#define R12EXT_BIT30                          (1U << 30)
+#define R12EXT_BIT31                          (1U << 31)
+/* --- R13 Define --- */
+#define R13_SRCCLKENI0                        (1U << 0)
+#define R13_SRCCLKENI1                        (1U << 1)
+#define R13_MD_SRCCLKENA_0                    (1U << 2)
+#define R13_MD_APSRC_REQ_0                    (1U << 3)
+#define R13_CONN_DDR_EN                       (1U << 4)
+#define R13_MD_SRCCLKENA_1                    (1U << 5)
+#define R13_SSPM_SRCCLKENA                    (1U << 6)
+#define R13_SSPM_APSRC_REQ                    (1U << 7)
+#define R13_MD1_STATE                         (1U << 8)
+#define R13_BIT9                              (1U << 9)
+#define R13_MM_STATE                          (1U << 10)
+#define R13_SSPM_STATE                        (1U << 11)
+#define R13_MD_DDR_EN_0                       (1U << 12)
+#define R13_CONN_STATE                        (1U << 13)
+#define R13_CONN_SRCCLKENA                    (1U << 14)
+#define R13_CONN_APSRC_REQ                    (1U << 15)
+#define R13_SC_DDR_PST_ACK_ALL                (1U << 16)
+#define R13_SC_DDR_PST_ABORT_ACK_ALL          (1U << 17)
+#define R13_SCP_STATE                         (1U << 18)
+#define R13_CSYSPWRUPREQ                      (1U << 19)
+#define R13_PWRAP_SLEEP_ACK                   (1U << 20)
+#define R13_SC_EMI_CLK_OFF_ACK_ALL            (1U << 21)
+#define R13_AUDIO_DSP_STATE                   (1U << 22)
+#define R13_SC_DMDRAMCSHU_ACK_ALL             (1U << 23)
+#define R13_CONN_SRCCLKENB                    (1U << 24)
+#define R13_SC_DR_SRAM_LOAD_ACK_ALL           (1U << 25)
+#define R13_SUBSYS_IDLE_SIGNALS0              (1U << 26)
+#define R13_DVFS_STATE                        (1U << 27)
+#define R13_SC_DR_SRAM_PLL_LOAD_ACK_ALL       (1U << 28)
+#define R13_SC_DR_SRAM_RESTORE_ACK_ALL        (1U << 29)
+#define R13_MD_VRF18_REQ_0                    (1U << 30)
+#define R13_DDR_EN_STATE                      (1U << 31)
+
+#endif /* PCM_DEF_H */
diff --git a/plat/mediatek/drivers/spm/mt8188/rules.mk b/plat/mediatek/drivers/spm/mt8188/rules.mk
new file mode 100644
index 0000000..a04e91f
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/rules.mk
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+MODULE := spm_${MTK_SOC}
+
+define GET_UPPER_DIR
+$(shell dirname ${LOCAL_DIR})
+endef
+UPPER_DIR := $(call GET_UPPER_DIR)
+
+MT_SPM_FEATURE_SUPPORT := y
+MT_SPM_CIRQ_FEATURE_SUPPORT := n
+MT_SPMFW_SPM_SRAM_SLEEP_SUPPORT := n
+MT_SPM_SSPM_NOTIFIER_SUPPORT := y
+MT_SPM_UART_SUSPEND_SUPPORT := n
+MT_SPM_RGU_SUPPORT := n
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/mt_spm.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/mt_spm_conservation.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/mt_spm_internal.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/mt_spm_pmic_wrap.c
+LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_cond.c
+LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_idle.c
+LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/mt_spm_suspend.c
+LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_api.c
+LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_bus26m.c
+LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_cpu_buck_ldo.c
+LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_dram.c
+LOCAL_SRCS-${MT_SPM_FEATURE_SUPPORT} += ${LOCAL_DIR}/constraints/mt_spm_rc_syspll.c
+LOCAL_SRCS-${MT_SPM_SSPM_NOTIFIER_SUPPORT} += ${UPPER_DIR}/version/notifier/v1/mt_spm_sspm_notifier.c
+
+ifeq (${MT_SPM_FEATURE_SUPPORT},n)
+$(eval $(call add_define,MTK_PLAT_SPM_UNSUPPORT))
+endif
+
+ifeq (${MT_SPM_CIRQ_FEATURE_SUPPORT},n)
+$(eval $(call add_define,MTK_PLAT_CIRQ_UNSUPPORT))
+endif
+
+ifeq (${MT_SPMFW_SPM_SRAM_SLEEP_SUPPORT},n)
+$(eval $(call add_define,MTK_PLAT_SPM_SRAM_SLP_UNSUPPORT))
+endif
+
+ifeq (${MT_SPM_SSPM_NOTIFIER_SUPPORT},n)
+$(eval $(call add_define,MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT))
+endif
+
+ifeq (${MT_SPM_UART_SUSPEND_SUPPORT},n)
+$(eval $(call add_define,MTK_PLAT_SPM_UART_UNSUPPORT))
+endif
+
+ifeq ($(MTK_VOLTAGE_BIN_VCORE),y)
+$(eval $(call add_define,MTK_VOLTAGE_BIN_VCORE_SUPPORT))
+endif
+
+ifeq ($(MT_SPM_RGU_SUPPORT),n)
+$(eval $(call add_define,MTK_PLAT_SPM_RGU_UNSUPPORT))
+endif
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/spm/mt8188/sleep_def.h b/plat/mediatek/drivers/spm/mt8188/sleep_def.h
new file mode 100644
index 0000000..09a575b
--- /dev/null
+++ b/plat/mediatek/drivers/spm/mt8188/sleep_def.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SLEEP_DEF_H
+#define SLEEP_DEF_H
+
+/*
+ * Auto generated by DE, please DO NOT modify this file directly.
+ */
+
+/* --- SPM Flag Define --- */
+#define SPM_FLAG_DISABLE_CPU_PDN              (1U << 0)
+#define SPM_FLAG_DISABLE_INFRA_PDN            (1U << 1)
+#define SPM_FLAG_DISABLE_DDRPHY_PDN           (1U << 2)
+#define SPM_FLAG_DISABLE_VCORE_DVS            (1U << 3)
+#define SPM_FLAG_DISABLE_VCORE_DFS            (1U << 4)
+#define SPM_FLAG_DISABLE_COMMON_SCENARIO      (1U << 5)
+#define SPM_FLAG_DISABLE_BUS_CLK_OFF          (1U << 6)
+#define SPM_FLAG_DISABLE_ARMPLL_OFF           (1U << 7)
+#define SPM_FLAG_KEEP_CSYSPWRACK_HIGH         (1U << 8)
+#define SPM_FLAG_ENABLE_LVTS_WORKAROUND       (1U << 9)
+#define SPM_FLAG_RUN_COMMON_SCENARIO          (1U << 10)
+#define SPM_FLAG_PERI_ON_IN_SUSPEND           (1U << 11)
+#define SPM_FLAG_ENABLE_SPM_DBG_WDT_DUMP      (1U << 12)
+#define SPM_FLAG_USE_SRCCLKENO2               (1U << 13)
+#define SPM_FLAG_ENABLE_6315_CTRL             (1U << 14)
+#define SPM_FLAG_ENABLE_TIA_WORKAROUND        (1U << 15)
+#define SPM_FLAG_DISABLE_SYSRAM_SLEEP         (1U << 16)
+#define SPM_FLAG_DISABLE_SSPM_SRAM_SLEEP      (1U << 17)
+#define SPM_FLAG_DISABLE_MCUPM_SRAM_SLEEP     (1U << 18)
+#define SPM_FLAG_DISABLE_DRAMC_ISSUE_CMD      (1U << 19)
+#define SPM_FLAG_ENABLE_VOLTAGE_BIN           (1U << 20)
+#define SPM_FLAG_RESERVED_BIT21               (1U << 21)
+#define SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP (1U << 22)
+#define SPM_FLAG_DISABLE_DRAMC_MD32_BACKUP    (1U << 23)
+#define SPM_FLAG_RESERVED_BIT24               (1U << 24)
+#define SPM_FLAG_RESERVED_BIT25               (1U << 25)
+#define SPM_FLAG_RESERVED_BIT26               (1U << 26)
+#define SPM_FLAG_VTCXO_STATE                  (1U << 27)
+#define SPM_FLAG_INFRA_STATE                  (1U << 28)
+#define SPM_FLAG_APSRC_STATE                  (1U << 29)
+#define SPM_FLAG_VRF18_STATE                  (1U << 30)
+#define SPM_FLAG_DDREN_STATE                  (1U << 31)
+/* --- SPM Flag1 Define --- */
+#define SPM_FLAG1_DISABLE_AXI_BUS_TO_26M      (1U << 0)
+#define SPM_FLAG1_DISABLE_SYSPLL_OFF          (1U << 1)
+#define SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH    (1U << 2)
+#define SPM_FLAG1_DISABLE_ULPOSC_OFF          (1U << 3)
+#define SPM_FLAG1_FW_SET_ULPOSC_ON            (1U << 4)
+#define SPM_FLAG1_RESERVED_BIT5               (1U << 5)
+#define SPM_FLAG1_ENABLE_REKICK               (1U << 6)
+#define SPM_FLAG1_RESERVED_BIT7               (1U << 7)
+#define SPM_FLAG1_RESERVED_BIT8               (1U << 8)
+#define SPM_FLAG1_RESERVED_BIT9               (1U << 9)
+#define SPM_FLAG1_DISABLE_SRCLKEN_LOW         (1U << 10)
+#define SPM_FLAG1_DISABLE_SCP_CLK_SWITCH      (1U << 11)
+#define SPM_FLAG1_RESERVED_BIT12              (1U << 12)
+#define SPM_FLAG1_RESERVED_BIT13              (1U << 13)
+#define SPM_FLAG1_RESERVED_BIT14              (1U << 14)
+#define SPM_FLAG1_RESERVED_BIT15              (1U << 15)
+#define SPM_FLAG1_RESERVED_BIT16              (1U << 16)
+#define SPM_FLAG1_RESERVED_BIT17              (1U << 17)
+#define SPM_FLAG1_RESERVED_BIT18              (1U << 18)
+#define SPM_FLAG1_RESERVED_BIT19              (1U << 19)
+#define SPM_FLAG1_DISABLE_DEVAPC_SRAM_SLEEP   (1U << 20)
+#define SPM_FLAG1_RESERVED_BIT21              (1U << 21)
+#define SPM_FLAG1_ENABLE_VS1_VOTER            (1U << 22)
+#define SPM_FLAG1_ENABLE_VS2_VOTER            (1U << 23)
+#define SPM_FLAG1_DISABLE_SCP_VREQ_MASK_CONTROL   (1U << 24)
+#define SPM_FLAG1_RESERVED_BIT25              (1U << 25)
+#define SPM_FLAG1_RESERVED_BIT26              (1U << 26)
+#define SPM_FLAG1_RESERVED_BIT27              (1U << 27)
+#define SPM_FLAG1_RESERVED_BIT28              (1U << 28)
+#define SPM_FLAG1_RESERVED_BIT29              (1U << 29)
+#define SPM_FLAG1_RESERVED_BIT30              (1U << 30)
+#define SPM_FLAG1_RESERVED_BIT31              (1U << 31)
+/* --- SPM DEBUG Define --- */
+#define SPM_DBG_DEBUG_IDX_26M_WAKE            (1U << 0)
+#define SPM_DBG_DEBUG_IDX_26M_SLEEP           (1U << 1)
+#define SPM_DBG_DEBUG_IDX_INFRA_WAKE          (1U << 2)
+#define SPM_DBG_DEBUG_IDX_INFRA_SLEEP         (1U << 3)
+#define SPM_DBG_DEBUG_IDX_APSRC_WAKE          (1U << 4)
+#define SPM_DBG_DEBUG_IDX_APSRC_SLEEP         (1U << 5)
+#define SPM_DBG_DEBUG_IDX_VRF18_WAKE          (1U << 6)
+#define SPM_DBG_DEBUG_IDX_VRF18_SLEEP         (1U << 7)
+#define SPM_DBG_DEBUG_IDX_DDREN_WAKE          (1U << 8)
+#define SPM_DBG_DEBUG_IDX_DDREN_SLEEP         (1U << 9)
+#define SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_APSRC    (1U << 10)
+#define SPM_DBG_DEBUG_IDX_MCUPM_SRAM_STATE    (1U << 11)
+#define SPM_DBG_DEBUG_IDX_SSPM_SRAM_STATE     (1U << 12)
+#define SPM_DBG_DEBUG_IDX_DRAM_SREF_ABORT_IN_DDREN    (1U << 13)
+#define SPM_DBG_DEBUG_IDX_DRAMC_MCU_SRAM_STATE   (1U << 14)
+#define SPM_DBG_DEBUG_IDX_SYSRAM_SLP          (1U << 15)
+#define SPM_DBG_DEBUG_IDX_SYSRAM_ON           (1U << 16)
+#define SPM_DBG_DEBUG_IDX_MCUPM_SRAM_SLP      (1U << 17)
+#define SPM_DBG_DEBUG_IDX_MCUPM_SRAM_ON       (1U << 18)
+#define SPM_DBG_DEBUG_IDX_SSPM_SRAM_SLP       (1U << 19)
+#define SPM_DBG_DEBUG_IDX_SSPM_SRAM_ON        (1U << 20)
+#define SPM_DBG_DEBUG_IDX_DRAMC_MCU_SRAM_SLP    (1U << 21)
+#define SPM_DBG_DEBUG_IDX_DRAMC_MCU_SRAM_ON    (1U << 22)
+#define SPM_DBG_DEBUG_IDX_SCP_VCORE_0P575V    (1U << 23)
+#define SPM_DBG_DEBUG_IDX_SCP_VCORE_0P600V    (1U << 24)
+#define SPM_DBG_DEBUG_IDX_SCP_VCORE_0P650V    (1U << 25)
+#define SPM_DBG_DEBUG_IDX_SCP_VCORE_0P725V    (1U << 26)
+#define SPM_DBG_DEBUG_IDX_SPM_GO_WAKEUP_NOW   (1U << 27)
+#define SPM_DBG_DEBUG_IDX_VTCXO_STATE         (1U << 28)
+#define SPM_DBG_DEBUG_IDX_INFRA_STATE         (1U << 29)
+#define SPM_DBG_DEBUG_IDX_VRR18_STATE         (1U << 30)
+#define SPM_DBG_DEBUG_IDX_APSRC_STATE         (1U << 31)
+/* --- SPM DEBUG1 Define --- */
+#define SPM_DBG1_DEBUG_IDX_CURRENT_IS_LP      (1U << 0)
+#define SPM_DBG1_DEBUG_IDX_VCORE_DVFS_START   (1U << 1)
+#define SPM_DBG1_DEBUG_IDX_SYSPLL_OFF         (1U << 2)
+#define SPM_DBG1_DEBUG_IDX_SYSPLL_ON          (1U << 3)
+#define SPM_DBG1_DEBUG_IDX_CURRENT_IS_VCORE_DVFS   (1U << 4)
+#define SPM_DBG1_DEBUG_IDX_INFRA_MTCMOS_OFF   (1U << 5)
+#define SPM_DBG1_DEBUG_IDX_INFRA_MTCMOS_ON    (1U << 6)
+#define SPM_DBG1_DEBUG_IDX_VRCXO_SLEEP_ABORT   (1U << 7)
+#define SPM_DBG1_RESERVED_BIT8                (1U << 8)
+#define SPM_DBG1_DEBUG_IDX_INFRA_SUB_MTCMOS_OFF   (1U << 9)
+#define SPM_DBG1_DEBUG_IDX_INFRA_SUB_MTCMOS_ON   (1U << 10)
+#define SPM_DBG1_DEBUG_IDX_PWRAP_CLK_TO_ULPOSC   (1U << 11)
+#define SPM_DBG1_DEBUG_IDX_PWRAP_CLK_TO_26M   (1U << 12)
+#define SPM_DBG1_DEBUG_IDX_SCP_CLK_TO_32K     (1U << 13)
+#define SPM_DBG1_DEBUG_IDX_SCP_CLK_TO_26M     (1U << 14)
+#define SPM_DBG1_DEBUG_IDX_BUS_CLK_OFF        (1U << 15)
+#define SPM_DBG1_DEBUG_IDX_BUS_CLK_ON         (1U << 16)
+#define SPM_DBG1_DEBUG_IDX_SRCLKEN2_LOW       (1U << 17)
+#define SPM_DBG1_DEBUG_IDX_SRCLKEN2_HIGH      (1U << 18)
+#define SPM_DBG1_RESERVED_BIT19               (1U << 19)
+#define SPM_DBG1_DEBUG_IDX_ULPOSC_IS_OFF_BUT_SHOULD_ON   (1U << 20)
+#define SPM_DBG1_DEBUG_IDX_6315_LOW		(1U << 21)
+#define SPM_DBG1_DEBUG_IDX_6315_HIGH		(1U << 22)
+#define SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_LOW_ABORT   (1U << 23)
+#define SPM_DBG1_DEBUG_IDX_PWRAP_SLEEP_ACK_HIGH_ABORT   (1U << 24)
+#define SPM_DBG1_DEBUG_IDX_EMI_SLP_IDLE_ABORT   (1U << 25)
+#define SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_LOW_ABORT   (1U << 26)
+#define SPM_DBG1_DEBUG_IDX_SCP_SLP_ACK_HIGH_ABORT   (1U << 27)
+#define SPM_DBG1_DEBUG_IDX_SPM_DVFS_CMD_RDY_ABORT   (1U << 28)
+#define SPM_DBG1_RESERVED_BIT29               (1U << 29)
+#define SPM_DBG1_RESERVED_BIT30               (1U << 30)
+#define SPM_DBG1_RESERVED_BIT31               (1U << 31)
+
+/*
+ * Macro and Inline
+ */
+#define is_cpu_pdn(flags)		((flags) & SPM_FLAG_DIS_CPU_PDN == 0)
+#define is_infra_pdn(flags)		((flags) & SPM_FLAG_DIS_INFRA_PDN == 0)
+#define is_ddrphy_pdn(flags)		((flags) & SPM_FLAG_DIS_DDRPHY_PDN == 0)
+
+#endif /* SLEEP_DEF_H */
diff --git a/plat/mediatek/drivers/spm/rules.mk b/plat/mediatek/drivers/spm/rules.mk
new file mode 100644
index 0000000..b7128db
--- /dev/null
+++ b/plat/mediatek/drivers/spm/rules.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+MODULE := spm
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
+
+ifneq ($(CONFIG_MTK_SPM_VERSION),)
+PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC)
+PLAT_INCLUDES += -I${LOCAL_DIR}/version/notifier/inc
+
+SUB_RULES-y += ${LOCAL_DIR}/$(CONFIG_MTK_SPM_VERSION)
+$(eval $(call add_define,SPM_PLAT_IMPL))
+endif
+
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/spm/version/notifier/inc/mt_spm_notifier.h b/plat/mediatek/drivers/spm/version/notifier/inc/mt_spm_notifier.h
new file mode 100644
index 0000000..4d12624
--- /dev/null
+++ b/plat/mediatek/drivers/spm/version/notifier/inc/mt_spm_notifier.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_NOTIFIER_H
+#define MT_SPM_NOTIFIER_H
+
+enum mt_spm_sspm_notify_id {
+	MT_SPM_NOTIFY_LP_ENTER = 0,
+	MT_SPM_NOTIFY_LP_LEAVE,
+	MT_SPM_NOTIFY_SUSPEND_VCORE_VOLTAGE,
+};
+
+#ifdef MTK_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
+static inline int mt_spm_sspm_notify_u32(int type, unsigned int val)
+{
+	(void)type;
+	(void)val;
+	return 0;
+}
+#else
+int mt_spm_sspm_notify_u32(int type, unsigned int val);
+#endif
+
+#endif /* MT_SPM_NOTIFIER_H */
diff --git a/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_intc.h b/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_intc.h
new file mode 100644
index 0000000..e57a966
--- /dev/null
+++ b/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_intc.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_SSPM_INTC_H
+#define MT_SPM_SSPM_INTC_H
+
+#include <mt_spm_reg.h>
+
+#define MT_SPM_SSPM_INTC_SEL_0	(0x10)
+#define MT_SPM_SSPM_INTC_SEL_1	(0x20)
+#define MT_SPM_SSPM_INTC_SEL_2	(0x40)
+#define MT_SPM_SSPM_INTC_SEL_3	(0x80)
+
+#define MT_SPM_SSPM_INTC_TRIGGER(id, sg)	(((0x10 << (id)) | (sg << (id))) & 0xFF)
+
+#define MT_SPM_SSPM_INTC0_HIGH	MT_SPM_SSPM_INTC_TRIGGER(0, 1)
+#define MT_SPM_SSPM_INTC0_LOW	MT_SPM_SSPM_INTC_TRIGGER(0, 0)
+
+#define MT_SPM_SSPM_INTC1_HIGH	MT_SPM_SSPM_INTC_TRIGGER(1, 1)
+#define MT_SPM_SSPM_INTC1_LOW	MT_SPM_SSPM_INTC_TRIGGER(1, 0)
+
+#define MT_SPM_SSPM_INTC2_HIGH	MT_SPM_SSPM_INTC_TRIGGER(2, 1)
+#define MT_SPM_SSPM_INTC2_LOW	MT_SPM_SSPM_INTC_TRIGGER(2, 0)
+
+#define MT_SPM_SSPM_INTC3_HIGH	MT_SPM_SSPM_INTC_TRIGGER(3, 1)
+#define MT_SPM_SSPM_INTC3_LOW	MT_SPM_SSPM_INTC_TRIGGER(3, 0)
+
+#define DO_SPM_SSPM_LP_SUSPEND()	mmio_write_32(SPM_MD32_IRQ, MT_SPM_SSPM_INTC0_HIGH)
+
+#define DO_SPM_SSPM_LP_RESUME()		mmio_write_32(SPM_MD32_IRQ, MT_SPM_SSPM_INTC0_LOW)
+
+#endif /* MT_SPM_SSPM_INTC_H */
diff --git a/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_notifier.c b/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_notifier.c
new file mode 100644
index 0000000..081988f
--- /dev/null
+++ b/plat/mediatek/drivers/spm/version/notifier/v1/mt_spm_sspm_notifier.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include "mt_spm_notifier.h"
+#include "mt_spm_sspm_intc.h"
+#include <platform_def.h>
+
+#define MT_SPM_SSPM_MBOX_OFF(x)	(SSPM_MBOX_3_BASE + x)
+#define MT_SPM_MBOX(slot)	MT_SPM_SSPM_MBOX_OFF((slot << 2UL))
+
+/* LOOKUP SSPM_MBOX_SPM_LP1 */
+#define SSPM_MBOX_SPM_LP_LOOKUP1	MT_SPM_MBOX(0)
+/* LOOKUP SSPM_MBOX_SPM_LP2 */
+#define SSPM_MBOX_SPM_LP_LOOKUP2	MT_SPM_MBOX(1)
+
+#define SSPM_MBOX_SPM_LP1		MT_SPM_MBOX(2)
+#define SSPM_MBOX_SPM_LP2		MT_SPM_MBOX(3)
+
+int mt_spm_sspm_notify_u32(int type, unsigned int val)
+{
+	switch (type) {
+	case MT_SPM_NOTIFY_LP_ENTER:
+		mmio_write_32(SSPM_MBOX_SPM_LP1, val);
+		DO_SPM_SSPM_LP_SUSPEND();
+		break;
+	case MT_SPM_NOTIFY_LP_LEAVE:
+		mmio_write_32(SSPM_MBOX_SPM_LP1, val);
+		DO_SPM_SSPM_LP_RESUME();
+		break;
+	default:
+		panic();
+		break;
+	}
+	return 0;
+}
diff --git a/plat/mediatek/drivers/usb/mt8188/mt_usb.c b/plat/mediatek/drivers/usb/mt8188/mt_usb.c
new file mode 100644
index 0000000..c9e7a56
--- /dev/null
+++ b/plat/mediatek/drivers/usb/mt8188/mt_usb.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <lpm/mt_lp_api.h>
+#include <platform_def.h>
+
+int mt_usb_init(void)
+{
+	INFO("[%s] mt_usb initialization\n", __func__);
+
+	/* Keep infra and peri on to support wake-up from USB */
+	mtk_usb_update(LPM_USB_ENTER);
+
+	return 0;
+}
+MTK_PLAT_SETUP_0_INIT(mt_usb_init);
diff --git a/plat/mediatek/drivers/usb/rules.mk b/plat/mediatek/drivers/usb/rules.mk
new file mode 100644
index 0000000..f8c43f1
--- /dev/null
+++ b/plat/mediatek/drivers/usb/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2023, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := usb
+
+LOCAL_SRCS-y := $(LOCAL_DIR)/$(MTK_SOC)/mt_usb.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/include/drivers/spm/mt_spm_resource_req.h b/plat/mediatek/include/drivers/spm/mt_spm_resource_req.h
new file mode 100644
index 0000000..890bacc
--- /dev/null
+++ b/plat/mediatek/include/drivers/spm/mt_spm_resource_req.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SPM_RESOURCE_REQ_H
+#define MT_SPM_RESOURCE_REQ_H
+
+/* SPM resource request internal bit */
+#define MT_SPM_BIT_XO_FPM	(0U)
+#define MT_SPM_BIT_26M		(1U)
+#define MT_SPM_BIT_INFRA	(2U)
+#define MT_SPM_BIT_SYSPLL	(3U)
+#define MT_SPM_BIT_DRAM_S0	(4U)
+#define MT_SPM_BIT_DRAM_S1	(5U)
+
+/* SPM resource request internal bit_mask */
+#define MT_SPM_XO_FPM	BIT(MT_SPM_BIT_XO_FPM)
+#define MT_SPM_26M	BIT(MT_SPM_BIT_26M)
+#define MT_SPM_INFRA	BIT(MT_SPM_BIT_INFRA)
+#define MT_SPM_SYSPLL	BIT(MT_SPM_BIT_SYSPLL)
+#define MT_SPM_DRAM_S0	BIT(MT_SPM_BIT_DRAM_S0)
+#define MT_SPM_DRAM_S1	BIT(MT_SPM_BIT_DRAM_S1)
+
+#endif /* MT_SPM_RESOURCE_REQ_H */
diff --git a/plat/mediatek/include/lpm/mt_lp_api.h b/plat/mediatek/include/lpm/mt_lp_api.h
new file mode 100644
index 0000000..00a2802
--- /dev/null
+++ b/plat/mediatek/include/lpm/mt_lp_api.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_LP_API_H
+#define MT_LP_API_H
+
+#include <lpm/mt_lp_rm.h>
+
+#if MTK_PUBEVENT_ENABLE
+#include <vendor_pubsub_events.h>
+#endif
+
+/* Ufs clk enum for PLAT_RC_CLKBUF_STATUS */
+enum rc_update_ex_ufs_ref_clk {
+	UFS_REF_CLK_OFF = 0,
+	UFS_REF_CLK_ON,
+};
+
+/* Enum for flight mode  */
+enum rc_update_ex_flight_mode {
+	FLIGHT_MODE_OFF = 0,
+	FLIGHT_MODE_ON,
+};
+
+struct mt_lpm_pubevent_data {
+	unsigned int u32;
+};
+
+enum mt_lpm_pubevents_id {
+	MT_LPM_PUBEVENTS_BBLPM_ENTER,
+	MT_LPM_PUBEVENTS_BBLPM_LEAVE,
+	MT_LPM_PUBEVENTS_TARGET_CORE,
+	MT_LPM_PUBEVENTS_SYS_POWER_OFF,
+	MT_LPM_PUBEVENTS_SYS_POWER_ON,
+};
+
+struct mt_lp_publish_event {
+	unsigned int id;
+	struct mt_lpm_pubevent_data val;
+};
+
+#if MTK_PUBEVENT_ENABLE
+#define MT_LP_PUBLISH_EVENT(x) ({\
+	PUBLISH_EVENT_ARG(lpm_publish_event, (const void *)(x)); })
+#define MT_LP_SUSPEND_PUBLISH_EVENT(x) ({\
+	PUBLISH_EVENT_ARG(suspend_publish_event, (const void *)(x)); })
+
+#define MT_LP_SUBSCRIBE_SUSPEND(func)	SUBSCRIBE_TO_EVENT(suspend_publish_event, func)
+#define MT_LP_SUBSCRIBE_LPM(func)	SUBSCRIBE_TO_EVENT(lpm_publish_event, func)
+#else
+#define MT_LP_PUBLISH_EVENT(x) ({ (void)x; })
+#define MT_LP_SUSPEND_PUBLISH_EVENT(x) ({ (void)x; })
+#define MT_LP_SUBSCRIBE_SUSPEND(func)
+#define MT_LP_SUBSCRIBE_LPM(func)
+#endif
+
+/* MTK low power API types for audio */
+enum mt_lp_api_audio_type {
+	AUDIO_AFE_ENTER,
+	AUDIO_AFE_LEAVE,
+	AUDIO_DSP_ENTER,
+	AUDIO_DSP_LEAVE,
+};
+
+/* MTK low power API types for usb */
+enum mt_lp_api_usb_type {
+	LPM_USB_ENTER,
+	LPM_USB_LEAVE,
+};
+
+int mt_audio_update(int type);
+int mtk_usb_update(int type);
+
+#endif /* MT_LP_API_H */
diff --git a/plat/mediatek/include/lpm/mt_lp_rm.h b/plat/mediatek/include/lpm/mt_lp_rm.h
new file mode 100644
index 0000000..bf99489
--- /dev/null
+++ b/plat/mediatek/include/lpm/mt_lp_rm.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2020-2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_LP_RM_H
+#define MT_LP_RM_H
+
+#include <stdbool.h>
+
+#define MT_RM_STATUS_OK		(0)
+#define MT_RM_STATUS_BAD	(-1)
+#define MT_RM_STATUS_STOP	(-2)
+
+enum PLAT_MT_LPM_RC_TYPE {
+	PLAT_RC_UPDATE_CONDITION,
+	PLAT_RC_STATUS,
+	PLAT_RC_UPDATE_REMAIN_IRQS,
+	PLAT_RC_IS_FMAUDIO,
+	PLAT_RC_IS_ADSP,
+	PLAT_RC_ENTER_CNT,
+	PLAT_RC_CLKBUF_STATUS,
+	PLAT_RC_UFS_STATUS,
+	PLAT_RC_IS_USB_PERI,
+	PLAT_RC_IS_USB_INFRA,
+	PLAT_RC_MAX,
+};
+
+enum plat_mt_lpm_hw_ctrl_type {
+	PLAT_AP_MDSRC_REQ,
+	PLAT_AP_MDSRC_ACK,
+	PLAT_AP_IS_MD_SLEEP,
+	PLAT_AP_MDSRC_SETTLE,
+	PLAT_AP_GPUEB_PLL_CONTROL,
+	PLAT_AP_GPUEB_GET_PWR_STATUS,
+	PLAT_AP_HW_CTRL_MAX,
+};
+
+struct mt_resource_constraint {
+	int level;
+	int (*init)(void);
+	bool (*is_valid)(unsigned int cpu, int stateid);
+	int (*update)(int stateid, int type, const void *p);
+	int (*run)(unsigned int cpu, int stateid);
+	int (*reset)(unsigned int cpu, int stateid);
+	int (*get_status)(unsigned int type, void *priv);
+	unsigned int (*allow)(int stateid);
+};
+
+struct mt_resource_manager {
+	int (*update)(struct mt_resource_constraint **con, unsigned int num,
+		      int stateid, void *priv);
+	struct mt_resource_constraint **consts;
+};
+
+extern int mt_lp_rm_register(struct mt_resource_manager *rm);
+extern int mt_lp_rm_do_constraint(unsigned int constraint_id, unsigned int cpuid, int stateid);
+extern int mt_lp_rm_find_constraint(unsigned int idx, unsigned int cpuid,
+				    int stateid, void *priv);
+extern int mt_lp_rm_find_and_run_constraint(unsigned int idx, unsigned int cpuid,
+					    int stateid, void *priv);
+extern int mt_lp_rm_reset_constraint(unsigned int idx, unsigned int cpuid, int stateid);
+extern int mt_lp_rm_do_update(int stateid, int type, void const *p);
+extern int mt_lp_rm_get_status(unsigned int type, void *priv);
+
+#endif /* MT_LP_RM_H */
diff --git a/plat/mediatek/include/lpm/mt_lp_rq.h b/plat/mediatek/include/lpm/mt_lp_rq.h
new file mode 100644
index 0000000..2c4908c
--- /dev/null
+++ b/plat/mediatek/include/lpm/mt_lp_rq.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_LP_RQ_H
+#define MT_LP_RQ_H
+
+/* Determine the generic resource request public type */
+#define MT_LP_RQ_XO_FPM		BIT(0)
+#define MT_LP_RQ_26M		BIT(1)
+#define MT_LP_RQ_INFRA		BIT(2)
+#define MT_LP_RQ_SYSPLL		BIT(3)
+#define MT_LP_RQ_DRAM		BIT(4)
+#define MT_LP_RQ_ALL		(0xFFFFFFFF)
+
+struct mt_lp_resource_user {
+	/* Determine the resource user mask */
+	unsigned int umask;
+	/* Determine the resource request user identify */
+	unsigned int uid;
+	/* Request the resource */
+	int (*request)(struct mt_lp_resource_user *this, unsigned int resource);
+	/* Release the resource */
+	int (*release)(struct mt_lp_resource_user *this);
+};
+
+int mt_lp_resource_user_register(char *uname, struct mt_lp_resource_user *ru);
+
+#endif /* MT_LP_RQ_H */
diff --git a/plat/mediatek/include/lpm/mt_lp_rqm.h b/plat/mediatek/include/lpm/mt_lp_rqm.h
new file mode 100644
index 0000000..c30f762
--- /dev/null
+++ b/plat/mediatek/include/lpm/mt_lp_rqm.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_LP_RQM_H
+#define MT_LP_RQM_H
+
+#include "mt_lp_rq.h"
+
+enum plat_mt_lpm_rq_update_type {
+	PLAT_RQ_USER_NUM,
+	PLAT_RQ_USER_VALID,
+	PLAT_RQ_USER_REQ,
+	PLAT_RQ_USER_REL,
+	PLAT_RQ_PER_USER_NAME,
+	PLAT_RQ_REQ_NUM,
+	PLAT_RQ_REQ_USAGE,
+};
+
+/* Determine the request valid */
+#define MT_LP_RQ_VALID		(0x1)
+#define MT_LP_RQ_INVALID	(0x0)
+
+/* Determine the request user opertions */
+#define MT_LP_RQ_USER_INVALID	(-1)
+#define MT_LP_RQ_USER_MAX	(32)
+#define MT_LP_RQ_USER_NAME_LEN	(4)
+#define MT_LP_RQ_USER_CHAR_U	(8)
+
+/* Determine the request update flag */
+#define MT_LP_RQ_FLAG_DONE		(0)
+#define MT_LP_RQ_FLAG_NEED_UPDATE	BIT(6)
+
+/* Determine the resource update id */
+#define MT_LP_RQ_ID_ALL_USAGE	(-1)
+
+/* Determine the return status */
+#define MT_LP_RQ_STA_OK		(0)
+#define MT_LP_RQ_STA_BAD	(-1)
+
+struct mt_lp_res_req {
+	/* Determine the resource req public identify */
+	const unsigned int res_id;
+	/* Determine the resource bitwise internal control */
+	const unsigned int res_rq;
+	/* Determine the users per bit for current resource usage */
+	unsigned int res_usage;
+};
+
+struct mt_resource_req_manager {
+	/* Determine the set of resources */
+	struct mt_lp_res_req **res;
+};
+
+struct resource_req_status {
+	/* Determine the status id */
+	unsigned int id;
+	/* Determine the status value */
+	unsigned int val;
+};
+
+int mt_lp_resource_request_manager_register(struct mt_resource_req_manager *rqm);
+int mt_lp_rq_update_status(int type, void *p);
+int mt_lp_rq_get_status(int type, void *p);
+
+#endif /* MT_LP_RQM_H */
diff --git a/plat/mediatek/include/lpm/mt_lpm_smc.h b/plat/mediatek/include/lpm/mt_lpm_smc.h
new file mode 100644
index 0000000..0117ca9
--- /dev/null
+++ b/plat/mediatek/include/lpm/mt_lpm_smc.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_LPM_SMC_H
+#define MT_LPM_SMC_H
+
+/*
+ * MTK LPM smc user format:
+ * bit[31:24]: magic number
+ * bit[23:16]: user number
+ * bit[15:00]: user id
+ */
+
+#define MT_LPM_SMC_MAGIC	(0xDA000000)
+#define MT_LPM_SMC_MAGIC_MASK	(0xFF000000)
+#define MT_LPM_SMC_USER_MASK	(0xFF)
+#define MT_LPM_SMC_USER_SHIFT	(16)
+
+#define MT_LPM_SMC_USER_ID_MASK	(0x0000FFFF)
+
+/*
+ * cpu_pm is used for MCDI to read/write CPC information
+ * spm_dbg is used for spm related debug information
+ * spm is used for spm related settings
+ * cpu_pm_lp is used for MCDI setting irq_remain
+ */
+enum mt_lpm_smc_user_id {
+	MT_LPM_SMC_USER_CPU_PM = 0,
+	MT_LPM_SMC_USER_SPM_DBG,
+	MT_LPM_SMC_USER_SPM,
+	MT_LPM_SMC_USER_CPU_PM_LP,
+	MT_LPM_SMC_USER_SECURE_CPU_PM,
+	MT_LPM_SMC_USER_SECURE_SPM_DBG,
+	MT_LPM_SMC_USER_SECURE_SPM,
+	MT_LPM_SMC_USER_MAX,
+};
+
+#define IS_MT_LPM_SMC(smcid)	((smcid & MT_LPM_SMC_MAGIC_MASK) == MT_LPM_SMC_MAGIC)
+
+/* get real user id */
+#define MT_LPM_SMC_USER(id)	((id >> MT_LPM_SMC_USER_SHIFT) & MT_LPM_SMC_USER_MASK)
+#define MT_LPM_SMC_USER_ID(uid)	(uid & MT_LPM_SMC_USER_ID_MASK)
+
+/* sink user id to smc's user id */
+#define MT_LPM_SMC_USER_SINK(user, uid)	(((uid & MT_LPM_SMC_USER_ID_MASK) |\
+					((user & MT_LPM_SMC_USER_MASK) << MT_LPM_SMC_USER_SHIFT)) |\
+					MT_LPM_SMC_MAGIC)
+
+/* sink cpu pm's smc id */
+#define MT_LPM_SMC_USER_ID_CPU_PM(uid)	MT_LPM_SMC_USER_SINK(MT_LPM_SMC_USER_CPU_PM, uid)
+/* sink spm's smc id */
+#define MT_LPM_SMC_USER_ID_SPM(uid)	MT_LPM_SMC_USER_SINK(MT_LPM_SMC_USER_SPM, uid)
+
+/* sink cpu pm's user id */
+#define MT_LPM_SMC_USER_CPU_PM(uid)	MT_LPM_SMC_USER_ID_CPU_PM(uid)
+
+/* sink spm's user id */
+#define MT_LPM_SMC_USER_SPM(uid)	MT_LPM_SMC_USER_ID_SPM(uid)
+
+/* behavior */
+#define MT_LPM_SMC_ACT_SET		BIT(0)
+#define MT_LPM_SMC_ACT_CLR		BIT(1)
+#define MT_LPM_SMC_ACT_GET		BIT(2)
+#define MT_LPM_SMC_ACT_PUSH		BIT(3)
+#define MT_LPM_SMC_ACT_POP		BIT(4)
+#define MT_LPM_SMC_ACT_SUBMIT		BIT(5)
+
+/* compatible action for legacy smc from lk */
+#define MT_LPM_SMC_ACT_COMPAT		BIT(31)
+
+enum mt_lpm_spmc_compat_id {
+	MT_LPM_SPMC_COMPAT_LK_FW_INIT,
+	MT_LPM_SPMC_COMPAT_LK_MCDI_WDT_DUMP,
+};
+
+#endif /* MT_LPM_SMC_H */
diff --git a/plat/mediatek/mt8186/drivers/spm/mt_spm_cond.c b/plat/mediatek/mt8186/drivers/spm/mt_spm_cond.c
index a420e16..14a84b2 100644
--- a/plat/mediatek/mt8186/drivers/spm/mt_spm_cond.c
+++ b/plat/mediatek/mt8186/drivers/spm/mt_spm_cond.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -148,7 +148,8 @@
 	(((mmio_read_32(SPM_PWR_STATUS) & mask) == 0U) &&	\
 	 ((mmio_read_32(SPM_PWR_STATUS_2ND) & mask) == 0U))
 
-int mt_spm_cond_update(struct mt_resource_constraint **con, int stateid, void *priv)
+int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num,
+		       int stateid, void *priv)
 {
 	int res;
 	uint32_t i;
diff --git a/plat/mediatek/mt8186/drivers/spm/mt_spm_cond.h b/plat/mediatek/mt8186/drivers/spm/mt_spm_cond.h
index 24c39ba..28a3020 100644
--- a/plat/mediatek/mt8186/drivers/spm/mt_spm_cond.h
+++ b/plat/mediatek/mt8186/drivers/spm/mt_spm_cond.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -54,7 +54,7 @@
 				      const struct mt_spm_cond_tables *dest,
 				      struct mt_spm_cond_tables *res);
 
-extern int mt_spm_cond_update(struct mt_resource_constraint **con,
+extern int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num,
 			      int stateid, void *priv);
 
 #endif /* MT_SPM_CONDIT_H */
diff --git a/plat/mediatek/mt8186/platform.mk b/plat/mediatek/mt8186/platform.mk
index 68f4a1f..2bd2fb4 100644
--- a/plat/mediatek/mt8186/platform.mk
+++ b/plat/mediatek/mt8186/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
+# Copyright (c) 2021-2023, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,6 @@
 MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
-                 -I${MTK_PLAT}/common/lpm                         \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/gic600/                    \
                  -I${MTK_PLAT}/drivers/gpio/                      \
@@ -18,6 +17,7 @@
                  -I${MTK_PLAT}/drivers/timer/                     \
                  -I${MTK_PLAT}/drivers/uart/                      \
                  -I${MTK_PLAT}/include/                           \
+                 -I${MTK_PLAT}/include/lpm                        \
                  -I${MTK_PLAT_SOC}/drivers/spm/                   \
                  -I${MTK_PLAT_SOC}/drivers/dcm/                   \
                  -I${MTK_PLAT_SOC}/drivers/dfd/                   \
diff --git a/plat/mediatek/mt8188/include/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
index 156a7e2..34d4637 100644
--- a/plat/mediatek/mt8188/include/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,8 @@
 #define MTK_DEV_RNG1_BASE	(IO_PHYS)
 #define MTK_DEV_RNG1_SIZE	(0x10000000)
 
+#define TOPCKGEN_BASE		(IO_PHYS)
+
 /*******************************************************************************
  * AUDIO related constants
  ******************************************************************************/
@@ -57,6 +59,8 @@
 /*******************************************************************************
  * Infra IOMMU related constants
  ******************************************************************************/
+#define INFRACFG_AO_BASE	(IO_PHYS + 0x00001000)
+#define INFRACFG_AO_MEM_BASE	(IO_PHYS + 0x00002000)
 #define PERICFG_AO_BASE		(IO_PHYS + 0x01003000)
 #define PERICFG_AO_REG_SIZE	(0x1000)
 
@@ -108,6 +112,33 @@
 #define SMI_LARB_REG_RNG_SIZE	(0x1000)
 
 /*******************************************************************************
+ * SPM related constants
+ ******************************************************************************/
+#define SPM_BASE		(IO_PHYS + 0x00006000)
+
+/*******************************************************************************
+ * APMIXEDSYS related constants
+ ******************************************************************************/
+#define APMIXEDSYS		(IO_PHYS + 0x0000C000)
+
+/*******************************************************************************
+ * VPPSYS related constants
+ ******************************************************************************/
+#define VPPSYS0_BASE		(IO_PHYS + 0x04000000)
+#define VPPSYS1_BASE		(IO_PHYS + 0x04f00000)
+
+/*******************************************************************************
+ * VDOSYS related constants
+ ******************************************************************************/
+#define VDOSYS0_BASE		(IO_PHYS + 0x0C01D000)
+#define VDOSYS1_BASE		(IO_PHYS + 0x0C100000)
+
+/*******************************************************************************
+ * SSPM_MBOX_3 related constants
+ ******************************************************************************/
+#define SSPM_MBOX_3_BASE	(IO_PHYS + 0x00480000)
+
+/*******************************************************************************
  * DP related constants
  ******************************************************************************/
 #define EDP_SEC_BASE		(IO_PHYS + 0x0C504000)
diff --git a/plat/mediatek/mt8188/plat_config.mk b/plat/mediatek/mt8188/plat_config.mk
index 137318e..2e3392f 100644
--- a/plat/mediatek/mt8188/plat_config.mk
+++ b/plat/mediatek/mt8188/plat_config.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+# Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -41,6 +41,8 @@
 CONFIG_MTK_CPU_PM_ARCH := 3_2
 CONFIG_MTK_SMP_EN := y
 CONFIG_MTK_CPU_SUSPEND_EN := y
+CONFIG_MTK_SPM_VERSION := mt8188
+CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND := y
 CPU_PM_TINYSYS_SUPPORT := y
 MTK_PUBEVENT_ENABLE := y
 
diff --git a/plat/mediatek/mt8188/platform.mk b/plat/mediatek/mt8188/platform.mk
index b6a17aa..85ceeb9 100644
--- a/plat/mediatek/mt8188/platform.mk
+++ b/plat/mediatek/mt8188/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+# Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -39,7 +39,9 @@
 MODULES-y += $(MTK_PLAT)/drivers/pmic_wrap
 MODULES-y += $(MTK_PLAT)/drivers/ptp3
 MODULES-y += $(MTK_PLAT)/drivers/rtc
+MODULES-y += $(MTK_PLAT)/drivers/spm
 MODULES-y += $(MTK_PLAT)/drivers/timer
+MODULES-y += $(MTK_PLAT)/drivers/usb
 MODULES-y += $(MTK_PLAT)/helpers
 MODULES-y += $(MTK_PLAT)/topology
 
diff --git a/plat/mediatek/mt8192/drivers/spm/mt_spm_cond.c b/plat/mediatek/mt8192/drivers/spm/mt_spm_cond.c
index 2d67fdf..4332b70 100644
--- a/plat/mediatek/mt8192/drivers/spm/mt_spm_cond.c
+++ b/plat/mediatek/mt8192/drivers/spm/mt_spm_cond.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -155,7 +155,7 @@
 	(((mmio_read_32(SPM_PWR_STATUS) & mask) == 0U) &&	\
 	 ((mmio_read_32(SPM_PWR_STATUS_2ND) & mask) == 0U))
 
-int mt_spm_cond_update(struct mt_resource_constraint **con,
+int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num,
 		       int stateid, void *priv)
 {
 	int res;
diff --git a/plat/mediatek/mt8192/drivers/spm/mt_spm_cond.h b/plat/mediatek/mt8192/drivers/spm/mt_spm_cond.h
index 91ebdd9..ffd5f3f 100644
--- a/plat/mediatek/mt8192/drivers/spm/mt_spm_cond.h
+++ b/plat/mediatek/mt8192/drivers/spm/mt_spm_cond.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -51,6 +51,6 @@
 				      const struct mt_spm_cond_tables *src,
 				      const struct mt_spm_cond_tables *dest,
 				      struct mt_spm_cond_tables *res);
-extern int mt_spm_cond_update(struct mt_resource_constraint **con,
+extern int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num,
 			      int stateid, void *priv);
 #endif /* MT_SPM_CONDIT_H */
diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk
index a19fc45..4afd157 100644
--- a/plat/mediatek/mt8192/platform.mk
+++ b/plat/mediatek/mt8192/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
+# Copyright (c) 2020-2023, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,6 @@
 MTK_PLAT_SOC  := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
-                 -I${MTK_PLAT}/common/lpm/                        \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/gic600/                    \
                  -I${MTK_PLAT}/drivers/gpio/                      \
@@ -18,6 +17,7 @@
                  -I${MTK_PLAT}/drivers/timer/                     \
                  -I${MTK_PLAT}/drivers/uart/                      \
                  -I${MTK_PLAT}/include/                           \
+                 -I${MTK_PLAT}/include/lpm/                       \
                  -I${MTK_PLAT_SOC}/include/                       \
                  -I${MTK_PLAT_SOC}/drivers/                       \
                  -I${MTK_PLAT_SOC}/drivers/apusys/                \
diff --git a/plat/mediatek/mt8195/drivers/spm/mt_spm_cond.c b/plat/mediatek/mt8195/drivers/spm/mt_spm_cond.c
index c80faf5..0ca0e1d 100644
--- a/plat/mediatek/mt8195/drivers/spm/mt_spm_cond.c
+++ b/plat/mediatek/mt8195/drivers/spm/mt_spm_cond.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -171,7 +171,7 @@
 	(((mmio_read_32(SPM_PWR_STATUS) & mask) == 0U) &&	\
 	 ((mmio_read_32(SPM_PWR_STATUS_2ND) & mask) == 0U))
 
-int mt_spm_cond_update(struct mt_resource_constraint **con,
+int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num,
 		       int stateid, void *priv)
 {
 	int res;
diff --git a/plat/mediatek/mt8195/drivers/spm/mt_spm_cond.h b/plat/mediatek/mt8195/drivers/spm/mt_spm_cond.h
index e471b55..83007af 100644
--- a/plat/mediatek/mt8195/drivers/spm/mt_spm_cond.h
+++ b/plat/mediatek/mt8195/drivers/spm/mt_spm_cond.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2023, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,6 +68,6 @@
 				      const struct mt_spm_cond_tables *src,
 				      const struct mt_spm_cond_tables *dest,
 				      struct mt_spm_cond_tables *res);
-extern int mt_spm_cond_update(struct mt_resource_constraint **con,
+extern int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num,
 			      int stateid, void *priv);
 #endif /* MT_SPM_CONDIT_H */
diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk
index 07d39cb..48dafa3 100644
--- a/plat/mediatek/mt8195/platform.mk
+++ b/plat/mediatek/mt8195/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
+# Copyright (c) 2021-2023, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,6 @@
 MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
-                 -I${MTK_PLAT}/common/lpm/                        \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/dp/                        \
                  -I${MTK_PLAT}/drivers/gic600/                    \
@@ -20,6 +19,7 @@
                  -I${MTK_PLAT}/drivers/timer/                     \
                  -I${MTK_PLAT}/drivers/uart/                      \
                  -I${MTK_PLAT}/include/                           \
+                 -I${MTK_PLAT}/include/lpm/                       \
                  -I${MTK_PLAT_SOC}/drivers/apusys/                \
                  -I${MTK_PLAT_SOC}/drivers/dcm                    \
                  -I${MTK_PLAT_SOC}/drivers/dfd                    \
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index 81de674..2533013 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -20,7 +20,7 @@
 /*******************************************************************************
  * Array to hold stream_id override config register offsets
  ******************************************************************************/
-const static uint32_t tegra186_streamid_override_regs[] = {
+static const uint32_t tegra186_streamid_override_regs[] = {
 	MC_STREAMID_OVERRIDE_CFG_SDMMCRA,
 	MC_STREAMID_OVERRIDE_CFG_SDMMCRAA,
 	MC_STREAMID_OVERRIDE_CFG_SDMMCR,
@@ -34,7 +34,7 @@
 /*******************************************************************************
  * Array to hold the security configs for stream IDs
  ******************************************************************************/
-const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
+static const mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
 	mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, DISABLE),
@@ -112,7 +112,7 @@
 /*******************************************************************************
  * Array to hold the transaction override configs
  ******************************************************************************/
-const static mc_txn_override_cfg_t tegra186_txn_override_cfgs[] = {
+static const mc_txn_override_cfg_t tegra186_txn_override_cfgs[] = {
 	mc_make_txn_override_cfg(BPMPW, CGID_TAG_ADR),
 	mc_make_txn_override_cfg(EQOSW, CGID_TAG_ADR),
 	mc_make_txn_override_cfg(NVJPGSWR, CGID_TAG_ADR),
diff --git a/plat/nxp/common/psci/plat_psci.c b/plat/nxp/common/psci/plat_psci.c
index 9281e97..f6dd7b3 100644
--- a/plat/nxp/common/psci/plat_psci.c
+++ b/plat/nxp/common/psci/plat_psci.c
@@ -350,7 +350,7 @@
 		else if (SOC_SYSTEM_STANDBY)
 			state->pwr_domain_state[PLAT_MAX_LVL] =
 				PLAT_MAX_RET_STATE;
-		 /* intentional fall-thru condition */
+		 /* fallthrough */
 	case PWR_STATE_LVL_SYS:
 		if (pwrdn && SOC_SYSTEM_PWR_DWN)
 			state->pwr_domain_state[PLAT_SYS_LVL] =
@@ -358,7 +358,7 @@
 		else if (SOC_SYSTEM_STANDBY)
 			state->pwr_domain_state[PLAT_SYS_LVL] =
 				PLAT_MAX_RET_STATE;
-		 /* intentional fall-thru condition */
+		 /* fallthrough */
 	case PWR_STATE_LVL_CLSTR:
 		if (pwrdn && SOC_CLUSTER_PWR_DWN)
 			state->pwr_domain_state[PLAT_CLSTR_LVL] =
@@ -366,7 +366,7 @@
 		else if (SOC_CLUSTER_STANDBY)
 			state->pwr_domain_state[PLAT_CLSTR_LVL] =
 				PLAT_MAX_RET_STATE;
-		 /* intentional fall-thru condition */
+		 /* fallthrough */
 	case PWR_STATE_LVL_CORE:
 		stat = PSCI_E_SUCCESS;
 
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 5a6b1e1..2393b39 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -123,5 +123,6 @@
 ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
-# Do not enable SVE
-ENABLE_SVE_FOR_NS	:= 0
+# Later QEMU versions support SME and SVE.
+ENABLE_SVE_FOR_NS	:= 1
+ENABLE_SME_FOR_NS	:= 1
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
index 5f1b7aa..ae361e9 100644
--- a/plat/qti/common/src/qti_pm.c
+++ b/plat/qti/common/src/qti_pm.c
@@ -47,8 +47,7 @@
 #define QTI_CORE_PWRDN_EN_MASK		1
 
 /* cpu power control happens to be same across all CPUs */
-_DEFINE_SYSREG_WRITE_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7)
-_DEFINE_SYSREG_READ_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7)
+DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7)
 
 const unsigned int qti_pm_idle_states[] = {
 	qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_OFF,
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 1bbaff6..c935b7d 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -25,7 +25,6 @@
 #include <drivers/raw_nand.h>
 #include <drivers/spi_nand.h>
 #include <drivers/spi_nor.h>
-#include <drivers/st/io_mmc.h>
 #include <drivers/st/stm32_fmc2_nand.h>
 #include <drivers/st/stm32_qspi.h>
 #include <drivers/st/stm32_sdmmc2.h>
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index a5316b6..bb3401f 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2023, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -35,6 +35,9 @@
 /* Return the base address of the RCC peripheral */
 uintptr_t stm32mp_rcc_base(void);
 
+void stm32mp_gic_pcpu_init(void);
+void stm32mp_gic_init(void);
+
 /* Check MMU status to allow spinlock use */
 bool stm32mp_lock_available(void);
 
@@ -113,12 +116,15 @@
 int stm32mp_map_ddr_non_cacheable(void);
 int stm32mp_unmap_ddr(void);
 
-/* Functions to save and get boot peripheral info */
-void stm32_save_boot_interface(uint32_t interface, uint32_t instance);
+/* Function to save boot info */
+void stm32_save_boot_info(boot_api_context_t *boot_context);
+/* Function to get boot peripheral info */
 void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance);
+/* Function to get BOOT_MODE backup register address */
+uintptr_t stm32_get_bkpr_boot_mode_addr(void);
 
-/* Functions to save and get boot authentication status and partition used */
-void stm32_save_boot_auth(uint32_t auth_status, uint32_t boot_partition);
+/* Display board information from the value found in OTP fuse */
+void stm32_display_board_info(uint32_t board_id);
 
 #if PSA_FWU_SUPPORT
 void stm32mp1_fwu_set_boot_idx(void);
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index bb56bac..f842e16 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <drivers/st/stm32_console.h>
 #include <drivers/st/stm32mp_clkfunc.h>
 #include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
@@ -24,6 +25,36 @@
 #define HEADER_VERSION_MAJOR_MASK	GENMASK(23, 16)
 #define RESET_TIMEOUT_US_1MS		1000U
 
+/* Internal layout of the 32bit OTP word board_id */
+#define BOARD_ID_BOARD_NB_MASK		GENMASK_32(31, 16)
+#define BOARD_ID_BOARD_NB_SHIFT		16
+#define BOARD_ID_VARCPN_MASK		GENMASK_32(15, 12)
+#define BOARD_ID_VARCPN_SHIFT		12
+#define BOARD_ID_REVISION_MASK		GENMASK_32(11, 8)
+#define BOARD_ID_REVISION_SHIFT		8
+#define BOARD_ID_VARFG_MASK		GENMASK_32(7, 4)
+#define BOARD_ID_VARFG_SHIFT		4
+#define BOARD_ID_BOM_MASK		GENMASK_32(3, 0)
+
+#define BOARD_ID2NB(_id)		(((_id) & BOARD_ID_BOARD_NB_MASK) >> \
+					 BOARD_ID_BOARD_NB_SHIFT)
+#define BOARD_ID2VARCPN(_id)		(((_id) & BOARD_ID_VARCPN_MASK) >> \
+					 BOARD_ID_VARCPN_SHIFT)
+#define BOARD_ID2REV(_id)		(((_id) & BOARD_ID_REVISION_MASK) >> \
+					 BOARD_ID_REVISION_SHIFT)
+#define BOARD_ID2VARFG(_id)		(((_id) & BOARD_ID_VARFG_MASK) >> \
+					 BOARD_ID_VARFG_SHIFT)
+#define BOARD_ID2BOM(_id)		((_id) & BOARD_ID_BOM_MASK)
+
+#define BOOT_AUTH_MASK			GENMASK_32(23, 20)
+#define BOOT_AUTH_SHIFT			20
+#define BOOT_PART_MASK			GENMASK_32(19, 16)
+#define BOOT_PART_SHIFT			16
+#define BOOT_ITF_MASK			GENMASK_32(15, 12)
+#define BOOT_ITF_SHIFT			12
+#define BOOT_INST_MASK			GENMASK_32(11, 8)
+#define BOOT_INST_SHIFT			8
+
 static console_t console;
 
 uintptr_t plat_get_ns_image_entrypoint(void)
@@ -277,3 +308,69 @@
 {
 	return (int32_t)(stm32mp_get_chip_version() & SOC_ID_REV_MASK);
 }
+
+void stm32_display_board_info(uint32_t board_id)
+{
+	char rev[2];
+
+	rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
+	rev[1] = '\0';
+	NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
+	       BOARD_ID2NB(board_id),
+	       BOARD_ID2VARCPN(board_id),
+	       BOARD_ID2VARFG(board_id),
+	       rev,
+	       BOARD_ID2BOM(board_id));
+}
+
+void stm32_save_boot_info(boot_api_context_t *boot_context)
+{
+	uint32_t auth_status;
+
+	assert(boot_context->boot_interface_instance <= (BOOT_INST_MASK >> BOOT_INST_SHIFT));
+	assert(boot_context->boot_interface_selected <= (BOOT_ITF_MASK >> BOOT_ITF_SHIFT));
+	assert(boot_context->boot_partition_used_toboot <= (BOOT_PART_MASK >> BOOT_PART_SHIFT));
+
+	switch (boot_context->auth_status) {
+	case BOOT_API_CTX_AUTH_NO:
+		auth_status = 0x0U;
+		break;
+
+	case BOOT_API_CTX_AUTH_SUCCESS:
+		auth_status = 0x2U;
+		break;
+
+	case BOOT_API_CTX_AUTH_FAILED:
+	default:
+		auth_status = 0x1U;
+		break;
+	}
+
+	clk_enable(TAMP_BKP_REG_CLK);
+
+	mmio_clrsetbits_32(stm32_get_bkpr_boot_mode_addr(),
+			   BOOT_ITF_MASK | BOOT_INST_MASK | BOOT_PART_MASK | BOOT_AUTH_MASK,
+			   (boot_context->boot_interface_instance << BOOT_INST_SHIFT) |
+			   (boot_context->boot_interface_selected << BOOT_ITF_SHIFT) |
+			   (boot_context->boot_partition_used_toboot << BOOT_PART_SHIFT) |
+			   (auth_status << BOOT_AUTH_SHIFT));
+
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+
+void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
+{
+	static uint32_t itf;
+
+	if (itf == 0U) {
+		clk_enable(TAMP_BKP_REG_CLK);
+
+		itf = mmio_read_32(stm32_get_bkpr_boot_mode_addr()) &
+		      (BOOT_ITF_MASK | BOOT_INST_MASK);
+
+		clk_disable(TAMP_BKP_REG_CLK);
+	}
+
+	*interface = (itf & BOOT_ITF_MASK) >> BOOT_ITF_SHIFT;
+	*instance = (itf & BOOT_INST_MASK) >> BOOT_INST_SHIFT;
+}
diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c
index acfe701..0da0019 100644
--- a/plat/st/common/stm32mp_crypto_lib.c
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -79,7 +79,7 @@
 	}
 }
 
-int get_plain_pk_from_asn1(void *pk_ptr, unsigned int pk_len, void **plain_pk,
+static int get_plain_pk_from_asn1(void *pk_ptr, unsigned int pk_len, void **plain_pk,
 			   unsigned int *len, int *pk_alg)
 {
 	int ret;
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 0b6cc78..1a59f0b 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -28,7 +28,7 @@
 #endif
 
 #if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
-io_block_spec_t metadata_block_spec = {
+static io_block_spec_t metadata_block_spec = {
 	.offset = 0,    /* To be filled at runtime */
 	.length = 0,    /* To be filled at runtime */
 };
diff --git a/plat/st/stm32mp1/stm32mp1_gic.c b/plat/st/common/stm32mp_gic.c
similarity index 75%
rename from plat/st/stm32mp1/stm32mp1_gic.c
rename to plat/st/common/stm32mp_gic.c
index 851a9cf..d02b635 100644
--- a/plat/st/stm32mp1/stm32mp1_gic.c
+++ b/plat/st/common/stm32mp_gic.c
@@ -1,21 +1,20 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <libfdt.h>
-
-#include <platform_def.h>
-
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/gicv2.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <lib/utils.h>
+#include <libfdt.h>
 #include <plat/common/platform.h>
 
+#include <platform_def.h>
+
-struct stm32_gic_instance {
+struct stm32mp_gic_instance {
 	uint32_t cells;
 	uint32_t phandle_node;
 };
@@ -24,7 +23,7 @@
  * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
  * interrupts.
  *****************************************************************************/
-static const interrupt_prop_t stm32mp1_interrupt_props[] = {
+static const interrupt_prop_t stm32mp_interrupt_props[] = {
 	PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0),
 	PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
 };
@@ -33,15 +32,15 @@
 static unsigned int target_mask_array[PLATFORM_CORE_COUNT] = {1, 2};
 
 static gicv2_driver_data_t platform_gic_data = {
-	.interrupt_props = stm32mp1_interrupt_props,
-	.interrupt_props_num = ARRAY_SIZE(stm32mp1_interrupt_props),
+	.interrupt_props = stm32mp_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(stm32mp_interrupt_props),
 	.target_masks = target_mask_array,
 	.target_masks_num = ARRAY_SIZE(target_mask_array),
 };
 
-static struct stm32_gic_instance stm32_gic;
+static struct stm32mp_gic_instance stm32mp_gic;
 
-void stm32mp1_gic_init(void)
+void stm32mp_gic_init(void)
 {
 	int node;
 	void *fdt;
@@ -71,20 +70,20 @@
 		panic();
 	}
 
-	stm32_gic.cells = fdt32_to_cpu(*cuint);
+	stm32mp_gic.cells = fdt32_to_cpu(*cuint);
 
-	stm32_gic.phandle_node = fdt_get_phandle(fdt, node);
-	if (stm32_gic.phandle_node == 0U) {
+	stm32mp_gic.phandle_node = fdt_get_phandle(fdt, node);
+	if (stm32mp_gic.phandle_node == 0U) {
 		panic();
 	}
 
 	gicv2_driver_init(&platform_gic_data);
 	gicv2_distif_init();
 
-	stm32mp1_gic_pcpu_init();
+	stm32mp_gic_pcpu_init();
 }
 
-void stm32mp1_gic_pcpu_init(void)
+void stm32mp_gic_pcpu_init(void)
 {
 	gicv2_pcpu_distif_init();
 	gicv2_set_pe_target_mask(plat_my_core_pos());
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 87d2d39..eeabd09 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -290,10 +290,7 @@
 		panic();
 	}
 
-	stm32_save_boot_interface(boot_context->boot_interface_selected,
-				  boot_context->boot_interface_instance);
-	stm32_save_boot_auth(boot_context->auth_status,
-			     boot_context->boot_partition_used_toboot);
+	stm32_save_boot_info(boot_context);
 
 #if STM32MP_USB_PROGRAMMER && STM32MP15
 	/* Deconfigure all UART RX pins configured by ROM code */
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 21ef60d..4a52255 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,9 +14,6 @@
 void stm32mp1_arch_security_setup(void);
 void stm32mp1_security_setup(void);
 
-void stm32mp1_gic_pcpu_init(void);
-void stm32mp1_gic_init(void);
-
 void stm32mp1_syscfg_init(void);
 void stm32mp1_syscfg_enable_io_compensation_start(void);
 void stm32mp1_syscfg_enable_io_compensation_finish(void);
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
index c4048fc..c455544 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -5,6 +5,7 @@
  */
 
 #include <common/desc_image_load.h>
+#include <plat/common/platform.h>
 
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 7eecf30..236296e 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -403,7 +403,6 @@
 BL2_SOURCES		+=	drivers/mmc/mmc.c					\
 				drivers/partition/gpt.c					\
 				drivers/partition/partition.c				\
-				drivers/st/io/io_mmc.c					\
 				drivers/st/mmc/stm32_sdmmc2.c
 endif
 
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index 1d754d9..f5184e7 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -32,7 +32,7 @@
 
 BL32_SOURCES		+=	${GICV2_SOURCES}			\
 				plat/common/plat_gicv2.c		\
-				plat/st/stm32mp1/stm32mp1_gic.c
+				plat/st/common/stm32mp_gic.c
 
 # Generic PSCI
 BL32_SOURCES		+=	plat/common/plat_psci_common.c
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index 50b0794..b46f4af 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,9 +7,8 @@
 #include <assert.h>
 #include <string.h>
 
-#include <platform_def.h>
-
 #include <arch_helpers.h>
+#include <bl32/sp_min/platform_sp_min.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
@@ -27,7 +26,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
-#include <platform_sp_min.h>
+#include <platform_def.h>
 
 /******************************************************************************
  * Placeholder variables for copying the arguments that have been passed to
@@ -181,7 +180,7 @@
 {
 	generic_delay_timer_init();
 
-	stm32mp1_gic_init();
+	stm32mp_gic_init();
 
 	if (stm32_iwdg_init() < 0) {
 		panic();
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index f0d8526..8cac4b5 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -548,6 +548,7 @@
  ******************************************************************************/
 #define TAMP_BASE			U(0x5C00A000)
 #define TAMP_BKP_REGISTER_BASE		(TAMP_BASE + U(0x100))
+#define TAMP_BKP_REG_CLK		RTCAPB
 #define TAMP_COUNTR			U(0x40)
 
 #if !(defined(__LINKER__) || defined(__ASSEMBLER__))
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
index 6e438c4..7439381 100644
--- a/plat/st/stm32mp1/stm32mp1_pm.c
+++ b/plat/st/stm32mp1/stm32mp1_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -118,7 +118,7 @@
  ******************************************************************************/
 static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-	stm32mp1_gic_pcpu_init();
+	stm32mp_gic_pcpu_init();
 
 	write_cntfrq_el0(cntfrq_core0);
 }
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index e6cb071..ea35055 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,37 +16,12 @@
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
-/* Internal layout of the 32bit OTP word board_id */
-#define BOARD_ID_BOARD_NB_MASK		GENMASK(31, 16)
-#define BOARD_ID_BOARD_NB_SHIFT		16
-#define BOARD_ID_VARCPN_MASK		GENMASK(15, 12)
-#define BOARD_ID_VARCPN_SHIFT		12
-#define BOARD_ID_REVISION_MASK		GENMASK(11, 8)
-#define BOARD_ID_REVISION_SHIFT		8
-#define BOARD_ID_VARFG_MASK		GENMASK(7, 4)
-#define BOARD_ID_VARFG_SHIFT		4
-#define BOARD_ID_BOM_MASK		GENMASK(3, 0)
-
-#define BOARD_ID2NB(_id)		(((_id) & BOARD_ID_BOARD_NB_MASK) >> \
-					 BOARD_ID_BOARD_NB_SHIFT)
-#define BOARD_ID2VARCPN(_id)		(((_id) & BOARD_ID_VARCPN_MASK) >> \
-					 BOARD_ID_VARCPN_SHIFT)
-#define BOARD_ID2REV(_id)		(((_id) & BOARD_ID_REVISION_MASK) >> \
-					 BOARD_ID_REVISION_SHIFT)
-#define BOARD_ID2VARFG(_id)		(((_id) & BOARD_ID_VARFG_MASK) >> \
-					 BOARD_ID_VARFG_SHIFT)
-#define BOARD_ID2BOM(_id)		((_id) & BOARD_ID_BOM_MASK)
-
 #if STM32MP13
 #define TAMP_BOOT_MODE_BACKUP_REG_ID	U(30)
 #endif
 #if STM32MP15
 #define TAMP_BOOT_MODE_BACKUP_REG_ID	U(20)
 #endif
-#define TAMP_BOOT_MODE_ITF_MASK		GENMASK(15, 8)
-#define TAMP_BOOT_MODE_ITF_SHIFT	8
-#define TAMP_BOOT_MODE_AUTH_MASK	GENMASK(23, 16)
-#define TAMP_BOOT_MODE_AUTH_SHIFT	16
 
 /*
  * Backup register to store fwu update information.
@@ -520,23 +495,14 @@
 
 void stm32mp_print_boardinfo(void)
 {
-	uint32_t board_id = 0;
+	uint32_t board_id = 0U;
 
 	if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
 		return;
 	}
 
 	if (board_id != 0U) {
-		char rev[2];
-
-		rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
-		rev[1] = '\0';
-		NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
-		       BOARD_ID2NB(board_id),
-		       BOARD_ID2VARCPN(board_id),
-		       BOARD_ID2VARFG(board_id),
-		       rev,
-		       BOARD_ID2BOM(board_id));
+		stm32_display_board_info(board_id);
 	}
 }
 
@@ -697,51 +663,9 @@
 }
 #endif
 
-void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
+uintptr_t stm32_get_bkpr_boot_mode_addr(void)
 {
-	uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
-
-	clk_enable(RTCAPB);
-
-	mmio_clrsetbits_32(bkpr_itf_idx,
-			   TAMP_BOOT_MODE_ITF_MASK,
-			   ((interface << 4) | (instance & 0xFU)) <<
-			   TAMP_BOOT_MODE_ITF_SHIFT);
-
-	clk_disable(RTCAPB);
-}
-
-void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
-{
-	static uint32_t itf;
-
-	if (itf == 0U) {
-		uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
-
-		clk_enable(RTCAPB);
-
-		itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
-			TAMP_BOOT_MODE_ITF_SHIFT;
-
-		clk_disable(RTCAPB);
-	}
-
-	*interface = itf >> 4;
-	*instance = itf & 0xFU;
-}
-
-void stm32_save_boot_auth(uint32_t auth_status, uint32_t boot_partition)
-{
-	uint32_t boot_status = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
-
-	clk_enable(RTCAPB);
-
-	mmio_clrsetbits_32(boot_status,
-			   TAMP_BOOT_MODE_AUTH_MASK,
-			   ((auth_status << 4) | (boot_partition & 0xFU)) <<
-			   TAMP_BOOT_MODE_AUTH_SHIFT);
-
-	clk_disable(RTCAPB);
+	return tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
 }
 
 #if PSA_FWU_SUPPORT
diff --git a/plat/ti/k3/board/generic/board.mk b/plat/ti/k3/board/generic/board.mk
index ef74cd6..58c966a 100644
--- a/plat/ti/k3/board/generic/board.mk
+++ b/plat/ti/k3/board/generic/board.mk
@@ -4,21 +4,9 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-BL32_BASE ?= 0x9e800000
-$(eval $(call add_define,BL32_BASE))
-
-PRELOADED_BL33_BASE ?= 0x80080000
-$(eval $(call add_define,PRELOADED_BL33_BASE))
-
-K3_HW_CONFIG_BASE ?= 0x82000000
-$(eval $(call add_define,K3_HW_CONFIG_BASE))
-
 # Define sec_proxy usage as the full prioritized communication scheme
 K3_SEC_PROXY_LITE	:=	0
 $(eval $(call add_define,K3_SEC_PROXY_LITE))
 
 # System coherency is managed in hardware
 USE_COHERENT_MEM	:=	1
-
-PLAT_INCLUDES		+=	\
-				-Iplat/ti/k3/board/generic/include	\
diff --git a/plat/ti/k3/board/generic/include/board_def.h b/plat/ti/k3/board/generic/include/board_def.h
index 4ff687c..edfa73f 100644
--- a/plat/ti/k3/board/generic/include/board_def.h
+++ b/plat/ti/k3/board/generic/include/board_def.h
@@ -15,29 +15,9 @@
 #define K3_CLUSTER2_CORE_COUNT		U(2)
 #define K3_CLUSTER3_CORE_COUNT		U(2)
 
-/*
- * This RAM will be used for the bootloader including code, bss, and stacks.
- * It may need to be increased if BL31 grows in size.
- *
- * The link addresses are determined by SEC_SRAM_BASE + offset.
- * When ENABLE_PIE is set, the TF images can be loaded anywhere, so
- * SEC_SRAM_BASE is really arbitrary.
- *
- * When ENABLE_PIE is unset, SEC_SRAM_BASE should be chosen so that
- * it matches to the physical address where BL31 is loaded, that is,
- * SEC_SRAM_BASE should be the base address of the RAM region.
- *
- * Lets make things explicit by mapping SRAM_BASE to 0x0 since ENABLE_PIE is
- * defined as default for our platform.
- */
-#define SEC_SRAM_BASE			UL(0x00000000) /* PIE remapped on fly */
-#define SEC_SRAM_SIZE			UL(0x00020000) /* 128k */
-
-#define PLAT_MAX_OFF_STATE		U(2)
-#define PLAT_MAX_RET_STATE		U(1)
-
 #define PLAT_PROC_START_ID		U(32)
 #define PLAT_PROC_DEVICE_START_ID	U(202)
 #define PLAT_CLUSTER_DEVICE_START_ID	U(198)
+#define PLAT_BOARD_DEVICE_ID		U(157)
 
 #endif /* BOARD_DEF_H */
diff --git a/plat/ti/k3/board/j784s4/board.mk b/plat/ti/k3/board/j784s4/board.mk
index 92433ab..21d4151 100644
--- a/plat/ti/k3/board/j784s4/board.mk
+++ b/plat/ti/k3/board/j784s4/board.mk
@@ -4,21 +4,17 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-BL32_BASE ?= 0x9e800000
-$(eval $(call add_define,BL32_BASE))
-
-PRELOADED_BL33_BASE ?= 0x80080000
-$(eval $(call add_define,PRELOADED_BL33_BASE))
-
-K3_HW_CONFIG_BASE ?= 0x82000000
-$(eval $(call add_define,K3_HW_CONFIG_BASE))
-
 # Define sec_proxy usage as the full prioritized communication scheme
 K3_SEC_PROXY_LITE	:=	0
 $(eval $(call add_define,K3_SEC_PROXY_LITE))
 
+# Use a 4 cycle data RAM latency for J784s4
+K3_DATA_RAM_4_LATENCY	:=	1
+$(eval $(call add_define,K3_DATA_RAM_4_LATENCY))
+
+# Delay snoop exclusive handling for J784s4
+K3_EXCLUSIVE_SNOOP_DELAY	:=	1
+$(eval $(call add_define,K3_EXCLUSIVE_SNOOP_DELAY))
+
 # System coherency is managed in hardware
 USE_COHERENT_MEM	:=	1
-
-PLAT_INCLUDES		+=	\
-				-Iplat/ti/k3/board/j784s4/include	\
diff --git a/plat/ti/k3/board/j784s4/include/board_def.h b/plat/ti/k3/board/j784s4/include/board_def.h
index c2debc7..c817999 100644
--- a/plat/ti/k3/board/j784s4/include/board_def.h
+++ b/plat/ti/k3/board/j784s4/include/board_def.h
@@ -14,30 +14,10 @@
 #define K3_CLUSTER1_CORE_COUNT		U(4)
 #define K3_CLUSTER2_CORE_COUNT		U(0)
 #define K3_CLUSTER3_CORE_COUNT		U(0)
-/*
- * This RAM will be used for the bootloader including code, bss, and stacks.
- * It may need to be increased if BL31 grows in size.
- *
- * The link addresses are determined by SEC_SRAM_BASE + offset.
- * When ENABLE_PIE is set, the TF images can be loaded anywhere, so
- * SEC_SRAM_BASE is really arbitrary.
- *
- * When ENABLE_PIE is unset, SEC_SRAM_BASE should be chosen so that
- * it matches to the physical address where BL31 is loaded, that is,
- * SEC_SRAM_BASE should be the base address of the RAM region.
- *
- * Lets make things explicit by mapping SRAM_BASE to 0x0 since ENABLE_PIE is
- * defined as default for our platform.
- */
-#define SEC_SRAM_BASE			UL(0x00000000) /* PIE remapped on fly */
-#define SEC_SRAM_SIZE			UL(0x00020000) /* 128k */
-
-#define PLAT_MAX_OFF_STATE		U(2)
-#define PLAT_MAX_RET_STATE		U(1)
 
 #define PLAT_PROC_START_ID		U(32)
-
 #define PLAT_PROC_DEVICE_START_ID	U(202)
 #define PLAT_CLUSTER_DEVICE_START_ID	U(198)
+#define PLAT_BOARD_DEVICE_ID		U(157)
 
 #endif /* BOARD_DEF_H */
diff --git a/plat/ti/k3/board/lite/board.mk b/plat/ti/k3/board/lite/board.mk
index 76246be..2fa09ad 100644
--- a/plat/ti/k3/board/lite/board.mk
+++ b/plat/ti/k3/board/lite/board.mk
@@ -4,21 +4,9 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-BL32_BASE ?= 0x9e800000
-$(eval $(call add_define,BL32_BASE))
-
-PRELOADED_BL33_BASE ?= 0x80080000
-$(eval $(call add_define,PRELOADED_BL33_BASE))
-
-K3_HW_CONFIG_BASE ?= 0x82000000
-$(eval $(call add_define,K3_HW_CONFIG_BASE))
-
 # Define sec_proxy usage as the lite version
 K3_SEC_PROXY_LITE	:=	1
 $(eval $(call add_define,K3_SEC_PROXY_LITE))
 
 # We dont have system level coherency capability
 USE_COHERENT_MEM	:=	0
-
-PLAT_INCLUDES	+=			\
-	-Iplat/ti/k3/board/lite/include	\
diff --git a/plat/ti/k3/board/lite/include/board_def.h b/plat/ti/k3/board/lite/include/board_def.h
index fd4e5b1..f523198 100644
--- a/plat/ti/k3/board/lite/include/board_def.h
+++ b/plat/ti/k3/board/lite/include/board_def.h
@@ -15,31 +15,9 @@
 #define K3_CLUSTER2_CORE_COUNT		U(0)
 #define K3_CLUSTER3_CORE_COUNT		U(0)
 
-/*
- * This RAM will be used for the bootloader including code, bss, and stacks.
- * It may need to be increased if BL31 grows in size.
- * Current computation assumes data structures necessary for GIC and ARM for
- * a single cluster of 4 processor.
- *
- * The link addresses are determined by SEC_SRAM_BASE + offset.
- * When ENABLE_PIE is set, the TF images can be loaded anywhere, so
- * SEC_SRAM_BASE is really arbitrary.
- *
- * When ENABLE_PIE is unset, SEC_SRAM_BASE should be chosen so that
- * it matches to the physical address where BL31 is loaded, that is,
- * SEC_SRAM_BASE should be the base address of the RAM region.
- *
- * Lets make things explicit by mapping SRAM_BASE to 0x0 since ENABLE_PIE is
- * defined as default for our platform.
- */
-#define SEC_SRAM_BASE			UL(0x00000000) /* PIE remapped on fly */
-#define SEC_SRAM_SIZE			UL(0x00020000) /* 128k */
-
-#define PLAT_MAX_OFF_STATE		U(2)
-#define PLAT_MAX_RET_STATE		U(1)
-
 #define PLAT_PROC_START_ID		U(32)
 #define PLAT_PROC_DEVICE_START_ID	U(135)
 #define PLAT_CLUSTER_DEVICE_START_ID	U(134)
+#define PLAT_BOARD_DEVICE_ID		U(157)
 
 #endif /* BOARD_DEF_H */
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index 2cbfa3d..569e60c 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -1432,7 +1432,7 @@
 	struct ti_sci_xfer xfer;
 	int ret;
 
-	ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_AUTH_BOOT_IMIAGE, 0,
+	ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_AUTH_BOOT_IMAGE, 0,
 				    &req, sizeof(req),
 				    &resp, sizeof(resp),
 				    &xfer);
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index d220612..1b1a910 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -47,7 +47,7 @@
 #define TISCI_MSG_PROC_HANDOVER		0xc005
 #define TISCI_MSG_SET_PROC_BOOT_CONFIG	0xc100
 #define TISCI_MSG_SET_PROC_BOOT_CTRL	0xc101
-#define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE	0xc120
+#define TISCI_MSG_PROC_AUTH_BOOT_IMAGE	0xc120
 #define TISCI_MSG_GET_PROC_BOOT_STATUS	0xc400
 #define TISCI_MSG_WAIT_PROC_BOOT_STATUS	0xc401
 
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index 457c95d..9a1fd94 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -67,7 +67,8 @@
 	assert(arg0 == 0U);
 	assert(arg1 == 0U);
 
-	bl31_console_setup();
+	/* Initialize the console to provide early debug support */
+	k3_console_setup();
 
 #ifdef BL32_BASE
 	/* Populate entry point information for BL32 */
@@ -120,6 +121,10 @@
 	k3_gic_init();
 
 	ti_sci_init();
+
+	if (ti_sci_device_get(PLAT_BOARD_DEVICE_ID)) {
+		WARN("Unable to take system power reference\n");
+	}
 }
 
 void platform_mem_init(void)
@@ -164,14 +169,6 @@
 	return SYS_COUNTER_FREQ_IN_TICKS;
 }
 
-/*
- * Empty function to prevent the console from being uninitialized after BL33 is
- * started and allow us to see messages from BL31.
- */
-void bl31_plat_runtime_setup(void)
-{
-}
-
 /*******************************************************************************
  * Return a pointer to the 'entry_point_info' structure of the next image
  * for the security state specified. BL3-3 corresponds to the non-secure
diff --git a/plat/ti/k3/common/k3_console.c b/plat/ti/k3/common/k3_console.c
index 8c44c17..1b01c9b 100644
--- a/plat/ti/k3/common/k3_console.c
+++ b/plat/ti/k3/common/k3_console.c
@@ -11,11 +11,14 @@
 
 #include <k3_console.h>
 
-void bl31_console_setup(void)
+void k3_console_setup(void)
 {
 	static console_t console;
 
-	/* Initialize the console to provide early debug support */
 	console_16550_register(K3_USART_BASE, K3_USART_CLK_SPEED,
 			       K3_USART_BAUD, &console);
+
+	console_set_scope(&console, CONSOLE_FLAG_BOOT |
+				    CONSOLE_FLAG_RUNTIME |
+				    CONSOLE_FLAG_CRASH);
 }
diff --git a/plat/ti/k3/common/k3_helpers.S b/plat/ti/k3/common/k3_helpers.S
index f4f7d18..f997b46 100644
--- a/plat/ti/k3/common/k3_helpers.S
+++ b/plat/ti/k3/common/k3_helpers.S
@@ -105,8 +105,32 @@
 	/* Cortex-A72 specific settings */
 a72:
 	mrs x0, CORTEX_A72_L2CTLR_EL1
-	orr x0, x0, #(CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT)
+#if K3_DATA_RAM_4_LATENCY
+	/* Set L2 cache data RAM latency to 4 cycles */
+	orr x0, x0, #(CORTEX_A72_L2_DATA_RAM_LATENCY_4_CYCLES << \
+			CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT)
+#else
+	/* Set L2 cache data RAM latency to 3 cycles */
+	orr x0, x0, #(CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << \
+			CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT)
+#endif
+	/* Enable L2 ECC and parity with inline data */
+	orr x0, x0, #CORTEX_A72_L2CTLR_EL1_ECC_AND_PARITY_ENABLE
+	orr x0, x0, #CORTEX_A72_L2CTLR_EL1_DATA_INLINE_ECC_ENABLE
 	msr CORTEX_A72_L2CTLR_EL1, x0
+
+	mrs x0, CORTEX_A72_L2ACTLR_EL1
+	/* Enable L2 UniqueClean evictions with data */
+	orr x0, x0, #CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN
+	msr CORTEX_A72_L2ACTLR_EL1, x0
+
+#if K3_EXCLUSIVE_SNOOP_DELAY
+	mrs	x0, CORTEX_A72_CPUACTLR_EL1
+	/* Set Snoop-delayed exclusive handling */
+	orr	x0, x0, #CORTEX_A72_CPUACTLR_EL1_DELAY_EXCLUSIVE_SNOOP
+	msr	CORTEX_A72_CPUACTLR_EL1, x0
+#endif
+
 	isb
 	ret
 endfunc plat_reset_handler
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index 6febbc6..d846495 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -205,7 +205,14 @@
 
 static void __dead2 k3_system_off(void)
 {
-	ERROR("System Off: operation not handled.\n");
+	int ret;
+
+	/* Queue up the system shutdown request */
+	ret = ti_sci_device_put_no_wait(PLAT_BOARD_DEVICE_ID);
+	if (ret != 0) {
+		ERROR("Sending system shutdown message failed (%d)\n", ret);
+	}
+
 	while (true)
 		wfi();
 }
@@ -227,13 +234,6 @@
 	return PSCI_E_SUCCESS;
 }
 
-static int k3_validate_ns_entrypoint(uintptr_t entrypoint)
-{
-	/* TODO: perform the proper validation */
-
-	return PSCI_E_SUCCESS;
-}
-
 #if K3_PM_SYSTEM_SUSPEND
 static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
@@ -281,7 +281,6 @@
 	.system_off = k3_system_off,
 	.system_reset = k3_system_reset,
 	.validate_power_state = k3_validate_power_state,
-	.validate_ns_entrypoint = k3_validate_ns_entrypoint
 };
 
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index 026d6a3..fb633a8 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -27,7 +27,6 @@
 ERRATA_A72_1319367	:=	1
 
 CRASH_REPORTING		:= 1
-HANDLE_EA_EL3_FIRST_NS	:= 1
 
 # Split out RO data into a non-executable section
 SEPARATE_CODE_AND_RODATA :=    1
diff --git a/plat/ti/k3/include/k3_console.h b/plat/ti/k3/include/k3_console.h
index 6376ab3..51b322c 100644
--- a/plat/ti/k3/include/k3_console.h
+++ b/plat/ti/k3/include/k3_console.h
@@ -7,6 +7,6 @@
 #ifndef K3_CONSOLE_H
 #define K3_CONSOLE_H
 
-void bl31_console_setup(void);
+void k3_console_setup(void);
 
 #endif /* K3_CONSOLE_H */
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index 81a383a..ae3775a 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -38,21 +38,31 @@
 					PLATFORM_CLUSTER_COUNT + \
 					PLATFORM_CORE_COUNT)
 #define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+#define PLAT_MAX_OFF_STATE		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
 
 /*******************************************************************************
  * Memory layout constants
  ******************************************************************************/
 
 /*
- * ARM-TF lives in SRAM, partition it here
+ * This RAM will be used for the bootloader including code, bss, and stacks.
+ * It may need to be increased if BL31 grows in size.
  *
- * BL3-1 specific defines.
+ * The link addresses are determined by BL31_BASE + offset.
+ * When ENABLE_PIE is set, the TF images can be loaded anywhere, so
+ * BL31_BASE is really arbitrary.
  *
- * Put BL3-1 at the base of the Trusted SRAM.
+ * When ENABLE_PIE is unset, BL31_BASE should be chosen so that
+ * it matches to the physical address where BL31 is loaded, that is,
+ * BL31_BASE should be the base address of the RAM region.
+ *
+ * Lets make things explicit by mapping BL31_BASE to 0x0 since ENABLE_PIE is
+ * defined as default for our platform.
  */
-#define BL31_BASE			SEC_SRAM_BASE
-#define BL31_SIZE			SEC_SRAM_SIZE
-#define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
+#define BL31_BASE	UL(0x00000000) /* PIE remapped on fly */
+#define BL31_SIZE	UL(0x00020000) /* 128k */
+#define BL31_LIMIT	(BL31_BASE + BL31_SIZE)
 
 /*
  * Defines the maximum number of translation tables that are allocated by the
diff --git a/plat/ti/k3/platform.mk b/plat/ti/k3/platform.mk
index 2de21aa..bce9ef1 100644
--- a/plat/ti/k3/platform.mk
+++ b/plat/ti/k3/platform.mk
@@ -10,5 +10,16 @@
 include ${PLAT_PATH}/common/plat_common.mk
 include ${PLAT_PATH}/board/${TARGET_BOARD}/board.mk
 
+BL32_BASE ?= 0x9e800000
+$(eval $(call add_define,BL32_BASE))
+
+PRELOADED_BL33_BASE ?= 0x80080000
+$(eval $(call add_define,PRELOADED_BL33_BASE))
+
+K3_HW_CONFIG_BASE ?= 0x82000000
+$(eval $(call add_define,K3_HW_CONFIG_BASE))
+
+PLAT_INCLUDES += -Iplat/ti/k3/board/${TARGET_BOARD}/include
+
 # modify BUILD_PLAT to point to board specific build directory
 BUILD_PLAT := $(abspath ${BUILD_BASE})/${PLAT}/${TARGET_BOARD}/${BUILD_TYPE}
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index 1733930..ce356f6 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,4 +39,8 @@
 					entry_point_info_t *bl33,
 					uint64_t atf_handoff_addr);
 
+/* JEDEC Standard Manufacturer's Identification Code and Bank ID JEP106 */
+#define JEDEC_XILINX_MFID	U(0x49)
+#define JEDEC_XILINX_BKID	U(0)
+
 #endif /* PLAT_STARTUP_H */
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 6438896..8fa7bc5 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -39,7 +39,7 @@
 #define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
 
 /* IPI configuration table */
-const static struct ipi_config *ipi_table;
+static const struct ipi_config *ipi_table;
 
 /* Total number of IPI */
 static uint32_t ipi_total;
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 513d6be..a3c3a6f 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -172,12 +172,13 @@
 }
 
 /**
- * pm_ipi_buff_read_callb() - Reads IPI response after remote processor has
- *			      handled interrupt
- * @value	Used to return value from IPI buffer element (optional)
+ * pm_ipi_buff_read_callb() - Callback function that reads value from
+ *			      ipi response buffer
+ * @value	Used to return value from IPI buffer element
  * @count	Number of values to return in @value
  *
- * @return	Returns status, either success or error+reason
+ * This callback function fills requested data in @value from ipi response
+ * buffer.
  */
 void pm_ipi_buff_read_callb(uint32_t *value, size_t count)
 {
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index f55cde9..ed7f270 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,7 +35,7 @@
 
 static void versal_print_platform_name(void)
 {
-	NOTICE("ATF running on Xilinx %s\n", PLATFORM_NAME);
+	NOTICE("TF-A running on %s\n", PLATFORM_NAME);
 }
 
 void versal_config_setup(void)
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 9b36208..995c852 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -135,7 +135,7 @@
 	} else if (ret != FSBL_HANDOFF_SUCCESS) {
 		panic();
 	} else {
-		INFO("BL31: fsbl-atf handover success %u\n", ret);
+		INFO("BL31: PLM to TF-A handover success %u\n", ret);
 	}
 
 	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
diff --git a/plat/xilinx/versal/include/plat_ipi.h b/plat/xilinx/versal/include/plat_ipi.h
index 36a4380..9143dc6 100644
--- a/plat/xilinx/versal/include/plat_ipi.h
+++ b/plat/xilinx/versal/include/plat_ipi.h
@@ -34,7 +34,6 @@
 #define IPI_BUFFER_TARGET_APU_OFFSET	0x80U
 #define IPI_BUFFER_TARGET_PMC_OFFSET	0x40U
 
-#define IPI_BUFFER_LOCAL_BASE	IPI_BUFFER_APU_BASE
 #define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMC_BASE
 
 #define IPI_BUFFER_TARGET_LOCAL_OFFSET	IPI_BUFFER_TARGET_APU_OFFSET
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 60431a5..ce4d98c 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -129,9 +129,10 @@
 #define PMC_GLOBAL_GLOB_GEN_STORAGE4	(PMC_GLOBAL_BASE + 0x40U)
 
 /* IPI registers and bitfields */
+#define PMC_REG_BASE		U(0xFF320000)
+#define PMC_IPI_TRIG_BIT	(1U << 1U)
 #define IPI0_REG_BASE		U(0xFF330000)
 #define IPI0_TRIG_BIT		(1U << 2U)
-#define PMC_IPI_TRIG_BIT	(1U << 1U)
 #define IPI1_REG_BASE		U(0xFF340000)
 #define IPI1_TRIG_BIT		(1U << 3U)
 #define IPI2_REG_BASE		U(0xFF350000)
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index 6f2ff94..28a4cb9 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -6,6 +6,8 @@
 
 /* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
 
+#include <inttypes.h>
+
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <tools_share/uuid.h>
@@ -23,11 +25,12 @@
 #define SIP_SVC_VERSION_MINOR	U(1)
 
 /* These macros are used to identify PM calls from the SMC function ID */
-#define PM_FID_MASK	0xf000u
+#define SIP_FID_MASK	GENMASK(23, 16)
+#define XLNX_FID_MASK	GENMASK(23, 12)
 #define PM_FID_VALUE	0u
 #define IPI_FID_VALUE	0x1000u
-#define is_pm_fid(_fid) (((_fid) & PM_FID_MASK) == PM_FID_VALUE)
-#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE)
+#define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE)
 
 /* SiP Service UUID */
 DEFINE_SVC_UUID2(versal_sip_uuid,
@@ -62,6 +65,14 @@
 			     void *handle,
 			     u_register_t flags)
 {
+	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
+		smc_fid, x1, x2, x3, x4);
+
+	if (smc_fid & SIP_FID_MASK) {
+		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
 	/* Let PM SMC handler deal with PM-related requests */
 	if (is_pm_fid(smc_fid)) {
 		return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
diff --git a/plat/xilinx/versal/versal_ipi.c b/plat/xilinx/versal/versal_ipi.c
index f99af82..67915f4 100644
--- a/plat/xilinx/versal/versal_ipi.c
+++ b/plat/xilinx/versal/versal_ipi.c
@@ -19,17 +19,17 @@
 #include <lib/mmio.h>
 
 /* versal ipi configuration table */
-const static struct ipi_config versal_ipi_table[] = {
-	/* A72 IPI */
-	[IPI_ID_APU] = {
-		.ipi_bit_mask = IPI0_TRIG_BIT,
-		.ipi_reg_base = IPI0_REG_BASE,
-		.secure_only = 0U,
-	},
-
+static const struct ipi_config versal_ipi_table[] = {
 	/* PMC IPI */
 	[IPI_ID_PMC] = {
 		.ipi_bit_mask = PMC_IPI_TRIG_BIT,
+		.ipi_reg_base = PMC_REG_BASE,
+		.secure_only = 0U,
+	},
+
+	/* A72 IPI */
+	[IPI_ID_APU] = {
+		.ipi_bit_mask = IPI0_TRIG_BIT,
 		.ipi_reg_base = IPI0_REG_BASE,
 		.secure_only = 0U,
 	},
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index c9942d6..a7bae72 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2020, 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-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <common/debug.h>
 #include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
+#include <drivers/arm/dcc.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <lib/mmio.h>
@@ -28,7 +29,6 @@
 
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
-static console_t versal_net_runtime_console;
 
 /*
  * Return a pointer to the 'entry_point_info' structure of the next image for
@@ -95,18 +95,30 @@
 		panic();
 	}
 
-	/* Initialize the console to provide early debug support */
-	rc = console_pl011_register(VERSAL_NET_UART_BASE, uart_clock,
+	if (VERSAL_NET_CONSOLE_IS(pl011_0) || VERSAL_NET_CONSOLE_IS(pl011_1)) {
+		static console_t versal_net_runtime_console;
+
+		/* Initialize the console to provide early debug support */
+		rc = console_pl011_register(VERSAL_NET_UART_BASE, uart_clock,
 				    VERSAL_NET_UART_BAUDRATE,
 				    &versal_net_runtime_console);
-	if (rc == 0) {
-		panic();
-	}
+		if (rc == 0) {
+			panic();
+		}
 
-	console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT |
-			  CONSOLE_FLAG_RUNTIME);
+		console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT |
+				CONSOLE_FLAG_RUNTIME);
+	} else if (VERSAL_NET_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();
+		}
+	}
 
-	NOTICE("TF-A running on Xilinx %s %d.%d\n", board_name_decode(),
+	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
 	       platform_version / 10U, platform_version % 10U);
 
 	/* Initialize the platform config for future decision making */
diff --git a/plat/xilinx/versal_net/include/plat_ipi.h b/plat/xilinx/versal_net/include/plat_ipi.h
index 5255f8f..5ac611c 100644
--- a/plat/xilinx/versal_net/include/plat_ipi.h
+++ b/plat/xilinx/versal_net/include/plat_ipi.h
@@ -37,7 +37,6 @@
 #define IPI_BUFFER_TARGET_APU_OFFSET	0x80U
 #define IPI_BUFFER_TARGET_PMC_OFFSET	0x40U
 
-#define IPI_BUFFER_LOCAL_BASE	IPI_BUFFER_APU_BASE
 #define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMC_BASE
 
 #define IPI_BUFFER_TARGET_LOCAL_OFFSET	IPI_BUFFER_TARGET_APU_OFFSET
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index 8cb5bf3..9d1b7c2 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,7 @@
 #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_IS(con)	(VERSAL_NET_CONSOLE_ID_ ## con == VERSAL_NET_CONSOLE)
 
@@ -53,9 +54,9 @@
 
 #define PSX_CRF_RST_TIMESTAMP_OFFSET	U(0x33C)
 
-#define APU_PCLI			U(0xECB10000)
-#define APU_PCLI_CPU_STEP		U(0x30)
-#define APU_PCLI_CLUSTER_CPU_STEP	(4U * APU_PCLI_CPU_STEP)
+#define APU_PCLI			(0xECB10000ULL)
+#define APU_PCLI_CPU_STEP		(0x30ULL)
+#define APU_PCLI_CLUSTER_CPU_STEP	(4ULL * APU_PCLI_CPU_STEP)
 #define APU_PCLI_CLUSTER_OFFSET		U(0x8000)
 #define APU_PCLI_CLUSTER_STEP		U(0x1000)
 #define PCLI_PREQ_OFFSET		U(0x4)
@@ -67,13 +68,29 @@
 /* Firmware Image Package */
 #define VERSAL_NET_PRIMARY_CPU		U(0)
 
-#define CORE_0_IEN_POWER_OFFSET			(0x00000018U)
+#define CORE_0_ISR_WAKE_OFFSET			(0x00000020ULL)
+#define APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_WAKE_MASK		(0x00000001U)
+#define CORE_0_IEN_WAKE_OFFSET			(0x00000028ULL)
+#define APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IEN_WAKE_MASK		(0x00000001U)
+#define CORE_0_IDS_WAKE_OFFSET			(0x0000002CULL)
+#define APU_PCIL_CORE_X_IDS_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IDS_WAKE_MASK		(0x00000001U)
+#define CORE_0_ISR_POWER_OFFSET			(0x00000010ULL)
+#define APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_POWER_MASK		U(0x00000001)
+#define CORE_0_IEN_POWER_OFFSET			(0x00000018ULL)
 #define APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_POWER_OFFSET + \
-						 (0x30 * cpu_id)))
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
 #define APU_PCIL_CORE_X_IEN_POWER_MASK		(0x00000001U)
-#define CORE_0_IDS_POWER_OFFSET			(0x0000001CU)
+#define CORE_0_IDS_POWER_OFFSET			(0x0000001CULL)
 #define APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_POWER_OFFSET + \
-						 (0x30 * cpu_id)))
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
 #define APU_PCIL_CORE_X_IDS_POWER_MASK		(0x00000001U)
 #define CORE_PWRDN_EN_BIT_MASK			(0x1U)
 
@@ -122,9 +139,16 @@
  * UART related constants
  ******************************************************************************/
 #define VERSAL_NET_UART0_BASE		U(0xF1920000)
+#define VERSAL_NET_UART1_BASE		U(0xF1930000)
+
 #define VERSAL_NET_UART_BAUDRATE	115200
 
-#define VERSAL_NET_UART_BASE		VERSAL_NET_UART0_BASE
+#if VERSAL_NET_CONSOLE_IS(pl011_1)
+#define VERSAL_NET_UART_BASE		VERSAL_NET_UART1_BASE
+#else
+/* Default console is UART0 */
+#define VERSAL_NET_UART_BASE            VERSAL_NET_UART0_BASE
+#endif
 
 #define PLAT_VERSAL_NET_CRASH_UART_BASE		VERSAL_NET_UART_BASE
 #define PLAT_VERSAL_NET_CRASH_UART_CLK_IN_HZ	VERSAL_NET_UART_CLOCK
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index 8beaa9a..c713061 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -196,6 +196,7 @@
 	VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
 
 	int32_t pstate = psci_get_pstate_type(power_state);
+	uint64_t i;
 
 	assert(req_state);
 
@@ -203,7 +204,8 @@
 	if (pstate == PSTATE_TYPE_STANDBY) {
 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
 	} else {
-		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
+		for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
 	}
 
 	/* We expect the 'state id' to be zero */
@@ -221,8 +223,10 @@
  */
 static void versal_net_get_sys_suspend_power_state(psci_power_state_t *req_state)
 {
-	req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE;
-	req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE;
+	uint64_t i;
+
+	for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
 }
 
 static const struct plat_psci_ops versal_net_nopmc_psci_ops = {
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index b3d56bc..28e3295 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -53,6 +53,11 @@
 HW_ASSISTED_COHERENCY := 1
 
 VERSAL_NET_CONSOLE	?=	pl011
+ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc))
+else
+  $(error Please define VERSAL_NET_CONSOLE)
+endif
+
 $(eval $(call add_define_val,VERSAL_NET_CONSOLE,VERSAL_NET_CONSOLE_ID_${VERSAL_NET_CONSOLE}))
 
 PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
@@ -67,6 +72,7 @@
 include lib/libfdt/libfdt.mk
 
 PLAT_BL_COMMON_SOURCES	:=	\
+				drivers/arm/dcc/dcc_console.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${GICV3_SOURCES}				\
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
index 6487324..f543193 100644
--- a/plat/xilinx/versal_net/pm_service/pm_client.c
+++ b/plat/xilinx/versal_net/pm_service/pm_client.c
@@ -164,8 +164,18 @@
 
 	isb();
 
+	/* Clear power down interrupt status before enabling */
+	mmio_write_32(APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id),
+		      APU_PCIL_CORE_X_ISR_POWER_MASK);
+	/* Enable power down interrupt */
 	mmio_write_32(APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id),
 		      APU_PCIL_CORE_X_IEN_POWER_MASK);
+	/* Clear wakeup interrupt status before enabling */
+	mmio_write_32(APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id),
+		      APU_PCIL_CORE_X_ISR_WAKE_MASK);
+	/* Enable wake interrupt */
+	mmio_write_32(APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id),
+		      APU_PCIL_CORE_X_IEN_WAKE_MASK);
 
 	bakery_lock_release(&pm_client_secure_lock);
 }
@@ -197,6 +207,7 @@
 void pm_client_wakeup(const struct pm_proc *proc)
 {
 	uint32_t cpuid = pm_get_cpuid(proc->node_id);
+	uintptr_t val;
 
 	if (cpuid == UNDEFINED_CPUID) {
 		return;
@@ -204,7 +215,22 @@
 
 	bakery_lock_get(&pm_client_secure_lock);
 
-	/* TODO: clear powerdown bit for affected cpu */
+	/* Clear powerdown request */
+	val = read_cpu_pwrctrl_val();
+	val &= ~CORE_PWRDN_EN_BIT_MASK;
+	write_cpu_pwrctrl_val(val);
+
+	isb();
+
+	/* Disabled power down interrupt */
+	mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpuid),
+			APU_PCIL_CORE_X_IDS_POWER_MASK);
+	/* Clear wakeup interrupt status before disabling */
+	mmio_write_32(APU_PCIL_CORE_X_ISR_WAKE_REG(cpuid),
+		      APU_PCIL_CORE_X_ISR_WAKE_MASK);
+	/* Disable wake interrupt */
+	mmio_write_32(APU_PCIL_CORE_X_IDS_WAKE_REG(cpuid),
+		      APU_PCIL_CORE_X_IDS_WAKE_MASK);
 
 	bakery_lock_release(&pm_client_secure_lock);
 }
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index 0e3940f..c91497c 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -9,6 +9,7 @@
 /* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
 
 #include <errno.h>
+#include <inttypes.h>
 
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -28,11 +29,12 @@
 #define SIP_SVC_VERSION_MINOR		(1U)
 
 /* These macros are used to identify PM calls from the SMC function ID */
-#define PM_FID_MASK	0xf000u
+#define SIP_FID_MASK	GENMASK(23, 16)
+#define XLNX_FID_MASK	GENMASK(23, 12)
 #define PM_FID_VALUE	0u
 #define IPI_FID_VALUE	0x1000u
-#define is_pm_fid(_fid)	(((_fid) & PM_FID_MASK) == PM_FID_VALUE)
-#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE)
+#define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE)
 
 /* SiP Service UUID */
 DEFINE_SVC_UUID2(versal_net_sip_uuid,
@@ -62,6 +64,14 @@
 			     void *handle,
 			     u_register_t flags)
 {
+	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
+		smc_fid, x1, x2, x3, x4);
+
+	if (smc_fid & SIP_FID_MASK) {
+		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
 	/* Let PM SMC handler deal with PM-related requests */
 	if (is_pm_fid(smc_fid)) {
 		return smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
diff --git a/plat/xilinx/versal_net/versal_net_gicv3.c b/plat/xilinx/versal_net/versal_net_gicv3.c
index b7ac6ab..1d45a58 100644
--- a/plat/xilinx/versal_net/versal_net_gicv3.c
+++ b/plat/xilinx/versal_net/versal_net_gicv3.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-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,14 +30,6 @@
 /* The GICv3 driver only needs to be initialized in EL3 */
 static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
-static const uintptr_t gicr_base_addrs[2] = {
-	PLAT_VERSAL_NET_GICR_BASE,	/* GICR Base address of the primary CPU */
-	0U				/* Zero Termination */
-};
-
-/* List of zero terminated GICR frame addresses which CPUs will probe */
-static const uintptr_t *gicr_frames;
-
 static const interrupt_prop_t versal_net_interrupt_props[] = {
 	PLAT_VERSAL_NET_G1S_IRQ_PROPS(INTR_GROUP1S),
 	PLAT_VERSAL_NET_G0_IRQ_PROPS(INTR_GROUP0)
@@ -72,7 +64,7 @@
 
 static const gicv3_driver_data_t versal_net_gic_data __unused = {
 	.gicd_base = PLAT_VERSAL_NET_GICD_BASE,
-	.gicr_base = 0U,
+	.gicr_base = PLAT_VERSAL_NET_GICR_BASE,
 	.interrupt_props = versal_net_interrupt_props,
 	.interrupt_props_num = ARRAY_SIZE(versal_net_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
@@ -90,12 +82,6 @@
 	 */
 #if IMAGE_BL31
 	gicv3_driver_init(&versal_net_gic_data);
-	gicr_frames = gicr_base_addrs;
-
-	if (gicv3_rdistif_probe(gicr_frames[0]) == -1) {
-		ERROR("No GICR base frame found for Primary CPU\n");
-		panic();
-	}
 #endif
 }
 
@@ -131,25 +117,6 @@
  *****************************************************************************/
 void plat_versal_net_gic_pcpu_init(void)
 {
-	int32_t result;
-	const uintptr_t *plat_gicr_frames = gicr_frames;
-
-	do {
-		result = gicv3_rdistif_probe(*plat_gicr_frames);
-
-		/* If the probe is successful, no need to proceed further */
-		if (result == 0) {
-			break;
-		}
-
-		plat_gicr_frames++;
-	} while (*plat_gicr_frames != 0U);
-
-	if (result == -1) {
-		ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
-		panic();
-	}
-
 	gicv3_rdistif_init(plat_my_core_pos());
 }
 
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 3946e9b..95a266e 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,10 +11,13 @@
 #include <common/debug.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
+#include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables.h>
 #include <plat_ipi.h>
 #include <plat_private.h>
+#include <plat_startup.h>
 #include <plat/common/platform.h>
+#include <services/arm_arch_svc.h>
 
 #include "pm_api_sys.h"
 
@@ -215,7 +219,7 @@
 #define ZYNQMP_PL_STATUS_MASK	BIT(ZYNQMP_PL_STATUS_BIT)
 #define ZYNQMP_CSU_VERSION_MASK	~(ZYNQMP_PL_STATUS_MASK)
 
-#define SILICON_ID_XCK24	0x4714093U
+#define SILICON_ID_XCK24	0x4712093U
 #define SILICON_ID_XCK26	0x4724093U
 
 static char *zynqmp_get_silicon_idcode_name(void)
@@ -303,13 +307,38 @@
 	maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
 		 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
 	if (tmp != maskid) {
-		ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid);
+		ERROR("Incorrect IDCODE 0x%x, maskid 0x%x\n", id, maskid);
 		return "UNKN";
 	}
-	VERBOSE("Xilinx IDCODE 0x%x\n", id);
+	VERBOSE("IDCODE 0x%x\n", id);
 	return zynqmp_get_silicon_idcode_name();
 }
 
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+	switch (fid) {
+	case SMCCC_ARCH_SOC_ID:
+		return SMC_ARCH_CALL_SUCCESS;
+	default:
+		return SMC_ARCH_CALL_NOT_SUPPORTED;
+	}
+
+	return SMC_ARCH_CALL_NOT_SUPPORTED;
+}
+
+int32_t plat_get_soc_version(void)
+{
+	uint32_t chip_id = zynqmp_get_silicon_ver();
+	uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_XILINX_BKID, JEDEC_XILINX_MFID);
+
+	return (int32_t)(manfid | (chip_id & 0xFFFF));
+}
+
+int32_t plat_get_soc_revision(void)
+{
+	return mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
+}
+
 static uint32_t zynqmp_get_ps_ver(void)
 {
 	uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 1d59537..59f7298 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -197,8 +197,9 @@
 	}
 
 	/* Reserve memory used by Trusted Firmware. */
-	if (fdt_add_reserved_memory(dtb, "tf-a", BL31_BASE, BL31_LIMIT - BL31_BASE)) {
-		WARN("Failed to add reserved memory nodes to DT.\n");
+	if (fdt_add_reserved_memory(dtb, "tf-a", BL31_BASE,
+				    BL31_LIMIT - BL31_BASE + 1)) {
+		WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
 	}
 
 	ret = fdt_pack(dtb);
@@ -214,7 +215,7 @@
 void bl31_platform_setup(void)
 {
 #if (BL31_LIMIT < PLAT_DDR_LOWMEM_MAX)
-		prepare_dtb();
+	prepare_dtb();
 #endif
 
 	/* Initialize the gic cpu and distributor interfaces */
@@ -245,7 +246,6 @@
 	plat_arm_interconnect_init();
 	plat_arm_interconnect_enter_coherency();
 
-
 	const mmap_region_t bl_regions[] = {
 #if (BL31_LIMIT < PLAT_DDR_LOWMEM_MAX)
 		MAP_REGION_FLAT(XILINX_OF_BOARD_DTB_ADDR, XILINX_OF_BOARD_DTB_MAX_SIZE,
diff --git a/plat/xilinx/zynqmp/custom_sip_svc.c b/plat/xilinx/zynqmp/custom_sip_svc.c
new file mode 100644
index 0000000..459aa39
--- /dev/null
+++ b/plat/xilinx/zynqmp/custom_sip_svc.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <smccc_helpers.h>
+
+uint64_t custom_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
+			    uint64_t x3, uint64_t x4, void *cookie,
+			    void *handle, uint64_t flags)
+{
+	WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
+	SMC_RET1(handle, SMC_UNK);
+}
diff --git a/plat/xilinx/zynqmp/include/custom_svc.h b/plat/xilinx/zynqmp/include/custom_svc.h
new file mode 100644
index 0000000..389a7bc
--- /dev/null
+++ b/plat/xilinx/zynqmp/include/custom_svc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef CUSTOM_SVC_H
+#define CUSTOM_SVC_H
+
+#define ZYNQMP_SIP_SVC_CUSTOM   U(0x82002000)
+#define ZYNQMP_SIP_SVC64_CUSTOM U(0xC2002000)
+
+uint64_t custom_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
+			    uint64_t x3, uint64_t x4, void *cookie,
+			    void *handle, uint64_t flags);
+
+#endif /* CUSTOM_SVC_H */
diff --git a/plat/xilinx/zynqmp/include/plat_ipi.h b/plat/xilinx/zynqmp/include/plat_ipi.h
index a78f93a..bf56d5e 100644
--- a/plat/xilinx/zynqmp/include/plat_ipi.h
+++ b/plat/xilinx/zynqmp/include/plat_ipi.h
@@ -35,7 +35,6 @@
 #define IPI_BUFFER_APU_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
 #define IPI_BUFFER_PMU_BASE	(IPI_BUFFER_BASEADDR + 0xE00U)
 
-#define IPI_BUFFER_LOCAL_BASE	IPI_BUFFER_APU_BASE
 #define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMU_BASE
 
 #define IPI_BUFFER_TARGET_LOCAL_OFFSET	0x80U
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index c2d22c2..ffed0ee 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -40,8 +40,8 @@
 # define BL31_BASE			U(0xfffea000)
 # define BL31_LIMIT			U(0x100000000)
 #else
-# define BL31_BASE			U(0xfffe5000)
-# define BL31_LIMIT			U(0x100000000)
+# define BL31_BASE			U(0x1000)
+# define BL31_LIMIT			U(0x7ffff)
 #endif
 #else
 # define BL31_BASE			(ZYNQMP_ATF_MEM_BASE)
@@ -91,7 +91,7 @@
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
 #if (BL31_LIMIT < PLAT_DDR_LOWMEM_MAX)
 #define MAX_MMAP_REGIONS		8
-#define MAX_XLAT_TABLES			6
+#define MAX_XLAT_TABLES			8
 #else
 #define MAX_MMAP_REGIONS		7
 #define MAX_XLAT_TABLES			5
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 05adbd0..38e7408 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -5,6 +5,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 
 override ERRATA_A53_855873 := 1
+ERRATA_A53_1530924 := 1
 override PROGRAMMABLE_RESET_ADDRESS := 1
 PSCI_EXTENDED_STATE_ID := 1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
@@ -138,6 +139,12 @@
 BL31_CPPFLAGS		+=	-fno-jump-tables
 TF_CFLAGS_aarch64	+=	-mbranch-protection=none
 
+ifdef CUSTOM_PKG_PATH
+include $(CUSTOM_PKG_PATH)/custom_pkg.mk
+else
+BL31_SOURCES		+=	plat/xilinx/zynqmp/custom_sip_svc.c
+endif
+
 ifneq (${RESET_TO_BL31},1)
   $(error "Using BL31 as the reset vector is only one option supported on ZynqMP. Please set RESET_TO_BL31 to 1.")
 endif
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index a17b6c5..63916b8 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -786,7 +787,7 @@
 {
 	switch (api_id) {
 	case PM_QUERY_DATA:
-		*version = ATF_API_BASE_VERSION;
+		*version = TFA_API_QUERY_DATA_VERSION;
 		bit_mask[0] = (uint32_t)(PM_QUERY_FEATURE_BITMASK);
 		bit_mask[1] = (uint32_t)(PM_QUERY_FEATURE_BITMASK >> 32);
 		return PM_RET_SUCCESS;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index e335b94..2fc7131 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,6 +32,9 @@
 #define FW_API_VERSION_2		(2U)
 /* Version of APIs implemented in ATF */
 #define ATF_API_BASE_VERSION		(1U)
+/* Updating the QUERY_DATA API versioning as the bitmask functionality
+ * support is added in the v2.*/
+#define TFA_API_QUERY_DATA_VERSION	(2U)
 
 /* Capabilities for RAM */
 #define PM_CAP_ACCESS	0x1U
@@ -122,9 +126,9 @@
 	/* PM Register Access API */
 	PM_REGISTER_ACCESS,
 	PM_EFUSE_ACCESS,
-	PM_FPGA_GET_VERSION,
-	PM_FPGA_GET_FEATURE_LIST,
 	PM_FEATURE_CHECK = 63,
+	PM_FPGA_GET_VERSION = 72,
+	PM_FPGA_GET_FEATURE_LIST,
 	PM_API_MAX
 };
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 4adbef3..a3f0278 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -334,22 +334,18 @@
 		SMC_RET1(handle, (uint64_t)ret);
 
 	case PM_GET_API_VERSION:
-		/* Check is PM API version already verified */
-		if (pm_ctx.api_version >= PM_VERSION) {
-			if (ipi_irq_flag == 0U) {
-				/*
-				 * Enable IPI IRQ
-				 * assume the rich OS is OK to handle callback IRQs now.
-				 * Even if we were wrong, it would not enable the IRQ in
-				 * the GIC.
-				 */
-				pm_ipi_irq_enable(primary_proc);
-				ipi_irq_flag = 1U;
-			}
-			SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
-				 ((uint64_t)pm_ctx.api_version << 32));
+		if (ipi_irq_flag == 0U) {
+			/*
+			 * Enable IPI IRQ
+			 * assume the rich OS is OK to handle callback IRQs now.
+			 * Even if we were wrong, it would not enable the IRQ in
+			 * the GIC.
+			 */
+			pm_ipi_irq_enable(primary_proc);
+			ipi_irq_flag = 1U;
 		}
-
+		SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
+			 ((uint64_t)pm_ctx.api_version << 32));
 	case PM_FPGA_LOAD:
 		ret = pm_fpga_load(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 4ce9b8a..8b0adc6 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -6,9 +6,12 @@
 
 /* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
 
+#include <inttypes.h>
+
 #include <common/runtime_svc.h>
 #include <tools_share/uuid.h>
 
+#include <custom_svc.h>
 #include "ipi_mailbox_svc.h"
 #include "pm_svc_main.h"
 
@@ -22,14 +25,14 @@
 #define SIP_SVC_VERSION_MINOR	1
 
 /* These macros are used to identify PM, IPI calls from the SMC function ID */
-#define PM_FID_MASK	0xf000u
+#define SIP_FID_MASK	GENMASK(23, 16)
+#define XLNX_FID_MASK	GENMASK(23, 12)
 #define PM_FID_VALUE	0u
 #define IPI_FID_VALUE	0x1000u
-#define EM_FID_MASK     0xf0000u
 #define EM_FID_VALUE    0xE0000u
-#define is_em_fid(_fid) (((_fid) & EM_FID_MASK) == EM_FID_VALUE)
-#define is_pm_fid(_fid) (((_fid) & PM_FID_MASK) == PM_FID_VALUE)
-#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE)
+#define is_em_fid(_fid) (((_fid) & XLNX_FID_MASK) == EM_FID_VALUE)
+#define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE)
 
 /* SiP Service UUID */
 DEFINE_SVC_UUID2(zynqmp_sip_uuid,
@@ -62,12 +65,22 @@
 			      void *handle,
 			      u_register_t flags)
 {
+	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
+		smc_fid, x1, x2, x3, x4);
+
 	/* Let EM SMC handler deal with EM-related requests */
 	if (is_em_fid(smc_fid)) {
 		return em_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
 					flags);
-	} else if (is_pm_fid(smc_fid)) {
+	}
+
+	if (smc_fid & SIP_FID_MASK) {
+		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
 	/* Let PM SMC handler deal with PM-related requests */
+	if (is_pm_fid(smc_fid)) {
 		return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
 				      flags);
 	}
@@ -89,6 +102,11 @@
 	case ZYNQMP_SIP_SVC_VERSION:
 		SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR);
 
+	case ZYNQMP_SIP_SVC_CUSTOM:
+	case ZYNQMP_SIP_SVC64_CUSTOM:
+		return custom_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+					  handle, flags);
+
 	default:
 		WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.c b/plat/xilinx/zynqmp/zynqmp_ipi.c
index 4ea3c6a..acd31df 100644
--- a/plat/xilinx/zynqmp/zynqmp_ipi.c
+++ b/plat/xilinx/zynqmp/zynqmp_ipi.c
@@ -21,7 +21,7 @@
 #include <plat_private.h>
 
 /* Zynqmp ipi configuration table */
-const static struct ipi_config zynqmp_ipi_table[] = {
+static const struct ipi_config zynqmp_ipi_table[] = {
 	/* APU IPI */
 	{
 		.ipi_bit_mask = 0x1,
diff --git a/services/spd/opteed/opteed.mk b/services/spd/opteed/opteed.mk
index 643b054..477b45d 100644
--- a/services/spd/opteed/opteed.mk
+++ b/services/spd/opteed/opteed.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -16,3 +16,19 @@
 
 # required so that optee code can control access to the timer registers
 NS_TIMER_SWITCH		:=	1
+
+# WARNING: This enables loading of OP-TEE via an SMC, which can be potentially
+# insecure. This removes the boundary between the startup of the secure and
+# non-secure worlds until the point where this SMC is invoked. Only use this
+# setting if you can ensure that the non-secure OS can remain trusted up until
+# the point where this SMC is invoked.
+OPTEE_ALLOW_SMC_LOAD		:=	0
+ifeq ($(OPTEE_ALLOW_SMC_LOAD),1)
+ifeq ($(PLAT_XLAT_TABLES_DYNAMIC),0)
+$(error When OPTEE_ALLOW_SMC_LOAD=1, PLAT_XLAT_TABLES_DYNAMIC must also be 1)
+endif
+$(warning "OPTEE_ALLOW_SMC_LOAD is enabled which may result in an insecure \
+	platform")
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+$(eval $(call add_define,OPTEE_ALLOW_SMC_LOAD))
+endif
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 160a693..ff09e7e 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,7 @@
  ******************************************************************************/
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <stddef.h>
 
 #include <arch_helpers.h>
@@ -24,12 +25,13 @@
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/optee_utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <tools_share/uuid.h>
 
 #include "opteed_private.h"
 #include "teesmc_opteed.h"
-#include "teesmc_opteed_macros.h"
 
 /*******************************************************************************
  * Address of the entrypoint vector table in OPTEE. It is
@@ -43,7 +45,16 @@
 optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
 uint32_t opteed_rw;
 
+#if OPTEE_ALLOW_SMC_LOAD
+static bool opteed_allow_load;
+#else
 static int32_t opteed_init(void);
+#endif
+
+uint64_t dual32to64(uint32_t high, uint32_t low)
+{
+	return ((uint64_t)high << 32) | low;
+}
 
 /*******************************************************************************
  * This function is the handler registered for S-EL1 interrupts by the
@@ -93,6 +104,11 @@
  ******************************************************************************/
 static int32_t opteed_setup(void)
 {
+#if OPTEE_ALLOW_SMC_LOAD
+	opteed_allow_load = true;
+	INFO("Delaying OP-TEE setup until we receive an SMC call to load it\n");
+	return 0;
+#else
 	entry_point_info_t *optee_ep_info;
 	uint32_t linear_id;
 	uint64_t opteed_pageable_part;
@@ -142,6 +158,7 @@
 	bl31_register_bl32_init(&opteed_init);
 
 	return 0;
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
 }
 
 /*******************************************************************************
@@ -151,20 +168,15 @@
  * used.  It also assumes that a valid non-secure context has been
  * initialised by PSCI so it does not need to save and restore any
  * non-secure state. This function performs a synchronous entry into
- * OPTEE. OPTEE passes control back to this routine through a SMC.
+ * OPTEE. OPTEE passes control back to this routine through a SMC. This returns
+ * a non-zero value on success and zero on failure.
  ******************************************************************************/
-static int32_t opteed_init(void)
+static int32_t
+opteed_init_with_entry_point(entry_point_info_t *optee_entry_point)
 {
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
-	entry_point_info_t *optee_entry_point;
 	uint64_t rc;
-
-	/*
-	 * Get information about the OPTEE (BL32) image. Its
-	 * absence is a critical failure.
-	 */
-	optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
 	assert(optee_entry_point);
 
 	cm_init_my_context(optee_entry_point);
@@ -179,6 +191,121 @@
 	return rc;
 }
 
+#if !OPTEE_ALLOW_SMC_LOAD
+static int32_t opteed_init(void)
+{
+	entry_point_info_t *optee_entry_point;
+	/*
+	 * Get information about the OP-TEE (BL32) image. Its
+	 * absence is a critical failure.
+	 */
+	optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
+	return opteed_init_with_entry_point(optee_entry_point);
+}
+#endif  /* !OPTEE_ALLOW_SMC_LOAD */
+
+#if OPTEE_ALLOW_SMC_LOAD
+/*******************************************************************************
+ * This function is responsible for handling the SMC that loads the OP-TEE
+ * binary image via a non-secure SMC call. It takes the size and physical
+ * address of the payload as parameters.
+ ******************************************************************************/
+static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa)
+{
+	uintptr_t data_va = data_pa;
+	uint64_t mapped_data_pa;
+	uintptr_t mapped_data_va;
+	uint64_t data_map_size;
+	int32_t rc;
+	optee_header_t *image_header;
+	uint8_t *image_ptr;
+	uint64_t target_pa;
+	uint64_t target_end_pa;
+	uint64_t image_pa;
+	uintptr_t image_va;
+	optee_image_t *curr_image;
+	uintptr_t target_va;
+	uint64_t target_size;
+	entry_point_info_t optee_ep_info;
+	uint32_t linear_id = plat_my_core_pos();
+
+	mapped_data_pa = page_align(data_pa, DOWN);
+	mapped_data_va = mapped_data_pa;
+	data_map_size = page_align(data_size + (mapped_data_pa - data_pa), UP);
+
+	/*
+	 * We do not validate the passed in address because we are trusting the
+	 * non-secure world at this point still.
+	 */
+	rc = mmap_add_dynamic_region(mapped_data_pa, mapped_data_va,
+				     data_map_size, MT_MEMORY | MT_RO | MT_NS);
+	if (rc != 0) {
+		return rc;
+	}
+
+	image_header = (optee_header_t *)data_va;
+	if (image_header->magic != TEE_MAGIC_NUM_OPTEE ||
+	    image_header->version != 2 || image_header->nb_images != 1) {
+		mmap_remove_dynamic_region(mapped_data_va, data_map_size);
+		return -EINVAL;
+	}
+
+	image_ptr = (uint8_t *)data_va + sizeof(optee_header_t) +
+			sizeof(optee_image_t);
+	if (image_header->arch == 1) {
+		opteed_rw = OPTEE_AARCH64;
+	} else {
+		opteed_rw = OPTEE_AARCH32;
+	}
+
+	curr_image = &image_header->optee_image_list[0];
+	image_pa = dual32to64(curr_image->load_addr_hi,
+			      curr_image->load_addr_lo);
+	image_va = image_pa;
+	target_end_pa = image_pa + curr_image->size;
+
+	/* Now also map the memory we want to copy it to. */
+	target_pa = page_align(image_pa, DOWN);
+	target_va = target_pa;
+	target_size = page_align(target_end_pa, UP) - target_pa;
+
+	rc = mmap_add_dynamic_region(target_pa, target_va, target_size,
+				     MT_MEMORY | MT_RW | MT_SECURE);
+	if (rc != 0) {
+		mmap_remove_dynamic_region(mapped_data_va, data_map_size);
+		return rc;
+	}
+
+	INFO("Loaded OP-TEE via SMC: size %d addr 0x%" PRIx64 "\n",
+	     curr_image->size, image_va);
+
+	memcpy((void *)image_va, image_ptr, curr_image->size);
+	flush_dcache_range(target_pa, target_size);
+
+	mmap_remove_dynamic_region(mapped_data_va, data_map_size);
+	mmap_remove_dynamic_region(target_va, target_size);
+
+	/* Save the non-secure state */
+	cm_el1_sysregs_context_save(NON_SECURE);
+
+	opteed_init_optee_ep_state(&optee_ep_info,
+				   opteed_rw,
+				   image_pa,
+				   0,
+				   0,
+				   0,
+				   &opteed_sp_context[linear_id]);
+	if (opteed_init_with_entry_point(&optee_ep_info) == 0) {
+		rc = -EFAULT;
+	}
+
+	/* Restore non-secure state */
+	cm_el1_sysregs_context_restore(NON_SECURE);
+	cm_set_next_eret_context(NON_SECURE);
+
+	return rc;
+}
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
 
 /*******************************************************************************
  * This function is responsible for handling all SMCs in the Trusted OS/App
@@ -207,6 +334,34 @@
 	 */
 
 	if (is_caller_non_secure(flags)) {
+#if OPTEE_ALLOW_SMC_LOAD
+		if (smc_fid == NSSMC_OPTEED_CALL_LOAD_IMAGE) {
+			/*
+			 * TODO: Consider wiping the code for SMC loading from
+			 * memory after it has been invoked similar to what is
+			 * done under RECLAIM_INIT, but extended to happen
+			 * later.
+			 */
+			if (!opteed_allow_load) {
+				SMC_RET1(handle, -EPERM);
+			}
+
+			opteed_allow_load = false;
+			uint64_t data_size = dual32to64(x1, x2);
+			uint64_t data_pa = dual32to64(x3, x4);
+			if (!data_size || !data_pa) {
+				/*
+				 * This is invoked when the OP-TEE image didn't
+				 * load correctly in the kernel but we want to
+				 * block off loading of it later for security
+				 * reasons.
+				 */
+				SMC_RET1(handle, -EINVAL);
+			}
+			SMC_RET1(handle, opteed_handle_smc_load(
+					data_size, data_pa));
+		}
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
 		/*
 		 * This is a fresh request from the non-secure client.
 		 * The parameters are in x1 and x2. Figure out which
@@ -219,8 +374,18 @@
 
 		/*
 		 * We are done stashing the non-secure context. Ask the
-		 * OPTEE to do the work now.
+		 * OP-TEE to do the work now. If we are loading vi an SMC,
+		 * then we also need to init this CPU context if not done
+		 * already.
 		 */
+		if (optee_vector_table == NULL) {
+			SMC_RET1(handle, -EINVAL);
+		}
+
+		if (get_optee_pstate(optee_ctx->state) ==
+		    OPTEE_PSTATE_UNKNOWN) {
+			opteed_cpu_on_finish_handler(0);
+		}
 
 		/*
 		 * Verify if there is a valid context to use, copy the
diff --git a/services/spd/opteed/opteed_pm.c b/services/spd/opteed/opteed_pm.c
index 719eeb7..fa724a1 100644
--- a/services/spd/opteed/opteed_pm.c
+++ b/services/spd/opteed/opteed_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,6 +32,10 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		return 0;
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
@@ -65,6 +69,10 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		return;
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
@@ -92,7 +100,7 @@
  * after initialising minimal architectural state that guarantees safe
  * execution.
  ******************************************************************************/
-static void opteed_cpu_on_finish_handler(u_register_t unused)
+void opteed_cpu_on_finish_handler(u_register_t unused)
 {
 	int32_t rc = 0;
 	uint32_t linear_id = plat_my_core_pos();
@@ -100,7 +108,8 @@
 	entry_point_info_t optee_on_entrypoint;
 
 	assert(optee_vector_table);
-	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF);
+	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF ||
+	       get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN);
 
 	opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
 				(uint64_t)&optee_vector_table->cpu_on_entry,
@@ -134,6 +143,10 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		return;
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_SUSPEND);
 
@@ -173,6 +186,14 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	/*
+	 * OP-TEE must have been initialized in order to reach this location so
+	 * it is safe to init the CPU context if not already done for this core.
+	 */
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		opteed_cpu_on_finish_handler(0);
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
@@ -193,6 +214,14 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	/*
+	 * OP-TEE must have been initialized in order to reach this location so
+	 * it is safe to init the CPU context if not already done for this core.
+	 */
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		opteed_cpu_on_finish_handler(0);
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h
index 242154f..ab6e4cd 100644
--- a/services/spd/opteed/opteed_private.h
+++ b/services/spd/opteed/opteed_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,9 +18,10 @@
  * OPTEE PM state information e.g. OPTEE is suspended, uninitialised etc
  * and macros to access the state information in the per-cpu 'state' flags
  ******************************************************************************/
-#define OPTEE_PSTATE_OFF		0
-#define OPTEE_PSTATE_ON			1
-#define OPTEE_PSTATE_SUSPEND		2
+#define OPTEE_PSTATE_OFF		1
+#define OPTEE_PSTATE_ON			2
+#define OPTEE_PSTATE_SUSPEND		3
+#define OPTEE_PSTATE_UNKNOWN		0
 #define OPTEE_PSTATE_SHIFT		0
 #define OPTEE_PSTATE_MASK		0x3
 #define get_optee_pstate(state)	((state >> OPTEE_PSTATE_SHIFT) & \
@@ -153,6 +154,7 @@
 				uint64_t mem_limit,
 				uint64_t dt_addr,
 				optee_context_t *optee_ctx);
+void opteed_cpu_on_finish_handler(u_register_t unused);
 
 extern optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
 extern uint32_t opteed_rw;
diff --git a/services/spd/opteed/teesmc_opteed.h b/services/spd/opteed/teesmc_opteed.h
index c82b58a..eae3ed2 100644
--- a/services/spd/opteed/teesmc_opteed.h
+++ b/services/spd/opteed/teesmc_opteed.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,8 +9,10 @@
 #ifndef TEESMC_OPTEED_H
 #define TEESMC_OPTEED_H
 
+#include "teesmc_opteed_macros.h"
+
 /*
- * This file specifies SMC function IDs used when returning from TEE to the
+ * This section specifies SMC function IDs used when returning from TEE to the
  * secure monitor.
  *
  * All SMC Function IDs indicates SMC32 Calling Convention but will carry
@@ -120,4 +122,39 @@
 #define TEESMC_OPTEED_RETURN_SYSTEM_RESET_DONE \
 	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_SYSTEM_RESET_DONE)
 
+/*
+ * This section specifies SMC function IDs used when the secure monitor is
+ * invoked from the non-secure world.
+ */
+
+/*
+ * Load OP-TEE image from the payload specified in the registers.
+ *
+ * WARNING: Use this cautiously as it could lead to insecure loading of the
+ * Trusted OS. Further details are in opteed.mk.
+ *
+ * Call register usage:
+ * x0 SMC Function ID, OPTEE_SMC_CALL_LOAD_IMAGE
+ * x1 Upper 32bit of a 64bit size for the payload
+ * x2 Lower 32bit of a 64bit size for the payload
+ * x3 Upper 32bit of the physical address for the payload
+ * x4 Lower 32bit of the physical address for the payload
+ *
+ * The payload consists of a optee_header struct that contains optee_image
+ * structs in a flex array, immediately following that in memory is the data
+ * referenced by the optee_image structs.
+ * Example:
+ *
+ * struct optee_header (with n images specified)
+ * image 0 data
+ * image 1 data
+ * ...
+ * image n-1 data
+ *
+ * Returns 0 on success and an error code otherwise.
+ */
+#define NSSMC_OPTEED_FUNCID_LOAD_IMAGE 2
+#define NSSMC_OPTEED_CALL_LOAD_IMAGE \
+	NSSMC_OPTEED_CALL(NSSMC_OPTEED_FUNCID_LOAD_IMAGE)
+
 #endif /*TEESMC_OPTEED_H*/
diff --git a/services/spd/opteed/teesmc_opteed_macros.h b/services/spd/opteed/teesmc_opteed_macros.h
index 9d8a169..ad3ed75 100644
--- a/services/spd/opteed/teesmc_opteed_macros.h
+++ b/services/spd/opteed/teesmc_opteed_macros.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,4 +14,10 @@
 		 (62 << FUNCID_OEN_SHIFT) | \
 		 ((func_num) & FUNCID_NUM_MASK))
 
+#define NSSMC_OPTEED_CALL(func_num) \
+		((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+		((SMC_32) << FUNCID_CC_SHIFT) | \
+		(50 << FUNCID_OEN_SHIFT) | \
+		((func_num) & FUNCID_NUM_MASK))
+
 #endif /* TEESMC_OPTEED_MACROS_H */
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 6bd9fdf..e12eae7 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -171,7 +171,7 @@
 	uint32_t ep_attr;
 	unsigned int linear_id = plat_my_core_pos();
 	rmmd_rmm_context_t *rmm_ctx = &rmm_context[linear_id];
-	rmm_manifest_t *manifest;
+	struct rmm_manifest *manifest;
 	int rc;
 
 	/* Make sure RME is supported. */
@@ -206,7 +206,7 @@
 					((void *)shared_buf_base != NULL));
 
 	/* Load the boot manifest at the beginning of the shared area */
-	manifest = (rmm_manifest_t *)shared_buf_base;
+	manifest = (struct rmm_manifest *)shared_buf_base;
 	rc = plat_rmmd_load_manifest(manifest);
 	if (rc != 0) {
 		ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
diff --git a/services/std_svc/rmmd/trp/linker.lds b/services/std_svc/rmmd/trp/linker.ld.S
similarity index 89%
rename from services/std_svc/rmmd/trp/linker.lds
rename to services/std_svc/rmmd/trp/linker.ld.S
index 2b7f383..9895cf9 100644
--- a/services/std_svc/rmmd/trp/linker.lds
+++ b/services/std_svc/rmmd/trp/linker.ld.S
@@ -1,6 +1,7 @@
 /*
- * (C) COPYRIGHT 2021 Arm Limited or its affiliates.
- * ALL RIGHTS RESERVED
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/bl_common.ld.h>
diff --git a/services/std_svc/rmmd/trp/trp.mk b/services/std_svc/rmmd/trp/trp.mk
index 44bbf22..e511bf5 100644
--- a/services/std_svc/rmmd/trp/trp.mk
+++ b/services/std_svc/rmmd/trp/trp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022 Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2023 Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,7 @@
 				services/std_svc/rmmd/trp/trp_main.c  \
 				services/std_svc/rmmd/trp/trp_helpers.c
 
-RMM_LINKERFILE		:=	services/std_svc/rmmd/trp/linker.lds
+RMM_DEFAULT_LINKER_SCRIPT_SOURCE := services/std_svc/rmmd/trp/linker.ld.S
 
 # Include the platform-specific TRP Makefile
 # If no platform-specific TRP Makefile exists, it means TRP is not supported
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 196bc11..4eb3e12 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -62,7 +62,7 @@
 			   sizeof(trp_shared_region_start));
 
 	/* Perform early platform-specific setup */
-	trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start);
+	trp_early_platform_setup((struct rmm_manifest *)trp_shared_region_start);
 }
 
 int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 7e6c89d..3c207ad 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,10 +16,14 @@
 #include <bl31/interrupt_mgmt.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <common/tbbr/tbbr_img_def.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/smccc.h>
 #include <lib/spinlock.h>
 #include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
@@ -245,6 +249,92 @@
 	SMC_RET0(&ctx->cpu_ctx);
 }
 
+#if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
+static int spmd_dynamic_map_mem(uintptr_t base_addr, size_t size,
+				 unsigned int attr, uintptr_t *align_addr,
+				 size_t *align_size)
+{
+	uintptr_t base_addr_align;
+	size_t mapped_size_align;
+	int rc;
+
+	/* Page aligned address and size if necessary */
+	base_addr_align = page_align(base_addr, DOWN);
+	mapped_size_align = page_align(size, UP);
+
+	if ((base_addr != base_addr_align) &&
+	    (size == mapped_size_align)) {
+		mapped_size_align += PAGE_SIZE;
+	}
+
+	/*
+	 * Map dynamically given region with its aligned base address and
+	 * size
+	 */
+	rc = mmap_add_dynamic_region((unsigned long long)base_addr_align,
+				     base_addr_align,
+				     mapped_size_align,
+				     attr);
+	if (rc == 0) {
+		*align_addr = base_addr_align;
+		*align_size = mapped_size_align;
+	}
+
+	return rc;
+}
+
+static void spmd_do_sec_cpy(uintptr_t root_base_addr, uintptr_t sec_base_addr,
+			    size_t size)
+{
+	uintptr_t root_base_addr_align, sec_base_addr_align;
+	size_t root_mapped_size_align, sec_mapped_size_align;
+	int rc;
+
+	assert(root_base_addr != 0UL);
+	assert(sec_base_addr != 0UL);
+	assert(size != 0UL);
+
+	/* Map the memory with required attributes */
+	rc = spmd_dynamic_map_mem(root_base_addr, size, MT_RO_DATA | MT_ROOT,
+				  &root_base_addr_align,
+				  &root_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while mapping", "root region",
+		      root_base_addr, rc);
+		panic();
+	}
+
+	rc = spmd_dynamic_map_mem(sec_base_addr, size, MT_RW_DATA | MT_SECURE,
+				  &sec_base_addr_align, &sec_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while mapping",
+		      "secure region", sec_base_addr, rc);
+		panic();
+	}
+
+	/* Do copy operation */
+	(void)memcpy((void *)sec_base_addr, (void *)root_base_addr, size);
+
+	/* Unmap root memory region */
+	rc = mmap_remove_dynamic_region(root_base_addr_align,
+					root_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while unmapping",
+		      "root region", root_base_addr_align, rc);
+		panic();
+	}
+
+	/* Unmap secure memory region */
+	rc = mmap_remove_dynamic_region(sec_base_addr_align,
+					sec_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while unmapping",
+		      "secure region", sec_base_addr_align, rc);
+		panic();
+	}
+}
+#endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */
+
 /*******************************************************************************
  * Loads SPMC manifest and inits SPMC.
  ******************************************************************************/
@@ -254,6 +344,7 @@
 	unsigned int core_id;
 	uint32_t ep_attr, flags;
 	int rc;
+	const struct dyn_cfg_dtb_info_t *image_info __unused;
 
 	/* Load the SPM Core manifest */
 	rc = plat_spm_core_manifest_load(&spmc_attrs, pm_addr);
@@ -344,6 +435,26 @@
 					     DISABLE_ALL_EXCEPTIONS);
 	}
 
+#if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
+	image_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TOS_FW_CONFIG_ID);
+	assert(image_info != NULL);
+
+	if ((image_info->config_addr == 0UL) ||
+	    (image_info->secondary_config_addr == 0UL) ||
+	    (image_info->config_max_size == 0UL)) {
+		return -EINVAL;
+	}
+
+	/* Copy manifest from root->secure region */
+	spmd_do_sec_cpy(image_info->config_addr,
+			image_info->secondary_config_addr,
+			image_info->config_max_size);
+
+	/* Update ep info of BL32 */
+	assert(spmc_ep_info != NULL);
+	spmc_ep_info->args.arg0 = image_info->secondary_config_addr;
+#endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */
+
 	/* Set an initial SPMC context state for all cores. */
 	for (core_id = 0U; core_id < PLATFORM_CORE_COUNT; core_id++) {
 		spm_core_context[core_id].state = SPMC_STATE_OFF;
@@ -470,10 +581,40 @@
 #endif
 	cm_set_next_eret_context(secure_state_out);
 
+#if SPMD_SPM_AT_SEL2
+	/*
+	 * If SPMC is at SEL2, save additional registers x8-x17, which may
+	 * be used in FF-A calls such as FFA_PARTITION_INFO_GET_REGS.
+	 * Note that technically, all SPMCs can support this, but this code is
+	 * under ifdef to minimize breakage in case other SPMCs do not save
+	 * and restore x8-x17.
+	 * We also need to pass through these registers since not all FF-A ABIs
+	 * modify x8-x17, in which case, SMCCC requires that these registers be
+	 * 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_GET_GP(handle, CTX_GPREG_X5),
+			SMC_GET_GP(handle, CTX_GPREG_X6),
+			SMC_GET_GP(handle, CTX_GPREG_X7),
+			SMC_GET_GP(handle, CTX_GPREG_X8),
+			SMC_GET_GP(handle, CTX_GPREG_X9),
+			SMC_GET_GP(handle, CTX_GPREG_X10),
+			SMC_GET_GP(handle, CTX_GPREG_X11),
+			SMC_GET_GP(handle, CTX_GPREG_X12),
+			SMC_GET_GP(handle, CTX_GPREG_X13),
+			SMC_GET_GP(handle, CTX_GPREG_X14),
+			SMC_GET_GP(handle, CTX_GPREG_X15),
+			SMC_GET_GP(handle, CTX_GPREG_X16),
+			SMC_GET_GP(handle, CTX_GPREG_X17)
+			);
+
+#else
 	SMC_RET8(cm_get_context(secure_state_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));
+#endif
 }
 
 /*******************************************************************************
@@ -868,7 +1009,8 @@
 						     FFA_ERROR_NOT_SUPPORTED);
 		}
 
-		/* Fall through to forward the call to the other world */
+		/* Forward the call to the other world */
+		/* fallthrough */
 	case FFA_MSG_SEND:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
 	case FFA_MEM_DONATE_SMC32:
@@ -908,7 +1050,8 @@
 			spmd_spm_core_sync_exit(0ULL);
 		}
 
-		/* Fall through to forward the call to the other world */
+		/* Forward the call to the other world */
+		/* fallthrough */
 	case FFA_INTERRUPT:
 	case FFA_MSG_YIELD:
 		/* This interface must be invoked only by the Secure world */
@@ -929,7 +1072,23 @@
 			return spmd_ffa_error_return(handle, FFA_ERROR_DENIED);
 		}
 		break; /* Not reached */
+#if MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED
+	case FFA_PARTITION_INFO_GET_REGS_SMC64:
+		if (secure_origin) {
+			/* TODO: Future patches to enable support for this */
+			return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+		}
 
+		/* Call only supported with SMCCC 1.2+ */
+		if (MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION) < 0x10002) {
+			return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+		}
+
+		return spmd_smc_forward(smc_fid, secure_origin,
+					x1, x2, x3, x4, cookie,
+					handle, flags);
+		break; /* Not reached */
+#endif
 	default:
 		WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
 		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
diff --git a/services/std_svc/trng/trng_entropy_pool.c b/services/std_svc/trng/trng_entropy_pool.c
index 30105b3..dd08c5e 100644
--- a/services/std_svc/trng/trng_entropy_pool.c
+++ b/services/std_svc/trng/trng_entropy_pool.c
@@ -66,7 +66,7 @@
 bool trng_pack_entropy(uint32_t nbits, uint64_t *out)
 {
 	bool ret = true;
-
+	uint32_t bits_to_discard = nbits;
 	spin_lock(&trng_pool_lock);
 
 	if (!trng_fill_entropy(nbits)) {
@@ -111,9 +111,66 @@
 		 *                   5 4 3 2 1 0 7 6
 		 *                  [e,e,e,e,e,e,e,e]
 		 */
-		out[word_i] = 0;
 		out[word_i] |= entropy[ENTROPY_WORD_INDEX(word_i)] >> rshift;
 
+		/**
+		 * Discarding the used/packed entropy bits from the respective
+		 * words, (word_i) and (word_i+1) as applicable.
+		 * In each iteration of the loop, we pack 64bits of entropy to
+		 * the output buffer. The bits are picked linearly starting from
+		 * 1st word (entropy[0]) till 4th word (entropy[3]) and then
+		 * rolls back (entropy[0]). Discarding of bits is managed
+		 * similarly.
+		 *
+		 * The following diagram illustrates the logic:
+		 *
+		 *          |---------entropy pool----------|
+		 * C var    |--(word_i + 1)-|----word_i-----|
+		 * bit idx  |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
+		 *          [e,e,e,e,e,e,e,e|e,e,0,0,0,0,0,0]
+		 *          |   [e,e,e,e,e,e,e,e]           |
+		 *          |   |--out[word_i]--|           |
+		 *    lshift|---|               |--rshift---|
+		 *          |e,e|0,0,0,0,0,0,0,0|0,0,0,0,0,0|
+		 *              |<==   ||    ==>|
+		 *               bits_to_discard (from these bytes)
+		 *
+		 * variable(bits_to_discard): Tracks the amount of bits to be
+		 * discarded and is updated accordingly in each iteration.
+		 *
+		 * It monitors these packed bits from respective word_i and
+		 * word_i+1 and overwrites them with zeros accordingly.
+		 * It discards linearly from the lowest index and moves upwards
+		 * until bits_to_discard variable becomes zero.
+		 *
+		 * In the above diagram,for example, we pack 2bytes(7th and 6th
+		 * from word_i) and 6bytes(0th till 5th from word_i+1), combine
+		 * and pack them as 64bit to output buffer out[i].
+		 * Depending on the number of bits requested, we discard the
+		 * bits from these packed bytes by overwriting them with zeros.
+		 */
+
+		/*
+		 * If the bits to be discarded is lesser than the amount of bits
+		 * copied to the output buffer from word_i, we discard that much
+		 * amount of bits only.
+		 */
+		if (bits_to_discard < (BITS_PER_WORD - rshift)) {
+			entropy[ENTROPY_WORD_INDEX(word_i)] &=
+			(~0ULL << ((bits_to_discard+rshift) % BITS_PER_WORD));
+			bits_to_discard = 0;
+		} else {
+		/*
+		 * If the bits to be discarded is more than the amount of valid
+		 * upper bits from word_i, which has been copied to the output
+		 * buffer, we just set the entire word_i to 0, as the lower bits
+		 * will be already zeros from previous operations, and the
+		 * bits_to_discard is updated precisely.
+		 */
+			entropy[ENTROPY_WORD_INDEX(word_i)] = 0;
+			bits_to_discard -= (BITS_PER_WORD - rshift);
+		}
+
 		/*
 		 * Note that a shift of 64 bits is treated as a shift of 0 bits.
 		 * When the shift amount is the same as the BITS_PER_WORD, we
@@ -123,6 +180,35 @@
 		if (lshift != BITS_PER_WORD) {
 			out[word_i] |= entropy[ENTROPY_WORD_INDEX(word_i + 1)]
 				<< lshift;
+			/**
+			 * Discarding the remaining packed bits from upperword
+			 * (word[i+1]) which was copied to output buffer by
+			 * overwriting with zeros.
+			 *
+			 * If the remaining bits to be discarded is lesser than
+			 * the amount of bits from [word_i+1], which has been
+			 * copied to the output buffer, we overwrite that much
+			 * amount of bits only.
+			 */
+			if (bits_to_discard < (BITS_PER_WORD - lshift)) {
+				entropy[ENTROPY_WORD_INDEX(word_i+1)]  &=
+				(~0ULL << ((bits_to_discard) % BITS_PER_WORD));
+				bits_to_discard = 0;
+			} else {
+			/*
+			 * If bits to discard is more than the bits from word_i+1
+			 * which got packed into the output, then we discard all
+			 * those copied bits.
+			 *
+			 * Note: we cannot set the entire word_i+1 to 0, as
+			 * there are still some unused valid entropy bits at the
+			 * upper end for future use.
+			 */
+				entropy[ENTROPY_WORD_INDEX(word_i+1)]  &=
+				(~0ULL << ((BITS_PER_WORD - lshift) % BITS_PER_WORD));
+				bits_to_discard -= (BITS_PER_WORD - lshift);
+		}
+
 		}
 	}
 	const uint64_t mask = ~0ULL >> (BITS_PER_WORD - (nbits % BITS_PER_WORD));
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 487777b..27ec979 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -212,7 +212,7 @@
 			*err_code = KEY_ERR_OPEN;
 		}
 	} else {
-		WARN("Key filename not specified\n");
+		VERBOSE("Key filename not specified\n");
 		*err_code = KEY_ERR_FILENAME;
 	}
 
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 5c240b5..fadf319 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -1,9 +1,12 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#ifndef _MSC_VER
+#include <sys/mount.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -298,6 +301,7 @@
 	fip_toc_header_t *toc_header;
 	fip_toc_entry_t *toc_entry;
 	int terminated = 0;
+	size_t st_size;
 
 	fp = fopen(filename, "rb");
 	if (fp == NULL)
@@ -306,13 +310,21 @@
 	if (fstat(fileno(fp), &st) == -1)
 		log_err("fstat %s", filename);
 
+	st_size = st.st_size;
+
-	buf = xmalloc(st.st_size, "failed to load file into memory");
-	if (fread(buf, 1, st.st_size, fp) != st.st_size)
+#ifdef BLKGETSIZE64
+	if ((st.st_mode & S_IFBLK) != 0)
+		if (ioctl(fileno(fp), BLKGETSIZE64, &st_size) == -1)
+			log_err("ioctl %s", filename);
+#endif
+
+	buf = xmalloc(st_size, "failed to load file into memory");
+	if (fread(buf, 1, st_size, fp) != st_size)
 		log_errx("Failed to read %s", filename);
-	bufend = buf + st.st_size;
+	bufend = buf + st_size;
 	fclose(fp);
 
-	if (st.st_size < sizeof(fip_toc_header_t))
+	if (st_size < sizeof(fip_toc_header_t))
 		log_errx("FIP %s is truncated", filename);
 
 	toc_header = (fip_toc_header_t *)buf;
@@ -347,9 +359,11 @@
 		    "failed to allocate image buffer, is FIP file corrupted?");
 		/* Overflow checks before memory copy. */
 		if (toc_entry->size > (uint64_t)-1 - toc_entry->offset_address)
-			log_errx("FIP %s is corrupted", filename);
-		if (toc_entry->size + toc_entry->offset_address > st.st_size)
-			log_errx("FIP %s is corrupted", filename);
+			log_errx("FIP %s is corrupted: entry size exceeds 64 bit address space",
+				filename);
+		if (toc_entry->size + toc_entry->offset_address > st_size)
+			log_errx("FIP %s is corrupted: entry size exceeds FIP file size",
+				filename);
 
 		memcpy(image->buffer, buf + toc_entry->offset_address,
 		    toc_entry->size);