feat(tc): introduce an FPGA subvariant and TC3 CPUs

TC is getting an FPGA port alongside the FVP. It is meant to be
identical, but the core configurations on TC2 differ (there are 14 in an
odd arrangement).

Introduce these differences and gate them behind a new TARGET_FLAVOUR
flag which defaults to FVP for compatibility.

While updating CPUs, it's a good time to do TC3 too. It has different
cores in a different configuration again, so it needs different capacity
values. Those have been derived using GeekBench 6.0 ST on the FPGA.

Finally GPU and DPU power domains are 1 above the CPUs so make that
relative.

In the end, the big/mid/little configurations are:
 * TC2 FVP:  1/3/4
 * TC2 FPGA: 2/3/5/4 (the 3 is a big "min" core)
 * TC3 both: 2/4/2 (with new capacities)

Co-developed-by: Tintu Thomas <tintu.thomas@arm.com>
Co-developed-by: Kshitij Sisodia <kshitij.sisodia@arm.com>
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
Change-Id: I3c3a10d6727f5010fd9026a404df27e9262dff6b
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 53bb267..fc953a3 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -8,6 +8,7 @@
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include "platform_def.h"
 #include "tc_vers.dtsi"
 
 / {
@@ -54,6 +55,26 @@
 				core7 {
 					cpu = <&CPU7>;
 				};
+#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
+				core8 {
+					cpu = <&CPU8>;
+				};
+				core9 {
+					cpu = <&CPU9>;
+				};
+				core10 {
+					cpu = <&CPU10>;
+				};
+				core11 {
+					cpu = <&CPU11>;
+				};
+				core12 {
+					cpu = <&CPU12>;
+				};
+				core13 {
+					cpu = <&CPU13>;
+				};
+#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
 			};
 		};
 
@@ -89,19 +110,16 @@
 
 				mpmm_gear0: counter@0 {
 					reg = <0>;
-
 					enable-at-el3;
 				};
 
 				mpmm_gear1: counter@1 {
 					reg = <1>;
-
 					enable-at-el3;
 				};
 
 				mpmm_gear2: counter@2 {
 					reg = <2>;
-
 					enable-at-el3;
 				};
 			};
@@ -114,7 +132,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <406>;
+			capacity-dmips-mhz = <LIT_CAPACITY>;
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -126,7 +144,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <406>;
+			capacity-dmips-mhz = <LIT_CAPACITY>;
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -136,9 +154,14 @@
 			compatible = "arm,armv8";
 			reg = <0x200>;
 			enable-method = "psci";
-			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <406>;
+#if TARGET_PLATFORM <= 2
+			clocks = <&scmi_dvfs 0>;
+			capacity-dmips-mhz = <LIT_CAPACITY>;
+#elif TARGET_PLATFORM == 3
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+#endif /* TARGET_PLATFORM == 3 */
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -148,9 +171,14 @@
 			compatible = "arm,armv8";
 			reg = <0x300>;
 			enable-method = "psci";
-			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <406>;
+#if TARGET_PLATFORM <= 2
+			clocks = <&scmi_dvfs 0>;
+			capacity-dmips-mhz = <LIT_CAPACITY>;
+#elif TARGET_PLATFORM == 3
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+#endif /* TARGET_PLATFORM == 3 */
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -162,7 +190,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <912>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -174,7 +202,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <912>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -184,9 +212,14 @@
 			compatible = "arm,armv8";
 			reg = <0x600>;
 			enable-method = "psci";
-			clocks = <&scmi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <912>;
+#if TARGET_PLATFORM <= 2
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+#elif TARGET_PLATFORM == 3
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+#endif /* TARGET_PLATFORM == 3 */
 			amu = <&amu>;
 			supports-mpmm;
 		};
@@ -196,13 +229,85 @@
 			compatible = "arm,armv8";
 			reg = <0x700>;
 			enable-method = "psci";
-			clocks = <&scmi_dvfs 2>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <1024>;
+#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+#else
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
+		CPU8:cpu@800 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x800>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU9:cpu@900 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x900>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG2_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU10:cpu@A00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xA00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG2_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU11:cpu@B00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xB00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG2_CAPACITY>;
 			amu = <&amu>;
 			supports-mpmm;
 		};
 
+		CPU12:cpu@C00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xC00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 3>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU13:cpu@D00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xD00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 3>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
 	};
 
 	reserved-memory {
@@ -238,6 +343,10 @@
 		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-affinity = <&CPU0>,  <&CPU1>,  <&CPU2>,  <&CPU3>,
 				     <&CPU4>,  <&CPU5>,  <&CPU6>,  <&CPU7>
+#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
+				    ,<&CPU8>,  <&CPU9>,  <&CPU10>, <&CPU11>,
+				     <&CPU12>, <&CPU13>
+#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
 		;
 	};
 
@@ -470,7 +579,7 @@
 		interrupt-names = "JOB", "MMU", "GPU";
 		clocks = <&gpu_core_clk>;
 		clock-names = "shadercores";
-		power-domains = <&scmi_devpd 9>;
+		power-domains = <&scmi_devpd GPU_SCMI_PD_IDX>;
 		scmi-perf-domain = <3>;
 		iommus = <&smmu_700 0x200>;
 	};
@@ -508,7 +617,7 @@
 		clocks = <&scmi_clk 0>;
 		clock-names = "aclk";
 		iommus = <&smmu_700 0x100>;
-		power-domains = <&scmi_devpd 10>;
+		power-domains = <&scmi_devpd DPU_SCMI_PD_IDX>;
 		pl0: pipeline@0 {
 			reg = <0>;
 			clocks = <&scmi_clk 1>;
@@ -589,6 +698,38 @@
 		compatible = "arm,embedded-trace-extension";
 		cpu = <&CPU7>;
 	};
+
+#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2
+	ete8 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU8>;
+	};
+
+	ete9 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU9>;
+	};
+
+	ete10 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU10>;
+	};
+
+	ete11 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU11>;
+	};
+
+	ete12 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU12>;
+	};
+
+	ete13 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU13>;
+	};
+#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM <= 2 */
 
 	trbe {
 		compatible = "arm,trace-buffer-extension";
diff --git a/fdts/tc_vers.dtsi b/fdts/tc_vers.dtsi
index 14e6c12..18f4e84 100644
--- a/fdts/tc_vers.dtsi
+++ b/fdts/tc_vers.dtsi
@@ -7,13 +7,33 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
+#define GPU_SCMI_PD_IDX		(PLAT_MAX_CPUS_PER_CLUSTER + 1)
+#define DPU_SCMI_PD_IDX		(PLAT_MAX_CPUS_PER_CLUSTER + 2)
+
+/* All perf is normalized against the big core */
+#define BIG_CAPACITY		1024
+
 #if TARGET_PLATFORM <= 2
+#if TARGET_FLAVOUR_FVP
+#define LIT_CAPACITY		406
+#define MID_CAPACITY		912
+#else /* TARGET_FLAVOUR_FPGA */
+#define LIT_CAPACITY		280
+#define MID_CAPACITY		775
+/* this is an area optimized configuration of the big core */
+#define BIG2_CAPACITY		930
+#endif /* TARGET_FLAVOUR_FPGA */
+
 #define INT_MBOX_RX		317
 #define MHU_TX_ADDR(pref)	pref##45000000 /* hex */
 #define MHU_RX_ADDR(pref)	pref##45010000 /* hex */
 #define MPAM_ADDR		0x1 0x00010000 /* 0x1_0001_0000 */
 #define UARTCLK_FREQ		5000000
 #elif TARGET_PLATFORM == 3
+
+#define LIT_CAPACITY		239
+#define MID_CAPACITY		686
+
 #define INT_MBOX_RX		300
 #define MHU_TX_ADDR(pref)	pref##46040000 /* hex */
 #define MHU_RX_ADDR(pref)	pref##46140000 /* hex */
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 6a0d6ab..00d2cb6 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -17,8 +17,6 @@
 #include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#define PLATFORM_CORE_COUNT		8
-
 #define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00080000	/* 512 KB */
 
 /*
@@ -258,9 +256,15 @@
 					 CSS_SCMI_PAYLOAD_SIZE_MAX)
 
 #define PLAT_ARM_CLUSTER_COUNT		U(1)
+#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM == 2
+#define PLAT_MAX_CPUS_PER_CLUSTER	U(14)
+#else /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM == 2 */
 #define PLAT_MAX_CPUS_PER_CLUSTER	U(8)
+#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM == 2 */
 #define PLAT_MAX_PE_PER_CPU		U(1)
 
+#define PLATFORM_CORE_COUNT		(PLAT_MAX_CPUS_PER_CLUSTER * PLAT_ARM_CLUSTER_COUNT)
+
 /* Message Handling Unit (MHU) base addresses */
 #if TARGET_PLATFORM <= 2
 	#define PLAT_CSS_MHU_BASE		UL(0x45400000)
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index a2368b7..74098bc 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -5,6 +5,8 @@
 
 include common/fdt_wrappers.mk
 
+TARGET_FLAVOUR			:=	fvp
+
 ifneq ($(shell expr $(TARGET_PLATFORM) \<= 1), 0)
         $(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
           Some of the features might not work as expected)
@@ -14,7 +16,14 @@
         $(error TARGET_PLATFORM must be less than or equal to 3)
 endif
 
+ifeq ($(filter ${TARGET_FLAVOUR}, fvp fpga),)
+        $(error TARGET_FLAVOUR must be fvp or fpga)
+endif
+
-$(eval $(call add_define,TARGET_PLATFORM))
+$(eval $(call add_defines, \
+	TARGET_PLATFORM \
+	TARGET_FLAVOUR_$(call uppercase,${TARGET_FLAVOUR}) \
+))
 
 CSS_LOAD_SCP_IMAGES	:=	1
 
diff --git a/plat/arm/board/tc/tc_topology.c b/plat/arm/board/tc/tc_topology.c
index 9e18da6..cc0dcc2 100644
--- a/plat/arm/board/tc/tc_topology.c
+++ b/plat/arm/board/tc/tc_topology.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <plat/arm/common/plat_arm.h>
 #include <plat/arm/css/common/css_pm.h>
+#include <platform_def.h>
 
 /******************************************************************************
  * The power domain tree descriptor.
@@ -36,6 +37,14 @@
 	(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 PLATFORM_CORE_COUNT == 14
+	(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)),
+#endif /* PLATFORM_CORE_COUNT == 14 */
 };
 
 /*******************************************************************************