/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * QEMU Loongson 7A1000 I/O interrupt controller.
 *
 * Copyright (C) 2021 Loongson Technology Corporation Limited
 */

#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "hw/sysbus.h"
#include "hw/loongarch/virt.h"
#include "hw/pci-host/ls7a.h"
#include "hw/irq.h"
#include "hw/intc/loongarch_pch_pic.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "trace.h"
#include "qapi/error.h"

static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
{
    uint64_t val;
    int irq;

    if (level) {
        val = mask & s->intirr & ~s->int_mask;
        if (val) {
            irq = ctz64(val);
            s->intisr |= MAKE_64BIT_MASK(irq, 1);
            qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
        }
    } else {
        /*
         * intirr means requested pending irq
         * do not clear pending irq for edge-triggered on lowering edge
         */
        val = mask & s->intisr & ~s->intirr;
        if (val) {
            irq = ctz64(val);
            s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
            qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
        }
    }
}

static void pch_pic_irq_handler(void *opaque, int irq, int level)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint64_t mask = 1ULL << irq;

    assert(irq < s->irq_num);
    trace_loongarch_pch_pic_irq_handler(irq, level);

    if (s->intedge & mask) {
        /* Edge triggered */
        if (level) {
            if ((s->last_intirr & mask) == 0) {
                /* marked pending on a rising edge */
                s->intirr |= mask;
            }
            s->last_intirr |= mask;
        } else {
            s->last_intirr &= ~mask;
        }
    } else {
        /* Level triggered */
        if (level) {
            s->intirr |= mask;
            s->last_intirr |= mask;
        } else {
            s->intirr &= ~mask;
            s->last_intirr &= ~mask;
        }
    }
    pch_pic_update_irq(s, mask, level);
}

static uint64_t loongarch_pch_pic_low_readw(void *opaque, hwaddr addr,
                                            unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint64_t val = 0;
    uint32_t offset = addr & 0xfff;

    switch (offset) {
    case PCH_PIC_INT_ID_LO:
        val = PCH_PIC_INT_ID_VAL;
        break;
    case PCH_PIC_INT_ID_HI:
        /*
         * With 7A1000 manual
         *   bit  0-15 pch irqchip version
         *   bit 16-31 irq number supported with pch irqchip
         */
        val = deposit32(PCH_PIC_INT_ID_VER, 16, 16, s->irq_num - 1);
        break;
    case PCH_PIC_INT_MASK_LO:
        val = (uint32_t)s->int_mask;
        break;
    case PCH_PIC_INT_MASK_HI:
        val = s->int_mask >> 32;
        break;
    case PCH_PIC_INT_EDGE_LO:
        val = (uint32_t)s->intedge;
        break;
    case PCH_PIC_INT_EDGE_HI:
        val = s->intedge >> 32;
        break;
    case PCH_PIC_HTMSI_EN_LO:
        val = (uint32_t)s->htmsi_en;
        break;
    case PCH_PIC_HTMSI_EN_HI:
        val = s->htmsi_en >> 32;
        break;
    case PCH_PIC_AUTO_CTRL0_LO:
    case PCH_PIC_AUTO_CTRL0_HI:
    case PCH_PIC_AUTO_CTRL1_LO:
    case PCH_PIC_AUTO_CTRL1_HI:
        break;
    default:
        break;
    }

    trace_loongarch_pch_pic_low_readw(size, addr, val);
    return val;
}

static uint64_t get_writew_val(uint64_t value, uint32_t target, bool hi)
{
    uint64_t mask = 0xffffffff00000000;
    uint64_t data = target;

    return hi ? (value & ~mask) | (data << 32) : (value & mask) | data;
}

static void loongarch_pch_pic_low_writew(void *opaque, hwaddr addr,
                                         uint64_t value, unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint32_t offset, old_valid, data = (uint32_t)value;
    uint64_t old, int_mask;
    offset = addr & 0xfff;

    trace_loongarch_pch_pic_low_writew(size, addr, data);

    switch (offset) {
    case PCH_PIC_INT_MASK_LO:
        old = s->int_mask;
        s->int_mask = get_writew_val(old, data, 0);
        old_valid = (uint32_t)old;
        if (old_valid & ~data) {
            pch_pic_update_irq(s, (old_valid & ~data), 1);
        }
        if (~old_valid & data) {
            pch_pic_update_irq(s, (~old_valid & data), 0);
        }
        break;
    case PCH_PIC_INT_MASK_HI:
        old = s->int_mask;
        s->int_mask = get_writew_val(old, data, 1);
        old_valid = (uint32_t)(old >> 32);
        int_mask = old_valid & ~data;
        if (int_mask) {
            pch_pic_update_irq(s, int_mask << 32, 1);
        }
        int_mask = ~old_valid & data;
        if (int_mask) {
            pch_pic_update_irq(s, int_mask << 32, 0);
        }
        break;
    case PCH_PIC_INT_EDGE_LO:
        s->intedge = get_writew_val(s->intedge, data, 0);
        break;
    case PCH_PIC_INT_EDGE_HI:
        s->intedge = get_writew_val(s->intedge, data, 1);
        break;
    case PCH_PIC_INT_CLEAR_LO:
        if (s->intedge & data) {
            s->intirr &= (~data);
            pch_pic_update_irq(s, data, 0);
            s->intisr &= (~data);
        }
        break;
    case PCH_PIC_INT_CLEAR_HI:
        value <<= 32;
        if (s->intedge & value) {
            s->intirr &= (~value);
            pch_pic_update_irq(s, value, 0);
            s->intisr &= (~value);
        }
        break;
    case PCH_PIC_HTMSI_EN_LO:
        s->htmsi_en = get_writew_val(s->htmsi_en, data, 0);
        break;
    case PCH_PIC_HTMSI_EN_HI:
        s->htmsi_en = get_writew_val(s->htmsi_en, data, 1);
        break;
    case PCH_PIC_AUTO_CTRL0_LO:
    case PCH_PIC_AUTO_CTRL0_HI:
    case PCH_PIC_AUTO_CTRL1_LO:
    case PCH_PIC_AUTO_CTRL1_HI:
        break;
    default:
        break;
    }
}

static uint64_t loongarch_pch_pic_high_readw(void *opaque, hwaddr addr,
                                        unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint64_t val = 0;
    uint32_t offset = addr & 0xfff;

    switch (offset) {
    case STATUS_LO_START:
        val = (uint32_t)(s->intisr & (~s->int_mask));
        break;
    case STATUS_HI_START:
        val = (s->intisr & (~s->int_mask)) >> 32;
        break;
    case POL_LO_START:
        val = (uint32_t)s->int_polarity;
        break;
    case POL_HI_START:
        val = s->int_polarity >> 32;
        break;
    default:
        break;
    }

    trace_loongarch_pch_pic_high_readw(size, addr, val);
    return val;
}

static void loongarch_pch_pic_high_writew(void *opaque, hwaddr addr,
                                     uint64_t value, unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint32_t offset, data = (uint32_t)value;
    offset = addr & 0xfff;

    trace_loongarch_pch_pic_high_writew(size, addr, data);

    switch (offset) {
    case STATUS_LO_START:
        s->intisr = get_writew_val(s->intisr, data, 0);
        break;
    case STATUS_HI_START:
        s->intisr = get_writew_val(s->intisr, data, 1);
        break;
    case POL_LO_START:
        s->int_polarity = get_writew_val(s->int_polarity, data, 0);
        break;
    case POL_HI_START:
        s->int_polarity = get_writew_val(s->int_polarity, data, 1);
        break;
    default:
        break;
    }
}

static uint64_t loongarch_pch_pic_readb(void *opaque, hwaddr addr,
                                        unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint64_t val = 0;
    uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_OFFSET;
    int64_t offset_tmp;

    switch (offset) {
    case PCH_PIC_HTMSI_VEC_OFFSET ... PCH_PIC_HTMSI_VEC_END:
        offset_tmp = offset - PCH_PIC_HTMSI_VEC_OFFSET;
        if (offset_tmp >= 0 && offset_tmp < 64) {
            val = s->htmsi_vector[offset_tmp];
        }
        break;
    case PCH_PIC_ROUTE_ENTRY_OFFSET ... PCH_PIC_ROUTE_ENTRY_END:
        offset_tmp = offset - PCH_PIC_ROUTE_ENTRY_OFFSET;
        if (offset_tmp >= 0 && offset_tmp < 64) {
            val = s->route_entry[offset_tmp];
        }
        break;
    default:
        break;
    }

    trace_loongarch_pch_pic_readb(size, addr, val);
    return val;
}

static void loongarch_pch_pic_writeb(void *opaque, hwaddr addr,
                                     uint64_t data, unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    int32_t offset_tmp;
    uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_OFFSET;

    trace_loongarch_pch_pic_writeb(size, addr, data);

    switch (offset) {
    case PCH_PIC_HTMSI_VEC_OFFSET ... PCH_PIC_HTMSI_VEC_END:
        offset_tmp = offset - PCH_PIC_HTMSI_VEC_OFFSET;
        if (offset_tmp >= 0 && offset_tmp < 64) {
            s->htmsi_vector[offset_tmp] = (uint8_t)(data & 0xff);
        }
        break;
    case PCH_PIC_ROUTE_ENTRY_OFFSET ... PCH_PIC_ROUTE_ENTRY_END:
        offset_tmp = offset - PCH_PIC_ROUTE_ENTRY_OFFSET;
        if (offset_tmp >= 0 && offset_tmp < 64) {
            s->route_entry[offset_tmp] = (uint8_t)(data & 0xff);
        }
        break;
    default:
        break;
    }
}

static const MemoryRegionOps loongarch_pch_pic_reg32_low_ops = {
    .read = loongarch_pch_pic_low_readw,
    .write = loongarch_pch_pic_low_writew,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static const MemoryRegionOps loongarch_pch_pic_reg32_high_ops = {
    .read = loongarch_pch_pic_high_readw,
    .write = loongarch_pch_pic_high_writew,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static const MemoryRegionOps loongarch_pch_pic_reg8_ops = {
    .read = loongarch_pch_pic_readb,
    .write = loongarch_pch_pic_writeb,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void loongarch_pch_pic_reset(DeviceState *d)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(d);
    int i;

    s->int_mask = -1;
    s->htmsi_en = 0x0;
    s->intedge  = 0x0;
    s->intclr   = 0x0;
    s->auto_crtl0 = 0x0;
    s->auto_crtl1 = 0x0;
    for (i = 0; i < 64; i++) {
        s->route_entry[i] = 0x1;
        s->htmsi_vector[i] = 0x0;
    }
    s->intirr = 0x0;
    s->intisr = 0x0;
    s->last_intirr = 0x0;
    s->int_polarity = 0x0;
}

static void loongarch_pch_pic_realize(DeviceState *dev, Error **errp)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(dev);

    if (!s->irq_num || s->irq_num  > VIRT_PCH_PIC_IRQ_NUM) {
        error_setg(errp, "Invalid 'pic_irq_num'");
        return;
    }

    qdev_init_gpio_out(dev, s->parent_irq, s->irq_num);
    qdev_init_gpio_in(dev, pch_pic_irq_handler, s->irq_num);
}

static void loongarch_pch_pic_init(Object *obj)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    memory_region_init_io(&s->iomem32_low, obj,
                          &loongarch_pch_pic_reg32_low_ops,
                          s, PCH_PIC_NAME(.reg32_part1), 0x100);
    memory_region_init_io(&s->iomem8, obj, &loongarch_pch_pic_reg8_ops,
                          s, PCH_PIC_NAME(.reg8), 0x2a0);
    memory_region_init_io(&s->iomem32_high, obj,
                          &loongarch_pch_pic_reg32_high_ops,
                          s, PCH_PIC_NAME(.reg32_part2), 0xc60);
    sysbus_init_mmio(sbd, &s->iomem32_low);
    sysbus_init_mmio(sbd, &s->iomem8);
    sysbus_init_mmio(sbd, &s->iomem32_high);

}

static Property loongarch_pch_pic_properties[] = {
    DEFINE_PROP_UINT32("pch_pic_irq_num",  LoongArchPCHPIC, irq_num, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static const VMStateDescription vmstate_loongarch_pch_pic = {
    .name = TYPE_LOONGARCH_PCH_PIC,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT64(int_mask, LoongArchPCHPIC),
        VMSTATE_UINT64(htmsi_en, LoongArchPCHPIC),
        VMSTATE_UINT64(intedge, LoongArchPCHPIC),
        VMSTATE_UINT64(intclr, LoongArchPCHPIC),
        VMSTATE_UINT64(auto_crtl0, LoongArchPCHPIC),
        VMSTATE_UINT64(auto_crtl1, LoongArchPCHPIC),
        VMSTATE_UINT8_ARRAY(route_entry, LoongArchPCHPIC, 64),
        VMSTATE_UINT8_ARRAY(htmsi_vector, LoongArchPCHPIC, 64),
        VMSTATE_UINT64(last_intirr, LoongArchPCHPIC),
        VMSTATE_UINT64(intirr, LoongArchPCHPIC),
        VMSTATE_UINT64(intisr, LoongArchPCHPIC),
        VMSTATE_UINT64(int_polarity, LoongArchPCHPIC),
        VMSTATE_END_OF_LIST()
    }
};

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

    dc->realize = loongarch_pch_pic_realize;
    dc->reset = loongarch_pch_pic_reset;
    dc->vmsd = &vmstate_loongarch_pch_pic;
    device_class_set_props(dc, loongarch_pch_pic_properties);
}

static const TypeInfo loongarch_pch_pic_info = {
    .name          = TYPE_LOONGARCH_PCH_PIC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(LoongArchPCHPIC),
    .instance_init = loongarch_pch_pic_init,
    .class_init    = loongarch_pch_pic_class_init,
};

static void loongarch_pch_pic_register_types(void)
{
    type_register_static(&loongarch_pch_pic_info);
}

type_init(loongarch_pch_pic_register_types)
