1 /* 2 * Copyright (c) 2019, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /* 8 * GIC-600 driver extension for multichip setup 9 */ 10 11 #include <assert.h> 12 13 #include <common/debug.h> 14 #include <drivers/arm/arm_gicv3_common.h> 15 #include <drivers/arm/gic600_multichip.h> 16 #include <drivers/arm/gicv3.h> 17 18 #include "../common/gic_common_private.h" 19 #include "gic600_multichip_private.h" 20 21 #warning "GIC-600 Multichip driver is currently experimental and the API may change in future." 22 23 /******************************************************************************* 24 * GIC-600 multichip operation related helper functions 25 ******************************************************************************/ 26 static void gicd_dchipr_wait_for_power_update_progress(uintptr_t base) 27 { 28 unsigned int retry = GICD_PUP_UPDATE_RETRIES; 29 30 while ((read_gicd_dchipr(base) & GICD_DCHIPR_PUP_BIT) != 0U) { 31 if (retry-- == 0) { 32 ERROR("GIC-600 connection to Routing Table Owner timed " 33 "out\n"); 34 panic(); 35 } 36 } 37 } 38 39 /******************************************************************************* 40 * Sets up the routing table owner. 41 ******************************************************************************/ 42 static void set_gicd_dchipr_rt_owner(uintptr_t base, unsigned int rt_owner) 43 { 44 /* 45 * Ensure that Group enables in GICD_CTLR are disabled and no pending 46 * register writes to GICD_CTLR. 47 */ 48 if ((gicd_read_ctlr(base) & 49 (CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT | 50 CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) { 51 ERROR("GICD_CTLR group interrupts are either enabled or have " 52 "pending writes. Cannot set RT owner.\n"); 53 panic(); 54 } 55 56 /* Poll till PUP is zero before intiating write */ 57 gicd_dchipr_wait_for_power_update_progress(base); 58 59 write_gicd_dchipr(base, read_gicd_dchipr(base) | 60 (rt_owner << GICD_DCHIPR_RT_OWNER_SHIFT)); 61 62 /* Poll till PUP is zero to ensure write is complete */ 63 gicd_dchipr_wait_for_power_update_progress(base); 64 } 65 66 /******************************************************************************* 67 * Configures the Chip Register to make connections to GICDs on 68 * a multichip platform. 69 ******************************************************************************/ 70 static void set_gicd_chipr_n(uintptr_t base, 71 unsigned int chip_id, 72 uint64_t chip_addr, 73 unsigned int spi_id_min, 74 unsigned int spi_id_max) 75 { 76 unsigned int spi_block_min, spi_blocks; 77 unsigned int gicd_iidr_val = gicd_read_iidr(base); 78 uint64_t chipr_n_val; 79 80 /* 81 * Ensure that group enables in GICD_CTLR are disabled and no pending 82 * register writes to GICD_CTLR. 83 */ 84 if ((gicd_read_ctlr(base) & 85 (CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT | 86 CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) { 87 ERROR("GICD_CTLR group interrupts are either enabled or have " 88 "pending writes. Cannot set CHIPR register.\n"); 89 panic(); 90 } 91 92 /* 93 * spi_id_min and spi_id_max of value 0 is used to intidicate that the 94 * chip doesn't own any SPI block. Re-assign min and max values as SPI 95 * id starts from 32. 96 */ 97 if (spi_id_min == 0 && spi_id_max == 0) { 98 spi_id_min = GIC600_SPI_ID_MIN; 99 spi_id_max = GIC600_SPI_ID_MIN; 100 } 101 102 spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min); 103 spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max); 104 105 switch ((gicd_iidr_val & IIDR_MODEL_MASK)) { 106 case IIDR_MODEL_ARM_GIC_600: 107 chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr, 108 spi_block_min, 109 spi_blocks); 110 break; 111 case IIDR_MODEL_ARM_GIC_700: 112 chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr, 113 spi_block_min, 114 spi_blocks); 115 break; 116 default: 117 ERROR("Unsupported GIC model 0x%x for multichip setup.\n", 118 gicd_iidr_val); 119 panic(); 120 break; 121 } 122 chipr_n_val |= GICD_CHIPRx_SOCKET_STATE; 123 124 /* 125 * Wait for DCHIPR.PUP to be zero before commencing writes to 126 * GICD_CHIPRx. 127 */ 128 gicd_dchipr_wait_for_power_update_progress(base); 129 130 /* 131 * Assign chip addr, spi min block, number of spi blocks and bring chip 132 * online by setting SocketState. 133 */ 134 write_gicd_chipr_n(base, chip_id, chipr_n_val); 135 136 /* 137 * Poll until DCHIP.PUP is zero to verify connection to rt_owner chip 138 * is complete. 139 */ 140 gicd_dchipr_wait_for_power_update_progress(base); 141 142 /* 143 * Ensure that write to GICD_CHIPRx is successful and the chip_n came 144 * online. 145 */ 146 if (read_gicd_chipr_n(base, chip_id) != chipr_n_val) { 147 ERROR("GICD_CHIPR%u write failed\n", chip_id); 148 panic(); 149 } 150 151 /* Ensure that chip is in consistent state */ 152 if (((read_gicd_chipsr(base) & GICD_CHIPSR_RTS_MASK) >> 153 GICD_CHIPSR_RTS_SHIFT) != 154 GICD_CHIPSR_RTS_STATE_CONSISTENT) { 155 ERROR("Chip %u routing table is not in consistent state\n", 156 chip_id); 157 panic(); 158 } 159 } 160 161 /******************************************************************************* 162 * Validates the GIC-600 Multichip data structure passed by the platform. 163 ******************************************************************************/ 164 static void gic600_multichip_validate_data( 165 struct gic600_multichip_data *multichip_data) 166 { 167 unsigned int i, spi_id_min, spi_id_max, blocks_of_32; 168 unsigned int multichip_spi_blocks = 0; 169 170 assert(multichip_data != NULL); 171 172 if (multichip_data->chip_count > GIC600_MAX_MULTICHIP) { 173 ERROR("GIC-600 Multichip count should not exceed %d\n", 174 GIC600_MAX_MULTICHIP); 175 panic(); 176 } 177 178 for (i = 0; i < multichip_data->chip_count; i++) { 179 spi_id_min = multichip_data->spi_ids[i][SPI_MIN_INDEX]; 180 spi_id_max = multichip_data->spi_ids[i][SPI_MAX_INDEX]; 181 182 if ((spi_id_min != 0) || (spi_id_max != 0)) { 183 184 /* SPI IDs range check */ 185 if (!(spi_id_min >= GIC600_SPI_ID_MIN) || 186 !(spi_id_max < GIC600_SPI_ID_MAX) || 187 !(spi_id_min <= spi_id_max) || 188 !((spi_id_max - spi_id_min + 1) % 32 == 0)) { 189 ERROR("Invalid SPI IDs {%u, %u} passed for " 190 "Chip %u\n", spi_id_min, 191 spi_id_max, i); 192 panic(); 193 } 194 195 /* SPI IDs overlap check */ 196 blocks_of_32 = BLOCKS_OF_32(spi_id_min, spi_id_max); 197 if ((multichip_spi_blocks & blocks_of_32) != 0) { 198 ERROR("SPI IDs of Chip %u overlapping\n", i); 199 panic(); 200 } 201 multichip_spi_blocks |= blocks_of_32; 202 } 203 } 204 } 205 206 /******************************************************************************* 207 * Intialize GIC-600 Multichip operation. 208 ******************************************************************************/ 209 void gic600_multichip_init(struct gic600_multichip_data *multichip_data) 210 { 211 unsigned int i; 212 213 gic600_multichip_validate_data(multichip_data); 214 215 INFO("GIC-600 Multichip driver is experimental\n"); 216 217 /* 218 * Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures 219 * that GIC-600 Multichip configuration is done first. 220 */ 221 if ((gicd_read_ctlr(multichip_data->rt_owner_base) & 222 (CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT | 223 CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) { 224 ERROR("GICD_CTLR group interrupts are either enabled or have " 225 "pending writes.\n"); 226 panic(); 227 } 228 229 /* Ensure that the routing table owner is in disconnected state */ 230 if (((read_gicd_chipsr(multichip_data->rt_owner_base) & 231 GICD_CHIPSR_RTS_MASK) >> GICD_CHIPSR_RTS_SHIFT) != 232 GICD_CHIPSR_RTS_STATE_DISCONNECTED) { 233 ERROR("GIC-600 routing table owner is not in disconnected " 234 "state to begin multichip configuration\n"); 235 panic(); 236 } 237 238 /* Initialize the GICD which is marked as routing table owner first */ 239 set_gicd_dchipr_rt_owner(multichip_data->rt_owner_base, 240 multichip_data->rt_owner); 241 242 set_gicd_chipr_n(multichip_data->rt_owner_base, multichip_data->rt_owner, 243 multichip_data->chip_addrs[multichip_data->rt_owner], 244 multichip_data-> 245 spi_ids[multichip_data->rt_owner][SPI_MIN_INDEX], 246 multichip_data-> 247 spi_ids[multichip_data->rt_owner][SPI_MAX_INDEX]); 248 249 for (i = 0; i < multichip_data->chip_count; i++) { 250 if (i == multichip_data->rt_owner) 251 continue; 252 253 set_gicd_chipr_n(multichip_data->rt_owner_base, i, 254 multichip_data->chip_addrs[i], 255 multichip_data->spi_ids[i][SPI_MIN_INDEX], 256 multichip_data->spi_ids[i][SPI_MAX_INDEX]); 257 } 258 } 259