1 /*
2  * QEMU model of the Configuration Frame Control module
3  *
4  * Copyright (C) 2023, Advanced Micro Devices, Inc.
5  *
6  * Written by Francisco Iglesias <francisco.iglesias@amd.com>
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  *
10  * References:
11  * [1] Versal ACAP Technical Reference Manual,
12  *     https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
13  *
14  * [2] Versal ACAP Register Reference,
15  *     https://docs.xilinx.com/r/en-US/am012-versal-register-reference/CFRAME_REG-Module
16  */
17 #ifndef HW_MISC_XLNX_VERSAL_CFRAME_REG_H
18 #define HW_MISC_XLNX_VERSAL_CFRAME_REG_H
19 
20 #include "hw/sysbus.h"
21 #include "hw/register.h"
22 #include "hw/misc/xlnx-cfi-if.h"
23 #include "hw/misc/xlnx-versal-cfu.h"
24 #include "qemu/fifo32.h"
25 
26 #define TYPE_XLNX_VERSAL_CFRAME_REG "xlnx-cframe-reg"
27 OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFrameReg, XLNX_VERSAL_CFRAME_REG)
28 
29 #define TYPE_XLNX_VERSAL_CFRAME_BCAST_REG "xlnx.cframe-bcast-reg"
30 OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFrameBcastReg,
31                            XLNX_VERSAL_CFRAME_BCAST_REG)
32 
33 /*
34  * The registers in this module are 128 bits wide but it is ok to write
35  * and read them through 4 sequential 32 bit accesses (address[3:2] = 0,
36  * 1, 2, 3).
37  */
38 REG32(CRC0, 0x0)
39     FIELD(CRC, CRC, 0, 32)
40 REG32(CRC1, 0x4)
41 REG32(CRC2, 0x8)
42 REG32(CRC3, 0xc)
43 REG32(FAR0, 0x10)
44     FIELD(FAR0, SEGMENT, 23, 2)
45     FIELD(FAR0, BLOCKTYPE, 20, 3)
46     FIELD(FAR0, FRAME_ADDR, 0, 20)
47 REG32(FAR1, 0x14)
48 REG32(FAR2, 0x18)
49 REG32(FAR3, 0x1c)
50 REG32(FAR_SFR0, 0x20)
51     FIELD(FAR_SFR0, BLOCKTYPE, 20, 3)
52     FIELD(FAR_SFR0, FRAME_ADDR, 0, 20)
53 REG32(FAR_SFR1, 0x24)
54 REG32(FAR_SFR2, 0x28)
55 REG32(FAR_SFR3, 0x2c)
56 REG32(FDRI0, 0x40)
57 REG32(FDRI1, 0x44)
58 REG32(FDRI2, 0x48)
59 REG32(FDRI3, 0x4c)
60 REG32(FRCNT0, 0x50)
61     FIELD(FRCNT0, FRCNT, 0, 32)
62 REG32(FRCNT1, 0x54)
63 REG32(FRCNT2, 0x58)
64 REG32(FRCNT3, 0x5c)
65 REG32(CMD0, 0x60)
66     FIELD(CMD0, CMD, 0, 5)
67 REG32(CMD1, 0x64)
68 REG32(CMD2, 0x68)
69 REG32(CMD3, 0x6c)
70 REG32(CR_MASK0, 0x70)
71 REG32(CR_MASK1, 0x74)
72 REG32(CR_MASK2, 0x78)
73 REG32(CR_MASK3, 0x7c)
74 REG32(CTL0, 0x80)
75     FIELD(CTL, PER_FRAME_CRC, 0, 1)
76 REG32(CTL1, 0x84)
77 REG32(CTL2, 0x88)
78 REG32(CTL3, 0x8c)
79 REG32(CFRM_ISR0, 0x150)
80     FIELD(CFRM_ISR0, READ_BROADCAST_ERROR, 21, 1)
81     FIELD(CFRM_ISR0, CMD_MISSING_ERROR, 20, 1)
82     FIELD(CFRM_ISR0, RW_ROWOFF_ERROR, 19, 1)
83     FIELD(CFRM_ISR0, READ_REG_ADDR_ERROR, 18, 1)
84     FIELD(CFRM_ISR0, READ_BLK_TYPE_ERROR, 17, 1)
85     FIELD(CFRM_ISR0, READ_FRAME_ADDR_ERROR, 16, 1)
86     FIELD(CFRM_ISR0, WRITE_REG_ADDR_ERROR, 15, 1)
87     FIELD(CFRM_ISR0, WRITE_BLK_TYPE_ERROR, 13, 1)
88     FIELD(CFRM_ISR0, WRITE_FRAME_ADDR_ERROR, 12, 1)
89     FIELD(CFRM_ISR0, MFW_OVERRUN_ERROR, 11, 1)
90     FIELD(CFRM_ISR0, FAR_FIFO_UNDERFLOW, 10, 1)
91     FIELD(CFRM_ISR0, FAR_FIFO_OVERFLOW, 9, 1)
92     FIELD(CFRM_ISR0, PER_FRAME_SEQ_ERROR, 8, 1)
93     FIELD(CFRM_ISR0, CRC_ERROR, 7, 1)
94     FIELD(CFRM_ISR0, WRITE_OVERRUN_ERROR, 6, 1)
95     FIELD(CFRM_ISR0, READ_OVERRUN_ERROR, 5, 1)
96     FIELD(CFRM_ISR0, CMD_INTERRUPT_ERROR, 4, 1)
97     FIELD(CFRM_ISR0, WRITE_INTERRUPT_ERROR, 3, 1)
98     FIELD(CFRM_ISR0, READ_INTERRUPT_ERROR, 2, 1)
99     FIELD(CFRM_ISR0, SEU_CRC_ERROR, 1, 1)
100     FIELD(CFRM_ISR0, SEU_ECC_ERROR, 0, 1)
101 REG32(CFRM_ISR1, 0x154)
102 REG32(CFRM_ISR2, 0x158)
103 REG32(CFRM_ISR3, 0x15c)
104 REG32(CFRM_IMR0, 0x160)
105     FIELD(CFRM_IMR0, READ_BROADCAST_ERROR, 21, 1)
106     FIELD(CFRM_IMR0, CMD_MISSING_ERROR, 20, 1)
107     FIELD(CFRM_IMR0, RW_ROWOFF_ERROR, 19, 1)
108     FIELD(CFRM_IMR0, READ_REG_ADDR_ERROR, 18, 1)
109     FIELD(CFRM_IMR0, READ_BLK_TYPE_ERROR, 17, 1)
110     FIELD(CFRM_IMR0, READ_FRAME_ADDR_ERROR, 16, 1)
111     FIELD(CFRM_IMR0, WRITE_REG_ADDR_ERROR, 15, 1)
112     FIELD(CFRM_IMR0, WRITE_BLK_TYPE_ERROR, 13, 1)
113     FIELD(CFRM_IMR0, WRITE_FRAME_ADDR_ERROR, 12, 1)
114     FIELD(CFRM_IMR0, MFW_OVERRUN_ERROR, 11, 1)
115     FIELD(CFRM_IMR0, FAR_FIFO_UNDERFLOW, 10, 1)
116     FIELD(CFRM_IMR0, FAR_FIFO_OVERFLOW, 9, 1)
117     FIELD(CFRM_IMR0, PER_FRAME_SEQ_ERROR, 8, 1)
118     FIELD(CFRM_IMR0, CRC_ERROR, 7, 1)
119     FIELD(CFRM_IMR0, WRITE_OVERRUN_ERROR, 6, 1)
120     FIELD(CFRM_IMR0, READ_OVERRUN_ERROR, 5, 1)
121     FIELD(CFRM_IMR0, CMD_INTERRUPT_ERROR, 4, 1)
122     FIELD(CFRM_IMR0, WRITE_INTERRUPT_ERROR, 3, 1)
123     FIELD(CFRM_IMR0, READ_INTERRUPT_ERROR, 2, 1)
124     FIELD(CFRM_IMR0, SEU_CRC_ERROR, 1, 1)
125     FIELD(CFRM_IMR0, SEU_ECC_ERROR, 0, 1)
126 REG32(CFRM_IMR1, 0x164)
127 REG32(CFRM_IMR2, 0x168)
128 REG32(CFRM_IMR3, 0x16c)
129 REG32(CFRM_IER0, 0x170)
130     FIELD(CFRM_IER0, READ_BROADCAST_ERROR, 21, 1)
131     FIELD(CFRM_IER0, CMD_MISSING_ERROR, 20, 1)
132     FIELD(CFRM_IER0, RW_ROWOFF_ERROR, 19, 1)
133     FIELD(CFRM_IER0, READ_REG_ADDR_ERROR, 18, 1)
134     FIELD(CFRM_IER0, READ_BLK_TYPE_ERROR, 17, 1)
135     FIELD(CFRM_IER0, READ_FRAME_ADDR_ERROR, 16, 1)
136     FIELD(CFRM_IER0, WRITE_REG_ADDR_ERROR, 15, 1)
137     FIELD(CFRM_IER0, WRITE_BLK_TYPE_ERROR, 13, 1)
138     FIELD(CFRM_IER0, WRITE_FRAME_ADDR_ERROR, 12, 1)
139     FIELD(CFRM_IER0, MFW_OVERRUN_ERROR, 11, 1)
140     FIELD(CFRM_IER0, FAR_FIFO_UNDERFLOW, 10, 1)
141     FIELD(CFRM_IER0, FAR_FIFO_OVERFLOW, 9, 1)
142     FIELD(CFRM_IER0, PER_FRAME_SEQ_ERROR, 8, 1)
143     FIELD(CFRM_IER0, CRC_ERROR, 7, 1)
144     FIELD(CFRM_IER0, WRITE_OVERRUN_ERROR, 6, 1)
145     FIELD(CFRM_IER0, READ_OVERRUN_ERROR, 5, 1)
146     FIELD(CFRM_IER0, CMD_INTERRUPT_ERROR, 4, 1)
147     FIELD(CFRM_IER0, WRITE_INTERRUPT_ERROR, 3, 1)
148     FIELD(CFRM_IER0, READ_INTERRUPT_ERROR, 2, 1)
149     FIELD(CFRM_IER0, SEU_CRC_ERROR, 1, 1)
150     FIELD(CFRM_IER0, SEU_ECC_ERROR, 0, 1)
151 REG32(CFRM_IER1, 0x174)
152 REG32(CFRM_IER2, 0x178)
153 REG32(CFRM_IER3, 0x17c)
154 REG32(CFRM_IDR0, 0x180)
155     FIELD(CFRM_IDR0, READ_BROADCAST_ERROR, 21, 1)
156     FIELD(CFRM_IDR0, CMD_MISSING_ERROR, 20, 1)
157     FIELD(CFRM_IDR0, RW_ROWOFF_ERROR, 19, 1)
158     FIELD(CFRM_IDR0, READ_REG_ADDR_ERROR, 18, 1)
159     FIELD(CFRM_IDR0, READ_BLK_TYPE_ERROR, 17, 1)
160     FIELD(CFRM_IDR0, READ_FRAME_ADDR_ERROR, 16, 1)
161     FIELD(CFRM_IDR0, WRITE_REG_ADDR_ERROR, 15, 1)
162     FIELD(CFRM_IDR0, WRITE_BLK_TYPE_ERROR, 13, 1)
163     FIELD(CFRM_IDR0, WRITE_FRAME_ADDR_ERROR, 12, 1)
164     FIELD(CFRM_IDR0, MFW_OVERRUN_ERROR, 11, 1)
165     FIELD(CFRM_IDR0, FAR_FIFO_UNDERFLOW, 10, 1)
166     FIELD(CFRM_IDR0, FAR_FIFO_OVERFLOW, 9, 1)
167     FIELD(CFRM_IDR0, PER_FRAME_SEQ_ERROR, 8, 1)
168     FIELD(CFRM_IDR0, CRC_ERROR, 7, 1)
169     FIELD(CFRM_IDR0, WRITE_OVERRUN_ERROR, 6, 1)
170     FIELD(CFRM_IDR0, READ_OVERRUN_ERROR, 5, 1)
171     FIELD(CFRM_IDR0, CMD_INTERRUPT_ERROR, 4, 1)
172     FIELD(CFRM_IDR0, WRITE_INTERRUPT_ERROR, 3, 1)
173     FIELD(CFRM_IDR0, READ_INTERRUPT_ERROR, 2, 1)
174     FIELD(CFRM_IDR0, SEU_CRC_ERROR, 1, 1)
175     FIELD(CFRM_IDR0, SEU_ECC_ERROR, 0, 1)
176 REG32(CFRM_IDR1, 0x184)
177 REG32(CFRM_IDR2, 0x188)
178 REG32(CFRM_IDR3, 0x18c)
179 REG32(CFRM_ITR0, 0x190)
180     FIELD(CFRM_ITR0, READ_BROADCAST_ERROR, 21, 1)
181     FIELD(CFRM_ITR0, CMD_MISSING_ERROR, 20, 1)
182     FIELD(CFRM_ITR0, RW_ROWOFF_ERROR, 19, 1)
183     FIELD(CFRM_ITR0, READ_REG_ADDR_ERROR, 18, 1)
184     FIELD(CFRM_ITR0, READ_BLK_TYPE_ERROR, 17, 1)
185     FIELD(CFRM_ITR0, READ_FRAME_ADDR_ERROR, 16, 1)
186     FIELD(CFRM_ITR0, WRITE_REG_ADDR_ERROR, 15, 1)
187     FIELD(CFRM_ITR0, WRITE_BLK_TYPE_ERROR, 13, 1)
188     FIELD(CFRM_ITR0, WRITE_FRAME_ADDR_ERROR, 12, 1)
189     FIELD(CFRM_ITR0, MFW_OVERRUN_ERROR, 11, 1)
190     FIELD(CFRM_ITR0, FAR_FIFO_UNDERFLOW, 10, 1)
191     FIELD(CFRM_ITR0, FAR_FIFO_OVERFLOW, 9, 1)
192     FIELD(CFRM_ITR0, PER_FRAME_SEQ_ERROR, 8, 1)
193     FIELD(CFRM_ITR0, CRC_ERROR, 7, 1)
194     FIELD(CFRM_ITR0, WRITE_OVERRUN_ERROR, 6, 1)
195     FIELD(CFRM_ITR0, READ_OVERRUN_ERROR, 5, 1)
196     FIELD(CFRM_ITR0, CMD_INTERRUPT_ERROR, 4, 1)
197     FIELD(CFRM_ITR0, WRITE_INTERRUPT_ERROR, 3, 1)
198     FIELD(CFRM_ITR0, READ_INTERRUPT_ERROR, 2, 1)
199     FIELD(CFRM_ITR0, SEU_CRC_ERROR, 1, 1)
200     FIELD(CFRM_ITR0, SEU_ECC_ERROR, 0, 1)
201 REG32(CFRM_ITR1, 0x194)
202 REG32(CFRM_ITR2, 0x198)
203 REG32(CFRM_ITR3, 0x19c)
204 REG32(SEU_SYNDRM00, 0x1a0)
205 REG32(SEU_SYNDRM01, 0x1a4)
206 REG32(SEU_SYNDRM02, 0x1a8)
207 REG32(SEU_SYNDRM03, 0x1ac)
208 REG32(SEU_SYNDRM10, 0x1b0)
209 REG32(SEU_SYNDRM11, 0x1b4)
210 REG32(SEU_SYNDRM12, 0x1b8)
211 REG32(SEU_SYNDRM13, 0x1bc)
212 REG32(SEU_SYNDRM20, 0x1c0)
213 REG32(SEU_SYNDRM21, 0x1c4)
214 REG32(SEU_SYNDRM22, 0x1c8)
215 REG32(SEU_SYNDRM23, 0x1cc)
216 REG32(SEU_SYNDRM30, 0x1d0)
217 REG32(SEU_SYNDRM31, 0x1d4)
218 REG32(SEU_SYNDRM32, 0x1d8)
219 REG32(SEU_SYNDRM33, 0x1dc)
220 REG32(SEU_VIRTUAL_SYNDRM0, 0x1e0)
221 REG32(SEU_VIRTUAL_SYNDRM1, 0x1e4)
222 REG32(SEU_VIRTUAL_SYNDRM2, 0x1e8)
223 REG32(SEU_VIRTUAL_SYNDRM3, 0x1ec)
224 REG32(SEU_CRC0, 0x1f0)
225 REG32(SEU_CRC1, 0x1f4)
226 REG32(SEU_CRC2, 0x1f8)
227 REG32(SEU_CRC3, 0x1fc)
228 REG32(CFRAME_FAR_BOT0, 0x200)
229 REG32(CFRAME_FAR_BOT1, 0x204)
230 REG32(CFRAME_FAR_BOT2, 0x208)
231 REG32(CFRAME_FAR_BOT3, 0x20c)
232 REG32(CFRAME_FAR_TOP0, 0x210)
233 REG32(CFRAME_FAR_TOP1, 0x214)
234 REG32(CFRAME_FAR_TOP2, 0x218)
235 REG32(CFRAME_FAR_TOP3, 0x21c)
236 REG32(LAST_FRAME_BOT0, 0x220)
237     FIELD(LAST_FRAME_BOT0, BLOCKTYPE1_LAST_FRAME_LSB, 20, 12)
238     FIELD(LAST_FRAME_BOT0, BLOCKTYPE0_LAST_FRAME, 0, 20)
239 REG32(LAST_FRAME_BOT1, 0x224)
240     FIELD(LAST_FRAME_BOT1, BLOCKTYPE3_LAST_FRAME_LSB, 28, 4)
241     FIELD(LAST_FRAME_BOT1, BLOCKTYPE2_LAST_FRAME, 8, 20)
242     FIELD(LAST_FRAME_BOT1, BLOCKTYPE1_LAST_FRAME_MSB, 0, 8)
243 REG32(LAST_FRAME_BOT2, 0x228)
244     FIELD(LAST_FRAME_BOT2, BLOCKTYPE3_LAST_FRAME_MSB, 0, 16)
245 REG32(LAST_FRAME_BOT3, 0x22c)
246 REG32(LAST_FRAME_TOP0, 0x230)
247     FIELD(LAST_FRAME_TOP0, BLOCKTYPE5_LAST_FRAME_LSB, 20, 12)
248     FIELD(LAST_FRAME_TOP0, BLOCKTYPE4_LAST_FRAME, 0, 20)
249 REG32(LAST_FRAME_TOP1, 0x234)
250     FIELD(LAST_FRAME_TOP1, BLOCKTYPE6_LAST_FRAME, 8, 20)
251     FIELD(LAST_FRAME_TOP1, BLOCKTYPE5_LAST_FRAME_MSB, 0, 8)
252 REG32(LAST_FRAME_TOP2, 0x238)
253 REG32(LAST_FRAME_TOP3, 0x23c)
254 
255 #define CFRAME_REG_R_MAX (R_LAST_FRAME_TOP3 + 1)
256 
257 #define FRAME_NUM_QWORDS 25
258 #define FRAME_NUM_WORDS (FRAME_NUM_QWORDS * 4) /* 25 * 128 bits */
259 
260 typedef struct XlnxCFrame {
261     uint32_t data[FRAME_NUM_WORDS];
262 } XlnxCFrame;
263 
264 struct XlnxVersalCFrameReg {
265     SysBusDevice parent_obj;
266     MemoryRegion iomem;
267     MemoryRegion iomem_fdri;
268     qemu_irq irq_cfrm_imr;
269 
270     /* 128-bit wfifo.  */
271     uint32_t wfifo[WFIFO_SZ];
272 
273     uint32_t regs[CFRAME_REG_R_MAX];
274     RegisterInfo regs_info[CFRAME_REG_R_MAX];
275 
276     bool rowon;
277     bool wcfg;
278     bool rcfg;
279 
280     GTree *cframes;
281     Fifo32 new_f_data;
282 
283     struct {
284         XlnxCfiIf *cfu_fdro;
285         uint32_t blktype_num_frames[7];
286     } cfg;
287     bool row_configured;
288 };
289 
290 struct XlnxVersalCFrameBcastReg {
291     SysBusDevice parent_obj;
292     MemoryRegion iomem_reg;
293     MemoryRegion iomem_fdri;
294 
295     /* 128-bit wfifo. */
296     uint32_t wfifo[WFIFO_SZ];
297 
298     struct {
299         XlnxCfiIf *cframe[15];
300     } cfg;
301 };
302 
303 #endif
304