Merge "allwinner: Enable workaround for Cortex-A53 erratum 1530924" into integration
diff --git a/Makefile b/Makefile
index 5c9186e..2d5a5bb 100644
--- a/Makefile
+++ b/Makefile
@@ -185,13 +185,14 @@
 else
 target32-directive	= 	-target armv8a-none-eabi
 
-# Set the compiler's target architecture profile based on ARM_ARCH_MINOR option
+# Set the compiler's target architecture profile based on
+# ARM_ARCH_MAJOR ARM_ARCH_MINOR options
 ifeq (${ARM_ARCH_MINOR},0)
-march32-directive	= 	-march=armv8-a
-march64-directive	= 	-march=armv8-a
+march32-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
+march64-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
 else
-march32-directive	= 	-march=armv8.${ARM_ARCH_MINOR}-a
-march64-directive	= 	-march=armv8.${ARM_ARCH_MINOR}-a
+march32-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
+march64-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
 endif
 endif
 
@@ -203,23 +204,43 @@
 endif
 endif
 
-# Enabled required option for memory stack tagging. Currently, these options are
-# enabled only for clang and armclang compiler.
+# Get architecture feature modifiers
+arch-features		=	${ARM_ARCH_FEATURE}
+
+# Enable required options for memory stack tagging.
+# Currently, these options are enabled only for clang and armclang compiler.
 ifeq (${SUPPORT_STACK_MEMTAG},yes)
 ifdef mem_tag_arch_support
+# Check for armclang and clang compilers
 ifneq ( ,$(filter $(notdir $(CC)),armclang clang))
-march64-directive       =       -march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a+memtag
+# Add "memtag" architecture feature modifier if not specified
+ifeq ( ,$(findstring memtag,$(arch-features)))
+arch-features       	:=       $(arch-features)+memtag
+endif	# memtag
 ifeq ($(notdir $(CC)),armclang)
 TF_CFLAGS		+=	-mmemtag-stack
 else ifeq ($(notdir $(CC)),clang)
 TF_CFLAGS		+=	-fsanitize=memtag
-endif
-endif
+endif	# armclang
+endif	# armclang clang
 else
 $(error "Error: stack memory tagging is not supported for architecture \
 	${ARCH},armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a")
+endif	# mem_tag_arch_support
+endif	# SUPPORT_STACK_MEMTAG
+
+# Set the compiler's architecture feature modifiers
+ifneq ($(arch-features), none)
+# Strip "none+" from arch-features
+arch-features		:=	$(subst none+,,$(arch-features))
+ifeq ($(ARCH), aarch32)
+march32-directive	:=	$(march32-directive)+$(arch-features)
+else
+march64-directive	:=	$(march64-directive)+$(arch-features)
 endif
-endif
+# Print features
+$(info Arm Architecture Features specified: $(subst +, ,$(arch-features)))
+endif	# arch-features
 
 ifneq ($(findstring armclang,$(notdir $(CC))),)
 TF_CFLAGS_aarch32	=	-target arm-arm-none-eabi $(march32-directive)
@@ -867,6 +888,7 @@
         CTX_INCLUDE_EL2_REGS \
         CTX_INCLUDE_NEVE_REGS \
         DEBUG \
+        DISABLE_MTPMU \
         DYN_DISABLE_AUTH \
         EL3_EXCEPTION_HANDLING \
         ENABLE_AMU \
@@ -956,6 +978,7 @@
         CTX_INCLUDE_EL2_REGS \
         CTX_INCLUDE_NEVE_REGS \
         DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \
+        DISABLE_MTPMU \
         ENABLE_AMU \
         ENABLE_ASSERTIONS \
         ENABLE_BTI \
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index b839990..d11b4ab 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -16,6 +16,10 @@
 				plat/common/${ARCH}/platform_up_stack.S \
 				${MBEDTLS_SOURCES}
 
+ifeq (${DISABLE_MTPMU},1)
+BL1_SOURCES		+=	lib/extensions/mtpmu/${ARCH}/mtpmu.S
+endif
+
 ifeq (${ARCH},aarch64)
 BL1_SOURCES		+=	lib/cpus/aarch64/dsu_helpers.S		\
 				lib/el3_runtime/aarch64/context.S
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
index 6dc0f18..735e7e0 100644
--- a/bl2/bl2.mk
+++ b/bl2/bl2.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -25,6 +25,10 @@
 				lib/cpus/${ARCH}/cpu_helpers.S		\
 				lib/cpus/errata_report.c
 
+ifeq (${DISABLE_MTPMU},1)
+BL2_SOURCES		+=	lib/extensions/mtpmu/${ARCH}/mtpmu.S
+endif
+
 ifeq (${ARCH},aarch64)
 BL2_SOURCES		+=	lib/cpus/aarch64/dsu_helpers.S
 endif
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index cd6549b..e299fe1 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -40,6 +40,9 @@
 				${SPMD_SOURCES}					\
 				${SPM_SOURCES}
 
+ifeq (${DISABLE_MTPMU},1)
+BL31_SOURCES		+=	lib/extensions/mtpmu/aarch64/mtpmu.S
+endif
 
 ifeq (${ENABLE_PMF}, 1)
 BL31_SOURCES		+=	lib/pmf/pmf_main.c
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 6233299..afd7ae1 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,6 +19,10 @@
 				services/std_svc/std_svc_setup.c	\
 				${PSCI_LIB_SOURCES}
 
+ifeq (${DISABLE_MTPMU},1)
+BL32_SOURCES		+=	lib/extensions/mtpmu/aarch32/mtpmu.S
+endif
+
 ifeq (${ENABLE_PMF}, 1)
 BL32_SOURCES		+=	lib/pmf/pmf_main.c
 endif
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index e901e0c..d859cc5 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -249,6 +249,9 @@
 -  ``ERRATA_A76_1868343``: This applies errata 1868343 workaround to Cortex-A76
    CPU. This needs to be enabled only for revision <= r4p0 of the CPU.
 
+-  ``ERRATA_A76_1946160``: This applies errata 1946160 workaround to Cortex-A76
+   CPU. This needs to be enabled only for revisions r3p0 - r4p1 of the CPU.
+
 For Cortex-A77, the following errata build flags are defined :
 
 -  ``ERRATA_A77_1508412``: This applies errata 1508412 workaround to Cortex-A77
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 8adf4ad..16de410 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -26,6 +26,12 @@
    ``aarch64`` or ``aarch32`` as values. By default, it is defined to
    ``aarch64``.
 
+-  ``ARM_ARCH_FEATURE``: Optional Arm Architecture build option which specifies
+   one or more feature modifiers. This option has the form ``[no]feature+...``
+   and defaults to ``none``. It translates into compiler option
+   ``-march=armvX[.Y]-a+[no]feature+...``. See compiler's documentation for the
+   list of supported feature modifiers.
+
 -  ``ARM_ARCH_MAJOR``: The major version of Arm Architecture to target when
    compiling TF-A. Its value must be numeric, and defaults to 8 . See also,
    *Armv8 Architecture Extensions* and *Armv7 Architecture Extensions* in
@@ -185,6 +191,11 @@
    of the binary image. If set to 1, then only the ELF image is built.
    0 is the default.
 
+-  ``DISABLE_MTPMU``: Boolean option to disable FEAT_MTPMU if implemented
+   (Armv8.6 onwards). Its default value is 0 to keep consistency with platforms
+   that do not implement FEAT_MTPMU. For more information on FEAT_MTPMU,
+   check the latest Arm ARM.
+
 -  ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted
    Board Boot authentication at runtime. This option is meant to be enabled only
    for development platforms. ``TRUSTED_BOARD_BOOT`` flag must be set if this
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index 2e50068..a1d2313 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -94,6 +94,10 @@
 -  ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the
    SPMC Core manifest. Valid when ``SPD=spmd`` is selected.
 
+-  ``OPTEE_SP_FW_CONFIG``: DTC build flag to include OP-TEE as SP in tb_fw_config
+   device tree. This flag is defined only when ``ARM_SPMC_MANIFEST_DTS`` manifest
+   file name contains pattern optee_sp.
+
 For a better understanding of these options, the Arm development platform memory
 map is explained in the :ref:`Firmware Design`.
 
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 3a13268..f643f6b 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -50,6 +50,7 @@
 -  ``FVP_RD_N1_edge``      (Version 11.10 build 36)
 -  ``FVP_RD_N1_edge_dual`` (Version 11.10 build 36)
 -  ``FVP_RD_Daniel``       (Version 11.10 build 36)
+-  ``FVP_RD_N2``           (Version 11.13 build 10)
 -  ``FVP_TC0``             (Version 0.0 build 6114)
 -  ``Foundation_Platform``
 
diff --git a/fdts/tc0.dts b/fdts/tc0.dts
index 763c813..5438474 100644
--- a/fdts/tc0.dts
+++ b/fdts/tc0.dts
@@ -109,6 +109,17 @@
 		reg = <0x0 0x80000000 0x0 0x7d000000>;
 	};
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		optee@0xfce00000 {
+			reg = <0x00000000 0xfce00000 0 0x00200000>;
+			no-map;
+		};
+	};
+
 	psci {
 		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
 		method = "smc";
@@ -370,4 +381,17 @@
 			};
 		};
 	};
+
+	ffa {
+		compatible = "arm,ffa";
+		conduit = "smc";
+		mem_share_buffer = "tx";
+	};
+
+	firmware {
+		optee {
+		      compatible = "linaro,optee-tz";
+		      method = "ffa";
+		};
+	};
 };
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index db8938f..c30073b 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -102,6 +102,11 @@
 /* CSSELR definitions */
 #define LEVEL_SHIFT		U(1)
 
+/* ID_DFR1_EL1 definitions */
+#define ID_DFR1_MTPMU_SHIFT	U(0)
+#define ID_DFR1_MTPMU_MASK	U(0xf)
+#define ID_DFR1_MTPMU_SUPPORTED	U(1)
+
 /* ID_MMFR4 definitions */
 #define ID_MMFR4_CNP_SHIFT	U(12)
 #define ID_MMFR4_CNP_LENGTH	U(4)
@@ -126,6 +131,9 @@
 #define ID_PFR1_GENTIMER_MASK	U(0xf)
 #define ID_PFR1_GIC_SHIFT	U(28)
 #define ID_PFR1_GIC_MASK	U(0xf)
+#define ID_PFR1_SEC_SHIFT	U(4)
+#define ID_PFR1_SEC_MASK	U(0xf)
+#define ID_PFR1_ELx_ENABLED	U(1)
 
 /* SCTLR definitions */
 #define SCTLR_RES1_DEF		((U(1) << 23) | (U(1) << 22) | (U(1) << 4) | \
@@ -164,6 +172,7 @@
 #define SDCR_SCCD_BIT		(U(1) << 23)
 #define SDCR_SPME_BIT		(U(1) << 17)
 #define SDCR_RESET_VAL		U(0x0)
+#define SDCR_MTPME_BIT		(U(1) << 28)
 
 /* HSCTLR definitions */
 #define HSCTLR_RES1	((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \
@@ -244,6 +253,7 @@
 #define VTTBR_BADDR_SHIFT	U(0)
 
 /* HDCR definitions */
+#define HDCR_MTPME_BIT		(U(1) << 28)
 #define HDCR_HLP_BIT		(U(1) << 26)
 #define HDCR_HPME_BIT		(U(1) << 7)
 #define HDCR_RESET_VAL		U(0x0)
@@ -503,6 +513,7 @@
 #define CTR		p15, 0, c0, c0, 1
 #define CNTFRQ		p15, 0, c14, c0, 0
 #define ID_MMFR4	p15, 0, c0, c2, 6
+#define ID_DFR1		p15, 0, c0, c3, 5
 #define ID_PFR0		p15, 0, c0, c1, 0
 #define ID_PFR1		p15, 0, c0, c1, 1
 #define MAIR0		p15, 0, c10, c2, 0
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index 4fd746d..580dd95 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -242,6 +242,10 @@
 	cps	#MODE32_mon
 	isb
 
+#if DISABLE_MTPMU
+	bl	mtpmu_disable
+#endif
+
 	.if \_warm_boot_mailbox
 		/* -------------------------------------------------------------
 		 * This code will be executed for both warm and cold resets.
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 6dcdacf..09e598a 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -188,6 +188,11 @@
 #define ID_AA64DFR0_PMS_SHIFT	U(32)
 #define ID_AA64DFR0_PMS_MASK	ULL(0xf)
 
+/* ID_AA64DFR0_EL1.MTPMU definitions (for ARMv8.6+) */
+#define ID_AA64DFR0_MTPMU_SHIFT		U(48)
+#define ID_AA64DFR0_MTPMU_MASK		ULL(0xf)
+#define ID_AA64DFR0_MTPMU_SUPPORTED	ULL(1)
+
 /* ID_AA64ISAR1_EL1 definitions */
 #define ID_AA64ISAR1_EL1	S3_0_C0_C6_1
 #define ID_AA64ISAR1_GPI_SHIFT	U(28)
@@ -421,6 +426,7 @@
 #define SCR_RESET_VAL		SCR_RES1_BITS
 
 /* MDCR_EL3 definitions */
+#define MDCR_MTPME_BIT		(ULL(1) << 28)
 #define MDCR_SCCD_BIT		(ULL(1) << 23)
 #define MDCR_SPME_BIT		(ULL(1) << 17)
 #define MDCR_SDD_BIT		(ULL(1) << 16)
@@ -436,6 +442,7 @@
 #define MDCR_EL3_RESET_VAL	ULL(0x0)
 
 /* MDCR_EL2 definitions */
+#define MDCR_EL2_MTPME		(U(1) << 28)
 #define MDCR_EL2_HLP		(U(1) << 26)
 #define MDCR_EL2_HCCD		(U(1) << 23)
 #define MDCR_EL2_TTRF		(U(1) << 19)
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 6f4143c..f759983 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -277,6 +277,10 @@
 		isb
 	.endif /* _init_sctlr */
 
+#if DISABLE_MTPMU
+		bl	mtpmu_disable
+#endif
+
 	.if \_warm_boot_mailbox
 		/* -------------------------------------------------------------
 		 * This code will be executed for both warm and cold resets.
diff --git a/include/drivers/allwinner/axp.h b/include/drivers/allwinner/axp.h
index 9c0035f..222820b 100644
--- a/include/drivers/allwinner/axp.h
+++ b/include/drivers/allwinner/axp.h
@@ -9,6 +9,10 @@
 
 #include <stdint.h>
 
+#define AXP20X_MODE_REG 0x3e
+#define AXP20X_MODE_I2C 0x00
+#define AXP20X_MODE_RSB 0x7c
+
 #define NA 0xff
 
 enum {
diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h
index c6315be..aa628df 100644
--- a/include/plat/arm/common/fconf_arm_sp_getter.h
+++ b/include/plat/arm/common/fconf_arm_sp_getter.h
@@ -13,7 +13,7 @@
 /* arm_sp getter */
 #define arm__sp_getter(prop)	arm_sp.prop
 
-#define ARM_SP_MAX_SIZE		U(0x80000)
+#define ARM_SP_MAX_SIZE		U(0xb0000)
 #define ARM_SP_OWNER_NAME_LEN	U(8)
 
 struct arm_sp_t {
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 2c99cdc..4f7f4bb 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -430,6 +430,61 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_1868343
 
+/* --------------------------------------------------
+ * Errata Workaround for A76 Erratum 1946160.
+ * This applies to revisions r3p0 - r4p1 of A76.
+ * It also exists in r0p0 - r2p0 but there is no fix
+ * in those revisions.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a76_1946160_wa
+	/* Compare x0 against revisions r3p0 - r4p1 */
+	mov	x17, x30
+	bl	check_errata_1946160
+	cbz	x0, 1f
+
+	mov	x0, #3
+	msr	S3_6_C15_C8_0, x0
+	ldr	x0, =0x10E3900002
+	msr	S3_6_C15_C8_2, x0
+	ldr	x0, =0x10FFF00083
+	msr	S3_6_C15_C8_3, x0
+	ldr	x0, =0x2001003FF
+	msr	S3_6_C15_C8_1, x0
+
+	mov	x0, #4
+	msr	S3_6_C15_C8_0, x0
+	ldr	x0, =0x10E3800082
+	msr	S3_6_C15_C8_2, x0
+	ldr	x0, =0x10FFF00083
+	msr	S3_6_C15_C8_3, x0
+	ldr	x0, =0x2001003FF
+	msr	S3_6_C15_C8_1, x0
+
+	mov	x0, #5
+	msr	S3_6_C15_C8_0, x0
+	ldr	x0, =0x10E3800200
+	msr	S3_6_C15_C8_2, x0
+	ldr	x0, =0x10FFF003E0
+	msr	S3_6_C15_C8_3, x0
+	ldr	x0, =0x2001003FF
+	msr	S3_6_C15_C8_1, x0
+
+	isb
+1:
+	ret	x17
+endfunc errata_a76_1946160_wa
+
+func check_errata_1946160
+	/* Applies to revisions r3p0 - r4p1. */
+	mov	x1, #0x30
+	mov	x2, #0x41
+	b	cpu_rev_var_range
+endfunc check_errata_1946160
+
 func check_errata_cve_2018_3639
 #if WORKAROUND_CVE_2018_3639
 	mov	x0, #ERRATA_APPLIES
@@ -509,6 +564,11 @@
 	bl	errata_a76_1791580_wa
 #endif
 
+#if ERRATA_A76_1946160
+	mov	x0, x18
+	bl	errata_a76_1946160_wa
+#endif
+
 #if WORKAROUND_CVE_2018_3639
 	/* If the PE implements SSBS, we don't need the dynamic workaround */
 	mrs	x0, id_aa64pfr1_el1
@@ -592,6 +652,7 @@
 	report_errata ERRATA_A76_1791580, cortex_a76, 1791580
 	report_errata ERRATA_A76_1165522, cortex_a76, 1165522
 	report_errata ERRATA_A76_1868343, cortex_a76, 1868343
+	report_errata ERRATA_A76_1946160, cortex_a76, 1946160
 	report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639
 	report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953
 	report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 084e6e7..da0157f 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -278,6 +278,10 @@
 # only to revision <= r4p0 of the Cortex A76 cpu.
 ERRATA_A76_1868343	?=0
 
+# Flag to apply erratum 1946160 workaround during reset. This erratum applies
+# only to revisions r3p0 - r4p1 of the Cortex A76 cpu.
+ERRATA_A76_1946160	?=0
+
 # Flag to apply erratum 1508412 workaround during reset. This erratum applies
 # only to revision <= r1p0 of the Cortex A77 cpu.
 ERRATA_A77_1508412	?=0
@@ -555,6 +559,10 @@
 $(eval $(call assert_boolean,ERRATA_A76_1868343))
 $(eval $(call add_define,ERRATA_A76_1868343))
 
+# Process ERRATA_A76_1946160 flag
+$(eval $(call assert_boolean,ERRATA_A76_1946160))
+$(eval $(call add_define,ERRATA_A76_1946160))
+
 # Process ERRATA_A77_1508412 flag
 $(eval $(call assert_boolean,ERRATA_A77_1508412))
 $(eval $(call add_define,ERRATA_A77_1508412))
diff --git a/lib/extensions/mtpmu/aarch32/mtpmu.S b/lib/extensions/mtpmu/aarch32/mtpmu.S
new file mode 100644
index 0000000..834cee3
--- /dev/null
+++ b/lib/extensions/mtpmu/aarch32/mtpmu.S
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+	.global	mtpmu_disable
+
+/* -------------------------------------------------------------
+ * The functions in this file are called at entrypoint, before
+ * the CPU has decided whether this is a cold or a warm boot.
+ * Therefore there are no stack yet to rely on for a C function
+ * call.
+ * -------------------------------------------------------------
+ */
+
+/*
+ * bool mtpmu_supported(void)
+ *
+ * Return a boolean indicating whether FEAT_MTPMU is supported or not.
+ *
+ * Trash registers: r0.
+ */
+func mtpmu_supported
+	ldcopr	r0, ID_DFR1
+	and	r0, r0, #(ID_DFR1_MTPMU_MASK >> ID_DFR1_MTPMU_SHIFT)
+	cmp	r0, #ID_DFR1_MTPMU_SUPPORTED
+	mov	r0, #0
+	addeq	r0, r0, #1
+	bx	lr
+endfunc mtpmu_supported
+
+/*
+ * bool el_implemented(unsigned int el)
+ *
+ * Return a boolean indicating if the specified EL (2 or 3) is implemented.
+ *
+ * Trash registers: r0
+ */
+func el_implemented
+	cmp	r0, #3
+	ldcopr	r0, ID_PFR1
+	lsreq	r0, r0, #ID_PFR1_SEC_SHIFT
+	lsrne	r0, r0, #ID_PFR1_VIRTEXT_SHIFT
+	/*
+	 * ID_PFR1_VIRTEXT_MASK is the same as ID_PFR1_SEC_MASK
+	 * so use any one of them
+	 */
+	and	r0, r0, #ID_PFR1_VIRTEXT_MASK
+	cmp	r0, #ID_PFR1_ELx_ENABLED
+	mov	r0, #0
+	addeq	r0, r0, #1
+	bx	lr
+endfunc el_implemented
+
+/*
+ * void mtpmu_disable(void)
+ *
+ * Disable mtpmu feature if supported.
+ *
+ * Trash register: r0, r1, r2
+ */
+func mtpmu_disable
+	mov	r2, lr
+	bl	mtpmu_supported
+	cmp	r0, #0
+	bxeq	r2	/* FEAT_MTPMU not supported */
+
+	/* FEAT_MTMPU Supported */
+	mov	r0, #3
+	bl	el_implemented
+	cmp	r0, #0
+	beq	1f
+
+	/* EL3 implemented */
+	ldcopr	r0, SDCR
+	ldr	r1, =SDCR_MTPME_BIT
+	bic	r0, r0, r1
+	stcopr	r0, SDCR
+
+	/*
+	 * If EL3 is implemented, HDCR.MTPME is implemented as Res0 and
+	 * FEAT_MTPMU is controlled only from EL3, so no need to perform
+	 * any operations for EL2.
+	 */
+	isb
+	bx	r2
+1:
+	/* EL3 not implemented */
+	mov	r0, #2
+	bl	el_implemented
+	cmp	r0, #0
+	bxeq	r2	/* No EL2 or EL3 implemented */
+
+	/* EL2 implemented */
+	ldcopr	r0, HDCR
+	ldr	r1, =HDCR_MTPME_BIT
+	orr	r0, r0, r1
+	stcopr	r0, HDCR
+	isb
+	bx	r2
+endfunc mtpmu_disable
diff --git a/lib/extensions/mtpmu/aarch64/mtpmu.S b/lib/extensions/mtpmu/aarch64/mtpmu.S
new file mode 100644
index 0000000..0a1d57b
--- /dev/null
+++ b/lib/extensions/mtpmu/aarch64/mtpmu.S
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+	.global	mtpmu_disable
+
+/* -------------------------------------------------------------
+ * The functions in this file are called at entrypoint, before
+ * the CPU has decided whether this is a cold or a warm boot.
+ * Therefore there are no stack yet to rely on for a C function
+ * call.
+ * -------------------------------------------------------------
+ */
+
+/*
+ * bool mtpmu_supported(void)
+ *
+ * Return a boolean indicating whether FEAT_MTPMU is supported or not.
+ *
+ * Trash registers: x0, x1
+ */
+func mtpmu_supported
+	mrs	x0, id_aa64dfr0_el1
+	mov_imm	x1, ID_AA64DFR0_MTPMU_MASK
+	and	x0, x1, x0, LSR #ID_AA64DFR0_MTPMU_SHIFT
+	cmp	x0, ID_AA64DFR0_MTPMU_SUPPORTED
+	cset	x0, eq
+	ret
+endfunc mtpmu_supported
+
+/*
+ * bool el_implemented(unsigned int el_shift)
+ *
+ * Return a boolean indicating if the specified EL is implemented.
+ * The EL is represented as the bitmask shift on id_aa64pfr0_el1 register.
+ *
+ * Trash registers: x0, x1
+ */
+func el_implemented
+	mrs	x1, id_aa64pfr0_el1
+	lsr	x1, x1, x0
+	cmp	x1, #ID_AA64PFR0_ELX_MASK
+	cset	x0, eq
+	ret
+endfunc el_implemented
+
+/*
+ * void mtpmu_disable(void)
+ *
+ * Disable mtpmu feature if supported.
+ *
+ * Trash register: x0, x1, x30
+ */
+func mtpmu_disable
+	mov	x10, x30
+	bl	mtpmu_supported
+	cbz	x0, exit_disable
+
+	/* FEAT_MTMPU Supported */
+	mov_imm	x0, ID_AA64PFR0_EL3_SHIFT
+	bl	el_implemented
+	cbz	x0, 1f
+
+	/* EL3 implemented */
+	mrs	x0, mdcr_el3
+	mov_imm x1, MDCR_MTPME_BIT
+	bic	x0, x0, x1
+	msr	mdcr_el3, x0
+
+	/*
+	 * If EL3 is implemented, MDCR_EL2.MTPME is implemented as Res0 and
+	 * FEAT_MTPMU is controlled only from EL3, so no need to perform
+	 * any operations for EL2.
+	 */
+	isb
+exit_disable:
+	ret	x10
+1:
+	/* EL3 not implemented */
+	mov_imm	x0, ID_AA64PFR0_EL2_SHIFT
+	bl	el_implemented
+	cbz	x0, exit_disable
+
+	/* EL2 implemented */
+	mrs	x0, mdcr_el2
+	mov_imm x1, MDCR_EL2_MTPME
+	bic	x0, x0, x1
+	msr	mdcr_el2, x0
+	isb
+	ret	x10
+endfunc mtpmu_disable
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 578bd59..5217a85 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -19,6 +19,9 @@
 # The Target build architecture. Supported values are: aarch64, aarch32.
 ARCH				:= aarch64
 
+# ARM Architecture feature modifiers: none by default
+ARM_ARCH_FEATURE		:= none
+
 # ARM Architecture major and minor versions: 8.0 by default.
 ARM_ARCH_MAJOR			:= 8
 ARM_ARCH_MINOR			:= 0
@@ -79,6 +82,10 @@
 # Disable the generation of the binary image (ELF only).
 DISABLE_BIN_GENERATION		:= 0
 
+# Disable MTPMU if FEAT_MTPMU is supported. Default is 0 to keep backwards
+# compatibility.
+DISABLE_MTPMU			:= 0
+
 # Enable capability to disable authentication dynamically. Only meant for
 # development platforms.
 DYN_DISABLE_AUTH		:= 0
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 0ca18ad..841fea8 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -125,11 +125,9 @@
 		device_bit = BIT(6);
 		break;
 	case SUNXI_SOC_H6:
-		if (use_rsb)
-			return -ENODEV;
-		pin_func = 0x33;
+		pin_func = use_rsb ? 0x22 : 0x33;
 		device_bit = BIT(16);
-		reset_offset = 0x19c;
+		reset_offset = use_rsb ? 0x1bc : 0x19c;
 		break;
 	case SUNXI_SOC_A64:
 		pin_func = use_rsb ? 0x22 : 0x33;
@@ -157,7 +155,7 @@
 	if (socid != SUNXI_SOC_H6)
 		mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit);
 	else
-		mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0));
+		mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, BIT(0));
 
 	/* assert, then de-assert reset of I2C/RSB controller */
 	mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index 5b7d76a..80a69c3 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -92,24 +92,16 @@
 	if (ret)
 		return ret;
 
-	/* Start with 400 KHz to issue the I2C->RSB switch command. */
-	ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 400000);
-	if (ret)
-		return ret;
-
-	/*
-	 * Initiate an I2C transaction to write 0x7c into register 0x3e,
-	 * switching the PMIC to RSB mode.
-	 */
-	ret = rsb_set_device_mode(0x7c3e00);
-	if (ret)
-		return ret;
-
-	/* Now in RSB mode, switch to the recommended 3 MHz. */
+	/* Switch to the recommended 3 MHz bus clock. */
 	ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
 	if (ret)
 		return ret;
 
+	/* Initiate an I2C transaction to switch the PMIC to RSB mode. */
+	ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8);
+	if (ret)
+		return ret;
+
 	/* Associate the 8-bit runtime address with the 12-bit bus address. */
 	ret = rsb_assign_runtime_address(AXP803_HW_ADDR,
 					 AXP803_RT_ADDR);
@@ -156,6 +148,11 @@
 		pmic = AXP803_RSB;
 		axp_setup_regulators(fdt);
 
+		/* Switch the PMIC back to I2C mode. */
+		ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C);
+		if (ret)
+			return ret;
+
 		break;
 	default:
 		return -ENODEV;
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index 702db77..1b71606 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -55,6 +55,7 @@
 #define SUNXI_R_TWD_BASE		0x07020800
 #define SUNXI_R_CPUCFG_BASE		0x07000400
 #define SUNXI_R_I2C_BASE		0x07081400
+#define SUNXI_R_RSB_BASE		0x07083000
 #define SUNXI_R_UART_BASE		0x07080000
 #define SUNXI_R_PIO_BASE		0x07022000
 
diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk
index 4ecc57c..1c98919 100644
--- a/plat/allwinner/sun50i_h6/platform.mk
+++ b/plat/allwinner/sun50i_h6/platform.mk
@@ -8,4 +8,4 @@
 include plat/allwinner/common/allwinner-common.mk
 
 BL31_SOURCES		+=	drivers/allwinner/axp/axp805.c		\
-				drivers/mentor/i2c/mi2cv.c
+				drivers/allwinner/sunxi_rsb.c
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index 443015b..a7865a5 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -6,20 +6,17 @@
  */
 
 #include <errno.h>
-#include <string.h>
 
-#include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/allwinner/axp.h>
-#include <drivers/delay_timer.h>
-#include <drivers/mentor/mi2cv.h>
-#include <lib/mmio.h>
+#include <drivers/allwinner/sunxi_rsb.h>
 
 #include <sunxi_def.h>
 #include <sunxi_mmap.h>
 #include <sunxi_private.h>
 
-#define AXP805_ADDR	0x36
+#define AXP805_HW_ADDR	0x745
+#define AXP805_RT_ADDR	0x3a
 
 static enum pmic_type {
 	UNKNOWN,
@@ -28,67 +25,67 @@
 
 int axp_read(uint8_t reg)
 {
-	uint8_t val;
-	int ret;
-
-	ret = i2c_write(AXP805_ADDR, 0, 0, &reg, 1);
-	if (ret == 0)
-		ret = i2c_read(AXP805_ADDR, 0, 0, &val, 1);
-	if (ret) {
-		ERROR("PMIC: Cannot read AXP805 register %02x\n", reg);
-		return ret;
-	}
-
-	return val;
+	return rsb_read(AXP805_RT_ADDR, reg);
 }
 
 int axp_write(uint8_t reg, uint8_t val)
 {
-	int ret;
-
-	ret = i2c_write(AXP805_ADDR, reg, 1, &val, 1);
-	if (ret)
-		ERROR("PMIC: Cannot write AXP805 register %02x\n", reg);
-
-	return ret;
+	return rsb_write(AXP805_RT_ADDR, reg, val);
 }
 
-static int axp805_probe(void)
+static int rsb_init(void)
 {
 	int ret;
 
-	/* Switch the AXP805 to master/single-PMIC mode. */
-	ret = axp_write(0xff, 0x0);
+	ret = rsb_init_controller();
 	if (ret)
 		return ret;
 
-	ret = axp_check_id();
+	/* Switch to the recommended 3 MHz bus clock. */
+	ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
 	if (ret)
 		return ret;
 
-	return 0;
+	/* Initiate an I2C transaction to switch the PMIC to RSB mode. */
+	ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8);
+	if (ret)
+		return ret;
+
+	/* Associate the 8-bit runtime address with the 12-bit bus address. */
+	ret = rsb_assign_runtime_address(AXP805_HW_ADDR, AXP805_RT_ADDR);
+	if (ret)
+		return ret;
+
+	return axp_check_id();
 }
 
 int sunxi_pmic_setup(uint16_t socid, const void *fdt)
 {
 	int ret;
 
-	INFO("PMIC: Probing AXP805 on I2C\n");
+	INFO("PMIC: Probing AXP805 on RSB\n");
 
-	ret = sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+	ret = sunxi_init_platform_r_twi(socid, true);
 	if (ret)
 		return ret;
 
-	/* initialise mi2cv driver */
-	i2c_init((void *)SUNXI_R_I2C_BASE);
+	ret = rsb_init();
+	if (ret)
+		return ret;
 
-	ret = axp805_probe();
+	/* Switch the AXP805 to master/single-PMIC mode. */
+	ret = axp_write(0xff, 0x0);
 	if (ret)
 		return ret;
 
 	pmic = AXP805;
 	axp_setup_regulators(fdt);
 
+	/* Switch the PMIC back to I2C mode. */
+	ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
@@ -96,10 +93,9 @@
 {
 	switch (pmic) {
 	case AXP805:
-		/* Re-initialise after rich OS might have used it. */
-		sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
-		/* initialise mi2cv driver */
-		i2c_init((void *)SUNXI_R_I2C_BASE);
+		/* (Re-)init RSB in case the rich OS has disabled it. */
+		sunxi_init_platform_r_twi(SUNXI_SOC_H6, true);
+		rsb_init();
 		axp_power_off();
 		break;
 	default:
diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h
index a118ca3..5b98b4e 100644
--- a/plat/arm/board/rddaniel/include/platform_def.h
+++ b/plat/arm/board/rddaniel/include/platform_def.h
@@ -9,7 +9,7 @@
 
 #include <lib/utils_def.h>
 
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		U(16)
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk
index 7422d63..6553ae2 100644
--- a/plat/arm/board/rddaniel/platform.mk
+++ b/plat/arm/board/rddaniel/platform.mk
@@ -14,6 +14,8 @@
 
 SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
 
+PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+
 BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
 				${RDDANIEL_BASE}/rddaniel_err.c
 
diff --git a/plat/arm/board/rddanielxlr/include/platform_def.h b/plat/arm/board/rddanielxlr/include/platform_def.h
index b1376b8..112b210 100644
--- a/plat/arm/board/rddanielxlr/include/platform_def.h
+++ b/plat/arm/board/rddanielxlr/include/platform_def.h
@@ -8,7 +8,7 @@
 #define PLATFORM_DEF_H
 
 #include <lib/utils_def.h>
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		U(4)
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
diff --git a/plat/arm/board/rddanielxlr/platform.mk b/plat/arm/board/rddanielxlr/platform.mk
index 8cbad52..2f41e2e 100644
--- a/plat/arm/board/rddanielxlr/platform.mk
+++ b/plat/arm/board/rddanielxlr/platform.mk
@@ -15,6 +15,8 @@
 
 SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
 
+PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+
 BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
 				${RDDANIELXLR_BASE}/rddanielxlr_err.c
 
diff --git a/plat/arm/board/rddanielxlr/rddanielxlr_plat.c b/plat/arm/board/rddanielxlr/rddanielxlr_plat.c
index 4b5f16a..a1a4876 100644
--- a/plat/arm/board/rddanielxlr/rddanielxlr_plat.c
+++ b/plat/arm/board/rddanielxlr/rddanielxlr_plat.c
@@ -8,7 +8,7 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
 #include <sgi_plat.h>
 
 #if defined(IMAGE_BL31)
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
index 3fb6409..c39fe2b 100644
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ b/plat/arm/board/rde1edge/include/platform_def.h
@@ -9,7 +9,7 @@
 
 #include <lib/utils_def.h>
 
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		U(2)
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(8)
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
index a7c0434..53074f4 100644
--- a/plat/arm/board/rde1edge/platform.mk
+++ b/plat/arm/board/rde1edge/platform.mk
@@ -12,6 +12,8 @@
 
 SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_e1.S
 
+PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+
 BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
 				${RDE1EDGE_BASE}/rde1edge_err.c
 
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
index ab63e23..b167c46 100644
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ b/plat/arm/board/rdn1edge/include/platform_def.h
@@ -9,7 +9,7 @@
 
 #include <lib/utils_def.h>
 
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		U(2)
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(4)
diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk
index b313426..d65854f 100644
--- a/plat/arm/board/rdn1edge/platform.mk
+++ b/plat/arm/board/rdn1edge/platform.mk
@@ -15,6 +15,8 @@
 
 SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n1.S
 
+PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+
 BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
 				${RDN1EDGE_BASE}/rdn1edge_err.c
 
diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c
index f62c6f4..1dbbf26 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_plat.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c
@@ -8,7 +8,7 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
 #include <sgi_plat.h>
 
 #if defined(IMAGE_BL31)
diff --git a/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts
new file mode 100644
index 0000000..9c9cefe
--- /dev/null
+++ b/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+	dtb-registry {
+		compatible = "fconf,dyn_cfg-dtb_registry";
+
+		tb_fw-config {
+			load-address = <0x0 0x4001300>;
+			max-size = <0x200>;
+			id = <TB_FW_CONFIG_ID>;
+		};
+
+		nt_fw-config {
+			load-address = <0x0 0xFEF00000>;
+			max-size = <0x0100000>;
+			id = <NT_FW_CONFIG_ID>;
+		};
+	};
+};
diff --git a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
new file mode 100644
index 0000000..bbc36fc
--- /dev/null
+++ b/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+	/* compatible string */
+	compatible = "arm,rd-n2";
+
+	/*
+	 * Place holder for system-id node with default values. The
+	 * value of platform-id and config-id will be set to the
+	 * correct values during the BL2 stage of boot.
+	 */
+	system-id {
+		platform-id = <0x0>;
+		config-id = <0x0>;
+		multi-chip-mode = <0x0>;
+	};
+};
diff --git a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
new file mode 100644
index 0000000..49eda27
--- /dev/null
+++ b/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	tb_fw-config {
+		compatible = "arm,tb_fw";
+
+		/* Disable authentication for development */
+		disable_auth = <0x0>;
+
+		/*
+		 * The following two entries are placeholders for Mbed TLS
+		 * heap information. The default values don't matter since
+		 * they will be overwritten by BL1.
+		 * In case of having shared Mbed TLS heap between BL1 and BL2,
+		 * BL1 will populate these two properties with the respective
+		 * info about the shared heap. This info will be available for
+		 * BL2 in order to locate and re-use the heap.
+		 */
+		mbedtls_heap_addr = <0x0 0x0>;
+		mbedtls_heap_size = <0x0>;
+	};
+};
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
new file mode 100644
index 0000000..5561f8c
--- /dev/null
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+
+#include <sgi_soc_platform_def_v2.h>
+
+#define PLAT_ARM_CLUSTER_COUNT		U(16)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
+#define CSS_SGI_MAX_PE_PER_CPU		U(1)
+
+#define PLAT_CSS_MHU_BASE		UL(0x2A920000)
+#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/* TZC Related Constants */
+#define PLAT_ARM_TZC_BASE		UL(0x10820000)
+#define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+#define TZC400_OFFSET			UL(0x1000000)
+#define TZC400_COUNT			U(8)
+
+#define TZC400_BASE(n)			(PLAT_ARM_TZC_BASE + \
+						(n * TZC400_OFFSET))
+
+#define TZC_NSAID_ALL_AP		U(0)
+#define TZC_NSAID_PCI			U(1)
+#define TZC_NSAID_HDLCD0		U(2)
+#define TZC_NSAID_CLCD			U(7)
+#define TZC_NSAID_AP			U(9)
+#define TZC_NSAID_VIRTIO		U(15)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS	\
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI))    | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP))     | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD))   | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
+ */
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 42)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 42)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#endif
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE		UL(0x301C0000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
new file mode 100644
index 0000000..6be6113
--- /dev/null
+++ b/plat/arm/board/rdn2/platform.mk
@@ -0,0 +1,59 @@
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# RD-N2 platform uses GIC-Clayton which is based on GICv4.1
+GIC_ENABLE_V4_EXTN	:=	1
+
+include plat/arm/css/sgi/sgi-common.mk
+
+RDN2_BASE		=	plat/arm/board/rdn2
+
+PLAT_INCLUDES		+=	-I${RDN2_BASE}/include/
+
+SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n2.S
+
+PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat_v2.c
+
+BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+				${RDN2_BASE}/rdn2_err.c
+
+BL2_SOURCES		+=	${RDN2_BASE}/rdn2_plat.c		\
+				${RDN2_BASE}/rdn2_security.c		\
+				${RDN2_BASE}/rdn2_err.c			\
+				lib/utils/mem_region.c			\
+				drivers/arm/tzc/tzc400.c		\
+				plat/arm/common/arm_tzc400.c		\
+				plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+				${RDN2_BASE}/rdn2_plat.c		\
+				${RDN2_BASE}/rdn2_topology.c		\
+				drivers/cfi/v2m/v2m_flash.c		\
+				lib/utils/mem_region.c			\
+				plat/arm/common/arm_nor_psci_mem_protect.c
+
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES		+=	${RDN2_BASE}/rdn2_trusted_boot.c
+BL2_SOURCES		+=	${RDN2_BASE}/rdn2_trusted_boot.c
+endif
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES		+=	${RDN2_BASE}/fdts/${PLAT}_fw_config.dts	\
+				${RDN2_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+
+FDT_SOURCES		+=	${RDN2_BASE}/fdts/${PLAT}_nt_fw_config.dts
+NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+
+override CTX_INCLUDE_AARCH32_REGS	:= 0
diff --git a/plat/arm/board/rdn2/rdn2_err.c b/plat/arm/board/rdn2/rdn2_err.c
new file mode 100644
index 0000000..802ac21
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rdn2 error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+	while (1) {
+		wfi();
+	}
+}
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c
new file mode 100644
index 0000000..5bf14e3
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+#include <sgi_plat.h>
+
+unsigned int plat_arm_sgi_get_platform_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
+			    & SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_sgi_get_config_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+			     SID_MULTI_CHIP_MODE_MASK) >>
+			     SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+void bl31_platform_setup(void)
+{
+	sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/rdn2/rdn2_security.c b/plat/arm/board/rdn2/rdn2_security.c
new file mode 100644
index 0000000..9568b60
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_security.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+
+static const arm_tzc_regions_info_t tzc_regions[] = {
+	ARM_TZC_REGIONS_DEF,
+	{}
+};
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+
+	int i;
+
+	for (i = 0; i < TZC400_COUNT; i++)
+		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
+
+}
diff --git a/plat/arm/board/rdn2/rdn2_topology.c b/plat/arm/board/rdn2/rdn2_topology.c
new file mode 100644
index 0000000..5c2e287
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_topology.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char rd_n2_pd_tree_desc[] = {
+	PLAT_ARM_CLUSTER_COUNT,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return rd_n2_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)),
+};
diff --git a/plat/arm/board/rdn2/rdn2_trusted_boot.c b/plat/arm/board/rdn2/rdn2_trusted_boot.c
new file mode 100644
index 0000000..4592b8f
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm         OBJECT IDENTIFIER,
+ *     parameters        ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm   AlgorithmIdentifier,
+ *     digest            OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index 95986cf..c929334 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -9,7 +9,7 @@
 
 #include <lib/utils_def.h>
 
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		U(2)
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(4)
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index 56f5733..89abcfe 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -12,6 +12,8 @@
 
 SGI_CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a75.S
 
+PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+
 BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
 				${SGI575_BASE}/sgi575_err.c
 
diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts
new file mode 100644
index 0000000..a58b911
--- /dev/null
+++ b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+#define	AFF	00
+
+#include "fvp-defs.dtsi"
+#undef POST
+#define	POST \
+	};
+
+/ {
+	compatible = "arm,ffa-core-manifest-1.0";
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	attribute {
+		spmc_id = <0x8000>;
+		maj_ver = <0x1>;
+		min_ver = <0x0>;
+		exec_state = <0x0>;
+		load_address = <0x0 0xfd000000>;
+		entrypoint = <0x0 0xfd000000>;
+		binary_size = <0x80000>;
+	};
+
+	/*
+	 * temporary: This entry is added based on v2.4 hafnium and will be
+	 * removed when rebased to upstream master.
+	 */
+	chosen {
+	       linux,initrd-start = <0>;
+	       linux,initrd-end = <0>;
+	};
+
+	hypervisor {
+		compatible = "hafnium,hafnium";
+		vm1 {
+			is_ffa_partition;
+			debug_name = "op-tee";
+			load_address = <0xfd280000>;
+		};
+	};
+
+	cpus {
+		#address-cells = <0x2>;
+		#size-cells = <0x0>;
+
+		CPU_0
+
+		/*
+		 * SPMC (Hafnium) requires secondary core nodes are declared
+		 * in descending order.
+		 */
+		CPU_3
+		CPU_2
+		CPU_1
+	};
+
+	/*
+	 * temporary: This device-memory region is added based on v2.4 hafnium
+	 * and will be removed when rebased to upstream master. As first
+	 * Secure Partition no longer maps device memory.
+	 */
+	device-memory@21000000 {
+		device_type = "device-memory";
+		reg = <0x0 0x21000000 0x5f000000>;
+	};
+
+	/* 32MB of TC0_TZC_DRAM1_BASE */
+	memory@fd000000 {
+		device_type = "memory";
+		reg = <0x0 0xfd000000 0x2000000>;
+	};
+};
diff --git a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
index 3df94bf..de5f95d 100644
--- a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
+++ b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
@@ -27,6 +27,12 @@
 
 	secure-partitions {
 		compatible = "arm,sp";
+#if OPTEE_SP_FW_CONFIG
+		op-tee {
+		       uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>;
+		       load-address = <0xfd280000>;
+		};
+#else
 		cactus-primary {
 			uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
 			load-address = <0xfe000000>;
@@ -43,5 +49,6 @@
 			uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>;
 			load-address = <0xfe200000>;
 		};
+#endif
 	};
 };
diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h
index 72a035f..2ff2699 100644
--- a/plat/arm/board/tc0/include/platform_def.h
+++ b/plat/arm/board/tc0/include/platform_def.h
@@ -112,7 +112,7 @@
  * little space for growth.
  */
 #if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE		0x1E000
+# define PLAT_ARM_MAX_BL2_SIZE		0x20000
 #else
 # define PLAT_ARM_MAX_BL2_SIZE		0x14000
 #endif
diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk
index 5d2cc38..6cc5f46 100644
--- a/plat/arm/board/tc0/platform.mk
+++ b/plat/arm/board/tc0/platform.mk
@@ -86,8 +86,12 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 ifeq (${SPD},spmd)
-FDT_SOURCES		+=	${TC0_BASE}/fdts/${PLAT}_spmc_manifest.dts
-TC0_TOS_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb
+ifeq ($(ARM_SPMC_MANIFEST_DTS),)
+ARM_SPMC_MANIFEST_DTS	:=	${TC0_BASE}/fdts/${PLAT}_spmc_manifest.dts
+endif
+
+FDT_SOURCES		+=	${ARM_SPMC_MANIFEST_DTS}
+TC0_TOS_FW_CONFIG	:=	${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb
 
 # Add the TOS_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TC0_TOS_FW_CONFIG},--tos-fw-config,${TC0_TOS_FW_CONFIG}))
diff --git a/plat/arm/board/tc0/tc0_plat.c b/plat/arm/board/tc0/tc0_plat.c
index e12ad56..b5698c0 100644
--- a/plat/arm/board/tc0/tc0_plat.c
+++ b/plat/arm/board/tc0/tc0_plat.c
@@ -51,6 +51,10 @@
 #if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
 	ARM_MAP_BL1_RW,
 #endif
+#ifdef SPD_opteed
+	ARM_MAP_OPTEE_CORE_MEM,
+	ARM_OPTEE_PAGEABLE_LOAD_MEM,
+#endif
 	{0}
 };
 #endif
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 159084f..b805746 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -9,12 +9,9 @@
 
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
-#include <plat/arm/board/common/board_css_def.h>
-#include <plat/arm/board/common/v2m_def.h>
 #include <plat/arm/common/arm_def.h>
 #include <plat/arm/common/arm_spm_def.h>
 #include <plat/arm/css/common/css_def.h>
-#include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
 #define PLATFORM_CORE_COUNT		(CSS_SGI_CHIP_COUNT *		\
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
new file mode 100644
index 0000000..03f1073
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_SOC_CSS_DEF_V2_H
+#define SGI_SOC_CSS_DEF_V2_H
+
+#include <lib/utils_def.h>
+#include <plat/common/common_def.h>
+
+/*
+ * Definitions common to all ARM CSS SoCs
+ */
+
+/* Following covers ARM CSS SoC Peripherals */
+
+#define SOC_SYSTEM_PERIPH_BASE		UL(0x0C000000)
+#define SOC_SYSTEM_PERIPH_SIZE		UL(0x02000000)
+
+#define SOC_PLATFORM_PERIPH_BASE	UL(0x0E000000)
+#define SOC_PLATFORM_PERIPH_SIZE	UL(0x02000000)
+
+#define SOC_CSS_PCIE_CONTROL_BASE	UL(0x0ef20000)
+
+/* PL011 UART related constants */
+#define SOC_CSS_UART1_BASE		UL(0x0ef80000)
+#define SOC_CSS_UART0_BASE		UL(0x0ef70000)
+
+/* Memory controller */
+#define SOC_MEMCNTRL_BASE		UL(0x10000000)
+#define SOC_MEMCNTRL_SIZE		UL(0x10000000)
+
+#define SOC_CSS_UART0_CLK_IN_HZ		UL(7372800)
+#define SOC_CSS_UART1_CLK_IN_HZ		UL(7372800)
+
+/* SoC NIC-400 Global Programmers View (GPV) */
+#define SOC_CSS_NIC400_BASE		UL(0x0ED00000)
+
+#define SOC_CSS_NIC400_USB_EHCI		U(0)
+#define SOC_CSS_NIC400_TLX_MASTER	U(1)
+#define SOC_CSS_NIC400_USB_OHCI		U(2)
+#define SOC_CSS_NIC400_PL354_SMC	U(3)
+/*
+ * The apb4_bridge controls access to:
+ *   - the PCIe configuration registers
+ *   - the MMU units for USB, HDLCD and DMA
+ */
+#define SOC_CSS_NIC400_APB4_BRIDGE	U(4)
+
+/* Non-volatile counters */
+#define SOC_TRUSTED_NVCTR_BASE		UL(0x0EE70000)
+#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0000)
+#define TFW_NVCTR_SIZE			U(4)
+#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE			U(4)
+
+/* Keys */
+#define SOC_KEYS_BASE			UL(0x0EE80000)
+#define TZ_PUB_KEY_HASH_BASE		(SOC_KEYS_BASE + 0x0000)
+#define TZ_PUB_KEY_HASH_SIZE		U(32)
+#define HU_KEY_BASE			(SOC_KEYS_BASE + 0x0020)
+#define HU_KEY_SIZE			U(16)
+#define END_KEY_BASE			(SOC_KEYS_BASE + 0x0044)
+#define END_KEY_SIZE			U(32)
+
+#define SOC_PLATFORM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(			\
+						SOC_PLATFORM_PERIPH_BASE, 	\
+						SOC_PLATFORM_PERIPH_SIZE, 	\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+#define SOC_SYSTEM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(			\
+						SOC_SYSTEM_PERIPH_BASE,		\
+						SOC_SYSTEM_PERIPH_SIZE,		\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+#define SOC_MEMCNTRL_MAP_DEVICE		MAP_REGION_FLAT(			\
+						SOC_MEMCNTRL_BASE,		\
+						SOC_MEMCNTRL_SIZE,		\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+/*
+ * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs.
+ */
+#define SOC_CSS_NIC400_BOOTSEC_BRIDGE		U(5)
+#define SOC_CSS_NIC400_BOOTSEC_BRIDGE_UART1	UL(1 << 12)
+
+/*
+ * Required platform porting definitions common to all ARM CSS SoCs
+ */
+/* 2MB used for SCP DDR retraining */
+#define PLAT_ARM_SCP_TZC_DRAM1_SIZE	UL(0x00200000)
+
+/* V2M motherboard system registers & offsets */
+#define V2M_SYSREGS_BASE		UL(0x0C010000)
+#define V2M_SYS_LED			U(0x8)
+
+/*
+ * V2M sysled bit definitions. The values written to this
+ * register are defined in arch.h & runtime_svc.h. Only
+ * used by the primary cpu to diagnose any cold boot issues.
+ *
+ * SYS_LED[0]   - Security state (S=0/NS=1)
+ * SYS_LED[2:1] - Exception Level (EL3-EL0)
+ * SYS_LED[7:3] - Exception Class (Sync/Async & origin)
+ *
+ */
+#define V2M_SYS_LED_SS_SHIFT		U(0)
+#define V2M_SYS_LED_EL_SHIFT		U(1)
+#define V2M_SYS_LED_EC_SHIFT		U(3)
+
+#define V2M_SYS_LED_SS_MASK		U(0x01)
+#define V2M_SYS_LED_EL_MASK		U(0x03)
+#define V2M_SYS_LED_EC_MASK		U(0x1f)
+
+/* NOR Flash */
+#define V2M_FLASH0_BASE			UL(0x08000000)
+#define V2M_FLASH0_SIZE			UL(0x04000000)
+#define V2M_FLASH_BLOCK_SIZE		UL(0x00040000)	/* 256 KB */
+
+/*
+ * The flash can be mapped either as read-only or read-write.
+ *
+ * If it is read-write then it should also be mapped as device memory because
+ * NOR flash programming involves sending a fixed, ordered sequence of commands.
+ *
+ * If it is read-only then it should also be mapped as:
+ * - Normal memory, because reading from NOR flash is transparent, it is like
+ *   reading from RAM.
+ * - Non-executable by default. If some parts of the flash need to be executable
+ *   then platform code is responsible for re-mapping the appropriate portion
+ *   of it as executable.
+ */
+#define V2M_MAP_FLASH0_RW		MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+						V2M_FLASH0_SIZE,	\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+#define V2M_MAP_FLASH0_RO		MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+						V2M_FLASH0_SIZE,	\
+						MT_RO_DATA | MT_SECURE)
+
+#define SGI_MAP_FLASH0_RO		MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+						V2M_FLASH0_SIZE,	\
+						MT_DEVICE | MT_RO | MT_SECURE)
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR		UL(0x0EFE00E0)
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0F)
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK	U(0xF00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT	U(0x08)
+#define BOARD_CSS_PLAT_TYPE_RTL			U(0x00)
+#define BOARD_CSS_PLAT_TYPE_FPGA		U(0x01)
+#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
+#define BOARD_CSS_PLAT_TYPE_FVP			U(0x03)
+
+#ifndef __ASSEMBLER__
+
+#include <lib/mmio.h>
+
+#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
+	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
+	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+
+#endif /* __ASSEMBLER__ */
+
+
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+/* Reserve the last block of flash for PSCI MEM PROTECT flag */
+#define PLAT_ARM_FIP_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_FIP_MAX_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/* UART related constants */
+#define PLAT_ARM_BOOT_UART_BASE			SOC_CSS_UART0_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ		SOC_CSS_UART0_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE			SOC_CSS_UART1_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ		SOC_CSS_UART1_CLK_IN_HZ
+
+#define PLAT_ARM_SP_MIN_RUN_UART_BASE		SOC_CSS_UART1_BASE
+#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ	SOC_CSS_UART1_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE		PLAT_ARM_RUN_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ		PLAT_ARM_RUN_UART_CLK_IN_HZ
+
+#endif /* SGI_SOC_CSS_DEF_V2_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def.h b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
new file mode 100644
index 0000000..d7a839a
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_SOC_PLATFORM_DEF_H
+#define SGI_SOC_PLATFORM_DEF_H
+
+#include <sgi_base_platform_def.h>
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
+
+#endif /* SGI_SOC_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
new file mode 100644
index 0000000..cb747c3
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_SOC_PLATFORM_DEF_V2_H
+#define SGI_SOC_PLATFORM_DEF_V2_H
+
+#include <sgi_base_platform_def.h>
+#include <sgi_soc_css_def_v2.h>
+
+#endif /* SGI_SOC_PLATFORM_DEF_V2_H */
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
index f4c5300..eb12f3f 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/css/sgi/include/sgi_variant.h
@@ -17,6 +17,9 @@
 /* SID Version values for RD-Daniel */
 #define RD_DANIEL_SID_VER_PART_NUM		0x078a
 
+/* SID Version values for RD-N2 */
+#define RD_N2_SID_VER_PART_NUM			0x07B7
+
 /* Structure containing SGI platform variant information */
 typedef struct sgi_platform_info {
 	unsigned int platform_id;	/* Part Number of the platform */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 6b9e0cd..615f53d 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -32,8 +32,7 @@
 				plat/common/plat_gicv3.c	\
 				plat/arm/common/arm_gicv3.c
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c	\
-				${CSS_ENT_BASE}/aarch64/sgi_helper.S
+PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/aarch64/sgi_helper.S
 
 BL1_SOURCES		+=	${INTERCONNECT_SOURCES}			\
 				drivers/arm/sbsa/sbsa.c
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index a4aed00..d5c7593 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -74,7 +74,8 @@
 scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
 {
 	if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM) {
+		sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM ||
+		sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM) {
 		if (channel_id >= ARRAY_SIZE(rd_n1e1_edge_scmi_plat_info))
 			panic();
 		return &rd_n1e1_edge_scmi_plat_info[channel_id];
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
new file mode 100644
index 0000000..a770255
--- /dev/null
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	SGI_MAP_FLASH0_RO,
+	CSS_SGI_MAP_DEVICE,
+	SOC_PLATFORM_PERIPH_MAP_DEVICE,
+	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+	{0}
+};
+#endif
+
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	SGI_MAP_FLASH0_RO,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+	ARM_V2M_MAP_MEM_PROTECT,
+#endif
+	CSS_SGI_MAP_DEVICE,
+	SOC_MEMCNTRL_MAP_DEVICE,
+	SOC_PLATFORM_PERIPH_MAP_DEVICE,
+	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+	ARM_MAP_NS_DRAM1,
+#if ARM_BL31_IN_DRAM
+	ARM_MAP_BL31_SEC_DRAM,
+#endif
+#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+	ARM_MAP_BL1_RW,
+#endif
+	{0}
+};
+#endif
+
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+	ARM_V2M_MAP_MEM_PROTECT,
+#endif
+	CSS_SGI_MAP_DEVICE,
+	SOC_PLATFORM_PERIPH_MAP_DEVICE,
+	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+	{0}
+};
+
+#endif
+
+ARM_CASSERT_MMAP
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	assert(heap_addr != NULL);
+	assert(heap_size != NULL);
+
+	return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
+
+void plat_arm_secure_wdt_start(void)
+{
+	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index df6c9af..eae881e 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -732,7 +732,7 @@
 			 arg2, arg3);
 
 	ret = pm_feature_check(PM_QUERY_DATA, &version);
-	if (PM_RET_SUCCESS == ret){
+	if (PM_RET_SUCCESS == ret) {
 		fw_api_version = version & 0xFFFF ;
 		if ((2U == fw_api_version) &&
 		    ((XPM_QID_CLOCK_GET_NAME == qid) ||