1 /*
2 * xlnx_dpdma.c
3 *
4 * Copyright (C) 2015 : GreenSocs Ltd
5 * http://www.greensocs.com/ , email: info@greensocs.com
6 *
7 * Developed by :
8 * Frederic Konrad <fred.konrad@greensocs.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24
25 #include "qemu/osdep.h"
26 #include "qemu/cutils.h"
27 #include "qemu/log.h"
28 #include "qemu/module.h"
29 #include "hw/dma/xlnx_dpdma.h"
30 #include "hw/irq.h"
31 #include "migration/vmstate.h"
32
33 #ifndef DEBUG_DPDMA
34 #define DEBUG_DPDMA 0
35 #endif
36
37 #define DPRINTF(fmt, ...) do { \
38 if (DEBUG_DPDMA) { \
39 qemu_log("xlnx_dpdma: " fmt , ## __VA_ARGS__); \
40 } \
41 } while (0)
42
43 /*
44 * Registers offset for DPDMA.
45 */
46 #define DPDMA_ERR_CTRL (0x0000)
47 #define DPDMA_ISR (0x0004 >> 2)
48 #define DPDMA_IMR (0x0008 >> 2)
49 #define DPDMA_IEN (0x000C >> 2)
50 #define DPDMA_IDS (0x0010 >> 2)
51 #define DPDMA_EISR (0x0014 >> 2)
52 #define DPDMA_EIMR (0x0018 >> 2)
53 #define DPDMA_EIEN (0x001C >> 2)
54 #define DPDMA_EIDS (0x0020 >> 2)
55 #define DPDMA_CNTL (0x0100 >> 2)
56
57 #define DPDMA_GBL (0x0104 >> 2)
58 #define DPDMA_GBL_TRG_CH(n) (1 << n)
59 #define DPDMA_GBL_RTRG_CH(n) (1 << 6 << n)
60
61 #define DPDMA_ALC0_CNTL (0x0108 >> 2)
62 #define DPDMA_ALC0_STATUS (0x010C >> 2)
63 #define DPDMA_ALC0_MAX (0x0110 >> 2)
64 #define DPDMA_ALC0_MIN (0x0114 >> 2)
65 #define DPDMA_ALC0_ACC (0x0118 >> 2)
66 #define DPDMA_ALC0_ACC_TRAN (0x011C >> 2)
67 #define DPDMA_ALC1_CNTL (0x0120 >> 2)
68 #define DPDMA_ALC1_STATUS (0x0124 >> 2)
69 #define DPDMA_ALC1_MAX (0x0128 >> 2)
70 #define DPDMA_ALC1_MIN (0x012C >> 2)
71 #define DPDMA_ALC1_ACC (0x0130 >> 2)
72 #define DPDMA_ALC1_ACC_TRAN (0x0134 >> 2)
73
74 #define DPDMA_DSCR_STRT_ADDRE_CH(n) ((0x0200 + n * 0x100) >> 2)
75 #define DPDMA_DSCR_STRT_ADDR_CH(n) ((0x0204 + n * 0x100) >> 2)
76 #define DPDMA_DSCR_NEXT_ADDRE_CH(n) ((0x0208 + n * 0x100) >> 2)
77 #define DPDMA_DSCR_NEXT_ADDR_CH(n) ((0x020C + n * 0x100) >> 2)
78 #define DPDMA_PYLD_CUR_ADDRE_CH(n) ((0x0210 + n * 0x100) >> 2)
79 #define DPDMA_PYLD_CUR_ADDR_CH(n) ((0x0214 + n * 0x100) >> 2)
80
81 #define DPDMA_CNTL_CH(n) ((0x0218 + n * 0x100) >> 2)
82 #define DPDMA_CNTL_CH_EN (1)
83 #define DPDMA_CNTL_CH_PAUSED (1 << 1)
84
85 #define DPDMA_STATUS_CH(n) ((0x021C + n * 0x100) >> 2)
86 #define DPDMA_STATUS_BURST_TYPE (1 << 4)
87 #define DPDMA_STATUS_MODE (1 << 5)
88 #define DPDMA_STATUS_EN_CRC (1 << 6)
89 #define DPDMA_STATUS_LAST_DSCR (1 << 7)
90 #define DPDMA_STATUS_LDSCR_FRAME (1 << 8)
91 #define DPDMA_STATUS_IGNR_DONE (1 << 9)
92 #define DPDMA_STATUS_DSCR_DONE (1 << 10)
93 #define DPDMA_STATUS_EN_DSCR_UP (1 << 11)
94 #define DPDMA_STATUS_EN_DSCR_INTR (1 << 12)
95 #define DPDMA_STATUS_PREAMBLE_OFF (13)
96
97 #define DPDMA_VDO_CH(n) ((0x0220 + n * 0x100) >> 2)
98 #define DPDMA_PYLD_SZ_CH(n) ((0x0224 + n * 0x100) >> 2)
99 #define DPDMA_DSCR_ID_CH(n) ((0x0228 + n * 0x100) >> 2)
100
101 /*
102 * Descriptor control field.
103 */
104 #define CONTROL_PREAMBLE_VALUE 0xA5
105
106 #define DSCR_CTRL_PREAMBLE 0xFF
107 #define DSCR_CTRL_EN_DSCR_DONE_INTR (1 << 8)
108 #define DSCR_CTRL_EN_DSCR_UPDATE (1 << 9)
109 #define DSCR_CTRL_IGNORE_DONE (1 << 10)
110 #define DSCR_CTRL_AXI_BURST_TYPE (1 << 11)
111 #define DSCR_CTRL_AXCACHE (0x0F << 12)
112 #define DSCR_CTRL_AXPROT (0x2 << 16)
113 #define DSCR_CTRL_DESCRIPTOR_MODE (1 << 18)
114 #define DSCR_CTRL_LAST_DESCRIPTOR (1 << 19)
115 #define DSCR_CTRL_ENABLE_CRC (1 << 20)
116 #define DSCR_CTRL_LAST_DESCRIPTOR_OF_FRAME (1 << 21)
117
118 /*
119 * Descriptor timestamp field.
120 */
121 #define STATUS_DONE (1 << 31)
122
123 #define DPDMA_FRAG_MAX_SZ (4096)
124
125 enum DPDMABurstType {
126 DPDMA_INCR = 0,
127 DPDMA_FIXED = 1
128 };
129
130 enum DPDMAMode {
131 DPDMA_CONTIGOUS = 0,
132 DPDMA_FRAGMENTED = 1
133 };
134
135 struct DPDMADescriptor {
136 uint32_t control;
137 uint32_t descriptor_id;
138 /* transfer size in byte. */
139 uint32_t xfer_size;
140 uint32_t line_size_stride;
141 uint32_t timestamp_lsb;
142 uint32_t timestamp_msb;
143 /* contains extension for both descriptor and source. */
144 uint32_t address_extension;
145 uint32_t next_descriptor;
146 uint32_t source_address;
147 uint32_t address_extension_23;
148 uint32_t address_extension_45;
149 uint32_t source_address2;
150 uint32_t source_address3;
151 uint32_t source_address4;
152 uint32_t source_address5;
153 uint32_t crc;
154 };
155
156 typedef enum DPDMABurstType DPDMABurstType;
157 typedef enum DPDMAMode DPDMAMode;
158 typedef struct DPDMADescriptor DPDMADescriptor;
159
xlnx_dpdma_desc_is_last(DPDMADescriptor * desc)160 static bool xlnx_dpdma_desc_is_last(DPDMADescriptor *desc)
161 {
162 return ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR) != 0);
163 }
164
xlnx_dpdma_desc_is_last_of_frame(DPDMADescriptor * desc)165 static bool xlnx_dpdma_desc_is_last_of_frame(DPDMADescriptor *desc)
166 {
167 return ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR_OF_FRAME) != 0);
168 }
169
xlnx_dpdma_desc_get_source_address(DPDMADescriptor * desc,uint8_t frag)170 static uint64_t xlnx_dpdma_desc_get_source_address(DPDMADescriptor *desc,
171 uint8_t frag)
172 {
173 uint64_t addr = 0;
174 assert(frag < 5);
175
176 switch (frag) {
177 case 0:
178 addr = (uint64_t)desc->source_address
179 + (extract64(desc->address_extension, 16, 16) << 32);
180 break;
181 case 1:
182 addr = (uint64_t)desc->source_address2
183 + (extract64(desc->address_extension_23, 0, 16) << 32);
184 break;
185 case 2:
186 addr = (uint64_t)desc->source_address3
187 + (extract64(desc->address_extension_23, 16, 16) << 32);
188 break;
189 case 3:
190 addr = (uint64_t)desc->source_address4
191 + (extract64(desc->address_extension_45, 0, 16) << 32);
192 break;
193 case 4:
194 addr = (uint64_t)desc->source_address5
195 + (extract64(desc->address_extension_45, 16, 16) << 32);
196 break;
197 default:
198 addr = 0;
199 break;
200 }
201
202 return addr;
203 }
204
xlnx_dpdma_desc_get_transfer_size(DPDMADescriptor * desc)205 static uint32_t xlnx_dpdma_desc_get_transfer_size(DPDMADescriptor *desc)
206 {
207 return desc->xfer_size;
208 }
209
xlnx_dpdma_desc_get_line_size(DPDMADescriptor * desc)210 static uint32_t xlnx_dpdma_desc_get_line_size(DPDMADescriptor *desc)
211 {
212 return extract32(desc->line_size_stride, 0, 18);
213 }
214
xlnx_dpdma_desc_get_line_stride(DPDMADescriptor * desc)215 static uint32_t xlnx_dpdma_desc_get_line_stride(DPDMADescriptor *desc)
216 {
217 return extract32(desc->line_size_stride, 18, 14) * 16;
218 }
219
xlnx_dpdma_desc_crc_enabled(DPDMADescriptor * desc)220 static inline bool xlnx_dpdma_desc_crc_enabled(DPDMADescriptor *desc)
221 {
222 return (desc->control & DSCR_CTRL_ENABLE_CRC) != 0;
223 }
224
xlnx_dpdma_desc_check_crc(DPDMADescriptor * desc)225 static inline bool xlnx_dpdma_desc_check_crc(DPDMADescriptor *desc)
226 {
227 uint32_t *p = (uint32_t *)desc;
228 uint32_t crc = 0;
229 uint8_t i;
230
231 /*
232 * CRC is calculated on the whole descriptor except the last 32bits word
233 * using 32bits addition.
234 */
235 for (i = 0; i < 15; i++) {
236 crc += p[i];
237 }
238
239 return crc == desc->crc;
240 }
241
xlnx_dpdma_desc_completion_interrupt(DPDMADescriptor * desc)242 static inline bool xlnx_dpdma_desc_completion_interrupt(DPDMADescriptor *desc)
243 {
244 return (desc->control & DSCR_CTRL_EN_DSCR_DONE_INTR) != 0;
245 }
246
xlnx_dpdma_desc_is_valid(DPDMADescriptor * desc)247 static inline bool xlnx_dpdma_desc_is_valid(DPDMADescriptor *desc)
248 {
249 return (desc->control & DSCR_CTRL_PREAMBLE) == CONTROL_PREAMBLE_VALUE;
250 }
251
xlnx_dpdma_desc_is_contiguous(DPDMADescriptor * desc)252 static inline bool xlnx_dpdma_desc_is_contiguous(DPDMADescriptor *desc)
253 {
254 return (desc->control & DSCR_CTRL_DESCRIPTOR_MODE) == 0;
255 }
256
xlnx_dpdma_desc_update_enabled(DPDMADescriptor * desc)257 static inline bool xlnx_dpdma_desc_update_enabled(DPDMADescriptor *desc)
258 {
259 return (desc->control & DSCR_CTRL_EN_DSCR_UPDATE) != 0;
260 }
261
xlnx_dpdma_desc_set_done(DPDMADescriptor * desc)262 static inline void xlnx_dpdma_desc_set_done(DPDMADescriptor *desc)
263 {
264 desc->timestamp_msb |= STATUS_DONE;
265 }
266
xlnx_dpdma_desc_is_already_done(DPDMADescriptor * desc)267 static inline bool xlnx_dpdma_desc_is_already_done(DPDMADescriptor *desc)
268 {
269 return (desc->timestamp_msb & STATUS_DONE) != 0;
270 }
271
xlnx_dpdma_desc_ignore_done_bit(DPDMADescriptor * desc)272 static inline bool xlnx_dpdma_desc_ignore_done_bit(DPDMADescriptor *desc)
273 {
274 return (desc->control & DSCR_CTRL_IGNORE_DONE) != 0;
275 }
276
277 static const VMStateDescription vmstate_xlnx_dpdma = {
278 .name = TYPE_XLNX_DPDMA,
279 .version_id = 1,
280 .fields = (const VMStateField[]) {
281 VMSTATE_UINT32_ARRAY(registers, XlnxDPDMAState,
282 XLNX_DPDMA_REG_ARRAY_SIZE),
283 VMSTATE_BOOL_ARRAY(operation_finished, XlnxDPDMAState, 6),
284 VMSTATE_END_OF_LIST()
285 }
286 };
287
xlnx_dpdma_update_irq(XlnxDPDMAState * s)288 static void xlnx_dpdma_update_irq(XlnxDPDMAState *s)
289 {
290 bool flags;
291
292 flags = ((s->registers[DPDMA_ISR] & (~s->registers[DPDMA_IMR]))
293 || (s->registers[DPDMA_EISR] & (~s->registers[DPDMA_EIMR])));
294 qemu_set_irq(s->irq, flags);
295 }
296
xlnx_dpdma_descriptor_start_address(XlnxDPDMAState * s,uint8_t channel)297 static uint64_t xlnx_dpdma_descriptor_start_address(XlnxDPDMAState *s,
298 uint8_t channel)
299 {
300 return (s->registers[DPDMA_DSCR_STRT_ADDRE_CH(channel)] << 16)
301 + s->registers[DPDMA_DSCR_STRT_ADDR_CH(channel)];
302 }
303
xlnx_dpdma_descriptor_next_address(XlnxDPDMAState * s,uint8_t channel)304 static uint64_t xlnx_dpdma_descriptor_next_address(XlnxDPDMAState *s,
305 uint8_t channel)
306 {
307 return ((uint64_t)s->registers[DPDMA_DSCR_NEXT_ADDRE_CH(channel)] << 32)
308 + s->registers[DPDMA_DSCR_NEXT_ADDR_CH(channel)];
309 }
310
xlnx_dpdma_is_channel_enabled(XlnxDPDMAState * s,uint8_t channel)311 static bool xlnx_dpdma_is_channel_enabled(XlnxDPDMAState *s,
312 uint8_t channel)
313 {
314 return (s->registers[DPDMA_CNTL_CH(channel)] & DPDMA_CNTL_CH_EN) != 0;
315 }
316
xlnx_dpdma_is_channel_paused(XlnxDPDMAState * s,uint8_t channel)317 static bool xlnx_dpdma_is_channel_paused(XlnxDPDMAState *s,
318 uint8_t channel)
319 {
320 return (s->registers[DPDMA_CNTL_CH(channel)] & DPDMA_CNTL_CH_PAUSED) != 0;
321 }
322
xlnx_dpdma_is_channel_retriggered(XlnxDPDMAState * s,uint8_t channel)323 static inline bool xlnx_dpdma_is_channel_retriggered(XlnxDPDMAState *s,
324 uint8_t channel)
325 {
326 /* Clear the retriggered bit after reading it. */
327 bool channel_is_retriggered = s->registers[DPDMA_GBL]
328 & DPDMA_GBL_RTRG_CH(channel);
329 s->registers[DPDMA_GBL] &= ~DPDMA_GBL_RTRG_CH(channel);
330 return channel_is_retriggered;
331 }
332
xlnx_dpdma_is_channel_triggered(XlnxDPDMAState * s,uint8_t channel)333 static inline bool xlnx_dpdma_is_channel_triggered(XlnxDPDMAState *s,
334 uint8_t channel)
335 {
336 return s->registers[DPDMA_GBL] & DPDMA_GBL_TRG_CH(channel);
337 }
338
xlnx_dpdma_update_desc_info(XlnxDPDMAState * s,uint8_t channel,DPDMADescriptor * desc)339 static void xlnx_dpdma_update_desc_info(XlnxDPDMAState *s, uint8_t channel,
340 DPDMADescriptor *desc)
341 {
342 s->registers[DPDMA_DSCR_NEXT_ADDRE_CH(channel)] =
343 extract32(desc->address_extension, 0, 16);
344 s->registers[DPDMA_DSCR_NEXT_ADDR_CH(channel)] = desc->next_descriptor;
345 s->registers[DPDMA_PYLD_CUR_ADDRE_CH(channel)] =
346 extract32(desc->address_extension, 16, 16);
347 s->registers[DPDMA_PYLD_CUR_ADDR_CH(channel)] = desc->source_address;
348 s->registers[DPDMA_VDO_CH(channel)] =
349 extract32(desc->line_size_stride, 18, 14)
350 + (extract32(desc->line_size_stride, 0, 18)
351 << 14);
352 s->registers[DPDMA_PYLD_SZ_CH(channel)] = desc->xfer_size;
353 s->registers[DPDMA_DSCR_ID_CH(channel)] = desc->descriptor_id;
354
355 /* Compute the status register with the descriptor information. */
356 s->registers[DPDMA_STATUS_CH(channel)] =
357 extract32(desc->control, 0, 8) << 13;
358 if ((desc->control & DSCR_CTRL_EN_DSCR_DONE_INTR) != 0) {
359 s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_EN_DSCR_INTR;
360 }
361 if ((desc->control & DSCR_CTRL_EN_DSCR_UPDATE) != 0) {
362 s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_EN_DSCR_UP;
363 }
364 if ((desc->timestamp_msb & STATUS_DONE) != 0) {
365 s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_DSCR_DONE;
366 }
367 if ((desc->control & DSCR_CTRL_IGNORE_DONE) != 0) {
368 s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_IGNR_DONE;
369 }
370 if ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR_OF_FRAME) != 0) {
371 s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_LDSCR_FRAME;
372 }
373 if ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR) != 0) {
374 s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_LAST_DSCR;
375 }
376 if ((desc->control & DSCR_CTRL_ENABLE_CRC) != 0) {
377 s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_EN_CRC;
378 }
379 if ((desc->control & DSCR_CTRL_DESCRIPTOR_MODE) != 0) {
380 s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_MODE;
381 }
382 if ((desc->control & DSCR_CTRL_AXI_BURST_TYPE) != 0) {
383 s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_BURST_TYPE;
384 }
385 }
386
xlnx_dpdma_dump_descriptor(DPDMADescriptor * desc)387 static void xlnx_dpdma_dump_descriptor(DPDMADescriptor *desc)
388 {
389 if (DEBUG_DPDMA) {
390 qemu_log("DUMP DESCRIPTOR:\n");
391 qemu_hexdump(stdout, "", desc, sizeof(DPDMADescriptor));
392 }
393 }
394
xlnx_dpdma_read(void * opaque,hwaddr offset,unsigned size)395 static uint64_t xlnx_dpdma_read(void *opaque, hwaddr offset,
396 unsigned size)
397 {
398 XlnxDPDMAState *s = XLNX_DPDMA(opaque);
399
400 DPRINTF("read @%" HWADDR_PRIx "\n", offset);
401 offset = offset >> 2;
402
403 switch (offset) {
404 /*
405 * Trying to read a write only register.
406 */
407 case DPDMA_GBL:
408 return 0;
409 default:
410 assert(offset <= (0xFFC >> 2));
411 return s->registers[offset];
412 }
413 return 0;
414 }
415
xlnx_dpdma_write(void * opaque,hwaddr offset,uint64_t value,unsigned size)416 static void xlnx_dpdma_write(void *opaque, hwaddr offset,
417 uint64_t value, unsigned size)
418 {
419 XlnxDPDMAState *s = XLNX_DPDMA(opaque);
420
421 DPRINTF("write @%" HWADDR_PRIx " = %" PRIx64 "\n", offset, value);
422 offset = offset >> 2;
423
424 switch (offset) {
425 case DPDMA_ISR:
426 s->registers[DPDMA_ISR] &= ~value;
427 xlnx_dpdma_update_irq(s);
428 break;
429 case DPDMA_IEN:
430 s->registers[DPDMA_IMR] &= ~value;
431 break;
432 case DPDMA_IDS:
433 s->registers[DPDMA_IMR] |= value;
434 break;
435 case DPDMA_EISR:
436 s->registers[DPDMA_EISR] &= ~value;
437 xlnx_dpdma_update_irq(s);
438 break;
439 case DPDMA_EIEN:
440 s->registers[DPDMA_EIMR] &= ~value;
441 break;
442 case DPDMA_EIDS:
443 s->registers[DPDMA_EIMR] |= value;
444 break;
445 case DPDMA_IMR:
446 case DPDMA_EIMR:
447 case DPDMA_DSCR_NEXT_ADDRE_CH(0):
448 case DPDMA_DSCR_NEXT_ADDRE_CH(1):
449 case DPDMA_DSCR_NEXT_ADDRE_CH(2):
450 case DPDMA_DSCR_NEXT_ADDRE_CH(3):
451 case DPDMA_DSCR_NEXT_ADDRE_CH(4):
452 case DPDMA_DSCR_NEXT_ADDRE_CH(5):
453 case DPDMA_DSCR_NEXT_ADDR_CH(0):
454 case DPDMA_DSCR_NEXT_ADDR_CH(1):
455 case DPDMA_DSCR_NEXT_ADDR_CH(2):
456 case DPDMA_DSCR_NEXT_ADDR_CH(3):
457 case DPDMA_DSCR_NEXT_ADDR_CH(4):
458 case DPDMA_DSCR_NEXT_ADDR_CH(5):
459 case DPDMA_PYLD_CUR_ADDRE_CH(0):
460 case DPDMA_PYLD_CUR_ADDRE_CH(1):
461 case DPDMA_PYLD_CUR_ADDRE_CH(2):
462 case DPDMA_PYLD_CUR_ADDRE_CH(3):
463 case DPDMA_PYLD_CUR_ADDRE_CH(4):
464 case DPDMA_PYLD_CUR_ADDRE_CH(5):
465 case DPDMA_PYLD_CUR_ADDR_CH(0):
466 case DPDMA_PYLD_CUR_ADDR_CH(1):
467 case DPDMA_PYLD_CUR_ADDR_CH(2):
468 case DPDMA_PYLD_CUR_ADDR_CH(3):
469 case DPDMA_PYLD_CUR_ADDR_CH(4):
470 case DPDMA_PYLD_CUR_ADDR_CH(5):
471 case DPDMA_STATUS_CH(0):
472 case DPDMA_STATUS_CH(1):
473 case DPDMA_STATUS_CH(2):
474 case DPDMA_STATUS_CH(3):
475 case DPDMA_STATUS_CH(4):
476 case DPDMA_STATUS_CH(5):
477 case DPDMA_VDO_CH(0):
478 case DPDMA_VDO_CH(1):
479 case DPDMA_VDO_CH(2):
480 case DPDMA_VDO_CH(3):
481 case DPDMA_VDO_CH(4):
482 case DPDMA_VDO_CH(5):
483 case DPDMA_PYLD_SZ_CH(0):
484 case DPDMA_PYLD_SZ_CH(1):
485 case DPDMA_PYLD_SZ_CH(2):
486 case DPDMA_PYLD_SZ_CH(3):
487 case DPDMA_PYLD_SZ_CH(4):
488 case DPDMA_PYLD_SZ_CH(5):
489 case DPDMA_DSCR_ID_CH(0):
490 case DPDMA_DSCR_ID_CH(1):
491 case DPDMA_DSCR_ID_CH(2):
492 case DPDMA_DSCR_ID_CH(3):
493 case DPDMA_DSCR_ID_CH(4):
494 case DPDMA_DSCR_ID_CH(5):
495 /*
496 * Trying to write to a read only register..
497 */
498 break;
499 case DPDMA_GBL:
500 /*
501 * This is a write only register so it's read as zero in the read
502 * callback.
503 * We store the value anyway so we can know if the channel is
504 * enabled.
505 */
506 s->registers[offset] |= value & 0x00000FFF;
507 break;
508 case DPDMA_DSCR_STRT_ADDRE_CH(0):
509 case DPDMA_DSCR_STRT_ADDRE_CH(1):
510 case DPDMA_DSCR_STRT_ADDRE_CH(2):
511 case DPDMA_DSCR_STRT_ADDRE_CH(3):
512 case DPDMA_DSCR_STRT_ADDRE_CH(4):
513 case DPDMA_DSCR_STRT_ADDRE_CH(5):
514 value &= 0x0000FFFF;
515 s->registers[offset] = value;
516 break;
517 case DPDMA_CNTL_CH(0):
518 s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(0);
519 value &= 0x3FFFFFFF;
520 s->registers[offset] = value;
521 break;
522 case DPDMA_CNTL_CH(1):
523 s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(1);
524 value &= 0x3FFFFFFF;
525 s->registers[offset] = value;
526 break;
527 case DPDMA_CNTL_CH(2):
528 s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(2);
529 value &= 0x3FFFFFFF;
530 s->registers[offset] = value;
531 break;
532 case DPDMA_CNTL_CH(3):
533 s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(3);
534 value &= 0x3FFFFFFF;
535 s->registers[offset] = value;
536 break;
537 case DPDMA_CNTL_CH(4):
538 s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(4);
539 value &= 0x3FFFFFFF;
540 s->registers[offset] = value;
541 break;
542 case DPDMA_CNTL_CH(5):
543 s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(5);
544 value &= 0x3FFFFFFF;
545 s->registers[offset] = value;
546 break;
547 default:
548 assert(offset <= (0xFFC >> 2));
549 s->registers[offset] = value;
550 break;
551 }
552 }
553
554 static const MemoryRegionOps dma_ops = {
555 .read = xlnx_dpdma_read,
556 .write = xlnx_dpdma_write,
557 .endianness = DEVICE_NATIVE_ENDIAN,
558 .valid = {
559 .min_access_size = 4,
560 .max_access_size = 4,
561 },
562 .impl = {
563 .min_access_size = 4,
564 .max_access_size = 4,
565 },
566 };
567
xlnx_dpdma_init(Object * obj)568 static void xlnx_dpdma_init(Object *obj)
569 {
570 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
571 XlnxDPDMAState *s = XLNX_DPDMA(obj);
572
573 memory_region_init_io(&s->iomem, obj, &dma_ops, s,
574 TYPE_XLNX_DPDMA, 0x1000);
575 sysbus_init_mmio(sbd, &s->iomem);
576 sysbus_init_irq(sbd, &s->irq);
577 }
578
xlnx_dpdma_reset(DeviceState * dev)579 static void xlnx_dpdma_reset(DeviceState *dev)
580 {
581 XlnxDPDMAState *s = XLNX_DPDMA(dev);
582 size_t i;
583
584 memset(s->registers, 0, sizeof(s->registers));
585 s->registers[DPDMA_IMR] = 0x07FFFFFF;
586 s->registers[DPDMA_EIMR] = 0xFFFFFFFF;
587 s->registers[DPDMA_ALC0_MIN] = 0x0000FFFF;
588 s->registers[DPDMA_ALC1_MIN] = 0x0000FFFF;
589
590 for (i = 0; i < 6; i++) {
591 s->data[i] = NULL;
592 s->operation_finished[i] = true;
593 }
594 }
595
xlnx_dpdma_class_init(ObjectClass * oc,void * data)596 static void xlnx_dpdma_class_init(ObjectClass *oc, void *data)
597 {
598 DeviceClass *dc = DEVICE_CLASS(oc);
599
600 dc->vmsd = &vmstate_xlnx_dpdma;
601 dc->reset = xlnx_dpdma_reset;
602 }
603
604 static const TypeInfo xlnx_dpdma_info = {
605 .name = TYPE_XLNX_DPDMA,
606 .parent = TYPE_SYS_BUS_DEVICE,
607 .instance_size = sizeof(XlnxDPDMAState),
608 .instance_init = xlnx_dpdma_init,
609 .class_init = xlnx_dpdma_class_init,
610 };
611
xlnx_dpdma_register_types(void)612 static void xlnx_dpdma_register_types(void)
613 {
614 type_register_static(&xlnx_dpdma_info);
615 }
616
xlnx_dpdma_read_descriptor(XlnxDPDMAState * s,uint64_t desc_addr,DPDMADescriptor * desc)617 static MemTxResult xlnx_dpdma_read_descriptor(XlnxDPDMAState *s,
618 uint64_t desc_addr,
619 DPDMADescriptor *desc)
620 {
621 MemTxResult res = dma_memory_read(&address_space_memory, desc_addr,
622 desc, sizeof(DPDMADescriptor),
623 MEMTXATTRS_UNSPECIFIED);
624 if (res) {
625 return res;
626 }
627
628 /* Convert from LE into host endianness. */
629 desc->control = le32_to_cpu(desc->control);
630 desc->descriptor_id = le32_to_cpu(desc->descriptor_id);
631 desc->xfer_size = le32_to_cpu(desc->xfer_size);
632 desc->line_size_stride = le32_to_cpu(desc->line_size_stride);
633 desc->timestamp_lsb = le32_to_cpu(desc->timestamp_lsb);
634 desc->timestamp_msb = le32_to_cpu(desc->timestamp_msb);
635 desc->address_extension = le32_to_cpu(desc->address_extension);
636 desc->next_descriptor = le32_to_cpu(desc->next_descriptor);
637 desc->source_address = le32_to_cpu(desc->source_address);
638 desc->address_extension_23 = le32_to_cpu(desc->address_extension_23);
639 desc->address_extension_45 = le32_to_cpu(desc->address_extension_45);
640 desc->source_address2 = le32_to_cpu(desc->source_address2);
641 desc->source_address3 = le32_to_cpu(desc->source_address3);
642 desc->source_address4 = le32_to_cpu(desc->source_address4);
643 desc->source_address5 = le32_to_cpu(desc->source_address5);
644 desc->crc = le32_to_cpu(desc->crc);
645
646 return res;
647 }
648
xlnx_dpdma_write_descriptor(uint64_t desc_addr,DPDMADescriptor * desc)649 static MemTxResult xlnx_dpdma_write_descriptor(uint64_t desc_addr,
650 DPDMADescriptor *desc)
651 {
652 DPDMADescriptor tmp_desc = *desc;
653
654 /* Convert from host endianness into LE. */
655 tmp_desc.control = cpu_to_le32(tmp_desc.control);
656 tmp_desc.descriptor_id = cpu_to_le32(tmp_desc.descriptor_id);
657 tmp_desc.xfer_size = cpu_to_le32(tmp_desc.xfer_size);
658 tmp_desc.line_size_stride = cpu_to_le32(tmp_desc.line_size_stride);
659 tmp_desc.timestamp_lsb = cpu_to_le32(tmp_desc.timestamp_lsb);
660 tmp_desc.timestamp_msb = cpu_to_le32(tmp_desc.timestamp_msb);
661 tmp_desc.address_extension = cpu_to_le32(tmp_desc.address_extension);
662 tmp_desc.next_descriptor = cpu_to_le32(tmp_desc.next_descriptor);
663 tmp_desc.source_address = cpu_to_le32(tmp_desc.source_address);
664 tmp_desc.address_extension_23 = cpu_to_le32(tmp_desc.address_extension_23);
665 tmp_desc.address_extension_45 = cpu_to_le32(tmp_desc.address_extension_45);
666 tmp_desc.source_address2 = cpu_to_le32(tmp_desc.source_address2);
667 tmp_desc.source_address3 = cpu_to_le32(tmp_desc.source_address3);
668 tmp_desc.source_address4 = cpu_to_le32(tmp_desc.source_address4);
669 tmp_desc.source_address5 = cpu_to_le32(tmp_desc.source_address5);
670 tmp_desc.crc = cpu_to_le32(tmp_desc.crc);
671
672 return dma_memory_write(&address_space_memory, desc_addr, &tmp_desc,
673 sizeof(DPDMADescriptor), MEMTXATTRS_UNSPECIFIED);
674 }
675
xlnx_dpdma_start_operation(XlnxDPDMAState * s,uint8_t channel,bool one_desc)676 size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel,
677 bool one_desc)
678 {
679 uint64_t desc_addr;
680 uint64_t source_addr[6];
681 DPDMADescriptor desc;
682 bool done = false;
683 size_t ptr = 0;
684
685 assert(channel <= 5);
686
687 DPRINTF("start dpdma channel 0x%" PRIX8 "\n", channel);
688
689 if (!xlnx_dpdma_is_channel_triggered(s, channel)) {
690 DPRINTF("Channel isn't triggered..\n");
691 return 0;
692 }
693
694 if (!xlnx_dpdma_is_channel_enabled(s, channel)) {
695 DPRINTF("Channel isn't enabled..\n");
696 return 0;
697 }
698
699 if (xlnx_dpdma_is_channel_paused(s, channel)) {
700 DPRINTF("Channel is paused..\n");
701 return 0;
702 }
703
704 do {
705 if ((s->operation_finished[channel])
706 || xlnx_dpdma_is_channel_retriggered(s, channel)) {
707 desc_addr = xlnx_dpdma_descriptor_start_address(s, channel);
708 s->operation_finished[channel] = false;
709 } else {
710 desc_addr = xlnx_dpdma_descriptor_next_address(s, channel);
711 }
712
713 if (xlnx_dpdma_read_descriptor(s, desc_addr, &desc)) {
714 s->registers[DPDMA_EISR] |= ((1 << 1) << channel);
715 xlnx_dpdma_update_irq(s);
716 s->operation_finished[channel] = true;
717 DPRINTF("Can't get the descriptor.\n");
718 break;
719 }
720
721 xlnx_dpdma_update_desc_info(s, channel, &desc);
722
723 #ifdef DEBUG_DPDMA
724 xlnx_dpdma_dump_descriptor(&desc);
725 #endif
726
727 DPRINTF("location of the descriptor: %" PRIx64 "\n", desc_addr);
728 if (!xlnx_dpdma_desc_is_valid(&desc)) {
729 s->registers[DPDMA_EISR] |= ((1 << 7) << channel);
730 xlnx_dpdma_update_irq(s);
731 s->operation_finished[channel] = true;
732 DPRINTF("Invalid descriptor..\n");
733 break;
734 }
735
736 if (xlnx_dpdma_desc_crc_enabled(&desc)
737 && !xlnx_dpdma_desc_check_crc(&desc)) {
738 s->registers[DPDMA_EISR] |= ((1 << 13) << channel);
739 xlnx_dpdma_update_irq(s);
740 s->operation_finished[channel] = true;
741 DPRINTF("Bad CRC for descriptor..\n");
742 break;
743 }
744
745 if (xlnx_dpdma_desc_is_already_done(&desc)
746 && !xlnx_dpdma_desc_ignore_done_bit(&desc)) {
747 /* We are trying to process an already processed descriptor. */
748 s->registers[DPDMA_EISR] |= ((1 << 25) << channel);
749 xlnx_dpdma_update_irq(s);
750 s->operation_finished[channel] = true;
751 DPRINTF("Already processed descriptor..\n");
752 break;
753 }
754
755 done = xlnx_dpdma_desc_is_last(&desc)
756 || xlnx_dpdma_desc_is_last_of_frame(&desc);
757
758 s->operation_finished[channel] = done;
759 if (s->data[channel]) {
760 int64_t transfer_len = xlnx_dpdma_desc_get_transfer_size(&desc);
761 uint32_t line_size = xlnx_dpdma_desc_get_line_size(&desc);
762 uint32_t line_stride = xlnx_dpdma_desc_get_line_stride(&desc);
763 if (xlnx_dpdma_desc_is_contiguous(&desc)) {
764 source_addr[0] = xlnx_dpdma_desc_get_source_address(&desc, 0);
765 while (transfer_len != 0) {
766 if (dma_memory_read(&address_space_memory,
767 source_addr[0],
768 &s->data[channel][ptr],
769 line_size,
770 MEMTXATTRS_UNSPECIFIED)) {
771 s->registers[DPDMA_ISR] |= ((1 << 12) << channel);
772 xlnx_dpdma_update_irq(s);
773 DPRINTF("Can't get data.\n");
774 break;
775 }
776 ptr += line_size;
777 transfer_len -= line_size;
778 source_addr[0] += line_stride;
779 }
780 } else {
781 DPRINTF("Source address:\n");
782 int frag;
783 for (frag = 0; frag < 5; frag++) {
784 source_addr[frag] =
785 xlnx_dpdma_desc_get_source_address(&desc, frag);
786 DPRINTF("Fragment %u: %" PRIx64 "\n", frag + 1,
787 source_addr[frag]);
788 }
789
790 frag = 0;
791 while ((transfer_len < 0) && (frag < 5)) {
792 size_t fragment_len = DPDMA_FRAG_MAX_SZ
793 - (source_addr[frag] % DPDMA_FRAG_MAX_SZ);
794
795 if (dma_memory_read(&address_space_memory,
796 source_addr[frag],
797 &(s->data[channel][ptr]),
798 fragment_len,
799 MEMTXATTRS_UNSPECIFIED)) {
800 s->registers[DPDMA_ISR] |= ((1 << 12) << channel);
801 xlnx_dpdma_update_irq(s);
802 DPRINTF("Can't get data.\n");
803 break;
804 }
805 ptr += fragment_len;
806 transfer_len -= fragment_len;
807 frag += 1;
808 }
809 }
810 }
811
812 if (xlnx_dpdma_desc_update_enabled(&desc)) {
813 /* The descriptor need to be updated when it's completed. */
814 DPRINTF("update the descriptor with the done flag set.\n");
815 xlnx_dpdma_desc_set_done(&desc);
816 if (xlnx_dpdma_write_descriptor(desc_addr, &desc)) {
817 DPRINTF("Can't write the descriptor.\n");
818 /* TODO: check hardware behaviour for memory write failure */
819 }
820 }
821
822 if (xlnx_dpdma_desc_completion_interrupt(&desc)) {
823 DPRINTF("completion interrupt enabled!\n");
824 s->registers[DPDMA_ISR] |= (1 << channel);
825 xlnx_dpdma_update_irq(s);
826 }
827
828 } while (!done && !one_desc);
829
830 return ptr;
831 }
832
xlnx_dpdma_set_host_data_location(XlnxDPDMAState * s,uint8_t channel,void * p)833 void xlnx_dpdma_set_host_data_location(XlnxDPDMAState *s, uint8_t channel,
834 void *p)
835 {
836 if (!s) {
837 qemu_log_mask(LOG_UNIMP, "DPDMA client not attached to valid DPDMA"
838 " instance\n");
839 return;
840 }
841
842 assert(channel <= 5);
843 s->data[channel] = p;
844 }
845
xlnx_dpdma_trigger_vsync_irq(XlnxDPDMAState * s)846 void xlnx_dpdma_trigger_vsync_irq(XlnxDPDMAState *s)
847 {
848 s->registers[DPDMA_ISR] |= (1 << 27);
849 xlnx_dpdma_update_irq(s);
850 }
851
852 type_init(xlnx_dpdma_register_types)
853