qemu/hw/gpio/xlnx-zynqmp-gpio.c
<<
>>
Prefs
   1/*
   2 * QEMU model of the GPIO gpio Registers
   3 *
   4 * Copyright (c) 2017 Xilinx Inc.
   5 *
   6 * Partly autogenerated by xregqemu.py 2017-02-11.
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a copy
   9 * of this software and associated documentation files (the "Software"), to deal
  10 * in the Software without restriction, including without limitation the rights
  11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 * copies of the Software, and to permit persons to whom the Software is
  13 * furnished to do so, subject to the following conditions:
  14 *
  15 * The above copyright notice and this permission notice shall be included in
  16 * all copies or substantial portions of the Software.
  17 *
  18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24 * THE SOFTWARE.
  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/* Returns Bank number based on addr passed
 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    /* if mask high, interrupt disabled
 282     * if mask low, interrupt enabled
 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) || /* Falling Edge */
 297       (level == 1 && level_old == 0 && pol)) {   /* Raising Edge */
 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    /* Get the banks first pin number in s->gpio_out
 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        /* 'i' is pin-offset of the s->gpio_out
 333         * i - pin should provice bank-pin-offset */
 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    /* Accept the data only if gpio is set as input */
 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    /* BANK 0,1,2 have 26 pins each
 375     * BANK 3,4,5 have 32 pins each
 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    /* Clear the mask value from data*/
 397    data &= (1 << 16) - 1;
 398    data_old = s->regs[data_reg] & 0x0000FFFF;
 399    /* Pins corresponding to unmasked bits of maskw are allowed to update
 400     * i.e high bit in ~maskw */
 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    /* BANK 0,1,2 have 10 pins and
 424     * BANK 3,4,5 have 16 pins in
 425     * the upper-half of the bank
 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        /* Calculate the oen signal offset for pins mapped to mio */
 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        /* Calculate the oen signal offset for emios.
 489         * EMIO's would start from bank 3 */
 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        /* Change in the oen value should update the signal */
 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                /* No update to gpio pins after POR */
 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                                &reg_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