/*
 * Block model of SPI controller present in
 * Microsemi's SmartFusion2 and SmartFusion SoCs.
 *
 * Copyright (C) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
 *
 * 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 "qemu/osdep.h"
#include "hw/ssi/mss-spi.h"
#include "qemu/log.h"

#ifndef MSS_SPI_ERR_DEBUG
#define MSS_SPI_ERR_DEBUG   0
#endif

#define DB_PRINT_L(lvl, fmt, args...) do { \
    if (MSS_SPI_ERR_DEBUG >= lvl) { \
        qemu_log("%s: " fmt "\n", __func__, ## args); \
    } \
} while (0)

#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

#define FIFO_CAPACITY         32

#define R_SPI_CONTROL         0
#define R_SPI_DFSIZE          1
#define R_SPI_STATUS          2
#define R_SPI_INTCLR          3
#define R_SPI_RX              4
#define R_SPI_TX              5
#define R_SPI_CLKGEN          6
#define R_SPI_SS              7
#define R_SPI_MIS             8
#define R_SPI_RIS             9

#define S_TXDONE             (1 << 0)
#define S_RXRDY              (1 << 1)
#define S_RXCHOVRF           (1 << 2)
#define S_RXFIFOFUL          (1 << 4)
#define S_RXFIFOFULNXT       (1 << 5)
#define S_RXFIFOEMP          (1 << 6)
#define S_RXFIFOEMPNXT       (1 << 7)
#define S_TXFIFOFUL          (1 << 8)
#define S_TXFIFOFULNXT       (1 << 9)
#define S_TXFIFOEMP          (1 << 10)
#define S_TXFIFOEMPNXT       (1 << 11)
#define S_FRAMESTART         (1 << 12)
#define S_SSEL               (1 << 13)
#define S_ACTIVE             (1 << 14)

#define C_ENABLE             (1 << 0)
#define C_MODE               (1 << 1)
#define C_INTRXDATA          (1 << 4)
#define C_INTTXDATA          (1 << 5)
#define C_INTRXOVRFLO        (1 << 6)
#define C_SPS                (1 << 26)
#define C_BIGFIFO            (1 << 29)
#define C_RESET              (1 << 31)

#define FRAMESZ_MASK         0x3F
#define FMCOUNT_MASK         0x00FFFF00
#define FMCOUNT_SHIFT        8
#define FRAMESZ_MAX          32

static void txfifo_reset(MSSSpiState *s)
{
    fifo32_reset(&s->tx_fifo);

    s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
    s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
}

static void rxfifo_reset(MSSSpiState *s)
{
    fifo32_reset(&s->rx_fifo);

    s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
    s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
}

static void set_fifodepth(MSSSpiState *s)
{
    unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;

    if (size <= 8) {
        s->fifo_depth = 32;
    } else if (size <= 16) {
        s->fifo_depth = 16;
    } else {
        s->fifo_depth = 8;
    }
}

static void update_mis(MSSSpiState *s)
{
    uint32_t reg = s->regs[R_SPI_CONTROL];
    uint32_t tmp;

    /*
     * form the Control register interrupt enable bits
     * same as RIS, MIS and Interrupt clear registers for simplicity
     */
    tmp = ((reg & C_INTRXOVRFLO) >> 4) | ((reg & C_INTRXDATA) >> 3) |
           ((reg & C_INTTXDATA) >> 5);
    s->regs[R_SPI_MIS] |= tmp & s->regs[R_SPI_RIS];
}

static void spi_update_irq(MSSSpiState *s)
{
    int irq;

    update_mis(s);
    irq = !!(s->regs[R_SPI_MIS]);

    qemu_set_irq(s->irq, irq);
}

static void mss_spi_reset(DeviceState *d)
{
    MSSSpiState *s = MSS_SPI(d);

    memset(s->regs, 0, sizeof s->regs);
    s->regs[R_SPI_CONTROL] = 0x80000102;
    s->regs[R_SPI_DFSIZE] = 0x4;
    s->regs[R_SPI_STATUS] = S_SSEL | S_TXFIFOEMP | S_RXFIFOEMP;
    s->regs[R_SPI_CLKGEN] = 0x7;
    s->regs[R_SPI_RIS] = 0x0;

    s->fifo_depth = 4;
    s->frame_count = 1;
    s->enabled = false;

    rxfifo_reset(s);
    txfifo_reset(s);
}

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

    addr >>= 2;
    switch (addr) {
    case R_SPI_RX:
        s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
        s->regs[R_SPI_STATUS] &= ~S_RXCHOVRF;
        ret = fifo32_pop(&s->rx_fifo);
        if (fifo32_is_empty(&s->rx_fifo)) {
            s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
        }
        break;

    case R_SPI_MIS:
        update_mis(s);
        ret = s->regs[R_SPI_MIS];
        break;

    default:
        if (addr < ARRAY_SIZE(s->regs)) {
            ret = s->regs[addr];
        } else {
            qemu_log_mask(LOG_GUEST_ERROR,
                         "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
                         addr * 4);
            return ret;
        }
        break;
    }

    DB_PRINT("addr=0x%" HWADDR_PRIx " = 0x%" PRIx32, addr * 4, ret);
    spi_update_irq(s);
    return ret;
}

static void assert_cs(MSSSpiState *s)
{
    qemu_set_irq(s->cs_line, 0);
}

static void deassert_cs(MSSSpiState *s)
{
    qemu_set_irq(s->cs_line, 1);
}

static void spi_flush_txfifo(MSSSpiState *s)
{
    uint32_t tx;
    uint32_t rx;
    bool sps = !!(s->regs[R_SPI_CONTROL] & C_SPS);

    /*
     * Chip Select(CS) is automatically controlled by this controller.
     * If SPS bit is set in Control register then CS is asserted
     * until all the frames set in frame count of Control register are
     * transferred. If SPS is not set then CS pulses between frames.
     * Note that Slave Select register specifies which of the CS line
     * has to be controlled automatically by controller. Bits SS[7:1] are for
     * masters in FPGA fabric since we model only Microcontroller subsystem
     * of Smartfusion2 we control only one CS(SS[0]) line.
     */
    while (!fifo32_is_empty(&s->tx_fifo) && s->frame_count) {
        assert_cs(s);

        s->regs[R_SPI_STATUS] &= ~(S_TXDONE | S_RXRDY);

        tx = fifo32_pop(&s->tx_fifo);
        DB_PRINT("data tx:0x%" PRIx32, tx);
        rx = ssi_transfer(s->spi, tx);
        DB_PRINT("data rx:0x%" PRIx32, rx);

        if (fifo32_num_used(&s->rx_fifo) == s->fifo_depth) {
            s->regs[R_SPI_STATUS] |= S_RXCHOVRF;
            s->regs[R_SPI_RIS] |= S_RXCHOVRF;
        } else {
            fifo32_push(&s->rx_fifo, rx);
            s->regs[R_SPI_STATUS] &= ~S_RXFIFOEMP;
            if (fifo32_num_used(&s->rx_fifo) == (s->fifo_depth - 1)) {
                s->regs[R_SPI_STATUS] |= S_RXFIFOFULNXT;
            } else if (fifo32_num_used(&s->rx_fifo) == s->fifo_depth) {
                s->regs[R_SPI_STATUS] |= S_RXFIFOFUL;
            }
        }
        s->frame_count--;
        if (!sps) {
            deassert_cs(s);
        }
    }

    if (!s->frame_count) {
        s->frame_count = (s->regs[R_SPI_CONTROL] & FMCOUNT_MASK) >>
                            FMCOUNT_SHIFT;
        deassert_cs(s);
        s->regs[R_SPI_RIS] |= S_TXDONE | S_RXRDY;
        s->regs[R_SPI_STATUS] |= S_TXDONE | S_RXRDY;
   }
}

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

    DB_PRINT("addr=0x%" HWADDR_PRIx " =0x%" PRIx32, addr, value);
    addr >>= 2;

    switch (addr) {
    case R_SPI_TX:
        /* adding to already full FIFO */
        if (fifo32_num_used(&s->tx_fifo) == s->fifo_depth) {
            break;
        }
        s->regs[R_SPI_STATUS] &= ~S_TXFIFOEMP;
        fifo32_push(&s->tx_fifo, value);
        if (fifo32_num_used(&s->tx_fifo) == (s->fifo_depth - 1)) {
            s->regs[R_SPI_STATUS] |= S_TXFIFOFULNXT;
        } else if (fifo32_num_used(&s->tx_fifo) == s->fifo_depth) {
            s->regs[R_SPI_STATUS] |= S_TXFIFOFUL;
        }
        if (s->enabled) {
            spi_flush_txfifo(s);
        }
        break;

    case R_SPI_CONTROL:
        s->regs[R_SPI_CONTROL] = value;
        if (value & C_BIGFIFO) {
            set_fifodepth(s);
        } else {
            s->fifo_depth = 4;
        }
        s->enabled = value & C_ENABLE;
        s->frame_count = (value & FMCOUNT_MASK) >> FMCOUNT_SHIFT;
        if (value & C_RESET) {
            mss_spi_reset(DEVICE(s));
        }
        break;

    case R_SPI_DFSIZE:
        if (s->enabled) {
            break;
        }
        /*
         * [31:6] bits are reserved bits and for future use.
         * [5:0] are for frame size. Only [5:0] bits are validated
         * during write, [31:6] bits are untouched.
         */
        if ((value & FRAMESZ_MASK) > FRAMESZ_MAX) {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: Incorrect size %u provided."
                         "Maximum frame size is %u\n",
                         __func__, value & FRAMESZ_MASK, FRAMESZ_MAX);
            break;
        }
        s->regs[R_SPI_DFSIZE] = value;
        break;

    case R_SPI_INTCLR:
        s->regs[R_SPI_INTCLR] = value;
        if (value & S_TXDONE) {
            s->regs[R_SPI_RIS] &= ~S_TXDONE;
        }
        if (value & S_RXRDY) {
            s->regs[R_SPI_RIS] &= ~S_RXRDY;
        }
        if (value & S_RXCHOVRF) {
            s->regs[R_SPI_RIS] &= ~S_RXCHOVRF;
        }
        break;

    case R_SPI_MIS:
    case R_SPI_STATUS:
    case R_SPI_RIS:
            qemu_log_mask(LOG_GUEST_ERROR,
                         "%s: Write to read only register 0x%" HWADDR_PRIx "\n",
                         __func__, addr * 4);
        break;

    default:
        if (addr < ARRAY_SIZE(s->regs)) {
            s->regs[addr] = value;
        } else {
            qemu_log_mask(LOG_GUEST_ERROR,
                         "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
                         addr * 4);
        }
        break;
    }

    spi_update_irq(s);
}

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

static void mss_spi_realize(DeviceState *dev, Error **errp)
{
    MSSSpiState *s = MSS_SPI(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

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

    sysbus_init_irq(sbd, &s->irq);
    ssi_auto_connect_slaves(dev, &s->cs_line, s->spi);
    sysbus_init_irq(sbd, &s->cs_line);

    memory_region_init_io(&s->mmio, OBJECT(s), &spi_ops, s,
                          TYPE_MSS_SPI, R_SPI_MAX * 4);
    sysbus_init_mmio(sbd, &s->mmio);

    fifo32_create(&s->tx_fifo, FIFO_CAPACITY);
    fifo32_create(&s->rx_fifo, FIFO_CAPACITY);
}

static const VMStateDescription vmstate_mss_spi = {
    .name = TYPE_MSS_SPI,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_FIFO32(tx_fifo, MSSSpiState),
        VMSTATE_FIFO32(rx_fifo, MSSSpiState),
        VMSTATE_UINT32_ARRAY(regs, MSSSpiState, R_SPI_MAX),
        VMSTATE_END_OF_LIST()
    }
};

static void mss_spi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = mss_spi_realize;
    dc->reset = mss_spi_reset;
    dc->vmsd = &vmstate_mss_spi;
}

static const TypeInfo mss_spi_info = {
    .name           = TYPE_MSS_SPI,
    .parent         = TYPE_SYS_BUS_DEVICE,
    .instance_size  = sizeof(MSSSpiState),
    .class_init     = mss_spi_class_init,
};

static void mss_spi_register_types(void)
{
    type_register_static(&mss_spi_info);
}

type_init(mss_spi_register_types)
