diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c index 5e44aa95c..6e9567e2b 100644 --- a/drivers/arm/gic/v3/gic600_multichip.c +++ b/drivers/arm/gic/v3/gic600_multichip.c @@ -321,13 +321,41 @@ static void gic700_multichip_validate_data( } } +/******************************************************************************* + * Initialize GIC-600 and GIC-700 Multichip operation in LCA mode by setting up + * the routing table first. + ******************************************************************************/ +static void gic600_multichip_lca_init( + struct gic600_multichip_data *multichip_data) +{ + unsigned int i, j; + unsigned int rt_owner = multichip_data->rt_owner; + + for (i = 0; i < multichip_data->chip_count; i++) { + for (j = 0; j < multichip_data->chip_count; j++) { + INFO("RT(LCA): CHIP%u -> CHIP%u 0x%lx\n", i, j, + multichip_data->chip_addrs[i][j]); + set_gicd_chipr_n(multichip_data->base_addrs[i], j, + multichip_data->chip_addrs[i][j], + multichip_data->spi_ids[j].spi_id_min, + multichip_data->spi_ids[j].spi_id_max); + } + } + + /* Initialize the GICD which is marked as routing table owner last */ + set_gicd_dchipr_rt_owner(multichip_data->base_addrs[rt_owner], + rt_owner); +} + /******************************************************************************* * Initialize GIC-600 and GIC-700 Multichip operation. ******************************************************************************/ void gic600_multichip_init(struct gic600_multichip_data *multichip_data) { unsigned int i; - uint32_t gicd_iidr_val = gicd_read_iidr(multichip_data->rt_owner_base); + unsigned int rt_owner = multichip_data->rt_owner; + uint32_t gicd_iidr_val = + gicd_read_iidr(multichip_data->base_addrs[rt_owner]); if ((gicd_iidr_val & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) { gic600_multichip_validate_data(multichip_data); @@ -341,16 +369,16 @@ void gic600_multichip_init(struct gic600_multichip_data *multichip_data) * Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures * that GIC-600 Multichip configuration is done first. */ - if ((gicd_read_ctlr(multichip_data->rt_owner_base) & - (CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT | - CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) { + if ((gicd_read_ctlr(multichip_data->base_addrs[rt_owner]) & + (CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT | + CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) { ERROR("GICD_CTLR group interrupts are either enabled or have " "pending writes.\n"); panic(); } /* Ensure that the routing table owner is in disconnected state */ - if (((read_gicd_chipsr(multichip_data->rt_owner_base) & + if (((read_gicd_chipsr(multichip_data->base_addrs[rt_owner]) & GICD_CHIPSR_RTS_MASK) >> GICD_CHIPSR_RTS_SHIFT) != GICD_CHIPSR_RTS_STATE_DISCONNECTED) { ERROR("GIC-600 routing table owner is not in disconnected " @@ -358,25 +386,34 @@ void gic600_multichip_init(struct gic600_multichip_data *multichip_data) panic(); } - /* Initialize the GICD which is marked as routing table owner first */ - set_gicd_dchipr_rt_owner(multichip_data->rt_owner_base, - multichip_data->rt_owner); + /* If LCA is not enabled */ + if ((read_gicd_cfgid(multichip_data->base_addrs[rt_owner]) & + GICD_CFGID_LCA_BIT) == 0) { + /* + * Initialize the GICD which is marked as routing table + * owner first. + */ + set_gicd_dchipr_rt_owner(multichip_data->base_addrs[rt_owner], + rt_owner); - set_gicd_chipr_n(multichip_data->rt_owner_base, multichip_data->rt_owner, - multichip_data->chip_addrs[multichip_data->rt_owner], - multichip_data-> - spi_ids[multichip_data->rt_owner].spi_id_min, - multichip_data-> - spi_ids[multichip_data->rt_owner].spi_id_max); + set_gicd_chipr_n(multichip_data->base_addrs[rt_owner], rt_owner, + multichip_data->chip_addrs[rt_owner][rt_owner], + multichip_data->spi_ids[rt_owner].spi_id_min, + multichip_data->spi_ids[rt_owner].spi_id_max); - for (i = 0; i < multichip_data->chip_count; i++) { - if (i == multichip_data->rt_owner) - continue; - - set_gicd_chipr_n(multichip_data->rt_owner_base, i, - multichip_data->chip_addrs[i], + for (i = 0; i < multichip_data->chip_count; i++) { + if (i == rt_owner) + continue; + set_gicd_chipr_n( + multichip_data->base_addrs[rt_owner], i, + multichip_data->chip_addrs[rt_owner][i], multichip_data->spi_ids[i].spi_id_min, multichip_data->spi_ids[i].spi_id_max); + } + } else { + /* If LCA is enabled */ + INFO("GIC Local chip addressing is enabled\n"); + gic600_multichip_lca_init(multichip_data); } plat_gic_multichip_data = multichip_data; diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h index fd1cb57d2..33030b3f9 100644 --- a/drivers/arm/gic/v3/gic600_multichip_private.h +++ b/drivers/arm/gic/v3/gic600_multichip_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2023, ARM Limited. All rights reserved. + * Copyright (c) 2019-2024, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,12 +15,14 @@ #define GICD_CHIPSR U(0xC000) #define GICD_DCHIPR U(0xC004) #define GICD_CHIPR U(0xC008) +#define GICD_CFGID U(0xF000) /* GIC600 GICD multichip related masks */ #define GICD_CHIPRx_PUP_BIT BIT_64(1) #define GICD_CHIPRx_SOCKET_STATE BIT_64(0) #define GICD_DCHIPR_PUP_BIT BIT_32(0) #define GICD_CHIPSR_RTS_MASK (BIT_32(4) | BIT_32(5)) +#define GICD_CFGID_LCA_BIT BIT_64(21) /* GIC600 GICD multichip related shifts */ #define GICD_CHIPRx_ADDR_SHIFT 16 @@ -98,6 +100,11 @@ static inline uint32_t read_gicd_chipsr(uintptr_t base) return mmio_read_32(base + GICD_CHIPSR); } +static inline uint64_t read_gicd_cfgid(uintptr_t base) +{ + return mmio_read_64(base + GICD_CFGID); +} + static inline void write_gicd_dchipr(uintptr_t base, uint32_t val) { mmio_write_32(base + GICD_DCHIPR, val); diff --git a/include/drivers/arm/gic600_multichip.h b/include/drivers/arm/gic600_multichip.h index 978d7357c..d0f90278c 100644 --- a/include/drivers/arm/gic600_multichip.h +++ b/include/drivers/arm/gic600_multichip.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited. All rights reserved. + * Copyright (c) 2019-2024, ARM Limited. All rights reserved. * Copyright (c) 2023, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -49,10 +49,10 @@ typedef struct multichip_spi_ids_desc { * value of {0, 0, 0} should be passed. ******************************************************************************/ struct gic600_multichip_data { - uintptr_t rt_owner_base; + uintptr_t base_addrs[GIC600_MAX_MULTICHIP]; unsigned int rt_owner; unsigned int chip_count; - uint64_t chip_addrs[GIC600_MAX_MULTICHIP]; + uint64_t chip_addrs[GIC600_MAX_MULTICHIP][GIC600_MAX_MULTICHIP]; multichip_spi_ids_desc_t spi_ids[GIC600_MAX_MULTICHIP]; }; diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index 27ea7f7dc..d8d60efe8 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -17,6 +17,8 @@ #include "n1sdp_private.h" #include +#define RT_OWNER 0 + /* * Platform information structure stored in SDS. * This structure holds information about platform's DDR @@ -44,12 +46,16 @@ static scmi_channel_plat_info_t n1sdp_scmi_plat_info = { }; static struct gic600_multichip_data n1sdp_multichip_data __init = { - .rt_owner_base = PLAT_ARM_GICD_BASE, - .rt_owner = 0, + .base_addrs = { + PLAT_ARM_GICD_BASE + }, + .rt_owner = RT_OWNER, .chip_count = 1, .chip_addrs = { - PLAT_ARM_GICD_BASE >> 16, - PLAT_ARM_GICD_BASE >> 16 + [RT_OWNER] = { + PLAT_ARM_GICD_BASE >> 16, + PLAT_ARM_GICD_BASE >> 16 + } }, .spi_ids = { {PLAT_ARM_GICD_BASE, 32, 511}, diff --git a/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c index ccabe2293..5cbdd5feb 100644 --- a/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c +++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c @@ -11,6 +11,8 @@ #include +#define RT_OWNER 0 + #if defined(IMAGE_BL31) static const mmap_region_t rdn1edge_dynamic_mmap[] = { NRD_CSS_SHARED_RAM_MMAP(1), @@ -19,12 +21,17 @@ static const mmap_region_t rdn1edge_dynamic_mmap[] = { }; static struct gic600_multichip_data rdn1e1_multichip_data __init = { - .rt_owner_base = PLAT_ARM_GICD_BASE, - .rt_owner = 0, + .base_addrs = { + PLAT_ARM_GICD_BASE + }, + .rt_owner = RT_OWNER, .chip_count = NRD_CHIP_COUNT, .chip_addrs = { - PLAT_ARM_GICD_BASE >> 16, - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16 + [RT_OWNER] = { + PLAT_ARM_GICD_BASE >> 16, + (PLAT_ARM_GICD_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16 + } }, .spi_ids = { {PLAT_ARM_GICD_BASE, diff --git a/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c index b1046d69b..cf820b84a 100644 --- a/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c +++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c @@ -13,6 +13,12 @@ #include #include +#define RT_OWNER 0 +#define A4SID_CHIP_0 0x0 +#define A4SID_CHIP_1 0x1 +#define A4SID_CHIP_2 0x2 +#define A4SID_CHIP_3 0x3 + #if defined(IMAGE_BL31) #if (NRD_PLATFORM_VARIANT == 2) static const mmap_region_t rdn2mc_dynamic_mmap[] = { @@ -33,19 +39,50 @@ static const mmap_region_t rdn2mc_dynamic_mmap[] = { #if (NRD_PLATFORM_VARIANT == 2) static struct gic600_multichip_data rdn2mc_multichip_data __init = { - .rt_owner_base = PLAT_ARM_GICD_BASE, - .rt_owner = 0, - .chip_count = NRD_CHIP_COUNT, - .chip_addrs = { - PLAT_ARM_GICD_BASE >> 16, + .base_addrs = { + PLAT_ARM_GICD_BASE, #if NRD_CHIP_COUNT > 1 - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, + PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1), #endif #if NRD_CHIP_COUNT > 2 - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, + PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2), #endif #if NRD_CHIP_COUNT > 3 - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, + PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3), +#endif + }, + .rt_owner = RT_OWNER, + .chip_count = NRD_CHIP_COUNT, + .chip_addrs = { + { + A4SID_CHIP_0, + A4SID_CHIP_1, + A4SID_CHIP_2, + A4SID_CHIP_3 + }, +#if NRD_CHIP_COUNT > 1 + { + A4SID_CHIP_0, + A4SID_CHIP_1, + A4SID_CHIP_2, + A4SID_CHIP_3 + }, +#endif +#if NRD_CHIP_COUNT > 2 + { + A4SID_CHIP_0, + A4SID_CHIP_1, + A4SID_CHIP_2, + A4SID_CHIP_3 + }, +#endif +#if NRD_CHIP_COUNT > 3 + { + A4SID_CHIP_0, + A4SID_CHIP_1, + A4SID_CHIP_2, + A4SID_CHIP_3 + } #endif }, .spi_ids = { diff --git a/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c index 5713cb9ab..0a40762d5 100644 --- a/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c +++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c @@ -11,6 +11,8 @@ #include +#define RT_OWNER 0 + #if defined(IMAGE_BL31) static const mmap_region_t rdv1mc_dynamic_mmap[] = { NRD_CSS_SHARED_RAM_MMAP(1), @@ -29,18 +31,25 @@ static const mmap_region_t rdv1mc_dynamic_mmap[] = { }; static struct gic600_multichip_data rdv1mc_multichip_data __init = { - .rt_owner_base = PLAT_ARM_GICD_BASE, - .rt_owner = 0, + .base_addrs = { + PLAT_ARM_GICD_BASE + }, + .rt_owner = RT_OWNER, .chip_count = NRD_CHIP_COUNT, .chip_addrs = { - PLAT_ARM_GICD_BASE >> 16, - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, + [RT_OWNER] = { + PLAT_ARM_GICD_BASE >> 16, + (PLAT_ARM_GICD_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, #if (NRD_CHIP_COUNT > 2) - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, + (PLAT_ARM_GICD_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, #endif #if (NRD_CHIP_COUNT > 3) - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, + (PLAT_ARM_GICD_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, #endif + } }, .spi_ids = { {PLAT_ARM_GICD_BASE, diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c index a5d687e82..e32e761d3 100644 --- a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c +++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c @@ -15,6 +15,15 @@ #include #include +#define RT_OWNER 0 + +/* + * Base addr of the frame that allocated by the platform + * intended for remote gic to local gic interrupt + * message communication + */ +#define NRD_RGIC2LGIC_MESSREG_HNI_BASE UL(0x5FFF0000) + #if (NRD_PLATFORM_VARIANT == 2) static const mmap_region_t rdv3mc_dynamic_mmap[] = { #if NRD_CHIP_COUNT > 1 @@ -32,19 +41,62 @@ static const mmap_region_t rdv3mc_dynamic_mmap[] = { }; static struct gic600_multichip_data rdv3mc_multichip_data __init = { - .rt_owner_base = PLAT_ARM_GICD_BASE, - .rt_owner = 0, - .chip_count = NRD_CHIP_COUNT, - .chip_addrs = { - PLAT_ARM_GICD_BASE >> 16, + .base_addrs = { + PLAT_ARM_GICD_BASE, #if NRD_CHIP_COUNT > 1 - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, + PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1), #endif #if NRD_CHIP_COUNT > 2 - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, + PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2), #endif #if NRD_CHIP_COUNT > 3 - (PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, + PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3), +#endif + }, + .rt_owner = RT_OWNER, + .chip_count = NRD_CHIP_COUNT, + .chip_addrs = { + { + NRD_RGIC2LGIC_MESSREG_HNI_BASE >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, + }, +#if NRD_CHIP_COUNT > 1 + { + NRD_RGIC2LGIC_MESSREG_HNI_BASE >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, + }, +#endif +#if NRD_CHIP_COUNT > 2 + { + NRD_RGIC2LGIC_MESSREG_HNI_BASE >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, + }, +#endif +#if NRD_CHIP_COUNT > 3 + { + NRD_RGIC2LGIC_MESSREG_HNI_BASE >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16, + (NRD_RGIC2LGIC_MESSREG_HNI_BASE + + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16, + } #endif }, .spi_ids = {