Introduce ARM GIC-600 driver

ARM GIC-600 IP complies with ARM GICv3 architecture, but among others,
implements a power control register in the Redistributor frame. This
register must be programmed to mark the frame as powered on, before
accessing other registers in the frame. Rest of initialization sequence
remains the same.

The driver provides APIs for Redistributor power management, and
overrides those in the generic GICv3 driver. The driver data is shared
between generic GICv3 driver and that of GIC-600.

For FVP platform, the GIC-600 driver is chosen when FVP_USE_GIC_DRIVER
is set to FVP_GIC600. Also update user guide.

Change-Id: I321b2360728d69f6d4b0a747b2cfcc3fe5a20d67
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 566c446..b68d998 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -8,12 +8,10 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <debug.h>
-#include <gic_common.h>
 #include <gicv3.h>
-#include "../common/gic_common_private.h"
 #include "gicv3_private.h"
 
-static const gicv3_driver_data_t *driver_data;
+const gicv3_driver_data_t *gicv3_driver_data;
 static unsigned int gicv2_compat;
 
 /*
@@ -90,18 +88,20 @@
 					   plat_driver_data->gicr_base,
 					   plat_driver_data->mpidr_to_core_pos);
 
-	driver_data = plat_driver_data;
+	gicv3_driver_data = plat_driver_data;
 
 	/*
 	 * The GIC driver data is initialized by the primary CPU with caches
 	 * enabled. When the secondary CPU boots up, it initializes the
 	 * GICC/GICR interface with the caches disabled. Hence flush the
-	 * driver_data to ensure coherency. This is not required if the
+	 * driver data to ensure coherency. This is not required if the
 	 * platform has HW_ASSISTED_COHERENCY enabled.
 	 */
 #if !HW_ASSISTED_COHERENCY
-	flush_dcache_range((uintptr_t) &driver_data, sizeof(driver_data));
-	flush_dcache_range((uintptr_t) driver_data, sizeof(*driver_data));
+	flush_dcache_range((uintptr_t) &gicv3_driver_data,
+			sizeof(gicv3_driver_data));
+	flush_dcache_range((uintptr_t) gicv3_driver_data,
+			sizeof(*gicv3_driver_data));
 #endif
 
 	INFO("GICv3 %s legacy support detected."
@@ -117,10 +117,10 @@
 {
 	unsigned int bitmap = 0;
 
-	assert(driver_data);
-	assert(driver_data->gicd_base);
-	assert(driver_data->g1s_interrupt_array ||
-	       driver_data->g0_interrupt_array);
+	assert(gicv3_driver_data);
+	assert(gicv3_driver_data->gicd_base);
+	assert(gicv3_driver_data->g1s_interrupt_array ||
+	       gicv3_driver_data->g0_interrupt_array);
 
 	assert(IS_IN_EL3());
 
@@ -129,39 +129,39 @@
 	 * the ARE_S bit. The Distributor might generate a system error
 	 * otherwise.
 	 */
-	gicd_clr_ctlr(driver_data->gicd_base,
+	gicd_clr_ctlr(gicv3_driver_data->gicd_base,
 		      CTLR_ENABLE_G0_BIT |
 		      CTLR_ENABLE_G1S_BIT |
 		      CTLR_ENABLE_G1NS_BIT,
 		      RWP_TRUE);
 
 	/* Set the ARE_S and ARE_NS bit now that interrupts have been disabled */
-	gicd_set_ctlr(driver_data->gicd_base,
+	gicd_set_ctlr(gicv3_driver_data->gicd_base,
 			CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE);
 
 	/* Set the default attribute of all SPIs */
-	gicv3_spis_configure_defaults(driver_data->gicd_base);
+	gicv3_spis_configure_defaults(gicv3_driver_data->gicd_base);
 
 	/* Configure the G1S SPIs */
-	if (driver_data->g1s_interrupt_array) {
-		gicv3_secure_spis_configure(driver_data->gicd_base,
-					driver_data->g1s_interrupt_num,
-					driver_data->g1s_interrupt_array,
+	if (gicv3_driver_data->g1s_interrupt_array) {
+		gicv3_secure_spis_configure(gicv3_driver_data->gicd_base,
+					gicv3_driver_data->g1s_interrupt_num,
+					gicv3_driver_data->g1s_interrupt_array,
 					INTR_GROUP1S);
 		bitmap |= CTLR_ENABLE_G1S_BIT;
 	}
 
 	/* Configure the G0 SPIs */
-	if (driver_data->g0_interrupt_array) {
-		gicv3_secure_spis_configure(driver_data->gicd_base,
-					driver_data->g0_interrupt_num,
-					driver_data->g0_interrupt_array,
+	if (gicv3_driver_data->g0_interrupt_array) {
+		gicv3_secure_spis_configure(gicv3_driver_data->gicd_base,
+					gicv3_driver_data->g0_interrupt_num,
+					gicv3_driver_data->g0_interrupt_array,
 					INTR_GROUP0);
 		bitmap |= CTLR_ENABLE_G0_BIT;
 	}
 
 	/* Enable the secure SPIs now that they have been configured */
-	gicd_set_ctlr(driver_data->gicd_base, bitmap, RWP_TRUE);
+	gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE);
 }
 
 /*******************************************************************************
@@ -173,37 +173,37 @@
 {
 	uintptr_t gicr_base;
 
-	assert(driver_data);
-	assert(proc_num < driver_data->rdistif_num);
-	assert(driver_data->rdistif_base_addrs);
-	assert(driver_data->gicd_base);
-	assert(gicd_read_ctlr(driver_data->gicd_base) & CTLR_ARE_S_BIT);
-	assert(driver_data->g1s_interrupt_array ||
-	       driver_data->g0_interrupt_array);
+	assert(gicv3_driver_data);
+	assert(proc_num < gicv3_driver_data->rdistif_num);
+	assert(gicv3_driver_data->rdistif_base_addrs);
+	assert(gicv3_driver_data->gicd_base);
+	assert(gicd_read_ctlr(gicv3_driver_data->gicd_base) & CTLR_ARE_S_BIT);
+	assert(gicv3_driver_data->g1s_interrupt_array ||
+	       gicv3_driver_data->g0_interrupt_array);
 
 	assert(IS_IN_EL3());
 
 	/* Power on redistributor */
 	gicv3_rdistif_on(proc_num);
 
-	gicr_base = driver_data->rdistif_base_addrs[proc_num];
+	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
 
 	/* Set the default attribute of all SGIs and PPIs */
 	gicv3_ppi_sgi_configure_defaults(gicr_base);
 
 	/* Configure the G1S SGIs/PPIs */
-	if (driver_data->g1s_interrupt_array) {
+	if (gicv3_driver_data->g1s_interrupt_array) {
 		gicv3_secure_ppi_sgi_configure(gicr_base,
-					driver_data->g1s_interrupt_num,
-					driver_data->g1s_interrupt_array,
+					gicv3_driver_data->g1s_interrupt_num,
+					gicv3_driver_data->g1s_interrupt_array,
 					INTR_GROUP1S);
 	}
 
 	/* Configure the G0 SGIs/PPIs */
-	if (driver_data->g0_interrupt_array) {
+	if (gicv3_driver_data->g0_interrupt_array) {
 		gicv3_secure_ppi_sgi_configure(gicr_base,
-					driver_data->g0_interrupt_num,
-					driver_data->g0_interrupt_array,
+					gicv3_driver_data->g0_interrupt_num,
+					gicv3_driver_data->g0_interrupt_array,
 					INTR_GROUP0);
 	}
 }
@@ -231,13 +231,13 @@
 	unsigned int scr_el3;
 	unsigned int icc_sre_el3;
 
-	assert(driver_data);
-	assert(proc_num < driver_data->rdistif_num);
-	assert(driver_data->rdistif_base_addrs);
+	assert(gicv3_driver_data);
+	assert(proc_num < gicv3_driver_data->rdistif_num);
+	assert(gicv3_driver_data->rdistif_base_addrs);
 	assert(IS_IN_EL3());
 
 	/* Mark the connected core as awake */
-	gicr_base = driver_data->rdistif_base_addrs[proc_num];
+	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
 	gicv3_rdistif_mark_core_awake(gicr_base);
 
 	/* Disable the legacy interrupt bypass */
@@ -291,9 +291,9 @@
 {
 	uintptr_t gicr_base;
 
-	assert(driver_data);
-	assert(proc_num < driver_data->rdistif_num);
-	assert(driver_data->rdistif_base_addrs);
+	assert(gicv3_driver_data);
+	assert(proc_num < gicv3_driver_data->rdistif_num);
+	assert(gicv3_driver_data->rdistif_base_addrs);
 
 	assert(IS_IN_EL3());
 
@@ -314,7 +314,7 @@
 	isb();
 
 	/* Mark the connected core as asleep */
-	gicr_base = driver_data->rdistif_base_addrs[proc_num];
+	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
 	gicv3_rdistif_mark_core_asleep(gicr_base);
 }
 
@@ -371,25 +371,25 @@
 	uintptr_t gicr_base;
 
 	assert(IS_IN_EL3());
-	assert(driver_data);
+	assert(gicv3_driver_data);
 
 	/* Ensure the parameters are valid */
 	assert(id < PENDING_G1S_INTID || id >= MIN_LPI_ID);
-	assert(proc_num < driver_data->rdistif_num);
+	assert(proc_num < gicv3_driver_data->rdistif_num);
 
 	/* All LPI interrupts are Group 1 non secure */
 	if (id >= MIN_LPI_ID)
 		return INTR_GROUP1NS;
 
 	if (id < MIN_SPI_ID) {
-		assert(driver_data->rdistif_base_addrs);
-		gicr_base = driver_data->rdistif_base_addrs[proc_num];
+		assert(gicv3_driver_data->rdistif_base_addrs);
+		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
 		igroup = gicr_get_igroupr0(gicr_base, id);
 		grpmodr = gicr_get_igrpmodr0(gicr_base, id);
 	} else {
-		assert(driver_data->gicd_base);
-		igroup = gicd_get_igroupr(driver_data->gicd_base, id);
-		grpmodr = gicd_get_igrpmodr(driver_data->gicd_base, id);
+		assert(gicv3_driver_data->gicd_base);
+		igroup = gicd_get_igroupr(gicv3_driver_data->gicd_base, id);
+		grpmodr = gicd_get_igrpmodr(gicv3_driver_data->gicd_base, id);
 	}
 
 	/*