2 * Status and system control registers for Xilinx Zynq Platform
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
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.
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/>.
18 #include "qemu/timer.h"
19 #include "hw/sysbus.h"
20 #include "sysemu/sysemu.h"
22 #ifdef ZYNQ_ARM_SLCR_ERR_DEBUG
23 #define DB_PRINT(...) do { \
24 fprintf(stderr, ": %s: ", __func__); \
25 fprintf(stderr, ## __VA_ARGS__); \
31 #define XILINX_LOCK_KEY 0x767b
32 #define XILINX_UNLOCK_KEY 0xdf0d
34 #define R_PSS_RST_CTRL_SOFT_RST 0x1
119 #define TYPE_ZYNQ_SLCR "xilinx,zynq_slcr"
120 #define ZYNQ_SLCR(obj) OBJECT_CHECK(ZynqSLCRState, (obj), TYPE_ZYNQ_SLCR)
122 typedef struct ZynqSLCRState
{
123 SysBusDevice parent_obj
;
131 uint32_t pll
[PLL_MAX
]; /* 0x100 - 0x11C */
132 uint32_t clk
[CLK_MAX
]; /* 0x120 - 0x16C */
133 uint32_t fpga
[4][FPGA_MAX
]; /* 0x170 - 0x1AC */
134 uint32_t misc
[MISC_MAX
]; /* 0x1B0 - 0x1D8 */
135 uint32_t reset
[RESET_MAX
]; /* 0x200 - 0x25C */
136 uint32_t apu_ctrl
; /* 0x300 */
137 uint32_t wdt_clk_sel
; /* 0x304 */
138 uint32_t tz_ocm
[3]; /* 0x400 - 0x408 */
139 uint32_t tz_ddr
; /* 0x430 */
140 uint32_t tz_dma
[3]; /* 0x440 - 0x448 */
141 uint32_t tz_misc
[3]; /* 0x450 - 0x458 */
142 uint32_t tz_fpga
[2]; /* 0x484 - 0x488 */
143 uint32_t dbg_ctrl
; /* 0x500 */
144 uint32_t pss_idcode
; /* 0x530 */
145 uint32_t ddr
[8]; /* 0x600 - 0x620 - 0x604-missing */
146 uint32_t mio
[54]; /* 0x700 - 0x7D4 */
147 uint32_t mio_func
[4]; /* 0x800 - 0x810 */
148 uint32_t sd
[2]; /* 0x830 - 0x834 */
149 uint32_t lvl_shftr_en
; /* 0x900 */
150 uint32_t ocm_cfg
; /* 0x910 */
151 uint32_t cpu_ram
[8]; /* 0xA00 - 0xA1C */
152 uint32_t iou
[7]; /* 0xA30 - 0xA48 */
153 uint32_t dmac_ram
; /* 0xA50 */
154 uint32_t afi
[4][3]; /* 0xA60 - 0xA8C */
155 uint32_t ocm
[3]; /* 0xA90 - 0xA98 */
156 uint32_t devci_ram
; /* 0xAA0 */
157 uint32_t csg_ram
; /* 0xAB0 */
158 uint32_t gpiob
[12]; /* 0xB00 - 0xB2C */
159 uint32_t ddriob
[14]; /* 0xB40 - 0xB74 */
161 uint8_t data
[0x1000];
165 static void zynq_slcr_reset(DeviceState
*d
)
167 ZynqSLCRState
*s
= ZYNQ_SLCR(d
);
174 s
->pll
[ARM_PLL_CTRL
] = 0x0001A008;
175 s
->pll
[DDR_PLL_CTRL
] = 0x0001A008;
176 s
->pll
[IO_PLL_CTRL
] = 0x0001A008;
177 s
->pll
[PLL_STATUS
] = 0x0000003F;
178 s
->pll
[ARM_PPL_CFG
] = 0x00014000;
179 s
->pll
[DDR_PLL_CFG
] = 0x00014000;
180 s
->pll
[IO_PLL_CFG
] = 0x00014000;
183 s
->clk
[ARM_CLK_CTRL
] = 0x1F000400;
184 s
->clk
[DDR_CLK_CTRL
] = 0x18400003;
185 s
->clk
[DCI_CLK_CTRL
] = 0x01E03201;
186 s
->clk
[APER_CLK_CTRL
] = 0x01FFCCCD;
187 s
->clk
[USB0_CLK_CTRL
] = s
->clk
[USB1_CLK_CTRL
] = 0x00101941;
188 s
->clk
[GEM0_RCLK_CTRL
] = s
->clk
[GEM1_RCLK_CTRL
] = 0x00000001;
189 s
->clk
[GEM0_CLK_CTRL
] = s
->clk
[GEM1_CLK_CTRL
] = 0x00003C01;
190 s
->clk
[SMC_CLK_CTRL
] = 0x00003C01;
191 s
->clk
[LQSPI_CLK_CTRL
] = 0x00002821;
192 s
->clk
[SDIO_CLK_CTRL
] = 0x00001E03;
193 s
->clk
[UART_CLK_CTRL
] = 0x00003F03;
194 s
->clk
[SPI_CLK_CTRL
] = 0x00003F03;
195 s
->clk
[CAN_CLK_CTRL
] = 0x00501903;
196 s
->clk
[DBG_CLK_CTRL
] = 0x00000F03;
197 s
->clk
[PCAP_CLK_CTRL
] = 0x00000F01;
200 s
->fpga
[0][CLK_CTRL
] = s
->fpga
[1][CLK_CTRL
] = s
->fpga
[2][CLK_CTRL
] =
201 s
->fpga
[3][CLK_CTRL
] = 0x00101800;
202 s
->fpga
[0][THR_STA
] = s
->fpga
[1][THR_STA
] = s
->fpga
[2][THR_STA
] =
203 s
->fpga
[3][THR_STA
] = 0x00010000;
206 s
->misc
[BANDGAP_TRIP
] = 0x0000001F;
207 s
->misc
[PLL_PREDIVISOR
] = 0x00000001;
208 s
->misc
[CLK_621_TRUE
] = 0x00000001;
211 s
->reset
[FPGA
] = 0x01F33F0F;
212 s
->reset
[RST_REASON
] = 0x00000040;
215 for (i
= 0; i
< 54; i
++) {
216 s
->mio
[i
] = 0x00001601;
218 for (i
= 2; i
<= 8; i
++) {
219 s
->mio
[i
] = 0x00000601;
222 /* MIO_MST_TRI0, MIO_MST_TRI1 */
223 s
->mio_func
[2] = s
->mio_func
[3] = 0xFFFFFFFF;
225 s
->cpu_ram
[0] = s
->cpu_ram
[1] = s
->cpu_ram
[3] =
226 s
->cpu_ram
[4] = s
->cpu_ram
[7] = 0x00010101;
227 s
->cpu_ram
[2] = s
->cpu_ram
[5] = 0x01010101;
228 s
->cpu_ram
[6] = 0x00000001;
230 s
->iou
[0] = s
->iou
[1] = s
->iou
[2] = s
->iou
[3] = 0x09090909;
231 s
->iou
[4] = s
->iou
[5] = 0x00090909;
232 s
->iou
[6] = 0x00000909;
234 s
->dmac_ram
= 0x00000009;
236 s
->afi
[0][0] = s
->afi
[0][1] = 0x09090909;
237 s
->afi
[1][0] = s
->afi
[1][1] = 0x09090909;
238 s
->afi
[2][0] = s
->afi
[2][1] = 0x09090909;
239 s
->afi
[3][0] = s
->afi
[3][1] = 0x09090909;
240 s
->afi
[0][2] = s
->afi
[1][2] = s
->afi
[2][2] = s
->afi
[3][2] = 0x00000909;
242 s
->ocm
[0] = 0x01010101;
243 s
->ocm
[1] = s
->ocm
[2] = 0x09090909;
245 s
->devci_ram
= 0x00000909;
246 s
->csg_ram
= 0x00000001;
248 s
->ddriob
[0] = s
->ddriob
[1] = s
->ddriob
[2] = s
->ddriob
[3] = 0x00000e00;
249 s
->ddriob
[4] = s
->ddriob
[5] = s
->ddriob
[6] = 0x00000e00;
250 s
->ddriob
[12] = 0x00000021;
253 static inline uint32_t zynq_slcr_read_imp(void *opaque
,
256 ZynqSLCRState
*s
= (ZynqSLCRState
*)opaque
;
262 case 0x8: /* UNLOCK */
263 DB_PRINT("Reading SCLR_LOCK/UNLOCK is not enabled\n");
265 case 0x0C: /* LOCKSTA */
267 case 0x100 ... 0x11C:
268 return s
->pll
[(offset
- 0x100) / 4];
269 case 0x120 ... 0x16C:
270 return s
->clk
[(offset
- 0x120) / 4];
271 case 0x170 ... 0x1AC:
272 return s
->fpga
[0][(offset
- 0x170) / 4];
273 case 0x1B0 ... 0x1D8:
274 return s
->misc
[(offset
- 0x1B0) / 4];
275 case 0x200 ... 0x258:
276 return s
->reset
[(offset
- 0x200) / 4];
282 return s
->wdt_clk_sel
;
283 case 0x400 ... 0x408:
284 return s
->tz_ocm
[(offset
- 0x400) / 4];
287 case 0x440 ... 0x448:
288 return s
->tz_dma
[(offset
- 0x440) / 4];
289 case 0x450 ... 0x458:
290 return s
->tz_misc
[(offset
- 0x450) / 4];
291 case 0x484 ... 0x488:
292 return s
->tz_fpga
[(offset
- 0x484) / 4];
296 return s
->pss_idcode
;
297 case 0x600 ... 0x620:
298 if (offset
== 0x604) {
301 return s
->ddr
[(offset
- 0x600) / 4];
302 case 0x700 ... 0x7D4:
303 return s
->mio
[(offset
- 0x700) / 4];
304 case 0x800 ... 0x810:
305 return s
->mio_func
[(offset
- 0x800) / 4];
306 case 0x830 ... 0x834:
307 return s
->sd
[(offset
- 0x830) / 4];
309 return s
->lvl_shftr_en
;
312 case 0xA00 ... 0xA1C:
313 return s
->cpu_ram
[(offset
- 0xA00) / 4];
314 case 0xA30 ... 0xA48:
315 return s
->iou
[(offset
- 0xA30) / 4];
318 case 0xA60 ... 0xA8C:
319 return s
->afi
[0][(offset
- 0xA60) / 4];
320 case 0xA90 ... 0xA98:
321 return s
->ocm
[(offset
- 0xA90) / 4];
326 case 0xB00 ... 0xB2C:
327 return s
->gpiob
[(offset
- 0xB00) / 4];
328 case 0xB40 ... 0xB74:
329 return s
->ddriob
[(offset
- 0xB40) / 4];
332 DB_PRINT("Bad register offset 0x%x\n", (int)offset
);
337 static uint64_t zynq_slcr_read(void *opaque
, hwaddr offset
,
340 uint32_t ret
= zynq_slcr_read_imp(opaque
, offset
);
342 DB_PRINT("addr: %08x data: %08x\n", (unsigned)offset
, (unsigned)ret
);
346 static void zynq_slcr_write(void *opaque
, hwaddr offset
,
347 uint64_t val
, unsigned size
)
349 ZynqSLCRState
*s
= (ZynqSLCRState
*)opaque
;
351 DB_PRINT("offset: %08x data: %08x\n", (unsigned)offset
, (unsigned)val
);
357 case 0x4: /* SLCR_LOCK */
358 if ((val
& 0xFFFF) == XILINX_LOCK_KEY
) {
359 DB_PRINT("XILINX LOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset
,
360 (unsigned)val
& 0xFFFF);
363 DB_PRINT("WRONG XILINX LOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
364 (int)offset
, (unsigned)val
& 0xFFFF);
367 case 0x8: /* SLCR_UNLOCK */
368 if ((val
& 0xFFFF) == XILINX_UNLOCK_KEY
) {
369 DB_PRINT("XILINX UNLOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset
,
370 (unsigned)val
& 0xFFFF);
373 DB_PRINT("WRONG XILINX UNLOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
374 (int)offset
, (unsigned)val
& 0xFFFF);
377 case 0xc: /* LOCKSTA */
378 DB_PRINT("Writing SCLR_LOCKSTA is not enabled\n");
384 case 0x100 ... 0x11C:
385 if (offset
== 0x10C) {
388 s
->pll
[(offset
- 0x100) / 4] = val
;
390 case 0x120 ... 0x16C:
391 s
->clk
[(offset
- 0x120) / 4] = val
;
393 case 0x170 ... 0x1AC:
394 s
->fpga
[0][(offset
- 0x170) / 4] = val
;
396 case 0x1B0 ... 0x1D8:
397 s
->misc
[(offset
- 0x1B0) / 4] = val
;
399 case 0x200 ... 0x25C:
400 if (offset
== 0x250) {
403 s
->reset
[(offset
- 0x200) / 4] = val
;
404 if (offset
== 0x200 && (val
& R_PSS_RST_CTRL_SOFT_RST
)) {
405 qemu_system_reset_request();
412 s
->wdt_clk_sel
= val
;
414 case 0x400 ... 0x408:
415 s
->tz_ocm
[(offset
- 0x400) / 4] = val
;
420 case 0x440 ... 0x448:
421 s
->tz_dma
[(offset
- 0x440) / 4] = val
;
423 case 0x450 ... 0x458:
424 s
->tz_misc
[(offset
- 0x450) / 4] = val
;
426 case 0x484 ... 0x488:
427 s
->tz_fpga
[(offset
- 0x484) / 4] = val
;
435 case 0x600 ... 0x620:
436 if (offset
== 0x604) {
439 s
->ddr
[(offset
- 0x600) / 4] = val
;
441 case 0x700 ... 0x7D4:
442 s
->mio
[(offset
- 0x700) / 4] = val
;
444 case 0x800 ... 0x810:
445 s
->mio_func
[(offset
- 0x800) / 4] = val
;
447 case 0x830 ... 0x834:
448 s
->sd
[(offset
- 0x830) / 4] = val
;
451 s
->lvl_shftr_en
= val
;
455 case 0xA00 ... 0xA1C:
456 s
->cpu_ram
[(offset
- 0xA00) / 4] = val
;
458 case 0xA30 ... 0xA48:
459 s
->iou
[(offset
- 0xA30) / 4] = val
;
464 case 0xA60 ... 0xA8C:
465 s
->afi
[0][(offset
- 0xA60) / 4] = val
;
476 case 0xB00 ... 0xB2C:
477 if (offset
== 0xB20 || offset
== 0xB2C) {
480 s
->gpiob
[(offset
- 0xB00) / 4] = val
;
482 case 0xB40 ... 0xB74:
483 s
->ddriob
[(offset
- 0xB40) / 4] = val
;
487 DB_PRINT("Bad register write %x <= %08x\n", (int)offset
,
491 DB_PRINT("SCLR registers are locked. Unlock them first\n");
495 static const MemoryRegionOps slcr_ops
= {
496 .read
= zynq_slcr_read
,
497 .write
= zynq_slcr_write
,
498 .endianness
= DEVICE_NATIVE_ENDIAN
,
501 static int zynq_slcr_init(SysBusDevice
*dev
)
503 ZynqSLCRState
*s
= ZYNQ_SLCR(dev
);
505 memory_region_init_io(&s
->iomem
, OBJECT(s
), &slcr_ops
, s
, "slcr", 0x1000);
506 sysbus_init_mmio(dev
, &s
->iomem
);
511 static const VMStateDescription vmstate_zynq_slcr
= {
514 .minimum_version_id
= 1,
515 .minimum_version_id_old
= 1,
516 .fields
= (VMStateField
[]) {
517 VMSTATE_UINT8_ARRAY(data
, ZynqSLCRState
, 0x1000),
518 VMSTATE_END_OF_LIST()
522 static void zynq_slcr_class_init(ObjectClass
*klass
, void *data
)
524 DeviceClass
*dc
= DEVICE_CLASS(klass
);
525 SysBusDeviceClass
*sdc
= SYS_BUS_DEVICE_CLASS(klass
);
527 sdc
->init
= zynq_slcr_init
;
528 dc
->vmsd
= &vmstate_zynq_slcr
;
529 dc
->reset
= zynq_slcr_reset
;
532 static const TypeInfo zynq_slcr_info
= {
533 .class_init
= zynq_slcr_class_init
,
534 .name
= TYPE_ZYNQ_SLCR
,
535 .parent
= TYPE_SYS_BUS_DEVICE
,
536 .instance_size
= sizeof(ZynqSLCRState
),
539 static void zynq_slcr_register_types(void)
541 type_register_static(&zynq_slcr_info
);
544 type_init(zynq_slcr_register_types
)