/*
 * Intel XScale PXA255/270 DMA controller.
 *
 * Copyright (c) 2006 Openedhand Ltd.
 * Copyright (c) 2006 Thorsten Zitterell
 * Written by Andrzej Zaborowski <balrog@zabor.org>
 *
 * This code is licenced under the GPL.
 */

#include "hw.h"
#include "pxa.h"

struct pxa2xx_dma_channel_s {
    target_phys_addr_t descr;
    target_phys_addr_t src;
    target_phys_addr_t dest;
    uint32_t cmd;
    uint32_t state;
    int request;
};

/* Allow the DMA to be used as a PIC.  */
typedef void (*pxa2xx_dma_handler_t)(void *opaque, int irq, int level);

struct pxa2xx_dma_state_s {
    pxa2xx_dma_handler_t handler;
    qemu_irq irq;

    uint32_t stopintr;
    uint32_t eorintr;
    uint32_t rasintr;
    uint32_t startintr;
    uint32_t endintr;

    uint32_t align;
    uint32_t pio;

    int channels;
    struct pxa2xx_dma_channel_s *chan;

    uint8_t *req;

    /* Flag to avoid recursive DMA invocations.  */
    int running;
};

#define PXA255_DMA_NUM_CHANNELS	16
#define PXA27X_DMA_NUM_CHANNELS	32

#define PXA2XX_DMA_NUM_REQUESTS	75

#define DCSR0	0x0000	/* DMA Control / Status register for Channel 0 */
#define DCSR31	0x007c	/* DMA Control / Status register for Channel 31 */
#define DALGN	0x00a0	/* DMA Alignment register */
#define DPCSR	0x00a4	/* DMA Programmed I/O Control Status register */
#define DRQSR0	0x00e0	/* DMA DREQ<0> Status register */
#define DRQSR1	0x00e4	/* DMA DREQ<1> Status register */
#define DRQSR2	0x00e8	/* DMA DREQ<2> Status register */
#define DINT	0x00f0	/* DMA Interrupt register */
#define DRCMR0	0x0100	/* Request to Channel Map register 0 */
#define DRCMR63	0x01fc	/* Request to Channel Map register 63 */
#define D_CH0	0x0200	/* Channel 0 Descriptor start */
#define DRCMR64	0x1100	/* Request to Channel Map register 64 */
#define DRCMR74	0x1128	/* Request to Channel Map register 74 */

/* Per-channel register */
#define DDADR	0x00
#define DSADR	0x01
#define DTADR	0x02
#define DCMD	0x03

/* Bit-field masks */
#define DRCMR_CHLNUM		0x1f
#define DRCMR_MAPVLD		(1 << 7)
#define DDADR_STOP		(1 << 0)
#define DDADR_BREN		(1 << 1)
#define DCMD_LEN		0x1fff
#define DCMD_WIDTH(x)		(1 << ((((x) >> 14) & 3) - 1))
#define DCMD_SIZE(x)		(4 << (((x) >> 16) & 3))
#define DCMD_FLYBYT		(1 << 19)
#define DCMD_FLYBYS		(1 << 20)
#define DCMD_ENDIRQEN		(1 << 21)
#define DCMD_STARTIRQEN		(1 << 22)
#define DCMD_CMPEN		(1 << 25)
#define DCMD_FLOWTRG		(1 << 28)
#define DCMD_FLOWSRC		(1 << 29)
#define DCMD_INCTRGADDR		(1 << 30)
#define DCMD_INCSRCADDR		(1 << 31)
#define DCSR_BUSERRINTR		(1 << 0)
#define DCSR_STARTINTR		(1 << 1)
#define DCSR_ENDINTR		(1 << 2)
#define DCSR_STOPINTR		(1 << 3)
#define DCSR_RASINTR		(1 << 4)
#define DCSR_REQPEND		(1 << 8)
#define DCSR_EORINT		(1 << 9)
#define DCSR_CMPST		(1 << 10)
#define DCSR_MASKRUN		(1 << 22)
#define DCSR_RASIRQEN		(1 << 23)
#define DCSR_CLRCMPST		(1 << 24)
#define DCSR_SETCMPST		(1 << 25)
#define DCSR_EORSTOPEN		(1 << 26)
#define DCSR_EORJMPEN		(1 << 27)
#define DCSR_EORIRQEN		(1 << 28)
#define DCSR_STOPIRQEN		(1 << 29)
#define DCSR_NODESCFETCH	(1 << 30)
#define DCSR_RUN		(1 << 31)

static inline void pxa2xx_dma_update(struct pxa2xx_dma_state_s *s, int ch)
{
    if (ch >= 0) {
        if ((s->chan[ch].state & DCSR_STOPIRQEN) &&
                (s->chan[ch].state & DCSR_STOPINTR))
            s->stopintr |= 1 << ch;
        else
            s->stopintr &= ~(1 << ch);

        if ((s->chan[ch].state & DCSR_EORIRQEN) &&
                (s->chan[ch].state & DCSR_EORINT))
            s->eorintr |= 1 << ch;
        else
            s->eorintr &= ~(1 << ch);

        if ((s->chan[ch].state & DCSR_RASIRQEN) &&
                (s->chan[ch].state & DCSR_RASINTR))
            s->rasintr |= 1 << ch;
        else
            s->rasintr &= ~(1 << ch);

        if (s->chan[ch].state & DCSR_STARTINTR)
            s->startintr |= 1 << ch;
        else
            s->startintr &= ~(1 << ch);

        if (s->chan[ch].state & DCSR_ENDINTR)
            s->endintr |= 1 << ch;
        else
            s->endintr &= ~(1 << ch);
    }

    if (s->stopintr | s->eorintr | s->rasintr | s->startintr | s->endintr)
        qemu_irq_raise(s->irq);
    else
        qemu_irq_lower(s->irq);
}

static inline void pxa2xx_dma_descriptor_fetch(
                struct pxa2xx_dma_state_s *s, int ch)
{
    uint32_t desc[4];
    target_phys_addr_t daddr = s->chan[ch].descr & ~0xf;
    if ((s->chan[ch].descr & DDADR_BREN) && (s->chan[ch].state & DCSR_CMPST))
        daddr += 32;

    cpu_physical_memory_read(daddr, (uint8_t *) desc, 16);
    s->chan[ch].descr = desc[DDADR];
    s->chan[ch].src = desc[DSADR];
    s->chan[ch].dest = desc[DTADR];
    s->chan[ch].cmd = desc[DCMD];

    if (s->chan[ch].cmd & DCMD_FLOWSRC)
        s->chan[ch].src &= ~3;
    if (s->chan[ch].cmd & DCMD_FLOWTRG)
        s->chan[ch].dest &= ~3;

    if (s->chan[ch].cmd & (DCMD_CMPEN | DCMD_FLYBYS | DCMD_FLYBYT))
        printf("%s: unsupported mode in channel %i\n", __FUNCTION__, ch);

    if (s->chan[ch].cmd & DCMD_STARTIRQEN)
        s->chan[ch].state |= DCSR_STARTINTR;
}

static void pxa2xx_dma_run(struct pxa2xx_dma_state_s *s)
{
    int c, srcinc, destinc;
    uint32_t n, size;
    uint32_t width;
    uint32_t length;
    uint8_t buffer[32];
    struct pxa2xx_dma_channel_s *ch;

    if (s->running ++)
        return;

    while (s->running) {
        s->running = 1;
        for (c = 0; c < s->channels; c ++) {
            ch = &s->chan[c];

            while ((ch->state & DCSR_RUN) && !(ch->state & DCSR_STOPINTR)) {
                /* Test for pending requests */
                if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) && !ch->request)
                    break;

                length = ch->cmd & DCMD_LEN;
                size = DCMD_SIZE(ch->cmd);
                width = DCMD_WIDTH(ch->cmd);

                srcinc = (ch->cmd & DCMD_INCSRCADDR) ? width : 0;
                destinc = (ch->cmd & DCMD_INCTRGADDR) ? width : 0;

                while (length) {
                    size = MIN(length, size);

                    for (n = 0; n < size; n += width) {
                        cpu_physical_memory_read(ch->src, buffer + n, width);
                        ch->src += srcinc;
                    }

                    for (n = 0; n < size; n += width) {
                        cpu_physical_memory_write(ch->dest, buffer + n, width);
                        ch->dest += destinc;
                    }

                    length -= size;

                    if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) &&
                            !ch->request) {
                        ch->state |= DCSR_EORINT;
                        if (ch->state & DCSR_EORSTOPEN)
                            ch->state |= DCSR_STOPINTR;
                        if ((ch->state & DCSR_EORJMPEN) &&
                                        !(ch->state & DCSR_NODESCFETCH))
                            pxa2xx_dma_descriptor_fetch(s, c);
                        break;
		    }
                }

                ch->cmd = (ch->cmd & ~DCMD_LEN) | length;

                /* Is the transfer complete now? */
                if (!length) {
                    if (ch->cmd & DCMD_ENDIRQEN)
                        ch->state |= DCSR_ENDINTR;

                    if ((ch->state & DCSR_NODESCFETCH) ||
                                (ch->descr & DDADR_STOP) ||
                                (ch->state & DCSR_EORSTOPEN)) {
                        ch->state |= DCSR_STOPINTR;
                        ch->state &= ~DCSR_RUN;

                        break;
                    }

                    ch->state |= DCSR_STOPINTR;
                    break;
                }
            }
        }

        s->running --;
    }
}

static uint32_t pxa2xx_dma_read(void *opaque, target_phys_addr_t offset)
{
    struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
    unsigned int channel;

    switch (offset) {
    case DRCMR64 ... DRCMR74:
        offset -= DRCMR64 - DRCMR0 - (64 << 2);
        /* Fall through */
    case DRCMR0 ... DRCMR63:
        channel = (offset - DRCMR0) >> 2;
        return s->req[channel];

    case DRQSR0:
    case DRQSR1:
    case DRQSR2:
        return 0;

    case DCSR0 ... DCSR31:
        channel = offset >> 2;
	if (s->chan[channel].request)
            return s->chan[channel].state | DCSR_REQPEND;
        return s->chan[channel].state;

    case DINT:
        return s->stopintr | s->eorintr | s->rasintr |
                s->startintr | s->endintr;

    case DALGN:
        return s->align;

    case DPCSR:
        return s->pio;
    }

    if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
        channel = (offset - D_CH0) >> 4;
        switch ((offset & 0x0f) >> 2) {
        case DDADR:
            return s->chan[channel].descr;
        case DSADR:
            return s->chan[channel].src;
        case DTADR:
            return s->chan[channel].dest;
        case DCMD:
            return s->chan[channel].cmd;
        }
    }

    cpu_abort(cpu_single_env,
                    "%s: Bad offset 0x" TARGET_FMT_plx "\n", __FUNCTION__, offset);
    return 7;
}

static void pxa2xx_dma_write(void *opaque,
                 target_phys_addr_t offset, uint32_t value)
{
    struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
    unsigned int channel;

    switch (offset) {
    case DRCMR64 ... DRCMR74:
        offset -= DRCMR64 - DRCMR0 - (64 << 2);
        /* Fall through */
    case DRCMR0 ... DRCMR63:
        channel = (offset - DRCMR0) >> 2;

        if (value & DRCMR_MAPVLD)
            if ((value & DRCMR_CHLNUM) > s->channels)
                cpu_abort(cpu_single_env, "%s: Bad DMA channel %i\n",
                        __FUNCTION__, value & DRCMR_CHLNUM);

        s->req[channel] = value;
        break;

    case DRQSR0:
    case DRQSR1:
    case DRQSR2:
        /* Nothing to do */
        break;

    case DCSR0 ... DCSR31:
        channel = offset >> 2;
        s->chan[channel].state &= 0x0000071f & ~(value &
                        (DCSR_EORINT | DCSR_ENDINTR |
                         DCSR_STARTINTR | DCSR_BUSERRINTR));
        s->chan[channel].state |= value & 0xfc800000;

        if (s->chan[channel].state & DCSR_STOPIRQEN)
            s->chan[channel].state &= ~DCSR_STOPINTR;

        if (value & DCSR_NODESCFETCH) {
            /* No-descriptor-fetch mode */
            if (value & DCSR_RUN) {
                s->chan[channel].state &= ~DCSR_STOPINTR;
                pxa2xx_dma_run(s);
            }
        } else {
            /* Descriptor-fetch mode */
            if (value & DCSR_RUN) {
                s->chan[channel].state &= ~DCSR_STOPINTR;
                pxa2xx_dma_descriptor_fetch(s, channel);
                pxa2xx_dma_run(s);
            }
        }

        /* Shouldn't matter as our DMA is synchronous.  */
        if (!(value & (DCSR_RUN | DCSR_MASKRUN)))
            s->chan[channel].state |= DCSR_STOPINTR;

        if (value & DCSR_CLRCMPST)
            s->chan[channel].state &= ~DCSR_CMPST;
        if (value & DCSR_SETCMPST)
            s->chan[channel].state |= DCSR_CMPST;

        pxa2xx_dma_update(s, channel);
        break;

    case DALGN:
        s->align = value;
        break;

    case DPCSR:
        s->pio = value & 0x80000001;
        break;

    default:
        if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
            channel = (offset - D_CH0) >> 4;
            switch ((offset & 0x0f) >> 2) {
            case DDADR:
                s->chan[channel].descr = value;
                break;
            case DSADR:
                s->chan[channel].src = value;
                break;
            case DTADR:
                s->chan[channel].dest = value;
                break;
            case DCMD:
                s->chan[channel].cmd = value;
                break;
            default:
                goto fail;
            }

            break;
        }
    fail:
        cpu_abort(cpu_single_env, "%s: Bad offset " TARGET_FMT_plx "\n",
                __FUNCTION__, offset);
    }
}

static uint32_t pxa2xx_dma_readbad(void *opaque, target_phys_addr_t offset)
{
    cpu_abort(cpu_single_env, "%s: Bad access width\n", __FUNCTION__);
    return 5;
}

static void pxa2xx_dma_writebad(void *opaque,
                 target_phys_addr_t offset, uint32_t value)
{
    cpu_abort(cpu_single_env, "%s: Bad access width\n", __FUNCTION__);
}

static CPUReadMemoryFunc *pxa2xx_dma_readfn[] = {
    pxa2xx_dma_readbad,
    pxa2xx_dma_readbad,
    pxa2xx_dma_read
};

static CPUWriteMemoryFunc *pxa2xx_dma_writefn[] = {
    pxa2xx_dma_writebad,
    pxa2xx_dma_writebad,
    pxa2xx_dma_write
};

static void pxa2xx_dma_save(QEMUFile *f, void *opaque)
{
    struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
    int i;

    qemu_put_be32(f, s->channels);

    qemu_put_be32s(f, &s->stopintr);
    qemu_put_be32s(f, &s->eorintr);
    qemu_put_be32s(f, &s->rasintr);
    qemu_put_be32s(f, &s->startintr);
    qemu_put_be32s(f, &s->endintr);
    qemu_put_be32s(f, &s->align);
    qemu_put_be32s(f, &s->pio);

    qemu_put_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS);
    for (i = 0; i < s->channels; i ++) {
        qemu_put_betl(f, s->chan[i].descr);
        qemu_put_betl(f, s->chan[i].src);
        qemu_put_betl(f, s->chan[i].dest);
        qemu_put_be32s(f, &s->chan[i].cmd);
        qemu_put_be32s(f, &s->chan[i].state);
        qemu_put_be32(f, s->chan[i].request);
    };
}

static int pxa2xx_dma_load(QEMUFile *f, void *opaque, int version_id)
{
    struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
    int i;

    if (qemu_get_be32(f) != s->channels)
        return -EINVAL;

    qemu_get_be32s(f, &s->stopintr);
    qemu_get_be32s(f, &s->eorintr);
    qemu_get_be32s(f, &s->rasintr);
    qemu_get_be32s(f, &s->startintr);
    qemu_get_be32s(f, &s->endintr);
    qemu_get_be32s(f, &s->align);
    qemu_get_be32s(f, &s->pio);

    qemu_get_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS);
    for (i = 0; i < s->channels; i ++) {
        s->chan[i].descr = qemu_get_betl(f);
        s->chan[i].src = qemu_get_betl(f);
        s->chan[i].dest = qemu_get_betl(f);
        qemu_get_be32s(f, &s->chan[i].cmd);
        qemu_get_be32s(f, &s->chan[i].state);
        s->chan[i].request = qemu_get_be32(f);
    };

    return 0;
}

static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base,
                qemu_irq irq, int channels)
{
    int i, iomemtype;
    struct pxa2xx_dma_state_s *s;
    s = (struct pxa2xx_dma_state_s *)
            qemu_mallocz(sizeof(struct pxa2xx_dma_state_s));

    s->channels = channels;
    s->chan = qemu_mallocz(sizeof(struct pxa2xx_dma_channel_s) * s->channels);
    s->irq = irq;
    s->handler = (pxa2xx_dma_handler_t) pxa2xx_dma_request;
    s->req = qemu_mallocz(sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);

    memset(s->chan, 0, sizeof(struct pxa2xx_dma_channel_s) * s->channels);
    for (i = 0; i < s->channels; i ++)
        s->chan[i].state = DCSR_STOPINTR;

    memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);

    iomemtype = cpu_register_io_memory(0, pxa2xx_dma_readfn,
                    pxa2xx_dma_writefn, s);
    cpu_register_physical_memory(base, 0x00010000, iomemtype);

    register_savevm("pxa2xx_dma", 0, 0, pxa2xx_dma_save, pxa2xx_dma_load, s);

    return s;
}

struct pxa2xx_dma_state_s *pxa27x_dma_init(target_phys_addr_t base,
                qemu_irq irq)
{
    return pxa2xx_dma_init(base, irq, PXA27X_DMA_NUM_CHANNELS);
}

struct pxa2xx_dma_state_s *pxa255_dma_init(target_phys_addr_t base,
                qemu_irq irq)
{
    return pxa2xx_dma_init(base, irq, PXA255_DMA_NUM_CHANNELS);
}

void pxa2xx_dma_request(struct pxa2xx_dma_state_s *s, int req_num, int on)
{
    int ch;
    if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS)
        cpu_abort(cpu_single_env,
              "%s: Bad DMA request %i\n", __FUNCTION__, req_num);

    if (!(s->req[req_num] & DRCMR_MAPVLD))
        return;
    ch = s->req[req_num] & DRCMR_CHLNUM;

    if (!s->chan[ch].request && on)
        s->chan[ch].state |= DCSR_RASINTR;
    else
        s->chan[ch].state &= ~DCSR_RASINTR;
    if (s->chan[ch].request && !on)
        s->chan[ch].state |= DCSR_EORINT;

    s->chan[ch].request = on;
    if (on) {
        pxa2xx_dma_run(s);
        pxa2xx_dma_update(s, ch);
    }
}
