Merge "feat(fvp): introduce PLATFORM_TEST_RAS_FFH config" into integration
diff --git a/changelog.yaml b/changelog.yaml
index 6dbb9b2..c969b2c 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -877,6 +877,9 @@
                 deprecated:
                   - drivers/tzc380
 
+          - title: SBSA
+            scope: sbsa
+
       - title: Marvell
         scope: marvell-drivers
 
diff --git a/docs/plat/allwinner.rst b/docs/plat/allwinner.rst
index 3e9ce51..8e967dc 100644
--- a/docs/plat/allwinner.rst
+++ b/docs/plat/allwinner.rst
@@ -23,6 +23,8 @@
 +------+-------------------+
 | H313 | sun50i_h616       |
 +------+-------------------+
+| T507 | sun50i_h616       |
++------+-------------------+
 | R329 | sun50i_r329       |
 +------+-------------------+
 
diff --git a/drivers/arm/sbsa/sbsa.c b/drivers/arm/sbsa/sbsa.c
index 79c6f26..a88e20c 100644
--- a/drivers/arm/sbsa/sbsa.c
+++ b/drivers/arm/sbsa/sbsa.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,3 +40,9 @@
 {
 	mmio_write_32(base + SBSA_WDOG_WCS_OFFSET, (0x0));
 }
+
+/* Refresh the secure watchdog timer explicitly */
+void sbsa_wdog_refresh(uintptr_t refresh_base)
+{
+	mmio_write_32(refresh_base + SBSA_WDOG_WRR_OFFSET, SBSA_WDOG_WRR_REFRESH);
+}
diff --git a/include/drivers/arm/sbsa.h b/include/drivers/arm/sbsa.h
index 9403634..4ca7194 100644
--- a/include/drivers/arm/sbsa.h
+++ b/include/drivers/arm/sbsa.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,12 @@
 
 #include <stdint.h>
 
-/* Register Offsets */
+/* SBSA Secure Watchdog Register Offsets */
+/* Refresh frame */
+#define SBSA_WDOG_WRR_OFFSET		UL(0x000)
+#define SBSA_WDOG_WRR_REFRESH		UL(0x1)
+
+/* Control and status frame */
 #define SBSA_WDOG_WCS_OFFSET		UL(0x000)
 #define SBSA_WDOG_WOR_LOW_OFFSET	UL(0x008)
 #define SBSA_WDOG_WOR_HIGH_OFFSET	UL(0x00C)
@@ -20,5 +25,6 @@
 
 void sbsa_wdog_start(uintptr_t base, uint64_t ms);
 void sbsa_wdog_stop(uintptr_t base);
+void sbsa_wdog_refresh(uintptr_t refresh_base);
 
 #endif /* SBSA_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index ffbd4ca..e8461f5 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -364,6 +364,7 @@
 /* secure watchdog */
 void plat_arm_secure_wdt_start(void);
 void plat_arm_secure_wdt_stop(void);
+void plat_arm_secure_wdt_refresh(void);
 
 /* Get SOC-ID of ARM platform */
 uint32_t plat_arm_get_soc_id(void);
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index dde174c..f87f857 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -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
  */
@@ -52,18 +52,21 @@
  * terminology. On a GICv2 system or mode, the interrupts will be treated as
  * Group 0 interrupts.
  */
-#define CSS_G1S_IRQ_PROPS(grp) \
+#define CSS_G1S_INT_PROPS(grp) \
 	INTR_PROP_DESC(CSS_IRQ_MHU, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_GPU_SMMU_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_TZC, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
-	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL)
 
+#define CSS_G1S_IRQ_PROPS(grp) \
+	CSS_G1S_INT_PROPS(grp), \
+	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
 #if CSS_USE_SCMI_SDS_DRIVER
 /* Memory region for shared data storage */
 #define PLAT_ARM_SDS_MEM_BASE		ARM_SHARED_RAM_BASE
diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h
new file mode 100644
index 0000000..22828c2
--- /dev/null
+++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CPUCFG_H
+#define SUNXI_CPUCFG_H
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
+#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
+/* The T507 datasheet does not mention this register. */
+#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
+
+#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
+
+#define SUNXI_C0_CPU_CTRL_REG(n)	(SUNXI_CPUCFG_BASE + 0x0060 + (n) * 4)
+
+#define SUNXI_CPU_CTRL_REG(n)		(SUNXI_CPUSUBSYS_BASE + 0x20 + (n) * 4)
+#define SUNXI_ALT_RVBAR_LO_REG(n)	(SUNXI_CPUSUBSYS_BASE + 0x40 + (n) * 8)
+#define SUNXI_ALT_RVBAR_HI_REG(n)	(SUNXI_CPUSUBSYS_BASE + 0x44 + (n) * 8)
+
+#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
+					(c) * 0x10 + (n) * 4)
+#define SUNXI_CPU_UNK_REG(n)		(SUNXI_R_CPUCFG_BASE + 0x0070 + (n) * 4)
+
+#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
+#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
+#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
+#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
+
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		24
+
+#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h
new file mode 100644
index 0000000..d4aec19
--- /dev/null
+++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CPUCFG_H
+#define SUNXI_CPUCFG_H
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0010)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0014)
+#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_C0_CPUXCFG_BASE + 0x0024)
+#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_C0_CPUXCFG_BASE + 0x00c0)
+
+#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_GEN_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
+
+#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
+					(c) * 0x10 + (n) * 4)
+
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_GEN_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		4
+
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return true;
+}
+
+#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index c17ef95..20f6c49 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -20,6 +20,7 @@
 #define SUNXI_SOC_H616			0x1823
 #define SUNXI_SOC_R329			0x1851
 
+#define SUNXI_VER_BITS_MASK		0xffU
 #define JEDEC_ALLWINNER_BKID		9U
 #define JEDEC_ALLWINNER_MFID		0x9eU
 
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 092659c..62f4fcb 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -183,5 +183,5 @@
 {
 	uint32_t reg = mmio_read_32(SRAM_VER_REG);
 
-	return reg & GENMASK_32(7, 0);
+	return reg & SUNXI_VER_BITS_MASK;
 }
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index 46e7090..30841e2 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -19,6 +19,12 @@
 #include <sunxi_mmap.h>
 #include <sunxi_private.h>
 
+#ifndef SUNXI_C0_CPU_CTRL_REG
+#define SUNXI_C0_CPU_CTRL_REG(n)	0
+#define SUNXI_CPU_UNK_REG(n)		0
+#define SUNXI_CPU_CTRL_REG(n)		0
+#endif
+
 static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core)
 {
 	if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff)
@@ -53,15 +59,30 @@
 
 	VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core);
 
-	/* Deassert DBGPWRDUP */
-	mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
-	/* Activate the core output clamps, but not for core 0. */
-	if (core != 0)
-		mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
-	/* Assert CPU power-on reset */
-	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
-	/* Remove power from the CPU */
-	sunxi_cpu_disable_power(cluster, core);
+	if (sunxi_cpucfg_has_per_cluster_regs()) {
+		/* Deassert DBGPWRDUP */
+		mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+		/* Activate the core output clamps, but not for core 0. */
+		if (core != 0) {
+			mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster),
+					BIT(core));
+		}
+		/* Assert CPU power-on reset */
+		mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+		/* Remove power from the CPU */
+		sunxi_cpu_disable_power(cluster, core);
+	} else {
+		/* power down(?) debug core */
+		mmio_clrbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(8));
+		/* ??? Activate the core output clamps, but not for core 0 */
+		if (core != 0) {
+			mmio_setbits_32(SUNXI_CPU_UNK_REG(core), BIT(1));
+		}
+		/* ??? Assert CPU power-on reset ??? */
+		mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(0));
+		/* Remove power from the CPU */
+		sunxi_cpu_disable_power(cluster, core);
+	}
 }
 
 void sunxi_cpu_on(u_register_t mpidr)
@@ -71,23 +92,45 @@
 
 	VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core);
 
+	if (sunxi_cpucfg_has_per_cluster_regs()) {
+		/* Assert CPU core reset */
+		mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
+		/* Assert CPU power-on reset */
+		mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+		/* Set CPU to start in AArch64 mode */
+		mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster),
+				BIT(SUNXI_AA64nAA32_OFFSET + core));
+		/* Apply power to the CPU */
+		sunxi_cpu_enable_power(cluster, core);
+		/* Release the core output clamps */
+		mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
+		/* Deassert CPU power-on reset */
+		mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+		/* Deassert CPU core reset */
+		mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
+		/* Assert DBGPWRDUP */
+		mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+	} else {
+		/* Assert CPU core reset */
+		mmio_clrbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(0));
+		/* ??? Assert CPU power-on reset ??? */
+		mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(0));
+
+		/* Set CPU to start in AArch64 mode */
+		mmio_setbits_32(SUNXI_CPU_CTRL_REG(core), BIT(0));
+
+		/* Apply power to the CPU */
+		sunxi_cpu_enable_power(cluster, core);
+
-	/* Assert CPU core reset */
-	mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
-	/* Assert CPU power-on reset */
-	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
-	/* Set CPU to start in AArch64 mode */
-	mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster),
-			BIT(SUNXI_AA64nAA32_OFFSET + core));
-	/* Apply power to the CPU */
-	sunxi_cpu_enable_power(cluster, core);
-	/* Release the core output clamps */
-	mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
-	/* Deassert CPU power-on reset */
-	mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
-	/* Deassert CPU core reset */
-	mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
-	/* Assert DBGPWRDUP */
-	mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+		/* ??? Release the core output clamps ??? */
+		mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(1));
+		/* ??? Deassert CPU power-on reset ??? */
+		mmio_setbits_32(SUNXI_CPU_UNK_REG(core), BIT(0));
+		/* Deassert CPU core reset */
+		mmio_setbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(0));
+		/* power up(?) debug core */
+		mmio_setbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(8));
+	}
 }
 
 void sunxi_cpu_power_off_others(void)
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 3772b4a..ebc406b 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -25,6 +25,11 @@
 }
 #endif
 
+#ifndef SUNXI_ALT_RVBAR_LO_REG
+#define SUNXI_ALT_RVBAR_LO_REG(n)	0
+#define SUNXI_ALT_RVBAR_HI_REG(n)	0
+#endif
+
 int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
 {
 	/* The non-secure entry point must be in DRAM */
@@ -42,10 +47,17 @@
 
 	/* Program all CPU entry points. */
 	for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; ++cpu) {
-		mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
-			      sec_entrypoint & 0xffffffff);
-		mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
-			      sec_entrypoint >> 32);
+		if (sunxi_cpucfg_has_per_cluster_regs()) {
+			mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
+				      sec_entrypoint & 0xffffffff);
+			mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
+				      sec_entrypoint >> 32);
+		} else {
+			mmio_write_32(SUNXI_ALT_RVBAR_LO_REG(cpu),
+				      sec_entrypoint & 0xffffffff);
+			mmio_write_32(SUNXI_ALT_RVBAR_HI_REG(cpu),
+				      sec_entrypoint >> 32);
+		}
 	}
 
 	if (sunxi_set_scpi_psci_ops(psci_ops) == 0) {
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
index aed3585..ddd53ba 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
@@ -36,4 +36,9 @@
 #define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
 #define SUNXI_AA64nAA32_OFFSET		24
 
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return true;
+}
+
 #endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
index 5bfda5d..585c51b 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
@@ -1,35 +1,6 @@
-/*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SUNXI_CPUCFG_H
-#define SUNXI_CPUCFG_H
-
-#include <sunxi_mmap.h>
-
-/* c = cluster, n = core */
-#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
-#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
-#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
-#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
-
-#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
-#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
-#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
-
-#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
-#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
-#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
-					(c) * 0x10 + (n) * 4)
-
-#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
-#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
-#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
-#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
-
-#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
-#define SUNXI_AA64nAA32_OFFSET		24
+#include <sunxi_cpucfg_ncat.h>
 
-#endif /* SUNXI_CPUCFG_H */
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return true;
+}
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index 58216d8..43133be 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -59,5 +59,6 @@
 #define SUNXI_R_RSB_BASE		0x07083000
 #define SUNXI_R_UART_BASE		0x07080000
 #define SUNXI_R_PIO_BASE		0x07022000
+#define SUNXI_CPUSUBSYS_BASE		0x08100000
 
 #endif /* SUNXI_MMAP_H */
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
index dab663b..5c590e4 100644
--- a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
@@ -1,35 +1,8 @@
-/*
- * Copyright (c) 2017-2020, ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
+#include <plat/common/platform.h>
 
-#ifndef SUNXI_CPUCFG_H
-#define SUNXI_CPUCFG_H
-
-#include <sunxi_mmap.h>
-
-/* c = cluster, n = core */
-#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
-#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
-#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
-#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
-
-#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
-#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
-#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
-
-#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
-#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
-#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
-					(c) * 0x10 + (n) * 4)
-
-#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
-#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
-#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
-#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
-
-#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
-#define SUNXI_AA64nAA32_OFFSET		24
+#include <sunxi_cpucfg_ncat.h>
 
-#endif /* SUNXI_CPUCFG_H */
+static inline bool sunxi_cpucfg_has_per_cluster_regs(void)
+{
+	return (plat_get_soc_revision() != 2);
+}
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_mmap.h b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
index 3b4f4a0..24a4ba8 100644
--- a/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
@@ -41,6 +41,7 @@
 #define SUNXI_R_UART_BASE		0x07080000
 #define SUNXI_R_I2C_BASE		0x07081400
 #define SUNXI_R_RSB_BASE		0x07083000
+#define SUNXI_CPUSUBSYS_BASE		0x08100000
 #define SUNXI_CPUCFG_BASE		0x09010000
 
 #endif /* SUNXI_MMAP_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
index 9478f32..3c3530f 100644
--- a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
@@ -1,31 +1 @@
-/*
- * Copyright (c) 2021 Sipeed
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SUNXI_CPUCFG_H
-#define SUNXI_CPUCFG_H
-
-#include <sunxi_mmap.h>
-
-/* c = cluster, n = core */
-#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0010)
-#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0014)
-#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_C0_CPUXCFG_BASE + 0x0024)
-#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_C0_CPUXCFG_BASE + 0x00c0)
-
-#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0000)
-#define SUNXI_CPUCFG_GEN_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0000)
-#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
-#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
-
-#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
-#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
-#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
-					(c) * 0x10 + (n) * 4)
-
-#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_GEN_CTRL_REG0
-#define SUNXI_AA64nAA32_OFFSET		4
-
-#endif /* SUNXI_CPUCFG_H */
+#include <sunxi_cpucfg_ncat2.h>
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index 4543671..4f97339 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.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
  */
@@ -15,7 +15,7 @@
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 
 	attribute {
 		spmc_id = <0x8000>;
@@ -78,9 +78,17 @@
 		CPU_1
 	};
 
-	memory@6000000 {
+	memory@0 {
 		device_type = "memory";
-		reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
+		reg = <0x0 0xfd000000 0x0 0x2000000>,
+		      <0x0 0x7000000 0x0 0x1000000>,
+		      <0x0 0xff000000 0x0 0x1000000>;
+	};
+
+	memory@1 {
+		device_type = "ns-memory";
+		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
+		      <0x0 0x88000000 0x0 0x10000000>;
 	};
 
 #if MEASURED_BOOT
diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
index d3a5e1a..b64e076 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,7 @@
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 
 	attribute {
 		spmc_id = <0x8000>;
@@ -117,9 +117,16 @@
 		};
 	};
 
-	/* 32MB of TC_TZC_DRAM1_BASE */
-	memory@fd000000 {
+	memory@0 {
 		device_type = "memory";
-		reg = <0x0 0xfd000000 0x2000000>;
+		reg = <0x0 0xfd000000 0x0 0x2000000>,
+		      <0x0 0x7000000 0x0 0x1000000>,
+		      <0x0 0xff000000 0x0 0x1000000>;
+	};
+
+	memory@1 {
+		device_type = "ns-memory";
+		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
+		      <0x0 0x88000000 0x1 0x00000000>;
 	};
 };
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index eea1be6..59fff6e 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -212,8 +212,11 @@
 #define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
 #define PLAT_ARM_DRAM2_END		(PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL)
 
-#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
-#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_INT_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp),	\
+					INTR_PROP_DESC(SBSA_SECURE_WDOG_INTID,	\
+						GIC_HIGHEST_SEC_PRIORITY, grp, \
+						GIC_INTR_CFG_LEVEL)
 
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
@@ -229,9 +232,11 @@
 #define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
 					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
 
-/*Secure Watchdog Constants */
-#define SBSA_SECURE_WDOG_BASE		UL(0x2A480000)
+/* Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_CONTROL_BASE	UL(0x2A480000)
+#define SBSA_SECURE_WDOG_REFRESH_BASE	UL(0x2A490000)
 #define SBSA_SECURE_WDOG_TIMEOUT	UL(100)
+#define SBSA_SECURE_WDOG_INTID		86
 
 #define PLAT_ARM_SCMI_CHANNEL_COUNT	1
 
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 63a9237..c75507a 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -118,7 +118,8 @@
 				lib/fconf/fconf_dyn_cfg_getter.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
 				lib/utils/mem_region.c			\
-				plat/arm/common/arm_nor_psci_mem_protect.c
+				plat/arm/common/arm_nor_psci_mem_protect.c	\
+				drivers/arm/sbsa/sbsa.c
 
 BL31_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 8ad1d30..630324f 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -13,6 +13,7 @@
 #include <common/debug.h>
 #include <drivers/arm/css/css_mhu_doorbell.h>
 #include <drivers/arm/css/scmi.h>
+#include <drivers/arm/sbsa.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <plat/arm/common/plat_arm.h>
@@ -81,3 +82,37 @@
 
 	fconf_populate("HW_CONFIG", hw_config_info->config_addr);
 }
+
+#if defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)
+void tc_bl31_plat_runtime_setup(void)
+{
+	arm_bl31_plat_runtime_setup();
+
+	/* Start secure watchdog timer. */
+	plat_arm_secure_wdt_start();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	tc_bl31_plat_runtime_setup();
+}
+
+/*
+ * Platform handler for Group0 secure interrupt.
+ */
+int plat_spmd_handle_group0_interrupt(uint32_t intid)
+{
+	/* Trusted Watchdog timer is the only source of Group0 interrupt now. */
+	if (intid == SBSA_SECURE_WDOG_INTID) {
+		INFO("Watchdog restarted\n");
+		/* Refresh the timer. */
+		plat_arm_secure_wdt_refresh();
+
+		/* Deactivate the corresponding interrupt. */
+		plat_ic_end_of_interrupt(intid);
+		return 0;
+	}
+
+	return -1;
+}
+#endif /*defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)*/
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index 228f2fa..766bfb5 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -147,10 +147,15 @@
 
 void plat_arm_secure_wdt_start(void)
 {
-	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+	sbsa_wdog_start(SBSA_SECURE_WDOG_CONTROL_BASE, SBSA_SECURE_WDOG_TIMEOUT);
 }
 
 void plat_arm_secure_wdt_stop(void)
 {
-	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+	sbsa_wdog_stop(SBSA_SECURE_WDOG_CONTROL_BASE);
+}
+
+void plat_arm_secure_wdt_refresh(void)
+{
+	sbsa_wdog_refresh(SBSA_SECURE_WDOG_REFRESH_BASE);
 }
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 19efdd3..8c62a9b 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_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
  */
@@ -43,6 +43,7 @@
 #pragma weak bl31_platform_setup
 #pragma weak bl31_plat_arch_setup
 #pragma weak bl31_plat_get_next_image_ep_info
+#pragma weak bl31_plat_runtime_setup
 
 #define MAP_BL31_TOTAL		MAP_REGION_FLAT(			\
 					BL31_START,			\