Merge "GICv3: GIC-600: Detect GIC-600 at runtime" into integration
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 7ca1067..920f934 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -717,8 +717,10 @@
The driver can be configured with the following options set in the platform
makefile:
-- ``GICV3_IMPL``: Selects between GIC-500 and GIC-600 variants of GICv3.
- This option can take values GIC500 and GIC600 with default set to GIC500.
+- ``GICV3_SUPPORT_GIC600``: Add support for the GIC-600 variants of GICv3.
+ Enabling this option will add runtime detection support for the
+ GIC-600, so is safe to select even for a GIC500 implementation.
+ This option defaults to 0.
- ``GICV3_IMPL_GIC600_MULTICHIP``: Selects GIC-600 variant with multichip
functionality. This option defaults to 0
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index eb7eb00..f23ec28 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -116,7 +116,6 @@
- ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
- - ``FVP_GIC600`` : The GIC600 implementation of GICv3 is selected
- ``FVP_GICV2`` : The GICv2 only driver is selected
- ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
diff --git a/drivers/arm/gic/v3/gic600.c b/drivers/arm/gic/v3/gic-x00.c
similarity index 76%
rename from drivers/arm/gic/v3/gic600.c
rename to drivers/arm/gic/v3/gic-x00.c
index 59652da..c1a9f0d 100644
--- a/drivers/arm/gic/v3/gic600.c
+++ b/drivers/arm/gic/v3/gic-x00.c
@@ -5,8 +5,9 @@
*/
/*
- * Driver for GIC-600 specific features. This driver only overrides
- * APIs that are different to those generic ones in GICv3 driver.
+ * Driver for GIC-500 and GIC-600 specific features. This driver only
+ * overrides APIs that are different to those generic ones in GICv3
+ * driver.
*
* GIC-600 supports independently power-gating redistributor interface.
*/
@@ -19,7 +20,8 @@
#include "gicv3_private.h"
/* GIC-600 specific register offsets */
-#define GICR_PWRR 0x24
+#define GICR_PWRR 0x24
+#define IIDR_MODEL_ARM_GIC_600 0x0200043b
/* GICR_PWRR fields */
#define PWRR_RDPD_SHIFT 0
@@ -39,6 +41,8 @@
#define PWRR_ON (0 << PWRR_RDPD_SHIFT)
#define PWRR_OFF (1 << PWRR_RDPD_SHIFT)
+#if GICV3_SUPPORT_GIC600
+
/* GIC-600 specific accessor functions */
static void gicr_write_pwrr(uintptr_t base, unsigned int val)
{
@@ -93,6 +97,29 @@
}
}
+static uintptr_t get_gicr_base(unsigned int proc_num)
+{
+ uintptr_t gicr_base;
+
+ assert(gicv3_driver_data);
+ assert(proc_num < gicv3_driver_data->rdistif_num);
+ assert(gicv3_driver_data->rdistif_base_addrs);
+
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+ assert(gicr_base);
+
+ return gicr_base;
+}
+
+static bool gicv3_is_gic600(uintptr_t gicr_base)
+{
+ uint32_t reg = mmio_read_32(gicr_base + GICR_IIDR);
+
+ return (reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600;
+}
+
+#endif
+
void gicv3_distif_pre_save(unsigned int proc_num)
{
arm_gicv3_distif_pre_save(proc_num);
@@ -103,38 +130,33 @@
arm_gicv3_distif_post_restore(proc_num);
}
+
/*
- * Power off GIC-600 redistributor
+ * Power off GIC-600 redistributor (if configured and detected)
*/
void gicv3_rdistif_off(unsigned int proc_num)
{
- uintptr_t gicr_base;
-
- assert(gicv3_driver_data);
- assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
-
- gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
- assert(gicr_base);
+#if GICV3_SUPPORT_GIC600
+ uintptr_t gicr_base = get_gicr_base(proc_num);
/* Attempt to power redistributor off */
- gic600_pwr_off(gicr_base);
+ if (gicv3_is_gic600(gicr_base)) {
+ gic600_pwr_off(gicr_base);
+ }
+#endif
}
/*
- * Power on GIC-600 redistributor
+ * Power on GIC-600 redistributor (if configured and detected)
*/
void gicv3_rdistif_on(unsigned int proc_num)
{
- uintptr_t gicr_base;
-
- assert(gicv3_driver_data);
- assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
-
- gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
- assert(gicr_base);
+#if GICV3_SUPPORT_GIC600
+ uintptr_t gicr_base = get_gicr_base(proc_num);
/* Power redistributor on */
- gic600_pwr_on(gicr_base);
+ if (gicv3_is_gic600(gicr_base)) {
+ gic600_pwr_on(gicr_base);
+ }
+#endif
}
diff --git a/drivers/arm/gic/v3/gic500.c b/drivers/arm/gic/v3/gic500.c
deleted file mode 100644
index f03e33f..0000000
--- a/drivers/arm/gic/v3/gic500.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/*
- * Driver for GIC500-specific features. This driver only overrides APIs that are
- * different to those generic ones in GICv3 driver.
- */
-#include "gicv3_private.h"
-
-void gicv3_distif_pre_save(unsigned int proc_num)
-{
- arm_gicv3_distif_pre_save(proc_num);
-}
-
-void gicv3_distif_post_restore(unsigned int proc_num)
-{
- arm_gicv3_distif_post_restore(proc_num);
-}
-
diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk
index 0f40103..a2fc16f 100644
--- a/drivers/arm/gic/v3/gicv3.mk
+++ b/drivers/arm/gic/v3/gicv3.mk
@@ -5,7 +5,7 @@
#
# Default configuration values
-GICV3_IMPL ?= GIC500
+GICV3_SUPPORT_GIC600 ?= 0
GICV3_IMPL_GIC600_MULTICHIP ?= 0
GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0
GIC_ENABLE_V4_EXTN ?= 0
@@ -20,19 +20,14 @@
GICV3_SOURCES += drivers/arm/gic/v3/arm_gicv3_common.c
endif
-# Either GIC-600 or GIC-500 can be selected at one time
-ifeq (${GICV3_IMPL}, GIC600)
-# GIC-600 sources
-GICV3_SOURCES += drivers/arm/gic/v3/gic600.c
+GICV3_SOURCES += drivers/arm/gic/v3/gic-x00.c
ifeq (${GICV3_IMPL_GIC600_MULTICHIP}, 1)
GICV3_SOURCES += drivers/arm/gic/v3/gic600_multichip.c
endif
-else ifeq (${GICV3_IMPL}, GIC500)
-# GIC-500 sources
-GICV3_SOURCES += drivers/arm/gic/v3/gic500.c
-else
-$(error "Incorrect GICV3_IMPL value ${GICV3_IMPL}")
-endif
+
+# Set GIC-600 support
+$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600))
+$(eval $(call add_define,GICV3_SUPPORT_GIC600))
# Set GICv4 extension
$(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN))
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 03596b9..77dc350 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -222,6 +222,14 @@
#define TYPER_PPI_NUM_SHIFT U(27)
#define TYPER_PPI_NUM_MASK U(0x1f)
+/* GICR_IIDR bit definitions */
+#define IIDR_PRODUCT_ID_MASK 0xff000000
+#define IIDR_VARIANT_MASK 0x000f0000
+#define IIDR_REVISION_MASK 0x0000f000
+#define IIDR_IMPLEMENTER_MASK 0x00000fff
+#define IIDR_MODEL_MASK (IIDR_PRODUCT_ID_MASK | \
+ IIDR_IMPLEMENTER_MASK)
+
/*******************************************************************************
* GICv3 and 3.1 CPU interface registers & constants
******************************************************************************/
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 7039a6d..34e50ea 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -70,8 +70,8 @@
lib/cpus/aarch64/cortex_a75.S
endif
-# GIC-600 configuration
-GICV3_IMPL := GIC600
+# Allow detection of GIC-600
+GICV3_SUPPORT_GIC600 := 1
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index e605608..7d670ac 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -49,13 +49,10 @@
$(eval $(call add_define,FVP_INTERCONNECT_DRIVER))
# Choose the GIC sources depending upon the how the FVP will be invoked
-ifeq (${FVP_USE_GIC_DRIVER},$(filter ${FVP_USE_GIC_DRIVER},FVP_GICV3 FVP_GIC600))
-
- # GIC500 is the default option in case GICV3_IMPL is not set
- ifeq (${FVP_USE_GIC_DRIVER}, FVP_GIC600)
- GICV3_IMPL := GIC600
- endif
+ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3)
+# The GIC model (GIC-600 or GIC-500) will be detected at runtime
+GICV3_SUPPORT_GIC600 := 1
GICV3_OVERRIDE_DISTIF_PWR_OPS := 1
# Include GICv3 driver files
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 44f7b8a..0bd3a21 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -15,7 +15,7 @@
N1SDP_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S
# GIC-600 configuration
-GICV3_IMPL := GIC600
+GICV3_SUPPORT_GIC600 := 1
GICV3_IMPL_GIC600_MULTICHIP := 1
# Include GICv3 driver files
diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk
index 265826f..7f514cc 100644
--- a/plat/arm/board/tc0/platform.mk
+++ b/plat/arm/board/tc0/platform.mk
@@ -25,7 +25,8 @@
GIC_ENABLE_V4_EXTN := 1
# GIC-600 configuration
-GICV3_IMPL := GIC600
+GICV3_SUPPORT_GIC600 := 1
+
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 2504581..6b9e0cd 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -23,7 +23,7 @@
PLAT_INCLUDES += -I${CSS_ENT_BASE}/include
# GIC-600 configuration
-GICV3_IMPL := GIC600
+GICV3_SUPPORT_GIC600 := 1
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
index 60e9fb2..5b954f8 100644
--- a/plat/arm/css/sgm/sgm-common.mk
+++ b/plat/arm/css/sgm/sgm-common.mk
@@ -23,7 +23,7 @@
INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c
# GIC-600 configuration
-GICV3_IMPL := GIC600
+GICV3_SUPPORT_GIC600 := 1
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk