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) 2017 Xilinx Inc.
   5 *
   6 * Autogenerated by xregqemu.py 2017-02-27.
   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#include "migration/vmstate.h"
  33#include "hw/qdev-properties.h"
  34#include "hw/arm/linux-boot-if.h"
  35
  36#include "hw/fdt_generic_util.h"
  37
  38#ifndef XILINX_CRF_APB_ERR_DEBUG
  39#define XILINX_CRF_APB_ERR_DEBUG 0
  40#endif
  41
  42#define TYPE_XILINX_CRF_APB "xlnx.zynqmp_crf"
  43
  44#define XILINX_CRF_APB(obj) \
  45     OBJECT_CHECK(CRF_APB, (obj), TYPE_XILINX_CRF_APB)
  46
  47REG32(ERR_CTRL, 0x0)
  48    FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
  49REG32(IR_STATUS, 0x4)
  50    FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
  51REG32(IR_MASK, 0x8)
  52    FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
  53REG32(IR_ENABLE, 0xc)
  54    FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
  55REG32(IR_DISABLE, 0x10)
  56    FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
  57REG32(CRF_WPROT, 0x1c)
  58    FIELD(CRF_WPROT, ACTIVE, 0, 1)
  59REG32(APLL_CTRL, 0x20)
  60    FIELD(APLL_CTRL, POST_SRC, 24, 3)
  61    FIELD(APLL_CTRL, PRE_SRC, 20, 3)
  62    FIELD(APLL_CTRL, CLKOUTDIV, 17, 1)
  63    FIELD(APLL_CTRL, DIV2, 16, 1)
  64    FIELD(APLL_CTRL, FBDIV, 8, 7)
  65    FIELD(APLL_CTRL, BYPASS, 3, 1)
  66    FIELD(APLL_CTRL, RESET, 0, 1)
  67REG32(APLL_CFG, 0x24)
  68    FIELD(APLL_CFG, LOCK_DLY, 25, 7)
  69    FIELD(APLL_CFG, LOCK_CNT, 13, 10)
  70    FIELD(APLL_CFG, LFHF, 10, 2)
  71    FIELD(APLL_CFG, CP, 5, 4)
  72    FIELD(APLL_CFG, RES, 0, 4)
  73REG32(APLL_FRAC_CFG, 0x28)
  74    FIELD(APLL_FRAC_CFG, ENABLED, 31, 1)
  75    FIELD(APLL_FRAC_CFG, SEED, 22, 3)
  76    FIELD(APLL_FRAC_CFG, ALGRTHM, 19, 1)
  77    FIELD(APLL_FRAC_CFG, ORDER, 18, 1)
  78    FIELD(APLL_FRAC_CFG, DATA, 0, 16)
  79REG32(DPLL_CTRL, 0x2c)
  80    FIELD(DPLL_CTRL, POST_SRC, 24, 3)
  81    FIELD(DPLL_CTRL, PRE_SRC, 20, 3)
  82    FIELD(DPLL_CTRL, CLKOUTDIV, 17, 1)
  83    FIELD(DPLL_CTRL, DIV2, 16, 1)
  84    FIELD(DPLL_CTRL, FBDIV, 8, 7)
  85    FIELD(DPLL_CTRL, BYPASS, 3, 1)
  86    FIELD(DPLL_CTRL, RESET, 0, 1)
  87REG32(DPLL_CFG, 0x30)
  88    FIELD(DPLL_CFG, LOCK_DLY, 25, 7)
  89    FIELD(DPLL_CFG, LOCK_CNT, 13, 10)
  90    FIELD(DPLL_CFG, LFHF, 10, 2)
  91    FIELD(DPLL_CFG, CP, 5, 4)
  92    FIELD(DPLL_CFG, RES, 0, 4)
  93REG32(DPLL_FRAC_CFG, 0x34)
  94    FIELD(DPLL_FRAC_CFG, ENABLED, 31, 1)
  95    FIELD(DPLL_FRAC_CFG, SEED, 22, 3)
  96    FIELD(DPLL_FRAC_CFG, ALGRTHM, 19, 1)
  97    FIELD(DPLL_FRAC_CFG, ORDER, 18, 1)
  98    FIELD(DPLL_FRAC_CFG, DATA, 0, 16)
  99REG32(VPLL_CTRL, 0x38)
 100    FIELD(VPLL_CTRL, POST_SRC, 24, 3)
 101    FIELD(VPLL_CTRL, PRE_SRC, 20, 3)
 102    FIELD(VPLL_CTRL, CLKOUTDIV, 17, 1)
 103    FIELD(VPLL_CTRL, DIV2, 16, 1)
 104    FIELD(VPLL_CTRL, FBDIV, 8, 7)
 105    FIELD(VPLL_CTRL, BYPASS, 3, 1)
 106    FIELD(VPLL_CTRL, RESET, 0, 1)
 107REG32(VPLL_CFG, 0x3c)
 108    FIELD(VPLL_CFG, LOCK_DLY, 25, 7)
 109    FIELD(VPLL_CFG, LOCK_CNT, 13, 10)
 110    FIELD(VPLL_CFG, LFHF, 10, 2)
 111    FIELD(VPLL_CFG, CP, 5, 4)
 112    FIELD(VPLL_CFG, RES, 0, 4)
 113REG32(VPLL_FRAC_CFG, 0x40)
 114    FIELD(VPLL_FRAC_CFG, ENABLED, 31, 1)
 115    FIELD(VPLL_FRAC_CFG, SEED, 22, 3)
 116    FIELD(VPLL_FRAC_CFG, ALGRTHM, 19, 1)
 117    FIELD(VPLL_FRAC_CFG, ORDER, 18, 1)
 118    FIELD(VPLL_FRAC_CFG, DATA, 0, 16)
 119REG32(PLL_STATUS, 0x44)
 120    FIELD(PLL_STATUS, VPLL_STABLE, 5, 1)
 121    FIELD(PLL_STATUS, DPLL_STABLE, 4, 1)
 122    FIELD(PLL_STATUS, APLL_STABLE, 3, 1)
 123    FIELD(PLL_STATUS, VPLL_LOCK, 2, 1)
 124    FIELD(PLL_STATUS, DPLL_LOCK, 1, 1)
 125    FIELD(PLL_STATUS, APLL_LOCK, 0, 1)
 126REG32(APLL_TO_LPD_CTRL, 0x48)
 127    FIELD(APLL_TO_LPD_CTRL, DIVISOR0, 8, 6)
 128REG32(DPLL_TO_LPD_CTRL, 0x4c)
 129    FIELD(DPLL_TO_LPD_CTRL, DIVISOR0, 8, 6)
 130REG32(VPLL_TO_LPD_CTRL, 0x50)
 131    FIELD(VPLL_TO_LPD_CTRL, DIVISOR0, 8, 6)
 132REG32(ACPU_CTRL, 0x60)
 133    FIELD(ACPU_CTRL, CLKACT_HALF, 25, 1)
 134    FIELD(ACPU_CTRL, CLKACT_FULL, 24, 1)
 135    FIELD(ACPU_CTRL, DIVISOR0, 8, 6)
 136    FIELD(ACPU_CTRL, SRCSEL, 0, 3)
 137REG32(DBG_TRACE_CTRL, 0x64)
 138    FIELD(DBG_TRACE_CTRL, CLKACT, 24, 1)
 139    FIELD(DBG_TRACE_CTRL, DIVISOR0, 8, 6)
 140    FIELD(DBG_TRACE_CTRL, SRCSEL, 0, 3)
 141REG32(DBG_FPD_CTRL, 0x68)
 142    FIELD(DBG_FPD_CTRL, CLKACT, 24, 1)
 143    FIELD(DBG_FPD_CTRL, DIVISOR0, 8, 6)
 144    FIELD(DBG_FPD_CTRL, SRCSEL, 0, 3)
 145REG32(DP_VIDEO_REF_CTRL, 0x70)
 146    FIELD(DP_VIDEO_REF_CTRL, CLKACT, 24, 1)
 147    FIELD(DP_VIDEO_REF_CTRL, DIVISOR1, 16, 6)
 148    FIELD(DP_VIDEO_REF_CTRL, DIVISOR0, 8, 6)
 149    FIELD(DP_VIDEO_REF_CTRL, SRCSEL, 0, 3)
 150REG32(DP_AUDIO_REF_CTRL, 0x74)
 151    FIELD(DP_AUDIO_REF_CTRL, CLKACT, 24, 1)
 152    FIELD(DP_AUDIO_REF_CTRL, DIVISOR1, 16, 6)
 153    FIELD(DP_AUDIO_REF_CTRL, DIVISOR0, 8, 6)
 154    FIELD(DP_AUDIO_REF_CTRL, SRCSEL, 0, 3)
 155REG32(DP_STC_REF_CTRL, 0x7c)
 156    FIELD(DP_STC_REF_CTRL, CLKACT, 24, 1)
 157    FIELD(DP_STC_REF_CTRL, DIVISOR1, 16, 6)
 158    FIELD(DP_STC_REF_CTRL, DIVISOR0, 8, 6)
 159    FIELD(DP_STC_REF_CTRL, SRCSEL, 0, 3)
 160REG32(DDR_CTRL, 0x80)
 161    FIELD(DDR_CTRL, CLKACT, 24, 1)
 162    FIELD(DDR_CTRL, DIVISOR0, 8, 6)
 163    FIELD(DDR_CTRL, SRCSEL, 0, 3)
 164REG32(GPU_REF_CTRL, 0x84)
 165    FIELD(GPU_REF_CTRL, PP1_CLKACT, 26, 1)
 166    FIELD(GPU_REF_CTRL, PP0_CLKACT, 25, 1)
 167    FIELD(GPU_REF_CTRL, CLKACT, 24, 1)
 168    FIELD(GPU_REF_CTRL, DIVISOR0, 8, 6)
 169    FIELD(GPU_REF_CTRL, SRCSEL, 0, 3)
 170REG32(SATA_REF_CTRL, 0xa0)
 171    FIELD(SATA_REF_CTRL, CLKACT, 24, 1)
 172    FIELD(SATA_REF_CTRL, DIVISOR0, 8, 6)
 173    FIELD(SATA_REF_CTRL, SRCSEL, 0, 3)
 174REG32(PCIE_REF_CTRL, 0xb4)
 175    FIELD(PCIE_REF_CTRL, CLKACT, 24, 1)
 176    FIELD(PCIE_REF_CTRL, DIVISOR0, 8, 6)
 177    FIELD(PCIE_REF_CTRL, SRCSEL, 0, 3)
 178REG32(GDMA_REF_CTRL, 0xb8)
 179    FIELD(GDMA_REF_CTRL, CLKACT, 24, 1)
 180    FIELD(GDMA_REF_CTRL, DIVISOR0, 8, 6)
 181    FIELD(GDMA_REF_CTRL, SRCSEL, 0, 3)
 182REG32(DPDMA_REF_CTRL, 0xbc)
 183    FIELD(DPDMA_REF_CTRL, CLKACT, 24, 1)
 184    FIELD(DPDMA_REF_CTRL, DIVISOR0, 8, 6)
 185    FIELD(DPDMA_REF_CTRL, SRCSEL, 0, 3)
 186REG32(TOPSW_MAIN_CTRL, 0xc0)
 187    FIELD(TOPSW_MAIN_CTRL, CLKACT, 24, 1)
 188    FIELD(TOPSW_MAIN_CTRL, DIVISOR0, 8, 6)
 189    FIELD(TOPSW_MAIN_CTRL, SRCSEL, 0, 3)
 190REG32(TOPSW_LSBUS_CTRL, 0xc4)
 191    FIELD(TOPSW_LSBUS_CTRL, CLKACT, 24, 1)
 192    FIELD(TOPSW_LSBUS_CTRL, DIVISOR0, 8, 6)
 193    FIELD(TOPSW_LSBUS_CTRL, SRCSEL, 0, 3)
 194REG32(DBG_TSTMP_CTRL, 0xf8)
 195    FIELD(DBG_TSTMP_CTRL, DIVISOR0, 8, 6)
 196    FIELD(DBG_TSTMP_CTRL, SRCSEL, 0, 3)
 197REG32(RST_FPD_TOP, 0x100)
 198    FIELD(RST_FPD_TOP, PCIE_CFG_RESET, 19, 1)
 199    FIELD(RST_FPD_TOP, PCIE_BRIDGE_RESET, 18, 1)
 200    FIELD(RST_FPD_TOP, PCIE_CTRL_RESET, 17, 1)
 201    FIELD(RST_FPD_TOP, DP_RESET, 16, 1)
 202    FIELD(RST_FPD_TOP, SWDT_RESET, 15, 1)
 203    FIELD(RST_FPD_TOP, AFI_FM5_RESET, 12, 1)
 204    FIELD(RST_FPD_TOP, AFI_FM4_RESET, 11, 1)
 205    FIELD(RST_FPD_TOP, AFI_FM3_RESET, 10, 1)
 206    FIELD(RST_FPD_TOP, AFI_FM2_RESET, 9, 1)
 207    FIELD(RST_FPD_TOP, AFI_FM1_RESET, 8, 1)
 208    FIELD(RST_FPD_TOP, AFI_FM0_RESET, 7, 1)
 209    FIELD(RST_FPD_TOP, GDMA_RESET, 6, 1)
 210    FIELD(RST_FPD_TOP, GPU_PP1_RESET, 5, 1)
 211    FIELD(RST_FPD_TOP, GPU_PP0_RESET, 4, 1)
 212    FIELD(RST_FPD_TOP, GPU_RESET, 3, 1)
 213    FIELD(RST_FPD_TOP, GT_RESET, 2, 1)
 214    FIELD(RST_FPD_TOP, SATA_RESET, 1, 1)
 215REG32(RST_FPD_APU, 0x104)
 216    FIELD(RST_FPD_APU, ACPU3_PWRON_RESET, 13, 1)
 217    FIELD(RST_FPD_APU, ACPU2_PWRON_RESET, 12, 1)
 218    FIELD(RST_FPD_APU, ACPU1_PWRON_RESET, 11, 1)
 219    FIELD(RST_FPD_APU, ACPU0_PWRON_RESET, 10, 1)
 220    FIELD(RST_FPD_APU, APU_L2_RESET, 8, 1)
 221    FIELD(RST_FPD_APU, ACPU3_RESET, 3, 1)
 222    FIELD(RST_FPD_APU, ACPU2_RESET, 2, 1)
 223    FIELD(RST_FPD_APU, ACPU1_RESET, 1, 1)
 224    FIELD(RST_FPD_APU, ACPU0_RESET, 0, 1)
 225REG32(RST_DDR_SS, 0x108)
 226    FIELD(RST_DDR_SS, DDR_RESET, 3, 1)
 227    FIELD(RST_DDR_SS, APM_RESET, 2, 1)
 228
 229#define R_MAX (R_RST_DDR_SS + 1)
 230
 231#define APU_MAX_CPU    4
 232
 233typedef struct CRF_APB {
 234    SysBusDevice parent_obj;
 235    MemoryRegion iomem;
 236    qemu_irq irq_ir;
 237    bool linux_direct_boot;
 238
 239    qemu_irq acpu_rst[APU_MAX_CPU];
 240    uint32_t regs[R_MAX];
 241    RegisterInfo regs_info[R_MAX];
 242} CRF_APB;
 243
 244static void ir_update_irq(CRF_APB *s)
 245{
 246    bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
 247    qemu_set_irq(s->irq_ir, pending);
 248}
 249
 250static void ir_status_postw(RegisterInfo *reg, uint64_t val64)
 251{
 252    CRF_APB *s = XILINX_CRF_APB(reg->opaque);
 253    ir_update_irq(s);
 254}
 255
 256static uint64_t ir_enable_prew(RegisterInfo *reg, uint64_t val64)
 257{
 258    CRF_APB *s = XILINX_CRF_APB(reg->opaque);
 259    uint32_t val = val64;
 260
 261    s->regs[R_IR_MASK] &= ~val;
 262    ir_update_irq(s);
 263    return 0;
 264}
 265
 266static uint64_t ir_disable_prew(RegisterInfo *reg, uint64_t val64)
 267{
 268    CRF_APB *s = XILINX_CRF_APB(reg->opaque);
 269    uint32_t val = val64;
 270
 271    s->regs[R_IR_MASK] |= val;
 272    ir_update_irq(s);
 273    return 0;
 274}
 275
 276static uint64_t rst_fpd_apu_prew(RegisterInfo *reg, uint64_t val64)
 277{
 278    CRF_APB *s = XILINX_CRF_APB(reg->opaque);
 279    uint32_t val = val64;
 280    uint32_t val_old = s->regs[R_RST_FPD_APU];
 281    unsigned int i;
 282
 283    for (i = 0; i < APU_MAX_CPU; i++) {
 284        /* Update irq's only when changed */
 285        uint32_t mask = (1 << (R_RST_FPD_APU_ACPU0_RESET_SHIFT + i));
 286        if ((val ^ val_old) & mask) {
 287            qemu_set_irq(s->acpu_rst[i], !!(val & mask));
 288        }
 289    }
 290    return val64;
 291}
 292
 293static const RegisterAccessInfo crf_apb_regs_info[] = {
 294    {   .name = "ERR_CTRL",  .addr = A_ERR_CTRL,
 295    },{ .name = "IR_STATUS",  .addr = A_IR_STATUS,
 296        .w1c = 0x1,
 297        .post_write = ir_status_postw,
 298    },{ .name = "IR_MASK",  .addr = A_IR_MASK,
 299        .reset = 0x1,
 300        .ro = 0x1,
 301    },{ .name = "IR_ENABLE",  .addr = A_IR_ENABLE,
 302        .pre_write = ir_enable_prew,
 303    },{ .name = "IR_DISABLE",  .addr = A_IR_DISABLE,
 304        .pre_write = ir_disable_prew,
 305    },{ .name = "CRF_WPROT",  .addr = A_CRF_WPROT,
 306    },{ .name = "APLL_CTRL",  .addr = A_APLL_CTRL,
 307        .reset = 0x12c09,
 308        .rsvd = 0xf88c80f6,
 309    },{ .name = "APLL_CFG",  .addr = A_APLL_CFG,
 310        .rsvd = 0x1801210,
 311    },{ .name = "APLL_FRAC_CFG",  .addr = A_APLL_FRAC_CFG,
 312        .rsvd = 0x7e330000,
 313    },{ .name = "DPLL_CTRL",  .addr = A_DPLL_CTRL,
 314        .reset = 0x2c09,
 315        .rsvd = 0xf88c80f6,
 316    },{ .name = "DPLL_CFG",  .addr = A_DPLL_CFG,
 317        .rsvd = 0x1801210,
 318    },{ .name = "DPLL_FRAC_CFG",  .addr = A_DPLL_FRAC_CFG,
 319        .rsvd = 0x7e330000,
 320    },{ .name = "VPLL_CTRL",  .addr = A_VPLL_CTRL,
 321        .reset = 0x12809,
 322        .rsvd = 0xf88c80f6,
 323    },{ .name = "VPLL_CFG",  .addr = A_VPLL_CFG,
 324        .rsvd = 0x1801210,
 325    },{ .name = "VPLL_FRAC_CFG",  .addr = A_VPLL_FRAC_CFG,
 326        .rsvd = 0x7e330000,
 327    },{ .name = "PLL_STATUS",  .addr = A_PLL_STATUS,
 328        .reset = 0x3f,
 329        .rsvd = 0xc0,
 330        .ro = 0x3f,
 331    },{ .name = "APLL_TO_LPD_CTRL",  .addr = A_APLL_TO_LPD_CTRL,
 332        .reset = 0x400,
 333        .rsvd = 0xc0ff,
 334    },{ .name = "DPLL_TO_LPD_CTRL",  .addr = A_DPLL_TO_LPD_CTRL,
 335        .reset = 0x400,
 336        .rsvd = 0xc0ff,
 337    },{ .name = "VPLL_TO_LPD_CTRL",  .addr = A_VPLL_TO_LPD_CTRL,
 338        .reset = 0x400,
 339        .rsvd = 0xc0ff,
 340    },{ .name = "ACPU_CTRL",  .addr = A_ACPU_CTRL,
 341        .reset = 0x3000400,
 342        .rsvd = 0xfcffc0f8,
 343    },{ .name = "DBG_TRACE_CTRL",  .addr = A_DBG_TRACE_CTRL,
 344        .reset = 0x2500,
 345        .rsvd = 0xfeffc0f8,
 346    },{ .name = "DBG_FPD_CTRL",  .addr = A_DBG_FPD_CTRL,
 347        .reset = 0x1002500,
 348        .rsvd = 0xfeffc0f8,
 349    },{ .name = "DP_VIDEO_REF_CTRL",  .addr = A_DP_VIDEO_REF_CTRL,
 350        .reset = 0x1002300,
 351        .rsvd = 0xfec0c0f8,
 352    },{ .name = "DP_AUDIO_REF_CTRL",  .addr = A_DP_AUDIO_REF_CTRL,
 353        .reset = 0x1032300,
 354        .rsvd = 0xfec0c0f8,
 355    },{ .name = "DP_STC_REF_CTRL",  .addr = A_DP_STC_REF_CTRL,
 356        .reset = 0x1203200,
 357        .rsvd = 0xfec0c0f8,
 358    },{ .name = "DDR_CTRL",  .addr = A_DDR_CTRL,
 359        .reset = 0x1000500,
 360        .rsvd = 0xfeffc0f8,
 361    },{ .name = "GPU_REF_CTRL",  .addr = A_GPU_REF_CTRL,
 362        .reset = 0x1500,
 363        .rsvd = 0xf8ffc0f8,
 364    },{ .name = "SATA_REF_CTRL",  .addr = A_SATA_REF_CTRL,
 365        .reset = 0x1001600,
 366        .rsvd = 0xfeffc0f8,
 367    },{ .name = "PCIE_REF_CTRL",  .addr = A_PCIE_REF_CTRL,
 368        .reset = 0x1500,
 369        .rsvd = 0xfeffc0f8,
 370    },{ .name = "GDMA_REF_CTRL",  .addr = A_GDMA_REF_CTRL,
 371        .reset = 0x1000500,
 372        .rsvd = 0xfeffc0f8,
 373    },{ .name = "DPDMA_REF_CTRL",  .addr = A_DPDMA_REF_CTRL,
 374        .reset = 0x1000500,
 375        .rsvd = 0xfeffc0f8,
 376    },{ .name = "TOPSW_MAIN_CTRL",  .addr = A_TOPSW_MAIN_CTRL,
 377        .reset = 0x1000400,
 378        .rsvd = 0xfeffc0f8,
 379    },{ .name = "TOPSW_LSBUS_CTRL",  .addr = A_TOPSW_LSBUS_CTRL,
 380        .reset = 0x1000800,
 381        .rsvd = 0xfeffc0f8,
 382    },{ .name = "DBG_TSTMP_CTRL",  .addr = A_DBG_TSTMP_CTRL,
 383        .reset = 0xa00,
 384        .rsvd = 0xffffc0f8,
 385    },
 386    {   .name = "RST_FPD_TOP",  .addr = A_RST_FPD_TOP,
 387        .reset = 0xf9ffe,
 388        .rsvd = 0xf06001,
 389    },{ .name = "RST_FPD_APU",  .addr = A_RST_FPD_APU,
 390        .reset = 0x3d0f,
 391        .rsvd = 0xc2f0,
 392        .pre_write = rst_fpd_apu_prew,
 393    },{ .name = "RST_DDR_SS",  .addr = A_RST_DDR_SS,
 394        .reset = 0xf,
 395        .rsvd = 0xf3,
 396    }
 397};
 398
 399static void crf_apb_reset(DeviceState *dev)
 400{
 401    CRF_APB *s = XILINX_CRF_APB(dev);
 402    unsigned int i;
 403
 404    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
 405        register_reset(&s->regs_info[i]);
 406    }
 407
 408    if (!s->linux_direct_boot) {
 409        /*
 410         * Set A53's in reset
 411         */
 412        for (i = 0; i < APU_MAX_CPU; i++) {
 413            qemu_set_irq(s->acpu_rst[i], 1);
 414        }
 415    }
 416
 417    ir_update_irq(s);
 418}
 419
 420static void crf_linux_boot_if_init(ARMLinuxBootIf *obj, bool secure_boot)
 421{
 422    CRF_APB *s = XILINX_CRF_APB(obj);
 423
 424    s->linux_direct_boot = true;
 425}
 426
 427
 428static const MemoryRegionOps crf_apb_ops = {
 429    .read = register_read_memory,
 430    .write = register_write_memory,
 431    .endianness = DEVICE_LITTLE_ENDIAN,
 432    .valid = {
 433        .min_access_size = 4,
 434        .max_access_size = 4,
 435    },
 436};
 437
 438static void crf_apb_realize(DeviceState *dev, Error **errp)
 439{
 440    CRF_APB *s = XILINX_CRF_APB(dev);
 441
 442    qdev_init_gpio_out_named(dev, s->acpu_rst, "RST_A9", APU_MAX_CPU);
 443}
 444
 445static void crf_apb_init(Object *obj)
 446{
 447    CRF_APB *s = XILINX_CRF_APB(obj);
 448    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 449    RegisterInfoArray *reg_array;
 450
 451    memory_region_init(&s->iomem, obj, TYPE_XILINX_CRF_APB, R_MAX * 4);
 452    reg_array =
 453        register_init_block32(DEVICE(obj), crf_apb_regs_info,
 454                              ARRAY_SIZE(crf_apb_regs_info),
 455                              s->regs_info, s->regs,
 456                              &crf_apb_ops,
 457                              XILINX_CRF_APB_ERR_DEBUG,
 458                              R_MAX * 4);
 459    memory_region_add_subregion(&s->iomem,
 460                                0x0,
 461                                &reg_array->mem);
 462    sysbus_init_mmio(sbd, &s->iomem);
 463    sysbus_init_irq(sbd, &s->irq_ir);
 464}
 465
 466static const VMStateDescription vmstate_crf_apb = {
 467    .name = TYPE_XILINX_CRF_APB,
 468    .version_id = 1,
 469    .minimum_version_id = 1,
 470    .minimum_version_id_old = 1,
 471    .fields = (VMStateField[]) {
 472        VMSTATE_UINT32_ARRAY(regs, CRF_APB, R_MAX),
 473        VMSTATE_END_OF_LIST(),
 474    }
 475};
 476
 477static const FDTGenericGPIOSet crf_gpios[] = {
 478    {
 479        .names = &fdt_generic_gpio_name_set_gpio,
 480        .gpios = (FDTGenericGPIOConnection[]) {
 481            { .name = "RST_A9",   .fdt_index = 0,   .range = 4 },
 482            { },
 483        }
 484    },
 485    { },
 486};
 487
 488static void crf_apb_class_init(ObjectClass *klass, void *data)
 489{
 490    DeviceClass *dc = DEVICE_CLASS(klass);
 491    FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
 492    ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_CLASS(klass);
 493
 494    dc->reset = crf_apb_reset;
 495    dc->realize = crf_apb_realize;
 496    dc->vmsd = &vmstate_crf_apb;
 497    fggc->controller_gpios = crf_gpios;
 498    albifc->arm_linux_init = crf_linux_boot_if_init;
 499}
 500
 501static const TypeInfo crf_apb_info = {
 502    .name          = TYPE_XILINX_CRF_APB,
 503    .parent        = TYPE_SYS_BUS_DEVICE,
 504    .instance_size = sizeof(CRF_APB),
 505    .class_init    = crf_apb_class_init,
 506    .instance_init = crf_apb_init,
 507    .interfaces    = (InterfaceInfo[]) {
 508        { TYPE_FDT_GENERIC_GPIO },
 509        { TYPE_ARM_LINUX_BOOT_IF },
 510        { }
 511    },
 512};
 513
 514static void crf_apb_register_types(void)
 515{
 516    type_register_static(&crf_apb_info);
 517}
 518
 519type_init(crf_apb_register_types)
 520