xref: /qemu/hw/misc/zynq_slcr.c (revision 69991d7dcbcf7f3fe38274bc67fcba3cbbfda0cf)
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