xref: /qemu/hw/dma/xilinx_axidma.c (revision db1015e92e04835c9eb50c29625fe566d1202dbd)
1 /*
2  * QEMU model of Xilinx AXI-DMA block.
3  *
4  * Copyright (c) 2011 Edgar E. Iglesias.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 #include "qemu/osdep.h"
26 #include "hw/sysbus.h"
27 #include "qapi/error.h"
28 #include "qemu/timer.h"
29 #include "hw/hw.h"
30 #include "hw/irq.h"
31 #include "hw/ptimer.h"
32 #include "hw/qdev-properties.h"
33 #include "qemu/log.h"
34 #include "qemu/module.h"
35 
36 #include "sysemu/dma.h"
37 #include "hw/stream.h"
38 #include "qom/object.h"
39 
40 #define D(x)
41 
42 #define TYPE_XILINX_AXI_DMA "xlnx.axi-dma"
43 #define TYPE_XILINX_AXI_DMA_DATA_STREAM "xilinx-axi-dma-data-stream"
44 #define TYPE_XILINX_AXI_DMA_CONTROL_STREAM "xilinx-axi-dma-control-stream"
45 
46 typedef struct XilinxAXIDMA XilinxAXIDMA;
47 #define XILINX_AXI_DMA(obj) \
48      OBJECT_CHECK(XilinxAXIDMA, (obj), TYPE_XILINX_AXI_DMA)
49 
50 typedef struct XilinxAXIDMAStreamSlave XilinxAXIDMAStreamSlave;
51 #define XILINX_AXI_DMA_DATA_STREAM(obj) \
52      OBJECT_CHECK(XilinxAXIDMAStreamSlave, (obj),\
53      TYPE_XILINX_AXI_DMA_DATA_STREAM)
54 
55 #define XILINX_AXI_DMA_CONTROL_STREAM(obj) \
56      OBJECT_CHECK(XilinxAXIDMAStreamSlave, (obj),\
57      TYPE_XILINX_AXI_DMA_CONTROL_STREAM)
58 
59 #define R_DMACR             (0x00 / 4)
60 #define R_DMASR             (0x04 / 4)
61 #define R_CURDESC           (0x08 / 4)
62 #define R_TAILDESC          (0x10 / 4)
63 #define R_MAX               (0x30 / 4)
64 
65 #define CONTROL_PAYLOAD_WORDS 5
66 #define CONTROL_PAYLOAD_SIZE (CONTROL_PAYLOAD_WORDS * (sizeof(uint32_t)))
67 
68 
69 enum {
70     DMACR_RUNSTOP = 1,
71     DMACR_TAILPTR_MODE = 2,
72     DMACR_RESET = 4
73 };
74 
75 enum {
76     DMASR_HALTED = 1,
77     DMASR_IDLE  = 2,
78     DMASR_IOC_IRQ  = 1 << 12,
79     DMASR_DLY_IRQ  = 1 << 13,
80 
81     DMASR_IRQ_MASK = 7 << 12
82 };
83 
84 struct SDesc {
85     uint64_t nxtdesc;
86     uint64_t buffer_address;
87     uint64_t reserved;
88     uint32_t control;
89     uint32_t status;
90     uint8_t app[CONTROL_PAYLOAD_SIZE];
91 };
92 
93 enum {
94     SDESC_CTRL_EOF = (1 << 26),
95     SDESC_CTRL_SOF = (1 << 27),
96 
97     SDESC_CTRL_LEN_MASK = (1 << 23) - 1
98 };
99 
100 enum {
101     SDESC_STATUS_EOF = (1 << 26),
102     SDESC_STATUS_SOF_BIT = 27,
103     SDESC_STATUS_SOF = (1 << SDESC_STATUS_SOF_BIT),
104     SDESC_STATUS_COMPLETE = (1 << 31)
105 };
106 
107 struct Stream {
108     struct XilinxAXIDMA *dma;
109     ptimer_state *ptimer;
110     qemu_irq irq;
111 
112     int nr;
113 
114     bool sof;
115     struct SDesc desc;
116     unsigned int complete_cnt;
117     uint32_t regs[R_MAX];
118     uint8_t app[20];
119     unsigned char txbuf[16 * 1024];
120 };
121 
122 struct XilinxAXIDMAStreamSlave {
123     Object parent;
124 
125     struct XilinxAXIDMA *dma;
126 };
127 
128 struct XilinxAXIDMA {
129     SysBusDevice busdev;
130     MemoryRegion iomem;
131     MemoryRegion *dma_mr;
132     AddressSpace as;
133 
134     uint32_t freqhz;
135     StreamSlave *tx_data_dev;
136     StreamSlave *tx_control_dev;
137     XilinxAXIDMAStreamSlave rx_data_dev;
138     XilinxAXIDMAStreamSlave rx_control_dev;
139 
140     struct Stream streams[2];
141 
142     StreamCanPushNotifyFn notify;
143     void *notify_opaque;
144 };
145 
146 /*
147  * Helper calls to extract info from descriptors and other trivial
148  * state from regs.
149  */
150 static inline int stream_desc_sof(struct SDesc *d)
151 {
152     return d->control & SDESC_CTRL_SOF;
153 }
154 
155 static inline int stream_desc_eof(struct SDesc *d)
156 {
157     return d->control & SDESC_CTRL_EOF;
158 }
159 
160 static inline int stream_resetting(struct Stream *s)
161 {
162     return !!(s->regs[R_DMACR] & DMACR_RESET);
163 }
164 
165 static inline int stream_running(struct Stream *s)
166 {
167     return s->regs[R_DMACR] & DMACR_RUNSTOP;
168 }
169 
170 static inline int stream_idle(struct Stream *s)
171 {
172     return !!(s->regs[R_DMASR] & DMASR_IDLE);
173 }
174 
175 static void stream_reset(struct Stream *s)
176 {
177     s->regs[R_DMASR] = DMASR_HALTED;  /* starts up halted.  */
178     s->regs[R_DMACR] = 1 << 16; /* Starts with one in compl threshold.  */
179     s->sof = true;
180 }
181 
182 /* Map an offset addr into a channel index.  */
183 static inline int streamid_from_addr(hwaddr addr)
184 {
185     int sid;
186 
187     sid = addr / (0x30);
188     sid &= 1;
189     return sid;
190 }
191 
192 static void stream_desc_load(struct Stream *s, hwaddr addr)
193 {
194     struct SDesc *d = &s->desc;
195 
196     address_space_read(&s->dma->as, addr, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
197 
198     /* Convert from LE into host endianness.  */
199     d->buffer_address = le64_to_cpu(d->buffer_address);
200     d->nxtdesc = le64_to_cpu(d->nxtdesc);
201     d->control = le32_to_cpu(d->control);
202     d->status = le32_to_cpu(d->status);
203 }
204 
205 static void stream_desc_store(struct Stream *s, hwaddr addr)
206 {
207     struct SDesc *d = &s->desc;
208 
209     /* Convert from host endianness into LE.  */
210     d->buffer_address = cpu_to_le64(d->buffer_address);
211     d->nxtdesc = cpu_to_le64(d->nxtdesc);
212     d->control = cpu_to_le32(d->control);
213     d->status = cpu_to_le32(d->status);
214     address_space_write(&s->dma->as, addr, MEMTXATTRS_UNSPECIFIED,
215                         d, sizeof *d);
216 }
217 
218 static void stream_update_irq(struct Stream *s)
219 {
220     unsigned int pending, mask, irq;
221 
222     pending = s->regs[R_DMASR] & DMASR_IRQ_MASK;
223     mask = s->regs[R_DMACR] & DMASR_IRQ_MASK;
224 
225     irq = pending & mask;
226 
227     qemu_set_irq(s->irq, !!irq);
228 }
229 
230 static void stream_reload_complete_cnt(struct Stream *s)
231 {
232     unsigned int comp_th;
233     comp_th = (s->regs[R_DMACR] >> 16) & 0xff;
234     s->complete_cnt = comp_th;
235 }
236 
237 static void timer_hit(void *opaque)
238 {
239     struct Stream *s = opaque;
240 
241     stream_reload_complete_cnt(s);
242     s->regs[R_DMASR] |= DMASR_DLY_IRQ;
243     stream_update_irq(s);
244 }
245 
246 static void stream_complete(struct Stream *s)
247 {
248     unsigned int comp_delay;
249 
250     /* Start the delayed timer.  */
251     ptimer_transaction_begin(s->ptimer);
252     comp_delay = s->regs[R_DMACR] >> 24;
253     if (comp_delay) {
254         ptimer_stop(s->ptimer);
255         ptimer_set_count(s->ptimer, comp_delay);
256         ptimer_run(s->ptimer, 1);
257     }
258 
259     s->complete_cnt--;
260     if (s->complete_cnt == 0) {
261         /* Raise the IOC irq.  */
262         s->regs[R_DMASR] |= DMASR_IOC_IRQ;
263         stream_reload_complete_cnt(s);
264     }
265     ptimer_transaction_commit(s->ptimer);
266 }
267 
268 static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
269                                  StreamSlave *tx_control_dev)
270 {
271     uint32_t prev_d;
272     uint32_t txlen;
273     uint64_t addr;
274     bool eop;
275 
276     if (!stream_running(s) || stream_idle(s)) {
277         return;
278     }
279 
280     while (1) {
281         stream_desc_load(s, s->regs[R_CURDESC]);
282 
283         if (s->desc.status & SDESC_STATUS_COMPLETE) {
284             s->regs[R_DMASR] |= DMASR_HALTED;
285             break;
286         }
287 
288         if (stream_desc_sof(&s->desc)) {
289             stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app), true);
290         }
291 
292         txlen = s->desc.control & SDESC_CTRL_LEN_MASK;
293 
294         eop = stream_desc_eof(&s->desc);
295         addr = s->desc.buffer_address;
296         while (txlen) {
297             unsigned int len;
298 
299             len = txlen > sizeof s->txbuf ? sizeof s->txbuf : txlen;
300             address_space_read(&s->dma->as, addr,
301                                MEMTXATTRS_UNSPECIFIED,
302                                s->txbuf, len);
303             stream_push(tx_data_dev, s->txbuf, len, eop && len == txlen);
304             txlen -= len;
305             addr += len;
306         }
307 
308         if (eop) {
309             stream_complete(s);
310         }
311 
312         /* Update the descriptor.  */
313         s->desc.status = txlen | SDESC_STATUS_COMPLETE;
314         stream_desc_store(s, s->regs[R_CURDESC]);
315 
316         /* Advance.  */
317         prev_d = s->regs[R_CURDESC];
318         s->regs[R_CURDESC] = s->desc.nxtdesc;
319         if (prev_d == s->regs[R_TAILDESC]) {
320             s->regs[R_DMASR] |= DMASR_IDLE;
321             break;
322         }
323     }
324 }
325 
326 static size_t stream_process_s2mem(struct Stream *s, unsigned char *buf,
327                                    size_t len, bool eop)
328 {
329     uint32_t prev_d;
330     unsigned int rxlen;
331     size_t pos = 0;
332 
333     if (!stream_running(s) || stream_idle(s)) {
334         return 0;
335     }
336 
337     while (len) {
338         stream_desc_load(s, s->regs[R_CURDESC]);
339 
340         if (s->desc.status & SDESC_STATUS_COMPLETE) {
341             s->regs[R_DMASR] |= DMASR_HALTED;
342             break;
343         }
344 
345         rxlen = s->desc.control & SDESC_CTRL_LEN_MASK;
346         if (rxlen > len) {
347             /* It fits.  */
348             rxlen = len;
349         }
350 
351         address_space_write(&s->dma->as, s->desc.buffer_address,
352                             MEMTXATTRS_UNSPECIFIED, buf + pos, rxlen);
353         len -= rxlen;
354         pos += rxlen;
355 
356         /* Update the descriptor.  */
357         if (eop) {
358             stream_complete(s);
359             memcpy(s->desc.app, s->app, sizeof(s->desc.app));
360             s->desc.status |= SDESC_STATUS_EOF;
361         }
362 
363         s->desc.status |= s->sof << SDESC_STATUS_SOF_BIT;
364         s->desc.status |= SDESC_STATUS_COMPLETE;
365         stream_desc_store(s, s->regs[R_CURDESC]);
366         s->sof = eop;
367 
368         /* Advance.  */
369         prev_d = s->regs[R_CURDESC];
370         s->regs[R_CURDESC] = s->desc.nxtdesc;
371         if (prev_d == s->regs[R_TAILDESC]) {
372             s->regs[R_DMASR] |= DMASR_IDLE;
373             break;
374         }
375     }
376 
377     return pos;
378 }
379 
380 static void xilinx_axidma_reset(DeviceState *dev)
381 {
382     int i;
383     XilinxAXIDMA *s = XILINX_AXI_DMA(dev);
384 
385     for (i = 0; i < 2; i++) {
386         stream_reset(&s->streams[i]);
387     }
388 }
389 
390 static size_t
391 xilinx_axidma_control_stream_push(StreamSlave *obj, unsigned char *buf,
392                                   size_t len, bool eop)
393 {
394     XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(obj);
395     struct Stream *s = &cs->dma->streams[1];
396 
397     if (len != CONTROL_PAYLOAD_SIZE) {
398         hw_error("AXI DMA requires %d byte control stream payload\n",
399                  (int)CONTROL_PAYLOAD_SIZE);
400     }
401 
402     memcpy(s->app, buf, len);
403     return len;
404 }
405 
406 static bool
407 xilinx_axidma_data_stream_can_push(StreamSlave *obj,
408                                    StreamCanPushNotifyFn notify,
409                                    void *notify_opaque)
410 {
411     XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
412     struct Stream *s = &ds->dma->streams[1];
413 
414     if (!stream_running(s) || stream_idle(s)) {
415         ds->dma->notify = notify;
416         ds->dma->notify_opaque = notify_opaque;
417         return false;
418     }
419 
420     return true;
421 }
422 
423 static size_t
424 xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len,
425                                bool eop)
426 {
427     XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
428     struct Stream *s = &ds->dma->streams[1];
429     size_t ret;
430 
431     ret = stream_process_s2mem(s, buf, len, eop);
432     stream_update_irq(s);
433     return ret;
434 }
435 
436 static uint64_t axidma_read(void *opaque, hwaddr addr,
437                             unsigned size)
438 {
439     XilinxAXIDMA *d = opaque;
440     struct Stream *s;
441     uint32_t r = 0;
442     int sid;
443 
444     sid = streamid_from_addr(addr);
445     s = &d->streams[sid];
446 
447     addr = addr % 0x30;
448     addr >>= 2;
449     switch (addr) {
450         case R_DMACR:
451             /* Simulate one cycles reset delay.  */
452             s->regs[addr] &= ~DMACR_RESET;
453             r = s->regs[addr];
454             break;
455         case R_DMASR:
456             s->regs[addr] &= 0xffff;
457             s->regs[addr] |= (s->complete_cnt & 0xff) << 16;
458             s->regs[addr] |= (ptimer_get_count(s->ptimer) & 0xff) << 24;
459             r = s->regs[addr];
460             break;
461         default:
462             r = s->regs[addr];
463             D(qemu_log("%s ch=%d addr=" TARGET_FMT_plx " v=%x\n",
464                            __func__, sid, addr * 4, r));
465             break;
466     }
467     return r;
468 
469 }
470 
471 static void axidma_write(void *opaque, hwaddr addr,
472                          uint64_t value, unsigned size)
473 {
474     XilinxAXIDMA *d = opaque;
475     struct Stream *s;
476     int sid;
477 
478     sid = streamid_from_addr(addr);
479     s = &d->streams[sid];
480 
481     addr = addr % 0x30;
482     addr >>= 2;
483     switch (addr) {
484         case R_DMACR:
485             /* Tailptr mode is always on.  */
486             value |= DMACR_TAILPTR_MODE;
487             /* Remember our previous reset state.  */
488             value |= (s->regs[addr] & DMACR_RESET);
489             s->regs[addr] = value;
490 
491             if (value & DMACR_RESET) {
492                 stream_reset(s);
493             }
494 
495             if ((value & 1) && !stream_resetting(s)) {
496                 /* Start processing.  */
497                 s->regs[R_DMASR] &= ~(DMASR_HALTED | DMASR_IDLE);
498             }
499             stream_reload_complete_cnt(s);
500             break;
501 
502         case R_DMASR:
503             /* Mask away write to clear irq lines.  */
504             value &= ~(value & DMASR_IRQ_MASK);
505             s->regs[addr] = value;
506             break;
507 
508         case R_TAILDESC:
509             s->regs[addr] = value;
510             s->regs[R_DMASR] &= ~DMASR_IDLE; /* Not idle.  */
511             if (!sid) {
512                 stream_process_mem2s(s, d->tx_data_dev, d->tx_control_dev);
513             }
514             break;
515         default:
516             D(qemu_log("%s: ch=%d addr=" TARGET_FMT_plx " v=%x\n",
517                   __func__, sid, addr * 4, (unsigned)value));
518             s->regs[addr] = value;
519             break;
520     }
521     if (sid == 1 && d->notify) {
522         StreamCanPushNotifyFn notifytmp = d->notify;
523         d->notify = NULL;
524         notifytmp(d->notify_opaque);
525     }
526     stream_update_irq(s);
527 }
528 
529 static const MemoryRegionOps axidma_ops = {
530     .read = axidma_read,
531     .write = axidma_write,
532     .endianness = DEVICE_NATIVE_ENDIAN,
533 };
534 
535 static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
536 {
537     XilinxAXIDMA *s = XILINX_AXI_DMA(dev);
538     XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev);
539     XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
540                                                             &s->rx_control_dev);
541     int i;
542 
543     object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
544                              (Object **)&ds->dma,
545                              object_property_allow_set_link,
546                              OBJ_PROP_LINK_STRONG);
547     object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA,
548                              (Object **)&cs->dma,
549                              object_property_allow_set_link,
550                              OBJ_PROP_LINK_STRONG);
551     object_property_set_link(OBJECT(ds), "dma", OBJECT(s), &error_abort);
552     object_property_set_link(OBJECT(cs), "dma", OBJECT(s), &error_abort);
553 
554     for (i = 0; i < 2; i++) {
555         struct Stream *st = &s->streams[i];
556 
557         st->dma = s;
558         st->nr = i;
559         st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_DEFAULT);
560         ptimer_transaction_begin(st->ptimer);
561         ptimer_set_freq(st->ptimer, s->freqhz);
562         ptimer_transaction_commit(st->ptimer);
563     }
564 
565     address_space_init(&s->as,
566                        s->dma_mr ? s->dma_mr : get_system_memory(), "dma");
567 }
568 
569 static void xilinx_axidma_init(Object *obj)
570 {
571     XilinxAXIDMA *s = XILINX_AXI_DMA(obj);
572     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
573 
574     object_initialize_child(OBJECT(s), "axistream-connected-target",
575                             &s->rx_data_dev, TYPE_XILINX_AXI_DMA_DATA_STREAM);
576     object_initialize_child(OBJECT(s), "axistream-control-connected-target",
577                             &s->rx_control_dev,
578                             TYPE_XILINX_AXI_DMA_CONTROL_STREAM);
579     object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
580                              (Object **)&s->dma_mr,
581                              qdev_prop_allow_set_link_before_realize,
582                              OBJ_PROP_LINK_STRONG);
583 
584     sysbus_init_irq(sbd, &s->streams[0].irq);
585     sysbus_init_irq(sbd, &s->streams[1].irq);
586 
587     memory_region_init_io(&s->iomem, obj, &axidma_ops, s,
588                           "xlnx.axi-dma", R_MAX * 4 * 2);
589     sysbus_init_mmio(sbd, &s->iomem);
590 }
591 
592 static Property axidma_properties[] = {
593     DEFINE_PROP_UINT32("freqhz", XilinxAXIDMA, freqhz, 50000000),
594     DEFINE_PROP_LINK("axistream-connected", XilinxAXIDMA,
595                      tx_data_dev, TYPE_STREAM_SLAVE, StreamSlave *),
596     DEFINE_PROP_LINK("axistream-control-connected", XilinxAXIDMA,
597                      tx_control_dev, TYPE_STREAM_SLAVE, StreamSlave *),
598     DEFINE_PROP_END_OF_LIST(),
599 };
600 
601 static void axidma_class_init(ObjectClass *klass, void *data)
602 {
603     DeviceClass *dc = DEVICE_CLASS(klass);
604 
605     dc->realize = xilinx_axidma_realize,
606     dc->reset = xilinx_axidma_reset;
607     device_class_set_props(dc, axidma_properties);
608 }
609 
610 static StreamSlaveClass xilinx_axidma_data_stream_class = {
611     .push = xilinx_axidma_data_stream_push,
612     .can_push = xilinx_axidma_data_stream_can_push,
613 };
614 
615 static StreamSlaveClass xilinx_axidma_control_stream_class = {
616     .push = xilinx_axidma_control_stream_push,
617 };
618 
619 static void xilinx_axidma_stream_class_init(ObjectClass *klass, void *data)
620 {
621     StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
622 
623     ssc->push = ((StreamSlaveClass *)data)->push;
624     ssc->can_push = ((StreamSlaveClass *)data)->can_push;
625 }
626 
627 static const TypeInfo axidma_info = {
628     .name          = TYPE_XILINX_AXI_DMA,
629     .parent        = TYPE_SYS_BUS_DEVICE,
630     .instance_size = sizeof(XilinxAXIDMA),
631     .class_init    = axidma_class_init,
632     .instance_init = xilinx_axidma_init,
633 };
634 
635 static const TypeInfo xilinx_axidma_data_stream_info = {
636     .name          = TYPE_XILINX_AXI_DMA_DATA_STREAM,
637     .parent        = TYPE_OBJECT,
638     .instance_size = sizeof(struct XilinxAXIDMAStreamSlave),
639     .class_init    = xilinx_axidma_stream_class_init,
640     .class_data    = &xilinx_axidma_data_stream_class,
641     .interfaces = (InterfaceInfo[]) {
642         { TYPE_STREAM_SLAVE },
643         { }
644     }
645 };
646 
647 static const TypeInfo xilinx_axidma_control_stream_info = {
648     .name          = TYPE_XILINX_AXI_DMA_CONTROL_STREAM,
649     .parent        = TYPE_OBJECT,
650     .instance_size = sizeof(struct XilinxAXIDMAStreamSlave),
651     .class_init    = xilinx_axidma_stream_class_init,
652     .class_data    = &xilinx_axidma_control_stream_class,
653     .interfaces = (InterfaceInfo[]) {
654         { TYPE_STREAM_SLAVE },
655         { }
656     }
657 };
658 
659 static void xilinx_axidma_register_types(void)
660 {
661     type_register_static(&axidma_info);
662     type_register_static(&xilinx_axidma_data_stream_info);
663     type_register_static(&xilinx_axidma_control_stream_info);
664 }
665 
666 type_init(xilinx_axidma_register_types)
667