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