qemu/hw/misc/xilinx_zynqmp_crf.c
<<
>>
Prefs
   1/*
   2 * QEMU model of the CRF_APB APB control registers for clock controller. The RST_ctrl_fpd will be added to this as well
   3 *
   4 * Copyright (c) 2014 Xilinx Inc.
   5 *
   6 * Autogenerated by xregqemu.py 2014-01-22.
   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 "qemu/log.h"
  32
  33#include "hw/fdt_generic_util.h"
  34
  35#ifndef XILINX_CRF_APB_ERR_DEBUG
  36#define XILINX_CRF_APB_ERR_DEBUG 0
  37#endif
  38
  39#define TYPE_XILINX_CRF_APB "xlnx.zynqmp_crf"
  40
  41#define XILINX_CRF_APB(obj) \
  42     OBJECT_CHECK(CRF_APB, (obj), TYPE_XILINX_CRF_APB)
  43
  44REG32(ERR_CTRL, 0x0)
  45    FIELD(ERR_CTRL, SLVERR_ENABLE, 1, 0)
  46REG32(IR_STATUS, 0x4)
  47    FIELD(IR_STATUS, ADDR_DECODE_ERR, 1, 0)
  48REG32(IR_MASK, 0x8)
  49    FIELD(IR_MASK, ADDR_DECODE_ERR, 1, 0)
  50REG32(IR_ENABLE, 0xc)
  51    FIELD(IR_ENABLE, ADDR_DECODE_ERR, 1, 0)
  52REG32(IR_DISABLE, 0x10)
  53    FIELD(IR_DISABLE, ADDR_DECODE_ERR, 1, 0)
  54REG32(CRF_ECO, 0x18)
  55REG32(APLL_CTRL, 0x20)
  56    FIELD(APLL_CTRL, POST_SRC, 3, 24)
  57    FIELD(APLL_CTRL, PRE_SRC, 3, 20)
  58    FIELD(APLL_CTRL, CLKOUTDIV, 1, 17)
  59    FIELD(APLL_CTRL, DIV2, 1, 16)
  60    FIELD(APLL_CTRL, FBDIV, 7, 8)
  61    FIELD(APLL_CTRL, BYPASS, 1, 3)
  62    FIELD(APLL_CTRL, RESET, 1, 0)
  63REG32(APLL_CFG, 0x24)
  64    FIELD(APLL_CFG, LOCK_DLY, 7, 25)
  65    FIELD(APLL_CFG, LOCK_CNT, 10, 13)
  66    FIELD(APLL_CFG, LFHF, 2, 10)
  67    FIELD(APLL_CFG, CP, 4, 5)
  68    FIELD(APLL_CFG, RES, 4, 0)
  69REG32(APLL_FRAC_CFG, 0x28)
  70    FIELD(APLL_FRAC_CFG, ENABLED, 1, 31)
  71    FIELD(APLL_FRAC_CFG, SEED, 3, 22)
  72    FIELD(APLL_FRAC_CFG, ALGRTHM, 1, 19)
  73    FIELD(APLL_FRAC_CFG, ORDER, 1, 18)
  74    FIELD(APLL_FRAC_CFG, DATA, 16, 0)
  75REG32(DPLL_CTRL, 0x2c)
  76    FIELD(DPLL_CTRL, POST_SRC, 3, 24)
  77    FIELD(DPLL_CTRL, PRE_SRC, 3, 20)
  78    FIELD(DPLL_CTRL, CLKOUTDIV, 1, 17)
  79    FIELD(DPLL_CTRL, DIV2, 1, 16)
  80    FIELD(DPLL_CTRL, FBDIV, 7, 8)
  81    FIELD(DPLL_CTRL, BYPASS, 1, 3)
  82    FIELD(DPLL_CTRL, RESET, 1, 0)
  83REG32(DPLL_CFG, 0x30)
  84    FIELD(DPLL_CFG, LOCK_DLY, 7, 25)
  85    FIELD(DPLL_CFG, LOCK_CNT, 10, 13)
  86    FIELD(DPLL_CFG, LFHF, 2, 10)
  87    FIELD(DPLL_CFG, CP, 4, 5)
  88    FIELD(DPLL_CFG, RES, 4, 0)
  89REG32(DPLL_FRAC_CFG, 0x34)
  90    FIELD(DPLL_FRAC_CFG, ENABLED, 1, 31)
  91    FIELD(DPLL_FRAC_CFG, SEED, 3, 22)
  92    FIELD(DPLL_FRAC_CFG, ALGRTHM, 1, 19)
  93    FIELD(DPLL_FRAC_CFG, ORDER, 1, 18)
  94    FIELD(DPLL_FRAC_CFG, DATA, 16, 0)
  95REG32(VPLL_CTRL, 0x38)
  96    FIELD(VPLL_CTRL, POST_SRC, 3, 24)
  97    FIELD(VPLL_CTRL, PRE_SRC, 3, 20)
  98    FIELD(VPLL_CTRL, CLKOUTDIV, 1, 17)
  99    FIELD(VPLL_CTRL, DIV2, 1, 16)
 100    FIELD(VPLL_CTRL, FBDIV, 7, 8)
 101    FIELD(VPLL_CTRL, BYPASS, 1, 3)
 102    FIELD(VPLL_CTRL, RESET, 1, 0)
 103REG32(VPLL_CFG, 0x3c)
 104    FIELD(VPLL_CFG, LOCK_DLY, 7, 25)
 105    FIELD(VPLL_CFG, LOCK_CNT, 10, 13)
 106    FIELD(VPLL_CFG, LFHF, 2, 10)
 107    FIELD(VPLL_CFG, CP, 4, 5)
 108    FIELD(VPLL_CFG, RES, 4, 0)
 109REG32(VPLL_FRAC_CFG, 0x40)
 110    FIELD(VPLL_FRAC_CFG, ENABLED, 1, 31)
 111    FIELD(VPLL_FRAC_CFG, SEED, 3, 22)
 112    FIELD(VPLL_FRAC_CFG, ALGRTHM, 1, 19)
 113    FIELD(VPLL_FRAC_CFG, ORDER, 1, 18)
 114    FIELD(VPLL_FRAC_CFG, DATA, 16, 0)
 115REG32(PLL_STATUS, 0x44)
 116    FIELD(PLL_STATUS, VPLL_STABLE, 1, 5)
 117    FIELD(PLL_STATUS, DPLL_STABLE, 1, 4)
 118    FIELD(PLL_STATUS, APLL_STABLE, 1, 3)
 119    FIELD(PLL_STATUS, VPLL_LOCK, 1, 2)
 120    FIELD(PLL_STATUS, DPLL_LOCK, 1, 1)
 121    FIELD(PLL_STATUS, APLL_LOCK, 1, 0)
 122REG32(APLL_TO_LPD_CTRL, 0x48)
 123    FIELD(APLL_TO_LPD_CTRL, DIVISOR0, 6, 8)
 124REG32(DPLL_TO_LPD_CTRL, 0x4c)
 125    FIELD(DPLL_TO_LPD_CTRL, DIVISOR0, 6, 8)
 126REG32(VPLL_TO_LPD_CTRL, 0x50)
 127    FIELD(VPLL_TO_LPD_CTRL, DIVISOR0, 6, 8)
 128REG32(CPU_A9_CTRL, 0x60)
 129    FIELD(CPU_A9_CTRL, A9CLKSTOP, 2, 26)
 130    FIELD(CPU_A9_CTRL, CLKACT_HALF, 1, 25)
 131    FIELD(CPU_A9_CTRL, CLKACT_FULL, 1, 24)
 132    FIELD(CPU_A9_CTRL, DIVISOR0, 6, 8)
 133    FIELD(CPU_A9_CTRL, SRCSEL, 3, 0)
 134REG32(DBG_TRACE_CTRL, 0x64)
 135    FIELD(DBG_TRACE_CTRL, CLKACT, 1, 24)
 136    FIELD(DBG_TRACE_CTRL, DIVISOR0, 6, 8)
 137    FIELD(DBG_TRACE_CTRL, SRCSEL, 3, 0)
 138REG32(DBG_FPD_CTRL, 0x68)
 139    FIELD(DBG_FPD_CTRL, CLKACT, 1, 24)
 140    FIELD(DBG_FPD_CTRL, DIVISOR0, 6, 8)
 141    FIELD(DBG_FPD_CTRL, SRCSEL, 3, 0)
 142REG32(DP_VIDEO_REF_CTRL, 0x70)
 143    FIELD(DP_VIDEO_REF_CTRL, CLKACT, 1, 24)
 144    FIELD(DP_VIDEO_REF_CTRL, DIVISOR0, 6, 8)
 145    FIELD(DP_VIDEO_REF_CTRL, SRCSEL, 3, 0)
 146REG32(DP_AUDIO_REF_CTRL, 0x74)
 147    FIELD(DP_AUDIO_REF_CTRL, CLKACT, 1, 24)
 148    FIELD(DP_AUDIO_REF_CTRL, DIVISOR0, 6, 8)
 149    FIELD(DP_AUDIO_REF_CTRL, SRCSEL, 3, 0)
 150REG32(DP_LINK_REF_CTRL, 0x78)
 151    FIELD(DP_LINK_REF_CTRL, CLKACT, 1, 24)
 152    FIELD(DP_LINK_REF_CTRL, DIVISOR1, 6, 16)
 153    FIELD(DP_LINK_REF_CTRL, DIVISOR0, 6, 8)
 154    FIELD(DP_LINK_REF_CTRL, SRCSEL, 3, 0)
 155REG32(DP_STC_REF_CTRL, 0x7c)
 156    FIELD(DP_STC_REF_CTRL, CLKACT, 1, 24)
 157    FIELD(DP_STC_REF_CTRL, DIVISOR1, 6, 16)
 158    FIELD(DP_STC_REF_CTRL, DIVISOR0, 6, 8)
 159    FIELD(DP_STC_REF_CTRL, SRCSEL, 3, 0)
 160REG32(DDR_CTRL, 0x80)
 161    FIELD(DDR_CTRL, CLKACT, 1, 24)
 162    FIELD(DDR_CTRL, DIVISOR0, 6, 8)
 163    FIELD(DDR_CTRL, SRCSEL, 3, 0)
 164REG32(GPU_REF_CTRL, 0x84)
 165    FIELD(GPU_REF_CTRL, PP1_CLKACT, 1, 26)
 166    FIELD(GPU_REF_CTRL, PP0_CLKACT, 1, 25)
 167    FIELD(GPU_REF_CTRL, CLKACT, 1, 24)
 168    FIELD(GPU_REF_CTRL, DIVISOR0, 6, 8)
 169    FIELD(GPU_REF_CTRL, SRCSEL, 3, 0)
 170REG32(AFI0_REF_CTRL, 0x88)
 171    FIELD(AFI0_REF_CTRL, CLKACT, 1, 24)
 172    FIELD(AFI0_REF_CTRL, DIVISOR0, 6, 8)
 173    FIELD(AFI0_REF_CTRL, SRCSEL, 3, 0)
 174REG32(AFI1_REF_CTRL, 0x8c)
 175    FIELD(AFI1_REF_CTRL, CLKACT, 1, 24)
 176    FIELD(AFI1_REF_CTRL, DIVISOR0, 6, 8)
 177    FIELD(AFI1_REF_CTRL, SRCSEL, 3, 0)
 178REG32(AFI2_REF_CTRL, 0x90)
 179    FIELD(AFI2_REF_CTRL, CLKACT, 1, 24)
 180    FIELD(AFI2_REF_CTRL, DIVISOR0, 6, 8)
 181    FIELD(AFI2_REF_CTRL, SRCSEL, 3, 0)
 182REG32(AFI3_REF_CTRL, 0x94)
 183    FIELD(AFI3_REF_CTRL, CLKACT, 1, 24)
 184    FIELD(AFI3_REF_CTRL, DIVISOR0, 6, 8)
 185    FIELD(AFI3_REF_CTRL, SRCSEL, 3, 0)
 186REG32(AFI4_REF_CTRL, 0x98)
 187    FIELD(AFI4_REF_CTRL, CLKACT, 1, 24)
 188    FIELD(AFI4_REF_CTRL, DIVISOR0, 6, 8)
 189    FIELD(AFI4_REF_CTRL, SRCSEL, 3, 0)
 190REG32(AFI5_REF_CTRL, 0x9c)
 191    FIELD(AFI5_REF_CTRL, CLKACT, 1, 24)
 192    FIELD(AFI5_REF_CTRL, DIVISOR0, 6, 8)
 193    FIELD(AFI5_REF_CTRL, SRCSEL, 3, 0)
 194REG32(SATA_REF_CTRL, 0xa0)
 195    FIELD(SATA_REF_CTRL, CLKACT, 1, 24)
 196    FIELD(SATA_REF_CTRL, DIVISOR0, 6, 8)
 197    FIELD(SATA_REF_CTRL, SRCSEL, 3, 0)
 198REG32(PCIE_REF_CTRL, 0xb4)
 199    FIELD(PCIE_REF_CTRL, CLKACT, 1, 24)
 200    FIELD(PCIE_REF_CTRL, DIVISOR0, 6, 8)
 201    FIELD(PCIE_REF_CTRL, SRCSEL, 3, 0)
 202REG32(GDMA_REF_CTRL, 0xb8)
 203    FIELD(GDMA_REF_CTRL, CLKACT, 1, 24)
 204    FIELD(GDMA_REF_CTRL, DIVISOR0, 6, 8)
 205    FIELD(GDMA_REF_CTRL, SRCSEL, 3, 0)
 206REG32(DPDMA_REF_CTRL, 0xbc)
 207    FIELD(DPDMA_REF_CTRL, CLKACT, 1, 24)
 208    FIELD(DPDMA_REF_CTRL, DIVISOR0, 6, 8)
 209    FIELD(DPDMA_REF_CTRL, SRCSEL, 3, 0)
 210REG32(TOPSW_MAIN_CTRL, 0xc0)
 211    FIELD(TOPSW_MAIN_CTRL, CLKACT, 1, 24)
 212    FIELD(TOPSW_MAIN_CTRL, DIVISOR0, 6, 8)
 213    FIELD(TOPSW_MAIN_CTRL, SRCSEL, 3, 0)
 214REG32(TOPSW_LSBUS_CTRL, 0xc4)
 215    FIELD(TOPSW_LSBUS_CTRL, CLKACT, 1, 24)
 216    FIELD(TOPSW_LSBUS_CTRL, DIVISOR0, 6, 8)
 217    FIELD(TOPSW_LSBUS_CTRL, SRCSEL, 3, 0)
 218REG32(GTGREF0_REF_CTRL, 0xc8)
 219    FIELD(GTGREF0_REF_CTRL, CLKACT, 1, 24)
 220    FIELD(GTGREF0_REF_CTRL, DIVISOR0, 6, 8)
 221    FIELD(GTGREF0_REF_CTRL, SRCSEL, 3, 0)
 222REG32(GTGREF1_REF_CTRL, 0xcc)
 223    FIELD(GTGREF1_REF_CTRL, CLKACT, 1, 24)
 224    FIELD(GTGREF1_REF_CTRL, DIVISOR0, 6, 8)
 225    FIELD(GTGREF1_REF_CTRL, SRCSEL, 3, 0)
 226REG32(DFT300_REF_CTRL, 0xd0)
 227    FIELD(DFT300_REF_CTRL, CLKACT, 1, 24)
 228    FIELD(DFT300_REF_CTRL, DIVISOR0, 6, 8)
 229    FIELD(DFT300_REF_CTRL, SRCSEL, 3, 0)
 230REG32(DFT270_REF_CTRL, 0xd4)
 231    FIELD(DFT270_REF_CTRL, CLKACT, 1, 24)
 232    FIELD(DFT270_REF_CTRL, DIVISOR0, 6, 8)
 233    FIELD(DFT270_REF_CTRL, SRCSEL, 3, 0)
 234REG32(DFT250_REF_CTRL, 0xd8)
 235    FIELD(DFT250_REF_CTRL, CLKACT, 1, 24)
 236    FIELD(DFT250_REF_CTRL, DIVISOR0, 6, 8)
 237    FIELD(DFT250_REF_CTRL, SRCSEL, 3, 0)
 238REG32(DFT125_REF_CTRL, 0xdc)
 239    FIELD(DFT125_REF_CTRL, CLKACT, 1, 24)
 240    FIELD(DFT125_REF_CTRL, DIVISOR0, 6, 8)
 241    FIELD(DFT125_REF_CTRL, SRCSEL, 3, 0)
 242
 243REG32(RST_FPD_TOP, 0x100)
 244    FIELD(RST_FPD_TOP, PCIE_BRDG_RESET, 1, 18)
 245    FIELD(RST_FPD_TOP, PCIE_CTRL_RESET, 1, 17)
 246    FIELD(RST_FPD_TOP, DP_RESET, 1, 16)
 247    FIELD(RST_FPD_TOP, AFI_FM5_RESET, 1, 12)
 248    FIELD(RST_FPD_TOP, AFI_FM4_RESET, 1, 11)
 249    FIELD(RST_FPD_TOP, AFI_FM3_RESET, 1, 10)
 250    FIELD(RST_FPD_TOP, AFI_FM2_RESET, 1, 9)
 251    FIELD(RST_FPD_TOP, AFI_FM1_RESET, 1, 8)
 252    FIELD(RST_FPD_TOP, AFI_FM0_RESET, 1, 7)
 253    FIELD(RST_FPD_TOP, GDMA_RESET, 1, 6)
 254    FIELD(RST_FPD_TOP, GPU_PP1_RESET, 1, 5)
 255    FIELD(RST_FPD_TOP, GPU_PP0_RESET, 1, 4)
 256    FIELD(RST_FPD_TOP, GPU_RESET, 1, 3)
 257    FIELD(RST_FPD_TOP, GT_RESET, 1, 2)
 258    FIELD(RST_FPD_TOP, SATA_RESET, 1, 1)
 259REG32(RST_FPD_APU, 0x104)
 260    FIELD(RST_FPD_APU, PERI_RESET, 1, 13)
 261    FIELD(RST_FPD_APU, SCU_RESET, 1, 12)
 262    FIELD(RST_FPD_APU, CPU1_AWDT_RESET, 1, 9)
 263    FIELD(RST_FPD_APU, CPU0_AWDT_RESET, 1, 8)
 264    FIELD(RST_FPD_APU, CPU1_CP14_RESET, 1, 5)
 265    FIELD(RST_FPD_APU, CPU0_CP14_RESET, 1, 4)
 266    FIELD(RST_FPD_APU, CPU3_A9_RESET, 1, 3)
 267    FIELD(RST_FPD_APU, CPU2_A9_RESET, 1, 2)
 268    FIELD(RST_FPD_APU, CPU1_A9_RESET, 1, 1)
 269    FIELD(RST_FPD_APU, CPU0_A9_RESET, 1, 0)
 270REG32(RST_DDR_SS, 0x108)
 271    FIELD(RST_DDR_SS, DDR_RESET, 1, 3)
 272    FIELD(RST_DDR_SS, APM_RESET, 1, 2)
 273    FIELD(RST_DDR_SS, QOS_RESET, 1, 1)
 274    FIELD(RST_DDR_SS, XMPU_RESET, 1, 0)
 275
 276#define R_MAX (R_RST_DDR_SS + 1)
 277
 278typedef struct CRF_APB {
 279    SysBusDevice parent_obj;
 280    MemoryRegion iomem;
 281    qemu_irq irq_ir;
 282
 283    uint32_t regs[R_MAX];
 284    RegisterInfo regs_info[R_MAX];
 285} CRF_APB;
 286
 287static const MemoryRegionOps crf_apb_ops = {
 288    .read = register_read_memory_le,
 289    .write = register_write_memory_le,
 290    .endianness = DEVICE_LITTLE_ENDIAN,
 291    .valid = {
 292        .min_access_size = 4,
 293        .max_access_size = 4,
 294    },
 295};
 296
 297static void ir_update_irq(CRF_APB *s)
 298{
 299    bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
 300    qemu_set_irq(s->irq_ir, pending);
 301}
 302
 303static void ir_status_postw(RegisterInfo *reg, uint64_t val64)
 304{
 305    CRF_APB *s = XILINX_CRF_APB(reg->opaque);
 306    ir_update_irq(s);
 307}
 308
 309static uint64_t ir_enable_prew(RegisterInfo *reg, uint64_t val64)
 310{
 311    CRF_APB *s = XILINX_CRF_APB(reg->opaque);
 312    uint32_t val = val64;
 313
 314    s->regs[R_IR_MASK] &= ~val;
 315    ir_update_irq(s);
 316    return 0;
 317}
 318
 319static uint64_t ir_disable_prew(RegisterInfo *reg, uint64_t val64)
 320{
 321    CRF_APB *s = XILINX_CRF_APB(reg->opaque);
 322    uint32_t val = val64;
 323
 324    s->regs[R_IR_MASK] |= val;
 325    ir_update_irq(s);
 326    return 0;
 327}
 328
 329static RegisterAccessInfo crf_apb_regs_info[] = {
 330    {   .name = "ERR_CTRL",  .decode.addr = A_ERR_CTRL,
 331    },{ .name = "IR_STATUS",  .decode.addr = A_IR_STATUS,
 332        .w1c = 0x1,
 333        .post_write = ir_status_postw,
 334    },{ .name = "IR_MASK",  .decode.addr = A_IR_MASK,
 335        .reset = 0x1,
 336        .ro = 0x1,
 337    },{ .name = "IR_ENABLE",  .decode.addr = A_IR_ENABLE,
 338        .pre_write = ir_enable_prew,
 339    },{ .name = "IR_DISABLE",  .decode.addr = A_IR_DISABLE,
 340        .pre_write = ir_disable_prew,
 341    },{ .name = "CRF_ECO",  .decode.addr = A_CRF_ECO,
 342    },{ .name = "APLL_CTRL",  .decode.addr = A_APLL_CTRL,
 343        .reset = 0x2809,
 344        .rsvd = 0xf88c80f6L,
 345    },{ .name = "APLL_CFG",  .decode.addr = A_APLL_CFG,
 346        .rsvd = 0x1801210,
 347    },{ .name = "APLL_FRAC_CFG",  .decode.addr = A_APLL_FRAC_CFG,
 348        .rsvd = 0x7e330000,
 349    },{ .name = "DPLL_CTRL",  .decode.addr = A_DPLL_CTRL,
 350        .reset = 0x2809,
 351        .rsvd = 0xf88c80f6L,
 352    },{ .name = "DPLL_CFG",  .decode.addr = A_DPLL_CFG,
 353        .rsvd = 0x1801210,
 354    },{ .name = "DPLL_FRAC_CFG",  .decode.addr = A_DPLL_FRAC_CFG,
 355        .rsvd = 0x7e330000,
 356    },{ .name = "VPLL_CTRL",  .decode.addr = A_VPLL_CTRL,
 357        .reset = 0x2809,
 358        .rsvd = 0xf88c80f6L,
 359    },{ .name = "VPLL_CFG",  .decode.addr = A_VPLL_CFG,
 360        .rsvd = 0x1801210,
 361    },{ .name = "VPLL_FRAC_CFG",  .decode.addr = A_VPLL_FRAC_CFG,
 362        .rsvd = 0x7e330000,
 363    },{ .name = "PLL_STATUS",  .decode.addr = A_PLL_STATUS,
 364        .reset = 0x3f,
 365        .rsvd = 0xc0,
 366        .ro = 0x3f,
 367    },{ .name = "APLL_TO_LPD_CTRL",  .decode.addr = A_APLL_TO_LPD_CTRL,
 368        .reset = 0x400,
 369        .rsvd = 0xc0ff,
 370    },{ .name = "DPLL_TO_LPD_CTRL",  .decode.addr = A_DPLL_TO_LPD_CTRL,
 371        .reset = 0x400,
 372        .rsvd = 0xc0ff,
 373    },{ .name = "VPLL_TO_LPD_CTRL",  .decode.addr = A_VPLL_TO_LPD_CTRL,
 374        .reset = 0x400,
 375        .rsvd = 0xc0ff,
 376    },{ .name = "CPU_A9_CTRL",  .decode.addr = A_CPU_A9_CTRL,
 377        .reset = 0xf000400,
 378        .rsvd = 0xf0ffc0f8L,
 379    },{ .name = "DBG_TRACE_CTRL",  .decode.addr = A_DBG_TRACE_CTRL,
 380        .reset = 0x2500,
 381        .rsvd = 0xfeffc0f8L,
 382    },{ .name = "DBG_FPD_CTRL",  .decode.addr = A_DBG_FPD_CTRL,
 383        .reset = 0x1002500,
 384        .rsvd = 0xfeffc0f8L,
 385    },{ .name = "DP_VIDEO_REF_CTRL",  .decode.addr = A_DP_VIDEO_REF_CTRL,
 386        .reset = 0x1002300,
 387        .rsvd = 0xfeffc0f8L,
 388    },{ .name = "DP_AUDIO_REF_CTRL",  .decode.addr = A_DP_AUDIO_REF_CTRL,
 389        .reset = 0x1002300,
 390        .rsvd = 0xfeffc0f8L,
 391    },{ .name = "DP_LINK_REF_CTRL",  .decode.addr = A_DP_LINK_REF_CTRL,
 392        .reset = 0x1203200,
 393        .rsvd = 0xfec0c0f8L,
 394    },{ .name = "DP_STC_REF_CTRL",  .decode.addr = A_DP_STC_REF_CTRL,
 395        .reset = 0x1203200,
 396        .rsvd = 0xfec0c0f8L,
 397    },{ .name = "DDR_CTRL",  .decode.addr = A_DDR_CTRL,
 398        .reset = 0x1000500,
 399        .rsvd = 0xfeffc0f8L,
 400    },{ .name = "GPU_REF_CTRL",  .decode.addr = A_GPU_REF_CTRL,
 401        .reset = 0x1500,
 402        .rsvd = 0xf8ffc0f8L,
 403    },{ .name = "AFI0_REF_CTRL",  .decode.addr = A_AFI0_REF_CTRL,
 404        .reset = 0x600,
 405        .rsvd = 0x7effc0f8,
 406    },{ .name = "AFI1_REF_CTRL",  .decode.addr = A_AFI1_REF_CTRL,
 407        .reset = 0x600,
 408        .rsvd = 0x7effc0f8,
 409    },{ .name = "AFI2_REF_CTRL",  .decode.addr = A_AFI2_REF_CTRL,
 410        .reset = 0x600,
 411        .rsvd = 0x7effc0f8,
 412    },{ .name = "AFI3_REF_CTRL",  .decode.addr = A_AFI3_REF_CTRL,
 413        .reset = 0x600,
 414        .rsvd = 0x7effc0f8,
 415    },{ .name = "AFI4_REF_CTRL",  .decode.addr = A_AFI4_REF_CTRL,
 416        .reset = 0x600,
 417        .rsvd = 0x7effc0f8,
 418    },{ .name = "AFI5_REF_CTRL",  .decode.addr = A_AFI5_REF_CTRL,
 419        .reset = 0x600,
 420        .rsvd = 0x7effc0f8,
 421    },{ .name = "SATA_REF_CTRL",  .decode.addr = A_SATA_REF_CTRL,
 422        .reset = 0x1001600,
 423        .rsvd = 0xfeffc0f8L,
 424    },{ .name = "PCIE_REF_CTRL",  .decode.addr = A_PCIE_REF_CTRL,
 425        .reset = 0x1500,
 426        .rsvd = 0xfeffc0f8L,
 427    },{ .name = "GDMA_REF_CTRL",  .decode.addr = A_GDMA_REF_CTRL,
 428        .reset = 0x1000500,
 429        .rsvd = 0xfeffc0f8L,
 430    },{ .name = "DPDMA_REF_CTRL",  .decode.addr = A_DPDMA_REF_CTRL,
 431        .reset = 0x1000500,
 432        .rsvd = 0xfeffc0f8L,
 433    },{ .name = "TOPSW_MAIN_CTRL",  .decode.addr = A_TOPSW_MAIN_CTRL,
 434        .reset = 0x1000500,
 435        .rsvd = 0xfeffc0f8L,
 436    },{ .name = "TOPSW_LSBUS_CTRL",  .decode.addr = A_TOPSW_LSBUS_CTRL,
 437        .reset = 0x1000800,
 438        .rsvd = 0xfeffc0f8L,
 439    },{ .name = "GTGREF0_REF_CTRL",  .decode.addr = A_GTGREF0_REF_CTRL,
 440        .reset = 0x800,
 441        .rsvd = 0xfeffc0f8L,
 442    },{ .name = "GTGREF1_REF_CTRL",  .decode.addr = A_GTGREF1_REF_CTRL,
 443        .reset = 0x800,
 444        .rsvd = 0xfeffc0f8L,
 445    },{ .name = "DFT300_REF_CTRL",  .decode.addr = A_DFT300_REF_CTRL,
 446        .reset = 0x800,
 447        .rsvd = 0xfeffc0f8L,
 448    },{ .name = "DFT270_REF_CTRL",  .decode.addr = A_DFT270_REF_CTRL,
 449        .reset = 0x800,
 450        .rsvd = 0xfeffc0f8L,
 451    },{ .name = "DFT250_REF_CTRL",  .decode.addr = A_DFT250_REF_CTRL,
 452        .reset = 0x800,
 453        .rsvd = 0xfeffc0f8L,
 454    },{ .name = "DFT125_REF_CTRL",  .decode.addr = A_DFT125_REF_CTRL,
 455        .reset = 0x800,
 456        .rsvd = 0xfeffc0f8L,
 457    },{ .name = "RST_FPD_TOP",  .decode.addr = A_RST_FPD_TOP,
 458        .reset = 0x71ffe,
 459        .rsvd = 0xf8e001,
 460    },{ .name = "RST_FPD_APU",  .decode.addr = A_RST_FPD_APU,
 461        .reset = 0x334f,
 462        .rsvd = 0xffcccc,
 463        .gpios = (RegisterGPIOMapping[]) {
 464            { .name = "RST_A9", .bit_pos = 0, .num = 4 },
 465            {},
 466        },
 467        .inhibit_reset = 1u << 31,
 468    },{ .name = "RST_DDR_SS",  .decode.addr = A_RST_DDR_SS,
 469        .reset = 0xf,
 470        .rsvd = 0xf0,
 471    }
 472};
 473
 474static void crf_apb_reset(DeviceState *dev)
 475{
 476    CRF_APB *s = XILINX_CRF_APB(dev);
 477    unsigned int i;
 478
 479    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
 480        register_reset(&s->regs_info[i]);
 481    }
 482
 483    ir_update_irq(s);
 484}
 485
 486static void crf_apb_realize(DeviceState *dev, Error **errp)
 487{
 488    CRF_APB *s = XILINX_CRF_APB(dev);
 489    const char *prefix = object_get_canonical_path(OBJECT(dev));
 490    unsigned int i;
 491
 492    for (i = 0; i < ARRAY_SIZE(crf_apb_regs_info); ++i) {
 493        RegisterInfo *r = &s->regs_info[i];
 494
 495        *r = (RegisterInfo) {
 496            .data = (uint8_t *)&s->regs[
 497                    crf_apb_regs_info[i].decode.addr/4],
 498            .data_size = sizeof(uint32_t),
 499            .access = &crf_apb_regs_info[i],
 500            .debug = XILINX_CRF_APB_ERR_DEBUG,
 501            .prefix = prefix,
 502            .opaque = s,
 503        };
 504        register_init(r);
 505        qdev_pass_all_gpios(DEVICE(r), dev);
 506
 507        memory_region_init_io(&r->mem, OBJECT(dev), &crf_apb_ops, r,
 508                              r->access->name, 4);
 509        memory_region_add_subregion(&s->iomem, r->access->decode.addr, &r->mem);
 510    }
 511}
 512
 513static void crf_apb_init(Object *obj)
 514{
 515    CRF_APB *s = XILINX_CRF_APB(obj);
 516    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 517
 518    memory_region_init(&s->iomem, obj, TYPE_XILINX_CRF_APB, R_MAX * 4);
 519    sysbus_init_mmio(sbd, &s->iomem);
 520    sysbus_init_irq(sbd, &s->irq_ir);
 521}
 522
 523static const VMStateDescription vmstate_crf_apb = {
 524    .name = TYPE_XILINX_CRF_APB,
 525    .version_id = 1,
 526    .minimum_version_id = 1,
 527    .minimum_version_id_old = 1,
 528    .fields = (VMStateField[]) {
 529        VMSTATE_UINT32_ARRAY(regs, CRF_APB, R_MAX),
 530        VMSTATE_END_OF_LIST(),
 531    }
 532};
 533
 534static const FDTGenericGPIOSet crf_gpios[] = {
 535    {
 536        .names = &fdt_generic_gpio_name_set_gpio,
 537        .gpios = (FDTGenericGPIOConnection[]) {
 538            { .name = "RST_A9",   .fdt_index = 0,   .range = 4 },
 539            { },
 540        }
 541    },
 542    { },
 543};
 544
 545static void crf_apb_class_init(ObjectClass *klass, void *data)
 546{
 547    DeviceClass *dc = DEVICE_CLASS(klass);
 548    FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
 549
 550    dc->reset = crf_apb_reset;
 551    dc->realize = crf_apb_realize;
 552    dc->vmsd = &vmstate_crf_apb;
 553    fggc->controller_gpios = crf_gpios;
 554}
 555
 556static const TypeInfo crf_apb_info = {
 557    .name          = TYPE_XILINX_CRF_APB,
 558    .parent        = TYPE_SYS_BUS_DEVICE,
 559    .instance_size = sizeof(CRF_APB),
 560    .class_init    = crf_apb_class_init,
 561    .instance_init = crf_apb_init,
 562    .interfaces    = (InterfaceInfo[]) {
 563        { TYPE_FDT_GENERIC_GPIO },
 564        { }
 565    },
 566};
 567
 568static void crf_apb_register_types(void)
 569{
 570    type_register_static(&crf_apb_info);
 571}
 572
 573type_init(crf_apb_register_types)
 574