1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "qemu/osdep.h"
28#include "hw/sysbus.h"
29#include "hw/register.h"
30#include "qemu/bitops.h"
31#include "qemu/log.h"
32#include "migration/vmstate.h"
33#include "hw/qdev-properties.h"
34
35#ifndef XILINX_CPM_PCSR_ERR_DEBUG
36#define XILINX_CPM_PCSR_ERR_DEBUG 0
37#endif
38
39#define TYPE_XILINX_CPM_PCSR "xlnx.versal_cpm_pcsr"
40
41#define XILINX_CPM_PCSR(obj) \
42 OBJECT_CHECK(CPM_PCSR, (obj), TYPE_XILINX_CPM_PCSR)
43
44REG32(MASK, 0x0)
45 FIELD(MASK, TEST_SAFE_WEN, 20, 1)
46 FIELD(MASK, SLVERREN_WEN, 19, 1)
47 FIELD(MASK, MEM_CLEAR_TRIGGER_WEN, 18, 1)
48 FIELD(MASK, SYS_RST_MASK3_WEN, 17, 1)
49 FIELD(MASK, SYS_RST_MASK2_WEN, 16, 1)
50 FIELD(MASK, SYS_RST_MASK1_WEN, 15, 1)
51 FIELD(MASK, PWRDN_WEN, 14, 1)
52 FIELD(MASK, DISNPICLK_WEN, 13, 1)
53 FIELD(MASK, APBEN_WEN, 12, 1)
54 FIELD(MASK, SCAN_CLEAR_TRIGGER_WEN, 11, 1)
55 FIELD(MASK, STARTCAL_WEN, 10, 1)
56 FIELD(MASK, FABRICEN_WEN, 9, 1)
57 FIELD(MASK, TRISTATE_WEN, 8, 1)
58 FIELD(MASK, HOLDSTATE_WEN, 7, 1)
59 FIELD(MASK, INITSTATE_WEN, 6, 1)
60 FIELD(MASK, ODISABLE3_WEN, 5, 1)
61 FIELD(MASK, ODISABLE2_WEN, 4, 1)
62 FIELD(MASK, ODISABLE1_WEN, 3, 1)
63 FIELD(MASK, ODISABLE0_WEN, 2, 1)
64 FIELD(MASK, GATEREG_WEN, 1, 1)
65 FIELD(MASK, PCOMPLETE_WEN, 0, 1)
66REG32(PCR, 0x4)
67 FIELD(PCR, TEST_SAFE, 20, 1)
68 FIELD(PCR, SLVERREN, 19, 1)
69 FIELD(PCR, MEM_CLEAR_TRIGGER, 18, 1)
70 FIELD(PCR, SYS_RST_MASK3, 17, 1)
71 FIELD(PCR, SYS_RST_MASK2, 16, 1)
72 FIELD(PCR, SYS_RST_MASK1, 15, 1)
73 FIELD(PCR, PWRDN, 14, 1)
74 FIELD(PCR, DISNPICLK, 13, 1)
75 FIELD(PCR, APBEN, 12, 1)
76 FIELD(PCR, SCAN_CLEAR_TRIGGER, 11, 1)
77 FIELD(PCR, STARTCAL, 10, 1)
78 FIELD(PCR, FABRICEN, 9, 1)
79 FIELD(PCR, TRISTATE, 8, 1)
80 FIELD(PCR, HOLDSTATE, 7, 1)
81 FIELD(PCR, INITSTATE, 6, 1)
82 FIELD(PCR, ODISABLE3, 5, 1)
83 FIELD(PCR, ODISABLE2, 4, 1)
84 FIELD(PCR, ODISABLE1, 3, 1)
85 FIELD(PCR, ODISABLE0, 2, 1)
86 FIELD(PCR, GATEREG, 1, 1)
87 FIELD(PCR, PCOMPLETE, 0, 1)
88REG32(PSR, 0x8)
89 FIELD(PSR, HARD_FAIL_AND, 11, 3)
90 FIELD(PSR, HARD_FAIL_OR, 8, 3)
91 FIELD(PSR, MEM_CLEAR_PASS, 7, 1)
92 FIELD(PSR, MEM_CLEAR_DONE, 6, 1)
93 FIELD(PSR, CALERROR, 5, 1)
94 FIELD(PSR, CALDONE, 4, 1)
95 FIELD(PSR, INCAL, 3, 1)
96 FIELD(PSR, SCAN_CLEAR_PASS, 2, 1)
97 FIELD(PSR, SCAN_CLEAR_DONE, 1, 1)
98 FIELD(PSR, PCSRLOCK, 0, 1)
99REG32(LOCK, 0xc)
100
101#define CPM_PCSR_R_MAX (R_LOCK + 1)
102
103typedef struct CPM_PCSR {
104 SysBusDevice parent_obj;
105 MemoryRegion iomem;
106
107 uint32_t regs[CPM_PCSR_R_MAX];
108 RegisterInfo regs_info[CPM_PCSR_R_MAX];
109} CPM_PCSR;
110
111static void cpm_pcsr_lock_postw(RegisterInfo *reg, uint64_t val)
112{
113 CPM_PCSR *s = reg->opaque;
114
115 if (val == 0xf9e8d7c6) {
116 s->regs[R_PSR] &= ~R_PSR_PCSRLOCK_MASK;
117 } else if (val == 1) {
118 s->regs[R_PSR] |= R_PSR_PCSRLOCK_MASK;
119 }
120}
121
122static const RegisterAccessInfo cpm_pcsr_regs_info[] = {
123 { .name = "MASK", .addr = A_MASK,
124 .reset = 0x1fe,
125 .rsvd = 0xffe00000,
126 },{ .name = "PCR", .addr = A_PCR,
127 .reset = 0x1fe,
128 .rsvd = 0xffe00000,
129 },{ .name = "PSR", .addr = A_PSR,
130 .reset = R_PSR_PCSRLOCK_MASK |
131 R_PSR_SCAN_CLEAR_DONE_MASK |
132 R_PSR_SCAN_CLEAR_PASS_MASK |
133 R_PSR_CALDONE_MASK |
134 R_PSR_MEM_CLEAR_DONE_MASK |
135 R_PSR_MEM_CLEAR_PASS_MASK,
136 .rsvd = 0xffffc000,
137 .ro = 0xffffffff,
138 },{ .name = "LOCK", .addr = A_LOCK,
139 .reset = 0x1,
140 .post_write = cpm_pcsr_lock_postw,
141 }
142};
143
144static void cpm_pcsr_reset(DeviceState *dev)
145{
146 CPM_PCSR *s = XILINX_CPM_PCSR(dev);
147 unsigned int i;
148
149 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
150 register_reset(&s->regs_info[i]);
151 }
152
153}
154
155static const MemoryRegionOps cpm_pcsr_ops = {
156 .read = register_read_memory,
157 .write = register_write_memory,
158 .endianness = DEVICE_LITTLE_ENDIAN,
159 .valid = {
160 .min_access_size = 4,
161 .max_access_size = 4,
162 },
163};
164
165static void cpm_pcsr_realize(DeviceState *dev, Error **errp)
166{
167
168}
169
170static void cpm_pcsr_init(Object *obj)
171{
172 CPM_PCSR *s = XILINX_CPM_PCSR(obj);
173 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
174 RegisterInfoArray *reg_array;
175
176 memory_region_init(&s->iomem, obj, TYPE_XILINX_CPM_PCSR, CPM_PCSR_R_MAX * 4);
177 reg_array =
178 register_init_block32(DEVICE(obj), cpm_pcsr_regs_info,
179 ARRAY_SIZE(cpm_pcsr_regs_info),
180 s->regs_info, s->regs,
181 &cpm_pcsr_ops,
182 XILINX_CPM_PCSR_ERR_DEBUG,
183 CPM_PCSR_R_MAX * 4);
184 memory_region_add_subregion(&s->iomem,
185 0x0,
186 ®_array->mem);
187 sysbus_init_mmio(sbd, &s->iomem);
188}
189
190static const VMStateDescription vmstate_cpm_pcsr = {
191 .name = TYPE_XILINX_CPM_PCSR,
192 .version_id = 1,
193 .minimum_version_id = 1,
194 .fields = (VMStateField[]) {
195 VMSTATE_UINT32_ARRAY(regs, CPM_PCSR, CPM_PCSR_R_MAX),
196 VMSTATE_END_OF_LIST(),
197 }
198};
199
200static void cpm_pcsr_class_init(ObjectClass *klass, void *data)
201{
202 DeviceClass *dc = DEVICE_CLASS(klass);
203
204 dc->reset = cpm_pcsr_reset;
205 dc->realize = cpm_pcsr_realize;
206 dc->vmsd = &vmstate_cpm_pcsr;
207}
208
209static const TypeInfo cpm_pcsr_info = {
210 .name = TYPE_XILINX_CPM_PCSR,
211 .parent = TYPE_SYS_BUS_DEVICE,
212 .instance_size = sizeof(CPM_PCSR),
213 .class_init = cpm_pcsr_class_init,
214 .instance_init = cpm_pcsr_init,
215};
216
217static void cpm_pcsr_register_types(void)
218{
219 type_register_static(&cpm_pcsr_info);
220}
221
222type_init(cpm_pcsr_register_types)
223