/*
 * ADC registers for Xilinx Zynq Platform
 *
 * Copyright (c) 2015 Guenter Roeck
 * Based on hw/misc/zynq_slcr.c, written by Michal Simek
 *
 * 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 of the License, or (at your option) any later version.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/misc/zynq-xadc.h"
#include "qemu/timer.h"
#include "sysemu/sysemu.h"

enum {
    CFG                = 0x000 / 4,
    INT_STS,
    INT_MASK,
    MSTS,
    CMDFIFO,
    RDFIFO,
    MCTL,
};

#define CFG_ENABLE              BIT(31)
#define CFG_CFIFOTH_SHIFT       20
#define CFG_CFIFOTH_LENGTH      4
#define CFG_DFIFOTH_SHIFT       16
#define CFG_DFIFOTH_LENGTH      4
#define CFG_WEDGE               BIT(13)
#define CFG_REDGE               BIT(12)
#define CFG_TCKRATE_SHIFT       8
#define CFG_TCKRATE_LENGTH      2

#define CFG_TCKRATE_DIV(x)      (0x1 << (x - 1))

#define CFG_IGAP_SHIFT          0
#define CFG_IGAP_LENGTH         5

#define INT_CFIFO_LTH           BIT(9)
#define INT_DFIFO_GTH           BIT(8)
#define INT_OT                  BIT(7)
#define INT_ALM_SHIFT           0
#define INT_ALM_LENGTH          7
#define INT_ALM_MASK            (((1 << INT_ALM_LENGTH) - 1) << INT_ALM_SHIFT)

#define INT_ALL (INT_CFIFO_LTH | INT_DFIFO_GTH | INT_OT | INT_ALM_MASK)

#define MSTS_CFIFO_LVL_SHIFT    16
#define MSTS_CFIFO_LVL_LENGTH   4
#define MSTS_DFIFO_LVL_SHIFT    12
#define MSTS_DFIFO_LVL_LENGTH   4
#define MSTS_CFIFOF             BIT(11)
#define MSTS_CFIFOE             BIT(10)
#define MSTS_DFIFOF             BIT(9)
#define MSTS_DFIFOE             BIT(8)
#define MSTS_OT                 BIT(7)
#define MSTS_ALM_SHIFT          0
#define MSTS_ALM_LENGTH         7

#define MCTL_RESET              BIT(4)

#define CMD_NOP                 0x00
#define CMD_READ                0x01
#define CMD_WRITE               0x02

static void zynq_xadc_update_ints(ZynqXADCState *s)
{

    /* We are fast, commands are actioned instantly so the CFIFO is always
     * empty (and below threshold).
     */
    s->regs[INT_STS] |= INT_CFIFO_LTH;

    if (s->xadc_dfifo_entries >
        extract32(s->regs[CFG], CFG_DFIFOTH_SHIFT, CFG_DFIFOTH_LENGTH)) {
        s->regs[INT_STS] |= INT_DFIFO_GTH;
    }

    qemu_set_irq(s->qemu_irq, !!(s->regs[INT_STS] & ~s->regs[INT_MASK]));
}

static void zynq_xadc_reset(DeviceState *d)
{
    ZynqXADCState *s = ZYNQ_XADC(d);

    s->regs[CFG] = 0x14 << CFG_IGAP_SHIFT |
                   CFG_TCKRATE_DIV(4) << CFG_TCKRATE_SHIFT | CFG_REDGE;
    s->regs[INT_STS] = INT_CFIFO_LTH;
    s->regs[INT_MASK] = 0xffffffff;
    s->regs[CMDFIFO] = 0;
    s->regs[RDFIFO] = 0;
    s->regs[MCTL] = MCTL_RESET;

    memset(s->xadc_regs, 0, sizeof(s->xadc_regs));
    memset(s->xadc_dfifo, 0, sizeof(s->xadc_dfifo));
    s->xadc_dfifo_entries = 0;

    zynq_xadc_update_ints(s);
}

static uint16_t xadc_pop_dfifo(ZynqXADCState *s)
{
    uint16_t rv = s->xadc_dfifo[0];
    int i;

    if (s->xadc_dfifo_entries > 0) {
        s->xadc_dfifo_entries--;
    }
    for (i = 0; i < s->xadc_dfifo_entries; i++) {
        s->xadc_dfifo[i] = s->xadc_dfifo[i + 1];
    }
    s->xadc_dfifo[s->xadc_dfifo_entries] = 0;
    zynq_xadc_update_ints(s);
    return rv;
}

static void xadc_push_dfifo(ZynqXADCState *s, uint16_t regval)
{
    if (s->xadc_dfifo_entries < ZYNQ_XADC_FIFO_DEPTH) {
        s->xadc_dfifo[s->xadc_dfifo_entries++] = s->xadc_read_reg_previous;
    }
    s->xadc_read_reg_previous = regval;
    zynq_xadc_update_ints(s);
}

static bool zynq_xadc_check_offset(hwaddr offset, bool rnw)
{
    switch (offset) {
    case CFG:
    case INT_MASK:
    case INT_STS:
    case MCTL:
        return true;
    case RDFIFO:
    case MSTS:
        return rnw;     /* read only */
    case CMDFIFO:
        return !rnw;    /* write only */
    default:
        return false;
    }
}

static uint64_t zynq_xadc_read(void *opaque, hwaddr offset, unsigned size)
{
    ZynqXADCState *s = opaque;
    int reg = offset / 4;
    uint32_t rv = 0;

    if (!zynq_xadc_check_offset(reg, true)) {
        qemu_log_mask(LOG_GUEST_ERROR, "zynq_xadc: Invalid read access to "
                      "addr %" HWADDR_PRIx "\n", offset);
        return 0;
    }

    switch (reg) {
    case CFG:
    case INT_MASK:
    case INT_STS:
    case MCTL:
        rv = s->regs[reg];
        break;
    case MSTS:
        rv = MSTS_CFIFOE;
        rv |= s->xadc_dfifo_entries << MSTS_DFIFO_LVL_SHIFT;
        if (!s->xadc_dfifo_entries) {
            rv |= MSTS_DFIFOE;
        } else if (s->xadc_dfifo_entries == ZYNQ_XADC_FIFO_DEPTH) {
            rv |= MSTS_DFIFOF;
        }
        break;
    case RDFIFO:
        rv = xadc_pop_dfifo(s);
        break;
    }
    return rv;
}

static void zynq_xadc_write(void *opaque, hwaddr offset, uint64_t val,
                            unsigned size)
{
    ZynqXADCState *s = (ZynqXADCState *)opaque;
    int reg = offset / 4;
    int xadc_reg;
    int xadc_cmd;
    int xadc_data;

    if (!zynq_xadc_check_offset(reg, false)) {
        qemu_log_mask(LOG_GUEST_ERROR, "zynq_xadc: Invalid write access "
                      "to addr %" HWADDR_PRIx "\n", offset);
        return;
    }

    switch (reg) {
    case CFG:
        s->regs[CFG] = val;
        break;
    case INT_STS:
        s->regs[INT_STS] &= ~val;
        break;
    case INT_MASK:
        s->regs[INT_MASK] = val & INT_ALL;
        break;
    case CMDFIFO:
        xadc_cmd  = extract32(val, 26,  4);
        xadc_reg  = extract32(val, 16, 10);
        xadc_data = extract32(val,  0, 16);

        if (s->regs[MCTL] & MCTL_RESET) {
            qemu_log_mask(LOG_GUEST_ERROR, "zynq_xadc: Sending command "
                          "while comm channel held in reset: %" PRIx32 "\n",
                          (uint32_t) val);
            break;
        }

        if (xadc_reg >= ZYNQ_XADC_NUM_ADC_REGS && xadc_cmd != CMD_NOP) {
            qemu_log_mask(LOG_GUEST_ERROR, "read/write op to invalid xadc "
                          "reg 0x%x\n", xadc_reg);
            break;
        }

        switch (xadc_cmd) {
        case CMD_READ:
            xadc_push_dfifo(s, s->xadc_regs[xadc_reg]);
            break;
        case CMD_WRITE:
            s->xadc_regs[xadc_reg] = xadc_data;
            /* fallthrough */
        case CMD_NOP:
            xadc_push_dfifo(s, 0);
            break;
        }
        break;
    case MCTL:
        s->regs[MCTL] = val & 0x00fffeff;
        break;
    }
    zynq_xadc_update_ints(s);
}

static const MemoryRegionOps xadc_ops = {
    .read = zynq_xadc_read,
    .write = zynq_xadc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void zynq_xadc_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    ZynqXADCState *s = ZYNQ_XADC(obj);

    memory_region_init_io(&s->iomem, obj, &xadc_ops, s, "zynq-xadc",
                          ZYNQ_XADC_MMIO_SIZE);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->qemu_irq);
}

static const VMStateDescription vmstate_zynq_xadc = {
    .name = "zynq-xadc",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, ZynqXADCState, ZYNQ_XADC_NUM_IO_REGS),
        VMSTATE_UINT16_ARRAY(xadc_regs, ZynqXADCState,
                             ZYNQ_XADC_NUM_ADC_REGS),
        VMSTATE_UINT16_ARRAY(xadc_dfifo, ZynqXADCState,
                             ZYNQ_XADC_FIFO_DEPTH),
        VMSTATE_UINT16(xadc_read_reg_previous, ZynqXADCState),
        VMSTATE_UINT16(xadc_dfifo_entries, ZynqXADCState),
        VMSTATE_END_OF_LIST()
    }
};

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

    dc->vmsd = &vmstate_zynq_xadc;
    dc->reset = zynq_xadc_reset;
}

static const TypeInfo zynq_xadc_info = {
    .class_init = zynq_xadc_class_init,
    .name  = TYPE_ZYNQ_XADC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size  = sizeof(ZynqXADCState),
    .instance_init = zynq_xadc_init,
};

static void zynq_xadc_register_types(void)
{
    type_register_static(&zynq_xadc_info);
}

type_init(zynq_xadc_register_types)
