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