1e3260506SPeter A. G. Crosthwaite /* 2e3260506SPeter A. G. Crosthwaite * Status and system control registers for Xilinx Zynq Platform 3e3260506SPeter A. G. Crosthwaite * 4e3260506SPeter A. G. Crosthwaite * Copyright (c) 2011 Michal Simek <monstr@monstr.eu> 5e3260506SPeter A. G. Crosthwaite * Copyright (c) 2012 PetaLogix Pty Ltd. 6e3260506SPeter A. G. Crosthwaite * Based on hw/arm_sysctl.c, written by Paul Brook 7e3260506SPeter A. G. Crosthwaite * 8e3260506SPeter A. G. Crosthwaite * This program is free software; you can redistribute it and/or 9e3260506SPeter A. G. Crosthwaite * modify it under the terms of the GNU General Public License 10e3260506SPeter A. G. Crosthwaite * as published by the Free Software Foundation; either version 11e3260506SPeter A. G. Crosthwaite * 2 of the License, or (at your option) any later version. 12e3260506SPeter A. G. Crosthwaite * 13e3260506SPeter A. G. Crosthwaite * You should have received a copy of the GNU General Public License along 14e3260506SPeter A. G. Crosthwaite * with this program; if not, see <http://www.gnu.org/licenses/>. 15e3260506SPeter A. G. Crosthwaite */ 16e3260506SPeter A. G. Crosthwaite 1783c9f4caSPaolo Bonzini #include "hw/hw.h" 181de7afc9SPaolo Bonzini #include "qemu/timer.h" 1983c9f4caSPaolo Bonzini #include "hw/sysbus.h" 209c17d615SPaolo Bonzini #include "sysemu/sysemu.h" 21e3260506SPeter A. G. Crosthwaite 22e3260506SPeter A. G. Crosthwaite #ifdef ZYNQ_ARM_SLCR_ERR_DEBUG 23e3260506SPeter A. G. Crosthwaite #define DB_PRINT(...) do { \ 24e3260506SPeter A. G. Crosthwaite fprintf(stderr, ": %s: ", __func__); \ 25e3260506SPeter A. G. Crosthwaite fprintf(stderr, ## __VA_ARGS__); \ 26e3260506SPeter A. G. Crosthwaite } while (0); 27e3260506SPeter A. G. Crosthwaite #else 28e3260506SPeter A. G. Crosthwaite #define DB_PRINT(...) 29e3260506SPeter A. G. Crosthwaite #endif 30e3260506SPeter A. G. Crosthwaite 31e3260506SPeter A. G. Crosthwaite #define XILINX_LOCK_KEY 0x767b 32e3260506SPeter A. G. Crosthwaite #define XILINX_UNLOCK_KEY 0xdf0d 33e3260506SPeter A. G. Crosthwaite 34*69991d7dSSebastian Huber #define R_PSS_RST_CTRL_SOFT_RST 0x1 35*69991d7dSSebastian Huber 36e3260506SPeter A. G. Crosthwaite typedef enum { 37e3260506SPeter A. G. Crosthwaite ARM_PLL_CTRL, 38e3260506SPeter A. G. Crosthwaite DDR_PLL_CTRL, 39e3260506SPeter A. G. Crosthwaite IO_PLL_CTRL, 40e3260506SPeter A. G. Crosthwaite PLL_STATUS, 41e3260506SPeter A. G. Crosthwaite ARM_PPL_CFG, 42e3260506SPeter A. G. Crosthwaite DDR_PLL_CFG, 43e3260506SPeter A. G. Crosthwaite IO_PLL_CFG, 44e3260506SPeter A. G. Crosthwaite PLL_BG_CTRL, 45e3260506SPeter A. G. Crosthwaite PLL_MAX 46e3260506SPeter A. G. Crosthwaite } PLLValues; 47e3260506SPeter A. G. Crosthwaite 48e3260506SPeter A. G. Crosthwaite typedef enum { 49e3260506SPeter A. G. Crosthwaite ARM_CLK_CTRL, 50e3260506SPeter A. G. Crosthwaite DDR_CLK_CTRL, 51e3260506SPeter A. G. Crosthwaite DCI_CLK_CTRL, 52e3260506SPeter A. G. Crosthwaite APER_CLK_CTRL, 53e3260506SPeter A. G. Crosthwaite USB0_CLK_CTRL, 54e3260506SPeter A. G. Crosthwaite USB1_CLK_CTRL, 55e3260506SPeter A. G. Crosthwaite GEM0_RCLK_CTRL, 56e3260506SPeter A. G. Crosthwaite GEM1_RCLK_CTRL, 57e3260506SPeter A. G. Crosthwaite GEM0_CLK_CTRL, 58e3260506SPeter A. G. Crosthwaite GEM1_CLK_CTRL, 59e3260506SPeter A. G. Crosthwaite SMC_CLK_CTRL, 60e3260506SPeter A. G. Crosthwaite LQSPI_CLK_CTRL, 61e3260506SPeter A. G. Crosthwaite SDIO_CLK_CTRL, 62e3260506SPeter A. G. Crosthwaite UART_CLK_CTRL, 63e3260506SPeter A. G. Crosthwaite SPI_CLK_CTRL, 64e3260506SPeter A. G. Crosthwaite CAN_CLK_CTRL, 65e3260506SPeter A. G. Crosthwaite CAN_MIOCLK_CTRL, 66e3260506SPeter A. G. Crosthwaite DBG_CLK_CTRL, 67e3260506SPeter A. G. Crosthwaite PCAP_CLK_CTRL, 68e3260506SPeter A. G. Crosthwaite TOPSW_CLK_CTRL, 69e3260506SPeter A. G. Crosthwaite CLK_MAX 70e3260506SPeter A. G. Crosthwaite } ClkValues; 71e3260506SPeter A. G. Crosthwaite 72e3260506SPeter A. G. Crosthwaite typedef enum { 73e3260506SPeter A. G. Crosthwaite CLK_CTRL, 74e3260506SPeter A. G. Crosthwaite THR_CTRL, 75e3260506SPeter A. G. Crosthwaite THR_CNT, 76e3260506SPeter A. G. Crosthwaite THR_STA, 77e3260506SPeter A. G. Crosthwaite FPGA_MAX 78e3260506SPeter A. G. Crosthwaite } FPGAValues; 79e3260506SPeter A. G. Crosthwaite 80e3260506SPeter A. G. Crosthwaite typedef enum { 81e3260506SPeter A. G. Crosthwaite SYNC_CTRL, 82e3260506SPeter A. G. Crosthwaite SYNC_STATUS, 83e3260506SPeter A. G. Crosthwaite BANDGAP_TRIP, 84e3260506SPeter A. G. Crosthwaite CC_TEST, 85e3260506SPeter A. G. Crosthwaite PLL_PREDIVISOR, 86e3260506SPeter A. G. Crosthwaite CLK_621_TRUE, 87e3260506SPeter A. G. Crosthwaite PICTURE_DBG, 88e3260506SPeter A. G. Crosthwaite PICTURE_DBG_UCNT, 89e3260506SPeter A. G. Crosthwaite PICTURE_DBG_LCNT, 90e3260506SPeter A. G. Crosthwaite MISC_MAX 91e3260506SPeter A. G. Crosthwaite } MiscValues; 92e3260506SPeter A. G. Crosthwaite 93e3260506SPeter A. G. Crosthwaite typedef enum { 94e3260506SPeter A. G. Crosthwaite PSS, 95e3260506SPeter A. G. Crosthwaite DDDR, 96fa2ddcb4SPeter A. G. Crosthwaite DMAC = 3, 97e3260506SPeter A. G. Crosthwaite USB, 98e3260506SPeter A. G. Crosthwaite GEM, 99e3260506SPeter A. G. Crosthwaite SDIO, 100e3260506SPeter A. G. Crosthwaite SPI, 101e3260506SPeter A. G. Crosthwaite CAN, 102e3260506SPeter A. G. Crosthwaite I2C, 103e3260506SPeter A. G. Crosthwaite UART, 104e3260506SPeter A. G. Crosthwaite GPIO, 105e3260506SPeter A. G. Crosthwaite LQSPI, 106e3260506SPeter A. G. Crosthwaite SMC, 107e3260506SPeter A. G. Crosthwaite OCM, 108e3260506SPeter A. G. Crosthwaite DEVCI, 109e3260506SPeter A. G. Crosthwaite FPGA, 110e3260506SPeter A. G. Crosthwaite A9_CPU, 111e3260506SPeter A. G. Crosthwaite RS_AWDT, 112e3260506SPeter A. G. Crosthwaite RST_REASON, 113e3260506SPeter A. G. Crosthwaite RST_REASON_CLR, 114e3260506SPeter A. G. Crosthwaite REBOOT_STATUS, 115e3260506SPeter A. G. Crosthwaite BOOT_MODE, 116e3260506SPeter A. G. Crosthwaite RESET_MAX 117e3260506SPeter A. G. Crosthwaite } ResetValues; 118e3260506SPeter A. G. Crosthwaite 119a054e2c2SAndreas Färber #define TYPE_ZYNQ_SLCR "xilinx,zynq_slcr" 120a054e2c2SAndreas Färber #define ZYNQ_SLCR(obj) OBJECT_CHECK(ZynqSLCRState, (obj), TYPE_ZYNQ_SLCR) 121a054e2c2SAndreas Färber 122a054e2c2SAndreas Färber typedef struct ZynqSLCRState { 123a054e2c2SAndreas Färber SysBusDevice parent_obj; 124a054e2c2SAndreas Färber 125e3260506SPeter A. G. Crosthwaite MemoryRegion iomem; 126e3260506SPeter A. G. Crosthwaite 127e3260506SPeter A. G. Crosthwaite union { 128e3260506SPeter A. G. Crosthwaite struct { 129e3260506SPeter A. G. Crosthwaite uint16_t scl; 130e3260506SPeter A. G. Crosthwaite uint16_t lockval; 131e3260506SPeter A. G. Crosthwaite uint32_t pll[PLL_MAX]; /* 0x100 - 0x11C */ 132e3260506SPeter A. G. Crosthwaite uint32_t clk[CLK_MAX]; /* 0x120 - 0x16C */ 133e3260506SPeter A. G. Crosthwaite uint32_t fpga[4][FPGA_MAX]; /* 0x170 - 0x1AC */ 134e3260506SPeter A. G. Crosthwaite uint32_t misc[MISC_MAX]; /* 0x1B0 - 0x1D8 */ 135e3260506SPeter A. G. Crosthwaite uint32_t reset[RESET_MAX]; /* 0x200 - 0x25C */ 136e3260506SPeter A. G. Crosthwaite uint32_t apu_ctrl; /* 0x300 */ 137e3260506SPeter A. G. Crosthwaite uint32_t wdt_clk_sel; /* 0x304 */ 138e3260506SPeter A. G. Crosthwaite uint32_t tz_ocm[3]; /* 0x400 - 0x408 */ 139e3260506SPeter A. G. Crosthwaite uint32_t tz_ddr; /* 0x430 */ 140e3260506SPeter A. G. Crosthwaite uint32_t tz_dma[3]; /* 0x440 - 0x448 */ 141e3260506SPeter A. G. Crosthwaite uint32_t tz_misc[3]; /* 0x450 - 0x458 */ 142e3260506SPeter A. G. Crosthwaite uint32_t tz_fpga[2]; /* 0x484 - 0x488 */ 143e3260506SPeter A. G. Crosthwaite uint32_t dbg_ctrl; /* 0x500 */ 144e3260506SPeter A. G. Crosthwaite uint32_t pss_idcode; /* 0x530 */ 145e3260506SPeter A. G. Crosthwaite uint32_t ddr[8]; /* 0x600 - 0x620 - 0x604-missing */ 146e3260506SPeter A. G. Crosthwaite uint32_t mio[54]; /* 0x700 - 0x7D4 */ 147e3260506SPeter A. G. Crosthwaite uint32_t mio_func[4]; /* 0x800 - 0x810 */ 148e3260506SPeter A. G. Crosthwaite uint32_t sd[2]; /* 0x830 - 0x834 */ 149e3260506SPeter A. G. Crosthwaite uint32_t lvl_shftr_en; /* 0x900 */ 150e3260506SPeter A. G. Crosthwaite uint32_t ocm_cfg; /* 0x910 */ 151e3260506SPeter A. G. Crosthwaite uint32_t cpu_ram[8]; /* 0xA00 - 0xA1C */ 152e3260506SPeter A. G. Crosthwaite uint32_t iou[7]; /* 0xA30 - 0xA48 */ 153e3260506SPeter A. G. Crosthwaite uint32_t dmac_ram; /* 0xA50 */ 154e3260506SPeter A. G. Crosthwaite uint32_t afi[4][3]; /* 0xA60 - 0xA8C */ 155e3260506SPeter A. G. Crosthwaite uint32_t ocm[3]; /* 0xA90 - 0xA98 */ 156e3260506SPeter A. G. Crosthwaite uint32_t devci_ram; /* 0xAA0 */ 157e3260506SPeter A. G. Crosthwaite uint32_t csg_ram; /* 0xAB0 */ 158e3260506SPeter A. G. Crosthwaite uint32_t gpiob[12]; /* 0xB00 - 0xB2C */ 159e3260506SPeter A. G. Crosthwaite uint32_t ddriob[14]; /* 0xB40 - 0xB74 */ 160e3260506SPeter A. G. Crosthwaite }; 161e3260506SPeter A. G. Crosthwaite uint8_t data[0x1000]; 162e3260506SPeter A. G. Crosthwaite }; 163e3260506SPeter A. G. Crosthwaite } ZynqSLCRState; 164e3260506SPeter A. G. Crosthwaite 165e3260506SPeter A. G. Crosthwaite static void zynq_slcr_reset(DeviceState *d) 166e3260506SPeter A. G. Crosthwaite { 167a054e2c2SAndreas Färber ZynqSLCRState *s = ZYNQ_SLCR(d); 168e3260506SPeter A. G. Crosthwaite int i; 169e3260506SPeter A. G. Crosthwaite 170e3260506SPeter A. G. Crosthwaite DB_PRINT("RESET\n"); 171e3260506SPeter A. G. Crosthwaite 172e3260506SPeter A. G. Crosthwaite s->lockval = 1; 173e3260506SPeter A. G. Crosthwaite /* 0x100 - 0x11C */ 174e3260506SPeter A. G. Crosthwaite s->pll[ARM_PLL_CTRL] = 0x0001A008; 175e3260506SPeter A. G. Crosthwaite s->pll[DDR_PLL_CTRL] = 0x0001A008; 176e3260506SPeter A. G. Crosthwaite s->pll[IO_PLL_CTRL] = 0x0001A008; 177e3260506SPeter A. G. Crosthwaite s->pll[PLL_STATUS] = 0x0000003F; 178e3260506SPeter A. G. Crosthwaite s->pll[ARM_PPL_CFG] = 0x00014000; 179e3260506SPeter A. G. Crosthwaite s->pll[DDR_PLL_CFG] = 0x00014000; 180e3260506SPeter A. G. Crosthwaite s->pll[IO_PLL_CFG] = 0x00014000; 181e3260506SPeter A. G. Crosthwaite 182e3260506SPeter A. G. Crosthwaite /* 0x120 - 0x16C */ 183e3260506SPeter A. G. Crosthwaite s->clk[ARM_CLK_CTRL] = 0x1F000400; 184e3260506SPeter A. G. Crosthwaite s->clk[DDR_CLK_CTRL] = 0x18400003; 185e3260506SPeter A. G. Crosthwaite s->clk[DCI_CLK_CTRL] = 0x01E03201; 186e3260506SPeter A. G. Crosthwaite s->clk[APER_CLK_CTRL] = 0x01FFCCCD; 187e3260506SPeter A. G. Crosthwaite s->clk[USB0_CLK_CTRL] = s->clk[USB1_CLK_CTRL] = 0x00101941; 188e3260506SPeter A. G. Crosthwaite s->clk[GEM0_RCLK_CTRL] = s->clk[GEM1_RCLK_CTRL] = 0x00000001; 189e3260506SPeter A. G. Crosthwaite s->clk[GEM0_CLK_CTRL] = s->clk[GEM1_CLK_CTRL] = 0x00003C01; 190e3260506SPeter A. G. Crosthwaite s->clk[SMC_CLK_CTRL] = 0x00003C01; 191e3260506SPeter A. G. Crosthwaite s->clk[LQSPI_CLK_CTRL] = 0x00002821; 192e3260506SPeter A. G. Crosthwaite s->clk[SDIO_CLK_CTRL] = 0x00001E03; 193e3260506SPeter A. G. Crosthwaite s->clk[UART_CLK_CTRL] = 0x00003F03; 194e3260506SPeter A. G. Crosthwaite s->clk[SPI_CLK_CTRL] = 0x00003F03; 195e3260506SPeter A. G. Crosthwaite s->clk[CAN_CLK_CTRL] = 0x00501903; 196e3260506SPeter A. G. Crosthwaite s->clk[DBG_CLK_CTRL] = 0x00000F03; 197e3260506SPeter A. G. Crosthwaite s->clk[PCAP_CLK_CTRL] = 0x00000F01; 198e3260506SPeter A. G. Crosthwaite 199e3260506SPeter A. G. Crosthwaite /* 0x170 - 0x1AC */ 200e3260506SPeter A. G. Crosthwaite s->fpga[0][CLK_CTRL] = s->fpga[1][CLK_CTRL] = s->fpga[2][CLK_CTRL] = 201e3260506SPeter A. G. Crosthwaite s->fpga[3][CLK_CTRL] = 0x00101800; 202e3260506SPeter A. G. Crosthwaite s->fpga[0][THR_STA] = s->fpga[1][THR_STA] = s->fpga[2][THR_STA] = 203e3260506SPeter A. G. Crosthwaite s->fpga[3][THR_STA] = 0x00010000; 204e3260506SPeter A. G. Crosthwaite 205e3260506SPeter A. G. Crosthwaite /* 0x1B0 - 0x1D8 */ 206e3260506SPeter A. G. Crosthwaite s->misc[BANDGAP_TRIP] = 0x0000001F; 207e3260506SPeter A. G. Crosthwaite s->misc[PLL_PREDIVISOR] = 0x00000001; 208e3260506SPeter A. G. Crosthwaite s->misc[CLK_621_TRUE] = 0x00000001; 209e3260506SPeter A. G. Crosthwaite 210e3260506SPeter A. G. Crosthwaite /* 0x200 - 0x25C */ 211e3260506SPeter A. G. Crosthwaite s->reset[FPGA] = 0x01F33F0F; 212e3260506SPeter A. G. Crosthwaite s->reset[RST_REASON] = 0x00000040; 213e3260506SPeter A. G. Crosthwaite 214e3260506SPeter A. G. Crosthwaite /* 0x700 - 0x7D4 */ 215e3260506SPeter A. G. Crosthwaite for (i = 0; i < 54; i++) { 216e3260506SPeter A. G. Crosthwaite s->mio[i] = 0x00001601; 217e3260506SPeter A. G. Crosthwaite } 218e3260506SPeter A. G. Crosthwaite for (i = 2; i <= 8; i++) { 219e3260506SPeter A. G. Crosthwaite s->mio[i] = 0x00000601; 220e3260506SPeter A. G. Crosthwaite } 221e3260506SPeter A. G. Crosthwaite 222e3260506SPeter A. G. Crosthwaite /* MIO_MST_TRI0, MIO_MST_TRI1 */ 223e3260506SPeter A. G. Crosthwaite s->mio_func[2] = s->mio_func[3] = 0xFFFFFFFF; 224e3260506SPeter A. G. Crosthwaite 225e3260506SPeter A. G. Crosthwaite s->cpu_ram[0] = s->cpu_ram[1] = s->cpu_ram[3] = 226e3260506SPeter A. G. Crosthwaite s->cpu_ram[4] = s->cpu_ram[7] = 0x00010101; 227e3260506SPeter A. G. Crosthwaite s->cpu_ram[2] = s->cpu_ram[5] = 0x01010101; 228e3260506SPeter A. G. Crosthwaite s->cpu_ram[6] = 0x00000001; 229e3260506SPeter A. G. Crosthwaite 230e3260506SPeter A. G. Crosthwaite s->iou[0] = s->iou[1] = s->iou[2] = s->iou[3] = 0x09090909; 231e3260506SPeter A. G. Crosthwaite s->iou[4] = s->iou[5] = 0x00090909; 232e3260506SPeter A. G. Crosthwaite s->iou[6] = 0x00000909; 233e3260506SPeter A. G. Crosthwaite 234e3260506SPeter A. G. Crosthwaite s->dmac_ram = 0x00000009; 235e3260506SPeter A. G. Crosthwaite 236e3260506SPeter A. G. Crosthwaite s->afi[0][0] = s->afi[0][1] = 0x09090909; 237e3260506SPeter A. G. Crosthwaite s->afi[1][0] = s->afi[1][1] = 0x09090909; 238e3260506SPeter A. G. Crosthwaite s->afi[2][0] = s->afi[2][1] = 0x09090909; 239e3260506SPeter A. G. Crosthwaite s->afi[3][0] = s->afi[3][1] = 0x09090909; 240e3260506SPeter A. G. Crosthwaite s->afi[0][2] = s->afi[1][2] = s->afi[2][2] = s->afi[3][2] = 0x00000909; 241e3260506SPeter A. G. Crosthwaite 242e3260506SPeter A. G. Crosthwaite s->ocm[0] = 0x01010101; 243e3260506SPeter A. G. Crosthwaite s->ocm[1] = s->ocm[2] = 0x09090909; 244e3260506SPeter A. G. Crosthwaite 245e3260506SPeter A. G. Crosthwaite s->devci_ram = 0x00000909; 246e3260506SPeter A. G. Crosthwaite s->csg_ram = 0x00000001; 247e3260506SPeter A. G. Crosthwaite 248e3260506SPeter A. G. Crosthwaite s->ddriob[0] = s->ddriob[1] = s->ddriob[2] = s->ddriob[3] = 0x00000e00; 249e3260506SPeter A. G. Crosthwaite s->ddriob[4] = s->ddriob[5] = s->ddriob[6] = 0x00000e00; 250e3260506SPeter A. G. Crosthwaite s->ddriob[12] = 0x00000021; 251e3260506SPeter A. G. Crosthwaite } 252e3260506SPeter A. G. Crosthwaite 253e3260506SPeter A. G. Crosthwaite static inline uint32_t zynq_slcr_read_imp(void *opaque, 254a8170e5eSAvi Kivity hwaddr offset) 255e3260506SPeter A. G. Crosthwaite { 256e3260506SPeter A. G. Crosthwaite ZynqSLCRState *s = (ZynqSLCRState *)opaque; 257e3260506SPeter A. G. Crosthwaite 258e3260506SPeter A. G. Crosthwaite switch (offset) { 259e3260506SPeter A. G. Crosthwaite case 0x0: /* SCL */ 260e3260506SPeter A. G. Crosthwaite return s->scl; 261e3260506SPeter A. G. Crosthwaite case 0x4: /* LOCK */ 262e3260506SPeter A. G. Crosthwaite case 0x8: /* UNLOCK */ 263e3260506SPeter A. G. Crosthwaite DB_PRINT("Reading SCLR_LOCK/UNLOCK is not enabled\n"); 264e3260506SPeter A. G. Crosthwaite return 0; 265e3260506SPeter A. G. Crosthwaite case 0x0C: /* LOCKSTA */ 266e3260506SPeter A. G. Crosthwaite return s->lockval; 267e3260506SPeter A. G. Crosthwaite case 0x100 ... 0x11C: 268e3260506SPeter A. G. Crosthwaite return s->pll[(offset - 0x100) / 4]; 269e3260506SPeter A. G. Crosthwaite case 0x120 ... 0x16C: 270e3260506SPeter A. G. Crosthwaite return s->clk[(offset - 0x120) / 4]; 271e3260506SPeter A. G. Crosthwaite case 0x170 ... 0x1AC: 272e3260506SPeter A. G. Crosthwaite return s->fpga[0][(offset - 0x170) / 4]; 273e3260506SPeter A. G. Crosthwaite case 0x1B0 ... 0x1D8: 274e3260506SPeter A. G. Crosthwaite return s->misc[(offset - 0x1B0) / 4]; 275e3260506SPeter A. G. Crosthwaite case 0x200 ... 0x258: 276e3260506SPeter A. G. Crosthwaite return s->reset[(offset - 0x200) / 4]; 277e3260506SPeter A. G. Crosthwaite case 0x25c: 278e3260506SPeter A. G. Crosthwaite return 1; 279e3260506SPeter A. G. Crosthwaite case 0x300: 280e3260506SPeter A. G. Crosthwaite return s->apu_ctrl; 281e3260506SPeter A. G. Crosthwaite case 0x304: 282e3260506SPeter A. G. Crosthwaite return s->wdt_clk_sel; 283e3260506SPeter A. G. Crosthwaite case 0x400 ... 0x408: 284e3260506SPeter A. G. Crosthwaite return s->tz_ocm[(offset - 0x400) / 4]; 285e3260506SPeter A. G. Crosthwaite case 0x430: 286e3260506SPeter A. G. Crosthwaite return s->tz_ddr; 287e3260506SPeter A. G. Crosthwaite case 0x440 ... 0x448: 288e3260506SPeter A. G. Crosthwaite return s->tz_dma[(offset - 0x440) / 4]; 289e3260506SPeter A. G. Crosthwaite case 0x450 ... 0x458: 290e3260506SPeter A. G. Crosthwaite return s->tz_misc[(offset - 0x450) / 4]; 291e3260506SPeter A. G. Crosthwaite case 0x484 ... 0x488: 292e3260506SPeter A. G. Crosthwaite return s->tz_fpga[(offset - 0x484) / 4]; 293e3260506SPeter A. G. Crosthwaite case 0x500: 294e3260506SPeter A. G. Crosthwaite return s->dbg_ctrl; 295e3260506SPeter A. G. Crosthwaite case 0x530: 296e3260506SPeter A. G. Crosthwaite return s->pss_idcode; 297e3260506SPeter A. G. Crosthwaite case 0x600 ... 0x620: 298e3260506SPeter A. G. Crosthwaite if (offset == 0x604) { 299e3260506SPeter A. G. Crosthwaite goto bad_reg; 300e3260506SPeter A. G. Crosthwaite } 301e3260506SPeter A. G. Crosthwaite return s->ddr[(offset - 0x600) / 4]; 302e3260506SPeter A. G. Crosthwaite case 0x700 ... 0x7D4: 303e3260506SPeter A. G. Crosthwaite return s->mio[(offset - 0x700) / 4]; 304e3260506SPeter A. G. Crosthwaite case 0x800 ... 0x810: 305e3260506SPeter A. G. Crosthwaite return s->mio_func[(offset - 0x800) / 4]; 306e3260506SPeter A. G. Crosthwaite case 0x830 ... 0x834: 307e3260506SPeter A. G. Crosthwaite return s->sd[(offset - 0x830) / 4]; 308e3260506SPeter A. G. Crosthwaite case 0x900: 309e3260506SPeter A. G. Crosthwaite return s->lvl_shftr_en; 310e3260506SPeter A. G. Crosthwaite case 0x910: 311e3260506SPeter A. G. Crosthwaite return s->ocm_cfg; 312e3260506SPeter A. G. Crosthwaite case 0xA00 ... 0xA1C: 313e3260506SPeter A. G. Crosthwaite return s->cpu_ram[(offset - 0xA00) / 4]; 314e3260506SPeter A. G. Crosthwaite case 0xA30 ... 0xA48: 315e3260506SPeter A. G. Crosthwaite return s->iou[(offset - 0xA30) / 4]; 316e3260506SPeter A. G. Crosthwaite case 0xA50: 317e3260506SPeter A. G. Crosthwaite return s->dmac_ram; 318e3260506SPeter A. G. Crosthwaite case 0xA60 ... 0xA8C: 3190d10f627SAnthony Liguori return s->afi[0][(offset - 0xA60) / 4]; 320e3260506SPeter A. G. Crosthwaite case 0xA90 ... 0xA98: 321e3260506SPeter A. G. Crosthwaite return s->ocm[(offset - 0xA90) / 4]; 322e3260506SPeter A. G. Crosthwaite case 0xAA0: 323e3260506SPeter A. G. Crosthwaite return s->devci_ram; 324e3260506SPeter A. G. Crosthwaite case 0xAB0: 325e3260506SPeter A. G. Crosthwaite return s->csg_ram; 326e3260506SPeter A. G. Crosthwaite case 0xB00 ... 0xB2C: 327e3260506SPeter A. G. Crosthwaite return s->gpiob[(offset - 0xB00) / 4]; 328e3260506SPeter A. G. Crosthwaite case 0xB40 ... 0xB74: 329e3260506SPeter A. G. Crosthwaite return s->ddriob[(offset - 0xB40) / 4]; 330e3260506SPeter A. G. Crosthwaite default: 331e3260506SPeter A. G. Crosthwaite bad_reg: 332e3260506SPeter A. G. Crosthwaite DB_PRINT("Bad register offset 0x%x\n", (int)offset); 333e3260506SPeter A. G. Crosthwaite return 0; 334e3260506SPeter A. G. Crosthwaite } 335e3260506SPeter A. G. Crosthwaite } 336e3260506SPeter A. G. Crosthwaite 337a8170e5eSAvi Kivity static uint64_t zynq_slcr_read(void *opaque, hwaddr offset, 338e3260506SPeter A. G. Crosthwaite unsigned size) 339e3260506SPeter A. G. Crosthwaite { 340e3260506SPeter A. G. Crosthwaite uint32_t ret = zynq_slcr_read_imp(opaque, offset); 341e3260506SPeter A. G. Crosthwaite 3428f603800SPeter Crosthwaite DB_PRINT("addr: %08x data: %08x\n", (unsigned)offset, (unsigned)ret); 343e3260506SPeter A. G. Crosthwaite return ret; 344e3260506SPeter A. G. Crosthwaite } 345e3260506SPeter A. G. Crosthwaite 346a8170e5eSAvi Kivity static void zynq_slcr_write(void *opaque, hwaddr offset, 347e3260506SPeter A. G. Crosthwaite uint64_t val, unsigned size) 348e3260506SPeter A. G. Crosthwaite { 349e3260506SPeter A. G. Crosthwaite ZynqSLCRState *s = (ZynqSLCRState *)opaque; 350e3260506SPeter A. G. Crosthwaite 3518f603800SPeter Crosthwaite DB_PRINT("offset: %08x data: %08x\n", (unsigned)offset, (unsigned)val); 352e3260506SPeter A. G. Crosthwaite 353e3260506SPeter A. G. Crosthwaite switch (offset) { 354e3260506SPeter A. G. Crosthwaite case 0x00: /* SCL */ 355e3260506SPeter A. G. Crosthwaite s->scl = val & 0x1; 356e3260506SPeter A. G. Crosthwaite return; 357e3260506SPeter A. G. Crosthwaite case 0x4: /* SLCR_LOCK */ 358e3260506SPeter A. G. Crosthwaite if ((val & 0xFFFF) == XILINX_LOCK_KEY) { 359e3260506SPeter A. G. Crosthwaite DB_PRINT("XILINX LOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset, 360e3260506SPeter A. G. Crosthwaite (unsigned)val & 0xFFFF); 361e3260506SPeter A. G. Crosthwaite s->lockval = 1; 362e3260506SPeter A. G. Crosthwaite } else { 363e3260506SPeter A. G. Crosthwaite DB_PRINT("WRONG XILINX LOCK KEY 0xF8000000 + 0x%x <= 0x%x\n", 364e3260506SPeter A. G. Crosthwaite (int)offset, (unsigned)val & 0xFFFF); 365e3260506SPeter A. G. Crosthwaite } 366e3260506SPeter A. G. Crosthwaite return; 367e3260506SPeter A. G. Crosthwaite case 0x8: /* SLCR_UNLOCK */ 368e3260506SPeter A. G. Crosthwaite if ((val & 0xFFFF) == XILINX_UNLOCK_KEY) { 369e3260506SPeter A. G. Crosthwaite DB_PRINT("XILINX UNLOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset, 370e3260506SPeter A. G. Crosthwaite (unsigned)val & 0xFFFF); 371e3260506SPeter A. G. Crosthwaite s->lockval = 0; 372e3260506SPeter A. G. Crosthwaite } else { 373e3260506SPeter A. G. Crosthwaite DB_PRINT("WRONG XILINX UNLOCK KEY 0xF8000000 + 0x%x <= 0x%x\n", 374e3260506SPeter A. G. Crosthwaite (int)offset, (unsigned)val & 0xFFFF); 375e3260506SPeter A. G. Crosthwaite } 376e3260506SPeter A. G. Crosthwaite return; 377e3260506SPeter A. G. Crosthwaite case 0xc: /* LOCKSTA */ 378e3260506SPeter A. G. Crosthwaite DB_PRINT("Writing SCLR_LOCKSTA is not enabled\n"); 379e3260506SPeter A. G. Crosthwaite return; 380e3260506SPeter A. G. Crosthwaite } 381e3260506SPeter A. G. Crosthwaite 382e3260506SPeter A. G. Crosthwaite if (!s->lockval) { 383e3260506SPeter A. G. Crosthwaite switch (offset) { 384e3260506SPeter A. G. Crosthwaite case 0x100 ... 0x11C: 385e3260506SPeter A. G. Crosthwaite if (offset == 0x10C) { 386e3260506SPeter A. G. Crosthwaite goto bad_reg; 387e3260506SPeter A. G. Crosthwaite } 388e3260506SPeter A. G. Crosthwaite s->pll[(offset - 0x100) / 4] = val; 389e3260506SPeter A. G. Crosthwaite break; 390e3260506SPeter A. G. Crosthwaite case 0x120 ... 0x16C: 391e3260506SPeter A. G. Crosthwaite s->clk[(offset - 0x120) / 4] = val; 392e3260506SPeter A. G. Crosthwaite break; 393e3260506SPeter A. G. Crosthwaite case 0x170 ... 0x1AC: 394e3260506SPeter A. G. Crosthwaite s->fpga[0][(offset - 0x170) / 4] = val; 395e3260506SPeter A. G. Crosthwaite break; 396e3260506SPeter A. G. Crosthwaite case 0x1B0 ... 0x1D8: 397e3260506SPeter A. G. Crosthwaite s->misc[(offset - 0x1B0) / 4] = val; 398e3260506SPeter A. G. Crosthwaite break; 399e3260506SPeter A. G. Crosthwaite case 0x200 ... 0x25C: 400e3260506SPeter A. G. Crosthwaite if (offset == 0x250) { 401e3260506SPeter A. G. Crosthwaite goto bad_reg; 402e3260506SPeter A. G. Crosthwaite } 403e3260506SPeter A. G. Crosthwaite s->reset[(offset - 0x200) / 4] = val; 404*69991d7dSSebastian Huber if (offset == 0x200 && (val & R_PSS_RST_CTRL_SOFT_RST)) { 405*69991d7dSSebastian Huber qemu_system_reset_request(); 406*69991d7dSSebastian Huber } 407e3260506SPeter A. G. Crosthwaite break; 408e3260506SPeter A. G. Crosthwaite case 0x300: 409e3260506SPeter A. G. Crosthwaite s->apu_ctrl = val; 410e3260506SPeter A. G. Crosthwaite break; 411e3260506SPeter A. G. Crosthwaite case 0x304: 412e3260506SPeter A. G. Crosthwaite s->wdt_clk_sel = val; 413e3260506SPeter A. G. Crosthwaite break; 414e3260506SPeter A. G. Crosthwaite case 0x400 ... 0x408: 415e3260506SPeter A. G. Crosthwaite s->tz_ocm[(offset - 0x400) / 4] = val; 416e3260506SPeter A. G. Crosthwaite break; 417e3260506SPeter A. G. Crosthwaite case 0x430: 418e3260506SPeter A. G. Crosthwaite s->tz_ddr = val; 419e3260506SPeter A. G. Crosthwaite break; 420e3260506SPeter A. G. Crosthwaite case 0x440 ... 0x448: 421e3260506SPeter A. G. Crosthwaite s->tz_dma[(offset - 0x440) / 4] = val; 422e3260506SPeter A. G. Crosthwaite break; 423e3260506SPeter A. G. Crosthwaite case 0x450 ... 0x458: 424e3260506SPeter A. G. Crosthwaite s->tz_misc[(offset - 0x450) / 4] = val; 425e3260506SPeter A. G. Crosthwaite break; 426e3260506SPeter A. G. Crosthwaite case 0x484 ... 0x488: 427e3260506SPeter A. G. Crosthwaite s->tz_fpga[(offset - 0x484) / 4] = val; 428e3260506SPeter A. G. Crosthwaite break; 429e3260506SPeter A. G. Crosthwaite case 0x500: 430e3260506SPeter A. G. Crosthwaite s->dbg_ctrl = val; 431e3260506SPeter A. G. Crosthwaite break; 432e3260506SPeter A. G. Crosthwaite case 0x530: 433e3260506SPeter A. G. Crosthwaite s->pss_idcode = val; 434e3260506SPeter A. G. Crosthwaite break; 435e3260506SPeter A. G. Crosthwaite case 0x600 ... 0x620: 436e3260506SPeter A. G. Crosthwaite if (offset == 0x604) { 437e3260506SPeter A. G. Crosthwaite goto bad_reg; 438e3260506SPeter A. G. Crosthwaite } 439e3260506SPeter A. G. Crosthwaite s->ddr[(offset - 0x600) / 4] = val; 440e3260506SPeter A. G. Crosthwaite break; 441e3260506SPeter A. G. Crosthwaite case 0x700 ... 0x7D4: 442e3260506SPeter A. G. Crosthwaite s->mio[(offset - 0x700) / 4] = val; 443e3260506SPeter A. G. Crosthwaite break; 444e3260506SPeter A. G. Crosthwaite case 0x800 ... 0x810: 445e3260506SPeter A. G. Crosthwaite s->mio_func[(offset - 0x800) / 4] = val; 446e3260506SPeter A. G. Crosthwaite break; 447e3260506SPeter A. G. Crosthwaite case 0x830 ... 0x834: 448e3260506SPeter A. G. Crosthwaite s->sd[(offset - 0x830) / 4] = val; 449e3260506SPeter A. G. Crosthwaite break; 450e3260506SPeter A. G. Crosthwaite case 0x900: 451e3260506SPeter A. G. Crosthwaite s->lvl_shftr_en = val; 452e3260506SPeter A. G. Crosthwaite break; 453e3260506SPeter A. G. Crosthwaite case 0x910: 454e3260506SPeter A. G. Crosthwaite break; 455e3260506SPeter A. G. Crosthwaite case 0xA00 ... 0xA1C: 456e3260506SPeter A. G. Crosthwaite s->cpu_ram[(offset - 0xA00) / 4] = val; 457e3260506SPeter A. G. Crosthwaite break; 458e3260506SPeter A. G. Crosthwaite case 0xA30 ... 0xA48: 459e3260506SPeter A. G. Crosthwaite s->iou[(offset - 0xA30) / 4] = val; 460e3260506SPeter A. G. Crosthwaite break; 461e3260506SPeter A. G. Crosthwaite case 0xA50: 462e3260506SPeter A. G. Crosthwaite s->dmac_ram = val; 463e3260506SPeter A. G. Crosthwaite break; 464e3260506SPeter A. G. Crosthwaite case 0xA60 ... 0xA8C: 4650d10f627SAnthony Liguori s->afi[0][(offset - 0xA60) / 4] = val; 466e3260506SPeter A. G. Crosthwaite break; 467e3260506SPeter A. G. Crosthwaite case 0xA90: 468e3260506SPeter A. G. Crosthwaite s->ocm[0] = val; 469e3260506SPeter A. G. Crosthwaite break; 470e3260506SPeter A. G. Crosthwaite case 0xAA0: 471e3260506SPeter A. G. Crosthwaite s->devci_ram = val; 472e3260506SPeter A. G. Crosthwaite break; 473e3260506SPeter A. G. Crosthwaite case 0xAB0: 474e3260506SPeter A. G. Crosthwaite s->csg_ram = val; 475e3260506SPeter A. G. Crosthwaite break; 476e3260506SPeter A. G. Crosthwaite case 0xB00 ... 0xB2C: 477e3260506SPeter A. G. Crosthwaite if (offset == 0xB20 || offset == 0xB2C) { 478e3260506SPeter A. G. Crosthwaite goto bad_reg; 479e3260506SPeter A. G. Crosthwaite } 480e3260506SPeter A. G. Crosthwaite s->gpiob[(offset - 0xB00) / 4] = val; 481e3260506SPeter A. G. Crosthwaite break; 482e3260506SPeter A. G. Crosthwaite case 0xB40 ... 0xB74: 483e3260506SPeter A. G. Crosthwaite s->ddriob[(offset - 0xB40) / 4] = val; 484e3260506SPeter A. G. Crosthwaite break; 485e3260506SPeter A. G. Crosthwaite default: 486e3260506SPeter A. G. Crosthwaite bad_reg: 4878f603800SPeter Crosthwaite DB_PRINT("Bad register write %x <= %08x\n", (int)offset, 4888f603800SPeter Crosthwaite (unsigned)val); 489e3260506SPeter A. G. Crosthwaite } 490e3260506SPeter A. G. Crosthwaite } else { 491e3260506SPeter A. G. Crosthwaite DB_PRINT("SCLR registers are locked. Unlock them first\n"); 492e3260506SPeter A. G. Crosthwaite } 493e3260506SPeter A. G. Crosthwaite } 494e3260506SPeter A. G. Crosthwaite 495e3260506SPeter A. G. Crosthwaite static const MemoryRegionOps slcr_ops = { 496e3260506SPeter A. G. Crosthwaite .read = zynq_slcr_read, 497e3260506SPeter A. G. Crosthwaite .write = zynq_slcr_write, 498e3260506SPeter A. G. Crosthwaite .endianness = DEVICE_NATIVE_ENDIAN, 499e3260506SPeter A. G. Crosthwaite }; 500e3260506SPeter A. G. Crosthwaite 501e3260506SPeter A. G. Crosthwaite static int zynq_slcr_init(SysBusDevice *dev) 502e3260506SPeter A. G. Crosthwaite { 503a054e2c2SAndreas Färber ZynqSLCRState *s = ZYNQ_SLCR(dev); 504e3260506SPeter A. G. Crosthwaite 5053c161542SPaolo Bonzini memory_region_init_io(&s->iomem, OBJECT(s), &slcr_ops, s, "slcr", 0x1000); 506e3260506SPeter A. G. Crosthwaite sysbus_init_mmio(dev, &s->iomem); 507e3260506SPeter A. G. Crosthwaite 508e3260506SPeter A. G. Crosthwaite return 0; 509e3260506SPeter A. G. Crosthwaite } 510e3260506SPeter A. G. Crosthwaite 511e3260506SPeter A. G. Crosthwaite static const VMStateDescription vmstate_zynq_slcr = { 512e3260506SPeter A. G. Crosthwaite .name = "zynq_slcr", 513e3260506SPeter A. G. Crosthwaite .version_id = 1, 514e3260506SPeter A. G. Crosthwaite .minimum_version_id = 1, 515e3260506SPeter A. G. Crosthwaite .minimum_version_id_old = 1, 516e3260506SPeter A. G. Crosthwaite .fields = (VMStateField[]) { 517e3260506SPeter A. G. Crosthwaite VMSTATE_UINT8_ARRAY(data, ZynqSLCRState, 0x1000), 518e3260506SPeter A. G. Crosthwaite VMSTATE_END_OF_LIST() 519e3260506SPeter A. G. Crosthwaite } 520e3260506SPeter A. G. Crosthwaite }; 521e3260506SPeter A. G. Crosthwaite 522e3260506SPeter A. G. Crosthwaite static void zynq_slcr_class_init(ObjectClass *klass, void *data) 523e3260506SPeter A. G. Crosthwaite { 524e3260506SPeter A. G. Crosthwaite DeviceClass *dc = DEVICE_CLASS(klass); 525e3260506SPeter A. G. Crosthwaite SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); 526e3260506SPeter A. G. Crosthwaite 527e3260506SPeter A. G. Crosthwaite sdc->init = zynq_slcr_init; 528e3260506SPeter A. G. Crosthwaite dc->vmsd = &vmstate_zynq_slcr; 529e3260506SPeter A. G. Crosthwaite dc->reset = zynq_slcr_reset; 530e3260506SPeter A. G. Crosthwaite } 531e3260506SPeter A. G. Crosthwaite 5328c43a6f0SAndreas Färber static const TypeInfo zynq_slcr_info = { 533e3260506SPeter A. G. Crosthwaite .class_init = zynq_slcr_class_init, 534a054e2c2SAndreas Färber .name = TYPE_ZYNQ_SLCR, 535e3260506SPeter A. G. Crosthwaite .parent = TYPE_SYS_BUS_DEVICE, 536e3260506SPeter A. G. Crosthwaite .instance_size = sizeof(ZynqSLCRState), 537e3260506SPeter A. G. Crosthwaite }; 538e3260506SPeter A. G. Crosthwaite 539e3260506SPeter A. G. Crosthwaite static void zynq_slcr_register_types(void) 540e3260506SPeter A. G. Crosthwaite { 541e3260506SPeter A. G. Crosthwaite type_register_static(&zynq_slcr_info); 542e3260506SPeter A. G. Crosthwaite } 543e3260506SPeter A. G. Crosthwaite 544e3260506SPeter A. G. Crosthwaite type_init(zynq_slcr_register_types) 545