xref: /arm-trusted-firmware/drivers/arm/gic/v3/gic600_multichip.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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