1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2019-2023, Arm Limited. All rights reserved. 3*91f16700Schasinglulu * Copyright (c) 2022-2023, NVIDIA Corporation. All rights reserved. 4*91f16700Schasinglulu * 5*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu /* 9*91f16700Schasinglulu * GIC-600 driver extension for multichip setup 10*91f16700Schasinglulu */ 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include <assert.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu #include <common/debug.h> 15*91f16700Schasinglulu #include <drivers/arm/arm_gicv3_common.h> 16*91f16700Schasinglulu #include <drivers/arm/gic600_multichip.h> 17*91f16700Schasinglulu #include <drivers/arm/gicv3.h> 18*91f16700Schasinglulu 19*91f16700Schasinglulu #include "../common/gic_common_private.h" 20*91f16700Schasinglulu #include "gic600_multichip_private.h" 21*91f16700Schasinglulu 22*91f16700Schasinglulu static struct gic600_multichip_data *plat_gic_multichip_data; 23*91f16700Schasinglulu 24*91f16700Schasinglulu /******************************************************************************* 25*91f16700Schasinglulu * Retrieve the address of the chip owner for a given SPI ID 26*91f16700Schasinglulu ******************************************************************************/ 27*91f16700Schasinglulu uintptr_t gic600_multichip_gicd_base_for_spi(uint32_t spi_id) 28*91f16700Schasinglulu { 29*91f16700Schasinglulu unsigned int i; 30*91f16700Schasinglulu 31*91f16700Schasinglulu /* Find the multichip instance */ 32*91f16700Schasinglulu for (i = 0U; i < GIC600_MAX_MULTICHIP; i++) { 33*91f16700Schasinglulu if ((spi_id <= plat_gic_multichip_data->spi_ids[i].spi_id_max) && 34*91f16700Schasinglulu (spi_id >= plat_gic_multichip_data->spi_ids[i].spi_id_min)) { 35*91f16700Schasinglulu break; 36*91f16700Schasinglulu } 37*91f16700Schasinglulu } 38*91f16700Schasinglulu 39*91f16700Schasinglulu /* Ensure that plat_gic_multichip_data contains valid values */ 40*91f16700Schasinglulu assert(i < GIC600_MAX_MULTICHIP); 41*91f16700Schasinglulu 42*91f16700Schasinglulu return plat_gic_multichip_data->spi_ids[i].gicd_base; 43*91f16700Schasinglulu } 44*91f16700Schasinglulu 45*91f16700Schasinglulu /******************************************************************************* 46*91f16700Schasinglulu * GIC-600 multichip operation related helper functions 47*91f16700Schasinglulu ******************************************************************************/ 48*91f16700Schasinglulu static void gicd_dchipr_wait_for_power_update_progress(uintptr_t base) 49*91f16700Schasinglulu { 50*91f16700Schasinglulu unsigned int retry = GICD_PUP_UPDATE_RETRIES; 51*91f16700Schasinglulu 52*91f16700Schasinglulu while ((read_gicd_dchipr(base) & GICD_DCHIPR_PUP_BIT) != 0U) { 53*91f16700Schasinglulu if (retry-- == 0U) { 54*91f16700Schasinglulu ERROR("GIC-600 connection to Routing Table Owner timed " 55*91f16700Schasinglulu "out\n"); 56*91f16700Schasinglulu panic(); 57*91f16700Schasinglulu } 58*91f16700Schasinglulu } 59*91f16700Schasinglulu } 60*91f16700Schasinglulu 61*91f16700Schasinglulu /******************************************************************************* 62*91f16700Schasinglulu * Sets up the routing table owner. 63*91f16700Schasinglulu ******************************************************************************/ 64*91f16700Schasinglulu static void set_gicd_dchipr_rt_owner(uintptr_t base, unsigned int rt_owner) 65*91f16700Schasinglulu { 66*91f16700Schasinglulu /* 67*91f16700Schasinglulu * Ensure that Group enables in GICD_CTLR are disabled and no pending 68*91f16700Schasinglulu * register writes to GICD_CTLR. 69*91f16700Schasinglulu */ 70*91f16700Schasinglulu if ((gicd_read_ctlr(base) & 71*91f16700Schasinglulu (CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT | 72*91f16700Schasinglulu CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) { 73*91f16700Schasinglulu ERROR("GICD_CTLR group interrupts are either enabled or have " 74*91f16700Schasinglulu "pending writes. Cannot set RT owner.\n"); 75*91f16700Schasinglulu panic(); 76*91f16700Schasinglulu } 77*91f16700Schasinglulu 78*91f16700Schasinglulu /* Poll till PUP is zero before intiating write */ 79*91f16700Schasinglulu gicd_dchipr_wait_for_power_update_progress(base); 80*91f16700Schasinglulu 81*91f16700Schasinglulu write_gicd_dchipr(base, read_gicd_dchipr(base) | 82*91f16700Schasinglulu (rt_owner << GICD_DCHIPR_RT_OWNER_SHIFT)); 83*91f16700Schasinglulu 84*91f16700Schasinglulu /* Poll till PUP is zero to ensure write is complete */ 85*91f16700Schasinglulu gicd_dchipr_wait_for_power_update_progress(base); 86*91f16700Schasinglulu } 87*91f16700Schasinglulu 88*91f16700Schasinglulu /******************************************************************************* 89*91f16700Schasinglulu * Configures the Chip Register to make connections to GICDs on 90*91f16700Schasinglulu * a multichip platform. 91*91f16700Schasinglulu ******************************************************************************/ 92*91f16700Schasinglulu static void set_gicd_chipr_n(uintptr_t base, 93*91f16700Schasinglulu unsigned int chip_id, 94*91f16700Schasinglulu uint64_t chip_addr, 95*91f16700Schasinglulu unsigned int spi_id_min, 96*91f16700Schasinglulu unsigned int spi_id_max) 97*91f16700Schasinglulu { 98*91f16700Schasinglulu unsigned int spi_block_min, spi_blocks; 99*91f16700Schasinglulu unsigned int gicd_iidr_val = gicd_read_iidr(base); 100*91f16700Schasinglulu uint64_t chipr_n_val; 101*91f16700Schasinglulu 102*91f16700Schasinglulu /* 103*91f16700Schasinglulu * Ensure that group enables in GICD_CTLR are disabled and no pending 104*91f16700Schasinglulu * register writes to GICD_CTLR. 105*91f16700Schasinglulu */ 106*91f16700Schasinglulu if ((gicd_read_ctlr(base) & 107*91f16700Schasinglulu (CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT | 108*91f16700Schasinglulu CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) { 109*91f16700Schasinglulu ERROR("GICD_CTLR group interrupts are either enabled or have " 110*91f16700Schasinglulu "pending writes. Cannot set CHIPR register.\n"); 111*91f16700Schasinglulu panic(); 112*91f16700Schasinglulu } 113*91f16700Schasinglulu 114*91f16700Schasinglulu /* 115*91f16700Schasinglulu * spi_id_min and spi_id_max of value 0 is used to intidicate that the 116*91f16700Schasinglulu * chip doesn't own any SPI block. Re-assign min and max values as SPI 117*91f16700Schasinglulu * id starts from 32. 118*91f16700Schasinglulu */ 119*91f16700Schasinglulu if (spi_id_min == 0 && spi_id_max == 0) { 120*91f16700Schasinglulu spi_id_min = GIC600_SPI_ID_MIN; 121*91f16700Schasinglulu spi_id_max = GIC600_SPI_ID_MIN; 122*91f16700Schasinglulu } 123*91f16700Schasinglulu 124*91f16700Schasinglulu switch ((gicd_iidr_val & IIDR_MODEL_MASK)) { 125*91f16700Schasinglulu case IIDR_MODEL_ARM_GIC_600: 126*91f16700Schasinglulu spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min); 127*91f16700Schasinglulu spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max); 128*91f16700Schasinglulu 129*91f16700Schasinglulu chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr, 130*91f16700Schasinglulu spi_block_min, 131*91f16700Schasinglulu spi_blocks); 132*91f16700Schasinglulu break; 133*91f16700Schasinglulu case IIDR_MODEL_ARM_GIC_700: 134*91f16700Schasinglulu /* Calculate the SPI_ID_MIN value for ESPI */ 135*91f16700Schasinglulu if (spi_id_min >= GIC700_ESPI_ID_MIN) { 136*91f16700Schasinglulu spi_block_min = ESPI_BLOCK_MIN_VALUE(spi_id_min); 137*91f16700Schasinglulu spi_block_min += SPI_BLOCKS_VALUE(GIC700_SPI_ID_MIN, 138*91f16700Schasinglulu GIC700_SPI_ID_MAX); 139*91f16700Schasinglulu } else { 140*91f16700Schasinglulu spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min); 141*91f16700Schasinglulu } 142*91f16700Schasinglulu 143*91f16700Schasinglulu /* Calculate the total number of blocks */ 144*91f16700Schasinglulu spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max); 145*91f16700Schasinglulu 146*91f16700Schasinglulu chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr, 147*91f16700Schasinglulu spi_block_min, 148*91f16700Schasinglulu spi_blocks); 149*91f16700Schasinglulu break; 150*91f16700Schasinglulu default: 151*91f16700Schasinglulu ERROR("Unsupported GIC model 0x%x for multichip setup.\n", 152*91f16700Schasinglulu gicd_iidr_val); 153*91f16700Schasinglulu panic(); 154*91f16700Schasinglulu break; 155*91f16700Schasinglulu } 156*91f16700Schasinglulu chipr_n_val |= GICD_CHIPRx_SOCKET_STATE; 157*91f16700Schasinglulu 158*91f16700Schasinglulu /* 159*91f16700Schasinglulu * Wait for DCHIPR.PUP to be zero before commencing writes to 160*91f16700Schasinglulu * GICD_CHIPRx. 161*91f16700Schasinglulu */ 162*91f16700Schasinglulu gicd_dchipr_wait_for_power_update_progress(base); 163*91f16700Schasinglulu 164*91f16700Schasinglulu /* 165*91f16700Schasinglulu * Assign chip addr, spi min block, number of spi blocks and bring chip 166*91f16700Schasinglulu * online by setting SocketState. 167*91f16700Schasinglulu */ 168*91f16700Schasinglulu write_gicd_chipr_n(base, chip_id, chipr_n_val); 169*91f16700Schasinglulu 170*91f16700Schasinglulu /* 171*91f16700Schasinglulu * Poll until DCHIP.PUP is zero to verify connection to rt_owner chip 172*91f16700Schasinglulu * is complete. 173*91f16700Schasinglulu */ 174*91f16700Schasinglulu gicd_dchipr_wait_for_power_update_progress(base); 175*91f16700Schasinglulu 176*91f16700Schasinglulu /* 177*91f16700Schasinglulu * Ensure that write to GICD_CHIPRx is successful and the chip_n came 178*91f16700Schasinglulu * online. 179*91f16700Schasinglulu */ 180*91f16700Schasinglulu if (read_gicd_chipr_n(base, chip_id) != chipr_n_val) { 181*91f16700Schasinglulu ERROR("GICD_CHIPR%u write failed\n", chip_id); 182*91f16700Schasinglulu panic(); 183*91f16700Schasinglulu } 184*91f16700Schasinglulu 185*91f16700Schasinglulu /* Ensure that chip is in consistent state */ 186*91f16700Schasinglulu if (((read_gicd_chipsr(base) & GICD_CHIPSR_RTS_MASK) >> 187*91f16700Schasinglulu GICD_CHIPSR_RTS_SHIFT) != 188*91f16700Schasinglulu GICD_CHIPSR_RTS_STATE_CONSISTENT) { 189*91f16700Schasinglulu ERROR("Chip %u routing table is not in consistent state\n", 190*91f16700Schasinglulu chip_id); 191*91f16700Schasinglulu panic(); 192*91f16700Schasinglulu } 193*91f16700Schasinglulu } 194*91f16700Schasinglulu 195*91f16700Schasinglulu /******************************************************************************* 196*91f16700Schasinglulu * Validates the GIC-600 Multichip data structure passed by the platform. 197*91f16700Schasinglulu ******************************************************************************/ 198*91f16700Schasinglulu static void gic600_multichip_validate_data( 199*91f16700Schasinglulu struct gic600_multichip_data *multichip_data) 200*91f16700Schasinglulu { 201*91f16700Schasinglulu unsigned int i, spi_id_min, spi_id_max, blocks_of_32; 202*91f16700Schasinglulu unsigned int multichip_spi_blocks = 0; 203*91f16700Schasinglulu 204*91f16700Schasinglulu assert(multichip_data != NULL); 205*91f16700Schasinglulu 206*91f16700Schasinglulu if (multichip_data->chip_count > GIC600_MAX_MULTICHIP) { 207*91f16700Schasinglulu ERROR("GIC-600 Multichip count should not exceed %d\n", 208*91f16700Schasinglulu GIC600_MAX_MULTICHIP); 209*91f16700Schasinglulu panic(); 210*91f16700Schasinglulu } 211*91f16700Schasinglulu 212*91f16700Schasinglulu for (i = 0U; i < multichip_data->chip_count; i++) { 213*91f16700Schasinglulu spi_id_min = multichip_data->spi_ids[i].spi_id_min; 214*91f16700Schasinglulu spi_id_max = multichip_data->spi_ids[i].spi_id_max; 215*91f16700Schasinglulu 216*91f16700Schasinglulu if ((spi_id_min != 0U) || (spi_id_max != 0U)) { 217*91f16700Schasinglulu 218*91f16700Schasinglulu /* SPI IDs range check */ 219*91f16700Schasinglulu if (!(spi_id_min >= GIC600_SPI_ID_MIN) || 220*91f16700Schasinglulu !(spi_id_max <= GIC600_SPI_ID_MAX) || 221*91f16700Schasinglulu !(spi_id_min <= spi_id_max) || 222*91f16700Schasinglulu !((spi_id_max - spi_id_min + 1) % 32 == 0)) { 223*91f16700Schasinglulu ERROR("Invalid SPI IDs {%u, %u} passed for " 224*91f16700Schasinglulu "Chip %u\n", spi_id_min, 225*91f16700Schasinglulu spi_id_max, i); 226*91f16700Schasinglulu panic(); 227*91f16700Schasinglulu } 228*91f16700Schasinglulu 229*91f16700Schasinglulu /* SPI IDs overlap check */ 230*91f16700Schasinglulu blocks_of_32 = BLOCKS_OF_32(spi_id_min, spi_id_max); 231*91f16700Schasinglulu if ((multichip_spi_blocks & blocks_of_32) != 0) { 232*91f16700Schasinglulu ERROR("SPI IDs of Chip %u overlapping\n", i); 233*91f16700Schasinglulu panic(); 234*91f16700Schasinglulu } 235*91f16700Schasinglulu multichip_spi_blocks |= blocks_of_32; 236*91f16700Schasinglulu } 237*91f16700Schasinglulu } 238*91f16700Schasinglulu } 239*91f16700Schasinglulu 240*91f16700Schasinglulu /******************************************************************************* 241*91f16700Schasinglulu * Validates the GIC-700 Multichip data structure passed by the platform. 242*91f16700Schasinglulu ******************************************************************************/ 243*91f16700Schasinglulu static void gic700_multichip_validate_data( 244*91f16700Schasinglulu struct gic600_multichip_data *multichip_data) 245*91f16700Schasinglulu { 246*91f16700Schasinglulu unsigned int i, spi_id_min, spi_id_max, blocks_of_32; 247*91f16700Schasinglulu unsigned int multichip_spi_blocks = 0U, multichip_espi_blocks = 0U; 248*91f16700Schasinglulu 249*91f16700Schasinglulu assert(multichip_data != NULL); 250*91f16700Schasinglulu 251*91f16700Schasinglulu if (multichip_data->chip_count > GIC600_MAX_MULTICHIP) { 252*91f16700Schasinglulu ERROR("GIC-700 Multichip count (%u) should not exceed %u\n", 253*91f16700Schasinglulu multichip_data->chip_count, GIC600_MAX_MULTICHIP); 254*91f16700Schasinglulu panic(); 255*91f16700Schasinglulu } 256*91f16700Schasinglulu 257*91f16700Schasinglulu for (i = 0U; i < multichip_data->chip_count; i++) { 258*91f16700Schasinglulu spi_id_min = multichip_data->spi_ids[i].spi_id_min; 259*91f16700Schasinglulu spi_id_max = multichip_data->spi_ids[i].spi_id_max; 260*91f16700Schasinglulu 261*91f16700Schasinglulu if ((spi_id_min == 0U) || (spi_id_max == 0U)) { 262*91f16700Schasinglulu continue; 263*91f16700Schasinglulu } 264*91f16700Schasinglulu 265*91f16700Schasinglulu /* MIN SPI ID check */ 266*91f16700Schasinglulu if ((spi_id_min < GIC700_SPI_ID_MIN) || 267*91f16700Schasinglulu ((spi_id_min >= GIC700_SPI_ID_MAX) && 268*91f16700Schasinglulu (spi_id_min < GIC700_ESPI_ID_MIN))) { 269*91f16700Schasinglulu ERROR("Invalid MIN SPI ID {%u} passed for " 270*91f16700Schasinglulu "Chip %u\n", spi_id_min, i); 271*91f16700Schasinglulu panic(); 272*91f16700Schasinglulu } 273*91f16700Schasinglulu 274*91f16700Schasinglulu if ((spi_id_min > spi_id_max) || 275*91f16700Schasinglulu ((spi_id_max - spi_id_min + 1) % 32 != 0)) { 276*91f16700Schasinglulu ERROR("Unaligned SPI IDs {%u, %u} passed for " 277*91f16700Schasinglulu "Chip %u\n", spi_id_min, 278*91f16700Schasinglulu spi_id_max, i); 279*91f16700Schasinglulu panic(); 280*91f16700Schasinglulu } 281*91f16700Schasinglulu 282*91f16700Schasinglulu /* ESPI IDs range check */ 283*91f16700Schasinglulu if ((spi_id_min >= GIC700_ESPI_ID_MIN) && 284*91f16700Schasinglulu (spi_id_max > GIC700_ESPI_ID_MAX)) { 285*91f16700Schasinglulu ERROR("Invalid ESPI IDs {%u, %u} passed for " 286*91f16700Schasinglulu "Chip %u\n", spi_id_min, 287*91f16700Schasinglulu spi_id_max, i); 288*91f16700Schasinglulu panic(); 289*91f16700Schasinglulu 290*91f16700Schasinglulu } 291*91f16700Schasinglulu 292*91f16700Schasinglulu /* SPI IDs range check */ 293*91f16700Schasinglulu if (((spi_id_min < GIC700_SPI_ID_MAX) && 294*91f16700Schasinglulu (spi_id_max > GIC700_SPI_ID_MAX))) { 295*91f16700Schasinglulu ERROR("Invalid SPI IDs {%u, %u} passed for " 296*91f16700Schasinglulu "Chip %u\n", spi_id_min, 297*91f16700Schasinglulu spi_id_max, i); 298*91f16700Schasinglulu panic(); 299*91f16700Schasinglulu } 300*91f16700Schasinglulu 301*91f16700Schasinglulu /* SPI IDs overlap check */ 302*91f16700Schasinglulu if (spi_id_max < GIC700_SPI_ID_MAX) { 303*91f16700Schasinglulu blocks_of_32 = BLOCKS_OF_32(spi_id_min, spi_id_max); 304*91f16700Schasinglulu if ((multichip_spi_blocks & blocks_of_32) != 0) { 305*91f16700Schasinglulu ERROR("SPI IDs of Chip %u overlapping\n", i); 306*91f16700Schasinglulu panic(); 307*91f16700Schasinglulu } 308*91f16700Schasinglulu multichip_spi_blocks |= blocks_of_32; 309*91f16700Schasinglulu } 310*91f16700Schasinglulu 311*91f16700Schasinglulu /* ESPI IDs overlap check */ 312*91f16700Schasinglulu if (spi_id_max > GIC700_ESPI_ID_MIN) { 313*91f16700Schasinglulu blocks_of_32 = BLOCKS_OF_32(spi_id_min - GIC700_ESPI_ID_MIN, 314*91f16700Schasinglulu spi_id_max - GIC700_ESPI_ID_MIN); 315*91f16700Schasinglulu if ((multichip_espi_blocks & blocks_of_32) != 0) { 316*91f16700Schasinglulu ERROR("SPI IDs of Chip %u overlapping\n", i); 317*91f16700Schasinglulu panic(); 318*91f16700Schasinglulu } 319*91f16700Schasinglulu multichip_espi_blocks |= blocks_of_32; 320*91f16700Schasinglulu } 321*91f16700Schasinglulu } 322*91f16700Schasinglulu } 323*91f16700Schasinglulu 324*91f16700Schasinglulu /******************************************************************************* 325*91f16700Schasinglulu * Initialize GIC-600 and GIC-700 Multichip operation. 326*91f16700Schasinglulu ******************************************************************************/ 327*91f16700Schasinglulu void gic600_multichip_init(struct gic600_multichip_data *multichip_data) 328*91f16700Schasinglulu { 329*91f16700Schasinglulu unsigned int i; 330*91f16700Schasinglulu uint32_t gicd_iidr_val = gicd_read_iidr(multichip_data->rt_owner_base); 331*91f16700Schasinglulu 332*91f16700Schasinglulu if ((gicd_iidr_val & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) { 333*91f16700Schasinglulu gic600_multichip_validate_data(multichip_data); 334*91f16700Schasinglulu } 335*91f16700Schasinglulu 336*91f16700Schasinglulu if ((gicd_iidr_val & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700) { 337*91f16700Schasinglulu gic700_multichip_validate_data(multichip_data); 338*91f16700Schasinglulu } 339*91f16700Schasinglulu 340*91f16700Schasinglulu /* 341*91f16700Schasinglulu * Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures 342*91f16700Schasinglulu * that GIC-600 Multichip configuration is done first. 343*91f16700Schasinglulu */ 344*91f16700Schasinglulu if ((gicd_read_ctlr(multichip_data->rt_owner_base) & 345*91f16700Schasinglulu (CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT | 346*91f16700Schasinglulu CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) { 347*91f16700Schasinglulu ERROR("GICD_CTLR group interrupts are either enabled or have " 348*91f16700Schasinglulu "pending writes.\n"); 349*91f16700Schasinglulu panic(); 350*91f16700Schasinglulu } 351*91f16700Schasinglulu 352*91f16700Schasinglulu /* Ensure that the routing table owner is in disconnected state */ 353*91f16700Schasinglulu if (((read_gicd_chipsr(multichip_data->rt_owner_base) & 354*91f16700Schasinglulu GICD_CHIPSR_RTS_MASK) >> GICD_CHIPSR_RTS_SHIFT) != 355*91f16700Schasinglulu GICD_CHIPSR_RTS_STATE_DISCONNECTED) { 356*91f16700Schasinglulu ERROR("GIC-600 routing table owner is not in disconnected " 357*91f16700Schasinglulu "state to begin multichip configuration\n"); 358*91f16700Schasinglulu panic(); 359*91f16700Schasinglulu } 360*91f16700Schasinglulu 361*91f16700Schasinglulu /* Initialize the GICD which is marked as routing table owner first */ 362*91f16700Schasinglulu set_gicd_dchipr_rt_owner(multichip_data->rt_owner_base, 363*91f16700Schasinglulu multichip_data->rt_owner); 364*91f16700Schasinglulu 365*91f16700Schasinglulu set_gicd_chipr_n(multichip_data->rt_owner_base, multichip_data->rt_owner, 366*91f16700Schasinglulu multichip_data->chip_addrs[multichip_data->rt_owner], 367*91f16700Schasinglulu multichip_data-> 368*91f16700Schasinglulu spi_ids[multichip_data->rt_owner].spi_id_min, 369*91f16700Schasinglulu multichip_data-> 370*91f16700Schasinglulu spi_ids[multichip_data->rt_owner].spi_id_max); 371*91f16700Schasinglulu 372*91f16700Schasinglulu for (i = 0; i < multichip_data->chip_count; i++) { 373*91f16700Schasinglulu if (i == multichip_data->rt_owner) 374*91f16700Schasinglulu continue; 375*91f16700Schasinglulu 376*91f16700Schasinglulu set_gicd_chipr_n(multichip_data->rt_owner_base, i, 377*91f16700Schasinglulu multichip_data->chip_addrs[i], 378*91f16700Schasinglulu multichip_data->spi_ids[i].spi_id_min, 379*91f16700Schasinglulu multichip_data->spi_ids[i].spi_id_max); 380*91f16700Schasinglulu } 381*91f16700Schasinglulu 382*91f16700Schasinglulu plat_gic_multichip_data = multichip_data; 383*91f16700Schasinglulu } 384*91f16700Schasinglulu 385*91f16700Schasinglulu /******************************************************************************* 386*91f16700Schasinglulu * Allow a way to query the status of the GIC600 multichip driver 387*91f16700Schasinglulu ******************************************************************************/ 388*91f16700Schasinglulu bool gic600_multichip_is_initialized(void) 389*91f16700Schasinglulu { 390*91f16700Schasinglulu return (plat_gic_multichip_data != NULL); 391*91f16700Schasinglulu } 392