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-dep.h"
30#include "qemu/bitops.h"
31#include "qemu/log.h"
32
33#include "hw/fdt_generic_util.h"
34
35#ifndef XLNX_ZYNQMP_GPIO_ERR_DEBUG
36#define XLNX_ZYNQMP_GPIO_ERR_DEBUG 0
37#endif
38
39#define TYPE_XLNX_ZYNQMP_GPIO "xlnx.zynqmp-gpio"
40
41#define XLNX_ZYNQMP_GPIO(obj) \
42 OBJECT_CHECK(XlnxZynqmpGPIO, (obj), TYPE_XLNX_ZYNQMP_GPIO)
43
44#define DPRINT(...) \
45 if (XLNX_ZYNQMP_GPIO_ERR_DEBUG) { \
46 qemu_log("%s:", __func__); \
47 qemu_log(__VA_ARGS__); \
48 }
49
50DEP_REG32(MASK_DATA_0_LSW, 0x0)
51 DEP_FIELD(MASK_DATA_0_LSW, MASK_0_LSW, 16, 16)
52 DEP_FIELD(MASK_DATA_0_LSW, DATA_0_LSW, 16, 0)
53DEP_REG32(MASK_DATA_0_MSW, 0x4)
54 DEP_FIELD(MASK_DATA_0_MSW, MASK_0_MSW, 10, 16)
55 DEP_FIELD(MASK_DATA_0_MSW, DATA_0_MSW, 10, 0)
56DEP_REG32(MASK_DATA_1_LSW, 0x8)
57 DEP_FIELD(MASK_DATA_1_LSW, MASK_1_LSW, 16, 16)
58 DEP_FIELD(MASK_DATA_1_LSW, DATA_1_LSW, 16, 0)
59DEP_REG32(MASK_DATA_1_MSW, 0xc)
60 DEP_FIELD(MASK_DATA_1_MSW, MASK_1_MSW, 10, 16)
61 DEP_FIELD(MASK_DATA_1_MSW, DATA_1_MSW, 10, 0)
62DEP_REG32(MASK_DATA_2_LSW, 0x10)
63 DEP_FIELD(MASK_DATA_2_LSW, MASK_2_LSW, 16, 16)
64 DEP_FIELD(MASK_DATA_2_LSW, DATA_2_LSW, 16, 0)
65DEP_REG32(MASK_DATA_2_MSW, 0x14)
66 DEP_FIELD(MASK_DATA_2_MSW, MASK_2_MSW, 10, 16)
67 DEP_FIELD(MASK_DATA_2_MSW, DATA_2_MSW, 10, 0)
68DEP_REG32(MASK_DATA_3_LSW, 0x18)
69 DEP_FIELD(MASK_DATA_3_LSW, MASK_3_LSW, 16, 16)
70 DEP_FIELD(MASK_DATA_3_LSW, DATA_3_LSW, 16, 0)
71DEP_REG32(MASK_DATA_3_MSW, 0x1c)
72 DEP_FIELD(MASK_DATA_3_MSW, MASK_3_MSW, 16, 16)
73 DEP_FIELD(MASK_DATA_3_MSW, DATA_3_MSW, 16, 0)
74DEP_REG32(MASK_DATA_4_LSW, 0x20)
75 DEP_FIELD(MASK_DATA_4_LSW, MASK_4_LSW, 16, 16)
76 DEP_FIELD(MASK_DATA_4_LSW, DATA_4_LSW, 16, 0)
77DEP_REG32(MASK_DATA_4_MSW, 0x24)
78 DEP_FIELD(MASK_DATA_4_MSW, MASK_4_MSW, 16, 16)
79 DEP_FIELD(MASK_DATA_4_MSW, DATA_4_MSW, 16, 0)
80DEP_REG32(MASK_DATA_5_LSW, 0x28)
81 DEP_FIELD(MASK_DATA_5_LSW, MASK_5_LSW, 16, 16)
82 DEP_FIELD(MASK_DATA_5_LSW, DATA_5_LSW, 16, 0)
83DEP_REG32(MASK_DATA_5_MSW, 0x2c)
84 DEP_FIELD(MASK_DATA_5_MSW, MASK_5_MSW, 16, 16)
85 DEP_FIELD(MASK_DATA_5_MSW, DATA_5_MSW, 16, 0)
86DEP_REG32(DATA_0, 0x40)
87 DEP_FIELD(DATA_0, DATA_0, 26, 0)
88DEP_REG32(DATA_1, 0x44)
89 DEP_FIELD(DATA_1, DATA_1, 26, 0)
90DEP_REG32(DATA_2, 0x48)
91 DEP_FIELD(DATA_2, DATA_2, 26, 0)
92DEP_REG32(DATA_3, 0x4c)
93DEP_REG32(DATA_4, 0x50)
94DEP_REG32(DATA_5, 0x54)
95DEP_REG32(DATA_0_RO, 0x60)
96 DEP_FIELD(DATA_0_RO, DATA_0_RO, 26, 0)
97DEP_REG32(DATA_1_RO, 0x64)
98 DEP_FIELD(DATA_1_RO, DATA_1_RO, 26, 0)
99DEP_REG32(DATA_2_RO, 0x68)
100 DEP_FIELD(DATA_2_RO, DATA_2_RO, 26, 0)
101DEP_REG32(DATA_3_RO, 0x6c)
102DEP_REG32(DATA_4_RO, 0x70)
103DEP_REG32(DATA_5_RO, 0x74)
104DEP_REG32(DIRM_0, 0x204)
105 DEP_FIELD(DIRM_0, DIRECTION_0, 26, 0)
106DEP_REG32(OEN_0, 0x208)
107 DEP_FIELD(OEN_0, OP_ENABLE_0, 26, 0)
108DEP_REG32(INT_MASK_0, 0x20c)
109 DEP_FIELD(INT_MASK_0, INT_MASK_0, 26, 0)
110DEP_REG32(INT_EN_0, 0x210)
111 DEP_FIELD(INT_EN_0, INT_ENABLE_0, 26, 0)
112DEP_REG32(INT_DIS_0, 0x214)
113 DEP_FIELD(INT_DIS_0, INT_DISABLE_0, 26, 0)
114DEP_REG32(INT_STAT_0, 0x218)
115 DEP_FIELD(INT_STAT_0, INT_STATUS_0, 26, 0)
116DEP_REG32(INT_TYPE_0, 0x21c)
117 DEP_FIELD(INT_TYPE_0, INT_TYPE_0, 26, 0)
118DEP_REG32(INT_POLARITY_0, 0x220)
119 DEP_FIELD(INT_POLARITY_0, INT_POL_0, 26, 0)
120DEP_REG32(INT_ANY_0, 0x224)
121 DEP_FIELD(INT_ANY_0, INT_ON_ANY_0, 26, 0)
122DEP_REG32(DIRM_1, 0x244)
123 DEP_FIELD(DIRM_1, DIRECTION_1, 26, 0)
124DEP_REG32(OEN_1, 0x248)
125 DEP_FIELD(OEN_1, OP_ENABLE_1, 26, 0)
126DEP_REG32(INT_MASK_1, 0x24c)
127 DEP_FIELD(INT_MASK_1, INT_MASK_1, 26, 0)
128DEP_REG32(INT_EN_1, 0x250)
129 DEP_FIELD(INT_EN_1, INT_ENABLE_1, 26, 0)
130DEP_REG32(INT_DIS_1, 0x254)
131 DEP_FIELD(INT_DIS_1, INT_DISABLE_1, 26, 0)
132DEP_REG32(INT_STAT_1, 0x258)
133 DEP_FIELD(INT_STAT_1, INT_STATUS_1, 26, 0)
134DEP_REG32(INT_TYPE_1, 0x25c)
135 DEP_FIELD(INT_TYPE_1, INT_TYPE_1, 26, 0)
136DEP_REG32(INT_POLARITY_1, 0x260)
137 DEP_FIELD(INT_POLARITY_1, INT_POL_1, 26, 0)
138DEP_REG32(INT_ANY_1, 0x264)
139 DEP_FIELD(INT_ANY_1, INT_ON_ANY_1, 26, 0)
140DEP_REG32(DIRM_2, 0x284)
141 DEP_FIELD(DIRM_2, DIRECTION_2, 26, 0)
142DEP_REG32(OEN_2, 0x288)
143 DEP_FIELD(OEN_2, OP_ENABLE_2, 26, 0)
144DEP_REG32(INT_MASK_2, 0x28c)
145 DEP_FIELD(INT_MASK_2, INT_MASK_2, 26, 0)
146DEP_REG32(INT_EN_2, 0x290)
147 DEP_FIELD(INT_EN_2, INT_ENABLE_2, 26, 0)
148DEP_REG32(INT_DIS_2, 0x294)
149 DEP_FIELD(INT_DIS_2, INT_DISABLE_2, 26, 0)
150DEP_REG32(INT_STAT_2, 0x298)
151 DEP_FIELD(INT_STAT_2, INT_STATUS_2, 26, 0)
152DEP_REG32(INT_TYPE_2, 0x29c)
153 DEP_FIELD(INT_TYPE_2, INT_TYPE_2, 26, 0)
154DEP_REG32(INT_POLARITY_2, 0x2a0)
155 DEP_FIELD(INT_POLARITY_2, INT_POL_2, 26, 0)
156DEP_REG32(INT_ANY_2, 0x2a4)
157 DEP_FIELD(INT_ANY_2, INT_ON_ANY_2, 26, 0)
158DEP_REG32(DIRM_3, 0x2c4)
159DEP_REG32(OEN_3, 0x2c8)
160DEP_REG32(INT_MASK_3, 0x2cc)
161DEP_REG32(INT_EN_3, 0x2d0)
162DEP_REG32(INT_DIS_3, 0x2d4)
163DEP_REG32(INT_STAT_3, 0x2d8)
164DEP_REG32(INT_TYPE_3, 0x2dc)
165DEP_REG32(INT_POLARITY_3, 0x2e0)
166DEP_REG32(INT_ANY_3, 0x2e4)
167DEP_REG32(DIRM_4, 0x304)
168DEP_REG32(OEN_4, 0x308)
169DEP_REG32(INT_MASK_4, 0x30c)
170DEP_REG32(INT_EN_4, 0x310)
171DEP_REG32(INT_DIS_4, 0x314)
172DEP_REG32(INT_STAT_4, 0x318)
173DEP_REG32(INT_TYPE_4, 0x31c)
174DEP_REG32(INT_POLARITY_4, 0x320)
175DEP_REG32(INT_ANY_4, 0x324)
176DEP_REG32(DIRM_5, 0x344)
177DEP_REG32(OEN_5, 0x348)
178DEP_REG32(INT_MASK_5, 0x34c)
179DEP_REG32(INT_EN_5, 0x350)
180DEP_REG32(INT_DIS_5, 0x354)
181DEP_REG32(INT_STAT_5, 0x358)
182DEP_REG32(INT_TYPE_5, 0x35c)
183DEP_REG32(INT_POLARITY_5, 0x360)
184DEP_REG32(INT_ANY_5, 0x364)
185
186#define R_MAX (R_INT_ANY_5 + 1)
187
188#define ZYNQMP_GPIO_BANK0 0
189#define ZYNQMP_GPIO_BANK1 26
190#define ZYNQMP_GPIO_BANK2 52
191#define ZYNQMP_GPIO_BANK3 78
192#define ZYNQMP_GPIO_BANK4 110
193#define ZYNQMP_GPIO_BANK5 142
194
195#define ZYNQMP_NUM_GPIOS 174
196#define ZYNQMP_NUM_OEN_SIGNALS ZYNQMP_NUM_GPIOS
197#define ZYNQMP_NUM_EMIO_PINS_PER_BANK 32
198#define ZYNQMP_NUM_MIO_PINS_PER_BANK 26
199#define ZYNQMP_GPIO_NUM_BANKS 6
200#define ZYNQMP_GPIO_NUM_MIO_BANKS 3
201#define ZYNQMP_GPIO_NUM_EMIO_BANKS 3
202#define ZYNQMP_GPIO_EMIO_START_OFFSET ZYNQMP_GPIO_BANK3
203#define ZYNQMP_GPIO_MIO_START_OFFSET ZYQNMP_GPIO_BANK0
204
205#define R_GPIO_DATA_X(bank) ((A_DATA_0 + (bank * 0x4)) / 4)
206
207#define R_GPIO_DIRM_X(bank) ((A_DIRM_0 + (bank * 0x40)) / 4)
208#define R_GPIO_OEN_X(bank) ((A_OEN_0 + (bank * 0x40)) / 4)
209#define R_GPIO_INT_MASK_X(bank) ((A_INT_MASK_0 + (bank * 0x40)) / 4)
210#define R_GPIO_INT_STAT_X(bank) ((A_INT_STAT_0 + (bank * 0x40)) / 4)
211#define R_GPIO_INT_POL_X(bank) ((A_INT_POLARITY_0 + (bank * 0x40)) / 4)
212
213typedef struct XlnxZynqmpGPIO {
214 SysBusDevice parent_obj;
215 MemoryRegion iomem;
216
217 qemu_irq irq;
218 qemu_irq *gpio_out;
219 qemu_irq *gpio_oen;
220
221 uint32_t regs[R_MAX];
222 DepRegisterInfo regs_info[R_MAX];
223} XlnxZynqmpGPIO;
224
225
226
227static int gpio_get_bank(hwaddr addr)
228{
229 switch (addr & 0xFFF) {
230 case 0x0 ... 0x2c:
231 return addr / 8;
232 case 0x40 ... 0x54:
233 addr -= 0x40;
234 return addr / 4;
235 case 0x60 ... 0x74:
236 addr -= 0x60;
237 return addr / 4;
238 case 0x204 ... 0x364:
239 return (addr >> 6) & 0x7;
240 default:
241 DPRINT("Register offset doesn't belong to any bank");
242 };
243 return 0;
244}
245
246static int gpio_get_bank_by_pin(int pin, int *offset)
247{
248 switch (pin) {
249 case ZYNQMP_GPIO_BANK0 ... (ZYNQMP_GPIO_BANK1 - 1):
250 *offset = pin - ZYNQMP_GPIO_BANK0;
251 return 0;
252 case ZYNQMP_GPIO_BANK1 ... (ZYNQMP_GPIO_BANK2 - 1):
253 *offset = pin - ZYNQMP_GPIO_BANK1;
254 return 1;
255 case ZYNQMP_GPIO_BANK2 ... (ZYNQMP_GPIO_BANK3 - 1):
256 *offset = pin - ZYNQMP_GPIO_BANK2;
257 return 2;
258 case ZYNQMP_GPIO_BANK3 ... (ZYNQMP_GPIO_BANK4 - 1):
259 *offset = pin - ZYNQMP_GPIO_BANK3;
260 return 3;
261 case ZYNQMP_GPIO_BANK4 ... (ZYNQMP_GPIO_BANK5 - 1):
262 *offset = pin - ZYNQMP_GPIO_BANK4;
263 return 4;
264 case ZYNQMP_GPIO_BANK5 ... (ZYNQMP_NUM_GPIOS - 1):
265 *offset = pin - ZYNQMP_GPIO_BANK5;
266 return 5;
267 default:
268 DPRINT("Pin number exceeded max gpios\n");
269 };
270 return 0;
271}
272
273static void gpio_update_irq(XlnxZynqmpGPIO *s)
274{
275 bool line;
276 int i;
277
278
279
280
281 for (i = 0; i < ZYNQMP_GPIO_NUM_BANKS; i++) {
282 line = !!(~s->regs[R_GPIO_INT_MASK_X(i)] &
283 s->regs[R_GPIO_INT_STAT_X(i)]);
284 qemu_set_irq(s->irq, line);
285 }
286}
287
288static void gpio_update_isr(XlnxZynqmpGPIO *s, int bank, int pin_offset,
289 uint32_t level, uint32_t level_old)
290{
291 uint32_t pol = s->regs[R_GPIO_INT_POL_X(bank)] & (1 << pin_offset);
292
293 if ((level == 0 && level_old == 1 && !pol) ||
294 (level == 1 && level_old == 0 && pol)) {
295 s->regs[R_GPIO_INT_STAT_X(bank)] =
296 deposit32(s->regs[R_GPIO_INT_STAT_X(bank)], pin_offset, 1, level);
297 }
298}
299
300static void gpio_update_pins(XlnxZynqmpGPIO *s, int bank, int offset, int width,
301 uint32_t mask, uint32_t val, uint32_t val_old)
302{
303 int pin = 0;
304 uint32_t i;
305
306
307 switch (bank) {
308 case 0:
309 pin = ZYNQMP_GPIO_BANK0 + offset;
310 break;
311 case 1:
312 pin = ZYNQMP_GPIO_BANK1 + offset;
313 break;
314 case 2:
315 pin = ZYNQMP_GPIO_BANK2 + offset;
316 break;
317 case 3:
318 pin = ZYNQMP_GPIO_BANK3 + offset;
319 break;
320 case 4:
321 pin = ZYNQMP_GPIO_BANK4 + offset;
322 break;
323 case 5:
324 pin = ZYNQMP_GPIO_BANK5 + offset;
325 break;
326 };
327
328 for (i = pin; i < pin + width; i++) {
329
330
331 gpio_update_isr(s, bank, i - pin, extract32(val, i - pin, 1),
332 extract32(val_old, i - pin, 1));
333 if (mask & (1 << (i - pin))) {
334 DPRINT("gpio out[%d] set to %d\n", i, extract32(val, i - pin, 1));
335 qemu_set_irq(s->gpio_out[i], extract32(val, i - pin, 1));
336 }
337 }
338}
339
340static void zynqmp_gpio_in_handler(void *opaque, int n, int level)
341{
342 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(opaque);
343 int offset = 0;
344 int bank = gpio_get_bank_by_pin(n, &offset);
345 uint32_t mask;
346 uint32_t data_old = s->regs[R_GPIO_DATA_X(bank)];
347
348
349 mask = ~(s->regs[R_GPIO_DIRM_X(bank)]);
350
351 if (mask & (1 << offset)) {
352 DPRINT("gpio in[%d] set to %d\n", n, level);
353 s->regs[R_GPIO_DATA_X(bank)] =
354 deposit32(s->regs[R_GPIO_DATA_X(bank)], offset, 1, level);
355
356 gpio_update_isr(s, bank, offset, level,
357 extract32(data_old, offset, 1));
358 }
359 gpio_update_irq(s);
360}
361
362static uint64_t gpio_data_reg_prew(DepRegisterInfo *reg, uint64_t val)
363{
364 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
365 uint32_t data = (uint32_t) val;
366 int bank = gpio_get_bank(reg->access->decode.addr);
367 int width;
368 uint32_t data_old = s->regs[R_GPIO_DATA_X(bank)];
369 uint32_t mask;
370
371
372
373
374 width = bank < 3 ? 26 : 32;
375
376 mask = (s->regs[R_GPIO_OEN_X(bank)] &
377 s->regs[R_GPIO_DIRM_X(bank)]);
378
379 gpio_update_pins(s, bank, 0, width, mask, data, data_old);
380 return val;
381}
382
383static uint64_t gpio_mask_data_lsw_prew(DepRegisterInfo *reg, uint64_t val)
384{
385 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
386 uint32_t data = (uint32_t) val;
387 uint16_t maskw = data >> 16;
388 uint32_t data_old = 0;
389 int bank = gpio_get_bank(reg->access->decode.addr);
390 uint32_t data_reg = R_GPIO_DATA_X(bank);
391 uint32_t mask;
392
393
394 data &= (1 << 16) - 1;
395 data_old = s->regs[data_reg] & 0x0000FFFF;
396
397
398 s->regs[data_reg] = deposit32(s->regs[data_reg], 0, 16,
399 (data_old & maskw) | (~maskw & data));
400
401 mask = (s->regs[R_GPIO_OEN_X(bank)] &
402 s->regs[R_GPIO_DIRM_X(bank)]);
403 gpio_update_pins(s, bank, 0, 16, (mask & 0x0000FFFF),
404 (s->regs[data_reg] & 0x0000FFFF),
405 data_old);
406 return val;
407}
408
409static uint64_t gpio_mask_data_msw_prew(DepRegisterInfo *reg, uint64_t val)
410{
411 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
412 uint32_t data = (uint32_t) val;
413 uint16_t maskw = data >> 16;
414 uint32_t data_old = 0;
415 int width;
416 int bank = gpio_get_bank(reg->access->decode.addr);
417 uint32_t data_reg = R_GPIO_DATA_X(bank);
418 uint32_t mask;
419
420
421
422
423
424 width = bank < 3 ? 10 : 16;
425
426 data &= (1 << width) - 1;
427 data_old = s->regs[data_reg] >> 16;
428
429 s->regs[data_reg] = deposit32(s->regs[data_reg], 16, width,
430 (data_old & maskw) | (~maskw & data));
431
432 mask = (s->regs[R_GPIO_OEN_X(bank)] &
433 s->regs[R_GPIO_DIRM_X(bank)]);
434 gpio_update_pins(s, bank, 16, width, (mask >> 16),
435 (s->regs[data_reg] >> 16), data_old);
436 return val;
437}
438
439static uint64_t gpio_reg_wo(DepRegisterInfo *reg, uint64_t val)
440{
441 return 0;
442}
443
444static uint64_t gpio_data_ro_postr(DepRegisterInfo *reg, uint64_t val)
445{
446 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
447 int bank = gpio_get_bank(reg->access->decode.addr);
448
449 return s->regs[R_GPIO_DATA_X(bank)];
450}
451
452static void gpio_int_en_postw(DepRegisterInfo *reg, uint64_t val)
453{
454 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
455 uint32_t data = (uint32_t) val;
456 int bank = gpio_get_bank(reg->access->decode.addr);
457
458 s->regs[R_GPIO_INT_MASK_X(bank)] &= ~data;
459}
460
461static void gpio_int_dis_postw(DepRegisterInfo *reg, uint64_t val)
462{
463 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
464 uint32_t data = (uint32_t) val;
465 int bank = gpio_get_bank(reg->access->decode.addr);
466
467 s->regs[R_GPIO_INT_MASK_X(bank)] |= data;
468}
469
470static uint64_t gpio_oen_prew(DepRegisterInfo *reg, uint64_t val)
471{
472 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(reg->opaque);
473 uint32_t data = (uint32_t) val;
474 uint32_t data_old = *(uint32_t *)reg->data;
475 int bank = gpio_get_bank(reg->access->decode.addr);
476 int oen_pin;
477 int width;
478 int i;
479
480 if (bank < ZYNQMP_GPIO_NUM_MIO_BANKS) {
481
482 oen_pin = bank * ZYNQMP_NUM_MIO_PINS_PER_BANK;
483 width = ZYNQMP_NUM_MIO_PINS_PER_BANK;
484 } else if (bank < ZYNQMP_GPIO_NUM_BANKS) {
485
486
487 oen_pin = ZYNQMP_GPIO_EMIO_START_OFFSET +
488 (bank - ZYNQMP_GPIO_NUM_MIO_BANKS) *
489 ZYNQMP_NUM_EMIO_PINS_PER_BANK;
490 width = ZYNQMP_NUM_EMIO_PINS_PER_BANK;
491 } else {
492 DPRINT("bank %d not available\n", bank);
493 return val;
494 }
495
496 for (i = 0; i < width; i++) {
497
498 if ((data_old ^ data) & (1 << i)) {
499 qemu_set_irq(s->gpio_oen[oen_pin + i], extract32(data, i, 1));
500 }
501 }
502
503 return val;
504}
505
506static DepRegisterAccessInfo gpio_regs_info[] = {
507 { .name = "MASK_DATA_0_LSW",
508 .decode.addr = A_MASK_DATA_0_LSW,
509 .pre_write = gpio_mask_data_lsw_prew,
510 .post_read = gpio_reg_wo,
511 },{ .name = "MASK_DATA_0_MSW",
512 .decode.addr = A_MASK_DATA_0_MSW,
513 .rsvd = 0xfc00fc00,
514 .pre_write = gpio_mask_data_msw_prew,
515 .post_read = gpio_reg_wo,
516 },{ .name = "MASK_DATA_1_LSW",
517 .decode.addr = A_MASK_DATA_1_LSW,
518 .pre_write = gpio_mask_data_lsw_prew,
519 .post_read = gpio_reg_wo,
520 },{ .name = "MASK_DATA_1_MSW",
521 .decode.addr = A_MASK_DATA_1_MSW,
522 .rsvd = 0xfc00fc00,
523 .pre_write = gpio_mask_data_msw_prew,
524 .post_read = gpio_reg_wo,
525 },{ .name = "MASK_DATA_2_LSW",
526 .decode.addr = A_MASK_DATA_2_LSW,
527 .pre_write = gpio_mask_data_lsw_prew,
528 .post_read = gpio_reg_wo,
529 },{ .name = "MASK_DATA_2_MSW",
530 .decode.addr = A_MASK_DATA_2_MSW,
531 .rsvd = 0xfc00fc00,
532 .pre_write = gpio_mask_data_msw_prew,
533 .post_read = gpio_reg_wo,
534 },{ .name = "MASK_DATA_3_LSW",
535 .decode.addr = A_MASK_DATA_3_LSW,
536 .pre_write = gpio_mask_data_lsw_prew,
537 .post_read = gpio_reg_wo,
538 },{ .name = "MASK_DATA_3_MSW",
539 .decode.addr = A_MASK_DATA_3_MSW,
540 .pre_write = gpio_mask_data_msw_prew,
541 .post_read = gpio_reg_wo,
542 },{ .name = "MASK_DATA_4_LSW",
543 .decode.addr = A_MASK_DATA_4_LSW,
544 .pre_write = gpio_mask_data_lsw_prew,
545 .post_read = gpio_reg_wo,
546 },{ .name = "MASK_DATA_4_MSW",
547 .decode.addr = A_MASK_DATA_4_MSW,
548 .pre_write = gpio_mask_data_msw_prew,
549 .post_read = gpio_reg_wo,
550 },{ .name = "MASK_DATA_5_LSW",
551 .decode.addr = A_MASK_DATA_5_LSW,
552 .pre_write = gpio_mask_data_lsw_prew,
553 .post_read = gpio_reg_wo,
554 },{ .name = "MASK_DATA_5_MSW",
555 .decode.addr = A_MASK_DATA_5_MSW,
556 .pre_write = gpio_mask_data_msw_prew,
557 .post_read = gpio_reg_wo,
558 },{ .name = "DATA_0", .decode.addr = A_DATA_0,
559 .pre_write = gpio_data_reg_prew,
560 .rsvd = 0xfc000000,
561 },{ .name = "DATA_1", .decode.addr = A_DATA_1,
562 .pre_write = gpio_data_reg_prew,
563 .rsvd = 0xfc000000,
564 },{ .name = "DATA_2", .decode.addr = A_DATA_2,
565 .pre_write = gpio_data_reg_prew,
566 .rsvd = 0xfc000000,
567 },{ .name = "DATA_3", .decode.addr = A_DATA_3,
568 .pre_write = gpio_data_reg_prew,
569 },{ .name = "DATA_4", .decode.addr = A_DATA_4,
570 .pre_write = gpio_data_reg_prew,
571 },{ .name = "DATA_5", .decode.addr = A_DATA_5,
572 .pre_write = gpio_data_reg_prew,
573 },{ .name = "DATA_0_RO",
574 .decode.addr = A_DATA_0_RO,
575 .rsvd = 0xfc000000,
576 .ro = 0xffffffff,
577 .post_read = gpio_data_ro_postr,
578 },{ .name = "DATA_1_RO",
579 .decode.addr = A_DATA_1_RO,
580 .rsvd = 0xfc000000,
581 .ro = 0xffffffff,
582 .post_read = gpio_data_ro_postr,
583 },{ .name = "DATA_2_RO",
584 .decode.addr = A_DATA_2_RO,
585 .rsvd = 0xfc000000,
586 .ro = 0xffffffff,
587 .post_read = gpio_data_ro_postr,
588 },{ .name = "DATA_3_RO",
589 .decode.addr = A_DATA_3_RO,
590 .ro = 0xffffffff,
591 .post_read = gpio_data_ro_postr,
592 },{ .name = "DATA_4_RO",
593 .decode.addr = A_DATA_4_RO,
594 .ro = 0xffffffff,
595 .post_read = gpio_data_ro_postr,
596 },{ .name = "DATA_5_RO",
597 .decode.addr = A_DATA_5_RO,
598 .ro = 0xffffffff,
599 .post_read = gpio_data_ro_postr,
600 },{ .name = "DIRM_0", .decode.addr = A_DIRM_0,
601 .rsvd = 0xfc000000,
602 },{ .name = "OEN_0", .decode.addr = A_OEN_0,
603 .rsvd = 0xfc000000,
604 .pre_write = gpio_oen_prew,
605 },{ .name = "INT_MASK_0",
606 .decode.addr = A_INT_MASK_0,
607 .reset = 0x3ffffff,
608 .rsvd = 0xfc000000,
609 .ro = 0x3ffffff,
610 },{ .name = "INT_EN_0", .decode.addr = A_INT_EN_0,
611 .post_write = gpio_int_en_postw,
612 .rsvd = 0xfc000000,
613 },{ .name = "INT_DIS_0",
614 .decode.addr = A_INT_DIS_0,
615 .rsvd = 0xfc000000,
616 .post_write = gpio_int_dis_postw,
617 },{ .name = "INT_STAT_0",
618 .decode.addr = A_INT_STAT_0,
619 .w1c = 0x3ffffff,
620 .rsvd = 0xfc000000,
621 },{ .name = "INT_TYPE_0",
622 .decode.addr = A_INT_TYPE_0,
623 .rsvd = 0xfc000000,
624 .reset = 0x3ffffff,
625 },{ .name = "INT_POLARITY_0",
626 .decode.addr = A_INT_POLARITY_0,
627 .rsvd = 0xfc000000,
628 },{ .name = "INT_ANY_0",
629 .decode.addr = A_INT_ANY_0,
630 .rsvd = 0xfc000000,
631 },{ .name = "DIRM_1", .decode.addr = A_DIRM_1,
632 .rsvd = 0xfc000000,
633 },{ .name = "OEN_1", .decode.addr = A_OEN_1,
634 .rsvd = 0xfc000000,
635 .pre_write = gpio_oen_prew,
636 },{ .name = "INT_MASK_1",
637 .decode.addr = A_INT_MASK_1,
638 .reset = 0x3ffffff,
639 .rsvd = 0xfc000000,
640 .ro = 0x3ffffff,
641 },{ .name = "INT_EN_1", .decode.addr = A_INT_EN_1,
642 .rsvd = 0xfc000000,
643 .post_write = gpio_int_en_postw,
644 },{ .name = "INT_DIS_1",
645 .rsvd = 0xfc000000,
646 .decode.addr = A_INT_DIS_1,
647 .post_write = gpio_int_dis_postw,
648 },{ .name = "INT_STAT_1",
649 .decode.addr = A_INT_STAT_1,
650 .rsvd = 0xfc000000,
651 .w1c = 0x3ffffff,
652 },{ .name = "INT_TYPE_1",
653 .decode.addr = A_INT_TYPE_1,
654 .rsvd = 0xfc000000,
655 .reset = 0x3ffffff,
656 },{ .name = "INT_POLARITY_1",
657 .decode.addr = A_INT_POLARITY_1,
658 .rsvd = 0xfc000000,
659 },{ .name = "INT_ANY_1",
660 .decode.addr = A_INT_ANY_1,
661 .rsvd = 0xfc000000,
662 },{ .name = "DIRM_2", .decode.addr = A_DIRM_2,
663 .rsvd = 0xfc000000,
664 },{ .name = "OEN_2", .decode.addr = A_OEN_2,
665 .rsvd = 0xfc000000,
666 .pre_write = gpio_oen_prew,
667 },{ .name = "INT_MASK_2",
668 .decode.addr = A_INT_MASK_2,
669 .ro = 0x3ffffff,
670 .rsvd = 0xfc000000,
671 .reset = 0x3ffffff,
672 },{ .name = "INT_EN_2", .decode.addr = A_INT_EN_2,
673 .post_write = gpio_int_en_postw,
674 .rsvd = 0xfc000000,
675 },{ .name = "INT_DIS_2",
676 .decode.addr = A_INT_DIS_2,
677 .rsvd = 0xfc000000,
678 .post_write = gpio_int_dis_postw,
679 },{ .name = "INT_STAT_2",
680 .decode.addr = A_INT_STAT_2,
681 .rsvd = 0xfc000000,
682 .w1c = 0x3ffffff,
683 },{ .name = "INT_TYPE_2",
684 .decode.addr = A_INT_TYPE_2,
685 .rsvd = 0xfc000000,
686 .reset = 0x3ffffff,
687 },{ .name = "INT_POLARITY_2",
688 .decode.addr = A_INT_POLARITY_2,
689 .rsvd = 0xfc000000,
690 },{ .name = "INT_ANY_2",
691 .decode.addr = A_INT_ANY_2,
692 .rsvd = 0xfc000000,
693 },{ .name = "DIRM_3", .decode.addr = A_DIRM_3,
694 },{ .name = "OEN_3", .decode.addr = A_OEN_3,
695 .pre_write = gpio_oen_prew,
696 },{ .name = "INT_MASK_3",
697 .decode.addr = A_INT_MASK_3,
698 .ro = 0xffffffff,
699 .reset = 0xffffffff,
700 },{ .name = "INT_EN_3", .decode.addr = A_INT_EN_3,
701 .post_write = gpio_int_en_postw,
702 },{ .name = "INT_DIS_3",
703 .decode.addr = A_INT_DIS_3,
704 .post_write = gpio_int_dis_postw,
705 },{ .name = "INT_STAT_3",
706 .decode.addr = A_INT_STAT_3,
707 .w1c = 0xffffffff,
708 },{ .name = "INT_TYPE_3",
709 .decode.addr = A_INT_TYPE_3,
710 .reset = 0xffffffff,
711 },{ .name = "INT_POLARITY_3",
712 .decode.addr = A_INT_POLARITY_3,
713 },{ .name = "INT_ANY_3",
714 .decode.addr = A_INT_ANY_3,
715 },{ .name = "DIRM_4", .decode.addr = A_DIRM_4,
716 },{ .name = "OEN_4", .decode.addr = A_OEN_4,
717 .pre_write = gpio_oen_prew,
718 },{ .name = "INT_MASK_4",
719 .decode.addr = A_INT_MASK_4,
720 .ro = 0xffffffff,
721 .reset = 0xffffffff,
722 },{ .name = "INT_EN_4", .decode.addr = A_INT_EN_4,
723 .post_write = gpio_int_en_postw,
724 },{ .name = "INT_DIS_4",
725 .decode.addr = A_INT_DIS_4,
726 .post_write = gpio_int_dis_postw,
727 },{ .name = "INT_STAT_4",
728 .decode.addr = A_INT_STAT_4,
729 .w1c = 0xffffffff,
730 },{ .name = "INT_TYPE_4",
731 .decode.addr = A_INT_TYPE_4,
732 .reset = 0xffffffff,
733 },{ .name = "INT_POLARITY_4",
734 .decode.addr = A_INT_POLARITY_4,
735 },{ .name = "INT_ANY_4",
736 .decode.addr = A_INT_ANY_4,
737 },{ .name = "DIRM_5", .decode.addr = A_DIRM_5,
738 },{ .name = "OEN_5", .decode.addr = A_OEN_5,
739 .pre_write = gpio_oen_prew,
740 },{ .name = "INT_MASK_5",
741 .decode.addr = A_INT_MASK_5,
742 .ro = 0xffffffff,
743 .reset = 0xffffffff,
744 },{ .name = "INT_EN_5", .decode.addr = A_INT_EN_5,
745 .post_write = gpio_int_en_postw,
746 },{ .name = "INT_DIS_5",
747 .decode.addr = A_INT_DIS_5,
748 .post_write = gpio_int_dis_postw,
749 },{ .name = "INT_STAT_5",
750 .decode.addr = A_INT_STAT_5,
751 .w1c = 0xffffffff,
752 },{ .name = "INT_TYPE_5",
753 .decode.addr = A_INT_TYPE_5,
754 .reset = 0xffffffff,
755 },{ .name = "INT_POLARITY_5",
756 .decode.addr = A_INT_POLARITY_5,
757 },{ .name = "INT_ANY_5",
758 .decode.addr = A_INT_ANY_5,
759 },
760};
761
762static void gpio_reset(DeviceState *dev)
763{
764 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(dev);
765 unsigned int i;
766
767 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
768 dep_register_reset(&s->regs_info[i]);
769 }
770
771}
772
773static uint64_t gpio_read(void *opaque, hwaddr addr, unsigned size)
774{
775 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(opaque);
776 DepRegisterInfo *r = &s->regs_info[addr / 4];
777
778 if (!r->data) {
779 qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
780 object_get_canonical_path(OBJECT(s)),
781 addr);
782 return 0;
783 }
784 return dep_register_read(r);
785}
786
787static void gpio_write(void *opaque, hwaddr addr, uint64_t value,
788 unsigned size)
789{
790 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(opaque);
791 DepRegisterInfo *r = &s->regs_info[addr / 4];
792
793 if (!r->data) {
794 qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
795 object_get_canonical_path(OBJECT(s)),
796 addr, value);
797 return;
798 }
799 dep_register_write(r, value, ~0);
800 gpio_update_irq(s);
801}
802
803static const MemoryRegionOps gpio_ops = {
804 .read = gpio_read,
805 .write = gpio_write,
806 .endianness = DEVICE_LITTLE_ENDIAN,
807 .valid = {
808 .min_access_size = 4,
809 .max_access_size = 4,
810 },
811};
812
813static void gpio_realize(DeviceState *dev, Error **errp)
814{
815 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(dev);
816 const char *prefix = object_get_canonical_path(OBJECT(dev));
817 const char *gpios_name;
818 unsigned int i;
819
820 for (i = 0; i < ARRAY_SIZE(gpio_regs_info); ++i) {
821 DepRegisterInfo *r = &s->regs_info[gpio_regs_info[i].decode.addr / 4];
822
823 *r = (DepRegisterInfo) {
824 .data = (uint8_t *)&s->regs[
825 gpio_regs_info[i].decode.addr / 4],
826 .data_size = sizeof(uint32_t),
827 .access = &gpio_regs_info[i],
828 .debug = XLNX_ZYNQMP_GPIO_ERR_DEBUG,
829 .prefix = prefix,
830 .opaque = s,
831 };
832 }
833 s->gpio_out = g_new0(qemu_irq, ZYNQMP_NUM_GPIOS);
834 s->gpio_oen = g_new0(qemu_irq, ZYNQMP_NUM_OEN_SIGNALS);
835
836 gpios_name = g_strdup("zynqmp_gpio_out");
837 qdev_init_gpio_out_named(dev, s->gpio_out, gpios_name, ZYNQMP_NUM_GPIOS);
838 g_free((gpointer) gpios_name);
839
840 gpios_name = g_strdup("zynqmp_gpio_oen");
841 qdev_init_gpio_out_named(dev, s->gpio_oen, gpios_name,
842 ZYNQMP_NUM_OEN_SIGNALS);
843 g_free((gpointer) gpios_name);
844
845 gpios_name = g_strdup("zynqmp_gpio_in");
846 qdev_init_gpio_in_named(dev, zynqmp_gpio_in_handler, gpios_name,
847 ZYNQMP_NUM_GPIOS);
848 g_free((gpointer)gpios_name);
849
850}
851
852static void gpio_init(Object *obj)
853{
854 XlnxZynqmpGPIO *s = XLNX_ZYNQMP_GPIO(obj);
855 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
856
857 memory_region_init_io(&s->iomem, obj, &gpio_ops, s,
858 TYPE_XLNX_ZYNQMP_GPIO, R_MAX * 4);
859 sysbus_init_mmio(sbd, &s->iomem);
860 sysbus_init_irq(sbd, &s->irq);
861}
862
863static const VMStateDescription vmstate_gpio = {
864 .name = TYPE_XLNX_ZYNQMP_GPIO,
865 .version_id = 1,
866 .minimum_version_id = 1,
867 .minimum_version_id_old = 1,
868 .fields = (VMStateField[]) {
869 VMSTATE_UINT32_ARRAY(regs, XlnxZynqmpGPIO, R_MAX),
870 VMSTATE_END_OF_LIST(),
871 }
872};
873
874static const FDTGenericGPIOSet xlnx_gpio_controller_gpios[] = {
875 {
876 .names = &fdt_generic_gpio_name_set_gpio,
877 .gpios = (FDTGenericGPIOConnection []) {
878 { .name = "zynqmp_gpio_out", .fdt_index = 0,
879 .range = ZYNQMP_NUM_GPIOS},
880 { .name = "zynqmp_gpio_oen", .fdt_index = ZYNQMP_NUM_GPIOS,
881 .range = ZYNQMP_NUM_OEN_SIGNALS},
882 { },
883 },
884 },
885 { },
886};
887
888static const FDTGenericGPIOSet xlnx_gpio_client_gpios[] = {
889 {
890 .names = &fdt_generic_gpio_name_set_gpio,
891 .gpios = (FDTGenericGPIOConnection []) {
892 { .name = "zynqmp_gpio_in", .fdt_index = 0,
893 .range = ZYNQMP_NUM_GPIOS },
894 { },
895 },
896 },
897 { },
898};
899
900static void gpio_class_init(ObjectClass *klass, void *data)
901{
902 DeviceClass *dc = DEVICE_CLASS(klass);
903 FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
904
905 dc->reset = gpio_reset;
906 dc->realize = gpio_realize;
907 dc->vmsd = &vmstate_gpio;
908 fggc->controller_gpios = xlnx_gpio_controller_gpios;
909 fggc->client_gpios = xlnx_gpio_client_gpios;
910}
911
912static const TypeInfo gpio_info = {
913 .name = TYPE_XLNX_ZYNQMP_GPIO,
914 .parent = TYPE_SYS_BUS_DEVICE,
915 .instance_size = sizeof(XlnxZynqmpGPIO),
916 .class_init = gpio_class_init,
917 .instance_init = gpio_init,
918 .interfaces = (InterfaceInfo[]) {
919 { TYPE_FDT_GENERIC_GPIO },
920 { }
921 },
922};
923
924static void gpio_register_types(void)
925{
926 type_register_static(&gpio_info);
927}
928
929type_init(gpio_register_types)
930