/*
 * 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 "sysbus.h"

//#define DEBUG_PL061 1

#ifdef DEBUG_PL061
#define DPRINTF(fmt, ...) \
do { printf("pl061: " fmt , ## __VA_ARGS__); } while (0)
#define BADF(fmt, ...) \
do { fprintf(stderr, "pl061: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
#else
#define DPRINTF(fmt, ...) do {} while(0)
#define BADF(fmt, ...) \
do { fprintf(stderr, "pl061: error: " fmt , ## __VA_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 {
    SysBusDevice busdev;
    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:
        hw_error("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:
        hw_error("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;
}

static void pl061_init(SysBusDevice *dev)
{
    int iomemtype;
    pl061_state *s = FROM_SYSBUS(pl061_state, dev);

    iomemtype = cpu_register_io_memory(pl061_readfn,
                                       pl061_writefn, s);
    sysbus_init_mmio(dev, 0x1000, iomemtype);
    sysbus_init_irq(dev, &s->irq);
    qdev_init_gpio_in(&dev->qdev, pl061_set_irq, 8);
    qdev_init_gpio_out(&dev->qdev, s->out, 8);
    pl061_reset(s);
    register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s);
}

static void pl061_register_devices(void)
{
    sysbus_register_dev("pl061", sizeof(pl061_state),
                        pl061_init);
}

device_init(pl061_register_devices)
