/*
 * xlnx_dpdma.c
 *
 *  Copyright (C) 2015 : GreenSocs Ltd
 *      http://www.greensocs.com/ , email: info@greensocs.com
 *
 *  Developed by :
 *  Frederic Konrad   <fred.konrad@greensocs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "hw/dma/xlnx_dpdma.h"
#include "hw/irq.h"
#include "migration/vmstate.h"

#ifndef DEBUG_DPDMA
#define DEBUG_DPDMA 0
#endif

#define DPRINTF(fmt, ...) do {                                                 \
    if (DEBUG_DPDMA) {                                                         \
        qemu_log("xlnx_dpdma: " fmt , ## __VA_ARGS__);                         \
    }                                                                          \
} while (0)

/*
 * Registers offset for DPDMA.
 */
#define DPDMA_ERR_CTRL                        (0x0000)
#define DPDMA_ISR                             (0x0004 >> 2)
#define DPDMA_IMR                             (0x0008 >> 2)
#define DPDMA_IEN                             (0x000C >> 2)
#define DPDMA_IDS                             (0x0010 >> 2)
#define DPDMA_EISR                            (0x0014 >> 2)
#define DPDMA_EIMR                            (0x0018 >> 2)
#define DPDMA_EIEN                            (0x001C >> 2)
#define DPDMA_EIDS                            (0x0020 >> 2)
#define DPDMA_CNTL                            (0x0100 >> 2)

#define DPDMA_GBL                             (0x0104 >> 2)
#define DPDMA_GBL_TRG_CH(n)                   (1 << n)
#define DPDMA_GBL_RTRG_CH(n)                  (1 << 6 << n)

#define DPDMA_ALC0_CNTL                       (0x0108 >> 2)
#define DPDMA_ALC0_STATUS                     (0x010C >> 2)
#define DPDMA_ALC0_MAX                        (0x0110 >> 2)
#define DPDMA_ALC0_MIN                        (0x0114 >> 2)
#define DPDMA_ALC0_ACC                        (0x0118 >> 2)
#define DPDMA_ALC0_ACC_TRAN                   (0x011C >> 2)
#define DPDMA_ALC1_CNTL                       (0x0120 >> 2)
#define DPDMA_ALC1_STATUS                     (0x0124 >> 2)
#define DPDMA_ALC1_MAX                        (0x0128 >> 2)
#define DPDMA_ALC1_MIN                        (0x012C >> 2)
#define DPDMA_ALC1_ACC                        (0x0130 >> 2)
#define DPDMA_ALC1_ACC_TRAN                   (0x0134 >> 2)

#define DPDMA_DSCR_STRT_ADDRE_CH(n)           ((0x0200 + n * 0x100) >> 2)
#define DPDMA_DSCR_STRT_ADDR_CH(n)            ((0x0204 + n * 0x100) >> 2)
#define DPDMA_DSCR_NEXT_ADDRE_CH(n)           ((0x0208 + n * 0x100) >> 2)
#define DPDMA_DSCR_NEXT_ADDR_CH(n)            ((0x020C + n * 0x100) >> 2)
#define DPDMA_PYLD_CUR_ADDRE_CH(n)            ((0x0210 + n * 0x100) >> 2)
#define DPDMA_PYLD_CUR_ADDR_CH(n)             ((0x0214 + n * 0x100) >> 2)

#define DPDMA_CNTL_CH(n)                      ((0x0218 + n * 0x100) >> 2)
#define DPDMA_CNTL_CH_EN                      (1)
#define DPDMA_CNTL_CH_PAUSED                  (1 << 1)

#define DPDMA_STATUS_CH(n)                    ((0x021C + n * 0x100) >> 2)
#define DPDMA_STATUS_BURST_TYPE               (1 << 4)
#define DPDMA_STATUS_MODE                     (1 << 5)
#define DPDMA_STATUS_EN_CRC                   (1 << 6)
#define DPDMA_STATUS_LAST_DSCR                (1 << 7)
#define DPDMA_STATUS_LDSCR_FRAME              (1 << 8)
#define DPDMA_STATUS_IGNR_DONE                (1 << 9)
#define DPDMA_STATUS_DSCR_DONE                (1 << 10)
#define DPDMA_STATUS_EN_DSCR_UP               (1 << 11)
#define DPDMA_STATUS_EN_DSCR_INTR             (1 << 12)
#define DPDMA_STATUS_PREAMBLE_OFF             (13)

#define DPDMA_VDO_CH(n)                       ((0x0220 + n * 0x100) >> 2)
#define DPDMA_PYLD_SZ_CH(n)                   ((0x0224 + n * 0x100) >> 2)
#define DPDMA_DSCR_ID_CH(n)                   ((0x0228 + n * 0x100) >> 2)

/*
 * Descriptor control field.
 */
#define CONTROL_PREAMBLE_VALUE                0xA5

#define DSCR_CTRL_PREAMBLE                    0xFF
#define DSCR_CTRL_EN_DSCR_DONE_INTR           (1 << 8)
#define DSCR_CTRL_EN_DSCR_UPDATE              (1 << 9)
#define DSCR_CTRL_IGNORE_DONE                 (1 << 10)
#define DSCR_CTRL_AXI_BURST_TYPE              (1 << 11)
#define DSCR_CTRL_AXCACHE                     (0x0F << 12)
#define DSCR_CTRL_AXPROT                      (0x2 << 16)
#define DSCR_CTRL_DESCRIPTOR_MODE             (1 << 18)
#define DSCR_CTRL_LAST_DESCRIPTOR             (1 << 19)
#define DSCR_CTRL_ENABLE_CRC                  (1 << 20)
#define DSCR_CTRL_LAST_DESCRIPTOR_OF_FRAME    (1 << 21)

/*
 * Descriptor timestamp field.
 */
#define STATUS_DONE                           (1 << 31)

#define DPDMA_FRAG_MAX_SZ                     (4096)

enum DPDMABurstType {
    DPDMA_INCR = 0,
    DPDMA_FIXED = 1
};

enum DPDMAMode {
    DPDMA_CONTIGOUS = 0,
    DPDMA_FRAGMENTED = 1
};

struct DPDMADescriptor {
    uint32_t control;
    uint32_t descriptor_id;
    /* transfer size in byte. */
    uint32_t xfer_size;
    uint32_t line_size_stride;
    uint32_t timestamp_lsb;
    uint32_t timestamp_msb;
    /* contains extension for both descriptor and source. */
    uint32_t address_extension;
    uint32_t next_descriptor;
    uint32_t source_address;
    uint32_t address_extension_23;
    uint32_t address_extension_45;
    uint32_t source_address2;
    uint32_t source_address3;
    uint32_t source_address4;
    uint32_t source_address5;
    uint32_t crc;
};

typedef enum DPDMABurstType DPDMABurstType;
typedef enum DPDMAMode DPDMAMode;
typedef struct DPDMADescriptor DPDMADescriptor;

static bool xlnx_dpdma_desc_is_last(DPDMADescriptor *desc)
{
    return ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR) != 0);
}

static bool xlnx_dpdma_desc_is_last_of_frame(DPDMADescriptor *desc)
{
    return ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR_OF_FRAME) != 0);
}

static uint64_t xlnx_dpdma_desc_get_source_address(DPDMADescriptor *desc,
                                                     uint8_t frag)
{
    uint64_t addr = 0;
    assert(frag < 5);

    switch (frag) {
    case 0:
        addr = (uint64_t)desc->source_address
            + (extract64(desc->address_extension, 16, 16) << 32);
        break;
    case 1:
        addr = (uint64_t)desc->source_address2
            + (extract64(desc->address_extension_23, 0, 16) << 32);
        break;
    case 2:
        addr = (uint64_t)desc->source_address3
            + (extract64(desc->address_extension_23, 16, 16) << 32);
        break;
    case 3:
        addr = (uint64_t)desc->source_address4
            + (extract64(desc->address_extension_45, 0, 16) << 32);
        break;
    case 4:
        addr = (uint64_t)desc->source_address5
            + (extract64(desc->address_extension_45, 16, 16) << 32);
        break;
    default:
        addr = 0;
        break;
    }

    return addr;
}

static uint32_t xlnx_dpdma_desc_get_transfer_size(DPDMADescriptor *desc)
{
    return desc->xfer_size;
}

static uint32_t xlnx_dpdma_desc_get_line_size(DPDMADescriptor *desc)
{
    return extract32(desc->line_size_stride, 0, 18);
}

static uint32_t xlnx_dpdma_desc_get_line_stride(DPDMADescriptor *desc)
{
    return extract32(desc->line_size_stride, 18, 14) * 16;
}

static inline bool xlnx_dpdma_desc_crc_enabled(DPDMADescriptor *desc)
{
    return (desc->control & DSCR_CTRL_ENABLE_CRC) != 0;
}

static inline bool xlnx_dpdma_desc_check_crc(DPDMADescriptor *desc)
{
    uint32_t *p = (uint32_t *)desc;
    uint32_t crc = 0;
    uint8_t i;

    /*
     * CRC is calculated on the whole descriptor except the last 32bits word
     * using 32bits addition.
     */
    for (i = 0; i < 15; i++) {
        crc += p[i];
    }

    return crc == desc->crc;
}

static inline bool xlnx_dpdma_desc_completion_interrupt(DPDMADescriptor *desc)
{
    return (desc->control & DSCR_CTRL_EN_DSCR_DONE_INTR) != 0;
}

static inline bool xlnx_dpdma_desc_is_valid(DPDMADescriptor *desc)
{
    return (desc->control & DSCR_CTRL_PREAMBLE) == CONTROL_PREAMBLE_VALUE;
}

static inline bool xlnx_dpdma_desc_is_contiguous(DPDMADescriptor *desc)
{
    return (desc->control & DSCR_CTRL_DESCRIPTOR_MODE) == 0;
}

static inline bool xlnx_dpdma_desc_update_enabled(DPDMADescriptor *desc)
{
    return (desc->control & DSCR_CTRL_EN_DSCR_UPDATE) != 0;
}

static inline void xlnx_dpdma_desc_set_done(DPDMADescriptor *desc)
{
    desc->timestamp_msb |= STATUS_DONE;
}

static inline bool xlnx_dpdma_desc_is_already_done(DPDMADescriptor *desc)
{
    return (desc->timestamp_msb & STATUS_DONE) != 0;
}

static inline bool xlnx_dpdma_desc_ignore_done_bit(DPDMADescriptor *desc)
{
    return (desc->control & DSCR_CTRL_IGNORE_DONE) != 0;
}

static const VMStateDescription vmstate_xlnx_dpdma = {
    .name = TYPE_XLNX_DPDMA,
    .version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32_ARRAY(registers, XlnxDPDMAState,
                             XLNX_DPDMA_REG_ARRAY_SIZE),
        VMSTATE_BOOL_ARRAY(operation_finished, XlnxDPDMAState, 6),
        VMSTATE_END_OF_LIST()
    }
};

static void xlnx_dpdma_update_irq(XlnxDPDMAState *s)
{
    bool flags;

    flags = ((s->registers[DPDMA_ISR] & (~s->registers[DPDMA_IMR]))
          || (s->registers[DPDMA_EISR] & (~s->registers[DPDMA_EIMR])));
    qemu_set_irq(s->irq, flags);
}

static uint64_t xlnx_dpdma_descriptor_start_address(XlnxDPDMAState *s,
                                                      uint8_t channel)
{
    return (s->registers[DPDMA_DSCR_STRT_ADDRE_CH(channel)] << 16)
          + s->registers[DPDMA_DSCR_STRT_ADDR_CH(channel)];
}

static uint64_t xlnx_dpdma_descriptor_next_address(XlnxDPDMAState *s,
                                                     uint8_t channel)
{
    return ((uint64_t)s->registers[DPDMA_DSCR_NEXT_ADDRE_CH(channel)] << 32)
           + s->registers[DPDMA_DSCR_NEXT_ADDR_CH(channel)];
}

static bool xlnx_dpdma_is_channel_enabled(XlnxDPDMAState *s,
                                            uint8_t channel)
{
    return (s->registers[DPDMA_CNTL_CH(channel)] & DPDMA_CNTL_CH_EN) != 0;
}

static bool xlnx_dpdma_is_channel_paused(XlnxDPDMAState *s,
                                           uint8_t channel)
{
    return (s->registers[DPDMA_CNTL_CH(channel)] & DPDMA_CNTL_CH_PAUSED) != 0;
}

static inline bool xlnx_dpdma_is_channel_retriggered(XlnxDPDMAState *s,
                                                       uint8_t channel)
{
    /* Clear the retriggered bit after reading it. */
    bool channel_is_retriggered = s->registers[DPDMA_GBL]
                                & DPDMA_GBL_RTRG_CH(channel);
    s->registers[DPDMA_GBL] &= ~DPDMA_GBL_RTRG_CH(channel);
    return channel_is_retriggered;
}

static inline bool xlnx_dpdma_is_channel_triggered(XlnxDPDMAState *s,
                                                     uint8_t channel)
{
    return s->registers[DPDMA_GBL] & DPDMA_GBL_TRG_CH(channel);
}

static void xlnx_dpdma_update_desc_info(XlnxDPDMAState *s, uint8_t channel,
                                          DPDMADescriptor *desc)
{
    s->registers[DPDMA_DSCR_NEXT_ADDRE_CH(channel)] =
                                extract32(desc->address_extension, 0, 16);
    s->registers[DPDMA_DSCR_NEXT_ADDR_CH(channel)] = desc->next_descriptor;
    s->registers[DPDMA_PYLD_CUR_ADDRE_CH(channel)] =
                                extract32(desc->address_extension, 16, 16);
    s->registers[DPDMA_PYLD_CUR_ADDR_CH(channel)] = desc->source_address;
    s->registers[DPDMA_VDO_CH(channel)] =
                                extract32(desc->line_size_stride, 18, 14)
                                + (extract32(desc->line_size_stride, 0, 18)
                                  << 14);
    s->registers[DPDMA_PYLD_SZ_CH(channel)] = desc->xfer_size;
    s->registers[DPDMA_DSCR_ID_CH(channel)] = desc->descriptor_id;

    /* Compute the status register with the descriptor information. */
    s->registers[DPDMA_STATUS_CH(channel)] =
                                extract32(desc->control, 0, 8) << 13;
    if ((desc->control & DSCR_CTRL_EN_DSCR_DONE_INTR) != 0) {
        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_EN_DSCR_INTR;
    }
    if ((desc->control & DSCR_CTRL_EN_DSCR_UPDATE) != 0) {
        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_EN_DSCR_UP;
    }
    if ((desc->timestamp_msb & STATUS_DONE) != 0) {
        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_DSCR_DONE;
    }
    if ((desc->control & DSCR_CTRL_IGNORE_DONE) != 0) {
        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_IGNR_DONE;
    }
    if ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR_OF_FRAME) != 0) {
        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_LDSCR_FRAME;
    }
    if ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR) != 0) {
        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_LAST_DSCR;
    }
    if ((desc->control & DSCR_CTRL_ENABLE_CRC) != 0) {
        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_EN_CRC;
    }
    if ((desc->control & DSCR_CTRL_DESCRIPTOR_MODE) != 0) {
        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_MODE;
    }
    if ((desc->control & DSCR_CTRL_AXI_BURST_TYPE) != 0) {
        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_BURST_TYPE;
    }
}

static void xlnx_dpdma_dump_descriptor(DPDMADescriptor *desc)
{
    if (DEBUG_DPDMA) {
        qemu_log("DUMP DESCRIPTOR:\n");
        qemu_hexdump(stdout, "", desc, sizeof(DPDMADescriptor));
    }
}

static uint64_t xlnx_dpdma_read(void *opaque, hwaddr offset,
                                unsigned size)
{
    XlnxDPDMAState *s = XLNX_DPDMA(opaque);

    DPRINTF("read @%" HWADDR_PRIx "\n", offset);
    offset = offset >> 2;

    switch (offset) {
    /*
     * Trying to read a write only register.
     */
    case DPDMA_GBL:
        return 0;
    default:
        assert(offset <= (0xFFC >> 2));
        return s->registers[offset];
    }
    return 0;
}

static void xlnx_dpdma_write(void *opaque, hwaddr offset,
                               uint64_t value, unsigned size)
{
    XlnxDPDMAState *s = XLNX_DPDMA(opaque);

    DPRINTF("write @%" HWADDR_PRIx " = %" PRIx64 "\n", offset, value);
    offset = offset >> 2;

    switch (offset) {
    case DPDMA_ISR:
        s->registers[DPDMA_ISR] &= ~value;
        xlnx_dpdma_update_irq(s);
        break;
    case DPDMA_IEN:
        s->registers[DPDMA_IMR] &= ~value;
        break;
    case DPDMA_IDS:
        s->registers[DPDMA_IMR] |= value;
        break;
    case DPDMA_EISR:
        s->registers[DPDMA_EISR] &= ~value;
        xlnx_dpdma_update_irq(s);
        break;
    case DPDMA_EIEN:
        s->registers[DPDMA_EIMR] &= ~value;
        break;
    case DPDMA_EIDS:
        s->registers[DPDMA_EIMR] |= value;
        break;
    case DPDMA_IMR:
    case DPDMA_EIMR:
    case DPDMA_DSCR_NEXT_ADDRE_CH(0):
    case DPDMA_DSCR_NEXT_ADDRE_CH(1):
    case DPDMA_DSCR_NEXT_ADDRE_CH(2):
    case DPDMA_DSCR_NEXT_ADDRE_CH(3):
    case DPDMA_DSCR_NEXT_ADDRE_CH(4):
    case DPDMA_DSCR_NEXT_ADDRE_CH(5):
    case DPDMA_DSCR_NEXT_ADDR_CH(0):
    case DPDMA_DSCR_NEXT_ADDR_CH(1):
    case DPDMA_DSCR_NEXT_ADDR_CH(2):
    case DPDMA_DSCR_NEXT_ADDR_CH(3):
    case DPDMA_DSCR_NEXT_ADDR_CH(4):
    case DPDMA_DSCR_NEXT_ADDR_CH(5):
    case DPDMA_PYLD_CUR_ADDRE_CH(0):
    case DPDMA_PYLD_CUR_ADDRE_CH(1):
    case DPDMA_PYLD_CUR_ADDRE_CH(2):
    case DPDMA_PYLD_CUR_ADDRE_CH(3):
    case DPDMA_PYLD_CUR_ADDRE_CH(4):
    case DPDMA_PYLD_CUR_ADDRE_CH(5):
    case DPDMA_PYLD_CUR_ADDR_CH(0):
    case DPDMA_PYLD_CUR_ADDR_CH(1):
    case DPDMA_PYLD_CUR_ADDR_CH(2):
    case DPDMA_PYLD_CUR_ADDR_CH(3):
    case DPDMA_PYLD_CUR_ADDR_CH(4):
    case DPDMA_PYLD_CUR_ADDR_CH(5):
    case DPDMA_STATUS_CH(0):
    case DPDMA_STATUS_CH(1):
    case DPDMA_STATUS_CH(2):
    case DPDMA_STATUS_CH(3):
    case DPDMA_STATUS_CH(4):
    case DPDMA_STATUS_CH(5):
    case DPDMA_VDO_CH(0):
    case DPDMA_VDO_CH(1):
    case DPDMA_VDO_CH(2):
    case DPDMA_VDO_CH(3):
    case DPDMA_VDO_CH(4):
    case DPDMA_VDO_CH(5):
    case DPDMA_PYLD_SZ_CH(0):
    case DPDMA_PYLD_SZ_CH(1):
    case DPDMA_PYLD_SZ_CH(2):
    case DPDMA_PYLD_SZ_CH(3):
    case DPDMA_PYLD_SZ_CH(4):
    case DPDMA_PYLD_SZ_CH(5):
    case DPDMA_DSCR_ID_CH(0):
    case DPDMA_DSCR_ID_CH(1):
    case DPDMA_DSCR_ID_CH(2):
    case DPDMA_DSCR_ID_CH(3):
    case DPDMA_DSCR_ID_CH(4):
    case DPDMA_DSCR_ID_CH(5):
        /*
         * Trying to write to a read only register..
         */
        break;
    case DPDMA_GBL:
        /*
         * This is a write only register so it's read as zero in the read
         * callback.
         * We store the value anyway so we can know if the channel is
         * enabled.
         */
        s->registers[offset] |= value & 0x00000FFF;
        break;
    case DPDMA_DSCR_STRT_ADDRE_CH(0):
    case DPDMA_DSCR_STRT_ADDRE_CH(1):
    case DPDMA_DSCR_STRT_ADDRE_CH(2):
    case DPDMA_DSCR_STRT_ADDRE_CH(3):
    case DPDMA_DSCR_STRT_ADDRE_CH(4):
    case DPDMA_DSCR_STRT_ADDRE_CH(5):
        value &= 0x0000FFFF;
        s->registers[offset] = value;
        break;
    case DPDMA_CNTL_CH(0):
        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(0);
        value &= 0x3FFFFFFF;
        s->registers[offset] = value;
        break;
    case DPDMA_CNTL_CH(1):
        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(1);
        value &= 0x3FFFFFFF;
        s->registers[offset] = value;
        break;
    case DPDMA_CNTL_CH(2):
        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(2);
        value &= 0x3FFFFFFF;
        s->registers[offset] = value;
        break;
    case DPDMA_CNTL_CH(3):
        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(3);
        value &= 0x3FFFFFFF;
        s->registers[offset] = value;
        break;
    case DPDMA_CNTL_CH(4):
        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(4);
        value &= 0x3FFFFFFF;
        s->registers[offset] = value;
        break;
    case DPDMA_CNTL_CH(5):
        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(5);
        value &= 0x3FFFFFFF;
        s->registers[offset] = value;
        break;
    default:
        assert(offset <= (0xFFC >> 2));
        s->registers[offset] = value;
        break;
    }
}

static const MemoryRegionOps dma_ops = {
    .read = xlnx_dpdma_read,
    .write = xlnx_dpdma_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void xlnx_dpdma_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    XlnxDPDMAState *s = XLNX_DPDMA(obj);

    memory_region_init_io(&s->iomem, obj, &dma_ops, s,
                          TYPE_XLNX_DPDMA, 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->irq);
}

static void xlnx_dpdma_reset(DeviceState *dev)
{
    XlnxDPDMAState *s = XLNX_DPDMA(dev);
    size_t i;

    memset(s->registers, 0, sizeof(s->registers));
    s->registers[DPDMA_IMR] =  0x07FFFFFF;
    s->registers[DPDMA_EIMR] = 0xFFFFFFFF;
    s->registers[DPDMA_ALC0_MIN] = 0x0000FFFF;
    s->registers[DPDMA_ALC1_MIN] = 0x0000FFFF;

    for (i = 0; i < 6; i++) {
        s->data[i] = NULL;
        s->operation_finished[i] = true;
    }
}

static void xlnx_dpdma_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->vmsd = &vmstate_xlnx_dpdma;
    dc->reset = xlnx_dpdma_reset;
}

static const TypeInfo xlnx_dpdma_info = {
    .name          = TYPE_XLNX_DPDMA,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(XlnxDPDMAState),
    .instance_init = xlnx_dpdma_init,
    .class_init    = xlnx_dpdma_class_init,
};

static void xlnx_dpdma_register_types(void)
{
    type_register_static(&xlnx_dpdma_info);
}

size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel,
                                    bool one_desc)
{
    uint64_t desc_addr;
    uint64_t source_addr[6];
    DPDMADescriptor desc;
    bool done = false;
    size_t ptr = 0;

    assert(channel <= 5);

    DPRINTF("start dpdma channel 0x%" PRIX8 "\n", channel);

    if (!xlnx_dpdma_is_channel_triggered(s, channel)) {
        DPRINTF("Channel isn't triggered..\n");
        return 0;
    }

    if (!xlnx_dpdma_is_channel_enabled(s, channel)) {
        DPRINTF("Channel isn't enabled..\n");
        return 0;
    }

    if (xlnx_dpdma_is_channel_paused(s, channel)) {
        DPRINTF("Channel is paused..\n");
        return 0;
    }

    do {
        if ((s->operation_finished[channel])
          || xlnx_dpdma_is_channel_retriggered(s, channel)) {
            desc_addr = xlnx_dpdma_descriptor_start_address(s, channel);
            s->operation_finished[channel] = false;
        } else {
            desc_addr = xlnx_dpdma_descriptor_next_address(s, channel);
        }

        if (dma_memory_read(&address_space_memory, desc_addr, &desc,
                            sizeof(DPDMADescriptor), MEMTXATTRS_UNSPECIFIED)) {
            s->registers[DPDMA_EISR] |= ((1 << 1) << channel);
            xlnx_dpdma_update_irq(s);
            s->operation_finished[channel] = true;
            DPRINTF("Can't get the descriptor.\n");
            break;
        }

        xlnx_dpdma_update_desc_info(s, channel, &desc);

#ifdef DEBUG_DPDMA
        xlnx_dpdma_dump_descriptor(&desc);
#endif

        DPRINTF("location of the descriptor: %" PRIx64 "\n", desc_addr);
        if (!xlnx_dpdma_desc_is_valid(&desc)) {
            s->registers[DPDMA_EISR] |= ((1 << 7) << channel);
            xlnx_dpdma_update_irq(s);
            s->operation_finished[channel] = true;
            DPRINTF("Invalid descriptor..\n");
            break;
        }

        if (xlnx_dpdma_desc_crc_enabled(&desc)
            && !xlnx_dpdma_desc_check_crc(&desc)) {
            s->registers[DPDMA_EISR] |= ((1 << 13) << channel);
            xlnx_dpdma_update_irq(s);
            s->operation_finished[channel] = true;
            DPRINTF("Bad CRC for descriptor..\n");
            break;
        }

        if (xlnx_dpdma_desc_is_already_done(&desc)
            && !xlnx_dpdma_desc_ignore_done_bit(&desc)) {
            /* We are trying to process an already processed descriptor. */
            s->registers[DPDMA_EISR] |= ((1 << 25) << channel);
            xlnx_dpdma_update_irq(s);
            s->operation_finished[channel] = true;
            DPRINTF("Already processed descriptor..\n");
            break;
        }

        done = xlnx_dpdma_desc_is_last(&desc)
             || xlnx_dpdma_desc_is_last_of_frame(&desc);

        s->operation_finished[channel] = done;
        if (s->data[channel]) {
            int64_t transfer_len = xlnx_dpdma_desc_get_transfer_size(&desc);
            uint32_t line_size = xlnx_dpdma_desc_get_line_size(&desc);
            uint32_t line_stride = xlnx_dpdma_desc_get_line_stride(&desc);
            if (xlnx_dpdma_desc_is_contiguous(&desc)) {
                source_addr[0] = xlnx_dpdma_desc_get_source_address(&desc, 0);
                while (transfer_len != 0) {
                    if (dma_memory_read(&address_space_memory,
                                        source_addr[0],
                                        &s->data[channel][ptr],
                                        line_size,
                                        MEMTXATTRS_UNSPECIFIED)) {
                        s->registers[DPDMA_ISR] |= ((1 << 12) << channel);
                        xlnx_dpdma_update_irq(s);
                        DPRINTF("Can't get data.\n");
                        break;
                    }
                    ptr += line_size;
                    transfer_len -= line_size;
                    source_addr[0] += line_stride;
                }
            } else {
                DPRINTF("Source address:\n");
                int frag;
                for (frag = 0; frag < 5; frag++) {
                    source_addr[frag] =
                          xlnx_dpdma_desc_get_source_address(&desc, frag);
                    DPRINTF("Fragment %u: %" PRIx64 "\n", frag + 1,
                            source_addr[frag]);
                }

                frag = 0;
                while ((transfer_len < 0) && (frag < 5)) {
                    size_t fragment_len = DPDMA_FRAG_MAX_SZ
                                    - (source_addr[frag] % DPDMA_FRAG_MAX_SZ);

                    if (dma_memory_read(&address_space_memory,
                                        source_addr[frag],
                                        &(s->data[channel][ptr]),
                                        fragment_len,
                                        MEMTXATTRS_UNSPECIFIED)) {
                        s->registers[DPDMA_ISR] |= ((1 << 12) << channel);
                        xlnx_dpdma_update_irq(s);
                        DPRINTF("Can't get data.\n");
                        break;
                    }
                    ptr += fragment_len;
                    transfer_len -= fragment_len;
                    frag += 1;
                }
            }
        }

        if (xlnx_dpdma_desc_update_enabled(&desc)) {
            /* The descriptor need to be updated when it's completed. */
            DPRINTF("update the descriptor with the done flag set.\n");
            xlnx_dpdma_desc_set_done(&desc);
            dma_memory_write(&address_space_memory, desc_addr, &desc,
                             sizeof(DPDMADescriptor), MEMTXATTRS_UNSPECIFIED);
        }

        if (xlnx_dpdma_desc_completion_interrupt(&desc)) {
            DPRINTF("completion interrupt enabled!\n");
            s->registers[DPDMA_ISR] |= (1 << channel);
            xlnx_dpdma_update_irq(s);
        }

    } while (!done && !one_desc);

    return ptr;
}

void xlnx_dpdma_set_host_data_location(XlnxDPDMAState *s, uint8_t channel,
                                         void *p)
{
    if (!s) {
        qemu_log_mask(LOG_UNIMP, "DPDMA client not attached to valid DPDMA"
                      " instance\n");
        return;
    }

    assert(channel <= 5);
    s->data[channel] = p;
}

void xlnx_dpdma_trigger_vsync_irq(XlnxDPDMAState *s)
{
    s->registers[DPDMA_ISR] |= (1 << 27);
    xlnx_dpdma_update_irq(s);
}

type_init(xlnx_dpdma_register_types)
