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  ******************************************************************************/
gicd_dchipr_wait_for_power_update_progress(uintptr_t base)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  ******************************************************************************/
set_gicd_dchipr_rt_owner(uintptr_t base,unsigned int rt_owner)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  ******************************************************************************/
set_gicd_chipr_n(uintptr_t base,unsigned int chip_id,uint64_t chip_addr,unsigned int spi_id_min,unsigned int spi_id_max)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  ******************************************************************************/
gic600_multichip_validate_data(struct gic600_multichip_data * multichip_data)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  ******************************************************************************/
gic600_multichip_init(struct gic600_multichip_data * multichip_data)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