21
#include "qemu/osdep.h"
23
#include "qapi/error.h"
25
#include "hw/qdev-properties.h"
27
#include "migration/vmstate.h"
28
#include "sysemu/dma.h"
31
#include "hw/register.h"
32
#include "hw/dma/xlnx_csu_dma.h"
40
FIELD(ADDR, ADDR, 2, 30)
42
FIELD(SIZE, SIZE, 2, 27)
43
FIELD(SIZE, LAST_WORD, 0, 1)
45
FIELD(STATUS, DONE_CNT, 13, 3)
46
FIELD(STATUS, FIFO_LEVEL, 5, 8)
47
FIELD(STATUS, OUTSTANDING, 1, 4)
48
FIELD(STATUS, BUSY, 0, 1)
50
FIELD(CTRL, FIFOTHRESH, 25, 7)
51
FIELD(CTRL, APB_ERR_RESP, 24, 1)
52
FIELD(CTRL, ENDIANNESS, 23, 1)
53
FIELD(CTRL, AXI_BRST_TYPE, 22, 1)
54
FIELD(CTRL, TIMEOUT_VAL, 10, 12)
55
FIELD(CTRL, FIFO_THRESH, 2, 8)
56
FIELD(CTRL, PAUSE_STRM, 1, 1)
57
FIELD(CTRL, PAUSE_MEM, 0, 1)
59
REG32(INT_STATUS, 0x14)
60
FIELD(INT_STATUS, FIFO_OVERFLOW, 7, 1)
61
FIELD(INT_STATUS, INVALID_APB, 6, 1)
62
FIELD(INT_STATUS, THRESH_HIT, 5, 1)
63
FIELD(INT_STATUS, TIMEOUT_MEM, 4, 1)
64
FIELD(INT_STATUS, TIMEOUT_STRM, 3, 1)
65
FIELD(INT_STATUS, AXI_BRESP_ERR, 2, 1)
66
FIELD(INT_STATUS, DONE, 1, 1)
67
FIELD(INT_STATUS, MEM_DONE, 0, 1)
68
REG32(INT_ENABLE, 0x18)
69
FIELD(INT_ENABLE, FIFO_OVERFLOW, 7, 1)
70
FIELD(INT_ENABLE, INVALID_APB, 6, 1)
71
FIELD(INT_ENABLE, THRESH_HIT, 5, 1)
72
FIELD(INT_ENABLE, TIMEOUT_MEM, 4, 1)
73
FIELD(INT_ENABLE, TIMEOUT_STRM, 3, 1)
74
FIELD(INT_ENABLE, AXI_BRESP_ERR, 2, 1)
75
FIELD(INT_ENABLE, DONE, 1, 1)
76
FIELD(INT_ENABLE, MEM_DONE, 0, 1)
77
REG32(INT_DISABLE, 0x1c)
78
FIELD(INT_DISABLE, FIFO_OVERFLOW, 7, 1)
79
FIELD(INT_DISABLE, INVALID_APB, 6, 1)
80
FIELD(INT_DISABLE, THRESH_HIT, 5, 1)
81
FIELD(INT_DISABLE, TIMEOUT_MEM, 4, 1)
82
FIELD(INT_DISABLE, TIMEOUT_STRM, 3, 1)
83
FIELD(INT_DISABLE, AXI_BRESP_ERR, 2, 1)
84
FIELD(INT_DISABLE, DONE, 1, 1)
85
FIELD(INT_DISABLE, MEM_DONE, 0, 1)
87
FIELD(INT_MASK, FIFO_OVERFLOW, 7, 1)
88
FIELD(INT_MASK, INVALID_APB, 6, 1)
89
FIELD(INT_MASK, THRESH_HIT, 5, 1)
90
FIELD(INT_MASK, TIMEOUT_MEM, 4, 1)
91
FIELD(INT_MASK, TIMEOUT_STRM, 3, 1)
92
FIELD(INT_MASK, AXI_BRESP_ERR, 2, 1)
93
FIELD(INT_MASK, DONE, 1, 1)
94
FIELD(INT_MASK, MEM_DONE, 0, 1)
96
FIELD(CTRL2, ARCACHE, 24, 3)
97
FIELD(CTRL2, ROUTE_BIT, 23, 1)
98
FIELD(CTRL2, TIMEOUT_EN, 22, 1)
99
FIELD(CTRL2, TIMEOUT_PRE, 4, 12)
100
FIELD(CTRL2, MAX_OUTS_CMDS, 0, 4)
102
FIELD(ADDR_MSB, ADDR_MSB, 0, 17)
104
#define R_CTRL_TIMEOUT_VAL_RESET (0xFFE)
105
#define R_CTRL_FIFO_THRESH_RESET (0x80)
106
#define R_CTRL_FIFOTHRESH_RESET (0x40)
108
#define R_CTRL2_TIMEOUT_PRE_RESET (0xFFF)
109
#define R_CTRL2_MAX_OUTS_CMDS_RESET (0x8)
111
#define XLNX_CSU_DMA_ERR_DEBUG (0)
112
#define XLNX_CSU_DMA_INT_R_MASK (0xff)
115
#define XLNX_CSU_DMA_TIMER_FREQ (400 * 1000 * 1000)
117
static bool xlnx_csu_dma_is_paused(XlnxCSUDMA *s)
121
paused = !!(s->regs[R_CTRL] & R_CTRL_PAUSE_STRM_MASK);
122
paused |= !!(s->regs[R_CTRL] & R_CTRL_PAUSE_MEM_MASK);
127
static bool xlnx_csu_dma_get_eop(XlnxCSUDMA *s)
129
return s->r_size_last_word;
132
static bool xlnx_csu_dma_burst_is_fixed(XlnxCSUDMA *s)
134
return !!(s->regs[R_CTRL] & R_CTRL_AXI_BRST_TYPE_MASK);
137
static bool xlnx_csu_dma_timeout_enabled(XlnxCSUDMA *s)
139
return !!(s->regs[R_CTRL2] & R_CTRL2_TIMEOUT_EN_MASK);
142
static void xlnx_csu_dma_update_done_cnt(XlnxCSUDMA *s, int a)
147
cnt = ARRAY_FIELD_EX32(s->regs, STATUS, DONE_CNT) + a;
148
ARRAY_FIELD_DP32(s->regs, STATUS, DONE_CNT, cnt);
151
static void xlnx_csu_dma_data_process(XlnxCSUDMA *s, uint8_t *buf, uint32_t len)
156
bswap = s->regs[R_CTRL] & R_CTRL_ENDIANNESS_MASK;
157
if (s->is_dst && !bswap) {
162
for (i = 0; i < len; i += 4) {
163
uint8_t *b = &buf[i];
168
.u8 = { b[0], b[1], b[2], b[3] }
172
s->regs[R_CRC] += v.u32;
187
static void xlnx_csu_dma_update_irq(XlnxCSUDMA *s)
189
qemu_set_irq(s->irq, !!(s->regs[R_INT_STATUS] & ~s->regs[R_INT_MASK]));
193
static uint32_t xlnx_csu_dma_read(XlnxCSUDMA *s, uint8_t *buf, uint32_t len)
195
hwaddr addr = (hwaddr)s->regs[R_ADDR_MSB] << 32 | s->regs[R_ADDR];
196
MemTxResult result = MEMTX_OK;
198
if (xlnx_csu_dma_burst_is_fixed(s)) {
201
for (i = 0; i < len && (result == MEMTX_OK); i += s->width) {
202
uint32_t mlen = MIN(len - i, s->width);
204
result = address_space_rw(&s->dma_as, addr, s->attr,
205
buf + i, mlen, false);
208
result = address_space_rw(&s->dma_as, addr, s->attr, buf, len, false);
211
if (result == MEMTX_OK) {
212
xlnx_csu_dma_data_process(s, buf, len);
214
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address " HWADDR_FMT_plx
215
" for mem read", __func__, addr);
216
s->regs[R_INT_STATUS] |= R_INT_STATUS_AXI_BRESP_ERR_MASK;
217
xlnx_csu_dma_update_irq(s);
223
static uint32_t xlnx_csu_dma_write(XlnxCSUDMA *s, uint8_t *buf, uint32_t len)
225
hwaddr addr = (hwaddr)s->regs[R_ADDR_MSB] << 32 | s->regs[R_ADDR];
226
MemTxResult result = MEMTX_OK;
228
xlnx_csu_dma_data_process(s, buf, len);
229
if (xlnx_csu_dma_burst_is_fixed(s)) {
232
for (i = 0; i < len && (result == MEMTX_OK); i += s->width) {
233
uint32_t mlen = MIN(len - i, s->width);
235
result = address_space_rw(&s->dma_as, addr, s->attr,
240
result = address_space_rw(&s->dma_as, addr, s->attr, buf, len, true);
243
if (result != MEMTX_OK) {
244
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address " HWADDR_FMT_plx
245
" for mem write", __func__, addr);
246
s->regs[R_INT_STATUS] |= R_INT_STATUS_AXI_BRESP_ERR_MASK;
247
xlnx_csu_dma_update_irq(s);
252
static void xlnx_csu_dma_done(XlnxCSUDMA *s)
254
s->regs[R_STATUS] &= ~R_STATUS_BUSY_MASK;
255
s->regs[R_INT_STATUS] |= R_INT_STATUS_DONE_MASK;
258
s->regs[R_INT_STATUS] |= R_INT_STATUS_MEM_DONE_MASK;
261
xlnx_csu_dma_update_done_cnt(s, 1);
264
static uint32_t xlnx_csu_dma_advance(XlnxCSUDMA *s, uint32_t len)
266
uint32_t size = s->regs[R_SIZE];
267
hwaddr dst = (hwaddr)s->regs[R_ADDR_MSB] << 32 | s->regs[R_ADDR];
272
s->regs[R_SIZE] = size;
274
if (!xlnx_csu_dma_burst_is_fixed(s)) {
276
s->regs[R_ADDR] = (uint32_t) dst;
277
s->regs[R_ADDR_MSB] = dst >> 32;
281
xlnx_csu_dma_done(s);
287
static void xlnx_csu_dma_src_notify(void *opaque)
289
XlnxCSUDMA *s = XLNX_CSU_DMA(opaque);
290
unsigned char buf[4 * 1024];
293
ptimer_transaction_begin(s->src_timer);
295
ptimer_stop(s->src_timer);
297
while (s->regs[R_SIZE] && !xlnx_csu_dma_is_paused(s) &&
298
stream_can_push(s->tx_dev, xlnx_csu_dma_src_notify, s)) {
299
uint32_t plen = MIN(s->regs[R_SIZE], sizeof buf);
303
if (s->regs[R_SIZE] == plen && xlnx_csu_dma_get_eop(s)) {
308
xlnx_csu_dma_read(s, buf, plen);
309
rlen = stream_push(s->tx_dev, buf, plen, eop);
310
xlnx_csu_dma_advance(s, rlen);
313
if (xlnx_csu_dma_timeout_enabled(s) && s->regs[R_SIZE] &&
314
!stream_can_push(s->tx_dev, xlnx_csu_dma_src_notify, s)) {
315
uint32_t timeout = ARRAY_FIELD_EX32(s->regs, CTRL, TIMEOUT_VAL);
316
uint32_t div = ARRAY_FIELD_EX32(s->regs, CTRL2, TIMEOUT_PRE) + 1;
317
uint32_t freq = XLNX_CSU_DMA_TIMER_FREQ;
320
ptimer_set_freq(s->src_timer, freq);
321
ptimer_set_count(s->src_timer, timeout);
322
ptimer_run(s->src_timer, 1);
325
ptimer_transaction_commit(s->src_timer);
326
xlnx_csu_dma_update_irq(s);
329
static uint64_t addr_pre_write(RegisterInfo *reg, uint64_t val)
332
return val & R_ADDR_ADDR_MASK;
335
static uint64_t size_pre_write(RegisterInfo *reg, uint64_t val)
337
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
338
uint64_t size = val & R_SIZE_SIZE_MASK;
340
if (s->regs[R_SIZE] != 0) {
341
if (size || s->is_dst) {
342
qemu_log_mask(LOG_GUEST_ERROR,
343
"%s: Starting DMA while already running.\n",
349
s->r_size_last_word = !!(val & R_SIZE_LAST_WORD_MASK);
356
static uint64_t size_post_read(RegisterInfo *reg, uint64_t val)
358
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
360
return val | s->r_size_last_word;
363
static void size_post_write(RegisterInfo *reg, uint64_t val)
365
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
367
s->regs[R_STATUS] |= R_STATUS_BUSY_MASK;
373
if (s->regs[R_SIZE] == 0) {
374
xlnx_csu_dma_done(s);
375
xlnx_csu_dma_update_irq(s);
381
xlnx_csu_dma_src_notify(s);
384
s->notify(s->notify_opaque);
389
static uint64_t status_pre_write(RegisterInfo *reg, uint64_t val)
391
return val & (R_STATUS_DONE_CNT_MASK | R_STATUS_BUSY_MASK);
394
static void ctrl_post_write(RegisterInfo *reg, uint64_t val)
396
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
399
if (!xlnx_csu_dma_is_paused(s)) {
400
xlnx_csu_dma_src_notify(s);
403
if (!xlnx_csu_dma_is_paused(s) && s->notify) {
404
s->notify(s->notify_opaque);
409
static uint64_t int_status_pre_write(RegisterInfo *reg, uint64_t val)
411
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
414
if ((val & s->regs[R_INT_STATUS] & R_INT_STATUS_DONE_MASK)) {
415
xlnx_csu_dma_update_done_cnt(s, -1);
418
return s->regs[R_INT_STATUS] & ~val;
421
static void int_status_post_write(RegisterInfo *reg, uint64_t val)
423
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
425
xlnx_csu_dma_update_irq(s);
428
static uint64_t int_enable_pre_write(RegisterInfo *reg, uint64_t val)
430
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
440
s->regs[R_INT_MASK] &= ~v32;
444
static void int_enable_post_write(RegisterInfo *reg, uint64_t val)
446
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
448
xlnx_csu_dma_update_irq(s);
451
static uint64_t int_disable_pre_write(RegisterInfo *reg, uint64_t val)
453
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
463
s->regs[R_INT_MASK] |= v32;
467
static void int_disable_post_write(RegisterInfo *reg, uint64_t val)
469
XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
471
xlnx_csu_dma_update_irq(s);
474
static uint64_t addr_msb_pre_write(RegisterInfo *reg, uint64_t val)
476
return val & R_ADDR_MSB_ADDR_MSB_MASK;
479
static MemTxResult xlnx_csu_dma_class_read(XlnxCSUDMA *s, hwaddr addr,
482
RegisterInfo *reg = &s->regs_info[R_SIZE];
483
uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
485
s->regs[R_ADDR] = addr;
486
s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
488
register_write(reg, len, we, object_get_typename(OBJECT(s)), false);
490
return (s->regs[R_SIZE] == 0) ? MEMTX_OK : MEMTX_ERROR;
493
static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
494
#define DMACH_REGINFO(NAME, snd) \
495
(const RegisterAccessInfo []) { \
497
.name = #NAME "_ADDR", \
499
.pre_write = addr_pre_write \
501
.name = #NAME "_SIZE", \
503
.pre_write = size_pre_write, \
504
.post_write = size_post_write, \
505
.post_read = size_post_read \
507
.name = #NAME "_STATUS", \
509
.pre_write = status_pre_write, \
510
.w1c = R_STATUS_DONE_CNT_MASK, \
511
.ro = (R_STATUS_BUSY_MASK \
512
| R_STATUS_FIFO_LEVEL_MASK \
513
| R_STATUS_OUTSTANDING_MASK) \
515
.name = #NAME "_CTRL", \
517
.post_write = ctrl_post_write, \
518
.reset = ((R_CTRL_TIMEOUT_VAL_RESET << R_CTRL_TIMEOUT_VAL_SHIFT) \
519
| (R_CTRL_FIFO_THRESH_RESET << R_CTRL_FIFO_THRESH_SHIFT)\
520
| (snd ? 0 : R_CTRL_FIFOTHRESH_RESET \
521
<< R_CTRL_FIFOTHRESH_SHIFT)) \
523
.name = #NAME "_CRC", \
526
.name = #NAME "_INT_STATUS", \
527
.addr = A_INT_STATUS, \
528
.pre_write = int_status_pre_write, \
529
.post_write = int_status_post_write \
531
.name = #NAME "_INT_ENABLE", \
532
.addr = A_INT_ENABLE, \
533
.pre_write = int_enable_pre_write, \
534
.post_write = int_enable_post_write \
536
.name = #NAME "_INT_DISABLE", \
537
.addr = A_INT_DISABLE, \
538
.pre_write = int_disable_pre_write, \
539
.post_write = int_disable_post_write \
541
.name = #NAME "_INT_MASK", \
542
.addr = A_INT_MASK, \
544
.reset = XLNX_CSU_DMA_INT_R_MASK \
546
.name = #NAME "_CTRL2", \
548
.reset = ((R_CTRL2_TIMEOUT_PRE_RESET \
549
<< R_CTRL2_TIMEOUT_PRE_SHIFT) \
550
| (R_CTRL2_MAX_OUTS_CMDS_RESET \
551
<< R_CTRL2_MAX_OUTS_CMDS_SHIFT)) \
553
.name = #NAME "_ADDR_MSB", \
554
.addr = A_ADDR_MSB, \
555
.pre_write = addr_msb_pre_write \
559
DMACH_REGINFO(DMA_SRC, true),
560
DMACH_REGINFO(DMA_DST, false)
563
static const MemoryRegionOps xlnx_csu_dma_ops = {
564
.read = register_read_memory,
565
.write = register_write_memory,
566
.endianness = DEVICE_LITTLE_ENDIAN,
568
.min_access_size = 4,
569
.max_access_size = 4,
573
static void xlnx_csu_dma_src_timeout_hit(void *opaque)
575
XlnxCSUDMA *s = XLNX_CSU_DMA(opaque);
578
if (!xlnx_csu_dma_timeout_enabled(s)) {
582
s->regs[R_INT_STATUS] |= R_INT_STATUS_TIMEOUT_STRM_MASK;
583
xlnx_csu_dma_update_irq(s);
586
static size_t xlnx_csu_dma_stream_push(StreamSink *obj, uint8_t *buf,
587
size_t len, bool eop)
589
XlnxCSUDMA *s = XLNX_CSU_DMA(obj);
590
uint32_t size = s->regs[R_SIZE];
591
uint32_t mlen = MIN(size, len) & (~3);
596
if (size == 0 || len <= 0) {
600
if (len && (xlnx_csu_dma_is_paused(s) || mlen == 0)) {
601
qemu_log_mask(LOG_GUEST_ERROR,
602
"csu-dma: DST channel dropping %zd b of data.\n", len);
603
s->regs[R_INT_STATUS] |= R_INT_STATUS_FIFO_OVERFLOW_MASK;
607
if (xlnx_csu_dma_write(s, buf, mlen) != mlen) {
611
xlnx_csu_dma_advance(s, mlen);
612
xlnx_csu_dma_update_irq(s);
617
static bool xlnx_csu_dma_stream_can_push(StreamSink *obj,
618
StreamCanPushNotifyFn notify,
621
XlnxCSUDMA *s = XLNX_CSU_DMA(obj);
623
if (s->regs[R_SIZE] != 0) {
627
s->notify_opaque = notify_opaque;
632
static void xlnx_csu_dma_reset(DeviceState *dev)
634
XlnxCSUDMA *s = XLNX_CSU_DMA(dev);
637
for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
638
register_reset(&s->regs_info[i]);
642
static void xlnx_csu_dma_realize(DeviceState *dev, Error **errp)
644
XlnxCSUDMA *s = XLNX_CSU_DMA(dev);
645
RegisterInfoArray *reg_array;
647
if (!s->is_dst && !s->tx_dev) {
648
error_setg(errp, "zynqmp.csu-dma: Stream not connected");
653
error_setg(errp, TYPE_XLNX_CSU_DMA " 'dma' link not set");
656
address_space_init(&s->dma_as, s->dma_mr, "csu-dma");
659
register_init_block32(dev, xlnx_csu_dma_regs_info[!!s->is_dst],
661
s->regs_info, s->regs,
663
XLNX_CSU_DMA_ERR_DEBUG,
664
XLNX_CSU_DMA_R_MAX * 4);
665
memory_region_add_subregion(&s->iomem,
669
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
670
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
672
s->src_timer = ptimer_init(xlnx_csu_dma_src_timeout_hit,
673
s, PTIMER_POLICY_LEGACY);
675
s->attr = MEMTXATTRS_UNSPECIFIED;
677
s->r_size_last_word = 0;
680
static const VMStateDescription vmstate_xlnx_csu_dma = {
681
.name = TYPE_XLNX_CSU_DMA,
683
.minimum_version_id = 0,
684
.fields = (const VMStateField[]) {
685
VMSTATE_PTIMER(src_timer, XlnxCSUDMA),
686
VMSTATE_UINT16(width, XlnxCSUDMA),
687
VMSTATE_BOOL(is_dst, XlnxCSUDMA),
688
VMSTATE_BOOL(r_size_last_word, XlnxCSUDMA),
689
VMSTATE_UINT32_ARRAY(regs, XlnxCSUDMA, XLNX_CSU_DMA_R_MAX),
690
VMSTATE_END_OF_LIST(),
694
static Property xlnx_csu_dma_properties[] = {
702
DEFINE_PROP_UINT16("dma-width", XlnxCSUDMA, width, 4),
708
DEFINE_PROP_BOOL("is-dst", XlnxCSUDMA, is_dst, true),
709
DEFINE_PROP_LINK("stream-connected-dma", XlnxCSUDMA, tx_dev,
710
TYPE_STREAM_SINK, StreamSink *),
711
DEFINE_PROP_LINK("dma", XlnxCSUDMA, dma_mr,
712
TYPE_MEMORY_REGION, MemoryRegion *),
713
DEFINE_PROP_END_OF_LIST(),
716
static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data)
718
DeviceClass *dc = DEVICE_CLASS(klass);
719
StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
720
XlnxCSUDMAClass *xcdc = XLNX_CSU_DMA_CLASS(klass);
722
dc->reset = xlnx_csu_dma_reset;
723
dc->realize = xlnx_csu_dma_realize;
724
dc->vmsd = &vmstate_xlnx_csu_dma;
725
device_class_set_props(dc, xlnx_csu_dma_properties);
727
ssc->push = xlnx_csu_dma_stream_push;
728
ssc->can_push = xlnx_csu_dma_stream_can_push;
730
xcdc->read = xlnx_csu_dma_class_read;
733
static void xlnx_csu_dma_init(Object *obj)
735
XlnxCSUDMA *s = XLNX_CSU_DMA(obj);
737
memory_region_init(&s->iomem, obj, TYPE_XLNX_CSU_DMA,
738
XLNX_CSU_DMA_R_MAX * 4);
741
static const TypeInfo xlnx_csu_dma_info = {
742
.name = TYPE_XLNX_CSU_DMA,
743
.parent = TYPE_SYS_BUS_DEVICE,
744
.instance_size = sizeof(XlnxCSUDMA),
745
.class_init = xlnx_csu_dma_class_init,
746
.class_size = sizeof(XlnxCSUDMAClass),
747
.instance_init = xlnx_csu_dma_init,
748
.interfaces = (InterfaceInfo[]) {
749
{ TYPE_STREAM_SINK },
754
static void xlnx_csu_dma_register_types(void)
756
type_register_static(&xlnx_csu_dma_info);
759
type_init(xlnx_csu_dma_register_types)