n1sdp: setup multichip gic routing table

N1SDP supports multichip configuration wherein n1sdp boards are
connected over high speed coherent CCIX link, for now only dual-chip
is supported.

Whether or not multiple chips are present is dynamically probed by
SCP firmware and passed on to TF-A, routing table will be set up
only if multiple chips are present.

Initialize GIC-600 multichip operation by overriding the default GICR
frames with array of GICR frames and setting the chip 0 as routing
table owner.

Change-Id: Ida35672be4bbf4c517469a5b330548d75e593ff2
Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index 79a0a79..4f158ee 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -9,6 +9,7 @@
 #include <drivers/arm/css/css_mhu_doorbell.h>
 #include <drivers/arm/css/scmi.h>
 #include <drivers/arm/css/sds.h>
+#include <drivers/arm/gic600_multichip.h>
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
@@ -53,6 +54,26 @@
 	.ring_doorbell = &mhu_ring_doorbell
 };
 
+static struct gic600_multichip_data n1sdp_multichip_data __init = {
+	.rt_owner_base = PLAT_ARM_GICD_BASE,
+	.rt_owner = 0,
+	.chip_count = 1,
+	.chip_addrs = {
+		PLAT_ARM_GICD_BASE >> 16,
+		PLAT_ARM_GICD_BASE >> 16
+	},
+	.spi_ids = {
+		{32, 255},
+		{0, 0}
+	}
+};
+
+static uintptr_t n1sdp_multichip_gicr_frames[3] = {
+	PLAT_ARM_GICR_BASE,
+	PLAT_ARM_GICR_BASE + PLAT_ARM_REMOTE_CHIP_OFFSET,
+	0
+};
+
 scmi_channel_plat_info_t *plat_css_get_scmi_info()
 {
 	return &n1sdp_scmi_plat_info;
@@ -149,14 +170,18 @@
 	}
 }
 
+void n1sdp_bl31_multichip_setup(void)
+{
+	plat_arm_override_gicr_frames(n1sdp_multichip_gicr_frames);
+	gic600_multichip_init(&n1sdp_multichip_data);
+}
+
 void bl31_platform_setup(void)
 {
 	int ret;
 	struct n1sdp_plat_info plat_info;
 	struct n1sdp_bl33_info bl33_info;
 
-	arm_bl31_platform_setup();
-
 	ret = sds_init();
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed\n");
@@ -181,6 +206,12 @@
 		panic();
 	}
 
+	if (plat_info.multichip_mode) {
+		n1sdp_multichip_data.chip_count = plat_info.slave_count + 1;
+		n1sdp_bl31_multichip_setup();
+	}
+	arm_bl31_platform_setup();
+
 	dmc_ecc_setup(plat_info.local_ddr_size);
 
 	/* Check if remote memory is present */
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 986bd70..8816670 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -18,6 +18,7 @@
 N1SDP_GIC_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gic600_multichip.c	\
 				plat/common/plat_gicv3.c		\
 				plat/arm/common/arm_gicv3.c		\
 				drivers/arm/gic/v3/gic600.c