1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "qemu/osdep.h"
28#include "hw/sysbus.h"
29#include "hw/register.h"
30#include "qemu/bitops.h"
31#include "qemu/log.h"
32#include "qapi/error.h"
33#include "migration/vmstate.h"
34#include "hw/qdev-properties.h"
35
36#include "hw/fdt_generic_util.h"
37
38#ifndef XILINX_VERSAL_RPU_ERR_DEBUG
39#define XILINX_VERSAL_RPU_ERR_DEBUG 0
40#endif
41
42#define TYPE_XILINX_VERSAL_RPU "xlnx.versal-rpu"
43
44#define XILINX_VERSAL_RPU(obj) \
45 OBJECT_CHECK(RPU, (obj), TYPE_XILINX_VERSAL_RPU)
46
47#define DPRINTF(...) do { \
48 if (XILINX_VERSAL_RPU_ERR_DEBUG) { \
49 qemu_log("%s: ", __func__); \
50 qemu_log(__VA_ARGS__); \
51 } \
52 } while (0)
53
54REG32(RPU_GLBL_CNTL, 0x0)
55 FIELD(RPU_GLBL_CNTL, GIC_AXPROT, 10, 1)
56 FIELD(RPU_GLBL_CNTL, TCM_CLK_CNTL, 8, 1)
57 FIELD(RPU_GLBL_CNTL, TCM_WAIT, 7, 1)
58 FIELD(RPU_GLBL_CNTL, TCM_COMB, 6, 1)
59 FIELD(RPU_GLBL_CNTL, TEINIT, 5, 1)
60 FIELD(RPU_GLBL_CNTL, SLCLAMP, 4, 1)
61 FIELD(RPU_GLBL_CNTL, SLSPLIT, 3, 1)
62 FIELD(RPU_GLBL_CNTL, DBGNOCLKSTOP, 2, 1)
63 FIELD(RPU_GLBL_CNTL, CFGIE, 1, 1)
64 FIELD(RPU_GLBL_CNTL, CFGEE, 0, 1)
65REG32(RPU_GLBL_STATUS, 0x4)
66 FIELD(RPU_GLBL_STATUS, DBGNOPWRDWN, 0, 1)
67REG32(RPU_ERR_CNTL, 0x8)
68 FIELD(RPU_ERR_CNTL, APB_ERR_RES, 0, 1)
69REG32(RPU_ERR_INJ, 0x20)
70 FIELD(RPU_ERR_INJ, DCCMINP2, 8, 8)
71 FIELD(RPU_ERR_INJ, DCCMINP, 0, 8)
72REG32(RPU_CCF_MASK, 0x24)
73 FIELD(RPU_CCF_MASK, TEST_MBIST_MODE, 7, 1)
74 FIELD(RPU_CCF_MASK, TEST_SCAN_MODE_LP, 6, 1)
75 FIELD(RPU_CCF_MASK, TEST_SCAN_MODE, 5, 1)
76 FIELD(RPU_CCF_MASK, ISO, 4, 1)
77 FIELD(RPU_CCF_MASK, PGE, 3, 1)
78 FIELD(RPU_CCF_MASK, R50_DBG_RST, 2, 1)
79 FIELD(RPU_CCF_MASK, R50_RST, 1, 1)
80 FIELD(RPU_CCF_MASK, PGE_RST, 0, 1)
81REG32(RPU_INTR_0, 0x28)
82REG32(RPU_INTR_1, 0x2c)
83REG32(RPU_INTR_2, 0x30)
84REG32(RPU_INTR_3, 0x34)
85REG32(RPU_INTR_4, 0x38)
86REG32(RPU_INTR_MASK_0, 0x40)
87REG32(RPU_INTR_MASK_1, 0x44)
88REG32(RPU_INTR_MASK_2, 0x48)
89REG32(RPU_INTR_MASK_3, 0x4c)
90REG32(RPU_INTR_MASK_4, 0x50)
91REG32(RPU_CCF_VAL, 0x54)
92 FIELD(RPU_CCF_VAL, TEST_MBIST_MODE, 7, 1)
93 FIELD(RPU_CCF_VAL, TEST_SCAN_MODE_LP, 6, 1)
94 FIELD(RPU_CCF_VAL, TEST_SCAN_MODE, 5, 1)
95 FIELD(RPU_CCF_VAL, ISO, 4, 1)
96 FIELD(RPU_CCF_VAL, PGE, 3, 1)
97 FIELD(RPU_CCF_VAL, R50_DBG_RST, 2, 1)
98 FIELD(RPU_CCF_VAL, R50_RST, 1, 1)
99 FIELD(RPU_CCF_VAL, PGE_RST, 0, 1)
100REG32(RPU_SAFETY_CHK, 0xf0)
101REG32(RPU_0_CFG, 0x100)
102 FIELD(RPU_0_CFG, CFGNMFI0, 3, 1)
103 FIELD(RPU_0_CFG, VINITHI, 2, 1)
104 FIELD(RPU_0_CFG, COHERENT, 1, 1)
105 FIELD(RPU_0_CFG, NCPUHALT, 0, 1)
106REG32(RPU_0_STATUS, 0x104)
107 FIELD(RPU_0_STATUS, NVALRESET, 5, 1)
108 FIELD(RPU_0_STATUS, NVALIRQ, 4, 1)
109 FIELD(RPU_0_STATUS, NVALFIQ, 3, 1)
110 FIELD(RPU_0_STATUS, NWFIPIPESTOPPED, 2, 1)
111 FIELD(RPU_0_STATUS, NWFEPIPESTOPPED, 1, 1)
112 FIELD(RPU_0_STATUS, NCLKSTOPPED, 0, 1)
113REG32(RPU_0_PWRDWN, 0x108)
114 FIELD(RPU_0_PWRDWN, EN, 0, 1)
115REG32(RPU_0_ISR, 0x114)
116 FIELD(RPU_0_ISR, FPUFC, 24, 1)
117 FIELD(RPU_0_ISR, FPOFC, 23, 1)
118 FIELD(RPU_0_ISR, FPIXC, 22, 1)
119 FIELD(RPU_0_ISR, FPIOC, 21, 1)
120 FIELD(RPU_0_ISR, FPIDC, 20, 1)
121 FIELD(RPU_0_ISR, FPDZC, 19, 1)
122 FIELD(RPU_0_ISR, TCM_ASLV_CE, 18, 1)
123 FIELD(RPU_0_ISR, TCM_ASLV_FAT, 17, 1)
124 FIELD(RPU_0_ISR, TCM_LST_CE, 16, 1)
125 FIELD(RPU_0_ISR, TCM_PREFETCH_CE, 15, 1)
126 FIELD(RPU_0_ISR, B1TCM_CE, 14, 1)
127 FIELD(RPU_0_ISR, B0TCM_CE, 13, 1)
128 FIELD(RPU_0_ISR, ATCM_CE, 12, 1)
129 FIELD(RPU_0_ISR, B1TCM_UE, 11, 1)
130 FIELD(RPU_0_ISR, B0TCM_UE, 10, 1)
131 FIELD(RPU_0_ISR, ATCM_UE, 9, 1)
132 FIELD(RPU_0_ISR, DTAG_DIRTY_FAT, 8, 1)
133 FIELD(RPU_0_ISR, DDATA_FAT, 7, 1)
134 FIELD(RPU_0_ISR, TCM_LST_FAT, 6, 1)
135 FIELD(RPU_0_ISR, TCM_PREFETCH_FAT, 5, 1)
136 FIELD(RPU_0_ISR, DDATA_CE, 4, 1)
137 FIELD(RPU_0_ISR, DTAG_DIRTY_CE, 3, 1)
138 FIELD(RPU_0_ISR, IDATA_CE, 2, 1)
139 FIELD(RPU_0_ISR, ITAG_CE, 1, 1)
140 FIELD(RPU_0_ISR, APB_ERR, 0, 1)
141REG32(RPU_0_IMR, 0x118)
142 FIELD(RPU_0_IMR, FPUFC, 24, 1)
143 FIELD(RPU_0_IMR, FPOFC, 23, 1)
144 FIELD(RPU_0_IMR, FPIXC, 22, 1)
145 FIELD(RPU_0_IMR, FPIOC, 21, 1)
146 FIELD(RPU_0_IMR, FPIDC, 20, 1)
147 FIELD(RPU_0_IMR, FPDZC, 19, 1)
148 FIELD(RPU_0_IMR, TCM_ASLV_CE, 18, 1)
149 FIELD(RPU_0_IMR, TCM_ASLV_FAT, 17, 1)
150 FIELD(RPU_0_IMR, TCM_LST_CE, 16, 1)
151 FIELD(RPU_0_IMR, TCM_PREFETCH_CE, 15, 1)
152 FIELD(RPU_0_IMR, B1TCM_CE, 14, 1)
153 FIELD(RPU_0_IMR, B0TCM_CE, 13, 1)
154 FIELD(RPU_0_IMR, ATCM_CE, 12, 1)
155 FIELD(RPU_0_IMR, B1TCM_UE, 11, 1)
156 FIELD(RPU_0_IMR, B0TCM_UE, 10, 1)
157 FIELD(RPU_0_IMR, ATCM_UE, 9, 1)
158 FIELD(RPU_0_IMR, DTAG_DIRTY_FAT, 8, 1)
159 FIELD(RPU_0_IMR, DDATA_FAT, 7, 1)
160 FIELD(RPU_0_IMR, TCM_LST_FAT, 6, 1)
161 FIELD(RPU_0_IMR, TCM_PREFETCH_FAT, 5, 1)
162 FIELD(RPU_0_IMR, DDATA_CE, 4, 1)
163 FIELD(RPU_0_IMR, DTAG_DIRTY_CE, 3, 1)
164 FIELD(RPU_0_IMR, IDATA_CE, 2, 1)
165 FIELD(RPU_0_IMR, ITAG_CE, 1, 1)
166 FIELD(RPU_0_IMR, APB_ERR, 0, 1)
167REG32(RPU_0_IEN, 0x11c)
168 FIELD(RPU_0_IEN, FPUFC, 24, 1)
169 FIELD(RPU_0_IEN, FPOFC, 23, 1)
170 FIELD(RPU_0_IEN, FPIXC, 22, 1)
171 FIELD(RPU_0_IEN, FPIOC, 21, 1)
172 FIELD(RPU_0_IEN, FPIDC, 20, 1)
173 FIELD(RPU_0_IEN, FPDZC, 19, 1)
174 FIELD(RPU_0_IEN, TCM_ASLV_CE, 18, 1)
175 FIELD(RPU_0_IEN, TCM_ASLV_FAT, 17, 1)
176 FIELD(RPU_0_IEN, TCM_LST_CE, 16, 1)
177 FIELD(RPU_0_IEN, TCM_PREFETCH_CE, 15, 1)
178 FIELD(RPU_0_IEN, B1TCM_CE, 14, 1)
179 FIELD(RPU_0_IEN, B0TCM_CE, 13, 1)
180 FIELD(RPU_0_IEN, ATCM_CE, 12, 1)
181 FIELD(RPU_0_IEN, B1TCM_UE, 11, 1)
182 FIELD(RPU_0_IEN, B0TCM_UE, 10, 1)
183 FIELD(RPU_0_IEN, ATCM_UE, 9, 1)
184 FIELD(RPU_0_IEN, DTAG_DIRTY_FAT, 8, 1)
185 FIELD(RPU_0_IEN, DDATA_FAT, 7, 1)
186 FIELD(RPU_0_IEN, TCM_LST_FAT, 6, 1)
187 FIELD(RPU_0_IEN, TCM_PREFETCH_FAT, 5, 1)
188 FIELD(RPU_0_IEN, DDATA_CE, 4, 1)
189 FIELD(RPU_0_IEN, DTAG_DIRTY_CE, 3, 1)
190 FIELD(RPU_0_IEN, IDATA_CE, 2, 1)
191 FIELD(RPU_0_IEN, ITAG_CE, 1, 1)
192 FIELD(RPU_0_IEN, APB_ERR, 0, 1)
193REG32(RPU_0_IDS, 0x120)
194 FIELD(RPU_0_IDS, FPUFC, 24, 1)
195 FIELD(RPU_0_IDS, FPOFC, 23, 1)
196 FIELD(RPU_0_IDS, FPIXC, 22, 1)
197 FIELD(RPU_0_IDS, FPIOC, 21, 1)
198 FIELD(RPU_0_IDS, FPIDC, 20, 1)
199 FIELD(RPU_0_IDS, FPDZC, 19, 1)
200 FIELD(RPU_0_IDS, TCM_ASLV_CE, 18, 1)
201 FIELD(RPU_0_IDS, TCM_ASLV_FAT, 17, 1)
202 FIELD(RPU_0_IDS, TCM_LST_CE, 16, 1)
203 FIELD(RPU_0_IDS, TCM_PREFETCH_CE, 15, 1)
204 FIELD(RPU_0_IDS, B1TCM_CE, 14, 1)
205 FIELD(RPU_0_IDS, B0TCM_CE, 13, 1)
206 FIELD(RPU_0_IDS, ATCM_CE, 12, 1)
207 FIELD(RPU_0_IDS, B1TCM_UE, 11, 1)
208 FIELD(RPU_0_IDS, B0TCM_UE, 10, 1)
209 FIELD(RPU_0_IDS, ATCM_UE, 9, 1)
210 FIELD(RPU_0_IDS, DTAG_DIRTY_FAT, 8, 1)
211 FIELD(RPU_0_IDS, DDATA_FAT, 7, 1)
212 FIELD(RPU_0_IDS, TCM_LST_FAT, 6, 1)
213 FIELD(RPU_0_IDS, TCM_PREFETCH_FAT, 5, 1)
214 FIELD(RPU_0_IDS, DDATA_CE, 4, 1)
215 FIELD(RPU_0_IDS, DTAG_DIRTY_CE, 3, 1)
216 FIELD(RPU_0_IDS, IDATA_CE, 2, 1)
217 FIELD(RPU_0_IDS, ITAG_CE, 1, 1)
218 FIELD(RPU_0_IDS, APB_ERR, 0, 1)
219REG32(RPU_0_SLV_BASE, 0x124)
220 FIELD(RPU_0_SLV_BASE, ADDR, 0, 8)
221REG32(RPU_0_AXI_OVER, 0x128)
222 FIELD(RPU_0_AXI_OVER, AWCACHE, 6, 4)
223 FIELD(RPU_0_AXI_OVER, ARCACHE, 2, 4)
224 FIELD(RPU_0_AXI_OVER, AWCACHE_EN, 1, 1)
225 FIELD(RPU_0_AXI_OVER, ARCACHE_EN, 0, 1)
226REG32(RPU_1_CFG, 0x200)
227 FIELD(RPU_1_CFG, CFGNMFI1, 3, 1)
228 FIELD(RPU_1_CFG, VINITHI, 2, 1)
229 FIELD(RPU_1_CFG, COHERENT, 1, 1)
230 FIELD(RPU_1_CFG, NCPUHALT, 0, 1)
231REG32(RPU_1_STATUS, 0x204)
232 FIELD(RPU_1_STATUS, NVALRESET, 5, 1)
233 FIELD(RPU_1_STATUS, NVALIRQ, 4, 1)
234 FIELD(RPU_1_STATUS, NVALFIQ, 3, 1)
235 FIELD(RPU_1_STATUS, NWFIPIPESTOPPED, 2, 1)
236 FIELD(RPU_1_STATUS, NWFEPIPESTOPPED, 1, 1)
237 FIELD(RPU_1_STATUS, NCLKSTOPPED, 0, 1)
238REG32(RPU_1_PWRDWN, 0x208)
239 FIELD(RPU_1_PWRDWN, EN, 0, 1)
240REG32(RPU_1_ISR, 0x214)
241 FIELD(RPU_1_ISR, FPUFC, 24, 1)
242 FIELD(RPU_1_ISR, FPOFC, 23, 1)
243 FIELD(RPU_1_ISR, FPIXC, 22, 1)
244 FIELD(RPU_1_ISR, FPIOC, 21, 1)
245 FIELD(RPU_1_ISR, FPIDC, 20, 1)
246 FIELD(RPU_1_ISR, FPDZC, 19, 1)
247 FIELD(RPU_1_ISR, TCM_ASLV_CE, 18, 1)
248 FIELD(RPU_1_ISR, TCM_ASLV_FAT, 17, 1)
249 FIELD(RPU_1_ISR, TCM_LST_CE, 16, 1)
250 FIELD(RPU_1_ISR, TCM_PREFETCH_CE, 15, 1)
251 FIELD(RPU_1_ISR, B1TCM_CE, 14, 1)
252 FIELD(RPU_1_ISR, B0TCM_CE, 13, 1)
253 FIELD(RPU_1_ISR, ATCM_CE, 12, 1)
254 FIELD(RPU_1_ISR, B1TCM_UE, 11, 1)
255 FIELD(RPU_1_ISR, B0TCM_UE, 10, 1)
256 FIELD(RPU_1_ISR, ATCM_UE, 9, 1)
257 FIELD(RPU_1_ISR, DTAG_DIRTY_FAT, 8, 1)
258 FIELD(RPU_1_ISR, DDATA_FAT, 7, 1)
259 FIELD(RPU_1_ISR, TCM_LST_FAT, 6, 1)
260 FIELD(RPU_1_ISR, TCM_PREFETCH_FAT, 5, 1)
261 FIELD(RPU_1_ISR, DDATA_CE, 4, 1)
262 FIELD(RPU_1_ISR, DTAG_DIRTY_CE, 3, 1)
263 FIELD(RPU_1_ISR, IDATA_CE, 2, 1)
264 FIELD(RPU_1_ISR, ITAG_CE, 1, 1)
265 FIELD(RPU_1_ISR, APB_ERR, 0, 1)
266REG32(RPU_1_IMR, 0x218)
267 FIELD(RPU_1_IMR, FPUFC, 24, 1)
268 FIELD(RPU_1_IMR, FPOFC, 23, 1)
269 FIELD(RPU_1_IMR, FPIXC, 22, 1)
270 FIELD(RPU_1_IMR, FPIOC, 21, 1)
271 FIELD(RPU_1_IMR, FPIDC, 20, 1)
272 FIELD(RPU_1_IMR, FPDZC, 19, 1)
273 FIELD(RPU_1_IMR, TCM_ASLV_CE, 18, 1)
274 FIELD(RPU_1_IMR, TCM_ASLV_FAT, 17, 1)
275 FIELD(RPU_1_IMR, TCM_LST_CE, 16, 1)
276 FIELD(RPU_1_IMR, TCM_PREFETCH_CE, 15, 1)
277 FIELD(RPU_1_IMR, B1TCM_CE, 14, 1)
278 FIELD(RPU_1_IMR, B0TCM_CE, 13, 1)
279 FIELD(RPU_1_IMR, ATCM_CE, 12, 1)
280 FIELD(RPU_1_IMR, B1TCM_UE, 11, 1)
281 FIELD(RPU_1_IMR, B0TCM_UE, 10, 1)
282 FIELD(RPU_1_IMR, ATCM_UE, 9, 1)
283 FIELD(RPU_1_IMR, DTAG_DIRTY_FAT, 8, 1)
284 FIELD(RPU_1_IMR, DDATA_FAT, 7, 1)
285 FIELD(RPU_1_IMR, TCM_LST_FAT, 6, 1)
286 FIELD(RPU_1_IMR, TCM_PREFETCH_FAT, 5, 1)
287 FIELD(RPU_1_IMR, DDATA_CE, 4, 1)
288 FIELD(RPU_1_IMR, DTAG_DIRTY_CE, 3, 1)
289 FIELD(RPU_1_IMR, IDATA_CE, 2, 1)
290 FIELD(RPU_1_IMR, ITAG_CE, 1, 1)
291 FIELD(RPU_1_IMR, APB_ERR, 0, 1)
292REG32(RPU_1_IEN, 0x21c)
293 FIELD(RPU_1_IEN, FPUFC, 24, 1)
294 FIELD(RPU_1_IEN, FPOFC, 23, 1)
295 FIELD(RPU_1_IEN, FPIXC, 22, 1)
296 FIELD(RPU_1_IEN, FPIOC, 21, 1)
297 FIELD(RPU_1_IEN, FPIDC, 20, 1)
298 FIELD(RPU_1_IEN, FPDZC, 19, 1)
299 FIELD(RPU_1_IEN, TCM_ASLV_CE, 18, 1)
300 FIELD(RPU_1_IEN, TCM_ASLV_FAT, 17, 1)
301 FIELD(RPU_1_IEN, TCM_LST_CE, 16, 1)
302 FIELD(RPU_1_IEN, TCM_PREFETCH_CE, 15, 1)
303 FIELD(RPU_1_IEN, B1TCM_CE, 14, 1)
304 FIELD(RPU_1_IEN, B0TCM_CE, 13, 1)
305 FIELD(RPU_1_IEN, ATCM_CE, 12, 1)
306 FIELD(RPU_1_IEN, B1TCM_UE, 11, 1)
307 FIELD(RPU_1_IEN, B0TCM_UE, 10, 1)
308 FIELD(RPU_1_IEN, ATCM_UE, 9, 1)
309 FIELD(RPU_1_IEN, DTAG_DIRTY_FAT, 8, 1)
310 FIELD(RPU_1_IEN, DDATA_FAT, 7, 1)
311 FIELD(RPU_1_IEN, TCM_LST_FAT, 6, 1)
312 FIELD(RPU_1_IEN, TCM_PREFETCH_FAT, 5, 1)
313 FIELD(RPU_1_IEN, DDATA_CE, 4, 1)
314 FIELD(RPU_1_IEN, DTAG_DIRTY_CE, 3, 1)
315 FIELD(RPU_1_IEN, IDATA_CE, 2, 1)
316 FIELD(RPU_1_IEN, ITAG_CE, 1, 1)
317 FIELD(RPU_1_IEN, APB_ERR, 0, 1)
318REG32(RPU_1_IDS, 0x220)
319 FIELD(RPU_1_IDS, FPUFC, 24, 1)
320 FIELD(RPU_1_IDS, FPOFC, 23, 1)
321 FIELD(RPU_1_IDS, FPIXC, 22, 1)
322 FIELD(RPU_1_IDS, FPIOC, 21, 1)
323 FIELD(RPU_1_IDS, FPIDC, 20, 1)
324 FIELD(RPU_1_IDS, FPDZC, 19, 1)
325 FIELD(RPU_1_IDS, TCM_ASLV_CE, 18, 1)
326 FIELD(RPU_1_IDS, TCM_ASLV_FAT, 17, 1)
327 FIELD(RPU_1_IDS, TCM_LST_CE, 16, 1)
328 FIELD(RPU_1_IDS, TCM_PREFETCH_CE, 15, 1)
329 FIELD(RPU_1_IDS, B1TCM_CE, 14, 1)
330 FIELD(RPU_1_IDS, B0TCM_CE, 13, 1)
331 FIELD(RPU_1_IDS, ATCM_CE, 12, 1)
332 FIELD(RPU_1_IDS, B1TCM_UE, 11, 1)
333 FIELD(RPU_1_IDS, B0TCM_UE, 10, 1)
334 FIELD(RPU_1_IDS, ATCM_UE, 9, 1)
335 FIELD(RPU_1_IDS, DTAG_DIRTY_FAT, 8, 1)
336 FIELD(RPU_1_IDS, DDATA_FAT, 7, 1)
337 FIELD(RPU_1_IDS, TCM_LST_FAT, 6, 1)
338 FIELD(RPU_1_IDS, TCM_PREFETCH_FAT, 5, 1)
339 FIELD(RPU_1_IDS, DDATA_CE, 4, 1)
340 FIELD(RPU_1_IDS, DTAG_DIRTY_CE, 3, 1)
341 FIELD(RPU_1_IDS, IDATA_CE, 2, 1)
342 FIELD(RPU_1_IDS, ITAG_CE, 1, 1)
343 FIELD(RPU_1_IDS, APB_ERR, 0, 1)
344REG32(RPU_1_SLV_BASE, 0x224)
345 FIELD(RPU_1_SLV_BASE, ADDR, 0, 8)
346REG32(RPU_1_AXI_OVER, 0x228)
347 FIELD(RPU_1_AXI_OVER, AWCACHE, 6, 4)
348 FIELD(RPU_1_AXI_OVER, ARCACHE, 2, 4)
349 FIELD(RPU_1_AXI_OVER, AWCACHE_EN, 1, 1)
350 FIELD(RPU_1_AXI_OVER, ARCACHE_EN, 0, 1)
351
352#define RPU_R_MAX (R_RPU_1_AXI_OVER + 1)
353
354#define MAX_RPU 2
355
356typedef struct RPU {
357 SysBusDevice parent_obj;
358 MemoryRegion iomem;
359 MemoryRegion mr_R5[2];
360 MemoryRegion mr_R5_alias[2];
361 MemoryRegion tcm_A[2];
362 MemoryRegion tcm_B[2];
363 MemoryRegion tcm_A1_alias[2];
364 MemoryRegion tcm_B1_alias[2];
365
366 MemoryRegion icache[2];
367 MemoryRegion dcache[2];
368
369 qemu_irq irq_rpu_1_imr;
370 qemu_irq irq_rpu_0_imr;
371 qemu_irq rpu_pwrdw[MAX_RPU];
372 qemu_irq rpu_sleep[MAX_RPU];
373
374 bool r5_rst[2];
375 qemu_irq halt[2];
376 qemu_irq vinithi[2];
377
378 struct {
379 uint32_t tcm_size;
380 uint32_t icache_size;
381 uint32_t dcache_size;
382 } cfg;
383
384 DeviceState *rpu_cpu[MAX_RPU];
385 uint32_t regs[RPU_R_MAX];
386 RegisterInfo regs_info[RPU_R_MAX];
387} RPU;
388
389static void rpu_1_imr_update_irq(RPU *s)
390{
391 bool pending = s->regs[R_RPU_1_ISR] & ~s->regs[R_RPU_1_IMR];
392 qemu_set_irq(s->irq_rpu_1_imr, pending);
393}
394
395static void rpu_1_isr_postw(RegisterInfo *reg, uint64_t val64)
396{
397 RPU *s = XILINX_VERSAL_RPU(reg->opaque);
398 rpu_1_imr_update_irq(s);
399}
400
401static uint64_t rpu_1_ien_prew(RegisterInfo *reg, uint64_t val64)
402{
403 RPU *s = XILINX_VERSAL_RPU(reg->opaque);
404 uint32_t val = val64;
405
406 s->regs[R_RPU_1_IMR] &= ~val;
407 rpu_1_imr_update_irq(s);
408 return 0;
409}
410
411static uint64_t rpu_1_ids_prew(RegisterInfo *reg, uint64_t val64)
412{
413 RPU *s = XILINX_VERSAL_RPU(reg->opaque);
414 uint32_t val = val64;
415
416 s->regs[R_RPU_1_IMR] |= val;
417 rpu_1_imr_update_irq(s);
418 return 0;
419}
420
421static void rpu_0_imr_update_irq(RPU *s)
422{
423 bool pending = s->regs[R_RPU_0_ISR] & ~s->regs[R_RPU_0_IMR];
424 qemu_set_irq(s->irq_rpu_0_imr, pending);
425}
426
427static void rpu_0_isr_postw(RegisterInfo *reg, uint64_t val64)
428{
429 RPU *s = XILINX_VERSAL_RPU(reg->opaque);
430 rpu_0_imr_update_irq(s);
431}
432
433static uint64_t rpu_0_ien_prew(RegisterInfo *reg, uint64_t val64)
434{
435 RPU *s = XILINX_VERSAL_RPU(reg->opaque);
436 uint32_t val = val64;
437
438 s->regs[R_RPU_0_IMR] &= ~val;
439 rpu_0_imr_update_irq(s);
440 return 0;
441}
442
443static uint64_t rpu_0_ids_prew(RegisterInfo *reg, uint64_t val64)
444{
445 RPU *s = XILINX_VERSAL_RPU(reg->opaque);
446 uint32_t val = val64;
447
448 s->regs[R_RPU_0_IMR] |= val;
449 rpu_0_imr_update_irq(s);
450 return 0;
451}
452
453static void rpu_setup_tcm(RPU *s)
454{
455 bool sl_clamp;
456 bool sl_split;
457 bool tcm_combine;
458
459
460 sl_clamp = ARRAY_FIELD_EX32(s->regs, RPU_GLBL_CNTL, SLCLAMP);
461 sl_split = ARRAY_FIELD_EX32(s->regs, RPU_GLBL_CNTL, SLSPLIT);
462 tcm_combine = ARRAY_FIELD_EX32(s->regs, RPU_GLBL_CNTL, TCM_COMB);
463
464 DPRINTF("%s: sl_clamp=%d sl_split=%d tcm_combine=%d\n",
465 __func__, sl_clamp, sl_split, tcm_combine);
466
467 if (tcm_combine) {
468 memory_region_set_enabled(&s->tcm_A1_alias[0], true);
469 memory_region_set_enabled(&s->tcm_A1_alias[1], false);
470 memory_region_set_enabled(&s->tcm_B1_alias[0], true);
471 memory_region_set_enabled(&s->tcm_B1_alias[1], false);
472 } else {
473 memory_region_set_enabled(&s->tcm_A1_alias[0], false);
474 memory_region_set_enabled(&s->tcm_A1_alias[1], true);
475 memory_region_set_enabled(&s->tcm_B1_alias[0], false);
476 memory_region_set_enabled(&s->tcm_B1_alias[1], true);
477 }
478
479
480 if (sl_split) {
481 if (sl_clamp) {
482 qemu_log_mask(LOG_GUEST_ERROR, "slclamp set in split mode!\n");
483 }
484 } else {
485 if (!sl_clamp) {
486 qemu_log_mask(LOG_GUEST_ERROR,
487 "slclamp not set in lock-step mode!\n");
488 }
489 }
490}
491
492#define PROPAGATE_GPIO(reg, f, irq) { \
493 bool val = ARRAY_FIELD_EX32(s->regs, reg, f); \
494 qemu_set_irq(irq, val); \
495}
496
497static void rpu_update_gpios(RPU *s)
498{
499 bool sl_split;
500 bool ncpuhalt[2];
501 int i;
502
503 sl_split = ARRAY_FIELD_EX32(s->regs, RPU_GLBL_CNTL, SLSPLIT);
504
505 ncpuhalt[0] = ARRAY_FIELD_EX32(s->regs, RPU_0_CFG, NCPUHALT);
506 ncpuhalt[1] = ARRAY_FIELD_EX32(s->regs, RPU_1_CFG, NCPUHALT);
507
508 for (i = 0; i < ARRAY_SIZE(ncpuhalt); i++) {
509 bool halt;
510
511
512 halt = !ncpuhalt[i];
513 halt |= s->r5_rst[i];
514
515 if (i == 1 && !sl_split) {
516
517 halt = true;
518 }
519
520 qemu_log_mask(CPU_LOG_RESET,
521 "r5 halt[%d]=%d rst=%d ncpuhalt=%d sl_split=%d\n",
522 i, halt, s->r5_rst[i], ncpuhalt[i], sl_split);
523 qemu_set_irq(s->halt[i], halt);
524 }
525
526 PROPAGATE_GPIO(RPU_0_CFG, VINITHI, s->vinithi[0]);
527 PROPAGATE_GPIO(RPU_1_CFG, VINITHI, s->vinithi[1]);
528
529
530
531
532 if (s->regs[R_RPU_0_PWRDWN] &
533 (!ARRAY_FIELD_EX32(s->regs, RPU_0_STATUS, NWFIPIPESTOPPED))) {
534 qemu_irq_pulse(s->rpu_sleep[0]);
535 }
536 if (s->regs[R_RPU_1_PWRDWN] &
537 (!ARRAY_FIELD_EX32(s->regs, RPU_1_STATUS, NWFIPIPESTOPPED))) {
538 qemu_irq_pulse(s->rpu_sleep[1]);
539 }
540}
541
542static void rpu_update_gpios_pw(RegisterInfo *reg, uint64_t val64)
543{
544 RPU *s = XILINX_VERSAL_RPU(reg->opaque);
545 rpu_update_gpios(s);
546}
547
548static void rpu_pwrdwn_postw(RegisterInfo *reg, uint64_t val64)
549{
550 RPU *s = XILINX_VERSAL_RPU(reg->opaque);
551 uint32_t r;
552
553 switch (reg->access->addr) {
554 case A_RPU_0_PWRDWN:
555 r = s->regs[R_RPU_0_PWRDWN];
556 if (!!r) {
557 qemu_set_irq(s->rpu_pwrdw[0], true);
558 }
559 break;
560 case A_RPU_1_PWRDWN:
561 r = s->regs[R_RPU_1_PWRDWN];
562 if (!!r) {
563 qemu_set_irq(s->rpu_pwrdw[1], true);
564 }
565 break;
566 default:
567 g_assert_not_reached();
568 }
569}
570
571static void rpu_update_gic_axprot(RPU *s, bool secure)
572{
573 unsigned int i;
574 for (i = 0; i < MAX_RPU; i++) {
575 if (s->rpu_cpu[i]) {
576 qdev_prop_set_bit(s->rpu_cpu[i], "memattr-secure", secure);
577 }
578 }
579}
580
581static void rpu_glbl_cntl_pw(RegisterInfo *reg, uint64_t val64)
582{
583 RPU *s = XILINX_VERSAL_RPU(reg->opaque);
584
585 rpu_update_gic_axprot(s, val64 & R_RPU_GLBL_CNTL_GIC_AXPROT_MASK ? false :
586 true);
587 rpu_setup_tcm(s);
588 rpu_update_gpios(s);
589}
590
591static const RegisterAccessInfo rpu_regs_info[] = {
592 { .name = "RPU_GLBL_CNTL", .addr = A_RPU_GLBL_CNTL,
593 .reset = 0x50,
594 .rsvd = 0xfffffa00,
595 .post_write = rpu_glbl_cntl_pw,
596 },{ .name = "RPU_GLBL_STATUS", .addr = A_RPU_GLBL_STATUS,
597 .rsvd = 0xfffffffe,
598 .ro = 0x1,
599 },{ .name = "RPU_ERR_CNTL", .addr = A_RPU_ERR_CNTL,
600 .rsvd = 0xfffffffe,
601 },{ .name = "RPU_ERR_INJ", .addr = A_RPU_ERR_INJ,
602 .rsvd = 0xffff0000,
603 },{ .name = "RPU_CCF_MASK", .addr = A_RPU_CCF_MASK,
604 .rsvd = 0xffffff00,
605 },{ .name = "RPU_INTR_0", .addr = A_RPU_INTR_0,
606 },{ .name = "RPU_INTR_1", .addr = A_RPU_INTR_1,
607 },{ .name = "RPU_INTR_2", .addr = A_RPU_INTR_2,
608 },{ .name = "RPU_INTR_3", .addr = A_RPU_INTR_3,
609 },{ .name = "RPU_INTR_4", .addr = A_RPU_INTR_4,
610 },{ .name = "RPU_INTR_MASK_0", .addr = A_RPU_INTR_MASK_0,
611 },{ .name = "RPU_INTR_MASK_1", .addr = A_RPU_INTR_MASK_1,
612 },{ .name = "RPU_INTR_MASK_2", .addr = A_RPU_INTR_MASK_2,
613 },{ .name = "RPU_INTR_MASK_3", .addr = A_RPU_INTR_MASK_3,
614 },{ .name = "RPU_INTR_MASK_4", .addr = A_RPU_INTR_MASK_4,
615 },{ .name = "RPU_CCF_VAL", .addr = A_RPU_CCF_VAL,
616 .reset = 0x7,
617 .rsvd = 0xffffff00,
618 },{ .name = "RPU_SAFETY_CHK", .addr = A_RPU_SAFETY_CHK,
619 },{ .name = "RPU_0_CFG", .addr = A_RPU_0_CFG,
620 .reset = 0x5,
621 .rsvd = 0xfffffff0,
622 .post_write = rpu_update_gpios_pw,
623 },{ .name = "RPU_0_STATUS", .addr = A_RPU_0_STATUS,
624 .reset = 0x3f,
625 .rsvd = 0xffffffc0,
626 .ro = 0x3f,
627 },{ .name = "RPU_0_PWRDWN", .addr = A_RPU_0_PWRDWN,
628 .rsvd = 0xfffffffe,
629 .post_write = rpu_pwrdwn_postw,
630 },{ .name = "RPU_0_ISR", .addr = A_RPU_0_ISR,
631 .rsvd = 0xfe000000,
632 .w1c = 0x1ffffff,
633 .post_write = rpu_0_isr_postw,
634 },{ .name = "RPU_0_IMR", .addr = A_RPU_0_IMR,
635 .reset = 0x1ffffff,
636 .rsvd = 0xfe000000,
637 .ro = 0x1ffffff,
638 },{ .name = "RPU_0_IEN", .addr = A_RPU_0_IEN,
639 .rsvd = 0xfe000000,
640 .pre_write = rpu_0_ien_prew,
641 },{ .name = "RPU_0_IDS", .addr = A_RPU_0_IDS,
642 .rsvd = 0xfe000000,
643 .pre_write = rpu_0_ids_prew,
644 },{ .name = "RPU_0_SLV_BASE", .addr = A_RPU_0_SLV_BASE,
645 .rsvd = 0xffffff00,
646 },{ .name = "RPU_0_AXI_OVER", .addr = A_RPU_0_AXI_OVER,
647 .rsvd = 0xfffffc00,
648 },{ .name = "RPU_1_CFG", .addr = A_RPU_1_CFG,
649 .reset = 0x5,
650 .rsvd = 0xfffffff0,
651 .post_write = rpu_update_gpios_pw,
652 },{ .name = "RPU_1_STATUS", .addr = A_RPU_1_STATUS,
653 .reset = 0x3f,
654 .rsvd = 0xffffffc0,
655 .ro = 0x3f,
656 },{ .name = "RPU_1_PWRDWN", .addr = A_RPU_1_PWRDWN,
657 .rsvd = 0xfffffffe,
658 .post_write = rpu_pwrdwn_postw,
659 },{ .name = "RPU_1_ISR", .addr = A_RPU_1_ISR,
660 .rsvd = 0xfe000000,
661 .w1c = 0x1ffffff,
662 .post_write = rpu_1_isr_postw,
663 },{ .name = "RPU_1_IMR", .addr = A_RPU_1_IMR,
664 .reset = 0x1ffffff,
665 .rsvd = 0xfe000000,
666 .ro = 0x1ffffff,
667 },{ .name = "RPU_1_IEN", .addr = A_RPU_1_IEN,
668 .rsvd = 0xfe000000,
669 .pre_write = rpu_1_ien_prew,
670 },{ .name = "RPU_1_IDS", .addr = A_RPU_1_IDS,
671 .rsvd = 0xfe000000,
672 .pre_write = rpu_1_ids_prew,
673 },{ .name = "RPU_1_SLV_BASE", .addr = A_RPU_1_SLV_BASE,
674 .rsvd = 0xffffff00,
675 },{ .name = "RPU_1_AXI_OVER", .addr = A_RPU_1_AXI_OVER,
676 .rsvd = 0xfffffc00,
677 }
678};
679
680static void rpu_reset(DeviceState *dev)
681{
682 RPU *s = XILINX_VERSAL_RPU(dev);
683 unsigned int i;
684
685 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
686 register_reset(&s->regs_info[i]);
687 }
688
689 rpu_1_imr_update_irq(s);
690 rpu_0_imr_update_irq(s);
691
692 rpu_update_gic_axprot(s, true);
693 rpu_update_gpios(s);
694}
695
696static void rpu_rst_h(void *opaque, int irq, int level)
697{
698 RPU *s = XILINX_VERSAL_RPU(opaque);
699
700 s->r5_rst[irq] = level;
701 rpu_update_gpios(s);
702}
703
704static void rpu_wfi_h(void *opaque, int irq, int level)
705{
706 RPU *s = XILINX_VERSAL_RPU(opaque);
707
708 switch (irq) {
709 case 0:
710 ARRAY_FIELD_DP32(s->regs, RPU_0_STATUS, NWFIPIPESTOPPED, !level);
711 break;
712 case 1:
713 ARRAY_FIELD_DP32(s->regs, RPU_1_STATUS, NWFIPIPESTOPPED, !level);
714 break;
715 default:
716 g_assert_not_reached();
717 }
718 rpu_update_gpios(s);
719}
720
721static void rpu_pwr_status_h(void *opaque, int irq, int level)
722{
723 RPU *s = XILINX_VERSAL_RPU(opaque);
724
725 if (!!level) {
726 qemu_set_irq(s->rpu_pwrdw[irq], false);
727 }
728}
729
730static const MemoryRegionOps rpu_ops = {
731 .read = register_read_memory,
732 .write = register_write_memory,
733 .endianness = DEVICE_LITTLE_ENDIAN,
734 .valid = {
735 .min_access_size = 4,
736 .max_access_size = 4,
737 },
738};
739
740static void rpu_realize(DeviceState *dev, Error **errp)
741{
742 RPU *s = XILINX_VERSAL_RPU(dev);
743 char *name;
744 int i;
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781 for (i = 0; i < ARRAY_SIZE(s->tcm_A); i++) {
782 name = g_strdup_printf("mr-R5_%d", i);
783 memory_region_init(&s->mr_R5[i], OBJECT(dev),
784 name,
785 s->cfg.tcm_size * 6);
786 g_free(name);
787
788 name = g_strdup_printf("tcm_A%d", i);
789 memory_region_init_ram(&s->tcm_A[i], OBJECT(dev),
790 name, s->cfg.tcm_size, &error_fatal);
791 g_free(name);
792
793 name = g_strdup_printf("tcm_B%d", i);
794 memory_region_init_ram(&s->tcm_B[i], OBJECT(dev),
795 name, s->cfg.tcm_size, &error_fatal);
796 g_free(name);
797
798 name = g_strdup_printf("icache%d", i);
799 memory_region_init_ram(&s->icache[i], OBJECT(dev),
800 name, s->cfg.icache_size, &error_fatal);
801 g_free(name);
802
803 name = g_strdup_printf("dcache%d", i);
804 memory_region_init_ram(&s->dcache[i], OBJECT(dev),
805 name, s->cfg.dcache_size, &error_fatal);
806 g_free(name);
807
808 name = g_strdup_printf("mr-R5_%d-alias", i);
809 memory_region_init_alias(&s->mr_R5_alias[i], OBJECT(dev),
810 name, &s->mr_R5[i], 0x0, s->cfg.tcm_size * 6);
811 g_free(name);
812
813 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr_R5[i]);
814 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr_R5_alias[i]);
815 }
816
817 for (i = 0; i < ARRAY_SIZE(s->tcm_A1_alias); i++) {
818 name = g_strdup_printf("tcm_A1-%d-alias", i);
819 memory_region_init_alias(&s->tcm_A1_alias[i], OBJECT(dev),
820 name, &s->tcm_A[1], 0x0, s->cfg.tcm_size);
821 g_free(name);
822
823 name = g_strdup_printf("tcm_B1-%d-alias", i);
824 memory_region_init_alias(&s->tcm_B1_alias[i], OBJECT(dev),
825 name, &s->tcm_B[1], 0x0, s->cfg.tcm_size);
826 g_free(name);
827 }
828
829
830 memory_region_add_subregion_overlap(&s->mr_R5[0], 0x0,
831 &s->tcm_A[0], 0);
832 memory_region_add_subregion_overlap(&s->mr_R5[0], s->cfg.tcm_size * 1,
833 &s->tcm_A1_alias[0], 0);
834 memory_region_add_subregion_overlap(&s->mr_R5[0], s->cfg.tcm_size * 2,
835 &s->tcm_B[0], 0);
836 memory_region_add_subregion_overlap(&s->mr_R5[0], s->cfg.tcm_size * 3,
837 &s->tcm_B1_alias[0], 0);
838 memory_region_add_subregion_overlap(&s->mr_R5[0], s->cfg.tcm_size * 4,
839 &s->icache[0], 0);
840 memory_region_add_subregion_overlap(&s->mr_R5[0], s->cfg.tcm_size * 5,
841 &s->dcache[0], 0);
842
843 memory_region_add_subregion_overlap(&s->mr_R5[1], 0x0,
844 &s->tcm_A1_alias[1], 0);
845 memory_region_add_subregion_overlap(&s->mr_R5[1], s->cfg.tcm_size * 2,
846 &s->tcm_B1_alias[1], 0);
847 memory_region_add_subregion_overlap(&s->mr_R5[1], s->cfg.tcm_size * 4,
848 &s->icache[1], 0);
849 memory_region_add_subregion_overlap(&s->mr_R5[1], s->cfg.tcm_size * 5,
850 &s->dcache[1], 0);
851}
852
853static void rpu_init(Object *obj)
854{
855 RPU *s = XILINX_VERSAL_RPU(obj);
856 DeviceState *dev = DEVICE(obj);
857 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
858 RegisterInfoArray *reg_array;
859 unsigned int i;
860 char *name;
861
862 memory_region_init(&s->iomem, obj, TYPE_XILINX_VERSAL_RPU, RPU_R_MAX * 4);
863 reg_array =
864 register_init_block32(DEVICE(obj), rpu_regs_info,
865 ARRAY_SIZE(rpu_regs_info),
866 s->regs_info, s->regs,
867 &rpu_ops,
868 XILINX_VERSAL_RPU_ERR_DEBUG,
869 RPU_R_MAX * 4);
870 memory_region_add_subregion(&s->iomem,
871 0x0,
872 ®_array->mem);
873 sysbus_init_mmio(sbd, &s->iomem);
874
875 sysbus_init_irq(sbd, &s->irq_rpu_1_imr);
876 sysbus_init_irq(sbd, &s->irq_rpu_0_imr);
877
878 qdev_init_gpio_out_named(dev, s->halt, "halt", 2);
879 qdev_init_gpio_out_named(dev, s->vinithi, "vinithi", 2);
880 qdev_init_gpio_in_named(dev, rpu_rst_h, "rpu-rst", 2);
881 qdev_init_gpio_in_named(dev, rpu_wfi_h, "rpu-wfi", 2);
882 qdev_init_gpio_in_named(dev, rpu_pwr_status_h, "rpu-pwr-status", MAX_RPU);
883 qdev_init_gpio_out_named(dev, s->rpu_pwrdw, "rpu-pwrdw", MAX_RPU);
884 qdev_init_gpio_out_named(dev, s->rpu_sleep, "rpu-sleep", MAX_RPU);
885
886 for (i = 0; i < MAX_RPU; i++) {
887 name = g_strdup_printf("rpu%d", i);
888 object_property_add_link(obj, name, TYPE_DEVICE,
889 (Object **)&s->rpu_cpu[i],
890 qdev_prop_allow_set_link_before_realize,
891 OBJ_PROP_LINK_STRONG);
892 g_free(name);
893 }
894}
895
896static const VMStateDescription vmstate_rpu = {
897 .name = TYPE_XILINX_VERSAL_RPU,
898 .version_id = 1,
899 .minimum_version_id = 1,
900 .fields = (VMStateField[]) {
901 VMSTATE_UINT32_ARRAY(regs, RPU, RPU_R_MAX),
902 VMSTATE_END_OF_LIST(),
903 }
904};
905
906static const FDTGenericGPIOSet crl_gpios[] = {
907 {
908 .names = &fdt_generic_gpio_name_set_gpio,
909 .gpios = (FDTGenericGPIOConnection[]) {
910 { .name = "halt", .fdt_index = 0, .range = 2 },
911 { .name = "rpu-wfi", .fdt_index = 2, .range = 2},
912 { .name = "vinithi", .fdt_index = 4, .range = 2 },
913 { .name = "rpu-pwrdw", .fdt_index = 6, .range = MAX_RPU },
914 { .name = "rpu-sleep", .fdt_index = (6 + MAX_RPU), .range = MAX_RPU },
915 { },
916 },
917 },
918 { },
919};
920
921static const FDTGenericGPIOSet rpu_client_gpios[] = {
922 {
923 .names = &fdt_generic_gpio_name_set_gpio,
924 .gpios = (FDTGenericGPIOConnection[]) {
925 { .name = "rpu-rst", .fdt_index = 0, .range = 2 },
926 { .name = "rpu-pwr-status", .fdt_index = 2, .range = MAX_RPU },
927 { },
928 },
929 },
930 { },
931};
932
933static Property rpu_properties[] = {
934 DEFINE_PROP_UINT32("tcm-size", RPU, cfg.tcm_size, 64 * 1024),
935 DEFINE_PROP_UINT32("icache-size", RPU, cfg.icache_size, 64 * 1024),
936 DEFINE_PROP_UINT32("dcache-size", RPU, cfg.dcache_size, 64 * 1024),
937 DEFINE_PROP_END_OF_LIST(),
938};
939
940static void rpu_class_init(ObjectClass *klass, void *data)
941{
942 DeviceClass *dc = DEVICE_CLASS(klass);
943 FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
944
945 dc->reset = rpu_reset;
946 dc->realize = rpu_realize;
947 dc->vmsd = &vmstate_rpu;
948 device_class_set_props(dc, rpu_properties);
949 fggc->controller_gpios = crl_gpios;
950 fggc->client_gpios = rpu_client_gpios;
951}
952
953static const TypeInfo rpu_info = {
954 .name = TYPE_XILINX_VERSAL_RPU,
955 .parent = TYPE_SYS_BUS_DEVICE,
956 .instance_size = sizeof(RPU),
957 .class_init = rpu_class_init,
958 .instance_init = rpu_init,
959 .interfaces = (InterfaceInfo[]) {
960 { TYPE_FDT_GENERIC_GPIO },
961 { }
962 },
963};
964
965static void rpu_register_types(void)
966{
967 type_register_static(&rpu_info);
968}
969
970type_init(rpu_register_types)
971