/*
 * QEMU model of the Xilinx SPI Controller
 *
 * Copyright (C) 2010 Edgar E. Iglesias.
 * Copyright (C) 2012 Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
 * Copyright (C) 2012 PetaLogix
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "hw/sysbus.h"
#include "sysemu/sysemu.h"
#include "qemu/log.h"
#include "qemu/fifo8.h"

#include "hw/ssi.h"

#ifdef XILINX_SPI_ERR_DEBUG
#define DB_PRINT(...) do { \
    fprintf(stderr,  ": %s: ", __func__); \
    fprintf(stderr, ## __VA_ARGS__); \
    } while (0);
#else
    #define DB_PRINT(...)
#endif

#define R_DGIER     (0x1c / 4)
#define R_DGIER_IE  (1 << 31)

#define R_IPISR     (0x20 / 4)
#define IRQ_DRR_NOT_EMPTY    (1 << (31 - 23))
#define IRQ_DRR_OVERRUN      (1 << (31 - 26))
#define IRQ_DRR_FULL         (1 << (31 - 27))
#define IRQ_TX_FF_HALF_EMPTY (1 << 6)
#define IRQ_DTR_UNDERRUN     (1 << 3)
#define IRQ_DTR_EMPTY        (1 << (31 - 29))

#define R_IPIER     (0x28 / 4)
#define R_SRR       (0x40 / 4)
#define R_SPICR     (0x60 / 4)
#define R_SPICR_TXFF_RST     (1 << 5)
#define R_SPICR_RXFF_RST     (1 << 6)
#define R_SPICR_MTI          (1 << 8)

#define R_SPISR     (0x64 / 4)
#define SR_TX_FULL    (1 << 3)
#define SR_TX_EMPTY   (1 << 2)
#define SR_RX_FULL    (1 << 1)
#define SR_RX_EMPTY   (1 << 0)

#define R_SPIDTR    (0x68 / 4)
#define R_SPIDRR    (0x6C / 4)
#define R_SPISSR    (0x70 / 4)
#define R_TX_FF_OCY (0x74 / 4)
#define R_RX_FF_OCY (0x78 / 4)
#define R_MAX       (0x7C / 4)

#define FIFO_CAPACITY 256

#define TYPE_XILINX_SPI "xlnx.xps-spi"
#define XILINX_SPI(obj) OBJECT_CHECK(XilinxSPI, (obj), TYPE_XILINX_SPI)

typedef struct XilinxSPI {
    SysBusDevice parent_obj;

    MemoryRegion mmio;

    qemu_irq irq;
    int irqline;

    uint8_t num_cs;
    qemu_irq *cs_lines;

    SSIBus *spi;

    Fifo8 rx_fifo;
    Fifo8 tx_fifo;

    uint32_t regs[R_MAX];
} XilinxSPI;

static void txfifo_reset(XilinxSPI *s)
{
    fifo8_reset(&s->tx_fifo);

    s->regs[R_SPISR] &= ~SR_TX_FULL;
    s->regs[R_SPISR] |= SR_TX_EMPTY;
}

static void rxfifo_reset(XilinxSPI *s)
{
    fifo8_reset(&s->rx_fifo);

    s->regs[R_SPISR] |= SR_RX_EMPTY;
    s->regs[R_SPISR] &= ~SR_RX_FULL;
}

static void xlx_spi_update_cs(XilinxSPI *s)
{
    int i;

    for (i = 0; i < s->num_cs; ++i) {
        qemu_set_irq(s->cs_lines[i], !(~s->regs[R_SPISSR] & 1 << i));
    }
}

static void xlx_spi_update_irq(XilinxSPI *s)
{
    uint32_t pending;

    s->regs[R_IPISR] |=
            (!fifo8_is_empty(&s->rx_fifo) ? IRQ_DRR_NOT_EMPTY : 0) |
            (fifo8_is_full(&s->rx_fifo) ? IRQ_DRR_FULL : 0);

    pending = s->regs[R_IPISR] & s->regs[R_IPIER];

    pending = pending && (s->regs[R_DGIER] & R_DGIER_IE);
    pending = !!pending;

    /* This call lies right in the data paths so don't call the
       irq chain unless things really changed.  */
    if (pending != s->irqline) {
        s->irqline = pending;
        DB_PRINT("irq_change of state %d ISR:%x IER:%X\n",
                    pending, s->regs[R_IPISR], s->regs[R_IPIER]);
        qemu_set_irq(s->irq, pending);
    }

}

static void xlx_spi_do_reset(XilinxSPI *s)
{
    memset(s->regs, 0, sizeof s->regs);

    rxfifo_reset(s);
    txfifo_reset(s);

    s->regs[R_SPISSR] = ~0;
    xlx_spi_update_irq(s);
    xlx_spi_update_cs(s);
}

static void xlx_spi_reset(DeviceState *d)
{
    xlx_spi_do_reset(XILINX_SPI(d));
}

static inline int spi_master_enabled(XilinxSPI *s)
{
    return !(s->regs[R_SPICR] & R_SPICR_MTI);
}

static void spi_flush_txfifo(XilinxSPI *s)
{
    uint32_t tx;
    uint32_t rx;

    while (!fifo8_is_empty(&s->tx_fifo)) {
        tx = (uint32_t)fifo8_pop(&s->tx_fifo);
        DB_PRINT("data tx:%x\n", tx);
        rx = ssi_transfer(s->spi, tx);
        DB_PRINT("data rx:%x\n", rx);
        if (fifo8_is_full(&s->rx_fifo)) {
            s->regs[R_IPISR] |= IRQ_DRR_OVERRUN;
        } else {
            fifo8_push(&s->rx_fifo, (uint8_t)rx);
            if (fifo8_is_full(&s->rx_fifo)) {
                s->regs[R_SPISR] |= SR_RX_FULL;
                s->regs[R_IPISR] |= IRQ_DRR_FULL;
            }
        }

        s->regs[R_SPISR] &= ~SR_RX_EMPTY;
        s->regs[R_SPISR] &= ~SR_TX_FULL;
        s->regs[R_SPISR] |= SR_TX_EMPTY;

        s->regs[R_IPISR] |= IRQ_DTR_EMPTY;
        s->regs[R_IPISR] |= IRQ_DRR_NOT_EMPTY;
    }

}

static uint64_t
spi_read(void *opaque, hwaddr addr, unsigned int size)
{
    XilinxSPI *s = opaque;
    uint32_t r = 0;

    addr >>= 2;
    switch (addr) {
    case R_SPIDRR:
        if (fifo8_is_empty(&s->rx_fifo)) {
            DB_PRINT("Read from empty FIFO!\n");
            return 0xdeadbeef;
        }

        s->regs[R_SPISR] &= ~SR_RX_FULL;
        r = fifo8_pop(&s->rx_fifo);
        if (fifo8_is_empty(&s->rx_fifo)) {
            s->regs[R_SPISR] |= SR_RX_EMPTY;
        }
        break;

    case R_SPISR:
        r = s->regs[addr];
        break;

    default:
        if (addr < ARRAY_SIZE(s->regs)) {
            r = s->regs[addr];
        }
        break;

    }
    DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, r);
    xlx_spi_update_irq(s);
    return r;
}

static void
spi_write(void *opaque, hwaddr addr,
            uint64_t val64, unsigned int size)
{
    XilinxSPI *s = opaque;
    uint32_t value = val64;

    DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr, value);
    addr >>= 2;
    switch (addr) {
    case R_SRR:
        if (value != 0xa) {
            DB_PRINT("Invalid write to SRR %x\n", value);
        } else {
            xlx_spi_do_reset(s);
        }
        break;

    case R_SPIDTR:
        s->regs[R_SPISR] &= ~SR_TX_EMPTY;
        fifo8_push(&s->tx_fifo, (uint8_t)value);
        if (fifo8_is_full(&s->tx_fifo)) {
            s->regs[R_SPISR] |= SR_TX_FULL;
        }
        if (!spi_master_enabled(s)) {
            goto done;
        } else {
            DB_PRINT("DTR and master enabled\n");
        }
        spi_flush_txfifo(s);
        break;

    case R_SPISR:
        DB_PRINT("Invalid write to SPISR %x\n", value);
        break;

    case R_IPISR:
        /* Toggle the bits.  */
        s->regs[addr] ^= value;
        break;

    /* Slave Select Register.  */
    case R_SPISSR:
        s->regs[addr] = value;
        xlx_spi_update_cs(s);
        break;

    case R_SPICR:
        /* FIXME: reset irq and sr state to empty queues.  */
        if (value & R_SPICR_RXFF_RST) {
            rxfifo_reset(s);
        }

        if (value & R_SPICR_TXFF_RST) {
            txfifo_reset(s);
        }
        value &= ~(R_SPICR_RXFF_RST | R_SPICR_TXFF_RST);
        s->regs[addr] = value;

        if (!(value & R_SPICR_MTI)) {
            spi_flush_txfifo(s);
        }
        break;

    default:
        if (addr < ARRAY_SIZE(s->regs)) {
            s->regs[addr] = value;
        }
        break;
    }

done:
    xlx_spi_update_irq(s);
}

static const MemoryRegionOps spi_ops = {
    .read = spi_read,
    .write = spi_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4
    }
};

static int xilinx_spi_init(SysBusDevice *sbd)
{
    DeviceState *dev = DEVICE(sbd);
    XilinxSPI *s = XILINX_SPI(dev);
    int i;

    DB_PRINT("\n");

    s->spi = ssi_create_bus(dev, "spi");

    sysbus_init_irq(sbd, &s->irq);
    s->cs_lines = g_new(qemu_irq, s->num_cs);
    ssi_auto_connect_slaves(dev, s->cs_lines, s->spi);
    for (i = 0; i < s->num_cs; ++i) {
        sysbus_init_irq(sbd, &s->cs_lines[i]);
    }

    memory_region_init_io(&s->mmio, OBJECT(s), &spi_ops, s,
                          "xilinx-spi", R_MAX * 4);
    sysbus_init_mmio(sbd, &s->mmio);

    s->irqline = -1;

    fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
    fifo8_create(&s->rx_fifo, FIFO_CAPACITY);

    return 0;
}

static const VMStateDescription vmstate_xilinx_spi = {
    .name = "xilinx_spi",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_FIFO8(tx_fifo, XilinxSPI),
        VMSTATE_FIFO8(rx_fifo, XilinxSPI),
        VMSTATE_UINT32_ARRAY(regs, XilinxSPI, R_MAX),
        VMSTATE_END_OF_LIST()
    }
};

static Property xilinx_spi_properties[] = {
    DEFINE_PROP_UINT8("num-ss-bits", XilinxSPI, num_cs, 1),
    DEFINE_PROP_END_OF_LIST(),
};

static void xilinx_spi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = xilinx_spi_init;
    dc->reset = xlx_spi_reset;
    dc->props = xilinx_spi_properties;
    dc->vmsd = &vmstate_xilinx_spi;
}

static const TypeInfo xilinx_spi_info = {
    .name           = TYPE_XILINX_SPI,
    .parent         = TYPE_SYS_BUS_DEVICE,
    .instance_size  = sizeof(XilinxSPI),
    .class_init     = xilinx_spi_class_init,
};

static void xilinx_spi_register_types(void)
{
    type_register_static(&xilinx_spi_info);
}

type_init(xilinx_spi_register_types)
