/*
 * 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/core/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, const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->vmsd = &vmstate_xlnx_dpdma;
    device_class_set_legacy_reset(dc, 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);
}

static MemTxResult xlnx_dpdma_read_descriptor(XlnxDPDMAState *s,
                                              uint64_t desc_addr,
                                              DPDMADescriptor *desc)
{
    MemTxResult res = dma_memory_read(&address_space_memory, desc_addr,
                                      desc, sizeof(DPDMADescriptor),
                                      MEMTXATTRS_UNSPECIFIED);
    if (res) {
        return res;
    }

    /* Convert from LE into host endianness.  */
    desc->control = le32_to_cpu(desc->control);
    desc->descriptor_id = le32_to_cpu(desc->descriptor_id);
    desc->xfer_size = le32_to_cpu(desc->xfer_size);
    desc->line_size_stride = le32_to_cpu(desc->line_size_stride);
    desc->timestamp_lsb = le32_to_cpu(desc->timestamp_lsb);
    desc->timestamp_msb = le32_to_cpu(desc->timestamp_msb);
    desc->address_extension = le32_to_cpu(desc->address_extension);
    desc->next_descriptor = le32_to_cpu(desc->next_descriptor);
    desc->source_address = le32_to_cpu(desc->source_address);
    desc->address_extension_23 = le32_to_cpu(desc->address_extension_23);
    desc->address_extension_45 = le32_to_cpu(desc->address_extension_45);
    desc->source_address2 = le32_to_cpu(desc->source_address2);
    desc->source_address3 = le32_to_cpu(desc->source_address3);
    desc->source_address4 = le32_to_cpu(desc->source_address4);
    desc->source_address5 = le32_to_cpu(desc->source_address5);
    desc->crc = le32_to_cpu(desc->crc);

    return res;
}

static MemTxResult xlnx_dpdma_write_descriptor(uint64_t desc_addr,
                                               DPDMADescriptor *desc)
{
    DPDMADescriptor tmp_desc = *desc;

    /* Convert from host endianness into LE.  */
    tmp_desc.control = cpu_to_le32(tmp_desc.control);
    tmp_desc.descriptor_id = cpu_to_le32(tmp_desc.descriptor_id);
    tmp_desc.xfer_size = cpu_to_le32(tmp_desc.xfer_size);
    tmp_desc.line_size_stride = cpu_to_le32(tmp_desc.line_size_stride);
    tmp_desc.timestamp_lsb = cpu_to_le32(tmp_desc.timestamp_lsb);
    tmp_desc.timestamp_msb = cpu_to_le32(tmp_desc.timestamp_msb);
    tmp_desc.address_extension = cpu_to_le32(tmp_desc.address_extension);
    tmp_desc.next_descriptor = cpu_to_le32(tmp_desc.next_descriptor);
    tmp_desc.source_address = cpu_to_le32(tmp_desc.source_address);
    tmp_desc.address_extension_23 = cpu_to_le32(tmp_desc.address_extension_23);
    tmp_desc.address_extension_45 = cpu_to_le32(tmp_desc.address_extension_45);
    tmp_desc.source_address2 = cpu_to_le32(tmp_desc.source_address2);
    tmp_desc.source_address3 = cpu_to_le32(tmp_desc.source_address3);
    tmp_desc.source_address4 = cpu_to_le32(tmp_desc.source_address4);
    tmp_desc.source_address5 = cpu_to_le32(tmp_desc.source_address5);
    tmp_desc.crc = cpu_to_le32(tmp_desc.crc);

    return dma_memory_write(&address_space_memory, desc_addr, &tmp_desc,
                            sizeof(DPDMADescriptor), MEMTXATTRS_UNSPECIFIED);
}

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 (xlnx_dpdma_read_descriptor(s, desc_addr, &desc)) {
            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);
            if (xlnx_dpdma_write_descriptor(desc_addr, &desc)) {
                DPRINTF("Can't write the descriptor.\n");
                /* TODO: check hardware behaviour for memory write failure */
            }
        }

        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)
