/*
 *  ASPEED LPC Controller
 *
 *  Copyright (C) 2017-2018 IBM Corp.
 *
 * This code is licensed under the GPL version 2 or later.  See
 * the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "hw/misc/aspeed_lpc.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"

#define TO_REG(offset) ((offset) >> 2)

#define HICR0                TO_REG(0x00)
#define   HICR0_LPC3E        BIT(7)
#define   HICR0_LPC2E        BIT(6)
#define   HICR0_LPC1E        BIT(5)
#define HICR1                TO_REG(0x04)
#define HICR2                TO_REG(0x08)
#define   HICR2_IBFIE3       BIT(3)
#define   HICR2_IBFIE2       BIT(2)
#define   HICR2_IBFIE1       BIT(1)
#define HICR3                TO_REG(0x0C)
#define HICR4                TO_REG(0x10)
#define   HICR4_KCSENBL      BIT(2)
#define IDR1                 TO_REG(0x24)
#define IDR2                 TO_REG(0x28)
#define IDR3                 TO_REG(0x2C)
#define ODR1                 TO_REG(0x30)
#define ODR2                 TO_REG(0x34)
#define ODR3                 TO_REG(0x38)
#define STR1                 TO_REG(0x3C)
#define   STR_OBF            BIT(0)
#define   STR_IBF            BIT(1)
#define   STR_CMD_DATA       BIT(3)
#define STR2                 TO_REG(0x40)
#define STR3                 TO_REG(0x44)
#define HICR5                TO_REG(0x80)
#define HICR6                TO_REG(0x84)
#define HICR7                TO_REG(0x88)
#define HICR8                TO_REG(0x8C)
#define HICRB                TO_REG(0x100)
#define   HICRB_IBFIE4       BIT(1)
#define   HICRB_LPC4E        BIT(0)
#define IDR4                 TO_REG(0x114)
#define ODR4                 TO_REG(0x118)
#define STR4                 TO_REG(0x11C)

enum aspeed_kcs_channel_id {
    kcs_channel_1 = 0,
    kcs_channel_2,
    kcs_channel_3,
    kcs_channel_4,
};

static const enum aspeed_lpc_subdevice aspeed_kcs_subdevice_map[] = {
    [kcs_channel_1] = aspeed_lpc_kcs_1,
    [kcs_channel_2] = aspeed_lpc_kcs_2,
    [kcs_channel_3] = aspeed_lpc_kcs_3,
    [kcs_channel_4] = aspeed_lpc_kcs_4,
};

struct aspeed_kcs_channel {
    enum aspeed_kcs_channel_id id;

    int idr;
    int odr;
    int str;
};

static const struct aspeed_kcs_channel aspeed_kcs_channel_map[] = {
    [kcs_channel_1] = {
        .id = kcs_channel_1,
        .idr = IDR1,
        .odr = ODR1,
        .str = STR1
    },

    [kcs_channel_2] = {
        .id = kcs_channel_2,
        .idr = IDR2,
        .odr = ODR2,
        .str = STR2
    },

    [kcs_channel_3] = {
        .id = kcs_channel_3,
        .idr = IDR3,
        .odr = ODR3,
        .str = STR3
    },

    [kcs_channel_4] = {
        .id = kcs_channel_4,
        .idr = IDR4,
        .odr = ODR4,
        .str = STR4
    },
};

struct aspeed_kcs_register_data {
    const char *name;
    int reg;
    const struct aspeed_kcs_channel *chan;
};

static const struct aspeed_kcs_register_data aspeed_kcs_registers[] = {
    {
        .name = "idr1",
        .reg = IDR1,
        .chan = &aspeed_kcs_channel_map[kcs_channel_1],
    },
    {
        .name = "odr1",
        .reg = ODR1,
        .chan = &aspeed_kcs_channel_map[kcs_channel_1],
    },
    {
        .name = "str1",
        .reg = STR1,
        .chan = &aspeed_kcs_channel_map[kcs_channel_1],
    },
    {
        .name = "idr2",
        .reg = IDR2,
        .chan = &aspeed_kcs_channel_map[kcs_channel_2],
    },
    {
        .name = "odr2",
        .reg = ODR2,
        .chan = &aspeed_kcs_channel_map[kcs_channel_2],
    },
    {
        .name = "str2",
        .reg = STR2,
        .chan = &aspeed_kcs_channel_map[kcs_channel_2],
    },
    {
        .name = "idr3",
        .reg = IDR3,
        .chan = &aspeed_kcs_channel_map[kcs_channel_3],
    },
    {
        .name = "odr3",
        .reg = ODR3,
        .chan = &aspeed_kcs_channel_map[kcs_channel_3],
    },
    {
        .name = "str3",
        .reg = STR3,
        .chan = &aspeed_kcs_channel_map[kcs_channel_3],
    },
    {
        .name = "idr4",
        .reg = IDR4,
        .chan = &aspeed_kcs_channel_map[kcs_channel_4],
    },
    {
        .name = "odr4",
        .reg = ODR4,
        .chan = &aspeed_kcs_channel_map[kcs_channel_4],
    },
    {
        .name = "str4",
        .reg = STR4,
        .chan = &aspeed_kcs_channel_map[kcs_channel_4],
    },
    { },
};

static const struct aspeed_kcs_register_data *
aspeed_kcs_get_register_data_by_name(const char *name)
{
    const struct aspeed_kcs_register_data *pos = aspeed_kcs_registers;

    while (pos->name) {
        if (!strcmp(pos->name, name)) {
            return pos;
        }
        pos++;
    }

    return NULL;
}

static const struct aspeed_kcs_channel *
aspeed_kcs_get_channel_by_register(int reg)
{
    const struct aspeed_kcs_register_data *pos = aspeed_kcs_registers;

    while (pos->name) {
        if (pos->reg == reg) {
            return pos->chan;
        }
        pos++;
    }

    return NULL;
}

static void aspeed_kcs_get_register_property(Object *obj,
                                             Visitor *v,
                                             const char *name,
                                             void *opaque,
                                             Error **errp)
{
    const struct aspeed_kcs_register_data *data;
    AspeedLPCState *s = ASPEED_LPC(obj);
    uint32_t val;

    data = aspeed_kcs_get_register_data_by_name(name);
    if (!data) {
        return;
    }

    if (!strncmp("odr", name, 3)) {
        s->regs[data->chan->str] &= ~STR_OBF;
    }

    val = s->regs[data->reg];

    visit_type_uint32(v, name, &val, errp);
}

static bool aspeed_kcs_channel_enabled(AspeedLPCState *s,
                                       const struct aspeed_kcs_channel *channel)
{
    switch (channel->id) {
    case kcs_channel_1: return s->regs[HICR0] & HICR0_LPC1E;
    case kcs_channel_2: return s->regs[HICR0] & HICR0_LPC2E;
    case kcs_channel_3:
        return (s->regs[HICR0] & HICR0_LPC3E) &&
                    (s->regs[HICR4] & HICR4_KCSENBL);
    case kcs_channel_4: return s->regs[HICRB] & HICRB_LPC4E;
    default: return false;
    }
}

static bool
aspeed_kcs_channel_ibf_irq_enabled(AspeedLPCState *s,
                                   const struct aspeed_kcs_channel *channel)
{
    if (!aspeed_kcs_channel_enabled(s, channel)) {
            return false;
    }

    switch (channel->id) {
    case kcs_channel_1: return s->regs[HICR2] & HICR2_IBFIE1;
    case kcs_channel_2: return s->regs[HICR2] & HICR2_IBFIE2;
    case kcs_channel_3: return s->regs[HICR2] & HICR2_IBFIE3;
    case kcs_channel_4: return s->regs[HICRB] & HICRB_IBFIE4;
    default: return false;
    }
}

static void aspeed_kcs_set_register_property(Object *obj,
                                             Visitor *v,
                                             const char *name,
                                             void *opaque,
                                             Error **errp)
{
    const struct aspeed_kcs_register_data *data;
    AspeedLPCState *s = ASPEED_LPC(obj);
    uint32_t val;

    data = aspeed_kcs_get_register_data_by_name(name);
    if (!data) {
        return;
    }

    if (!visit_type_uint32(v, name, &val, errp)) {
        return;
    }

    if (strncmp("str", name, 3)) {
        s->regs[data->reg] = val;
    }

    if (!strncmp("idr", name, 3)) {
        s->regs[data->chan->str] |= STR_IBF;
        if (aspeed_kcs_channel_ibf_irq_enabled(s, data->chan)) {
            enum aspeed_lpc_subdevice subdev;

            subdev = aspeed_kcs_subdevice_map[data->chan->id];
            qemu_irq_raise(s->subdevice_irqs[subdev]);
        }
    }
}

static void aspeed_lpc_set_irq(void *opaque, int irq, int level)
{
    AspeedLPCState *s = (AspeedLPCState *)opaque;

    if (level) {
        s->subdevice_irqs_pending |= BIT(irq);
    } else {
        s->subdevice_irqs_pending &= ~BIT(irq);
    }

    qemu_set_irq(s->irq, !!s->subdevice_irqs_pending);
}

static uint64_t aspeed_lpc_read(void *opaque, hwaddr offset, unsigned size)
{
    AspeedLPCState *s = ASPEED_LPC(opaque);
    int reg = TO_REG(offset);

    if (reg >= ARRAY_SIZE(s->regs)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
        return 0;
    }

    switch (reg) {
    case IDR1:
    case IDR2:
    case IDR3:
    case IDR4:
    {
        const struct aspeed_kcs_channel *channel;

        channel = aspeed_kcs_get_channel_by_register(reg);
        if (s->regs[channel->str] & STR_IBF) {
            enum aspeed_lpc_subdevice subdev;

            subdev = aspeed_kcs_subdevice_map[channel->id];
            qemu_irq_lower(s->subdevice_irqs[subdev]);
        }

        s->regs[channel->str] &= ~STR_IBF;
        break;
    }
    default:
        break;
    }

    return s->regs[reg];
}

static void aspeed_lpc_write(void *opaque, hwaddr offset, uint64_t data,
                             unsigned int size)
{
    AspeedLPCState *s = ASPEED_LPC(opaque);
    int reg = TO_REG(offset);

    if (reg >= ARRAY_SIZE(s->regs)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
        return;
    }


    switch (reg) {
    case ODR1:
    case ODR2:
    case ODR3:
    case ODR4:
        s->regs[aspeed_kcs_get_channel_by_register(reg)->str] |= STR_OBF;
        break;
    default:
        break;
    }

    s->regs[reg] = data;
}

static const MemoryRegionOps aspeed_lpc_ops = {
    .read = aspeed_lpc_read,
    .write = aspeed_lpc_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static void aspeed_lpc_reset(DeviceState *dev)
{
    struct AspeedLPCState *s = ASPEED_LPC(dev);

    s->subdevice_irqs_pending = 0;

    memset(s->regs, 0, sizeof(s->regs));

    s->regs[HICR7] = s->hicr7;
}

static void aspeed_lpc_realize(DeviceState *dev, Error **errp)
{
    AspeedLPCState *s = ASPEED_LPC(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    sysbus_init_irq(sbd, &s->irq);
    sysbus_init_irq(sbd, &s->subdevice_irqs[aspeed_lpc_kcs_1]);
    sysbus_init_irq(sbd, &s->subdevice_irqs[aspeed_lpc_kcs_2]);
    sysbus_init_irq(sbd, &s->subdevice_irqs[aspeed_lpc_kcs_3]);
    sysbus_init_irq(sbd, &s->subdevice_irqs[aspeed_lpc_kcs_4]);
    sysbus_init_irq(sbd, &s->subdevice_irqs[aspeed_lpc_ibt]);

    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_lpc_ops, s,
            TYPE_ASPEED_LPC, 0x1000);

    sysbus_init_mmio(sbd, &s->iomem);

    qdev_init_gpio_in(dev, aspeed_lpc_set_irq, ASPEED_LPC_NR_SUBDEVS);
}

static void aspeed_lpc_init(Object *obj)
{
    object_property_add(obj, "idr1", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "odr1", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "str1", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "idr2", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "odr2", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "str2", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "idr3", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "odr3", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "str3", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "idr4", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "odr4", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
    object_property_add(obj, "str4", "uint32", aspeed_kcs_get_register_property,
                        aspeed_kcs_set_register_property, NULL, NULL);
}

static const VMStateDescription vmstate_aspeed_lpc = {
    .name = TYPE_ASPEED_LPC,
    .version_id = 2,
    .minimum_version_id = 2,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, AspeedLPCState, ASPEED_LPC_NR_REGS),
        VMSTATE_UINT32(subdevice_irqs_pending, AspeedLPCState),
        VMSTATE_END_OF_LIST(),
    }
};

static Property aspeed_lpc_properties[] = {
    DEFINE_PROP_UINT32("hicr7", AspeedLPCState, hicr7, 0),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->realize = aspeed_lpc_realize;
    device_class_set_legacy_reset(dc, aspeed_lpc_reset);
    dc->desc = "Aspeed LPC Controller",
    dc->vmsd = &vmstate_aspeed_lpc;
    device_class_set_props(dc, aspeed_lpc_properties);
}

static const TypeInfo aspeed_lpc_info = {
    .name = TYPE_ASPEED_LPC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(AspeedLPCState),
    .class_init = aspeed_lpc_class_init,
    .instance_init = aspeed_lpc_init,
};

static void aspeed_lpc_register_types(void)
{
    type_register_static(&aspeed_lpc_info);
}

type_init(aspeed_lpc_register_types);
