/*
 * 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 "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 I/O region */
    memory_region_init_ram_nomigrate(&s->io, OBJECT(s), "io", 16, NULL);
    memory_region_set_enabled(&s->io, false);

    /* 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 << 20),
    DEFINE_PROP_SIZE("mmio_base", XilinxPCIEHost, mmio_base, 0),
    DEFINE_PROP_SIZE("mmio_size", XilinxPCIEHost, mmio_size, 1 << 20),
    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)
