qemu/hw/misc/xilinx_zynqmp_pmu_local.c
<<
>>
Prefs
   1/*
   2 * QEMU model of the PMU_LOCAL Power Management Unit Local Register File
   3 *
   4 * Copyright (c) 2014 Xilinx Inc.
   5 *
   6 * Autogenerated by xregqemu.py 2014-09-01.
   7 * Written by Edgar E. Iglesias.
   8 *
   9 * Permission is hereby granted, free of charge, to any person obtaining a copy
  10 * of this software and associated documentation files (the "Software"), to deal
  11 * in the Software without restriction, including without limitation the rights
  12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13 * copies of the Software, and to permit persons to whom the Software is
  14 * furnished to do so, subject to the following conditions:
  15 *
  16 * The above copyright notice and this permission notice shall be included in
  17 * all copies or substantial portions of the Software.
  18 *
  19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25 * THE SOFTWARE.
  26 */
  27
  28#include "qemu/osdep.h"
  29#include "hw/sysbus.h"
  30#include "hw/register.h"
  31#include "qemu/bitops.h"
  32#include "qemu/log.h"
  33
  34#include "hw/fdt_generic_util.h"
  35
  36#ifndef XILINX_PMU_LOCAL_ERR_DEBUG
  37#define XILINX_PMU_LOCAL_ERR_DEBUG 0
  38#endif
  39
  40#define TYPE_XILINX_PMU_LOCAL "xlnx.pmu-local"
  41
  42#define XILINX_PMU_LOCAL(obj) \
  43     OBJECT_CHECK(PMULocal, (obj), TYPE_XILINX_PMU_LOCAL)
  44
  45REG32(ACPU0_PWR_CNTRL, 0x0)
  46    FIELD(ACPU0_PWR_CNTRL, ISOLATION, 1, 4)
  47    FIELD(ACPU0_PWR_CNTRL, PWR_GATES, 4, 0)
  48REG32(ACPU0_PWR_STATUS, 0x4)
  49    FIELD(ACPU0_PWR_STATUS, PWR_GATES, 4, 0)
  50REG32(ACPU1_PWR_CNTRL, 0x10)
  51    FIELD(ACPU1_PWR_CNTRL, ISOLATION, 1, 4)
  52    FIELD(ACPU1_PWR_CNTRL, PWR_GATES, 4, 0)
  53REG32(ACPU1_PWR_STATUS, 0x14)
  54    FIELD(ACPU1_PWR_STATUS, PWR_GATES, 4, 0)
  55REG32(ACPU2_PWR_CNTRL, 0x20)
  56    FIELD(ACPU2_PWR_CNTRL, ISOLATION, 1, 4)
  57    FIELD(ACPU2_PWR_CNTRL, PWR_GATES, 4, 0)
  58REG32(ACPU2_PWR_STATUS, 0x24)
  59    FIELD(ACPU2_PWR_STATUS, PWR_GATES, 4, 0)
  60REG32(ACPU3_PWR_CNTRL, 0x30)
  61    FIELD(ACPU3_PWR_CNTRL, ISOLATION, 1, 4)
  62    FIELD(ACPU3_PWR_CNTRL, PWR_GATES, 4, 0)
  63REG32(ACPU3_PWR_STATUS, 0x34)
  64    FIELD(ACPU3_PWR_STATUS, PWR_GATES, 4, 0)
  65REG32(PP0_PWR_CNTRL, 0x40)
  66    FIELD(PP0_PWR_CNTRL, ISOLATION, 1, 4)
  67    FIELD(PP0_PWR_CNTRL, PWR_GATES, 4, 0)
  68REG32(PP0_PWR_STATUS, 0x44)
  69    FIELD(PP0_PWR_STATUS, PWR_GATES, 4, 0)
  70REG32(PP1_PWR_CNTRL, 0x48)
  71    FIELD(PP1_PWR_CNTRL, ISOLATION, 1, 4)
  72    FIELD(PP1_PWR_CNTRL, PWR_GATES, 4, 0)
  73REG32(PP1_PWR_STATUS, 0x4c)
  74    FIELD(PP1_PWR_STATUS, PWR_GATES, 4, 0)
  75REG32(USB0_PWR_CNTRL, 0x60)
  76    FIELD(USB0_PWR_CNTRL, ISOLATION, 1, 4)
  77    FIELD(USB0_PWR_CNTRL, PWR_GATES, 4, 0)
  78REG32(USB0_PWR_STATUS, 0x64)
  79    FIELD(USB0_PWR_STATUS, PWR_GATES, 4, 0)
  80REG32(USB1_PWR_CNTRL, 0x70)
  81    FIELD(USB1_PWR_CNTRL, ISOLATION, 1, 4)
  82    FIELD(USB1_PWR_CNTRL, PWR_GATES, 4, 0)
  83REG32(USB1_PWR_STATUS, 0x74)
  84    FIELD(USB1_PWR_STATUS, PWR_GATES, 4, 0)
  85REG32(RPU_PWR_CNTRL, 0x80)
  86    FIELD(RPU_PWR_CNTRL, ISOLATION, 1, 4)
  87    FIELD(RPU_PWR_CNTRL, PWR_GATES, 4, 0)
  88REG32(RPU_PWR_STATUS, 0x84)
  89    FIELD(RPU_PWR_STATUS, PWR_GATES, 4, 0)
  90REG32(L2_PWR_CNTRL, 0xb0)
  91    FIELD(L2_PWR_CNTRL, BANK0, 1, 0)
  92REG32(L2_RET_CNTRL, 0xb4)
  93    FIELD(L2_RET_CNTRL, BANK0, 1, 0)
  94REG32(L2_CE_CNTRL, 0xb8)
  95    FIELD(L2_CE_CNTRL, BANK0, 1, 0)
  96REG32(L2_PWR_STATUS, 0xbc)
  97    FIELD(L2_PWR_STATUS, BANK0, 1, 0)
  98REG32(OCM_PWR_CNTRL, 0xc0)
  99    FIELD(OCM_PWR_CNTRL, BANK3, 1, 24)
 100    FIELD(OCM_PWR_CNTRL, BANK2, 1, 16)
 101    FIELD(OCM_PWR_CNTRL, BANK1, 1, 8)
 102    FIELD(OCM_PWR_CNTRL, BANK0, 1, 0)
 103REG32(OCM_RET_CNTRL, 0xc4)
 104    FIELD(OCM_RET_CNTRL, BANK3, 1, 3)
 105    FIELD(OCM_RET_CNTRL, BANK2, 1, 2)
 106    FIELD(OCM_RET_CNTRL, BANK1, 1, 1)
 107    FIELD(OCM_RET_CNTRL, BANK0, 1, 0)
 108REG32(OCM_CE_CNTRL, 0xc8)
 109    FIELD(OCM_CE_CNTRL, BANK3, 1, 3)
 110    FIELD(OCM_CE_CNTRL, BANK2, 1, 2)
 111    FIELD(OCM_CE_CNTRL, BANK1, 1, 1)
 112    FIELD(OCM_CE_CNTRL, BANK0, 1, 0)
 113REG32(OCM_PWR_STATUS, 0xcc)
 114    FIELD(OCM_PWR_STATUS, BANK3, 1, 24)
 115    FIELD(OCM_PWR_STATUS, BANK2, 1, 16)
 116    FIELD(OCM_PWR_STATUS, BANK1, 1, 8)
 117    FIELD(OCM_PWR_STATUS, BANK0, 1, 0)
 118REG32(TCM_PWR_CNTRL, 0xd0)
 119    FIELD(TCM_PWR_CNTRL, TCMB1, 1, 24)
 120    FIELD(TCM_PWR_CNTRL, TCMA1, 1, 16)
 121    FIELD(TCM_PWR_CNTRL, TCMB0, 1, 8)
 122    FIELD(TCM_PWR_CNTRL, TCMA0, 1, 0)
 123REG32(TCM_RET_CNTRL, 0xd4)
 124    FIELD(TCM_RET_CNTRL, TCMB1, 1, 3)
 125    FIELD(TCM_RET_CNTRL, TCMA1, 1, 2)
 126    FIELD(TCM_RET_CNTRL, TCMB0, 1, 1)
 127    FIELD(TCM_RET_CNTRL, TCMA0, 1, 0)
 128REG32(TCM_CE_CNTRL, 0xd8)
 129    FIELD(TCM_CE_CNTRL, TCMB1, 1, 3)
 130    FIELD(TCM_CE_CNTRL, TCMA1, 1, 2)
 131    FIELD(TCM_CE_CNTRL, TCMB0, 1, 1)
 132    FIELD(TCM_CE_CNTRL, TCMA0, 1, 0)
 133REG32(TCM_PWR_STATUS, 0xdc)
 134    FIELD(TCM_PWR_STATUS, TCMB1, 1, 24)
 135    FIELD(TCM_PWR_STATUS, TCMA1, 1, 16)
 136    FIELD(TCM_PWR_STATUS, TCMB0, 1, 8)
 137    FIELD(TCM_PWR_STATUS, TCMA0, 1, 0)
 138REG32(DOMAIN_ISO_CNTRL, 0xf0)
 139    FIELD(DOMAIN_ISO_CNTRL, LP_FP_LOCKED, 1, 31)
 140    FIELD(DOMAIN_ISO_CNTRL, FP_PL, 1, 5)
 141    FIELD(DOMAIN_ISO_CNTRL, LP_PL_PCAP, 1, 4)
 142    FIELD(DOMAIN_ISO_CNTRL, LP_PL_Non_PCAP, 1, 3)
 143    FIELD(DOMAIN_ISO_CNTRL, LP_FP_2, 1, 2)
 144    FIELD(DOMAIN_ISO_CNTRL, LP_FP_1, 1, 1)
 145    FIELD(DOMAIN_ISO_CNTRL, PMU, 1, 0)
 146REG32(LOC_PWR_STATE, 0x100)
 147    FIELD(LOC_PWR_STATE, USB1, 1, 21)
 148    FIELD(LOC_PWR_STATE, USB0, 1, 20)
 149    FIELD(LOC_PWR_STATE, OCM_BANK3, 1, 19)
 150    FIELD(LOC_PWR_STATE, OCM_BANK2, 1, 18)
 151    FIELD(LOC_PWR_STATE, OCM_BANK1, 1, 17)
 152    FIELD(LOC_PWR_STATE, OCM_BANK0, 1, 16)
 153    FIELD(LOC_PWR_STATE, TCM1B, 1, 15)
 154    FIELD(LOC_PWR_STATE, TCM1A, 1, 14)
 155    FIELD(LOC_PWR_STATE, TCM0B, 1, 13)
 156    FIELD(LOC_PWR_STATE, TCM0A, 1, 12)
 157    FIELD(LOC_PWR_STATE, R5_1, 1, 11)
 158    FIELD(LOC_PWR_STATE, R5_0, 1, 10)
 159    FIELD(LOC_PWR_STATE, L2, 1, 7)
 160    FIELD(LOC_PWR_STATE, GPU_PP1, 1, 5)
 161    FIELD(LOC_PWR_STATE, GPU_PP0, 1, 4)
 162    FIELD(LOC_PWR_STATE, ACPU3, 1, 3)
 163    FIELD(LOC_PWR_STATE, ACPU2, 1, 2)
 164    FIELD(LOC_PWR_STATE, ACPU1, 1, 1)
 165    FIELD(LOC_PWR_STATE, ACPU0, 1, 0)
 166REG32(LOC_AUX_PWR_STATE, 0x104)
 167    FIELD(LOC_AUX_PWR_STATE, ACPU3_EMUL, 1, 31)
 168    FIELD(LOC_AUX_PWR_STATE, ACPU2_EMUL, 1, 30)
 169    FIELD(LOC_AUX_PWR_STATE, ACPU1_EMUL, 1, 29)
 170    FIELD(LOC_AUX_PWR_STATE, ACPU0_EMUL, 1, 28)
 171    FIELD(LOC_AUX_PWR_STATE, RPU_EMUL, 1, 27)
 172    FIELD(LOC_AUX_PWR_STATE, OCM_BANK3, 1, 19)
 173    FIELD(LOC_AUX_PWR_STATE, OCM_BANK2, 1, 18)
 174    FIELD(LOC_AUX_PWR_STATE, OCM_BANK1, 1, 17)
 175    FIELD(LOC_AUX_PWR_STATE, OCM_BANK0, 1, 16)
 176    FIELD(LOC_AUX_PWR_STATE, TCM1B, 1, 15)
 177    FIELD(LOC_AUX_PWR_STATE, TCM1A, 1, 14)
 178    FIELD(LOC_AUX_PWR_STATE, TCM0B, 1, 13)
 179    FIELD(LOC_AUX_PWR_STATE, TCM0A, 1, 12)
 180    FIELD(LOC_AUX_PWR_STATE, L2, 1, 7)
 181REG32(LOCAL_RESET, 0x200)
 182    FIELD(LOCAL_RESET, CSU_RST, 1, 0)
 183REG32(LOCAL_CNTRL, 0x204)
 184    FIELD(LOCAL_CNTRL, BUS_CLK_DIS, 1, 0)
 185REG32(GPO1_READ, 0x214)
 186    FIELD(GPO1_READ, MIO_GPO, 6, 0)
 187REG32(GPO2_READ, 0x218)
 188    FIELD(GPO2_READ, DAP_RPU_WAKE_ACK, 1, 9)
 189    FIELD(GPO2_READ, DAP_FP_WAKE_ACK, 1, 8)
 190REG32(GPO3_READ, 0x21c)
 191REG32(GPI1_MASK, 0x224)
 192    FIELD(GPI1_MASK, APB_AIB_ERROR, 1, 31)
 193    FIELD(GPI1_MASK, AXI_AIB_ERROR, 1, 30)
 194    FIELD(GPI1_MASK, ERROR_REG2_INT, 1, 29)
 195    FIELD(GPI1_MASK, ERROR_REG1_INT, 1, 28)
 196    FIELD(GPI1_MASK, DBG_ACPU3_PWRUP_REQ, 1, 23)
 197    FIELD(GPI1_MASK, DBG_ACPU2_PWRUP_REQ, 1, 22)
 198    FIELD(GPI1_MASK, DBG_ACPU1_PWRUP_REQ, 1, 21)
 199    FIELD(GPI1_MASK, DBG_ACPU0_PWRUP_REQ, 1, 20)
 200    FIELD(GPI1_MASK, FPD_WAKE_GIC_PROX, 1, 16)
 201    FIELD(GPI1_MASK, MIO_WAKE, 6, 10)
 202    FIELD(GPI1_MASK, DAP_RPU_WAKE, 1, 9)
 203    FIELD(GPI1_MASK, DAP_FP_WAKE, 1, 8)
 204    FIELD(GPI1_MASK, USB1_WAKE, 1, 7)
 205    FIELD(GPI1_MASK, USB0_WAKE, 1, 6)
 206    FIELD(GPI1_MASK, R5_1_WAKE, 1, 5)
 207    FIELD(GPI1_MASK, R5_0_WAKE, 1, 4)
 208    FIELD(GPI1_MASK, ACPU3_WAKE, 1, 3)
 209    FIELD(GPI1_MASK, ACPU2_WAKE, 1, 2)
 210    FIELD(GPI1_MASK, ACPU1_WAKE, 1, 1)
 211    FIELD(GPI1_MASK, ACPU0_WAKE, 1, 0)
 212REG32(GPI2_MASK, 0x228)
 213    FIELD(GPI2_MASK, DBG_ACPU3_RST_REQ, 1, 23)
 214    FIELD(GPI2_MASK, DBG_ACPU2_RST_REQ, 1, 22)
 215    FIELD(GPI2_MASK, DBG_ACPU1_RST_REQ, 1, 21)
 216    FIELD(GPI2_MASK, DBG_ACPU0_RST_REQ, 1, 20)
 217    FIELD(GPI2_MASK, CP_ACPU3_RST_REQ, 1, 19)
 218    FIELD(GPI2_MASK, CP_ACPU2_RST_REQ, 1, 18)
 219    FIELD(GPI2_MASK, CP_ACPU1_RST_REQ, 1, 17)
 220    FIELD(GPI2_MASK, CP_ACPU0_RST_REQ, 1, 16)
 221    FIELD(GPI2_MASK, FP_LP_PWRDWN_ACK, 1, 6)
 222    FIELD(GPI2_MASK, R5_1_PWRDWN_REQ, 1, 5)
 223    FIELD(GPI2_MASK, R5_0_PWRDWN_REQ, 1, 4)
 224    FIELD(GPI2_MASK, ACPU3_PWRDWN_REQ, 1, 3)
 225    FIELD(GPI2_MASK, ACPU2_PWRDWN_REQ, 1, 2)
 226    FIELD(GPI2_MASK, ACPU1_PWRDWN_REQ, 1, 1)
 227    FIELD(GPI2_MASK, ACPU0_PWRDWN_REQ, 1, 0)
 228REG32(GPI3_MASK, 0x22c)
 229REG32(LOCAL_GEN_STORAGE0, 0x300)
 230REG32(LOCAL_GEN_STORAGE1, 0x304)
 231REG32(LOCAL_GEN_STORAGE2, 0x308)
 232REG32(LOCAL_GEN_STORAGE3, 0x30c)
 233REG32(PERS_LOC_GEN_STORAGE0, 0x310)
 234REG32(PERS_LOC_GEN_STORAGE1, 0x314)
 235REG32(PERS_LOC_GEN_STORAGE2, 0x318)
 236REG32(PERS_LOC_GEN_STORAGE3, 0x31c)
 237REG32(ADDR_ERROR_STATUS, 0x320)
 238    FIELD(ADDR_ERROR_STATUS, STATUS, 1, 0)
 239REG32(ADDR_ERROR_INT_MASK, 0x324)
 240    FIELD(ADDR_ERROR_INT_MASK, MASK, 1, 0)
 241REG32(ADDR_ERROR_INT_EN, 0x328)
 242    FIELD(ADDR_ERROR_INT_EN, EN, 1, 0)
 243REG32(ADDR_ERROR_INT_DIS, 0x32c)
 244    FIELD(ADDR_ERROR_INT_DIS, _, 1, 0)
 245REG32(MBISR_CNTRL, 0x330)
 246    FIELD(MBISR_CNTRL, FPD_GROUP, 1, 5)
 247    FIELD(MBISR_CNTRL, ENABLE, 1, 0)
 248REG32(MBISR_STATUS, 0x334)
 249    FIELD(MBISR_STATUS, PASS, 1, 4)
 250    FIELD(MBISR_STATUS, DONE, 1, 0)
 251REG32(PMU_PB_ERR, 0x338)
 252    FIELD(PMU_PB_ERR, PBERR_FLAG, 1, 31)
 253    FIELD(PMU_PB_ERR, PBERR_DATA, 31, 0)
 254REG32(PMU_SERV_ERR, 0x33c)
 255    FIELD(PMU_SERV_ERR, FWERR, 4, 28)
 256    FIELD(PMU_SERV_ERR, SERVERR_FLAG, 1, 23)
 257    FIELD(PMU_SERV_ERR, SERVERR_DATA, 20, 0)
 258REG32(PWR_ACK_ERR_LPD, 0x340)
 259REG32(PWR_ACK_ERR_FPD, 0x344)
 260REG32(SERV_LOGCLR_ERR, 0x348)
 261REG32(LOGCLR_TRIG, 0x350)
 262    FIELD(LOGCLR_TRIG, FP, 1, 17)
 263    FIELD(LOGCLR_TRIG, LP, 1, 16)
 264    FIELD(LOGCLR_TRIG, USB1, 1, 13)
 265    FIELD(LOGCLR_TRIG, USB0, 1, 12)
 266    FIELD(LOGCLR_TRIG, RPU, 1, 10)
 267    FIELD(LOGCLR_TRIG, PP1, 1, 7)
 268    FIELD(LOGCLR_TRIG, PP0, 1, 6)
 269    FIELD(LOGCLR_TRIG, ACPU3, 1, 3)
 270    FIELD(LOGCLR_TRIG, ACPU2, 1, 2)
 271    FIELD(LOGCLR_TRIG, ACPU1, 1, 1)
 272    FIELD(LOGCLR_TRIG, ACPU0, 1, 0)
 273REG32(LOGCLR_ACK, 0x354)
 274    FIELD(LOGCLR_ACK, FP, 1, 17)
 275    FIELD(LOGCLR_ACK, LP, 1, 16)
 276    FIELD(LOGCLR_ACK, USB1, 1, 13)
 277    FIELD(LOGCLR_ACK, USB0, 1, 12)
 278    FIELD(LOGCLR_ACK, RPU, 1, 10)
 279    FIELD(LOGCLR_ACK, PP1, 1, 7)
 280    FIELD(LOGCLR_ACK, PP0, 1, 6)
 281    FIELD(LOGCLR_ACK, ACPU3, 1, 3)
 282    FIELD(LOGCLR_ACK, ACPU2, 1, 2)
 283    FIELD(LOGCLR_ACK, ACPU1, 1, 1)
 284    FIELD(LOGCLR_ACK, ACPU0, 1, 0)
 285REG32(APU_WFI_STATUS, 0x360)
 286    FIELD(APU_WFI_STATUS, L2_WFI, 1, 16)
 287    FIELD(APU_WFI_STATUS, ACPU3_WFI, 1, 3)
 288    FIELD(APU_WFI_STATUS, ACPU2_WFI, 1, 2)
 289    FIELD(APU_WFI_STATUS, ACPU1_WFI, 1, 1)
 290    FIELD(APU_WFI_STATUS, ACPU0_WFI, 1, 0)
 291REG32(ECO_1, 0x400)
 292REG32(ECO_2, 0x404)
 293
 294#define R_MAX (R_ECO_2 + 1)
 295
 296typedef struct PMULocal {
 297    SysBusDevice parent_obj;
 298    MemoryRegion iomem;
 299    qemu_irq irq_addr_error;
 300    qemu_irq fpd_pwr_cntrl;
 301
 302    uint32_t regs[R_MAX];
 303    RegisterInfo regs_info[R_MAX];
 304} PMULocal;
 305
 306static void addr_error_update_irq(PMULocal *s)
 307{
 308    bool pending = s->regs[R_ADDR_ERROR_STATUS] & ~s->regs[R_ADDR_ERROR_INT_MASK];
 309    qemu_set_irq(s->irq_addr_error, pending);
 310}
 311
 312static void addr_error_status_postw(RegisterInfo *reg, uint64_t val64)
 313{
 314    PMULocal *s = XILINX_PMU_LOCAL(reg->opaque);
 315    addr_error_update_irq(s);
 316}
 317
 318static uint64_t addr_error_int_en_prew(RegisterInfo *reg, uint64_t val64)
 319{
 320    PMULocal *s = XILINX_PMU_LOCAL(reg->opaque);
 321    uint32_t val = val64;
 322
 323    s->regs[R_ADDR_ERROR_INT_MASK] &= ~val;
 324    addr_error_update_irq(s);
 325    return 0;
 326}
 327
 328static uint64_t addr_error_int_dis_prew(RegisterInfo *reg, uint64_t val64)
 329{
 330    PMULocal *s = XILINX_PMU_LOCAL(reg->opaque);
 331    uint32_t val = val64;
 332
 333    s->regs[R_ADDR_ERROR_INT_MASK] |= val;
 334    addr_error_update_irq(s);
 335    return 0;
 336}
 337
 338struct PwrStateMap {
 339    bool end;
 340    uint64_t addr;
 341    uint32_t mask;
 342    unsigned int bit;
 343    bool xor;
 344};
 345
 346static struct {
 347    bool end;
 348    uint64_t addr;
 349    unsigned int bit;
 350    uint32_t mask;
 351    struct PwrStateMap *map;
 352} power_reg_map [] = {
 353    {   .addr = A_ACPU0_PWR_CNTRL, .bit = 0, .mask = 0xf,
 354        .map = (struct PwrStateMap[]) {
 355            { .addr = A_ACPU0_PWR_STATUS, .bit = 0 },
 356            { .end = true }
 357        }
 358    },
 359    {   .addr = A_ACPU1_PWR_CNTRL, .bit = 0, .mask = 0xf,
 360        .map = (struct PwrStateMap[]) {
 361            { .addr = A_ACPU1_PWR_STATUS, .bit = 0 },
 362            { .end = true }
 363        }
 364    },
 365    {   .addr = A_ACPU2_PWR_CNTRL, .bit = 0, .mask = 0xf,
 366        .map = (struct PwrStateMap[]) {
 367            { .addr = A_ACPU2_PWR_STATUS, .bit = 0 },
 368            { .end = true }
 369        }
 370    },
 371    {   .addr = A_ACPU3_PWR_CNTRL, .bit = 0, .mask = 0xf,
 372        .map = (struct PwrStateMap[]) {
 373            { .addr = A_ACPU3_PWR_STATUS, .bit = 0 },
 374            { .end = true }
 375        }
 376    },
 377    {   .addr = A_PP0_PWR_CNTRL, .bit = 0, .mask = 0xf,
 378        .map = (struct PwrStateMap[]) {
 379            { .addr = A_PP0_PWR_STATUS, .bit = 0 },
 380            { .end = true }
 381        }
 382    },
 383    {   .addr = A_PP1_PWR_CNTRL, .bit = 0, .mask = 0xf,
 384        .map = (struct PwrStateMap[]) {
 385            { .addr = A_PP1_PWR_STATUS, .bit = 0 },
 386            { .end = true }
 387        }
 388    },
 389    {   .addr = A_USB0_PWR_CNTRL, .bit = 0, .mask = 0xf,
 390        .map = (struct PwrStateMap[]) {
 391            { .addr = A_USB0_PWR_STATUS, .bit = 0 },
 392            { .end = true }
 393        }
 394    },
 395    {   .addr = A_USB1_PWR_CNTRL, .bit = 0, .mask = 0xf,
 396        .map = (struct PwrStateMap[]) {
 397            { .addr = A_USB1_PWR_STATUS, .bit = 0 },
 398            { .end = true }
 399        }
 400    },
 401    {   .addr = A_RPU_PWR_CNTRL, .bit = 0, .mask = 0xf,
 402        .map = (struct PwrStateMap[]) {
 403            { .addr = A_RPU_PWR_STATUS, .bit = 0 },
 404            { .end = true }
 405        }
 406    },
 407
 408    /* RAMs.  */
 409    {   .addr = A_L2_PWR_CNTRL, .bit = 0, .mask = 0x1,
 410        .map = (struct PwrStateMap[]) {
 411            { .addr = A_L2_PWR_STATUS, .bit = 0 },
 412            { .end = true }
 413        }
 414    },
 415    {   .addr = A_OCM_PWR_CNTRL, .bit = 0, .mask = 0x01010101,
 416        .map = (struct PwrStateMap[]) {
 417            { .addr = A_OCM_PWR_STATUS, .bit = 0 },
 418            { .end = true }
 419        }
 420    },
 421    {   .addr = A_TCM_PWR_CNTRL, .bit = 0, .mask = 0x01010101,
 422        .map = (struct PwrStateMap[]) {
 423            { .addr = A_TCM_PWR_STATUS, .bit = 0 },
 424            { .end = true }
 425        }
 426    },
 427    { .end = true }
 428};
 429
 430static void prop_power_gate_postw(RegisterInfo *reg, uint64_t val64)
 431{
 432    PMULocal *s = XILINX_PMU_LOCAL(reg->opaque);
 433    uint64_t addr = reg->access->decode.addr;
 434    uint32_t val32 = val64;
 435    unsigned int i, n;
 436    uint32_t src_val;
 437
 438    for (i = 0; !power_reg_map[i].end; i++) {
 439        if (addr != power_reg_map[i].addr) {
 440            continue;
 441        }
 442        src_val = val32 & (power_reg_map[i].mask << power_reg_map[i].bit);
 443
 444        for (n = 0; !power_reg_map[i].map[n].end; n++) {
 445            uint64_t dst_addr = power_reg_map[i].map[n].addr;
 446            unsigned int dst_bit = power_reg_map[i].map[n].bit;
 447            uint32_t dst_mask;
 448            uint32_t dst_val;
 449
 450            dst_mask = power_reg_map[i].mask << dst_bit;
 451            if (power_reg_map[i].map[n].mask) {
 452                dst_mask = power_reg_map[i].map[n].mask << dst_bit;
 453            }
 454            dst_val = src_val ^ power_reg_map[i].map[n].xor;
 455            dst_val <<= dst_bit;
 456
 457            s->regs[dst_addr / 4] &= ~dst_mask;
 458            s->regs[dst_addr / 4] |= dst_val;
 459        }
 460    }
 461}
 462
 463#define FPD_ISOLATION_MASK \
 464    ( R_DOMAIN_ISO_CNTRL_LP_FP_1_MASK | \
 465      R_DOMAIN_ISO_CNTRL_LP_FP_2_MASK | \
 466      R_DOMAIN_ISO_CNTRL_FP_PL_MASK )
 467
 468/* Used to control FPD power state, depending on the state of the isolation
 469 * bits.
 470 * FIXME: At the moment, this looks like the best place from which to control
 471 * the state of the FPD. If a better location is found, this should be moved.
 472 */
 473static void domain_iso_cntrl_postw(RegisterInfo *reg, uint64_t val64)
 474{
 475    PMULocal *s = XILINX_PMU_LOCAL(reg->opaque);
 476    uint32_t val = val64;
 477
 478    if ((val & FPD_ISOLATION_MASK) == FPD_ISOLATION_MASK) {
 479        qemu_set_irq(s->fpd_pwr_cntrl, 0);
 480    } else {
 481        qemu_set_irq(s->fpd_pwr_cntrl, 1);
 482    }
 483}
 484
 485static RegisterAccessInfo pmu_local_regs_info[] = {
 486#define ACPU_PWR_REGDEF(n) \
 487    {   .name = "ACPU" #n "_PWR_CNTRL", \
 488        .decode.addr = A_ACPU ## n ## _PWR_CNTRL, \
 489        .reset = 0xf, \
 490        .rsvd = 0xffffffe0, \
 491        .ro = 0xffffffe0, \
 492        .post_write = prop_power_gate_postw, \
 493        .gpios = (RegisterGPIOMapping[]) { \
 494            { .name = "ACPU" #n "_PWR_CNTRL", .bit_pos = 0, .width = 1 }, \
 495            {}, \
 496        } \
 497    },{ .name = "ACPU" #n "_PWR_STATUS", \
 498        .decode.addr = A_ACPU ## n ## _PWR_STATUS, \
 499        .reset = 0xf, \
 500        .rsvd = 0xfffffff0, \
 501        .ro = 0xffffffff, \
 502    }
 503    ACPU_PWR_REGDEF(0),
 504    ACPU_PWR_REGDEF(1),
 505    ACPU_PWR_REGDEF(2),
 506    ACPU_PWR_REGDEF(3),
 507      { .name = "PP0_PWR_CNTRL",  .decode.addr = A_PP0_PWR_CNTRL,
 508        .reset = 0xf,
 509        .rsvd = 0xffffffe0,
 510        .ro = 0xffffffe0,
 511        .post_write = prop_power_gate_postw,
 512        .gpios = (RegisterGPIOMapping[]) {
 513            { .name = "PP0_PWR_CNTRL", .bit_pos = 0, .width = 1 },
 514            {},
 515        }
 516    },{ .name = "PP0_PWR_STATUS",  .decode.addr = A_PP0_PWR_STATUS,
 517        .reset = 0xf,
 518        .rsvd = 0xfffffff0,
 519        .ro = 0xffffffff,
 520    },{ .name = "PP1_PWR_CNTRL",  .decode.addr = A_PP1_PWR_CNTRL,
 521        .reset = 0xf,
 522        .rsvd = 0xffffffe0,
 523        .ro = 0xffffffe0,
 524        .post_write = prop_power_gate_postw,
 525        .gpios = (RegisterGPIOMapping[]) {
 526            { .name = "PP1_PWR_CNTRL", .bit_pos = 0, .width = 1 },
 527            {},
 528        }
 529    },{ .name = "PP1_PWR_STATUS",  .decode.addr = A_PP1_PWR_STATUS,
 530        .reset = 0xf,
 531        .rsvd = 0xfffffff0,
 532        .ro = 0xffffffff,
 533    },{ .name = "USB0_PWR_CNTRL",  .decode.addr = A_USB0_PWR_CNTRL,
 534        .reset = 0xf,
 535        .rsvd = 0xffffffe0,
 536        .ro = 0xffffffe0,
 537        .post_write = prop_power_gate_postw,
 538        .gpios = (RegisterGPIOMapping[]) {
 539            { .name = "USB0_PWR_CNTRL", .bit_pos = 0, .width = 1 },
 540            {},
 541        }
 542    },{ .name = "USB0_PWR_STATUS",  .decode.addr = A_USB0_PWR_STATUS,
 543        .reset = 0xf,
 544        .rsvd = 0xfffffff0,
 545        .ro = 0xffffffff,
 546    },{ .name = "USB1_PWR_CNTRL",  .decode.addr = A_USB1_PWR_CNTRL,
 547        .reset = 0xf,
 548        .rsvd = 0xffffffe0,
 549        .ro = 0xffffffe0,
 550        .post_write = prop_power_gate_postw,
 551        .gpios = (RegisterGPIOMapping[]) {
 552            { .name = "USB1_PWR_CNTRL", .bit_pos = 0, .width = 1 },
 553            {},
 554        }
 555    },{ .name = "USB1_PWR_STATUS",  .decode.addr = A_USB1_PWR_STATUS,
 556        .reset = 0xf,
 557        .rsvd = 0xfffffff0,
 558        .ro = 0xffffffff,
 559    },{ .name = "RPU_PWR_CNTRL",  .decode.addr = A_RPU_PWR_CNTRL,
 560        .reset = 0xf,
 561        .rsvd = 0xffffffe0,
 562        .ro = 0xffffffe0,
 563        .post_write = prop_power_gate_postw,
 564        .gpios = (RegisterGPIOMapping[]) {
 565            { .name = "RPU_PWR_CNTRL", .bit_pos = 0, .width = 1 },
 566            {},
 567        }
 568    },{ .name = "RPU_PWR_STATUS",  .decode.addr = A_RPU_PWR_STATUS,
 569        .reset = 0xf,
 570        .rsvd = 0xfffffff0,
 571        .ro = 0xffffffff,
 572    },{ .name = "L2_PWR_CNTRL",  .decode.addr = A_L2_PWR_CNTRL,
 573        .reset = 0x1,
 574        .rsvd = 0xfffffffe,
 575        .ro = 0xfffffffe,
 576        .post_write = prop_power_gate_postw,
 577        .gpios = (RegisterGPIOMapping[]) {
 578            { .name = "L2_PWR_CNTRL", .bit_pos = 0, .width = 1 },
 579            {},
 580        }
 581    },{ .name = "L2_RET_CNTRL",  .decode.addr = A_L2_RET_CNTRL,
 582        .rsvd = 0xfffffffe,
 583        .ro = 0xfffffffe,
 584        .gpios = (RegisterGPIOMapping[]) {
 585            { .name = "L2_RET_CNTRL", .bit_pos = 0, .width = 1 },
 586            {},
 587        }
 588    },{ .name = "L2_CE_CNTRL",  .decode.addr = A_L2_CE_CNTRL,
 589        .reset = 0x1,
 590        .rsvd = 0xfffffffe,
 591        .ro = 0xfffffffe,
 592    },{ .name = "L2_PWR_STATUS",  .decode.addr = A_L2_PWR_STATUS,
 593        .reset = 0x1,
 594        .rsvd = 0xfffffffe,
 595        .ro = 0xffffffff,
 596    },{ .name = "OCM_PWR_CNTRL",  .decode.addr = A_OCM_PWR_CNTRL,
 597        .reset = 0x1010101,
 598        .rsvd = 0xfefefefe,
 599        .ro = 0xfefefefe,
 600        .post_write = prop_power_gate_postw,
 601        .gpios = (RegisterGPIOMapping[]) {
 602            { .name = "OCM_PWR_CNTRL_BANK0", .bit_pos = 0, .width = 1 },
 603            { .name = "OCM_PWR_CNTRL_BANK1", .bit_pos = 8, .width = 1 },
 604            { .name = "OCM_PWR_CNTRL_BANK2", .bit_pos = 16, .width = 1 },
 605            { .name = "OCM_PWR_CNTRL_BANK3", .bit_pos = 24, .width = 1 },
 606            {},
 607        }
 608    },{ .name = "OCM_RET_CNTRL",  .decode.addr = A_OCM_RET_CNTRL,
 609        .rsvd = 0xfffffff0,
 610        .ro = 0xfffffff0,
 611        .gpios = (RegisterGPIOMapping[]) {
 612            { .name = "OCM_RET_CNTRL_BANK0", .bit_pos = 0, .width = 1 },
 613            { .name = "OCM_RET_CNTRL_BANK1", .bit_pos = 1, .width = 1 },
 614            { .name = "OCM_RET_CNTRL_BANK2", .bit_pos = 2, .width = 1 },
 615            { .name = "OCM_RET_CNTRL_BANK3", .bit_pos = 3, .width = 1 },
 616            {},
 617        }
 618    },{ .name = "OCM_CE_CNTRL",  .decode.addr = A_OCM_CE_CNTRL,
 619        .reset = 0xf,
 620        .rsvd = 0xfffffff0,
 621        .ro = 0xfffffff0,
 622    },{ .name = "OCM_PWR_STATUS",  .decode.addr = A_OCM_PWR_STATUS,
 623        .reset = 0x1010101,
 624        .rsvd = 0xfefefefe,
 625        .ro = 0xffffffff,
 626    },{ .name = "TCM_PWR_CNTRL",  .decode.addr = A_TCM_PWR_CNTRL,
 627        .reset = 0x1010101,
 628        .rsvd = 0xfefefefe,
 629        .ro = 0xfefefefe,
 630        .post_write = prop_power_gate_postw,
 631        .gpios = (RegisterGPIOMapping[]) {
 632            { .name = "TCM_PWR_CNTRL_A0", .bit_pos = 0, .width = 1 },
 633            { .name = "TCM_PWR_CNTRL_B0", .bit_pos = 8, .width = 1 },
 634            { .name = "TCM_PWR_CNTRL_A1", .bit_pos = 16, .width = 1 },
 635            { .name = "TCM_PWR_CNTRL_B1", .bit_pos = 24, .width = 1 },
 636            {},
 637        }
 638    },{ .name = "TCM_RET_CNTRL",  .decode.addr = A_TCM_RET_CNTRL,
 639        .rsvd = 0xfffffff0,
 640        .ro = 0xfffffff0,
 641        .gpios = (RegisterGPIOMapping[]) {
 642            { .name = "TCM_RET_CNTRL_A0", .bit_pos = 0, .width = 1 },
 643            { .name = "TCM_RET_CNTRL_B0", .bit_pos = 1, .width = 1 },
 644            { .name = "TCM_RET_CNTRL_A1", .bit_pos = 2, .width = 1 },
 645            { .name = "TCM_RET_CNTRL_B1", .bit_pos = 3, .width = 1 },
 646            {},
 647        }
 648    },{ .name = "TCM_CE_CNTRL",  .decode.addr = A_TCM_CE_CNTRL,
 649        .reset = 0xf,
 650        .rsvd = 0xfffffff0,
 651        .ro = 0xfffffff0,
 652    },{ .name = "TCM_PWR_STATUS",  .decode.addr = A_TCM_PWR_STATUS,
 653        .reset = 0x1010101,
 654        .rsvd = 0xfefefefe,
 655        .ro = 0xffffffff,
 656    },{ .name = "DOMAIN_ISO_CNTRL",  .decode.addr = A_DOMAIN_ISO_CNTRL,
 657        .reset = 0x00000028,
 658        .rsvd = 0x7fffffc0,
 659        .ro = 0x7fffffc0,
 660        .post_write = domain_iso_cntrl_postw,
 661    },{ .name = "LOC_PWR_STATE",  .decode.addr = A_LOC_PWR_STATE,
 662        .reset = 0x3ffcbf,
 663        .rsvd = 0xffc00340,
 664        .ro = 0xffc00340,
 665    },{ .name = "LOC_AUX_PWR_STATE",  .decode.addr = A_LOC_AUX_PWR_STATE,
 666        .reset = 0xff080,
 667        .rsvd = 0x7f00f7f,
 668        .ro = 0x7f00f00,
 669    },{ .name = "LOCAL_RESET",  .decode.addr = A_LOCAL_RESET,
 670        .reset = 0x1,
 671        .rsvd = 0xfffffffe,
 672        .ro = 0xfffffffe,
 673        .inhibit_reset = 1u << 31,
 674        .gpios = (RegisterGPIOMapping[]) {
 675            { .name = "CSU_RST", .bit_pos = 0, .width = 1 },
 676            {},
 677        }
 678    },{ .name = "LOCAL_CNTRL",  .decode.addr = A_LOCAL_CNTRL,
 679        .rsvd = 0xfffffffe,
 680        .ro = 0xfffffffe,
 681    },{ .name = "GPO1_READ",  .decode.addr = A_GPO1_READ,
 682        .rsvd = 0xffffffc0,
 683        .ro = 0xffffffff,
 684    },{ .name = "GPO2_READ",  .decode.addr = A_GPO2_READ,
 685        .rsvd = 0xfffffcff,
 686        .ro = 0xffffffff,
 687    },{ .name = "GPO3_READ",  .decode.addr = A_GPO3_READ,
 688        .ro = 0xffffffff,
 689    },{ .name = "GPI1_MASK",  .decode.addr = A_GPI1_MASK,
 690        .rsvd = 0xf0e0000,
 691        .ro = 0xf0e0000,
 692        .gpios = (RegisterGPIOMapping[]) {
 693            { .name = "GPI1_ENABLE", .bit_pos = 0, .width = 32 },
 694            {},
 695        }
 696    },{ .name = "GPI2_MASK",  .decode.addr = A_GPI2_MASK,
 697        .rsvd = 0xff00ff80,
 698        .ro = 0xff00ff80,
 699        .gpios = (RegisterGPIOMapping[]) {
 700            { .name = "GPI2_ENABLE", .bit_pos = 0, .width = 32 },
 701            {},
 702        }
 703    },{ .name = "GPI3_MASK",  .decode.addr = A_GPI3_MASK,
 704    },{ .name = "LOCAL_GEN_STORAGE0",  .decode.addr = A_LOCAL_GEN_STORAGE0,
 705    },{ .name = "LOCAL_GEN_STORAGE1",  .decode.addr = A_LOCAL_GEN_STORAGE1,
 706    },{ .name = "LOCAL_GEN_STORAGE2",  .decode.addr = A_LOCAL_GEN_STORAGE2,
 707    },{ .name = "LOCAL_GEN_STORAGE3",  .decode.addr = A_LOCAL_GEN_STORAGE3,
 708    },{ .name = "PERS_LOC_GEN_STORAGE0",  .decode.addr = A_PERS_LOC_GEN_STORAGE0,
 709    },{ .name = "PERS_LOC_GEN_STORAGE1",  .decode.addr = A_PERS_LOC_GEN_STORAGE1,
 710    },{ .name = "PERS_LOC_GEN_STORAGE2",  .decode.addr = A_PERS_LOC_GEN_STORAGE2,
 711    },{ .name = "PERS_LOC_GEN_STORAGE3",  .decode.addr = A_PERS_LOC_GEN_STORAGE3,
 712    },{ .name = "ADDR_ERROR_STATUS",  .decode.addr = A_ADDR_ERROR_STATUS,
 713        .w1c = 0x1,
 714        .post_write = addr_error_status_postw,
 715    },{ .name = "ADDR_ERROR_INT_MASK",  .decode.addr = A_ADDR_ERROR_INT_MASK,
 716        .reset = 0x1,
 717        .ro = 0x1,
 718    },{ .name = "ADDR_ERROR_INT_EN",  .decode.addr = A_ADDR_ERROR_INT_EN,
 719        .pre_write = addr_error_int_en_prew,
 720    },{ .name = "ADDR_ERROR_INT_DIS",  .decode.addr = A_ADDR_ERROR_INT_DIS,
 721        .pre_write = addr_error_int_dis_prew,
 722    },{ .name = "MBISR_CNTRL",  .decode.addr = A_MBISR_CNTRL,
 723        .rsvd = 0xffffffde,
 724        .ro = 0xffffffde,
 725    },{ .name = "MBISR_STATUS",  .decode.addr = A_MBISR_STATUS,
 726        .rsvd = 0xffffffee,
 727        .ro = 0xffffffff,
 728    },{ .name = "PMU_PB_ERR",  .decode.addr = A_PMU_PB_ERR,
 729    },{ .name = "PMU_SERV_ERR",  .decode.addr = A_PMU_SERV_ERR,
 730        .rsvd = 0xf700000,
 731        .ro = 0xf700000,
 732    },{ .name = "PWR_ACK_ERR_LPD",  .decode.addr = A_PWR_ACK_ERR_LPD,
 733    },{ .name = "PWR_ACK_ERR_FPD",  .decode.addr = A_PWR_ACK_ERR_FPD,
 734    },{ .name = "SERV_LOGCLR_ERR",  .decode.addr = A_SERV_LOGCLR_ERR,
 735    },{ .name = "LOGCLR_TRIG",  .decode.addr = A_LOGCLR_TRIG,
 736        .rsvd = 0xfffccb30,
 737    },{ .name = "LOGCLR_ACK",  .decode.addr = A_LOGCLR_ACK,
 738        .rsvd = 0xfffccb30,
 739        .ro = 0xffffffff,
 740    },{ .name = "APU_WFI_STATUS",  .decode.addr = A_APU_WFI_STATUS,
 741        .rsvd = 0xfffefff0,
 742        .ro = 0xffffffff,
 743    },{ .name = "ECO_1",  .decode.addr = A_ECO_1,
 744    },{ .name = "ECO_2",  .decode.addr = A_ECO_2,
 745    }
 746};
 747
 748static void pmu_local_reset(DeviceState *dev)
 749{
 750    PMULocal *s = XILINX_PMU_LOCAL(dev);
 751    unsigned int i;
 752
 753    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
 754        register_reset(&s->regs_info[i]);
 755    }
 756
 757    /*
 758     * since post_write is not called on register_reset, we have to manually
 759     * call the post_write function for the DOMAIN_ISO_CNTRL register to
 760     * ensure that the FPD power state is updated correctly on reset
 761     */
 762    domain_iso_cntrl_postw(&s->regs_info[R_DOMAIN_ISO_CNTRL],
 763                            s->regs[R_DOMAIN_ISO_CNTRL]);
 764
 765    addr_error_update_irq(s);
 766}
 767
 768static uint64_t pmu_local_read(void *opaque, hwaddr addr, unsigned size)
 769{
 770    PMULocal *s = XILINX_PMU_LOCAL(opaque);
 771    RegisterInfo *r = &s->regs_info[addr / 4];
 772
 773    if (!r->data) {
 774        qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
 775                 object_get_canonical_path(OBJECT(s)),
 776                 addr);
 777        AF_DP32(s->regs, ADDR_ERROR_STATUS, STATUS, true);
 778        addr_error_update_irq(s);
 779        return 0;
 780    }
 781    return register_read(r);
 782}
 783
 784static void pmu_local_write(void *opaque, hwaddr addr, uint64_t value,
 785                      unsigned size)
 786{
 787    PMULocal *s = XILINX_PMU_LOCAL(opaque);
 788    RegisterInfo *r = &s->regs_info[addr / 4];
 789
 790    if (!r->data) {
 791        qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
 792                 object_get_canonical_path(OBJECT(s)),
 793                 addr, value);
 794        AF_DP32(s->regs, ADDR_ERROR_STATUS, STATUS, true);
 795        addr_error_update_irq(s);
 796        return;
 797    }
 798    register_write(r, value, ~0);
 799}
 800
 801static const MemoryRegionOps pmu_local_ops = {
 802    .read = pmu_local_read,
 803    .write = pmu_local_write,
 804    .endianness = DEVICE_LITTLE_ENDIAN,
 805    .valid = {
 806        .min_access_size = 4,
 807        .max_access_size = 4,
 808    },
 809};
 810
 811static void pmu_local_realize(DeviceState *dev, Error **errp)
 812{
 813    PMULocal *s = XILINX_PMU_LOCAL(dev);
 814    const char *prefix = object_get_canonical_path(OBJECT(dev));
 815    unsigned int i;
 816
 817    for (i = 0; i < ARRAY_SIZE(pmu_local_regs_info); ++i) {
 818        RegisterInfo *r = &s->regs_info[pmu_local_regs_info[i].decode.addr/4];
 819
 820        *r = (RegisterInfo) {
 821            .data = (uint8_t *)&s->regs[
 822                    pmu_local_regs_info[i].decode.addr/4],
 823            .data_size = sizeof(uint32_t),
 824            .access = &pmu_local_regs_info[i],
 825            .debug = XILINX_PMU_LOCAL_ERR_DEBUG,
 826            .prefix = prefix,
 827            .opaque = s,
 828        };
 829        register_init(r);
 830        qdev_pass_all_gpios(DEVICE(r), dev);
 831    }
 832    qdev_init_gpio_out_named(dev, &s->fpd_pwr_cntrl, "fpd_pwr_cntrl", 1);
 833}
 834
 835static void pmu_local_init(Object *obj)
 836{
 837    PMULocal *s = XILINX_PMU_LOCAL(obj);
 838    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 839
 840    memory_region_init_io(&s->iomem, obj, &pmu_local_ops, s,
 841                          TYPE_XILINX_PMU_LOCAL, R_MAX * 4);
 842    sysbus_init_mmio(sbd, &s->iomem);
 843    sysbus_init_irq(sbd, &s->irq_addr_error);
 844}
 845
 846static const VMStateDescription vmstate_pmu_local = {
 847    .name = TYPE_XILINX_PMU_LOCAL,
 848    .version_id = 1,
 849    .minimum_version_id = 1,
 850    .minimum_version_id_old = 1,
 851    .fields = (VMStateField[]) {
 852        VMSTATE_UINT32_ARRAY(regs, PMULocal, R_MAX),
 853        VMSTATE_END_OF_LIST(),
 854    }
 855};
 856
 857static const FDTGenericGPIOSet pmu_local_controller_gpios[] = {
 858    {
 859       .names = &fdt_generic_gpio_name_set_gpio,
 860       .gpios = (FDTGenericGPIOConnection []) {
 861            { .name = "CSU_RST",   .fdt_index = 0 },
 862            { .name = "ACPU0_PWR_CNTRL",   .fdt_index = 1 },
 863            { .name = "ACPU1_PWR_CNTRL",   .fdt_index = 2 },
 864            { .name = "ACPU2_PWR_CNTRL",   .fdt_index = 3 },
 865            { .name = "ACPU3_PWR_CNTRL",   .fdt_index = 4 },
 866            { .name = "PP0_PWR_CNTRL",     .fdt_index = 5 },
 867            { .name = "PP1_PWR_CNTRL",     .fdt_index = 6 },
 868            { .name = "USB0_PWR_CNTRL",    .fdt_index = 7 },
 869            { .name = "USB1_PWR_CNTRL",    .fdt_index = 8 },
 870            { .name = "RPU_PWR_CNTRL",     .fdt_index = 9 },
 871            { .name = "L2_PWR_CNTRL",      .fdt_index = 10 },
 872            { .name = "L2_RET_CNTRL",      .fdt_index = 11 },
 873            { .name = "OCM_PWR_CNTRL_BANK0",    .fdt_index = 12 },
 874            { .name = "OCM_PWR_CNTRL_BANK1",    .fdt_index = 13 },
 875            { .name = "OCM_PWR_CNTRL_BANK2",    .fdt_index = 14 },
 876            { .name = "OCM_PWR_CNTRL_BANK3",    .fdt_index = 15 },
 877            { .name = "OCM_RET_CNTRL_BANK0",    .fdt_index = 16 },
 878            { .name = "OCM_RET_CNTRL_BANK1",    .fdt_index = 17 },
 879            { .name = "OCM_RET_CNTRL_BANK2",    .fdt_index = 18 },
 880            { .name = "OCM_RET_CNTRL_BANK3",    .fdt_index = 19 },
 881            { .name = "TCM_PWR_CNTRL_A0",     .fdt_index = 20 },
 882            { .name = "TCM_PWR_CNTRL_B0",     .fdt_index = 21 },
 883            { .name = "TCM_PWR_CNTRL_A1",     .fdt_index = 22 },
 884            { .name = "TCM_PWR_CNTRL_B1",     .fdt_index = 23 },
 885            { .name = "TCM_RET_CNTRL_A0",     .fdt_index = 24 },
 886            { .name = "TCM_RET_CNTRL_B0",     .fdt_index = 25 },
 887            { .name = "TCM_RET_CNTRL_A1",     .fdt_index = 26 },
 888            { .name = "TCM_RET_CNTRL_B1",     .fdt_index = 27 },
 889            { .name = "fpd_pwr_cntrl",          .fdt_index = 28},
 890            { .name = "GPI1_ENABLE",            .fdt_index = 29},
 891            { .name = "GPI2_ENABLE",            .fdt_index = 30},
 892            { },
 893       },
 894    },
 895    { },
 896};
 897
 898static void pmu_local_class_init(ObjectClass *klass, void *data)
 899{
 900    DeviceClass *dc = DEVICE_CLASS(klass);
 901    FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
 902
 903    dc->reset = pmu_local_reset;
 904    dc->realize = pmu_local_realize;
 905    dc->vmsd = &vmstate_pmu_local;
 906    fggc->controller_gpios = pmu_local_controller_gpios;
 907}
 908
 909static const TypeInfo pmu_local_info = {
 910    .name          = TYPE_XILINX_PMU_LOCAL,
 911    .parent        = TYPE_SYS_BUS_DEVICE,
 912    .instance_size = sizeof(PMULocal),
 913    .class_init    = pmu_local_class_init,
 914    .instance_init = pmu_local_init,
 915    .interfaces    = (InterfaceInfo[]) {
 916        { TYPE_FDT_GENERIC_GPIO },
 917        { }
 918    },
 919};
 920
 921static void pmu_local_register_types(void)
 922{
 923    type_register_static(&pmu_local_info);
 924}
 925
 926type_init(pmu_local_register_types)
 927