xref: /rk3399_ARM-atf/drivers/arm/gic/v3/gic600_multichip.c (revision 042d710d1d917357c5142b340c79978264d3afb1)
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