Merge changes from topic "gic-700-auto" into integration

* changes:
  feat(arm_fpga): support GICv4 images
  feat(gicv3): detect GICv4 feature at runtime
  feat(gicv3): multichip: detect GIC-700 at runtime
  refactor(gic): move GIC IIDR numbers
  refactor(gicv3): rename GIC Clayton to GIC-700
This commit is contained in:
André Przywara 2021-09-10 17:17:46 +02:00 committed by TrustedFirmware Code Review
commit 0295079162
13 changed files with 80 additions and 43 deletions

View File

@ -16,15 +16,13 @@
#include <assert.h>
#include <arch_helpers.h>
#include <drivers/arm/arm_gicv3_common.h>
#include <drivers/arm/gicv3.h>
#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 */

View File

@ -11,6 +11,7 @@
#include <assert.h>
#include <common/debug.h>
#include <drivers/arm/arm_gicv3_common.h>
#include <drivers/arm/gic600_multichip.h>
#include <drivers/arm/gicv3.h>
@ -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

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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 */

View File

@ -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 <drivers/arm/gic_common.h>
#include <lib/utils_def.h>
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);

View File

@ -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);
}

View File

@ -8,6 +8,7 @@
#include <common/fdt_wrappers.h>
#include <drivers/arm/gicv3.h>
#include <drivers/arm/gic_common.h>
#include <lib/mmio.h>
#include <libfdt.h>
#include <platform_def.h>
@ -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);
}

View File

@ -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__ */

View File

@ -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

View File

@ -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

View File

@ -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