xref: /openbmc/qemu/hw/misc/zynq_slcr.c (revision b9c0a2e0)
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 "qemu/timer.h"
19 #include "sysemu/runstate.h"
20 #include "hw/sysbus.h"
21 #include "migration/vmstate.h"
22 #include "qemu/log.h"
23 #include "qemu/module.h"
24 #include "hw/registerfields.h"
25 #include "hw/qdev-clock.h"
26 #include "qom/object.h"
27 #include "hw/qdev-properties.h"
28 #include "qapi/error.h"
29 
30 #ifndef ZYNQ_SLCR_ERR_DEBUG
31 #define ZYNQ_SLCR_ERR_DEBUG 0
32 #endif
33 
34 #define DB_PRINT(...) do { \
35         if (ZYNQ_SLCR_ERR_DEBUG) { \
36             fprintf(stderr,  ": %s: ", __func__); \
37             fprintf(stderr, ## __VA_ARGS__); \
38         } \
39     } while (0)
40 
41 #define XILINX_LOCK_KEY 0x767b
42 #define XILINX_UNLOCK_KEY 0xdf0d
43 
44 REG32(SCL, 0x000)
45 REG32(LOCK, 0x004)
46 REG32(UNLOCK, 0x008)
47 REG32(LOCKSTA, 0x00c)
48 
49 REG32(ARM_PLL_CTRL, 0x100)
50 REG32(DDR_PLL_CTRL, 0x104)
51 REG32(IO_PLL_CTRL, 0x108)
52 /* fields for [ARM|DDR|IO]_PLL_CTRL registers */
53     FIELD(xxx_PLL_CTRL, PLL_RESET, 0, 1)
54     FIELD(xxx_PLL_CTRL, PLL_PWRDWN, 1, 1)
55     FIELD(xxx_PLL_CTRL, PLL_BYPASS_QUAL, 3, 1)
56     FIELD(xxx_PLL_CTRL, PLL_BYPASS_FORCE, 4, 1)
57     FIELD(xxx_PLL_CTRL, PLL_FPDIV, 12, 7)
58 REG32(PLL_STATUS, 0x10c)
59 REG32(ARM_PLL_CFG, 0x110)
60 REG32(DDR_PLL_CFG, 0x114)
61 REG32(IO_PLL_CFG, 0x118)
62 
63 REG32(ARM_CLK_CTRL, 0x120)
64 REG32(DDR_CLK_CTRL, 0x124)
65 REG32(DCI_CLK_CTRL, 0x128)
66 REG32(APER_CLK_CTRL, 0x12c)
67 REG32(USB0_CLK_CTRL, 0x130)
68 REG32(USB1_CLK_CTRL, 0x134)
69 REG32(GEM0_RCLK_CTRL, 0x138)
70 REG32(GEM1_RCLK_CTRL, 0x13c)
71 REG32(GEM0_CLK_CTRL, 0x140)
72 REG32(GEM1_CLK_CTRL, 0x144)
73 REG32(SMC_CLK_CTRL, 0x148)
74 REG32(LQSPI_CLK_CTRL, 0x14c)
75 REG32(SDIO_CLK_CTRL, 0x150)
76 REG32(UART_CLK_CTRL, 0x154)
77     FIELD(UART_CLK_CTRL, CLKACT0, 0, 1)
78     FIELD(UART_CLK_CTRL, CLKACT1, 1, 1)
79     FIELD(UART_CLK_CTRL, SRCSEL,  4, 2)
80     FIELD(UART_CLK_CTRL, DIVISOR, 8, 6)
81 REG32(SPI_CLK_CTRL, 0x158)
82 REG32(CAN_CLK_CTRL, 0x15c)
83 REG32(CAN_MIOCLK_CTRL, 0x160)
84 REG32(DBG_CLK_CTRL, 0x164)
85 REG32(PCAP_CLK_CTRL, 0x168)
86 REG32(TOPSW_CLK_CTRL, 0x16c)
87 
88 #define FPGA_CTRL_REGS(n, start) \
89     REG32(FPGA ## n ## _CLK_CTRL, (start)) \
90     REG32(FPGA ## n ## _THR_CTRL, (start) + 0x4)\
91     REG32(FPGA ## n ## _THR_CNT,  (start) + 0x8)\
92     REG32(FPGA ## n ## _THR_STA,  (start) + 0xc)
93 FPGA_CTRL_REGS(0, 0x170)
94 FPGA_CTRL_REGS(1, 0x180)
95 FPGA_CTRL_REGS(2, 0x190)
96 FPGA_CTRL_REGS(3, 0x1a0)
97 
98 REG32(BANDGAP_TRIP, 0x1b8)
99 REG32(PLL_PREDIVISOR, 0x1c0)
100 REG32(CLK_621_TRUE, 0x1c4)
101 
102 REG32(PSS_RST_CTRL, 0x200)
103     FIELD(PSS_RST_CTRL, SOFT_RST, 0, 1)
104 REG32(DDR_RST_CTRL, 0x204)
105 REG32(TOPSW_RESET_CTRL, 0x208)
106 REG32(DMAC_RST_CTRL, 0x20c)
107 REG32(USB_RST_CTRL, 0x210)
108 REG32(GEM_RST_CTRL, 0x214)
109 REG32(SDIO_RST_CTRL, 0x218)
110 REG32(SPI_RST_CTRL, 0x21c)
111 REG32(CAN_RST_CTRL, 0x220)
112 REG32(I2C_RST_CTRL, 0x224)
113 REG32(UART_RST_CTRL, 0x228)
114 REG32(GPIO_RST_CTRL, 0x22c)
115 REG32(LQSPI_RST_CTRL, 0x230)
116 REG32(SMC_RST_CTRL, 0x234)
117 REG32(OCM_RST_CTRL, 0x238)
118 REG32(FPGA_RST_CTRL, 0x240)
119 REG32(A9_CPU_RST_CTRL, 0x244)
120 
121 REG32(RS_AWDT_CTRL, 0x24c)
122 REG32(RST_REASON, 0x250)
123 
124 REG32(REBOOT_STATUS, 0x258)
125 REG32(BOOT_MODE, 0x25c)
126     FIELD(BOOT_MODE, BOOT_MODE, 0, 4)
127 
128 REG32(APU_CTRL, 0x300)
129 REG32(WDT_CLK_SEL, 0x304)
130 
131 REG32(TZ_DMA_NS, 0x440)
132 REG32(TZ_DMA_IRQ_NS, 0x444)
133 REG32(TZ_DMA_PERIPH_NS, 0x448)
134 
135 REG32(PSS_IDCODE, 0x530)
136 
137 REG32(DDR_URGENT, 0x600)
138 REG32(DDR_CAL_START, 0x60c)
139 REG32(DDR_REF_START, 0x614)
140 REG32(DDR_CMD_STA, 0x618)
141 REG32(DDR_URGENT_SEL, 0x61c)
142 REG32(DDR_DFI_STATUS, 0x620)
143 
144 REG32(MIO, 0x700)
145 #define MIO_LENGTH 54
146 
147 REG32(MIO_LOOPBACK, 0x804)
148 REG32(MIO_MST_TRI0, 0x808)
149 REG32(MIO_MST_TRI1, 0x80c)
150 
151 REG32(SD0_WP_CD_SEL, 0x830)
152 REG32(SD1_WP_CD_SEL, 0x834)
153 
154 REG32(LVL_SHFTR_EN, 0x900)
155 REG32(OCM_CFG, 0x910)
156 
157 REG32(CPU_RAM, 0xa00)
158 
159 REG32(IOU, 0xa30)
160 
161 REG32(DMAC_RAM, 0xa50)
162 
163 REG32(AFI0, 0xa60)
164 REG32(AFI1, 0xa6c)
165 REG32(AFI2, 0xa78)
166 REG32(AFI3, 0xa84)
167 #define AFI_LENGTH 3
168 
169 REG32(OCM, 0xa90)
170 
171 REG32(DEVCI_RAM, 0xaa0)
172 
173 REG32(CSG_RAM, 0xab0)
174 
175 REG32(GPIOB_CTRL, 0xb00)
176 REG32(GPIOB_CFG_CMOS18, 0xb04)
177 REG32(GPIOB_CFG_CMOS25, 0xb08)
178 REG32(GPIOB_CFG_CMOS33, 0xb0c)
179 REG32(GPIOB_CFG_HSTL, 0xb14)
180 REG32(GPIOB_DRVR_BIAS_CTRL, 0xb18)
181 
182 REG32(DDRIOB, 0xb40)
183 #define DDRIOB_LENGTH 14
184 
185 #define ZYNQ_SLCR_MMIO_SIZE     0x1000
186 #define ZYNQ_SLCR_NUM_REGS      (ZYNQ_SLCR_MMIO_SIZE / 4)
187 
188 #define TYPE_ZYNQ_SLCR "xilinx-zynq_slcr"
189 OBJECT_DECLARE_SIMPLE_TYPE(ZynqSLCRState, ZYNQ_SLCR)
190 
191 struct ZynqSLCRState {
192     SysBusDevice parent_obj;
193 
194     MemoryRegion iomem;
195 
196     uint32_t regs[ZYNQ_SLCR_NUM_REGS];
197 
198     Clock *ps_clk;
199     Clock *uart0_ref_clk;
200     Clock *uart1_ref_clk;
201     uint8_t boot_mode;
202 };
203 
204 /*
205  * return the output frequency of ARM/DDR/IO pll
206  * using input frequency and PLL_CTRL register
207  */
208 static uint64_t zynq_slcr_compute_pll(uint64_t input, uint32_t ctrl_reg)
209 {
210     uint32_t mult = ((ctrl_reg & R_xxx_PLL_CTRL_PLL_FPDIV_MASK) >>
211             R_xxx_PLL_CTRL_PLL_FPDIV_SHIFT);
212 
213     /* first, check if pll is bypassed */
214     if (ctrl_reg & R_xxx_PLL_CTRL_PLL_BYPASS_FORCE_MASK) {
215         return input;
216     }
217 
218     /* is pll disabled ? */
219     if (ctrl_reg & (R_xxx_PLL_CTRL_PLL_RESET_MASK |
220                     R_xxx_PLL_CTRL_PLL_PWRDWN_MASK)) {
221         return 0;
222     }
223 
224     /* Consider zero feedback as maximum divide ratio possible */
225     if (!mult) {
226         mult = 1 << R_xxx_PLL_CTRL_PLL_FPDIV_LENGTH;
227     }
228 
229     /* frequency multiplier -> period division */
230     return input / mult;
231 }
232 
233 /*
234  * return the output period of a clock given:
235  * + the periods in an array corresponding to input mux selector
236  * + the register xxx_CLK_CTRL value
237  * + enable bit index in ctrl register
238  *
239  * This function makes the assumption that the ctrl_reg value is organized as
240  * follows:
241  * + bits[13:8]  clock frequency divisor
242  * + bits[5:4]   clock mux selector (index in array)
243  * + bits[index] clock enable
244  */
245 static uint64_t zynq_slcr_compute_clock(const uint64_t periods[],
246                                         uint32_t ctrl_reg,
247                                         unsigned index)
248 {
249     uint32_t srcsel = extract32(ctrl_reg, 4, 2); /* bits [5:4] */
250     uint32_t divisor = extract32(ctrl_reg, 8, 6); /* bits [13:8] */
251 
252     /* first, check if clock is disabled */
253     if (((ctrl_reg >> index) & 1u) == 0) {
254         return 0;
255     }
256 
257     /*
258      * according to the Zynq technical ref. manual UG585 v1.12.2 in
259      * Clocks chapter, section 25.10.1 page 705:
260      * "The 6-bit divider provides a divide range of 1 to 63"
261      * We follow here what is implemented in linux kernel and consider
262      * the 0 value as a bypass (no division).
263      */
264     /* frequency divisor -> period multiplication */
265     return periods[srcsel] * (divisor ? divisor : 1u);
266 }
267 
268 /*
269  * macro helper around zynq_slcr_compute_clock to avoid repeating
270  * the register name.
271  */
272 #define ZYNQ_COMPUTE_CLK(state, plls, reg, enable_field) \
273     zynq_slcr_compute_clock((plls), (state)->regs[reg], \
274                             reg ## _ ## enable_field ## _SHIFT)
275 
276 static void zynq_slcr_compute_clocks_internal(ZynqSLCRState *s, uint64_t ps_clk)
277 {
278     uint64_t io_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_IO_PLL_CTRL]);
279     uint64_t arm_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_ARM_PLL_CTRL]);
280     uint64_t ddr_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_DDR_PLL_CTRL]);
281 
282     uint64_t uart_mux[4] = {io_pll, io_pll, arm_pll, ddr_pll};
283 
284     /* compute uartX reference clocks */
285     clock_set(s->uart0_ref_clk,
286               ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT0));
287     clock_set(s->uart1_ref_clk,
288               ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT1));
289 }
290 
291 /**
292  * Compute and set the outputs clocks periods.
293  * But do not propagate them further. Connected clocks
294  * will not receive any updates (See zynq_slcr_compute_clocks())
295  */
296 static void zynq_slcr_compute_clocks(ZynqSLCRState *s)
297 {
298     uint64_t ps_clk = clock_get(s->ps_clk);
299 
300     /* consider outputs clocks are disabled while in reset */
301     if (device_is_in_reset(DEVICE(s))) {
302         ps_clk = 0;
303     }
304 
305     zynq_slcr_compute_clocks_internal(s, ps_clk);
306 }
307 
308 /**
309  * Propagate the outputs clocks.
310  * zynq_slcr_compute_clocks() should have been called before
311  * to configure them.
312  */
313 static void zynq_slcr_propagate_clocks(ZynqSLCRState *s)
314 {
315     clock_propagate(s->uart0_ref_clk);
316     clock_propagate(s->uart1_ref_clk);
317 }
318 
319 static void zynq_slcr_ps_clk_callback(void *opaque, ClockEvent event)
320 {
321     ZynqSLCRState *s = (ZynqSLCRState *) opaque;
322 
323     zynq_slcr_compute_clocks(s);
324     zynq_slcr_propagate_clocks(s);
325 }
326 
327 static void zynq_slcr_reset_init(Object *obj, ResetType type)
328 {
329     ZynqSLCRState *s = ZYNQ_SLCR(obj);
330     int i;
331 
332     DB_PRINT("RESET\n");
333 
334     s->regs[R_LOCKSTA] = 1;
335     /* 0x100 - 0x11C */
336     s->regs[R_ARM_PLL_CTRL]   = 0x0001A008;
337     s->regs[R_DDR_PLL_CTRL]   = 0x0001A008;
338     s->regs[R_IO_PLL_CTRL]    = 0x0001A008;
339     s->regs[R_PLL_STATUS]     = 0x0000003F;
340     s->regs[R_ARM_PLL_CFG]    = 0x00014000;
341     s->regs[R_DDR_PLL_CFG]    = 0x00014000;
342     s->regs[R_IO_PLL_CFG]     = 0x00014000;
343 
344     /* 0x120 - 0x16C */
345     s->regs[R_ARM_CLK_CTRL]   = 0x1F000400;
346     s->regs[R_DDR_CLK_CTRL]   = 0x18400003;
347     s->regs[R_DCI_CLK_CTRL]   = 0x01E03201;
348     s->regs[R_APER_CLK_CTRL]  = 0x01FFCCCD;
349     s->regs[R_USB0_CLK_CTRL]  = s->regs[R_USB1_CLK_CTRL]  = 0x00101941;
350     s->regs[R_GEM0_RCLK_CTRL] = s->regs[R_GEM1_RCLK_CTRL] = 0x00000001;
351     s->regs[R_GEM0_CLK_CTRL]  = s->regs[R_GEM1_CLK_CTRL]  = 0x00003C01;
352     s->regs[R_SMC_CLK_CTRL]   = 0x00003C01;
353     s->regs[R_LQSPI_CLK_CTRL] = 0x00002821;
354     s->regs[R_SDIO_CLK_CTRL]  = 0x00001E03;
355     s->regs[R_UART_CLK_CTRL]  = 0x00003F03;
356     s->regs[R_SPI_CLK_CTRL]   = 0x00003F03;
357     s->regs[R_CAN_CLK_CTRL]   = 0x00501903;
358     s->regs[R_DBG_CLK_CTRL]   = 0x00000F03;
359     s->regs[R_PCAP_CLK_CTRL]  = 0x00000F01;
360 
361     /* 0x170 - 0x1AC */
362     s->regs[R_FPGA0_CLK_CTRL] = s->regs[R_FPGA1_CLK_CTRL]
363                               = s->regs[R_FPGA2_CLK_CTRL]
364                               = s->regs[R_FPGA3_CLK_CTRL] = 0x00101800;
365     s->regs[R_FPGA0_THR_STA] = s->regs[R_FPGA1_THR_STA]
366                              = s->regs[R_FPGA2_THR_STA]
367                              = s->regs[R_FPGA3_THR_STA] = 0x00010000;
368 
369     /* 0x1B0 - 0x1D8 */
370     s->regs[R_BANDGAP_TRIP]   = 0x0000001F;
371     s->regs[R_PLL_PREDIVISOR] = 0x00000001;
372     s->regs[R_CLK_621_TRUE]   = 0x00000001;
373 
374     /* 0x200 - 0x25C */
375     s->regs[R_FPGA_RST_CTRL]  = 0x01F33F0F;
376     s->regs[R_RST_REASON]     = 0x00000040;
377 
378     s->regs[R_BOOT_MODE]      = s->boot_mode & R_BOOT_MODE_BOOT_MODE_MASK;
379 
380     /* 0x700 - 0x7D4 */
381     for (i = 0; i < 54; i++) {
382         s->regs[R_MIO + i] = 0x00001601;
383     }
384     for (i = 2; i <= 8; i++) {
385         s->regs[R_MIO + i] = 0x00000601;
386     }
387 
388     s->regs[R_MIO_MST_TRI0] = s->regs[R_MIO_MST_TRI1] = 0xFFFFFFFF;
389 
390     s->regs[R_CPU_RAM + 0] = s->regs[R_CPU_RAM + 1] = s->regs[R_CPU_RAM + 3]
391                            = s->regs[R_CPU_RAM + 4] = s->regs[R_CPU_RAM + 7]
392                            = 0x00010101;
393     s->regs[R_CPU_RAM + 2] = s->regs[R_CPU_RAM + 5] = 0x01010101;
394     s->regs[R_CPU_RAM + 6] = 0x00000001;
395 
396     s->regs[R_IOU + 0] = s->regs[R_IOU + 1] = s->regs[R_IOU + 2]
397                        = s->regs[R_IOU + 3] = 0x09090909;
398     s->regs[R_IOU + 4] = s->regs[R_IOU + 5] = 0x00090909;
399     s->regs[R_IOU + 6] = 0x00000909;
400 
401     s->regs[R_DMAC_RAM] = 0x00000009;
402 
403     s->regs[R_AFI0 + 0] = s->regs[R_AFI0 + 1] = 0x09090909;
404     s->regs[R_AFI1 + 0] = s->regs[R_AFI1 + 1] = 0x09090909;
405     s->regs[R_AFI2 + 0] = s->regs[R_AFI2 + 1] = 0x09090909;
406     s->regs[R_AFI3 + 0] = s->regs[R_AFI3 + 1] = 0x09090909;
407     s->regs[R_AFI0 + 2] = s->regs[R_AFI1 + 2] = s->regs[R_AFI2 + 2]
408                         = s->regs[R_AFI3 + 2] = 0x00000909;
409 
410     s->regs[R_OCM + 0] = 0x01010101;
411     s->regs[R_OCM + 1] = s->regs[R_OCM + 2] = 0x09090909;
412 
413     s->regs[R_DEVCI_RAM] = 0x00000909;
414     s->regs[R_CSG_RAM]   = 0x00000001;
415 
416     s->regs[R_DDRIOB + 0] = s->regs[R_DDRIOB + 1] = s->regs[R_DDRIOB + 2]
417                           = s->regs[R_DDRIOB + 3] = 0x00000e00;
418     s->regs[R_DDRIOB + 4] = s->regs[R_DDRIOB + 5] = s->regs[R_DDRIOB + 6]
419                           = 0x00000e00;
420     s->regs[R_DDRIOB + 12] = 0x00000021;
421 }
422 
423 static void zynq_slcr_reset_hold(Object *obj, ResetType type)
424 {
425     ZynqSLCRState *s = ZYNQ_SLCR(obj);
426 
427     /* will disable all output clocks */
428     zynq_slcr_compute_clocks_internal(s, 0);
429     zynq_slcr_propagate_clocks(s);
430 }
431 
432 static void zynq_slcr_reset_exit(Object *obj, ResetType type)
433 {
434     ZynqSLCRState *s = ZYNQ_SLCR(obj);
435 
436     /* will compute output clocks according to ps_clk and registers */
437     zynq_slcr_compute_clocks_internal(s, clock_get(s->ps_clk));
438     zynq_slcr_propagate_clocks(s);
439 }
440 
441 static bool zynq_slcr_check_offset(hwaddr offset, bool rnw)
442 {
443     switch (offset) {
444     case R_LOCK:
445     case R_UNLOCK:
446     case R_DDR_CAL_START:
447     case R_DDR_REF_START:
448         return !rnw; /* Write only */
449     case R_LOCKSTA:
450     case R_FPGA0_THR_STA:
451     case R_FPGA1_THR_STA:
452     case R_FPGA2_THR_STA:
453     case R_FPGA3_THR_STA:
454     case R_BOOT_MODE:
455     case R_PSS_IDCODE:
456     case R_DDR_CMD_STA:
457     case R_DDR_DFI_STATUS:
458     case R_PLL_STATUS:
459         return rnw;/* read only */
460     case R_SCL:
461     case R_ARM_PLL_CTRL ... R_IO_PLL_CTRL:
462     case R_ARM_PLL_CFG ... R_IO_PLL_CFG:
463     case R_ARM_CLK_CTRL ... R_TOPSW_CLK_CTRL:
464     case R_FPGA0_CLK_CTRL ... R_FPGA0_THR_CNT:
465     case R_FPGA1_CLK_CTRL ... R_FPGA1_THR_CNT:
466     case R_FPGA2_CLK_CTRL ... R_FPGA2_THR_CNT:
467     case R_FPGA3_CLK_CTRL ... R_FPGA3_THR_CNT:
468     case R_BANDGAP_TRIP:
469     case R_PLL_PREDIVISOR:
470     case R_CLK_621_TRUE:
471     case R_PSS_RST_CTRL ... R_A9_CPU_RST_CTRL:
472     case R_RS_AWDT_CTRL:
473     case R_RST_REASON:
474     case R_REBOOT_STATUS:
475     case R_APU_CTRL:
476     case R_WDT_CLK_SEL:
477     case R_TZ_DMA_NS ... R_TZ_DMA_PERIPH_NS:
478     case R_DDR_URGENT:
479     case R_DDR_URGENT_SEL:
480     case R_MIO ... R_MIO + MIO_LENGTH - 1:
481     case R_MIO_LOOPBACK ... R_MIO_MST_TRI1:
482     case R_SD0_WP_CD_SEL:
483     case R_SD1_WP_CD_SEL:
484     case R_LVL_SHFTR_EN:
485     case R_OCM_CFG:
486     case R_CPU_RAM:
487     case R_IOU:
488     case R_DMAC_RAM:
489     case R_AFI0 ... R_AFI3 + AFI_LENGTH - 1:
490     case R_OCM:
491     case R_DEVCI_RAM:
492     case R_CSG_RAM:
493     case R_GPIOB_CTRL ... R_GPIOB_CFG_CMOS33:
494     case R_GPIOB_CFG_HSTL:
495     case R_GPIOB_DRVR_BIAS_CTRL:
496     case R_DDRIOB ... R_DDRIOB + DDRIOB_LENGTH - 1:
497         return true;
498     default:
499         return false;
500     }
501 }
502 
503 static uint64_t zynq_slcr_read(void *opaque, hwaddr offset,
504     unsigned size)
505 {
506     ZynqSLCRState *s = opaque;
507     offset /= 4;
508     uint32_t ret = s->regs[offset];
509 
510     if (!zynq_slcr_check_offset(offset, true)) {
511         qemu_log_mask(LOG_GUEST_ERROR, "zynq_slcr: Invalid read access to "
512                       " addr %" HWADDR_PRIx "\n", offset * 4);
513     }
514 
515     DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n", offset * 4, ret);
516     return ret;
517 }
518 
519 static void zynq_slcr_write(void *opaque, hwaddr offset,
520                           uint64_t val, unsigned size)
521 {
522     ZynqSLCRState *s = (ZynqSLCRState *)opaque;
523     offset /= 4;
524 
525     DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx64 "\n", offset * 4, val);
526 
527     if (!zynq_slcr_check_offset(offset, false)) {
528         qemu_log_mask(LOG_GUEST_ERROR, "zynq_slcr: Invalid write access to "
529                       "addr %" HWADDR_PRIx "\n", offset * 4);
530         return;
531     }
532 
533     switch (offset) {
534     case R_SCL:
535         s->regs[R_SCL] = val & 0x1;
536         return;
537     case R_LOCK:
538         if ((val & 0xFFFF) == XILINX_LOCK_KEY) {
539             DB_PRINT("XILINX LOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
540                 (unsigned)val & 0xFFFF);
541             s->regs[R_LOCKSTA] = 1;
542         } else {
543             DB_PRINT("WRONG XILINX LOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
544                 (int)offset, (unsigned)val & 0xFFFF);
545         }
546         return;
547     case R_UNLOCK:
548         if ((val & 0xFFFF) == XILINX_UNLOCK_KEY) {
549             DB_PRINT("XILINX UNLOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
550                 (unsigned)val & 0xFFFF);
551             s->regs[R_LOCKSTA] = 0;
552         } else {
553             DB_PRINT("WRONG XILINX UNLOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
554                 (int)offset, (unsigned)val & 0xFFFF);
555         }
556         return;
557     }
558 
559     if (s->regs[R_LOCKSTA]) {
560         qemu_log_mask(LOG_GUEST_ERROR,
561                       "SCLR registers are locked. Unlock them first\n");
562         return;
563     }
564     s->regs[offset] = val;
565 
566     switch (offset) {
567     case R_PSS_RST_CTRL:
568         if (FIELD_EX32(val, PSS_RST_CTRL, SOFT_RST)) {
569             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
570         }
571         break;
572     case R_IO_PLL_CTRL:
573     case R_ARM_PLL_CTRL:
574     case R_DDR_PLL_CTRL:
575     case R_UART_CLK_CTRL:
576         zynq_slcr_compute_clocks(s);
577         zynq_slcr_propagate_clocks(s);
578         break;
579     }
580 }
581 
582 static const MemoryRegionOps slcr_ops = {
583     .read = zynq_slcr_read,
584     .write = zynq_slcr_write,
585     .endianness = DEVICE_NATIVE_ENDIAN,
586 };
587 
588 static const ClockPortInitArray zynq_slcr_clocks = {
589     QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback, ClockUpdate),
590     QDEV_CLOCK_OUT(ZynqSLCRState, uart0_ref_clk),
591     QDEV_CLOCK_OUT(ZynqSLCRState, uart1_ref_clk),
592     QDEV_CLOCK_END
593 };
594 
595 static void zynq_slcr_realize(DeviceState *dev, Error **errp)
596 {
597     ZynqSLCRState *s = ZYNQ_SLCR(dev);
598 
599     if (s->boot_mode > 0xF) {
600         error_setg(errp, "Invalid boot mode %d specified", s->boot_mode);
601     }
602 }
603 
604 static void zynq_slcr_init(Object *obj)
605 {
606     ZynqSLCRState *s = ZYNQ_SLCR(obj);
607 
608     memory_region_init_io(&s->iomem, obj, &slcr_ops, s, "slcr",
609                           ZYNQ_SLCR_MMIO_SIZE);
610     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
611 
612     qdev_init_clocks(DEVICE(obj), zynq_slcr_clocks);
613 }
614 
615 static const VMStateDescription vmstate_zynq_slcr = {
616     .name = "zynq_slcr",
617     .version_id = 3,
618     .minimum_version_id = 2,
619     .fields = (const VMStateField[]) {
620         VMSTATE_UINT32_ARRAY(regs, ZynqSLCRState, ZYNQ_SLCR_NUM_REGS),
621         VMSTATE_CLOCK_V(ps_clk, ZynqSLCRState, 3),
622         VMSTATE_END_OF_LIST()
623     }
624 };
625 
626 static Property zynq_slcr_props[] = {
627     DEFINE_PROP_UINT8("boot-mode", ZynqSLCRState, boot_mode, 1),
628     DEFINE_PROP_END_OF_LIST(),
629 };
630 
631 static void zynq_slcr_class_init(ObjectClass *klass, void *data)
632 {
633     DeviceClass *dc = DEVICE_CLASS(klass);
634     ResettableClass *rc = RESETTABLE_CLASS(klass);
635 
636     dc->vmsd = &vmstate_zynq_slcr;
637     dc->realize = zynq_slcr_realize;
638     rc->phases.enter = zynq_slcr_reset_init;
639     rc->phases.hold  = zynq_slcr_reset_hold;
640     rc->phases.exit  = zynq_slcr_reset_exit;
641     device_class_set_props(dc, zynq_slcr_props);
642 }
643 
644 static const TypeInfo zynq_slcr_info = {
645     .class_init = zynq_slcr_class_init,
646     .name  = TYPE_ZYNQ_SLCR,
647     .parent = TYPE_SYS_BUS_DEVICE,
648     .instance_size  = sizeof(ZynqSLCRState),
649     .instance_init = zynq_slcr_init,
650 };
651 
652 static void zynq_slcr_register_types(void)
653 {
654     type_register_static(&zynq_slcr_info);
655 }
656 
657 type_init(zynq_slcr_register_types)
658