/*
 * On-chip DMA controller framework.
 *
 * Copyright (C) 2008 Nokia Corporation
 * Written by Andrzej Zaborowski <andrew@openedhand.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 or
 * (at your option) version 3 of the License.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
#include "qemu-common.h"
#include "qemu-timer.h"
#include "soc_dma.h"

void transfer_mem2mem(struct soc_dma_ch_s *ch)
{
    memcpy(ch->paddr[0], ch->paddr[1], ch->bytes);
    ch->paddr[0] += ch->bytes;
    ch->paddr[1] += ch->bytes;
}

void transfer_mem2fifo(struct soc_dma_ch_s *ch)
{
    ch->io_fn[1](ch->io_opaque[1], ch->paddr[0], ch->bytes);
    ch->paddr[0] += ch->bytes;
}

void transfer_fifo2mem(struct soc_dma_ch_s *ch)
{
    ch->io_fn[0](ch->io_opaque[0], ch->paddr[1], ch->bytes);
    ch->paddr[1] += ch->bytes;
}

/* This is further optimisable but isn't very important because often
 * DMA peripherals forbid this kind of transfers and even when they don't,
 * oprating systems may not need to use them.  */
static void *fifo_buf;
static int fifo_size;
void transfer_fifo2fifo(struct soc_dma_ch_s *ch)
{
    if (ch->bytes > fifo_size)
        fifo_buf = qemu_realloc(fifo_buf, fifo_size = ch->bytes);

    /* Implement as transfer_fifo2linear + transfer_linear2fifo.  */
    ch->io_fn[0](ch->io_opaque[0], fifo_buf, ch->bytes);
    ch->io_fn[1](ch->io_opaque[1], fifo_buf, ch->bytes);
}

struct dma_s {
    struct soc_dma_s soc;
    int chnum;
    uint64_t ch_enable_mask;
    int64_t channel_freq;
    int enabled_count;

    struct memmap_entry_s {
        enum soc_dma_port_type type;
        target_phys_addr_t addr;
        union {
           struct {
               void *opaque;
               soc_dma_io_t fn;
               int out;
           } fifo;
           struct {
               void *base;
               size_t size;
           } mem;
        } u;
    } *memmap;
    int memmap_size;

    struct soc_dma_ch_s ch[0];
};

static void soc_dma_ch_schedule(struct soc_dma_ch_s *ch, int delay_bytes)
{
    int64_t now = qemu_get_clock(vm_clock);
    struct dma_s *dma = (struct dma_s *) ch->dma;

    qemu_mod_timer(ch->timer, now + delay_bytes / dma->channel_freq);
}

static void soc_dma_ch_run(void *opaque)
{
    struct soc_dma_ch_s *ch = (struct soc_dma_ch_s *) opaque;

    ch->running = 1;
    ch->dma->setup_fn(ch);
    ch->transfer_fn(ch);
    ch->running = 0;

    if (ch->enable)
        soc_dma_ch_schedule(ch, ch->bytes);
    ch->bytes = 0;
}

static inline struct memmap_entry_s *soc_dma_lookup(struct dma_s *dma,
                target_phys_addr_t addr)
{
    struct memmap_entry_s *lo;
    int hi;

    lo = dma->memmap;
    hi = dma->memmap_size;

    while (hi > 1) {
        hi /= 2;
        if (lo[hi].addr <= addr)
            lo += hi;
    }

    return lo;
}

static inline enum soc_dma_port_type soc_dma_ch_update_type(
                struct soc_dma_ch_s *ch, int port)
{
    struct dma_s *dma = (struct dma_s *) ch->dma;
    struct memmap_entry_s *entry = soc_dma_lookup(dma, ch->vaddr[port]);

    if (entry->type == soc_dma_port_fifo) {
        while (entry < dma->memmap + dma->memmap_size &&
                        entry->u.fifo.out != port)
            entry ++;
        if (entry->addr != ch->vaddr[port] || entry->u.fifo.out != port)
            return soc_dma_port_other;

        if (ch->type[port] != soc_dma_access_const)
            return soc_dma_port_other;

        ch->io_fn[port] = entry->u.fifo.fn;
        ch->io_opaque[port] = entry->u.fifo.opaque;
        return soc_dma_port_fifo;
    } else if (entry->type == soc_dma_port_mem) {
        if (entry->addr > ch->vaddr[port] ||
                        entry->addr + entry->u.mem.size <= ch->vaddr[port])
            return soc_dma_port_other;

        /* TODO: support constant memory address for source port as used for
         * drawing solid rectangles by PalmOS(R).  */
        if (ch->type[port] != soc_dma_access_const)
            return soc_dma_port_other;

        ch->paddr[port] = (uint8_t *) entry->u.mem.base +
                (ch->vaddr[port] - entry->addr);
        /* TODO: save bytes left to the end of the mapping somewhere so we
         * can check we're not reading beyond it.  */
        return soc_dma_port_mem;
    } else
        return soc_dma_port_other;
}

void soc_dma_ch_update(struct soc_dma_ch_s *ch)
{
    enum soc_dma_port_type src, dst;

    src = soc_dma_ch_update_type(ch, 0);
    if (src == soc_dma_port_other) {
        ch->update = 0;
        ch->transfer_fn = ch->dma->transfer_fn;
        return;
    }
    dst = soc_dma_ch_update_type(ch, 1);

    /* TODO: use src and dst as array indices.  */
    if (src == soc_dma_port_mem && dst == soc_dma_port_mem)
        ch->transfer_fn = transfer_mem2mem;
    else if (src == soc_dma_port_mem && dst == soc_dma_port_fifo)
        ch->transfer_fn = transfer_mem2fifo;
    else if (src == soc_dma_port_fifo && dst == soc_dma_port_mem)
        ch->transfer_fn = transfer_fifo2mem;
    else if (src == soc_dma_port_fifo && dst == soc_dma_port_fifo)
        ch->transfer_fn = transfer_fifo2fifo;
    else
        ch->transfer_fn = ch->dma->transfer_fn;

    ch->update = (dst != soc_dma_port_other);
}

static void soc_dma_ch_freq_update(struct dma_s *s)
{
    if (s->enabled_count)
        /* We completely ignore channel priorities and stuff */
        s->channel_freq = s->soc.freq / s->enabled_count;
    else
        /* TODO: Signal that we want to disable the functional clock and let
         * the platform code decide what to do with it, i.e. check that
         * auto-idle is enabled in the clock controller and if we are stopping
         * the clock, do the same with any parent clocks that had only one
         * user keeping them on and auto-idle enabled.  */;
}

void soc_dma_set_request(struct soc_dma_ch_s *ch, int level)
{
    struct dma_s *dma = (struct dma_s *) ch->dma;

    dma->enabled_count += level - ch->enable;

    if (level)
        dma->ch_enable_mask |= 1 << ch->num;
    else
        dma->ch_enable_mask &= ~(1 << ch->num);

    if (level != ch->enable) {
        soc_dma_ch_freq_update(dma);
        ch->enable = level;

        if (!ch->enable)
            qemu_del_timer(ch->timer);
        else if (!ch->running)
            soc_dma_ch_run(ch);
        else
            soc_dma_ch_schedule(ch, 1);
    }
}

void soc_dma_reset(struct soc_dma_s *soc)
{
    struct dma_s *s = (struct dma_s *) soc;

    s->soc.drqbmp = 0;
    s->ch_enable_mask = 0;
    s->enabled_count = 0;
    soc_dma_ch_freq_update(s);
}

/* TODO: take a functional-clock argument */
struct soc_dma_s *soc_dma_init(int n)
{
    int i;
    struct dma_s *s = qemu_mallocz(sizeof(*s) + n * sizeof(*s->ch));

    s->chnum = n;
    s->soc.ch = s->ch;
    for (i = 0; i < n; i ++) {
        s->ch[i].dma = &s->soc;
        s->ch[i].num = i;
        s->ch[i].timer = qemu_new_timer(vm_clock, soc_dma_ch_run, &s->ch[i]);
    }

    soc_dma_reset(&s->soc);
    fifo_size = 0;

    return &s->soc;
}

void soc_dma_port_add_fifo(struct soc_dma_s *soc, target_phys_addr_t virt_base,
                soc_dma_io_t fn, void *opaque, int out)
{
    struct memmap_entry_s *entry;
    struct dma_s *dma = (struct dma_s *) soc;

    dma->memmap = qemu_realloc(dma->memmap, sizeof(*entry) *
                    (dma->memmap_size + 1));
    entry = soc_dma_lookup(dma, virt_base);

    if (dma->memmap_size) {
        if (entry->type == soc_dma_port_mem) {
            if (entry->addr <= virt_base &&
                            entry->addr + entry->u.mem.size > virt_base) {
                fprintf(stderr, "%s: FIFO at " TARGET_FMT_lx
                                " collides with RAM region at " TARGET_FMT_lx
                                "-" TARGET_FMT_lx "\n", __FUNCTION__,
                                (target_ulong) virt_base,
                                (target_ulong) entry->addr, (target_ulong)
                                (entry->addr + entry->u.mem.size));
                exit(-1);
            }

            if (entry->addr <= virt_base)
                entry ++;
        } else
            while (entry < dma->memmap + dma->memmap_size &&
                            entry->addr <= virt_base) {
                if (entry->addr == virt_base && entry->u.fifo.out == out) {
                    fprintf(stderr, "%s: FIFO at " TARGET_FMT_lx
                                    " collides FIFO at " TARGET_FMT_lx "\n",
                                    __FUNCTION__, (target_ulong) virt_base,
                                    (target_ulong) entry->addr);
                    exit(-1);
                }

                entry ++;
            }

        memmove(entry + 1, entry,
                        (uint8_t *) (dma->memmap + dma->memmap_size ++) -
                        (uint8_t *) entry);
    } else
        dma->memmap_size ++;

    entry->addr          = virt_base;
    entry->type          = soc_dma_port_fifo;
    entry->u.fifo.fn     = fn;
    entry->u.fifo.opaque = opaque;
    entry->u.fifo.out    = out;
}

void soc_dma_port_add_mem(struct soc_dma_s *soc, uint8_t *phys_base,
                target_phys_addr_t virt_base, size_t size)
{
    struct memmap_entry_s *entry;
    struct dma_s *dma = (struct dma_s *) soc;

    dma->memmap = qemu_realloc(dma->memmap, sizeof(*entry) *
                    (dma->memmap_size + 1));
    entry = soc_dma_lookup(dma, virt_base);

    if (dma->memmap_size) {
        if (entry->type == soc_dma_port_mem) {
            if ((entry->addr >= virt_base && entry->addr < virt_base + size) ||
                            (entry->addr <= virt_base &&
                             entry->addr + entry->u.mem.size > virt_base)) {
                fprintf(stderr, "%s: RAM at " TARGET_FMT_lx "-" TARGET_FMT_lx
                                " collides with RAM region at " TARGET_FMT_lx
                                "-" TARGET_FMT_lx "\n", __FUNCTION__,
                                (target_ulong) virt_base,
                                (target_ulong) (virt_base + size),
                                (target_ulong) entry->addr, (target_ulong)
                                (entry->addr + entry->u.mem.size));
                exit(-1);
            }

            if (entry->addr <= virt_base)
                entry ++;
        } else {
            if (entry->addr >= virt_base &&
                            entry->addr < virt_base + size) {
                fprintf(stderr, "%s: RAM at " TARGET_FMT_lx "-" TARGET_FMT_lx
                                " collides with FIFO at " TARGET_FMT_lx
                                "\n", __FUNCTION__,
                                (target_ulong) virt_base,
                                (target_ulong) (virt_base + size),
                                (target_ulong) entry->addr);
                exit(-1);
            }

            while (entry < dma->memmap + dma->memmap_size &&
                            entry->addr <= virt_base)
                entry ++;
	}

        memmove(entry + 1, entry,
                        (uint8_t *) (dma->memmap + dma->memmap_size ++) -
                        (uint8_t *) entry);
    } else
        dma->memmap_size ++;

    entry->addr          = virt_base;
    entry->type          = soc_dma_port_mem;
    entry->u.mem.base    = phys_base;
    entry->u.mem.size    = size;
}

/* TODO: port removal for ports like PCMCIA memory */
