feat(gicv3): multichip: detect GIC-700 at runtime
At the moment we have a GIC_ENABLE_V4_EXTN build time variable to determine whether the GIC interrupt controller is compliant to version 4.0 of the GIC spec or not. In case of the GIC-600 multichip support we were somewhat abusing that flag to differentiate between a GIC-700 and GIC-600 implementation being used in the system. To avoid a build time dependency on this flag, look at the GICD_IIDR register and check if the hardware is a GIC-600 or not, to make this decision at runtime. We then use the values for either GIC-700 or the GIC-600, respectively. Change-Id: I8c09ec1cd6fd60d28da879ed55ffef5506f9869d Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
parent
1fe27d7135
commit
feb7081863
|
@ -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
|
||||
|
|
|
@ -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-700.
|
||||
* Other shifts and mask remains same between GIC-600 and GIC-700.
|
||||
*/
|
||||
#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
|
||||
|
|
Loading…
Reference in New Issue