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:
commit
0295079162
|
@ -16,15 +16,13 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <arch_helpers.h>
|
#include <arch_helpers.h>
|
||||||
|
#include <drivers/arm/arm_gicv3_common.h>
|
||||||
#include <drivers/arm/gicv3.h>
|
#include <drivers/arm/gicv3.h>
|
||||||
|
|
||||||
#include "gicv3_private.h"
|
#include "gicv3_private.h"
|
||||||
|
|
||||||
/* GIC-600 specific register offsets */
|
/* GIC-600 specific register offsets */
|
||||||
#define GICR_PWRR 0x24U
|
#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 */
|
/* GICR_PWRR fields */
|
||||||
#define PWRR_RDPD_SHIFT 0
|
#define PWRR_RDPD_SHIFT 0
|
||||||
|
@ -46,7 +44,7 @@
|
||||||
|
|
||||||
#if GICV3_SUPPORT_GIC600
|
#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)
|
static void gicr_write_pwrr(uintptr_t base, unsigned int val)
|
||||||
{
|
{
|
||||||
mmio_write_32(base + GICR_PWRR, 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);
|
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.
|
* powered down at reset.
|
||||||
*/
|
*/
|
||||||
return (((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) ||
|
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_600AE) ||
|
||||||
((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_CLAYTON));
|
((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* GICV3_SUPPORT_GIC600 */
|
#endif /* GICV3_SUPPORT_GIC600 */
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
|
#include <drivers/arm/arm_gicv3_common.h>
|
||||||
#include <drivers/arm/gic600_multichip.h>
|
#include <drivers/arm/gic600_multichip.h>
|
||||||
#include <drivers/arm/gicv3.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_id_max)
|
||||||
{
|
{
|
||||||
unsigned int spi_block_min, spi_blocks;
|
unsigned int spi_block_min, spi_blocks;
|
||||||
|
unsigned int gicd_iidr_val = gicd_read_iidr(base);
|
||||||
uint64_t chipr_n_val;
|
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_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
|
||||||
spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
|
spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
|
||||||
|
|
||||||
chipr_n_val = (GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks)) |
|
switch ((gicd_iidr_val & IIDR_MODEL_MASK)) {
|
||||||
GICD_CHIPRx_SOCKET_STATE;
|
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
|
* Wait for DCHIPR.PUP to be zero before commencing writes to
|
||||||
|
|
|
@ -27,17 +27,11 @@
|
||||||
#define GICD_CHIPSR_RTS_SHIFT 4
|
#define GICD_CHIPSR_RTS_SHIFT 4
|
||||||
#define GICD_DCHIPR_RT_OWNER_SHIFT 4
|
#define GICD_DCHIPR_RT_OWNER_SHIFT 4
|
||||||
|
|
||||||
/*
|
/* Other shifts and masks remain the same between GIC-600 and GIC-700. */
|
||||||
* If GIC v4 extension is enabled, then use SPI macros specific to GIC-Clayton.
|
#define GIC_700_SPI_BLOCK_MIN_SHIFT 9
|
||||||
* Other shifts and mask remains same between GIC-600 and GIC-Clayton.
|
#define GIC_700_SPI_BLOCKS_SHIFT 3
|
||||||
*/
|
#define GIC_600_SPI_BLOCK_MIN_SHIFT 10
|
||||||
#if GIC_ENABLE_V4_EXTN
|
#define GIC_600_SPI_BLOCKS_SHIFT 5
|
||||||
#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
|
|
||||||
|
|
||||||
#define GICD_CHIPSR_RTS_STATE_DISCONNECTED U(0)
|
#define GICD_CHIPSR_RTS_STATE_DISCONNECTED U(0)
|
||||||
#define GICD_CHIPSR_RTS_STATE_UPDATING U(1)
|
#define GICD_CHIPSR_RTS_STATE_UPDATING U(1)
|
||||||
|
@ -59,10 +53,14 @@
|
||||||
#define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
|
#define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
|
||||||
(((spi_id_max) - (spi_id_min) + 1) / \
|
(((spi_id_max) - (spi_id_min) + 1) / \
|
||||||
GIC600_SPI_ID_MIN)
|
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) | \
|
(((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
|
||||||
((spi_block_min) << GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT) | \
|
((spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \
|
||||||
((spi_blocks) << GICD_CHIPRx_SPI_BLOCKS_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
|
* Multichip data assertion macros
|
||||||
|
|
|
@ -86,8 +86,7 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
|
||||||
if (proc_num < rdistif_num) {
|
if (proc_num < rdistif_num) {
|
||||||
rdistif_base_addrs[proc_num] = rdistif_base;
|
rdistif_base_addrs[proc_num] = rdistif_base;
|
||||||
}
|
}
|
||||||
|
rdistif_base += gicv3_redist_size(typer_val);
|
||||||
rdistif_base += (1U << GICR_PCPUBASE_SHIFT);
|
|
||||||
} while ((typer_val & TYPER_LAST_BIT) == 0U);
|
} 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;
|
uintptr_t rdistif_base = gicr_frame;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
for (count = 1; count < PLATFORM_CORE_COUNT; count++) {
|
for (count = 1U; count < PLATFORM_CORE_COUNT; count++) {
|
||||||
if ((gicr_read_typer(rdistif_base) & TYPER_LAST_BIT) != 0U) {
|
uint64_t typer_val = gicr_read_typer(rdistif_base);
|
||||||
|
|
||||||
|
if ((typer_val & TYPER_LAST_BIT) != 0U) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rdistif_base += (1U << GICR_PCPUBASE_SHIFT);
|
rdistif_base += gicv3_redist_size(typer_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
|
@ -123,13 +123,7 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data)
|
||||||
gic_version &= PIDR2_ARCH_REV_MASK;
|
gic_version &= PIDR2_ARCH_REV_MASK;
|
||||||
|
|
||||||
/* Check GIC version */
|
/* Check GIC version */
|
||||||
#if GIC_ENABLE_V4_EXTN
|
#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
|
|
||||||
assert(gic_version == ARCH_REV_GICV3);
|
assert(gic_version == ARCH_REV_GICV3);
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
|
@ -1298,7 +1292,7 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame)
|
||||||
gicr_frame_found = true;
|
gicr_frame_found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rdistif_base += (uintptr_t)(ULL(1) << GICR_PCPUBASE_SHIFT);
|
rdistif_base += gicv3_redist_size(typer_val);
|
||||||
} while ((typer_val & TYPER_LAST_BIT) == 0U);
|
} while ((typer_val & TYPER_LAST_BIT) == 0U);
|
||||||
|
|
||||||
if (!gicr_frame_found) {
|
if (!gicr_frame_found) {
|
||||||
|
|
|
@ -17,4 +17,8 @@
|
||||||
#define WAKER_SL_BIT (1U << WAKER_SL_SHIFT)
|
#define WAKER_SL_BIT (1U << WAKER_SL_SHIFT)
|
||||||
#define WAKER_QSC_BIT (1U << WAKER_QSC_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 */
|
#endif /* ARM_GICV3_COMMON_H */
|
||||||
|
|
|
@ -153,11 +153,8 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Common GIC Redistributor interface registers & constants
|
* Common GIC Redistributor interface registers & constants
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#if GIC_ENABLE_V4_EXTN
|
#define GICR_V4_PCPUBASE_SHIFT 0x12
|
||||||
#define GICR_PCPUBASE_SHIFT 0x12
|
#define GICR_V3_PCPUBASE_SHIFT 0x11
|
||||||
#else
|
|
||||||
#define GICR_PCPUBASE_SHIFT 0x11
|
|
||||||
#endif
|
|
||||||
#define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */
|
#define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */
|
||||||
#define GICR_CTLR U(0x0)
|
#define GICR_CTLR U(0x0)
|
||||||
#define GICR_IIDR U(0x04)
|
#define GICR_IIDR U(0x04)
|
||||||
|
@ -212,12 +209,14 @@
|
||||||
#define TYPER_AFF_VAL_SHIFT 32
|
#define TYPER_AFF_VAL_SHIFT 32
|
||||||
#define TYPER_PROC_NUM_SHIFT 8
|
#define TYPER_PROC_NUM_SHIFT 8
|
||||||
#define TYPER_LAST_SHIFT 4
|
#define TYPER_LAST_SHIFT 4
|
||||||
|
#define TYPER_VLPI_SHIFT 1
|
||||||
|
|
||||||
#define TYPER_AFF_VAL_MASK U(0xffffffff)
|
#define TYPER_AFF_VAL_MASK U(0xffffffff)
|
||||||
#define TYPER_PROC_NUM_MASK U(0xffff)
|
#define TYPER_PROC_NUM_MASK U(0xffff)
|
||||||
#define TYPER_LAST_MASK U(0x1)
|
#define TYPER_LAST_MASK U(0x1)
|
||||||
|
|
||||||
#define TYPER_LAST_BIT BIT_32(TYPER_LAST_SHIFT)
|
#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_SHIFT U(27)
|
||||||
#define TYPER_PPI_NUM_MASK U(0x1f)
|
#define TYPER_PPI_NUM_MASK U(0x1f)
|
||||||
|
@ -312,6 +311,19 @@
|
||||||
#include <drivers/arm/gic_common.h>
|
#include <drivers/arm/gic_common.h>
|
||||||
#include <lib/utils_def.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)
|
static inline bool gicv3_is_intr_id_special_identifier(unsigned int id)
|
||||||
{
|
{
|
||||||
return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT);
|
return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT);
|
||||||
|
|
|
@ -218,7 +218,7 @@ static void fpga_prepare_dtb(void)
|
||||||
INFO("Adjusting GICR DT region to cover %u cores\n",
|
INFO("Adjusting GICR DT region to cover %u cores\n",
|
||||||
nr_cores);
|
nr_cores);
|
||||||
err = fdt_adjust_gic_redist(fdt, nr_cores,
|
err = fdt_adjust_gic_redist(fdt, nr_cores,
|
||||||
1U << GICR_PCPUBASE_SHIFT);
|
fpga_get_redist_size());
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ERROR("Error %d fixing up GIC DT node\n", err);
|
ERROR("Error %d fixing up GIC DT node\n", err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <common/fdt_wrappers.h>
|
#include <common/fdt_wrappers.h>
|
||||||
#include <drivers/arm/gicv3.h>
|
#include <drivers/arm/gicv3.h>
|
||||||
#include <drivers/arm/gic_common.h>
|
#include <drivers/arm/gic_common.h>
|
||||||
|
#include <lib/mmio.h>
|
||||||
#include <libfdt.h>
|
#include <libfdt.h>
|
||||||
|
|
||||||
#include <platform_def.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);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ void fpga_pwr_gic_on_finish(void);
|
||||||
void fpga_pwr_gic_off(void);
|
void fpga_pwr_gic_off(void);
|
||||||
unsigned int plat_fpga_calc_core_pos(uint32_t mpid);
|
unsigned int plat_fpga_calc_core_pos(uint32_t mpid);
|
||||||
unsigned int fpga_get_nr_gic_cores(void);
|
unsigned int fpga_get_nr_gic_cores(void);
|
||||||
|
uintptr_t fpga_get_redist_size(void);
|
||||||
|
|
||||||
#endif /* __ASSEMBLER__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ endif
|
||||||
# Allow detection of GIC-600
|
# Allow detection of GIC-600
|
||||||
GICV3_SUPPORT_GIC600 := 1
|
GICV3_SUPPORT_GIC600 := 1
|
||||||
|
|
||||||
|
GIC_ENABLE_V4_EXTN := 1
|
||||||
|
|
||||||
# Include GICv3 driver files
|
# Include GICv3 driver files
|
||||||
include drivers/arm/gic/v3/gicv3.mk
|
include drivers/arm/gic/v3/gicv3.mk
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# 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
|
GIC_ENABLE_V4_EXTN := 1
|
||||||
|
|
||||||
include plat/arm/css/sgi/sgi-common.mk
|
include plat/arm/css/sgi/sgi-common.mk
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# 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
|
GIC_ENABLE_V4_EXTN := 1
|
||||||
|
|
||||||
include plat/arm/css/sgi/sgi-common.mk
|
include plat/arm/css/sgi/sgi-common.mk
|
||||||
|
|
Loading…
Reference in New Issue