qemu/hw/misc/zynq_slcr.c
<<
>>
Prefs
   1/*
   2 * Status and system control registers for Xilinx Zynq Platform
   3 *
   4 * Copyright (c) 2011 Michal Simek <monstr@monstr.eu>
   5 * Copyright (c) 2012 PetaLogix Pty Ltd.
   6 * Based on hw/arm_sysctl.c, written by Paul Brook
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License
  10 * as published by the Free Software Foundation; either version
  11 * 2 of the License, or (at your option) any later version.
  12 *
  13 * You should have received a copy of the GNU General Public License along
  14 * with this program; if not, see <http://www.gnu.org/licenses/>.
  15 */
  16
  17#include "qemu/osdep.h"
  18#include "hw/hw.h"
  19#include "qemu/timer.h"
  20#include "hw/sysbus.h"
  21#include "sysemu/sysemu.h"
  22#include "qemu/log.h"
  23
  24#ifndef ZYNQ_SLCR_ERR_DEBUG
  25#define ZYNQ_SLCR_ERR_DEBUG 0
  26#endif
  27
  28#define DB_PRINT(...) do { \
  29        if (ZYNQ_SLCR_ERR_DEBUG) { \
  30            fprintf(stderr,  ": %s: ", __func__); \
  31            fprintf(stderr, ## __VA_ARGS__); \
  32        } \
  33    } while (0)
  34
  35#define XILINX_LOCK_KEY 0x767b
  36#define XILINX_UNLOCK_KEY 0xdf0d
  37
  38#define R_PSS_RST_CTRL_SOFT_RST 0x1
  39
  40enum {
  41    SCL             = 0x000 / 4,
  42    LOCK,
  43    UNLOCK,
  44    LOCKSTA,
  45
  46    ARM_PLL_CTRL    = 0x100 / 4,
  47    DDR_PLL_CTRL,
  48    IO_PLL_CTRL,
  49    PLL_STATUS,
  50    ARM_PLL_CFG,
  51    DDR_PLL_CFG,
  52    IO_PLL_CFG,
  53
  54    ARM_CLK_CTRL    = 0x120 / 4,
  55    DDR_CLK_CTRL,
  56    DCI_CLK_CTRL,
  57    APER_CLK_CTRL,
  58    USB0_CLK_CTRL,
  59    USB1_CLK_CTRL,
  60    GEM0_RCLK_CTRL,
  61    GEM1_RCLK_CTRL,
  62    GEM0_CLK_CTRL,
  63    GEM1_CLK_CTRL,
  64    SMC_CLK_CTRL,
  65    LQSPI_CLK_CTRL,
  66    SDIO_CLK_CTRL,
  67    UART_CLK_CTRL,
  68    SPI_CLK_CTRL,
  69    CAN_CLK_CTRL,
  70    CAN_MIOCLK_CTRL,
  71    DBG_CLK_CTRL,
  72    PCAP_CLK_CTRL,
  73    TOPSW_CLK_CTRL,
  74
  75#define FPGA_CTRL_REGS(n, start) \
  76    FPGA ## n ## _CLK_CTRL = (start) / 4, \
  77    FPGA ## n ## _THR_CTRL, \
  78    FPGA ## n ## _THR_CNT, \
  79    FPGA ## n ## _THR_STA,
  80    FPGA_CTRL_REGS(0, 0x170)
  81    FPGA_CTRL_REGS(1, 0x180)
  82    FPGA_CTRL_REGS(2, 0x190)
  83    FPGA_CTRL_REGS(3, 0x1a0)
  84
  85    BANDGAP_TRIP    = 0x1b8 / 4,
  86    PLL_PREDIVISOR  = 0x1c0 / 4,
  87    CLK_621_TRUE,
  88
  89    PSS_RST_CTRL    = 0x200 / 4,
  90    DDR_RST_CTRL,
  91    TOPSW_RESET_CTRL,
  92    DMAC_RST_CTRL,
  93    USB_RST_CTRL,
  94    GEM_RST_CTRL,
  95    SDIO_RST_CTRL,
  96    SPI_RST_CTRL,
  97    CAN_RST_CTRL,
  98    I2C_RST_CTRL,
  99    UART_RST_CTRL,
 100    GPIO_RST_CTRL,
 101    LQSPI_RST_CTRL,
 102    SMC_RST_CTRL,
 103    OCM_RST_CTRL,
 104    FPGA_RST_CTRL   = 0x240 / 4,
 105    A9_CPU_RST_CTRL,
 106
 107    RS_AWDT_CTRL    = 0x24c / 4,
 108    RST_REASON,
 109
 110    REBOOT_STATUS   = 0x258 / 4,
 111    BOOT_MODE,
 112
 113    APU_CTRL        = 0x300 / 4,
 114    WDT_CLK_SEL,
 115
 116    TZ_DMA_NS       = 0x440 / 4,
 117    TZ_DMA_IRQ_NS,
 118    TZ_DMA_PERIPH_NS,
 119
 120    PSS_IDCODE      = 0x530 / 4,
 121
 122    DDR_URGENT      = 0x600 / 4,
 123    DDR_CAL_START   = 0x60c / 4,
 124    DDR_REF_START   = 0x614 / 4,
 125    DDR_CMD_STA,
 126    DDR_URGENT_SEL,
 127    DDR_DFI_STATUS,
 128
 129    MIO             = 0x700 / 4,
 130#define MIO_LENGTH 54
 131
 132    MIO_LOOPBACK    = 0x804 / 4,
 133    MIO_MST_TRI0,
 134    MIO_MST_TRI1,
 135
 136    SD0_WP_CD_SEL   = 0x830 / 4,
 137    SD1_WP_CD_SEL,
 138
 139    LVL_SHFTR_EN    = 0x900 / 4,
 140    OCM_CFG         = 0x910 / 4,
 141
 142    CPU_RAM         = 0xa00 / 4,
 143
 144    IOU             = 0xa30 / 4,
 145
 146    DMAC_RAM        = 0xa50 / 4,
 147
 148    AFI0            = 0xa60 / 4,
 149    AFI1 = AFI0 + 3,
 150    AFI2 = AFI1 + 3,
 151    AFI3 = AFI2 + 3,
 152#define AFI_LENGTH 3
 153
 154    OCM             = 0xa90 / 4,
 155
 156    DEVCI_RAM       = 0xaa0 / 4,
 157
 158    CSG_RAM         = 0xab0 / 4,
 159
 160    GPIOB_CTRL      = 0xb00 / 4,
 161    GPIOB_CFG_CMOS18,
 162    GPIOB_CFG_CMOS25,
 163    GPIOB_CFG_CMOS33,
 164    GPIOB_CFG_HSTL  = 0xb14 / 4,
 165    GPIOB_DRVR_BIAS_CTRL,
 166
 167    DDRIOB          = 0xb40 / 4,
 168#define DDRIOB_LENGTH 14
 169};
 170
 171#define ZYNQ_SLCR_MMIO_SIZE     0x1000
 172#define ZYNQ_SLCR_NUM_REGS      (ZYNQ_SLCR_MMIO_SIZE / 4)
 173
 174#define TYPE_ZYNQ_SLCR "xilinx,zynq_slcr"
 175#define ZYNQ_SLCR(obj) OBJECT_CHECK(ZynqSLCRState, (obj), TYPE_ZYNQ_SLCR)
 176
 177typedef struct ZynqSLCRState {
 178    SysBusDevice parent_obj;
 179
 180    MemoryRegion iomem;
 181
 182    uint32_t regs[ZYNQ_SLCR_NUM_REGS];
 183} ZynqSLCRState;
 184
 185static void zynq_slcr_reset(DeviceState *d)
 186{
 187    ZynqSLCRState *s = ZYNQ_SLCR(d);
 188    int i;
 189
 190    DB_PRINT("RESET\n");
 191
 192    s->regs[LOCKSTA] = 1;
 193    /* 0x100 - 0x11C */
 194    s->regs[ARM_PLL_CTRL]   = 0x0001A008;
 195    s->regs[DDR_PLL_CTRL]   = 0x0001A008;
 196    s->regs[IO_PLL_CTRL]    = 0x0001A008;
 197    s->regs[PLL_STATUS]     = 0x0000003F;
 198    s->regs[ARM_PLL_CFG]    = 0x00014000;
 199    s->regs[DDR_PLL_CFG]    = 0x00014000;
 200    s->regs[IO_PLL_CFG]     = 0x00014000;
 201
 202    /* 0x120 - 0x16C */
 203    s->regs[ARM_CLK_CTRL]   = 0x1F000400;
 204    s->regs[DDR_CLK_CTRL]   = 0x18400003;
 205    s->regs[DCI_CLK_CTRL]   = 0x01E03201;
 206    s->regs[APER_CLK_CTRL]  = 0x01FFCCCD;
 207    s->regs[USB0_CLK_CTRL]  = s->regs[USB1_CLK_CTRL]    = 0x00101941;
 208    s->regs[GEM0_RCLK_CTRL] = s->regs[GEM1_RCLK_CTRL]   = 0x00000001;
 209    s->regs[GEM0_CLK_CTRL]  = s->regs[GEM1_CLK_CTRL]    = 0x00003C01;
 210    s->regs[SMC_CLK_CTRL]   = 0x00003C01;
 211    s->regs[LQSPI_CLK_CTRL] = 0x00002821;
 212    s->regs[SDIO_CLK_CTRL]  = 0x00001E03;
 213    s->regs[UART_CLK_CTRL]  = 0x00003F03;
 214    s->regs[SPI_CLK_CTRL]   = 0x00003F03;
 215    s->regs[CAN_CLK_CTRL]   = 0x00501903;
 216    s->regs[DBG_CLK_CTRL]   = 0x00000F03;
 217    s->regs[PCAP_CLK_CTRL]  = 0x00000F01;
 218
 219    /* 0x170 - 0x1AC */
 220    s->regs[FPGA0_CLK_CTRL] = s->regs[FPGA1_CLK_CTRL] = s->regs[FPGA2_CLK_CTRL]
 221                            = s->regs[FPGA3_CLK_CTRL] = 0x00101800;
 222    s->regs[FPGA0_THR_STA] = s->regs[FPGA1_THR_STA] = s->regs[FPGA2_THR_STA]
 223                           = s->regs[FPGA3_THR_STA] = 0x00010000;
 224
 225    /* 0x1B0 - 0x1D8 */
 226    s->regs[BANDGAP_TRIP]   = 0x0000001F;
 227    s->regs[PLL_PREDIVISOR] = 0x00000001;
 228    s->regs[CLK_621_TRUE]   = 0x00000001;
 229
 230    /* 0x200 - 0x25C */
 231    s->regs[FPGA_RST_CTRL]  = 0x01F33F0F;
 232    s->regs[RST_REASON]     = 0x00000040;
 233
 234    s->regs[BOOT_MODE]      = 0x00000001;
 235
 236    /* 0x700 - 0x7D4 */
 237    for (i = 0; i < 54; i++) {
 238        s->regs[MIO + i] = 0x00001601;
 239    }
 240    for (i = 2; i <= 8; i++) {
 241        s->regs[MIO + i] = 0x00000601;
 242    }
 243
 244    s->regs[MIO_MST_TRI0] = s->regs[MIO_MST_TRI1] = 0xFFFFFFFF;
 245
 246    s->regs[CPU_RAM + 0] = s->regs[CPU_RAM + 1] = s->regs[CPU_RAM + 3]
 247                         = s->regs[CPU_RAM + 4] = s->regs[CPU_RAM + 7]
 248                         = 0x00010101;
 249    s->regs[CPU_RAM + 2] = s->regs[CPU_RAM + 5] = 0x01010101;
 250    s->regs[CPU_RAM + 6] = 0x00000001;
 251
 252    s->regs[IOU + 0] = s->regs[IOU + 1] = s->regs[IOU + 2] = s->regs[IOU + 3]
 253                     = 0x09090909;
 254    s->regs[IOU + 4] = s->regs[IOU + 5] = 0x00090909;
 255    s->regs[IOU + 6] = 0x00000909;
 256
 257    s->regs[DMAC_RAM] = 0x00000009;
 258
 259    s->regs[AFI0 + 0] = s->regs[AFI0 + 1] = 0x09090909;
 260    s->regs[AFI1 + 0] = s->regs[AFI1 + 1] = 0x09090909;
 261    s->regs[AFI2 + 0] = s->regs[AFI2 + 1] = 0x09090909;
 262    s->regs[AFI3 + 0] = s->regs[AFI3 + 1] = 0x09090909;
 263    s->regs[AFI0 + 2] = s->regs[AFI1 + 2] = s->regs[AFI2 + 2]
 264                      = s->regs[AFI3 + 2] = 0x00000909;
 265
 266    s->regs[OCM + 0]    = 0x01010101;
 267    s->regs[OCM + 1]    = s->regs[OCM + 2] = 0x09090909;
 268
 269    s->regs[DEVCI_RAM]  = 0x00000909;
 270    s->regs[CSG_RAM]    = 0x00000001;
 271
 272    s->regs[DDRIOB + 0] = s->regs[DDRIOB + 1] = s->regs[DDRIOB + 2]
 273                        = s->regs[DDRIOB + 3] = 0x00000e00;
 274    s->regs[DDRIOB + 4] = s->regs[DDRIOB + 5] = s->regs[DDRIOB + 6]
 275                        = 0x00000e00;
 276    s->regs[DDRIOB + 12] = 0x00000021;
 277}
 278
 279
 280static bool zynq_slcr_check_offset(hwaddr offset, bool rnw)
 281{
 282    switch (offset) {
 283    case LOCK:
 284    case UNLOCK:
 285    case DDR_CAL_START:
 286    case DDR_REF_START:
 287        return !rnw; /* Write only */
 288    case LOCKSTA:
 289    case FPGA0_THR_STA:
 290    case FPGA1_THR_STA:
 291    case FPGA2_THR_STA:
 292    case FPGA3_THR_STA:
 293    case BOOT_MODE:
 294    case PSS_IDCODE:
 295    case DDR_CMD_STA:
 296    case DDR_DFI_STATUS:
 297    case PLL_STATUS:
 298        return rnw;/* read only */
 299    case SCL:
 300    case ARM_PLL_CTRL ... IO_PLL_CTRL:
 301    case ARM_PLL_CFG ... IO_PLL_CFG:
 302    case ARM_CLK_CTRL ... TOPSW_CLK_CTRL:
 303    case FPGA0_CLK_CTRL ... FPGA0_THR_CNT:
 304    case FPGA1_CLK_CTRL ... FPGA1_THR_CNT:
 305    case FPGA2_CLK_CTRL ... FPGA2_THR_CNT:
 306    case FPGA3_CLK_CTRL ... FPGA3_THR_CNT:
 307    case BANDGAP_TRIP:
 308    case PLL_PREDIVISOR:
 309    case CLK_621_TRUE:
 310    case PSS_RST_CTRL ... A9_CPU_RST_CTRL:
 311    case RS_AWDT_CTRL:
 312    case RST_REASON:
 313    case REBOOT_STATUS:
 314    case APU_CTRL:
 315    case WDT_CLK_SEL:
 316    case TZ_DMA_NS ... TZ_DMA_PERIPH_NS:
 317    case DDR_URGENT:
 318    case DDR_URGENT_SEL:
 319    case MIO ... MIO + MIO_LENGTH - 1:
 320    case MIO_LOOPBACK ... MIO_MST_TRI1:
 321    case SD0_WP_CD_SEL:
 322    case SD1_WP_CD_SEL:
 323    case LVL_SHFTR_EN:
 324    case OCM_CFG:
 325    case CPU_RAM:
 326    case IOU:
 327    case DMAC_RAM:
 328    case AFI0 ... AFI3 + AFI_LENGTH - 1:
 329    case OCM:
 330    case DEVCI_RAM:
 331    case CSG_RAM:
 332    case GPIOB_CTRL ... GPIOB_CFG_CMOS33:
 333    case GPIOB_CFG_HSTL:
 334    case GPIOB_DRVR_BIAS_CTRL:
 335    case DDRIOB ... DDRIOB + DDRIOB_LENGTH - 1:
 336        return true;
 337    default:
 338        return false;
 339    }
 340}
 341
 342static uint64_t zynq_slcr_read(void *opaque, hwaddr offset,
 343    unsigned size)
 344{
 345    ZynqSLCRState *s = opaque;
 346    offset /= 4;
 347    uint32_t ret = s->regs[offset];
 348
 349    if (!zynq_slcr_check_offset(offset, true)) {
 350        qemu_log_mask(LOG_GUEST_ERROR, "zynq_slcr: Invalid read access to "
 351                      " addr %" HWADDR_PRIx "\n", offset * 4);
 352    }
 353
 354    DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n", offset * 4, ret);
 355    return ret;
 356}
 357
 358static void zynq_slcr_write(void *opaque, hwaddr offset,
 359                          uint64_t val, unsigned size)
 360{
 361    ZynqSLCRState *s = (ZynqSLCRState *)opaque;
 362    offset /= 4;
 363
 364    DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx64 "\n", offset * 4, val);
 365
 366    if (!zynq_slcr_check_offset(offset, false)) {
 367        qemu_log_mask(LOG_GUEST_ERROR, "zynq_slcr: Invalid write access to "
 368                      "addr %" HWADDR_PRIx "\n", offset * 4);
 369        return;
 370    }
 371
 372    switch (offset) {
 373    case SCL:
 374        s->regs[SCL] = val & 0x1;
 375        return;
 376    case LOCK:
 377        if ((val & 0xFFFF) == XILINX_LOCK_KEY) {
 378            DB_PRINT("XILINX LOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
 379                (unsigned)val & 0xFFFF);
 380            s->regs[LOCKSTA] = 1;
 381        } else {
 382            DB_PRINT("WRONG XILINX LOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
 383                (int)offset, (unsigned)val & 0xFFFF);
 384        }
 385        return;
 386    case UNLOCK:
 387        if ((val & 0xFFFF) == XILINX_UNLOCK_KEY) {
 388            DB_PRINT("XILINX UNLOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
 389                (unsigned)val & 0xFFFF);
 390            s->regs[LOCKSTA] = 0;
 391        } else {
 392            DB_PRINT("WRONG XILINX UNLOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
 393                (int)offset, (unsigned)val & 0xFFFF);
 394        }
 395        return;
 396    }
 397
 398    if (s->regs[LOCKSTA]) {
 399        qemu_log_mask(LOG_GUEST_ERROR,
 400                      "SCLR registers are locked. Unlock them first\n");
 401        return;
 402    }
 403    s->regs[offset] = val;
 404
 405    switch (offset) {
 406    case PSS_RST_CTRL:
 407        if (val & R_PSS_RST_CTRL_SOFT_RST) {
 408            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 409        }
 410        break;
 411    }
 412}
 413
 414static const MemoryRegionOps slcr_ops = {
 415    .read = zynq_slcr_read,
 416    .write = zynq_slcr_write,
 417    .endianness = DEVICE_NATIVE_ENDIAN,
 418};
 419
 420static void zynq_slcr_init(Object *obj)
 421{
 422    ZynqSLCRState *s = ZYNQ_SLCR(obj);
 423
 424    memory_region_init_io(&s->iomem, obj, &slcr_ops, s, "slcr",
 425                          ZYNQ_SLCR_MMIO_SIZE);
 426    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
 427}
 428
 429static const VMStateDescription vmstate_zynq_slcr = {
 430    .name = "zynq_slcr",
 431    .version_id = 2,
 432    .minimum_version_id = 2,
 433    .fields = (VMStateField[]) {
 434        VMSTATE_UINT32_ARRAY(regs, ZynqSLCRState, ZYNQ_SLCR_NUM_REGS),
 435        VMSTATE_END_OF_LIST()
 436    }
 437};
 438
 439static void zynq_slcr_class_init(ObjectClass *klass, void *data)
 440{
 441    DeviceClass *dc = DEVICE_CLASS(klass);
 442
 443    dc->vmsd = &vmstate_zynq_slcr;
 444    dc->reset = zynq_slcr_reset;
 445}
 446
 447static const TypeInfo zynq_slcr_info = {
 448    .class_init = zynq_slcr_class_init,
 449    .name  = TYPE_ZYNQ_SLCR,
 450    .parent = TYPE_SYS_BUS_DEVICE,
 451    .instance_size  = sizeof(ZynqSLCRState),
 452    .instance_init = zynq_slcr_init,
 453};
 454
 455static void zynq_slcr_register_types(void)
 456{
 457    type_register_static(&zynq_slcr_info);
 458}
 459
 460type_init(zynq_slcr_register_types)
 461