feat(arm_fpga): add ITS autodetection

Some FPGAs come with a GIC that has an ITS block configured. Since the
ITS sits between the distributor and redistributors, we can autodetect
that, and already adjust the GICR base address.

To also make this ITS usable, add an ITS node to our base DTB, and
remove that should we not find an ITS during the scan for the
redistributor. This allows to use the same TF-A binary for FPGA images
with or without an ITS.

Change-Id: I4c0417dec7bccdbad8cbca26fa2634950fc50a66
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
diff --git a/fdts/arm_fpga.dts b/fdts/arm_fpga.dts
index b7b4f0e..aad0a04 100644
--- a/fdts/arm_fpga.dts
+++ b/fdts/arm_fpga.dts
@@ -98,5 +98,12 @@
 	/* The GICR size will be adjusted at runtime to match the cores. */
 		      <0x0 0x30040000 0x0 0x00020000>;	/* GICR for one core */
 		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+		its: msi-controller@30040000 {
+			compatible = "arm,gic-v3-its";
+			reg = <0x0 0x30040000 0x0 0x40000>;
+			#msi-cells = <1>;
+			msi-controller;
+		};
 	};
 };
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index abe68ad..31c3615 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -242,6 +242,16 @@
 		}
 	}
 
+	/* Check whether we have an ITS. Remove the DT node if not. */
+	if (!fpga_has_its()) {
+		int node = fdt_node_offset_by_compatible(fdt, 0,
+							 "arm,gic-v3-its");
+
+		if (node >= 0) {
+			fdt_del_node(fdt, node);
+		}
+	}
+
 	err = fdt_pack(fdt);
 	if (err < 0) {
 		ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err);
diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c
index c379e7d..e06a9da 100644
--- a/plat/arm/board/arm_fpga/fpga_gicv3.c
+++ b/plat/arm/board/arm_fpga/fpga_gicv3.c
@@ -155,3 +155,8 @@
 {
 	return fpga_gicv3_driver_data.gicr_base;
 }
+
+bool fpga_has_its(void)
+{
+	return nr_itses > 0;
+}
diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h
index 61c8992..84d651c 100644
--- a/plat/arm/board/arm_fpga/fpga_private.h
+++ b/plat/arm/board/arm_fpga/fpga_private.h
@@ -27,6 +27,7 @@
 unsigned int fpga_get_nr_gic_cores(void);
 uintptr_t fpga_get_redist_size(void);
 uintptr_t fpga_get_redist_base(void);
+bool fpga_has_its(void);
 
 #endif /* __ASSEMBLER__ */