Merge changes from topic "jw/gic-lca-support" into integration

* changes:
  fix(rdn2): add LCA multichip data for RD-N2-Cfg2
  fix(rdv3): add LCA multichip data for RD-V3-Cfg2
  feat(gic): add support for local chip addressing
This commit is contained in:
Manish V Badarkhe 2025-02-20 17:17:35 +01:00 committed by TrustedFirmware Code Review
commit 99b2ae269e
8 changed files with 209 additions and 54 deletions

View file

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

View file

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

View file

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

View file

@ -17,6 +17,8 @@
#include "n1sdp_private.h"
#include <platform_def.h>
#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},

View file

@ -11,6 +11,8 @@
#include <nrd_plat.h>
#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,

View file

@ -13,6 +13,12 @@
#include <nrd_plat.h>
#include <rdn2_ras.h>
#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 = {

View file

@ -11,6 +11,8 @@
#include <nrd_plat.h>
#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,

View file

@ -15,6 +15,15 @@
#include <nrd_variant.h>
#include <rdv3_rse_comms.h>
#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 = {