/*
 * Arm PrimeCell PL061 General Purpose IO with additional
 * Luminary Micro Stellaris bits.
 *
 * Copyright (c) 2007 CodeSourcery.
 * Written by Paul Brook
 *
 * This code is licenced under the GPL.
 */

#include "hw.h"
#include "primecell.h"

//#define DEBUG_PL061 1

#ifdef DEBUG_PL061
#define DPRINTF(fmt, args...) \
do { printf("pl061: " fmt , ##args); } while (0)
#define BADF(fmt, args...) \
do { fprintf(stderr, "pl061: error: " fmt , ##args); exit(1);} while (0)
#else
#define DPRINTF(fmt, args...) do {} while(0)
#define BADF(fmt, args...) \
do { fprintf(stderr, "pl061: error: " fmt , ##args);} while (0)
#endif

static const uint8_t pl061_id[12] =
  { 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 };

typedef struct {
    int locked;
    uint8_t data;
    uint8_t old_data;
    uint8_t dir;
    uint8_t isense;
    uint8_t ibe;
    uint8_t iev;
    uint8_t im;
    uint8_t istate;
    uint8_t afsel;
    uint8_t dr2r;
    uint8_t dr4r;
    uint8_t dr8r;
    uint8_t odr;
    uint8_t pur;
    uint8_t pdr;
    uint8_t slr;
    uint8_t den;
    uint8_t cr;
    uint8_t float_high;
    qemu_irq irq;
    qemu_irq out[8];
} pl061_state;

static void pl061_update(pl061_state *s)
{
    uint8_t changed;
    uint8_t mask;
    uint8_t out;
    int i;

    /* Outputs float high.  */
    /* FIXME: This is board dependent.  */
    out = (s->data & s->dir) | ~s->dir;
    changed = s->old_data ^ out;
    if (!changed)
        return;

    s->old_data = out;
    for (i = 0; i < 8; i++) {
        mask = 1 << i;
        if ((changed & mask) && s->out) {
            DPRINTF("Set output %d = %d\n", i, (out & mask) != 0);
            qemu_set_irq(s->out[i], (out & mask) != 0);
        }
    }

    /* FIXME: Implement input interrupts.  */
}

static uint32_t pl061_read(void *opaque, target_phys_addr_t offset)
{
    pl061_state *s = (pl061_state *)opaque;

    if (offset >= 0xfd0 && offset < 0x1000) {
        return pl061_id[(offset - 0xfd0) >> 2];
    }
    if (offset < 0x400) {
        return s->data & (offset >> 2);
    }
    switch (offset) {
    case 0x400: /* Direction */
        return s->dir;
    case 0x404: /* Interrupt sense */
        return s->isense;
    case 0x408: /* Interrupt both edges */
        return s->ibe;
    case 0x40c: /* Interupt event */
        return s->iev;
    case 0x410: /* Interrupt mask */
        return s->im;
    case 0x414: /* Raw interrupt status */
        return s->istate;
    case 0x418: /* Masked interrupt status */
        return s->istate | s->im;
    case 0x420: /* Alternate function select */
        return s->afsel;
    case 0x500: /* 2mA drive */
        return s->dr2r;
    case 0x504: /* 4mA drive */
        return s->dr4r;
    case 0x508: /* 8mA drive */
        return s->dr8r;
    case 0x50c: /* Open drain */
        return s->odr;
    case 0x510: /* Pull-up */
        return s->pur;
    case 0x514: /* Pull-down */
        return s->pdr;
    case 0x518: /* Slew rate control */
        return s->slr;
    case 0x51c: /* Digital enable */
        return s->den;
    case 0x520: /* Lock */
        return s->locked;
    case 0x524: /* Commit */
        return s->cr;
    default:
        cpu_abort (cpu_single_env, "pl061_read: Bad offset %x\n",
                   (int)offset);
        return 0;
    }
}

static void pl061_write(void *opaque, target_phys_addr_t offset,
                        uint32_t value)
{
    pl061_state *s = (pl061_state *)opaque;
    uint8_t mask;

    if (offset < 0x400) {
        mask = (offset >> 2) & s->dir;
        s->data = (s->data & ~mask) | (value & mask);
        pl061_update(s);
        return;
    }
    switch (offset) {
    case 0x400: /* Direction */
        s->dir = value;
        break;
    case 0x404: /* Interrupt sense */
        s->isense = value;
        break;
    case 0x408: /* Interrupt both edges */
        s->ibe = value;
        break;
    case 0x40c: /* Interupt event */
        s->iev = value;
        break;
    case 0x410: /* Interrupt mask */
        s->im = value;
        break;
    case 0x41c: /* Interrupt clear */
        s->istate &= ~value;
        break;
    case 0x420: /* Alternate function select */
        mask = s->cr;
        s->afsel = (s->afsel & ~mask) | (value & mask);
        break;
    case 0x500: /* 2mA drive */
        s->dr2r = value;
        break;
    case 0x504: /* 4mA drive */
        s->dr4r = value;
        break;
    case 0x508: /* 8mA drive */
        s->dr8r = value;
        break;
    case 0x50c: /* Open drain */
        s->odr = value;
        break;
    case 0x510: /* Pull-up */
        s->pur = value;
        break;
    case 0x514: /* Pull-down */
        s->pdr = value;
        break;
    case 0x518: /* Slew rate control */
        s->slr = value;
        break;
    case 0x51c: /* Digital enable */
        s->den = value;
        break;
    case 0x520: /* Lock */
        s->locked = (value != 0xacce551);
        break;
    case 0x524: /* Commit */
        if (!s->locked)
            s->cr = value;
        break;
    default:
        cpu_abort (cpu_single_env, "pl061_write: Bad offset %x\n",
                   (int)offset);
    }
    pl061_update(s);
}

static void pl061_reset(pl061_state *s)
{
  s->locked = 1;
  s->cr = 0xff;
}

static void pl061_set_irq(void * opaque, int irq, int level)
{
    pl061_state *s = (pl061_state *)opaque;
    uint8_t mask;

    mask = 1 << irq;
    if ((s->dir & mask) == 0) {
        s->data &= ~mask;
        if (level)
            s->data |= mask;
        pl061_update(s);
    }
}

static CPUReadMemoryFunc *pl061_readfn[] = {
   pl061_read,
   pl061_read,
   pl061_read
};

static CPUWriteMemoryFunc *pl061_writefn[] = {
   pl061_write,
   pl061_write,
   pl061_write
};

static void pl061_save(QEMUFile *f, void *opaque)
{
    pl061_state *s = (pl061_state *)opaque;

    qemu_put_be32(f, s->locked);
    qemu_put_be32(f, s->data);
    qemu_put_be32(f, s->old_data);
    qemu_put_be32(f, s->dir);
    qemu_put_be32(f, s->isense);
    qemu_put_be32(f, s->ibe);
    qemu_put_be32(f, s->iev);
    qemu_put_be32(f, s->im);
    qemu_put_be32(f, s->istate);
    qemu_put_be32(f, s->afsel);
    qemu_put_be32(f, s->dr2r);
    qemu_put_be32(f, s->dr4r);
    qemu_put_be32(f, s->dr8r);
    qemu_put_be32(f, s->odr);
    qemu_put_be32(f, s->pur);
    qemu_put_be32(f, s->pdr);
    qemu_put_be32(f, s->slr);
    qemu_put_be32(f, s->den);
    qemu_put_be32(f, s->cr);
    qemu_put_be32(f, s->float_high);
}

static int pl061_load(QEMUFile *f, void *opaque, int version_id)
{
    pl061_state *s = (pl061_state *)opaque;
    if (version_id != 1)
        return -EINVAL;

    s->locked = qemu_get_be32(f);
    s->data = qemu_get_be32(f);
    s->old_data = qemu_get_be32(f);
    s->dir = qemu_get_be32(f);
    s->isense = qemu_get_be32(f);
    s->ibe = qemu_get_be32(f);
    s->iev = qemu_get_be32(f);
    s->im = qemu_get_be32(f);
    s->istate = qemu_get_be32(f);
    s->afsel = qemu_get_be32(f);
    s->dr2r = qemu_get_be32(f);
    s->dr4r = qemu_get_be32(f);
    s->dr8r = qemu_get_be32(f);
    s->odr = qemu_get_be32(f);
    s->pur = qemu_get_be32(f);
    s->pdr = qemu_get_be32(f);
    s->slr = qemu_get_be32(f);
    s->den = qemu_get_be32(f);
    s->cr = qemu_get_be32(f);
    s->float_high = qemu_get_be32(f);

    return 0;
}

/* Returns an array of inputs.  */
qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out)
{
    int iomemtype;
    pl061_state *s;

    s = (pl061_state *)qemu_mallocz(sizeof(pl061_state));
    iomemtype = cpu_register_io_memory(0, pl061_readfn,
                                       pl061_writefn, s);
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
    s->irq = irq;
    pl061_reset(s);
    if (out)
        *out = s->out;

    register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s);
    return qemu_allocate_irqs(pl061_set_irq, s, 8);
}
