/*
 * QEMU model of the DDRC ddrc
 *
 * Copyright (c) 2015 Xilinx Inc.
 *
 * Autogenerated by xregqemu.py 2015-09-16.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "hw/register.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"

#ifndef XILINX_DDRC_ERR_DEBUG
#define XILINX_DDRC_ERR_DEBUG 0
#endif

#define TYPE_XILINX_DDRC "xlnx.zynqmp-ddrc"

#define XILINX_DDRC(obj) \
     OBJECT_CHECK(DDRC, (obj), TYPE_XILINX_DDRC)

REG32(MSTR, 0x0)
    FIELD(MSTR, DEVICE_CONFIG, 30, 2)
    FIELD(MSTR, FREQUENCY_MODE, 29, 1)
    FIELD(MSTR, ACTIVE_RANKS, 24, 2)
    FIELD(MSTR, BURST_RDWR, 16, 4)
    FIELD(MSTR, DLL_OFF_MODE, 15, 1)
    FIELD(MSTR, DATA_BUS_WIDTH, 12, 2)
    FIELD(MSTR, GEARDOWN_MODE, 11, 1)
    FIELD(MSTR, EN_2T_TIMING_MODE, 10, 1)
    FIELD(MSTR, BURSTCHOP, 9, 1)
    FIELD(MSTR, LPDDR4, 5, 1)
    FIELD(MSTR, DDR4, 4, 1)
    FIELD(MSTR, LPDDR3, 3, 1)
    FIELD(MSTR, LPDDR2, 2, 1)
    FIELD(MSTR, DDR3, 0, 1)
REG32(STAT, 0x4)
    FIELD(STAT, SELFREF_STATE, 8, 2)
    FIELD(STAT, SELFREF_TYPE, 4, 2)
    FIELD(STAT, OPERATING_MODE, 0, 3)
REG32(MRCTRL0, 0x10)
    FIELD(MRCTRL0, MR_WR, 31, 1)
    FIELD(MRCTRL0, MR_ADDR, 12, 4)
    FIELD(MRCTRL0, MR_RANK, 4, 2)
    FIELD(MRCTRL0, SW_INIT_INT, 3, 1)
    FIELD(MRCTRL0, PDA_EN, 2, 1)
    FIELD(MRCTRL0, MPR_EN, 1, 1)
    FIELD(MRCTRL0, MR_TYPE, 0, 1)
REG32(MRCTRL1, 0x14)
    FIELD(MRCTRL1, MR_DATA, 0, 18)
REG32(MRSTAT, 0x18)
    FIELD(MRSTAT, PDA_DONE, 8, 1)
    FIELD(MRSTAT, MR_WR_BUSY, 0, 1)
REG32(MRCTRL2, 0x1c)
REG32(DERATEEN, 0x20)
    FIELD(DERATEEN, RC_DERATE_VALUE, 8, 2)
    FIELD(DERATEEN, DERATE_BYTE, 4, 4)
    FIELD(DERATEEN, DERATE_VALUE, 1, 1)
    FIELD(DERATEEN, DERATE_ENABLE, 0, 1)
REG32(DERATEINT, 0x24)
REG32(PWRCTL, 0x30)
    FIELD(PWRCTL, STAY_IN_SELFREF, 6, 1)
    FIELD(PWRCTL, SELFREF_SW, 5, 1)
    FIELD(PWRCTL, MPSM_EN, 4, 1)
    FIELD(PWRCTL, EN_DFI_DRAM_CLK_DISABLE, 3, 1)
    FIELD(PWRCTL, DEEPPOWERDOWN_EN, 2, 1)
    FIELD(PWRCTL, POWERDOWN_EN, 1, 1)
    FIELD(PWRCTL, SELFREF_EN, 0, 1)
REG32(PWRTMG, 0x34)
    FIELD(PWRTMG, SELFREF_TO_X32, 16, 8)
    FIELD(PWRTMG, T_DPD_X4096, 8, 8)
    FIELD(PWRTMG, POWERDOWN_TO_X32, 0, 5)
REG32(HWLPCTL, 0x38)
    FIELD(HWLPCTL, HW_LP_IDLE_X32, 16, 12)
    FIELD(HWLPCTL, HW_LP_EXIT_IDLE_EN, 1, 1)
    FIELD(HWLPCTL, HW_LP_EN, 0, 1)
REG32(RFSHCTL0, 0x50)
    FIELD(RFSHCTL0, REFRESH_MARGIN, 20, 4)
    FIELD(RFSHCTL0, REFRESH_TO_X32, 12, 5)
    FIELD(RFSHCTL0, REFRESH_BURST, 4, 5)
    FIELD(RFSHCTL0, PER_BANK_REFRESH, 2, 1)
REG32(RFSHCTL1, 0x54)
    FIELD(RFSHCTL1, REFRESH_TIMER1_START_VALUE_X32, 16, 12)
    FIELD(RFSHCTL1, REFRESH_TIMER0_START_VALUE_X32, 0, 12)
REG32(RFSHCTL3, 0x60)
    FIELD(RFSHCTL3, REFRESH_MODE, 4, 3)
    FIELD(RFSHCTL3, REFRESH_UPDATE_LEVEL, 1, 1)
    FIELD(RFSHCTL3, DIS_AUTO_REFRESH, 0, 1)
REG32(RFSHTMG, 0x64)
    FIELD(RFSHTMG, T_RFC_NOM_X32, 16, 12)
    FIELD(RFSHTMG, LPDDR3_TREFBW_EN, 15, 1)
    FIELD(RFSHTMG, T_RFC_MIN, 0, 10)
REG32(ECCCFG0, 0x70)
    FIELD(ECCCFG0, DIS_SCRUB, 4, 1)
    FIELD(ECCCFG0, ECC_MODE, 0, 3)
REG32(ECCCFG1, 0x74)
    FIELD(ECCCFG1, DATA_POISON_BIT, 1, 1)
    FIELD(ECCCFG1, DATA_POISON_EN, 0, 1)
REG32(ECCSTAT, 0x78)
    FIELD(ECCSTAT, ECC_UNCORRECTED_ERR, 16, 4)
    FIELD(ECCSTAT, ECC_CORRECTED_ERR, 8, 4)
    FIELD(ECCSTAT, ECC_CORRECTED_BIT_NUM, 0, 7)
REG32(ECCCLR, 0x7c)
    FIELD(ECCCLR, ECC_CLR_UNCORR_ERR_CNT, 3, 1)
    FIELD(ECCCLR, ECC_CLR_CORR_ERR_CNT, 2, 1)
    FIELD(ECCCLR, ECC_CLR_UNCORR_ERR, 1, 1)
    FIELD(ECCCLR, ECC_CLR_CORR_ERR, 0, 1)
REG32(ECCERRCNT, 0x80)
    FIELD(ECCERRCNT, ECC_UNCORR_ERR_CNT, 16, 16)
    FIELD(ECCERRCNT, ECC_CORR_ERR_CNT, 0, 16)
REG32(ECCCADDR0, 0x84)
    FIELD(ECCCADDR0, ECC_CORR_RANK, 24, 1)
    FIELD(ECCCADDR0, ECC_CORR_ROW, 0, 18)
REG32(ECCCADDR1, 0x88)
    FIELD(ECCCADDR1, ECC_CORR_BG, 24, 2)
    FIELD(ECCCADDR1, ECC_CORR_BANK, 16, 3)
    FIELD(ECCCADDR1, ECC_CORR_COL, 0, 12)
REG32(ECCCSYN0, 0x8c)
REG32(ECCCSYN1, 0x90)
REG32(ECCCSYN2, 0x94)
    FIELD(ECCCSYN2, ECC_CORR_SYNDROMES_71_64, 0, 8)
REG32(ECCBITMASK0, 0x98)
REG32(ECCBITMASK1, 0x9c)
REG32(ECCBITMASK2, 0xa0)
    FIELD(ECCBITMASK2, ECC_CORR_BIT_MASK_71_64, 0, 8)
REG32(ECCUADDR0, 0xa4)
    FIELD(ECCUADDR0, ECC_UNCORR_RANK, 24, 1)
    FIELD(ECCUADDR0, ECC_UNCORR_ROW, 0, 18)
REG32(ECCUADDR1, 0xa8)
    FIELD(ECCUADDR1, ECC_UNCORR_BG, 24, 2)
    FIELD(ECCUADDR1, ECC_UNCORR_BANK, 16, 3)
    FIELD(ECCUADDR1, ECC_UNCORR_COL, 0, 12)
REG32(ECCUSYN0, 0xac)
REG32(ECCUSYN1, 0xb0)
REG32(ECCUSYN2, 0xb4)
    FIELD(ECCUSYN2, ECC_UNCORR_SYNDROMES_71_64, 0, 8)
REG32(ECCPOISONADDR0, 0xb8)
    FIELD(ECCPOISONADDR0, ECC_POISON_RANK, 24, 1)
    FIELD(ECCPOISONADDR0, ECC_POISON_COL, 0, 12)
REG32(ECCPOISONADDR1, 0xbc)
    FIELD(ECCPOISONADDR1, ECC_POISON_BG, 28, 2)
    FIELD(ECCPOISONADDR1, ECC_POISON_BANK, 24, 3)
    FIELD(ECCPOISONADDR1, ECC_POISON_ROW, 0, 18)
REG32(CRCPARCTL0, 0xc0)
    FIELD(CRCPARCTL0, RETRY_CTRLUPD_ENABLE, 15, 1)
    FIELD(CRCPARCTL0, DFI_ALERT_ERR_MAX_REACHED_INT_CLR, 8, 1)
    FIELD(CRCPARCTL0, DFI_ALERT_ERR_FATL_INT_CLR, 4, 1)
    FIELD(CRCPARCTL0, DFI_ALERT_ERR_CNT_CLR, 2, 1)
    FIELD(CRCPARCTL0, DFI_ALERT_ERR_INT_CLR, 1, 1)
    FIELD(CRCPARCTL0, DFI_ALERT_ERR_INT_EN, 0, 1)
REG32(CRCPARCTL1, 0xc4)
    FIELD(CRCPARCTL1, DFI_T_PHY_RDLAT, 24, 6)
    FIELD(CRCPARCTL1, ALERT_WAIT_FOR_SW, 9, 1)
    FIELD(CRCPARCTL1, CRC_PARITY_RETRY_ENABLE, 8, 1)
    FIELD(CRCPARCTL1, CRC_INC_DM, 7, 1)
    FIELD(CRCPARCTL1, CRC_ENABLE, 4, 1)
    FIELD(CRCPARCTL1, PARITY_ENABLE, 0, 1)
REG32(CRCPARCTL2, 0xc8)
    FIELD(CRCPARCTL2, T_PAR_ALERT_PW_MAX, 16, 9)
    FIELD(CRCPARCTL2, T_CRC_ALERT_PW_MAX, 8, 5)
    FIELD(CRCPARCTL2, RETRY_FIFO_MAX_HOLD_TIMER_X4, 0, 6)
REG32(CRCPARSTAT, 0xcc)
    FIELD(CRCPARSTAT, CMD_IN_ERR_WINDOW, 29, 1)
    FIELD(CRCPARSTAT, RETRY_OPERATING_MODE, 28, 1)
    FIELD(CRCPARSTAT, RETRY_CURRENT_STATE, 24, 4)
    FIELD(CRCPARSTAT, DFI_ALERT_ERR_FATL_CODE, 20, 3)
    FIELD(CRCPARSTAT, DFI_ALERT_ERR_NO_SW, 19, 1)
    FIELD(CRCPARSTAT, DFI_ALERT_ERR_MAX_REACHED_INT, 18, 1)
    FIELD(CRCPARSTAT, DFI_ALERT_ERR_FATL_INT, 17, 1)
    FIELD(CRCPARSTAT, DFI_ALERT_ERR_INT, 16, 1)
    FIELD(CRCPARSTAT, DFI_ALERT_ERR_CNT, 0, 16)
REG32(INIT0, 0xd0)
    FIELD(INIT0, SKIP_DRAM_INIT, 30, 2)
    FIELD(INIT0, POST_CKE_X1024, 16, 10)
    FIELD(INIT0, PRE_CKE_X1024, 0, 12)
REG32(INIT1, 0xd4)
    FIELD(INIT1, DRAM_RSTN_X1024, 16, 9)
    FIELD(INIT1, FINAL_WAIT_X32, 8, 7)
    FIELD(INIT1, PRE_OCD_X32, 0, 4)
REG32(INIT2, 0xd8)
    FIELD(INIT2, IDLE_AFTER_RESET_X32, 8, 8)
    FIELD(INIT2, MIN_STABLE_CLOCK_X1, 0, 4)
REG32(INIT3, 0xdc)
    FIELD(INIT3, MR, 16, 16)
    FIELD(INIT3, EMR, 0, 16)
REG32(INIT4, 0xe0)
    FIELD(INIT4, EMR2, 16, 16)
    FIELD(INIT4, EMR3, 0, 16)
REG32(INIT5, 0xe4)
    FIELD(INIT5, DEV_ZQINIT_X32, 16, 8)
    FIELD(INIT5, MAX_AUTO_INIT_X1024, 0, 10)
REG32(INIT6, 0xe8)
    FIELD(INIT6, MR4, 16, 16)
    FIELD(INIT6, MR5, 0, 16)
REG32(INIT7, 0xec)
    FIELD(INIT7, MR6, 16, 16)
REG32(DIMMCTL, 0xf0)
    FIELD(DIMMCTL, DIMM_DIS_BG_MIRRORING, 5, 1)
    FIELD(DIMMCTL, MRS_BG1_EN, 4, 1)
    FIELD(DIMMCTL, MRS_A17_EN, 3, 1)
    FIELD(DIMMCTL, DIMM_OUTPUT_INV_EN, 2, 1)
    FIELD(DIMMCTL, DIMM_ADDR_MIRR_EN, 1, 1)
    FIELD(DIMMCTL, DIMM_STAGGER_CS_EN, 0, 1)
REG32(RANKCTL, 0xf4)
    FIELD(RANKCTL, DIFF_RANK_WR_GAP, 8, 4)
    FIELD(RANKCTL, DIFF_RANK_RD_GAP, 4, 4)
    FIELD(RANKCTL, MAX_RANK_RD, 0, 4)
REG32(DRAMTMG0, 0x100)
    FIELD(DRAMTMG0, WR2PRE, 24, 7)
    FIELD(DRAMTMG0, T_FAW, 16, 6)
    FIELD(DRAMTMG0, T_RAS_MAX, 8, 7)
    FIELD(DRAMTMG0, T_RAS_MIN, 0, 6)
REG32(DRAMTMG1, 0x104)
    FIELD(DRAMTMG1, T_XP, 16, 5)
    FIELD(DRAMTMG1, RD2PRE, 8, 5)
    FIELD(DRAMTMG1, T_RC, 0, 7)
REG32(DRAMTMG2, 0x108)
    FIELD(DRAMTMG2, WRITE_LATENCY, 24, 6)
    FIELD(DRAMTMG2, READ_LATENCY, 16, 6)
    FIELD(DRAMTMG2, RD2WR, 8, 6)
    FIELD(DRAMTMG2, WR2RD, 0, 6)
REG32(DRAMTMG3, 0x10c)
    FIELD(DRAMTMG3, T_MRW, 20, 10)
    FIELD(DRAMTMG3, T_MRD, 12, 6)
    FIELD(DRAMTMG3, T_MOD, 0, 10)
REG32(DRAMTMG4, 0x110)
    FIELD(DRAMTMG4, T_RCD, 24, 5)
    FIELD(DRAMTMG4, T_CCD, 16, 4)
    FIELD(DRAMTMG4, T_RRD, 8, 4)
    FIELD(DRAMTMG4, T_RP, 0, 5)
REG32(DRAMTMG5, 0x114)
    FIELD(DRAMTMG5, T_CKSRX, 24, 4)
    FIELD(DRAMTMG5, T_CKSRE, 16, 4)
    FIELD(DRAMTMG5, T_CKESR, 8, 6)
    FIELD(DRAMTMG5, T_CKE, 0, 5)
REG32(DRAMTMG6, 0x118)
    FIELD(DRAMTMG6, T_CKDPDE, 24, 4)
    FIELD(DRAMTMG6, T_CKDPDX, 16, 4)
    FIELD(DRAMTMG6, T_CKCSX, 0, 4)
REG32(DRAMTMG7, 0x11c)
    FIELD(DRAMTMG7, T_CKPDE, 8, 4)
    FIELD(DRAMTMG7, T_CKPDX, 0, 4)
REG32(DRAMTMG8, 0x120)
    FIELD(DRAMTMG8, T_XS_FAST_X32, 24, 7)
    FIELD(DRAMTMG8, T_XS_ABORT_X32, 16, 7)
    FIELD(DRAMTMG8, T_XS_DLL_X32, 8, 7)
    FIELD(DRAMTMG8, T_XS_X32, 0, 7)
REG32(DRAMTMG9, 0x124)
    FIELD(DRAMTMG9, DDR4_WR_PREAMBLE, 30, 1)
    FIELD(DRAMTMG9, T_CCD_S, 16, 3)
    FIELD(DRAMTMG9, T_RRD_S, 8, 4)
    FIELD(DRAMTMG9, WR2RD_S, 0, 6)
REG32(DRAMTMG10, 0x128)
    FIELD(DRAMTMG10, T_SYNC_GEAR, 16, 5)
    FIELD(DRAMTMG10, T_CMD_GEAR, 8, 5)
    FIELD(DRAMTMG10, T_GEAR_SETUP, 2, 2)
    FIELD(DRAMTMG10, T_GEAR_HOLD, 0, 2)
REG32(DRAMTMG11, 0x12c)
    FIELD(DRAMTMG11, POST_MPSM_GAP_X32, 24, 7)
    FIELD(DRAMTMG11, T_MPX_LH, 16, 5)
    FIELD(DRAMTMG11, T_MPX_S, 8, 2)
    FIELD(DRAMTMG11, T_CKMPE, 0, 5)
REG32(DRAMTMG12, 0x130)
    FIELD(DRAMTMG12, T_CMDCKE, 16, 2)
    FIELD(DRAMTMG12, T_CKEHCMD, 8, 4)
    FIELD(DRAMTMG12, T_MRD_PDA, 0, 5)
REG32(DRAMTMG13, 0x134)
    FIELD(DRAMTMG13, ODTLOFF, 24, 7)
    FIELD(DRAMTMG13, T_CCD_MW, 16, 6)
    FIELD(DRAMTMG13, T_PPD, 0, 3)
REG32(DRAMTMG14, 0x138)
    FIELD(DRAMTMG14, T_XSR, 0, 12)
REG32(ZQCTL0, 0x180)
    FIELD(ZQCTL0, DIS_AUTO_ZQ, 31, 1)
    FIELD(ZQCTL0, DIS_SRX_ZQCL, 30, 1)
    FIELD(ZQCTL0, ZQ_RESISTOR_SHARED, 29, 1)
    FIELD(ZQCTL0, DIS_MPSMX_ZQCL, 28, 1)
    FIELD(ZQCTL0, T_ZQ_LONG_NOP, 16, 11)
    FIELD(ZQCTL0, T_ZQ_SHORT_NOP, 0, 10)
REG32(ZQCTL1, 0x184)
    FIELD(ZQCTL1, T_ZQ_RESET_NOP, 20, 10)
    FIELD(ZQCTL1, T_ZQ_SHORT_INTERVAL_X1024, 0, 20)
REG32(ZQCTL2, 0x188)
    FIELD(ZQCTL2, ZQ_RESET, 0, 1)
REG32(ZQSTAT, 0x18c)
    FIELD(ZQSTAT, ZQ_RESET_BUSY, 0, 1)
REG32(DFITMG0, 0x190)
    FIELD(DFITMG0, DFI_T_CTRL_DELAY, 24, 5)
    FIELD(DFITMG0, DFI_RDDATA_USE_SDR, 23, 1)
    FIELD(DFITMG0, DFI_T_RDDATA_EN, 16, 6)
    FIELD(DFITMG0, DFI_WRDATA_USE_SDR, 15, 1)
    FIELD(DFITMG0, DFI_TPHY_WRDATA, 8, 6)
    FIELD(DFITMG0, DFI_TPHY_WRLAT, 0, 6)
REG32(DFITMG1, 0x194)
    FIELD(DFITMG1, DFI_T_CMD_LAT, 28, 4)
    FIELD(DFITMG1, DFI_T_PARIN_LAT, 24, 2)
    FIELD(DFITMG1, DFI_T_WRDATA_DELAY, 16, 5)
    FIELD(DFITMG1, DFI_T_DRAM_CLK_DISABLE, 8, 4)
    FIELD(DFITMG1, DFI_T_DRAM_CLK_ENABLE, 0, 4)
REG32(DFILPCFG0, 0x198)
    FIELD(DFILPCFG0, DFI_TLP_RESP, 24, 4)
    FIELD(DFILPCFG0, DFI_LP_WAKEUP_DPD, 20, 4)
    FIELD(DFILPCFG0, DFI_LP_EN_DPD, 16, 1)
    FIELD(DFILPCFG0, DFI_LP_WAKEUP_SR, 12, 4)
    FIELD(DFILPCFG0, DFI_LP_EN_SR, 8, 1)
    FIELD(DFILPCFG0, DFI_LP_WAKEUP_PD, 4, 4)
    FIELD(DFILPCFG0, DFI_LP_EN_PD, 0, 1)
REG32(DFILPCFG1, 0x19c)
    FIELD(DFILPCFG1, DFI_LP_WAKEUP_MPSM, 4, 4)
    FIELD(DFILPCFG1, DFI_LP_EN_MPSM, 0, 1)
REG32(DFIUPD0, 0x1a0)
    FIELD(DFIUPD0, DIS_AUTO_CTRLUPD, 31, 1)
    FIELD(DFIUPD0, DIS_AUTO_CTRLUPD_SRX, 30, 1)
    FIELD(DFIUPD0, DFI_T_CTRLUP_MAX, 16, 10)
    FIELD(DFIUPD0, DFI_T_CTRLUP_MIN, 0, 10)
REG32(DFIUPD1, 0x1a4)
    FIELD(DFIUPD1, DFI_T_CTRLUPD_INTERVAL_MIN_X1024, 16, 8)
    FIELD(DFIUPD1, DFI_T_CTRLUPD_INTERVAL_MAX_X1024, 0, 8)
REG32(DFIUPD2, 0x1a8)
    FIELD(DFIUPD2, DFI_PHYUPD_EN, 31, 1)
REG32(DFIMISC, 0x1b0)
    FIELD(DFIMISC, DFI_DATA_CS_POLARITY, 2, 1)
    FIELD(DFIMISC, PHY_DBI_MODE, 1, 1)
    FIELD(DFIMISC, DFI_INIT_COMPLETE_EN, 0, 1)
REG32(DFITMG2, 0x1b4)
    FIELD(DFITMG2, DFI_TPHY_RDCSLAT, 8, 6)
    FIELD(DFITMG2, DFI_TPHY_WRCSLAT, 0, 6)
REG32(DBICTL, 0x1c0)
    FIELD(DBICTL, RD_DBI_EN, 2, 1)
    FIELD(DBICTL, WR_DBI_EN, 1, 1)
    FIELD(DBICTL, DM_EN, 0, 1)
REG32(ADDRMAP0, 0x200)
    FIELD(ADDRMAP0, ADDRMAP_CS_BIT0, 0, 5)
REG32(ADDRMAP1, 0x204)
    FIELD(ADDRMAP1, ADDRMAP_BANK_B2, 16, 5)
    FIELD(ADDRMAP1, ADDRMAP_BANK_B1, 8, 5)
    FIELD(ADDRMAP1, ADDRMAP_BANK_B0, 0, 5)
REG32(ADDRMAP2, 0x208)
    FIELD(ADDRMAP2, ADDRMAP_COL_B5, 24, 4)
    FIELD(ADDRMAP2, ADDRMAP_COL_B4, 16, 4)
    FIELD(ADDRMAP2, ADDRMAP_COL_B3, 8, 4)
    FIELD(ADDRMAP2, ADDRMAP_COL_B2, 0, 4)
REG32(ADDRMAP3, 0x20c)
    FIELD(ADDRMAP3, ADDRMAP_COL_B9, 24, 4)
    FIELD(ADDRMAP3, ADDRMAP_COL_B8, 16, 4)
    FIELD(ADDRMAP3, ADDRMAP_COL_B7, 8, 4)
    FIELD(ADDRMAP3, ADDRMAP_COL_B6, 0, 4)
REG32(ADDRMAP4, 0x210)
    FIELD(ADDRMAP4, ADDRMAP_COL_B11, 8, 4)
    FIELD(ADDRMAP4, ADDRMAP_COL_B10, 0, 4)
REG32(ADDRMAP5, 0x214)
    FIELD(ADDRMAP5, ADDRMAP_ROW_B11, 24, 4)
    FIELD(ADDRMAP5, ADDRMAP_ROW_B2_10, 16, 4)
    FIELD(ADDRMAP5, ADDRMAP_ROW_B1, 8, 4)
    FIELD(ADDRMAP5, ADDRMAP_ROW_B0, 0, 4)
REG32(ADDRMAP6, 0x218)
    FIELD(ADDRMAP6, LPDDR3_6GB_12GB, 31, 1)
    FIELD(ADDRMAP6, ADDRMAP_ROW_B15, 24, 4)
    FIELD(ADDRMAP6, ADDRMAP_ROW_B14, 16, 4)
    FIELD(ADDRMAP6, ADDRMAP_ROW_B13, 8, 4)
    FIELD(ADDRMAP6, ADDRMAP_ROW_B12, 0, 4)
REG32(ADDRMAP7, 0x21c)
    FIELD(ADDRMAP7, ADDRMAP_ROW_B17, 8, 4)
    FIELD(ADDRMAP7, ADDRMAP_ROW_B16, 0, 4)
REG32(ADDRMAP8, 0x220)
    FIELD(ADDRMAP8, ADDRMAP_BG_B1, 8, 5)
    FIELD(ADDRMAP8, ADDRMAP_BG_B0, 0, 5)
REG32(ADDRMAP9, 0x224)
    FIELD(ADDRMAP9, ADDRMAP_ROW_B5, 24, 4)
    FIELD(ADDRMAP9, ADDRMAP_ROW_B4, 16, 4)
    FIELD(ADDRMAP9, ADDRMAP_ROW_B3, 8, 4)
    FIELD(ADDRMAP9, ADDRMAP_ROW_B2, 0, 4)
REG32(ADDRMAP10, 0x228)
    FIELD(ADDRMAP10, ADDRMAP_ROW_B9, 24, 4)
    FIELD(ADDRMAP10, ADDRMAP_ROW_B8, 16, 4)
    FIELD(ADDRMAP10, ADDRMAP_ROW_B7, 8, 4)
    FIELD(ADDRMAP10, ADDRMAP_ROW_B6, 0, 4)
REG32(ADDRMAP11, 0x22c)
    FIELD(ADDRMAP11, ADDRMAP_ROW_B10, 0, 4)
REG32(ODTCFG, 0x240)
    FIELD(ODTCFG, WR_ODT_HOLD, 24, 4)
    FIELD(ODTCFG, WR_ODT_DELAY, 16, 5)
    FIELD(ODTCFG, RD_ODT_HOLD, 8, 4)
    FIELD(ODTCFG, RD_ODT_DELAY, 2, 5)
REG32(ODTMAP, 0x244)
    FIELD(ODTMAP, RANK1_RD_ODT, 12, 2)
    FIELD(ODTMAP, RANK1_WR_ODT, 8, 2)
    FIELD(ODTMAP, RANK0_RD_ODT, 4, 2)
    FIELD(ODTMAP, RANK0_WR_ODT, 0, 2)
REG32(SCHED, 0x250)
    FIELD(SCHED, RDWR_IDLE_GAP, 24, 7)
    FIELD(SCHED, GO2CRITICAL_HYSTERESIS, 16, 8)
    FIELD(SCHED, LPR_NUM_ENTRIES, 8, 6)
    FIELD(SCHED, PAGECLOSE, 2, 1)
    FIELD(SCHED, PREFER_WRITE, 1, 1)
    FIELD(SCHED, FORCE_LOW_PRI_N, 0, 1)
REG32(SCHED1, 0x254)
    FIELD(SCHED1, PAGECLOSE_TIMER, 0, 8)
REG32(PERFHPR1, 0x25c)
    FIELD(PERFHPR1, HPR_XACT_RUN_LENGTH, 24, 8)
    FIELD(PERFHPR1, HPR_MAX_STARVE, 0, 16)
REG32(PERFLPR1, 0x264)
    FIELD(PERFLPR1, LPR_XACT_RUN_LENGTH, 24, 8)
    FIELD(PERFLPR1, LPR_MAX_STARVE, 0, 16)
REG32(PERFWR1, 0x26c)
    FIELD(PERFWR1, W_XACT_RUN_LENGTH, 24, 8)
    FIELD(PERFWR1, W_MAX_STARVE, 0, 16)
REG32(PERFVPR1, 0x274)
    FIELD(PERFVPR1, VPR_TIMEOUT_RANGE, 0, 11)
REG32(PERFVPW1, 0x278)
    FIELD(PERFVPW1, VPW_TIMEOUT_RANGE, 0, 11)
REG32(DQMAP0, 0x280)
    FIELD(DQMAP0, DQ_NIBBLE_MAP_12_15, 24, 8)
    FIELD(DQMAP0, DQ_NIBBLE_MAP_8_11, 16, 8)
    FIELD(DQMAP0, DQ_NIBBLE_MAP_4_7, 8, 8)
    FIELD(DQMAP0, DQ_NIBBLE_MAP_0_3, 0, 8)
REG32(DQMAP1, 0x284)
    FIELD(DQMAP1, DQ_NIBBLE_MAP_28_31, 24, 8)
    FIELD(DQMAP1, DQ_NIBBLE_MAP_24_27, 16, 8)
    FIELD(DQMAP1, DQ_NIBBLE_MAP_20_23, 8, 8)
    FIELD(DQMAP1, DQ_NIBBLE_MAP_16_19, 0, 8)
REG32(DQMAP2, 0x288)
    FIELD(DQMAP2, DQ_NIBBLE_MAP_44_47, 24, 8)
    FIELD(DQMAP2, DQ_NIBBLE_MAP_40_43, 16, 8)
    FIELD(DQMAP2, DQ_NIBBLE_MAP_36_39, 8, 8)
    FIELD(DQMAP2, DQ_NIBBLE_MAP_32_35, 0, 8)
REG32(DQMAP3, 0x28c)
    FIELD(DQMAP3, DQ_NIBBLE_MAP_60_63, 24, 8)
    FIELD(DQMAP3, DQ_NIBBLE_MAP_56_59, 16, 8)
    FIELD(DQMAP3, DQ_NIBBLE_MAP_52_55, 8, 8)
    FIELD(DQMAP3, DQ_NIBBLE_MAP_48_51, 0, 8)
REG32(DQMAP4, 0x290)
    FIELD(DQMAP4, DQ_NIBBLE_MAP_CB_4_7, 8, 8)
    FIELD(DQMAP4, DQ_NIBBLE_MAP_CB_0_3, 0, 8)
REG32(DQMAP5, 0x294)
    FIELD(DQMAP5, DIS_DQ_RANK_SWAP, 0, 1)
REG32(DBG0, 0x300)
    FIELD(DBG0, DIS_COLLISION_PAGE_OPT, 4, 1)
    FIELD(DBG0, DIS_WC, 0, 1)
REG32(DBG1, 0x304)
    FIELD(DBG1, DIS_HIF, 1, 1)
    FIELD(DBG1, DIS_DQ, 0, 1)
REG32(DBGCAM, 0x308)
    FIELD(DBGCAM, DBG_STALL_RD, 31, 1)
    FIELD(DBGCAM, DBG_STALL_WR, 30, 1)
    FIELD(DBGCAM, WR_DATA_PIPELINE_EMPTY, 29, 1)
    FIELD(DBGCAM, RD_DATA_PIPELINE_EMPTY, 28, 1)
    FIELD(DBGCAM, DBG_WR_Q_EMPTY, 26, 1)
    FIELD(DBGCAM, DBG_RD_Q_EMPTY, 25, 1)
    FIELD(DBGCAM, DBG_STALL, 24, 1)
    FIELD(DBGCAM, DBG_W_Q_DEPTH, 16, 7)
    FIELD(DBGCAM, DBG_LPR_Q_DEPTH, 8, 7)
    FIELD(DBGCAM, DBG_HPR_Q_DEPTH, 0, 7)
REG32(DBGCMD, 0x30c)
    FIELD(DBGCMD, HW_REF_ZQ_EN, 31, 1)
    FIELD(DBGCMD, CTRLUPD, 5, 1)
    FIELD(DBGCMD, ZQ_CALIB_SHORT, 4, 1)
    FIELD(DBGCMD, RANK1_REFRESH, 1, 1)
    FIELD(DBGCMD, RANK0_REFRESH, 0, 1)
REG32(DBGSTAT, 0x310)
    FIELD(DBGSTAT, CTRLUPD_BUSY, 5, 1)
    FIELD(DBGSTAT, ZQ_CALIB_SHORT_BUSY, 4, 1)
    FIELD(DBGSTAT, RANK1_REFRESH_BUSY, 1, 1)
    FIELD(DBGSTAT, RANK0_REFRESH_BUSY, 0, 1)
REG32(SWCTL, 0x320)
    FIELD(SWCTL, SW_DONE, 0, 1)
REG32(SWSTAT, 0x324)
    FIELD(SWSTAT, SW_DONE_ACK, 0, 1)
REG32(POISONCFG, 0x36c)
    FIELD(POISONCFG, RD_POISON_INTR_CLR, 24, 1)
    FIELD(POISONCFG, RD_POISON_INTR_EN, 20, 1)
    FIELD(POISONCFG, RD_POISON_SLVERR_EN, 16, 1)
    FIELD(POISONCFG, WR_POISON_INTR_CLR, 8, 1)
    FIELD(POISONCFG, WR_POISON_INTR_EN, 4, 1)
    FIELD(POISONCFG, WR_POISON_SLVERR_EN, 0, 1)
REG32(POISONSTAT, 0x370)
    FIELD(POISONSTAT, RD_POISON_INTR_5, 21, 1)
    FIELD(POISONSTAT, RD_POISON_INTR_4, 20, 1)
    FIELD(POISONSTAT, RD_POISON_INTR_3, 19, 1)
    FIELD(POISONSTAT, RD_POISON_INTR_2, 18, 1)
    FIELD(POISONSTAT, RD_POISON_INTR_1, 17, 1)
    FIELD(POISONSTAT, RD_POISON_INTR_0, 16, 1)
    FIELD(POISONSTAT, WR_POISON_INTR_5, 5, 1)
    FIELD(POISONSTAT, WR_POISON_INTR_4, 4, 1)
    FIELD(POISONSTAT, WR_POISON_INTR_3, 3, 1)
    FIELD(POISONSTAT, WR_POISON_INTR_2, 2, 1)
    FIELD(POISONSTAT, WR_POISON_INTR_1, 1, 1)
    FIELD(POISONSTAT, WR_POISON_INTR_0, 0, 1)
REG32(PSTAT, 0x3fc)
    FIELD(PSTAT, WR_PORT_BUSY_5, 21, 1)
    FIELD(PSTAT, WR_PORT_BUSY_4, 20, 1)
    FIELD(PSTAT, WR_PORT_BUSY_3, 19, 1)
    FIELD(PSTAT, WR_PORT_BUSY_2, 18, 1)
    FIELD(PSTAT, WR_PORT_BUSY_1, 17, 1)
    FIELD(PSTAT, WR_PORT_BUSY_0, 16, 1)
    FIELD(PSTAT, RD_PORT_BUSY_5, 5, 1)
    FIELD(PSTAT, RD_PORT_BUSY_4, 4, 1)
    FIELD(PSTAT, RD_PORT_BUSY_3, 3, 1)
    FIELD(PSTAT, RD_PORT_BUSY_2, 2, 1)
    FIELD(PSTAT, RD_PORT_BUSY_1, 1, 1)
    FIELD(PSTAT, RD_PORT_BUSY_0, 0, 1)
REG32(PCCFG, 0x400)
    FIELD(PCCFG, BL_EXP_MODE, 8, 1)
    FIELD(PCCFG, PAGEMATCH_LIMIT, 4, 1)
    FIELD(PCCFG, GO2CRITICAL_EN, 0, 1)
REG32(PCFGR_0, 0x404)
    FIELD(PCFGR_0, RD_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGR_0, RD_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGR_0, RD_PORT_AGING_EN, 12, 1)
    FIELD(PCFGR_0, RD_PORT_PRIORITY, 0, 10)
REG32(PCFGW_0, 0x408)
    FIELD(PCFGW_0, WR_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGW_0, WR_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGW_0, WR_PORT_AGING_EN, 12, 1)
    FIELD(PCFGW_0, WR_PORT_PRIORITY, 0, 10)
REG32(PCTRL_0, 0x490)
    FIELD(PCTRL_0, PORT_EN, 0, 1)
REG32(PCFGQOS0_0, 0x494)
    FIELD(PCFGQOS0_0, RQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGQOS0_0, RQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGQOS0_0, RQOS_MAP_LEVEL1, 0, 4)
REG32(PCFGQOS1_0, 0x498)
    FIELD(PCFGQOS1_0, RQOS_MAP_TIMEOUTR, 16, 11)
    FIELD(PCFGQOS1_0, RQOS_MAP_TIMEOUTB, 0, 11)
REG32(PCFGWQOS0_0, 0x49c)
    FIELD(PCFGWQOS0_0, WQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGWQOS0_0, WQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGWQOS0_0, WQOS_MAP_LEVEL, 0, 4)
REG32(PCFGWQOS1_0, 0x4a0)
    FIELD(PCFGWQOS1_0, WQOS_MAP_TIMEOUT, 0, 11)
REG32(PCFGR_1, 0x4b4)
    FIELD(PCFGR_1, RD_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGR_1, RD_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGR_1, RD_PORT_AGING_EN, 12, 1)
    FIELD(PCFGR_1, RD_PORT_PRIORITY, 0, 10)
REG32(PCFGW_1, 0x4b8)
    FIELD(PCFGW_1, WR_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGW_1, WR_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGW_1, WR_PORT_AGING_EN, 12, 1)
    FIELD(PCFGW_1, WR_PORT_PRIORITY, 0, 10)
REG32(PCTRL_1, 0x540)
    FIELD(PCTRL_1, PORT_EN, 0, 1)
REG32(PCFGQOS0_1, 0x544)
    FIELD(PCFGQOS0_1, RQOS_MAP_REGION2, 24, 2)
    FIELD(PCFGQOS0_1, RQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGQOS0_1, RQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGQOS0_1, RQOS_MAP_LEVEL2, 8, 4)
    FIELD(PCFGQOS0_1, RQOS_MAP_LEVEL1, 0, 4)
REG32(PCFGQOS1_1, 0x548)
    FIELD(PCFGQOS1_1, RQOS_MAP_TIMEOUTR, 16, 11)
    FIELD(PCFGQOS1_1, RQOS_MAP_TIMEOUTB, 0, 11)
REG32(PCFGWQOS0_1, 0x54c)
    FIELD(PCFGWQOS0_1, WQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGWQOS0_1, WQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGWQOS0_1, WQOS_MAP_LEVEL, 0, 4)
REG32(PCFGWQOS1_1, 0x550)
    FIELD(PCFGWQOS1_1, WQOS_MAP_TIMEOUT, 0, 11)
REG32(PCFGR_2, 0x564)
    FIELD(PCFGR_2, RD_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGR_2, RD_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGR_2, RD_PORT_AGING_EN, 12, 1)
    FIELD(PCFGR_2, RD_PORT_PRIORITY, 0, 10)
REG32(PCFGW_2, 0x568)
    FIELD(PCFGW_2, WR_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGW_2, WR_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGW_2, WR_PORT_AGING_EN, 12, 1)
    FIELD(PCFGW_2, WR_PORT_PRIORITY, 0, 10)
REG32(PCTRL_2, 0x5f0)
    FIELD(PCTRL_2, PORT_EN, 0, 1)
REG32(PCFGQOS0_2, 0x5f4)
    FIELD(PCFGQOS0_2, RQOS_MAP_REGION2, 24, 2)
    FIELD(PCFGQOS0_2, RQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGQOS0_2, RQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGQOS0_2, RQOS_MAP_LEVEL2, 8, 4)
    FIELD(PCFGQOS0_2, RQOS_MAP_LEVEL1, 0, 4)
REG32(PCFGQOS1_2, 0x5f8)
    FIELD(PCFGQOS1_2, RQOS_MAP_TIMEOUTR, 16, 11)
    FIELD(PCFGQOS1_2, RQOS_MAP_TIMEOUTB, 0, 11)
REG32(PCFGWQOS0_2, 0x5fc)
    FIELD(PCFGWQOS0_2, WQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGWQOS0_2, WQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGWQOS0_2, WQOS_MAP_LEVEL, 0, 4)
REG32(PCFGWQOS1_2, 0x600)
    FIELD(PCFGWQOS1_2, WQOS_MAP_TIMEOUT, 0, 11)
REG32(PCFGR_3, 0x614)
    FIELD(PCFGR_3, RD_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGR_3, RD_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGR_3, RD_PORT_AGING_EN, 12, 1)
    FIELD(PCFGR_3, RD_PORT_PRIORITY, 0, 10)
REG32(PCFGW_3, 0x618)
    FIELD(PCFGW_3, WR_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGW_3, WR_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGW_3, WR_PORT_AGING_EN, 12, 1)
    FIELD(PCFGW_3, WR_PORT_PRIORITY, 0, 10)
REG32(PCTRL_3, 0x6a0)
    FIELD(PCTRL_3, PORT_EN, 0, 1)
REG32(PCFGQOS0_3, 0x6a4)
    FIELD(PCFGQOS0_3, RQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGQOS0_3, RQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGQOS0_3, RQOS_MAP_LEVEL1, 0, 4)
REG32(PCFGQOS1_3, 0x6a8)
    FIELD(PCFGQOS1_3, RQOS_MAP_TIMEOUTR, 16, 11)
    FIELD(PCFGQOS1_3, RQOS_MAP_TIMEOUTB, 0, 11)
REG32(PCFGWQOS0_3, 0x6ac)
    FIELD(PCFGWQOS0_3, WQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGWQOS0_3, WQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGWQOS0_3, WQOS_MAP_LEVEL, 0, 4)
REG32(PCFGWQOS1_3, 0x6b0)
    FIELD(PCFGWQOS1_3, WQOS_MAP_TIMEOUT, 0, 11)
REG32(PCFGR_4, 0x6c4)
    FIELD(PCFGR_4, RD_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGR_4, RD_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGR_4, RD_PORT_AGING_EN, 12, 1)
    FIELD(PCFGR_4, RD_PORT_PRIORITY, 0, 10)
REG32(PCFGW_4, 0x6c8)
    FIELD(PCFGW_4, WR_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGW_4, WR_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGW_4, WR_PORT_AGING_EN, 12, 1)
    FIELD(PCFGW_4, WR_PORT_PRIORITY, 0, 10)
REG32(PCTRL_4, 0x750)
    FIELD(PCTRL_4, PORT_EN, 0, 1)
REG32(PCFGQOS0_4, 0x754)
    FIELD(PCFGQOS0_4, RQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGQOS0_4, RQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGQOS0_4, RQOS_MAP_LEVEL1, 0, 4)
REG32(PCFGQOS1_4, 0x758)
    FIELD(PCFGQOS1_4, RQOS_MAP_TIMEOUTR, 16, 11)
    FIELD(PCFGQOS1_4, RQOS_MAP_TIMEOUTB, 0, 11)
REG32(PCFGWQOS0_4, 0x75c)
    FIELD(PCFGWQOS0_4, WQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGWQOS0_4, WQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGWQOS0_4, WQOS_MAP_LEVEL, 0, 4)
REG32(PCFGWQOS1_4, 0x760)
    FIELD(PCFGWQOS1_4, WQOS_MAP_TIMEOUT, 0, 11)
REG32(PCFGR_5, 0x774)
    FIELD(PCFGR_5, RD_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGR_5, RD_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGR_5, RD_PORT_AGING_EN, 12, 1)
    FIELD(PCFGR_5, RD_PORT_PRIORITY, 0, 10)
REG32(PCFGW_5, 0x778)
    FIELD(PCFGW_5, WR_PORT_PAGEMATCH_EN, 14, 1)
    FIELD(PCFGW_5, WR_PORT_URGENT_EN, 13, 1)
    FIELD(PCFGW_5, WR_PORT_AGING_EN, 12, 1)
    FIELD(PCFGW_5, WR_PORT_PRIORITY, 0, 10)
REG32(PCTRL_5, 0x800)
    FIELD(PCTRL_5, PORT_EN, 0, 1)
REG32(PCFGQOS0_5, 0x804)
    FIELD(PCFGQOS0_5, RQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGQOS0_5, RQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGQOS0_5, RQOS_MAP_LEVEL1, 0, 4)
REG32(PCFGQOS1_5, 0x808)
    FIELD(PCFGQOS1_5, RQOS_MAP_TIMEOUTR, 16, 11)
    FIELD(PCFGQOS1_5, RQOS_MAP_TIMEOUTB, 0, 11)
REG32(PCFGWQOS0_5, 0x80c)
    FIELD(PCFGWQOS0_5, WQOS_MAP_REGION1, 20, 2)
    FIELD(PCFGWQOS0_5, WQOS_MAP_REGION0, 16, 2)
    FIELD(PCFGWQOS0_5, WQOS_MAP_LEVEL, 0, 4)
REG32(PCFGWQOS1_5, 0x810)
    FIELD(PCFGWQOS1_5, WQOS_MAP_TIMEOUT, 0, 11)
REG32(SARBASE0, 0xf04)
    FIELD(SARBASE0, BASE_ADDR, 0, 9)
REG32(SARSIZE0, 0xf08)
    FIELD(SARSIZE0, NBLOCKS, 0, 8)
REG32(SARBASE1, 0xf0c)
    FIELD(SARBASE1, BASE_ADDR, 0, 9)
REG32(SARSIZE1, 0xf10)
    FIELD(SARSIZE1, NBLOCKS, 0, 8)
REG32(DERATEINT_SHADOW, 0x2024)
REG32(RFSHCTL0_SHADOW, 0x2050)
    FIELD(RFSHCTL0_SHADOW, REFRESH_MARGIN, 20, 4)
    FIELD(RFSHCTL0_SHADOW, REFRESH_TO_X32, 12, 5)
    FIELD(RFSHCTL0_SHADOW, REFRESH_BURST, 4, 5)
    FIELD(RFSHCTL0_SHADOW, PER_BANK_REFRESH, 2, 1)
REG32(RFSHTMG_SHADOW, 0x2064)
    FIELD(RFSHTMG_SHADOW, T_RFC_NOM_X32, 16, 12)
    FIELD(RFSHTMG_SHADOW, LPDDR3_TREFBW_EN, 15, 1)
    FIELD(RFSHTMG_SHADOW, T_RFC_MIN, 0, 10)
REG32(INIT3_SHADOW, 0x20dc)
    FIELD(INIT3_SHADOW, MR, 16, 16)
    FIELD(INIT3_SHADOW, EMR, 0, 16)
REG32(INIT4_SHADOW, 0x20e0)
    FIELD(INIT4_SHADOW, EMR2, 16, 16)
    FIELD(INIT4_SHADOW, EMR3, 0, 16)
REG32(INIT6_SHADOW, 0x20e8)
    FIELD(INIT6_SHADOW, MR4, 16, 16)
    FIELD(INIT6_SHADOW, MR5, 0, 16)
REG32(INIT7_SHADOW, 0x20ec)
    FIELD(INIT7_SHADOW, MR6, 16, 16)
REG32(DRAMTMG0_SHADOW, 0x2100)
    FIELD(DRAMTMG0_SHADOW, WR2PRE, 24, 7)
    FIELD(DRAMTMG0_SHADOW, T_FAW, 16, 6)
    FIELD(DRAMTMG0_SHADOW, T_RAS_MAX, 8, 7)
    FIELD(DRAMTMG0_SHADOW, T_RAS_MIN, 0, 6)
REG32(DRAMTMG1_SHADOW, 0x2104)
    FIELD(DRAMTMG1_SHADOW, T_XP, 16, 5)
    FIELD(DRAMTMG1_SHADOW, RD2PRE, 8, 5)
    FIELD(DRAMTMG1_SHADOW, T_RC, 0, 7)
REG32(DRAMTMG2_SHADOW, 0x2108)
    FIELD(DRAMTMG2_SHADOW, WRITE_LATENCY, 24, 6)
    FIELD(DRAMTMG2_SHADOW, READ_LATENCY, 16, 6)
    FIELD(DRAMTMG2_SHADOW, RD2WR, 8, 6)
    FIELD(DRAMTMG2_SHADOW, WR2RD, 0, 6)
REG32(DRAMTMG3_SHADOW, 0x210c)
    FIELD(DRAMTMG3_SHADOW, T_MRW, 20, 10)
    FIELD(DRAMTMG3_SHADOW, T_MRD, 12, 6)
    FIELD(DRAMTMG3_SHADOW, T_MOD, 0, 10)
REG32(DRAMTMG4_SHADOW, 0x2110)
    FIELD(DRAMTMG4_SHADOW, T_RCD, 24, 5)
    FIELD(DRAMTMG4_SHADOW, T_CCD, 16, 4)
    FIELD(DRAMTMG4_SHADOW, T_RRD, 8, 4)
    FIELD(DRAMTMG4_SHADOW, T_RP, 0, 5)
REG32(DRAMTMG5_SHADOW, 0x2114)
    FIELD(DRAMTMG5_SHADOW, T_CKSRX, 24, 4)
    FIELD(DRAMTMG5_SHADOW, T_CKSRE, 16, 4)
    FIELD(DRAMTMG5_SHADOW, T_CKESR, 8, 6)
    FIELD(DRAMTMG5_SHADOW, T_CKE, 0, 5)
REG32(DRAMTMG6_SHADOW, 0x2118)
    FIELD(DRAMTMG6_SHADOW, T_CKDPDE, 24, 4)
    FIELD(DRAMTMG6_SHADOW, T_CKDPDX, 16, 4)
    FIELD(DRAMTMG6_SHADOW, T_CKCSX, 0, 4)
REG32(DRAMTMG7_SHADOW, 0x211c)
    FIELD(DRAMTMG7_SHADOW, T_CKPDE, 8, 4)
    FIELD(DRAMTMG7_SHADOW, T_CKPDX, 0, 4)
REG32(DRAMTMG8_SHADOW, 0x2120)
    FIELD(DRAMTMG8_SHADOW, T_XS_FAST_X32, 24, 7)
    FIELD(DRAMTMG8_SHADOW, T_XS_ABORT_X32, 16, 7)
    FIELD(DRAMTMG8_SHADOW, T_XS_DLL_X32, 8, 7)
    FIELD(DRAMTMG8_SHADOW, T_XS_X32, 0, 7)
REG32(DRAMTMG9_SHADOW, 0x2124)
    FIELD(DRAMTMG9_SHADOW, DDR4_WR_PREAMBLE, 30, 1)
    FIELD(DRAMTMG9_SHADOW, T_CCD_S, 16, 3)
    FIELD(DRAMTMG9_SHADOW, T_RRD_S, 8, 4)
    FIELD(DRAMTMG9_SHADOW, WR2RD_S, 0, 6)
REG32(DRAMTMG10_SHADOW, 0x2128)
    FIELD(DRAMTMG10_SHADOW, T_SYNC_GEAR, 16, 5)
    FIELD(DRAMTMG10_SHADOW, T_CMD_GEAR, 8, 5)
    FIELD(DRAMTMG10_SHADOW, T_GEAR_SETUP, 2, 2)
    FIELD(DRAMTMG10_SHADOW, T_GEAR_HOLD, 0, 2)
REG32(DRAMTMG11_SHADOW, 0x212c)
    FIELD(DRAMTMG11_SHADOW, POST_MPSM_GAP_X32, 24, 7)
    FIELD(DRAMTMG11_SHADOW, T_MPX_LH, 16, 5)
    FIELD(DRAMTMG11_SHADOW, T_MPX_S, 8, 2)
    FIELD(DRAMTMG11_SHADOW, T_CKMPE, 0, 5)
REG32(DRAMTMG12_SHADOW, 0x2130)
    FIELD(DRAMTMG12_SHADOW, T_CMDCKE, 16, 2)
    FIELD(DRAMTMG12_SHADOW, T_CKEHCMD, 8, 4)
    FIELD(DRAMTMG12_SHADOW, T_MRD_PDA, 0, 5)
REG32(DRAMTMG13_SHADOW, 0x2134)
    FIELD(DRAMTMG13_SHADOW, ODTLOFF, 24, 7)
    FIELD(DRAMTMG13_SHADOW, T_CCD_MW, 16, 6)
    FIELD(DRAMTMG13_SHADOW, T_PPD, 0, 3)
REG32(DRAMTMG14_SHADOW, 0x2138)
    FIELD(DRAMTMG14_SHADOW, T_XSR, 0, 12)
REG32(ZQCTL0_SHADOW, 0x2180)
    FIELD(ZQCTL0_SHADOW, DIS_AUTO_ZQ, 31, 1)
    FIELD(ZQCTL0_SHADOW, DIS_SRX_ZQCL, 30, 1)
    FIELD(ZQCTL0_SHADOW, ZQ_RESISTOR_SHARED, 29, 1)
    FIELD(ZQCTL0_SHADOW, DIS_MPSMX_ZQCL, 28, 1)
    FIELD(ZQCTL0_SHADOW, T_ZQ_LONG_NOP, 16, 11)
    FIELD(ZQCTL0_SHADOW, T_ZQ_SHORT_NOP, 0, 10)
REG32(DFITMG0_SHADOW, 0x2190)
    FIELD(DFITMG0_SHADOW, DFI_T_CTRL_DELAY, 24, 5)
    FIELD(DFITMG0_SHADOW, DFI_RDDATA_USE_SDR, 23, 1)
    FIELD(DFITMG0_SHADOW, DFI_T_RDDATA_EN, 16, 6)
    FIELD(DFITMG0_SHADOW, DFI_WRDATA_USE_SDR, 15, 1)
    FIELD(DFITMG0_SHADOW, DFI_TPHY_WRDATA, 8, 6)
    FIELD(DFITMG0_SHADOW, DFI_TPHY_WRLAT, 0, 6)
REG32(DFITMG1_SHADOW, 0x2194)
    FIELD(DFITMG1_SHADOW, DFI_T_CMD_LAT, 28, 4)
    FIELD(DFITMG1_SHADOW, DFI_T_PARIN_LAT, 24, 2)
    FIELD(DFITMG1_SHADOW, DFI_T_WRDATA_DELAY, 16, 5)
    FIELD(DFITMG1_SHADOW, DFI_T_DRAM_CLK_DISABLE, 8, 4)
    FIELD(DFITMG1_SHADOW, DFI_T_DRAM_CLK_ENABLE, 0, 4)
REG32(DFITMG2_SHADOW, 0x21b4)
    FIELD(DFITMG2_SHADOW, DFI_TPHY_RDCSLAT, 8, 6)
    FIELD(DFITMG2_SHADOW, DFI_TPHY_WRCSLAT, 0, 6)
REG32(ODTCFG_SHADOW, 0x2240)
    FIELD(ODTCFG_SHADOW, WR_ODT_HOLD, 24, 4)
    FIELD(ODTCFG_SHADOW, WR_ODT_DELAY, 16, 5)
    FIELD(ODTCFG_SHADOW, RD_ODT_HOLD, 8, 4)
    FIELD(ODTCFG_SHADOW, RD_ODT_DELAY, 2, 5)

#define R_MAX (R_ODTCFG_SHADOW + 1)

#define R_STAT_OPERATING_MODE_SR     3
#define R_STAT_OPERATING_MODE_NORMAL 1

#define R_STAT_SELFREF_TYPE_SRSW 2
#define R_STAT_SELFREF_TYPE_NONE 0

typedef struct DDRC {
    SysBusDevice parent_obj;
    MemoryRegion iomem;

    uint32_t regs[R_MAX];
    RegisterInfo regs_info[R_MAX];
} DDRC;

static void ddrc_pwrctl_post_write(RegisterInfo *reg, uint64_t val)
{
    DDRC *s = XILINX_DDRC(reg->opaque);

    /*
     * Software requests self-refresh enter. Pretend that we complied and update
     * the STAT register accordingly.
     */
    if (val & R_PWRCTL_SELFREF_SW_MASK) {
        ARRAY_FIELD_DP32(s->regs, STAT, OPERATING_MODE,
                         R_STAT_OPERATING_MODE_SR);
        ARRAY_FIELD_DP32(s->regs, STAT, SELFREF_TYPE,
                         R_STAT_SELFREF_TYPE_SRSW);
    }

    /* switch to normal mode */
    if (!(val & R_PWRCTL_SELFREF_SW_MASK)) {
        ARRAY_FIELD_DP32(s->regs, STAT, OPERATING_MODE,
                         R_STAT_OPERATING_MODE_NORMAL);
        ARRAY_FIELD_DP32(s->regs, STAT, SELFREF_TYPE, R_STAT_SELFREF_TYPE_NONE);
    }
}

static const RegisterAccessInfo ddrc_regs_info[] = {
    {   .name = "MSTR",  .addr = A_MSTR,
        .reset = 0x3040001,
    },{ .name = "STAT",  .addr = A_STAT,
        .ro = 0x337,
        /* Reset to Normal mode. */
        .reset = 0x1,
    },{ .name = "MRCTRL0",  .addr = A_MRCTRL0,
        .reset = 0x30,
    },{ .name = "MRCTRL1",  .addr = A_MRCTRL1,
    },{ .name = "MRSTAT",  .addr = A_MRSTAT,
        .ro = 0x101,
    },{ .name = "MRCTRL2",  .addr = A_MRCTRL2,
    },{ .name = "DERATEEN",  .addr = A_DERATEEN,
    },{ .name = "DERATEINT",  .addr = A_DERATEINT,
        .reset = 0x800000,
    },{ .name = "PWRCTL",  .addr = A_PWRCTL,
        .post_write = ddrc_pwrctl_post_write,
    },{ .name = "PWRTMG",  .addr = A_PWRTMG,
        .reset = 0x402010,
    },{ .name = "HWLPCTL",  .addr = A_HWLPCTL,
        .reset = 0x3,
    },{ .name = "RFSHCTL0",  .addr = A_RFSHCTL0,
        .reset = 0x210000,
    },{ .name = "RFSHCTL1",  .addr = A_RFSHCTL1,
    },{ .name = "RFSHCTL3",  .addr = A_RFSHCTL3,
    },{ .name = "RFSHTMG",  .addr = A_RFSHTMG,
        .reset = 0x62008c,
    },{ .name = "ECCCFG0",  .addr = A_ECCCFG0,
    },{ .name = "ECCCFG1",  .addr = A_ECCCFG1,
    },{ .name = "ECCSTAT",  .addr = A_ECCSTAT,
        .ro = 0xf0f7f,
    },{ .name = "ECCCLR",  .addr = A_ECCCLR,
        .w1c = 0xf,
    },{ .name = "ECCERRCNT",  .addr = A_ECCERRCNT,
        .ro = 0xffffffff,
    },{ .name = "ECCCADDR0",  .addr = A_ECCCADDR0,
        .ro = 0x103ffff,
    },{ .name = "ECCCADDR1",  .addr = A_ECCCADDR1,
        .ro = 0x3070fff,
    },{ .name = "ECCCSYN0",  .addr = A_ECCCSYN0,
        .ro = 0xffffffff,
    },{ .name = "ECCCSYN1",  .addr = A_ECCCSYN1,
        .ro = 0xffffffff,
    },{ .name = "ECCCSYN2",  .addr = A_ECCCSYN2,
        .ro = 0xff,
    },{ .name = "ECCBITMASK0",  .addr = A_ECCBITMASK0,
        .ro = 0xffffffff,
    },{ .name = "ECCBITMASK1",  .addr = A_ECCBITMASK1,
        .ro = 0xffffffff,
    },{ .name = "ECCBITMASK2",  .addr = A_ECCBITMASK2,
        .ro = 0xff,
    },{ .name = "ECCUADDR0",  .addr = A_ECCUADDR0,
        .ro = 0x103ffff,
    },{ .name = "ECCUADDR1",  .addr = A_ECCUADDR1,
        .ro = 0x3070fff,
    },{ .name = "ECCUSYN0",  .addr = A_ECCUSYN0,
        .ro = 0xffffffff,
    },{ .name = "ECCUSYN1",  .addr = A_ECCUSYN1,
        .ro = 0xffffffff,
    },{ .name = "ECCUSYN2",  .addr = A_ECCUSYN2,
        .ro = 0xff,
    },{ .name = "ECCPOISONADDR0",  .addr = A_ECCPOISONADDR0,
    },{ .name = "ECCPOISONADDR1",  .addr = A_ECCPOISONADDR1,
    },{ .name = "CRCPARCTL0",  .addr = A_CRCPARCTL0,
        .reset = 0x8000,
        .w1c = 0x116,
    },{ .name = "CRCPARCTL1",  .addr = A_CRCPARCTL1,
        .reset = 0x10000200,
    },{ .name = "CRCPARCTL2",  .addr = A_CRCPARCTL2,
        .reset = 0x30050c,
    },{ .name = "CRCPARSTAT",  .addr = A_CRCPARSTAT,
        .ro = 0x3f7fffff,
    },{ .name = "INIT0",  .addr = A_INIT0,
        .reset = 0x2004e,
    },{ .name = "INIT1",  .addr = A_INIT1,
    },{ .name = "INIT2",  .addr = A_INIT2,
        .reset = 0xd05,
    },{ .name = "INIT3",  .addr = A_INIT3,
        .reset = 0x510,
    },{ .name = "INIT4",  .addr = A_INIT4,
    },{ .name = "INIT5",  .addr = A_INIT5,
        .reset = 0x100004,
    },{ .name = "INIT6",  .addr = A_INIT6,
    },{ .name = "INIT7",  .addr = A_INIT7,
    },{ .name = "DIMMCTL",  .addr = A_DIMMCTL,
    },{ .name = "RANKCTL",  .addr = A_RANKCTL,
        .reset = 0x66f,
    },{ .name = "DRAMTMG0",  .addr = A_DRAMTMG0,
        .reset = 0xf101b0f,
    },{ .name = "DRAMTMG1",  .addr = A_DRAMTMG1,
        .reset = 0x80414,
    },{ .name = "DRAMTMG2",  .addr = A_DRAMTMG2,
        .reset = 0x305060d,
    },{ .name = "DRAMTMG3",  .addr = A_DRAMTMG3,
        .reset = 0x50400c,
    },{ .name = "DRAMTMG4",  .addr = A_DRAMTMG4,
        .reset = 0x5040405,
    },{ .name = "DRAMTMG5",  .addr = A_DRAMTMG5,
        .reset = 0x5050403,
    },{ .name = "DRAMTMG6",  .addr = A_DRAMTMG6,
        .reset = 0x2020005,
    },{ .name = "DRAMTMG7",  .addr = A_DRAMTMG7,
        .reset = 0x202,
    },{ .name = "DRAMTMG8",  .addr = A_DRAMTMG8,
        .reset = 0x3034405,
    },{ .name = "DRAMTMG9",  .addr = A_DRAMTMG9,
        .reset = 0x4040d,
    },{ .name = "DRAMTMG10",  .addr = A_DRAMTMG10,
        .reset = 0x1c180a,
    },{ .name = "DRAMTMG11",  .addr = A_DRAMTMG11,
        .reset = 0x440c021c,
    },{ .name = "DRAMTMG12",  .addr = A_DRAMTMG12,
        .reset = 0x20610,
    },{ .name = "DRAMTMG13",  .addr = A_DRAMTMG13,
        .reset = 0x1c200004,
    },{ .name = "DRAMTMG14",  .addr = A_DRAMTMG14,
        .reset = 0xa0,
    },{ .name = "ZQCTL0",  .addr = A_ZQCTL0,
        .reset = 0x2000040,
    },{ .name = "ZQCTL1",  .addr = A_ZQCTL1,
        .reset = 0x2000100,
    },{ .name = "ZQCTL2",  .addr = A_ZQCTL2,
    },{ .name = "ZQSTAT",  .addr = A_ZQSTAT,
        .ro = 0x1,
    },{ .name = "DFITMG0",  .addr = A_DFITMG0,
        .reset = 0x7020002,
    },{ .name = "DFITMG1",  .addr = A_DFITMG1,
        .reset = 0x404,
    },{ .name = "DFILPCFG0",  .addr = A_DFILPCFG0,
        .reset = 0x7000000,
    },{ .name = "DFILPCFG1",  .addr = A_DFILPCFG1,
    },{ .name = "DFIUPD0",  .addr = A_DFIUPD0,
        .reset = 0x400003,
    },{ .name = "DFIUPD1",  .addr = A_DFIUPD1,
    },{ .name = "DFIUPD2",  .addr = A_DFIUPD2,
        .reset = 0x80000000,
    },{ .name = "DFIMISC",  .addr = A_DFIMISC,
        .reset = 0x1,
    },{ .name = "DFITMG2",  .addr = A_DFITMG2,
        .reset = 0x202,
    },{ .name = "DBICTL",  .addr = A_DBICTL,
        .reset = 0x1,
    },{ .name = "ADDRMAP0",  .addr = A_ADDRMAP0,
    },{ .name = "ADDRMAP1",  .addr = A_ADDRMAP1,
    },{ .name = "ADDRMAP2",  .addr = A_ADDRMAP2,
    },{ .name = "ADDRMAP3",  .addr = A_ADDRMAP3,
    },{ .name = "ADDRMAP4",  .addr = A_ADDRMAP4,
    },{ .name = "ADDRMAP5",  .addr = A_ADDRMAP5,
    },{ .name = "ADDRMAP6",  .addr = A_ADDRMAP6,
    },{ .name = "ADDRMAP7",  .addr = A_ADDRMAP7,
    },{ .name = "ADDRMAP8",  .addr = A_ADDRMAP8,
    },{ .name = "ADDRMAP9",  .addr = A_ADDRMAP9,
    },{ .name = "ADDRMAP10",  .addr = A_ADDRMAP10,
    },{ .name = "ADDRMAP11",  .addr = A_ADDRMAP11,
    },{ .name = "ODTCFG",  .addr = A_ODTCFG,
        .reset = 0x4000400,
    },{ .name = "ODTMAP",  .addr = A_ODTMAP,
        .reset = 0x2211,
    },{ .name = "SCHED",  .addr = A_SCHED,
        .reset = 0x2005,
    },{ .name = "SCHED1",  .addr = A_SCHED1,
    },{ .name = "PERFHPR1",  .addr = A_PERFHPR1,
        .reset = 0xf000001,
    },{ .name = "PERFLPR1",  .addr = A_PERFLPR1,
        .reset = 0xf00007f,
    },{ .name = "PERFWR1",  .addr = A_PERFWR1,
        .reset = 0xf00007f,
    },{ .name = "PERFVPR1",  .addr = A_PERFVPR1,
    },{ .name = "PERFVPW1",  .addr = A_PERFVPW1,
    },{ .name = "DQMAP0",  .addr = A_DQMAP0,
    },{ .name = "DQMAP1",  .addr = A_DQMAP1,
    },{ .name = "DQMAP2",  .addr = A_DQMAP2,
    },{ .name = "DQMAP3",  .addr = A_DQMAP3,
    },{ .name = "DQMAP4",  .addr = A_DQMAP4,
    },{ .name = "DQMAP5",  .addr = A_DQMAP5,
    },{ .name = "DBG0",  .addr = A_DBG0,
    },{ .name = "DBG1",  .addr = A_DBG1,
    },{ .name = "DBGCAM",  .addr = A_DBGCAM,
        .ro = 0xf77f7f7f,
    },{ .name = "DBGCMD",  .addr = A_DBGCMD,
    },{ .name = "DBGSTAT",  .addr = A_DBGSTAT,
        .ro = 0x33,
    },{ .name = "SWCTL",  .addr = A_SWCTL,
        .reset = 0x1,
    },{ .name = "SWSTAT",  .addr = A_SWSTAT,
        .ro = 0x1,
    },{ .name = "POISONCFG",  .addr = A_POISONCFG,
        .reset = 0x110011,
        .w1c = 0x1000100,
    },{ .name = "POISONSTAT",  .addr = A_POISONSTAT,
        .ro = 0x3f003f,
    },{ .name = "PSTAT",  .addr = A_PSTAT,
        .ro = 0x3f003f,
    },{ .name = "PCCFG",  .addr = A_PCCFG,
    },{ .name = "PCFGR_0",  .addr = A_PCFGR_0,
    },{ .name = "PCFGW_0",  .addr = A_PCFGW_0,
        .reset = 0x4000,
    },{ .name = "PCTRL_0",  .addr = A_PCTRL_0,
    },{ .name = "PCFGQOS0_0",  .addr = A_PCFGQOS0_0,
    },{ .name = "PCFGQOS1_0",  .addr = A_PCFGQOS1_0,
    },{ .name = "PCFGWQOS0_0",  .addr = A_PCFGWQOS0_0,
    },{ .name = "PCFGWQOS1_0",  .addr = A_PCFGWQOS1_0,
    },{ .name = "PCFGR_1",  .addr = A_PCFGR_1,
    },{ .name = "PCFGW_1",  .addr = A_PCFGW_1,
        .reset = 0x4000,
    },{ .name = "PCTRL_1",  .addr = A_PCTRL_1,
    },{ .name = "PCFGQOS0_1",  .addr = A_PCFGQOS0_1,
        .reset = 0x2000e00,
    },{ .name = "PCFGQOS1_1",  .addr = A_PCFGQOS1_1,
    },{ .name = "PCFGWQOS0_1",  .addr = A_PCFGWQOS0_1,
    },{ .name = "PCFGWQOS1_1",  .addr = A_PCFGWQOS1_1,
    },{ .name = "PCFGR_2",  .addr = A_PCFGR_2,
    },{ .name = "PCFGW_2",  .addr = A_PCFGW_2,
        .reset = 0x4000,
    },{ .name = "PCTRL_2",  .addr = A_PCTRL_2,
    },{ .name = "PCFGQOS0_2",  .addr = A_PCFGQOS0_2,
        .reset = 0x2000e00,
    },{ .name = "PCFGQOS1_2",  .addr = A_PCFGQOS1_2,
    },{ .name = "PCFGWQOS0_2",  .addr = A_PCFGWQOS0_2,
    },{ .name = "PCFGWQOS1_2",  .addr = A_PCFGWQOS1_2,
    },{ .name = "PCFGR_3",  .addr = A_PCFGR_3,
    },{ .name = "PCFGW_3",  .addr = A_PCFGW_3,
        .reset = 0x4000,
    },{ .name = "PCTRL_3",  .addr = A_PCTRL_3,
    },{ .name = "PCFGQOS0_3",  .addr = A_PCFGQOS0_3,
    },{ .name = "PCFGQOS1_3",  .addr = A_PCFGQOS1_3,
    },{ .name = "PCFGWQOS0_3",  .addr = A_PCFGWQOS0_3,
    },{ .name = "PCFGWQOS1_3",  .addr = A_PCFGWQOS1_3,
    },{ .name = "PCFGR_4",  .addr = A_PCFGR_4,
    },{ .name = "PCFGW_4",  .addr = A_PCFGW_4,
        .reset = 0x4000,
    },{ .name = "PCTRL_4",  .addr = A_PCTRL_4,
    },{ .name = "PCFGQOS0_4",  .addr = A_PCFGQOS0_4,
    },{ .name = "PCFGQOS1_4",  .addr = A_PCFGQOS1_4,
    },{ .name = "PCFGWQOS0_4",  .addr = A_PCFGWQOS0_4,
    },{ .name = "PCFGWQOS1_4",  .addr = A_PCFGWQOS1_4,
    },{ .name = "PCFGR_5",  .addr = A_PCFGR_5,
    },{ .name = "PCFGW_5",  .addr = A_PCFGW_5,
        .reset = 0x4000,
    },{ .name = "PCTRL_5",  .addr = A_PCTRL_5,
    },{ .name = "PCFGQOS0_5",  .addr = A_PCFGQOS0_5,
    },{ .name = "PCFGQOS1_5",  .addr = A_PCFGQOS1_5,
    },{ .name = "PCFGWQOS0_5",  .addr = A_PCFGWQOS0_5,
    },{ .name = "PCFGWQOS1_5",  .addr = A_PCFGWQOS1_5,
    },{ .name = "SARBASE0",  .addr = A_SARBASE0,
    },{ .name = "SARSIZE0",  .addr = A_SARSIZE0,
    },{ .name = "SARBASE1",  .addr = A_SARBASE1,
        .reset = 0x1,
    },{ .name = "SARSIZE1",  .addr = A_SARSIZE1,
    },{ .name = "DERATEINT_SHADOW",  .addr = A_DERATEINT_SHADOW,
        .reset = 0x800000,
    },{ .name = "RFSHCTL0_SHADOW",  .addr = A_RFSHCTL0_SHADOW,
        .reset = 0x210000,
    },{ .name = "RFSHTMG_SHADOW",  .addr = A_RFSHTMG_SHADOW,
        .reset = 0x62008c,
    },{ .name = "INIT3_SHADOW",  .addr = A_INIT3_SHADOW,
        .reset = 0x510,
    },{ .name = "INIT4_SHADOW",  .addr = A_INIT4_SHADOW,
    },{ .name = "INIT6_SHADOW",  .addr = A_INIT6_SHADOW,
    },{ .name = "INIT7_SHADOW",  .addr = A_INIT7_SHADOW,
    },{ .name = "DRAMTMG0_SHADOW",  .addr = A_DRAMTMG0_SHADOW,
        .reset = 0xf101b0f,
    },{ .name = "DRAMTMG1_SHADOW",  .addr = A_DRAMTMG1_SHADOW,
        .reset = 0x80414,
    },{ .name = "DRAMTMG2_SHADOW",  .addr = A_DRAMTMG2_SHADOW,
        .reset = 0x305060d,
    },{ .name = "DRAMTMG3_SHADOW",  .addr = A_DRAMTMG3_SHADOW,
        .reset = 0x50400c,
    },{ .name = "DRAMTMG4_SHADOW",  .addr = A_DRAMTMG4_SHADOW,
        .reset = 0x5040405,
    },{ .name = "DRAMTMG5_SHADOW",  .addr = A_DRAMTMG5_SHADOW,
        .reset = 0x5050403,
    },{ .name = "DRAMTMG6_SHADOW",  .addr = A_DRAMTMG6_SHADOW,
        .reset = 0x2020005,
    },{ .name = "DRAMTMG7_SHADOW",  .addr = A_DRAMTMG7_SHADOW,
        .reset = 0x202,
    },{ .name = "DRAMTMG8_SHADOW",  .addr = A_DRAMTMG8_SHADOW,
        .reset = 0x3034405,
    },{ .name = "DRAMTMG9_SHADOW",  .addr = A_DRAMTMG9_SHADOW,
        .reset = 0x4040d,
    },{ .name = "DRAMTMG10_SHADOW",  .addr = A_DRAMTMG10_SHADOW,
        .reset = 0x1c180a,
    },{ .name = "DRAMTMG11_SHADOW",  .addr = A_DRAMTMG11_SHADOW,
        .reset = 0x440c021c,
    },{ .name = "DRAMTMG12_SHADOW",  .addr = A_DRAMTMG12_SHADOW,
        .reset = 0x20610,
    },{ .name = "DRAMTMG13_SHADOW",  .addr = A_DRAMTMG13_SHADOW,
        .reset = 0x1c200004,
    },{ .name = "DRAMTMG14_SHADOW",  .addr = A_DRAMTMG14_SHADOW,
        .reset = 0xa0,
    },{ .name = "ZQCTL0_SHADOW",  .addr = A_ZQCTL0_SHADOW,
        .reset = 0x2000040,
    },{ .name = "DFITMG0_SHADOW",  .addr = A_DFITMG0_SHADOW,
        .reset = 0x7020002,
    },{ .name = "DFITMG1_SHADOW",  .addr = A_DFITMG1_SHADOW,
        .reset = 0x404,
    },{ .name = "DFITMG2_SHADOW",  .addr = A_DFITMG2_SHADOW,
        .reset = 0x202,
    },{ .name = "ODTCFG_SHADOW",  .addr = A_ODTCFG_SHADOW,
        .reset = 0x4000400,
    }
};

static void ddrc_reset(DeviceState *dev)
{
    DDRC *s = XILINX_DDRC(dev);
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
        register_reset(&s->regs_info[i]);
    }

}

static const MemoryRegionOps ddrc_ops = {
    .read = register_read_memory,
    .write_with_attrs = register_write_memory_with_attrs,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void ddrc_init(Object *obj)
{
    DDRC *s = XILINX_DDRC(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    RegisterInfoArray *reg_array;

    memory_region_init(&s->iomem, obj, TYPE_XILINX_DDRC, R_MAX * 4);
    reg_array =
        register_init_block32(DEVICE(obj), ddrc_regs_info,
                              ARRAY_SIZE(ddrc_regs_info),
                              s->regs_info, s->regs,
                              &ddrc_ops,
                              XILINX_DDRC_ERR_DEBUG,
                              R_MAX * 4);
    memory_region_add_subregion(&s->iomem,
                                0x0,
                                &reg_array->mem);
    sysbus_init_mmio(sbd, &s->iomem);
}

static const VMStateDescription vmstate_ddrc = {
    .name = TYPE_XILINX_DDRC,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, DDRC, R_MAX),
        VMSTATE_END_OF_LIST(),
    }
};

static void ddrc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->reset = ddrc_reset;
    dc->vmsd = &vmstate_ddrc;
}

static const TypeInfo ddrc_info = {
    .name          = TYPE_XILINX_DDRC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(DDRC),
    .class_init    = ddrc_class_init,
    .instance_init = ddrc_init,
};

static void ddrc_register_types(void)
{
    type_register_static(&ddrc_info);
}

type_init(ddrc_register_types)
