diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c index 6e106babf..aaef485ff 100644 --- a/drivers/arm/gic/v3/gic-x00.c +++ b/drivers/arm/gic/v3/gic-x00.c @@ -16,15 +16,13 @@ #include #include +#include #include #include "gicv3_private.h" /* GIC-600 specific register offsets */ #define GICR_PWRR 0x24U -#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b) -#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b) -#define IIDR_MODEL_ARM_GIC_CLAYTON U(0x0400043b) /* GICR_PWRR fields */ #define PWRR_RDPD_SHIFT 0 @@ -46,7 +44,7 @@ #if GICV3_SUPPORT_GIC600 -/* GIC-600/Clayton specific accessor functions */ +/* GIC-600/700 specific accessor functions */ static void gicr_write_pwrr(uintptr_t base, unsigned int val) { mmio_write_32(base + GICR_PWRR, val); @@ -123,12 +121,12 @@ static bool gicv3_redists_need_power_mgmt(uintptr_t gicr_base) uint32_t reg = mmio_read_32(gicr_base + GICR_IIDR); /* - * The Arm GIC-600 and GIC-Clayton models have their redistributors + * The Arm GIC-600 and GIC-700 models have their redistributors * powered down at reset. */ return (((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) || ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600AE) || - ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_CLAYTON)); + ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700)); } #endif /* GICV3_SUPPORT_GIC600 */ diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c index ca7c43bf9..fd3d8c207 100644 --- a/drivers/arm/gic/v3/gic600_multichip.c +++ b/drivers/arm/gic/v3/gic600_multichip.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -73,6 +74,7 @@ static void set_gicd_chipr_n(uintptr_t base, unsigned int spi_id_max) { unsigned int spi_block_min, spi_blocks; + unsigned int gicd_iidr_val = gicd_read_iidr(base); uint64_t chipr_n_val; /* @@ -100,8 +102,24 @@ static void set_gicd_chipr_n(uintptr_t base, spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min); spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max); - chipr_n_val = (GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks)) | - GICD_CHIPRx_SOCKET_STATE; + switch ((gicd_iidr_val & IIDR_MODEL_MASK)) { + case IIDR_MODEL_ARM_GIC_600: + chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr, + spi_block_min, + spi_blocks); + break; + case IIDR_MODEL_ARM_GIC_700: + chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr, + spi_block_min, + spi_blocks); + break; + default: + ERROR("Unsupported GIC model 0x%x for multichip setup.\n", + gicd_iidr_val); + panic(); + break; + } + chipr_n_val |= GICD_CHIPRx_SOCKET_STATE; /* * Wait for DCHIPR.PUP to be zero before commencing writes to diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h index fe4134cba..5d1ff6a19 100644 --- a/drivers/arm/gic/v3/gic600_multichip_private.h +++ b/drivers/arm/gic/v3/gic600_multichip_private.h @@ -27,17 +27,11 @@ #define GICD_CHIPSR_RTS_SHIFT 4 #define GICD_DCHIPR_RT_OWNER_SHIFT 4 -/* - * If GIC v4 extension is enabled, then use SPI macros specific to GIC-Clayton. - * Other shifts and mask remains same between GIC-600 and GIC-Clayton. - */ -#if GIC_ENABLE_V4_EXTN -#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 9 -#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 3 -#else -#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 10 -#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 5 -#endif +/* Other shifts and masks remain the same between GIC-600 and GIC-700. */ +#define GIC_700_SPI_BLOCK_MIN_SHIFT 9 +#define GIC_700_SPI_BLOCKS_SHIFT 3 +#define GIC_600_SPI_BLOCK_MIN_SHIFT 10 +#define GIC_600_SPI_BLOCKS_SHIFT 5 #define GICD_CHIPSR_RTS_STATE_DISCONNECTED U(0) #define GICD_CHIPSR_RTS_STATE_UPDATING U(1) @@ -59,10 +53,14 @@ #define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \ (((spi_id_max) - (spi_id_min) + 1) / \ GIC600_SPI_ID_MIN) -#define GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks) \ +#define GICD_CHIPR_VALUE_GIC_700(chip_addr, spi_block_min, spi_blocks) \ (((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \ - ((spi_block_min) << GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT) | \ - ((spi_blocks) << GICD_CHIPRx_SPI_BLOCKS_SHIFT)) + ((spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \ + ((spi_blocks) << GIC_700_SPI_BLOCKS_SHIFT)) +#define GICD_CHIPR_VALUE_GIC_600(chip_addr, spi_block_min, spi_blocks) \ + (((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \ + ((spi_block_min) << GIC_600_SPI_BLOCK_MIN_SHIFT) | \ + ((spi_blocks) << GIC_600_SPI_BLOCKS_SHIFT)) /* * Multichip data assertion macros diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index a0f44e966..d752013e2 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -86,8 +86,7 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, if (proc_num < rdistif_num) { rdistif_base_addrs[proc_num] = rdistif_base; } - - rdistif_base += (1U << GICR_PCPUBASE_SHIFT); + rdistif_base += gicv3_redist_size(typer_val); } while ((typer_val & TYPER_LAST_BIT) == 0U); } @@ -383,11 +382,13 @@ unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame) uintptr_t rdistif_base = gicr_frame; unsigned int count; - for (count = 1; count < PLATFORM_CORE_COUNT; count++) { - if ((gicr_read_typer(rdistif_base) & TYPER_LAST_BIT) != 0U) { + for (count = 1U; count < PLATFORM_CORE_COUNT; count++) { + uint64_t typer_val = gicr_read_typer(rdistif_base); + + if ((typer_val & TYPER_LAST_BIT) != 0U) { break; } - rdistif_base += (1U << GICR_PCPUBASE_SHIFT); + rdistif_base += gicv3_redist_size(typer_val); } return count; diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index b1139b5e9..53a8fae3b 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -123,13 +123,7 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) gic_version &= PIDR2_ARCH_REV_MASK; /* Check GIC version */ -#if GIC_ENABLE_V4_EXTN - assert(gic_version == ARCH_REV_GICV4); - - /* GICv4 supports Direct Virtual LPI injection */ - assert((gicd_read_typer(plat_driver_data->gicd_base) - & TYPER_DVIS) != 0); -#else +#if !GIC_ENABLE_V4_EXTN assert(gic_version == ARCH_REV_GICV3); #endif /* @@ -1298,7 +1292,7 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame) gicr_frame_found = true; break; } - rdistif_base += (uintptr_t)(ULL(1) << GICR_PCPUBASE_SHIFT); + rdistif_base += gicv3_redist_size(typer_val); } while ((typer_val & TYPER_LAST_BIT) == 0U); if (!gicr_frame_found) { diff --git a/include/drivers/arm/arm_gicv3_common.h b/include/drivers/arm/arm_gicv3_common.h index b88b59fbf..e5df31136 100644 --- a/include/drivers/arm/arm_gicv3_common.h +++ b/include/drivers/arm/arm_gicv3_common.h @@ -17,4 +17,8 @@ #define WAKER_SL_BIT (1U << WAKER_SL_SHIFT) #define WAKER_QSC_BIT (1U << WAKER_QSC_SHIFT) +#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b) +#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b) +#define IIDR_MODEL_ARM_GIC_700 U(0x0400043b) + #endif /* ARM_GICV3_COMMON_H */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index d8ac4cb33..fa8946b16 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -153,11 +153,8 @@ /******************************************************************************* * Common GIC Redistributor interface registers & constants ******************************************************************************/ -#if GIC_ENABLE_V4_EXTN -#define GICR_PCPUBASE_SHIFT 0x12 -#else -#define GICR_PCPUBASE_SHIFT 0x11 -#endif +#define GICR_V4_PCPUBASE_SHIFT 0x12 +#define GICR_V3_PCPUBASE_SHIFT 0x11 #define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */ #define GICR_CTLR U(0x0) #define GICR_IIDR U(0x04) @@ -212,12 +209,14 @@ #define TYPER_AFF_VAL_SHIFT 32 #define TYPER_PROC_NUM_SHIFT 8 #define TYPER_LAST_SHIFT 4 +#define TYPER_VLPI_SHIFT 1 #define TYPER_AFF_VAL_MASK U(0xffffffff) #define TYPER_PROC_NUM_MASK U(0xffff) #define TYPER_LAST_MASK U(0x1) #define TYPER_LAST_BIT BIT_32(TYPER_LAST_SHIFT) +#define TYPER_VLPI_BIT BIT_32(TYPER_VLPI_SHIFT) #define TYPER_PPI_NUM_SHIFT U(27) #define TYPER_PPI_NUM_MASK U(0x1f) @@ -312,6 +311,19 @@ #include #include +static inline uintptr_t gicv3_redist_size(uint64_t typer_val) +{ +#if GIC_ENABLE_V4_EXTN + if ((typer_val & TYPER_VLPI_BIT) != 0U) { + return 1U << GICR_V4_PCPUBASE_SHIFT; + } else { + return 1U << GICR_V3_PCPUBASE_SHIFT; + } +#else + return 1U << GICR_V3_PCPUBASE_SHIFT; +#endif +} + static inline bool gicv3_is_intr_id_special_identifier(unsigned int id) { return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT); diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index a5f5ea0f3..81d040cba 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -218,7 +218,7 @@ static void fpga_prepare_dtb(void) INFO("Adjusting GICR DT region to cover %u cores\n", nr_cores); err = fdt_adjust_gic_redist(fdt, nr_cores, - 1U << GICR_PCPUBASE_SHIFT); + fpga_get_redist_size()); if (err < 0) { ERROR("Error %d fixing up GIC DT node\n", err); } diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c index bfc116bef..4a97beb96 100644 --- a/plat/arm/board/arm_fpga/fpga_gicv3.c +++ b/plat/arm/board/arm_fpga/fpga_gicv3.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -82,3 +83,11 @@ unsigned int fpga_get_nr_gic_cores(void) { return gicv3_rdistif_get_number_frames(fpga_gicv3_driver_data.gicr_base); } + +uintptr_t fpga_get_redist_size(void) +{ + uint64_t typer_val = mmio_read_64(fpga_gicv3_driver_data.gicr_base + + GICR_TYPER); + + return gicv3_redist_size(typer_val); +} diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h index 1ca241f26..cc809c4e4 100644 --- a/plat/arm/board/arm_fpga/fpga_private.h +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -25,6 +25,7 @@ void fpga_pwr_gic_on_finish(void); void fpga_pwr_gic_off(void); unsigned int plat_fpga_calc_core_pos(uint32_t mpid); unsigned int fpga_get_nr_gic_cores(void); +uintptr_t fpga_get_redist_size(void); #endif /* __ASSEMBLER__ */ diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index f80ea2fef..baffbcf62 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -89,6 +89,8 @@ endif # Allow detection of GIC-600 GICV3_SUPPORT_GIC600 := 1 +GIC_ENABLE_V4_EXTN := 1 + # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk index 794f8974f..5b24c32bd 100644 --- a/plat/arm/board/rdn2/platform.mk +++ b/plat/arm/board/rdn2/platform.mk @@ -3,7 +3,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# RD-N2 platform uses GIC-Clayton which is based on GICv4.1 +# RD-N2 platform uses GIC-700 which is based on GICv4.1 GIC_ENABLE_V4_EXTN := 1 include plat/arm/css/sgi/sgi-common.mk diff --git a/plat/arm/board/rdv1/platform.mk b/plat/arm/board/rdv1/platform.mk index 1ae85de7c..11f52127e 100644 --- a/plat/arm/board/rdv1/platform.mk +++ b/plat/arm/board/rdv1/platform.mk @@ -3,7 +3,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# RD-V1 platform uses GIC-Clayton which is based on GICv4.1 +# RD-V1 platform uses GIC-700 which is based on GICv4.1 GIC_ENABLE_V4_EXTN := 1 include plat/arm/css/sgi/sgi-common.mk