/*
 * Xilinx PCIe host controller emulation.
 *
 * Copyright (c) 2016 Imagination Technologies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci-host/xilinx-pcie.h"

enum root_cfg_reg {
    /* Interrupt Decode Register */
    ROOTCFG_INTDEC              = 0x138,

    /* Interrupt Mask Register */
    ROOTCFG_INTMASK             = 0x13c,
    /* INTx Interrupt Received */
#define ROOTCFG_INTMASK_INTX    (1 << 16)
    /* MSI Interrupt Received */
#define ROOTCFG_INTMASK_MSI     (1 << 17)

    /* PHY Status/Control Register */
    ROOTCFG_PSCR                = 0x144,
    /* Link Up */
#define ROOTCFG_PSCR_LINK_UP    (1 << 11)

    /* Root Port Status/Control Register */
    ROOTCFG_RPSCR               = 0x148,
    /* Bridge Enable */
#define ROOTCFG_RPSCR_BRIDGEEN  (1 << 0)
    /* Interrupt FIFO Not Empty */
#define ROOTCFG_RPSCR_INTNEMPTY (1 << 18)
    /* Interrupt FIFO Overflow */
#define ROOTCFG_RPSCR_INTOVF    (1 << 19)

    /* Root Port Interrupt FIFO Read Register 1 */
    ROOTCFG_RPIFR1              = 0x158,
#define ROOTCFG_RPIFR1_INT_LANE_SHIFT   27
#define ROOTCFG_RPIFR1_INT_ASSERT_SHIFT 29
#define ROOTCFG_RPIFR1_INT_VALID_SHIFT  31
    /* Root Port Interrupt FIFO Read Register 2 */
    ROOTCFG_RPIFR2              = 0x15c,
};

static void xilinx_pcie_update_intr(XilinxPCIEHost *s,
                                    uint32_t set, uint32_t clear)
{
    int level;

    s->intr |= set;
    s->intr &= ~clear;

    if (s->intr_fifo_r != s->intr_fifo_w) {
        s->intr |= ROOTCFG_INTMASK_INTX;
    }

    level = !!(s->intr & s->intr_mask);
    qemu_set_irq(s->irq, level);
}

static void xilinx_pcie_queue_intr(XilinxPCIEHost *s,
                                   uint32_t fifo_reg1, uint32_t fifo_reg2)
{
    XilinxPCIEInt *intr;
    unsigned int new_w;

    new_w = (s->intr_fifo_w + 1) % ARRAY_SIZE(s->intr_fifo);
    if (new_w == s->intr_fifo_r) {
        s->rpscr |= ROOTCFG_RPSCR_INTOVF;
        return;
    }

    intr = &s->intr_fifo[s->intr_fifo_w];
    s->intr_fifo_w = new_w;

    intr->fifo_reg1 = fifo_reg1;
    intr->fifo_reg2 = fifo_reg2;

    xilinx_pcie_update_intr(s, ROOTCFG_INTMASK_INTX, 0);
}

static void xilinx_pcie_set_irq(void *opaque, int irq_num, int level)
{
    XilinxPCIEHost *s = XILINX_PCIE_HOST(opaque);

    xilinx_pcie_queue_intr(s,
       (irq_num << ROOTCFG_RPIFR1_INT_LANE_SHIFT) |
           (level << ROOTCFG_RPIFR1_INT_ASSERT_SHIFT) |
           (1 << ROOTCFG_RPIFR1_INT_VALID_SHIFT),
       0);
}

static void xilinx_pcie_host_realize(DeviceState *dev, Error **errp)
{
    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
    XilinxPCIEHost *s = XILINX_PCIE_HOST(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev);

    snprintf(s->name, sizeof(s->name), "pcie%u", s->bus_nr);

    /* PCI configuration space */
    pcie_host_mmcfg_init(pex, s->cfg_size);

    /* MMIO region */
    memory_region_init(&s->mmio, OBJECT(s), "mmio", UINT64_MAX);
    memory_region_set_enabled(&s->mmio, false);

    /* dummy PCI I/O region (not visible to the CPU) */
    memory_region_init(&s->io, OBJECT(s), "io", 16);

    /* interrupt out */
    qdev_init_gpio_out_named(dev, &s->irq, "interrupt_out", 1);

    sysbus_init_mmio(sbd, &pex->mmio);
    sysbus_init_mmio(sbd, &s->mmio);

    pci->bus = pci_register_root_bus(dev, s->name, xilinx_pcie_set_irq,
                                     pci_swizzle_map_irq_fn, s, &s->mmio,
                                     &s->io, 0, 4, TYPE_PCIE_BUS);

    qdev_set_parent_bus(DEVICE(&s->root), BUS(pci->bus));
    qdev_init_nofail(DEVICE(&s->root));
}

static const char *xilinx_pcie_host_root_bus_path(PCIHostState *host_bridge,
                                                  PCIBus *rootbus)
{
    return "0000:00";
}

static void xilinx_pcie_host_init(Object *obj)
{
    XilinxPCIEHost *s = XILINX_PCIE_HOST(obj);
    XilinxPCIERoot *root = &s->root;

    object_initialize(root, sizeof(*root), TYPE_XILINX_PCIE_ROOT);
    object_property_add_child(obj, "root", OBJECT(root), NULL);
    qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
    qdev_prop_set_bit(DEVICE(root), "multifunction", false);
}

static Property xilinx_pcie_host_props[] = {
    DEFINE_PROP_UINT32("bus_nr", XilinxPCIEHost, bus_nr, 0),
    DEFINE_PROP_SIZE("cfg_base", XilinxPCIEHost, cfg_base, 0),
    DEFINE_PROP_SIZE("cfg_size", XilinxPCIEHost, cfg_size, 32 * MiB),
    DEFINE_PROP_SIZE("mmio_base", XilinxPCIEHost, mmio_base, 0),
    DEFINE_PROP_SIZE("mmio_size", XilinxPCIEHost, mmio_size, 1 * MiB),
    DEFINE_PROP_BOOL("link_up", XilinxPCIEHost, link_up, true),
    DEFINE_PROP_END_OF_LIST(),
};

static void xilinx_pcie_host_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);

    hc->root_bus_path = xilinx_pcie_host_root_bus_path;
    dc->realize = xilinx_pcie_host_realize;
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    dc->fw_name = "pci";
    dc->props = xilinx_pcie_host_props;
}

static const TypeInfo xilinx_pcie_host_info = {
    .name       = TYPE_XILINX_PCIE_HOST,
    .parent     = TYPE_PCIE_HOST_BRIDGE,
    .instance_size = sizeof(XilinxPCIEHost),
    .instance_init = xilinx_pcie_host_init,
    .class_init = xilinx_pcie_host_class_init,
};

static uint32_t xilinx_pcie_root_config_read(PCIDevice *d,
                                             uint32_t address, int len)
{
    XilinxPCIEHost *s = XILINX_PCIE_HOST(OBJECT(d)->parent);
    uint32_t val;

    switch (address) {
    case ROOTCFG_INTDEC:
        val = s->intr;
        break;
    case ROOTCFG_INTMASK:
        val = s->intr_mask;
        break;
    case ROOTCFG_PSCR:
        val = s->link_up ? ROOTCFG_PSCR_LINK_UP : 0;
        break;
    case ROOTCFG_RPSCR:
        if (s->intr_fifo_r != s->intr_fifo_w) {
            s->rpscr &= ~ROOTCFG_RPSCR_INTNEMPTY;
        } else {
            s->rpscr |= ROOTCFG_RPSCR_INTNEMPTY;
        }
        val = s->rpscr;
        break;
    case ROOTCFG_RPIFR1:
        if (s->intr_fifo_w == s->intr_fifo_r) {
            /* FIFO empty */
            val = 0;
        } else {
            val = s->intr_fifo[s->intr_fifo_r].fifo_reg1;
        }
        break;
    case ROOTCFG_RPIFR2:
        if (s->intr_fifo_w == s->intr_fifo_r) {
            /* FIFO empty */
            val = 0;
        } else {
            val = s->intr_fifo[s->intr_fifo_r].fifo_reg2;
        }
        break;
    default:
        val = pci_default_read_config(d, address, len);
        break;
    }
    return val;
}

static void xilinx_pcie_root_config_write(PCIDevice *d, uint32_t address,
                                          uint32_t val, int len)
{
    XilinxPCIEHost *s = XILINX_PCIE_HOST(OBJECT(d)->parent);
    switch (address) {
    case ROOTCFG_INTDEC:
        xilinx_pcie_update_intr(s, 0, val);
        break;
    case ROOTCFG_INTMASK:
        s->intr_mask = val;
        xilinx_pcie_update_intr(s, 0, 0);
        break;
    case ROOTCFG_RPSCR:
        s->rpscr &= ~ROOTCFG_RPSCR_BRIDGEEN;
        s->rpscr |= val & ROOTCFG_RPSCR_BRIDGEEN;
        memory_region_set_enabled(&s->mmio, val & ROOTCFG_RPSCR_BRIDGEEN);

        if (val & ROOTCFG_INTMASK_INTX) {
            s->rpscr &= ~ROOTCFG_INTMASK_INTX;
        }
        break;
    case ROOTCFG_RPIFR1:
    case ROOTCFG_RPIFR2:
        if (s->intr_fifo_w == s->intr_fifo_r) {
            /* FIFO empty */
            return;
        } else {
            s->intr_fifo_r = (s->intr_fifo_r + 1) % ARRAY_SIZE(s->intr_fifo);
        }
        break;
    default:
        pci_default_write_config(d, address, val, len);
        break;
    }
}

static void xilinx_pcie_root_realize(PCIDevice *pci_dev, Error **errp)
{
    BusState *bus = qdev_get_parent_bus(DEVICE(pci_dev));
    XilinxPCIEHost *s = XILINX_PCIE_HOST(bus->parent);

    pci_set_word(pci_dev->config + PCI_COMMAND,
                 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
    pci_set_word(pci_dev->config + PCI_MEMORY_BASE, s->mmio_base >> 16);
    pci_set_word(pci_dev->config + PCI_MEMORY_LIMIT,
                 ((s->mmio_base + s->mmio_size - 1) >> 16) & 0xfff0);

    pci_bridge_initfn(pci_dev, TYPE_PCI_BUS);

    if (pcie_endpoint_cap_v1_init(pci_dev, 0x80) < 0) {
        error_setg(errp, "Failed to initialize PCIe capability");
    }
}

static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
{
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    dc->desc = "Xilinx AXI-PCIe Host Bridge";
    k->vendor_id = PCI_VENDOR_ID_XILINX;
    k->device_id = 0x7021;
    k->revision = 0;
    k->class_id = PCI_CLASS_BRIDGE_HOST;
    k->is_bridge = true;
    k->realize = xilinx_pcie_root_realize;
    k->exit = pci_bridge_exitfn;
    dc->reset = pci_bridge_reset;
    k->config_read = xilinx_pcie_root_config_read;
    k->config_write = xilinx_pcie_root_config_write;
    /*
     * PCI-facing part of the host bridge, not usable without the
     * host-facing part, which can't be device_add'ed, yet.
     */
    dc->user_creatable = false;
}

static const TypeInfo xilinx_pcie_root_info = {
    .name = TYPE_XILINX_PCIE_ROOT,
    .parent = TYPE_PCI_BRIDGE,
    .instance_size = sizeof(XilinxPCIERoot),
    .class_init = xilinx_pcie_root_class_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_PCIE_DEVICE },
        { }
    },
};

static void xilinx_pcie_register(void)
{
    type_register_static(&xilinx_pcie_root_info);
    type_register_static(&xilinx_pcie_host_info);
}

type_init(xilinx_pcie_register)
