/*
 * QEMU PowerPC PowerNV (POWER9) PHB4 model
 *
 * Copyright (c) 2018-2020, IBM Corporation.
 *
 * 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 "qapi/error.h"
#include "qemu/log.h"
#include "target/ppc/cpu.h"
#include "hw/ppc/fdt.h"
#include "hw/pci-host/pnv_phb4_regs.h"
#include "hw/pci-host/pnv_phb4.h"
#include "hw/ppc/pnv_xscom.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_bus.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_chip.h"
#include "hw/qdev-properties.h"
#include "system/system.h"

#include <libfdt.h>

#define phb_pec_error(pec, fmt, ...)                                    \
    qemu_log_mask(LOG_GUEST_ERROR, "phb4_pec[%d:%d]: " fmt "\n",        \
                  (pec)->chip_id, (pec)->index, ## __VA_ARGS__)


static uint64_t pnv_pec_nest_xscom_read(void *opaque, hwaddr addr,
                                        unsigned size)
{
    PnvPhb4PecState *pec = PNV_PHB4_PEC(opaque);
    uint32_t reg = addr >> 3;

    /* All registers are readable */
    return pec->nest_regs[reg];
}

static void pnv_pec_nest_xscom_write(void *opaque, hwaddr addr,
                                     uint64_t val, unsigned size)
{
    PnvPhb4PecState *pec = PNV_PHB4_PEC(opaque);
    uint32_t reg = addr >> 3;

    switch (reg) {
    case PEC_NEST_DROP_PRIO_CTRL:
        pec->nest_regs[reg] = val & PPC_BITMASK(0, 25);
        break;
    case PEC_NEST_PBCQ_ERR_INJECT:
        pec->nest_regs[reg] = val & PPC_BITMASK(0, 11);
        break;
    case PEC_NEST_PCI_NEST_CLK_TRACE_CTL:
        pec->nest_regs[reg] = val & PPC_BITMASK(0, 16);
        break;
    case PEC_NEST_PBCQ_PMON_CTRL:
        pec->nest_regs[reg] = val & PPC_BITMASK(0, 37);
        break;
    case PEC_NEST_PBCQ_PBUS_ADDR_EXT:
        pec->nest_regs[reg] = val & PPC_BITMASK(0, 6);
        break;
    case PEC_NEST_PBCQ_PRED_VEC_TIMEOUT:
        pec->nest_regs[reg] = val & PPC_BITMASK(0, 15);
        break;
    case PEC_NEST_PBCQ_READ_STK_OVR:
        pec->nest_regs[reg] = val & PPC_BITMASK(0, 48);
        break;
    case PEC_NEST_PBCQ_WRITE_STK_OVR:
    case PEC_NEST_PBCQ_STORE_STK_OVR:
        pec->nest_regs[reg] = val & PPC_BITMASK(0, 24);
        break;
    case PEC_NEST_PBCQ_RETRY_BKOFF_CTRL:
        pec->nest_regs[reg] = val & PPC_BITMASK(0, 41);
        break;
    case PEC_NEST_PBCQ_HW_CONFIG:
    case PEC_NEST_CAPP_CTRL:
        pec->nest_regs[reg] = val;
        break;
    default:
        phb_pec_error(pec, "%s @0x%"HWADDR_PRIx"=%"PRIx64"\n", __func__,
                      addr, val);
    }
}

static const MemoryRegionOps pnv_pec_nest_xscom_ops = {
    .read = pnv_pec_nest_xscom_read,
    .write = pnv_pec_nest_xscom_write,
    .valid.min_access_size = 8,
    .valid.max_access_size = 8,
    .impl.min_access_size = 8,
    .impl.max_access_size = 8,
    .endianness = DEVICE_BIG_ENDIAN,
};

static uint64_t pnv_pec_pci_xscom_read(void *opaque, hwaddr addr,
                                       unsigned size)
{
    PnvPhb4PecState *pec = PNV_PHB4_PEC(opaque);
    uint32_t reg = addr >> 3;

    /* All registers are readable */
    return pec->pci_regs[reg];
}

static void pnv_pec_pci_xscom_write(void *opaque, hwaddr addr,
                                    uint64_t val, unsigned size)
{
    PnvPhb4PecState *pec = PNV_PHB4_PEC(opaque);
    uint32_t reg = addr >> 3;

    switch (reg) {
    case PEC_PCI_PBAIB_HW_CONFIG:
        pec->pci_regs[reg] = val & PPC_BITMASK(0, 42);
        break;
    case PEC_PCI_PBAIB_HW_OVR:
        pec->pci_regs[reg] = val & PPC_BITMASK(0, 15);
        break;
    case PEC_PCI_PBAIB_READ_STK_OVR:
        pec->pci_regs[reg] = val & PPC_BITMASK(0, 48);
        break;
    default:
        phb_pec_error(pec, "%s @0x%"HWADDR_PRIx"=%"PRIx64"\n", __func__,
                      addr, val);
    }
}

static const MemoryRegionOps pnv_pec_pci_xscom_ops = {
    .read = pnv_pec_pci_xscom_read,
    .write = pnv_pec_pci_xscom_write,
    .valid.min_access_size = 8,
    .valid.max_access_size = 8,
    .impl.min_access_size = 8,
    .impl.max_access_size = 8,
    .endianness = DEVICE_BIG_ENDIAN,
};

PnvPhb4PecState *pnv_pec_add_phb(PnvChip *chip, PnvPHB *phb, Error **errp)
{
    PnvPhb4PecState *pecs = NULL;
    int chip_id = phb->chip_id;
    int index = phb->phb_id;
    int i, j;

    if (phb->version == 4) {
        Pnv9Chip *chip9 = PNV9_CHIP(chip);

        pecs = chip9->pecs;
    } else if (phb->version == 5) {
        Pnv10Chip *chip10 = PNV10_CHIP(chip);

        pecs = chip10->pecs;
    } else {
        g_assert_not_reached();
    }

    for (i = 0; i < chip->num_pecs; i++) {
        /*
         * For each PEC, check the amount of phbs it supports
         * and see if the given phb4 index matches an index.
         */
        PnvPhb4PecState *pec = &pecs[i];

        for (j = 0; j < pec->num_phbs; j++) {
            if (index == pnv_phb4_pec_get_phb_id(pec, j)) {
                pec->phbs[j] = phb;
                phb->pec = pec;
                return pec;
            }
        }
    }
    error_setg(errp,
               "pnv-phb4 chip-id %d index %d didn't match any existing PEC",
               chip_id, index);

    return NULL;
}

static PnvPHB *pnv_pec_default_phb_realize(PnvPhb4PecState *pec,
                                           int stack_no,
                                           Error **errp)
{
    PnvPHB *phb = PNV_PHB(qdev_new(TYPE_PNV_PHB));
    int phb_id = pnv_phb4_pec_get_phb_id(pec, stack_no);

    object_property_add_child(OBJECT(pec), "phb[*]", OBJECT(phb));
    object_property_set_link(OBJECT(phb), "pec", OBJECT(pec),
                             &error_abort);
    object_property_set_int(OBJECT(phb), "chip-id", pec->chip_id,
                            &error_fatal);
    object_property_set_int(OBJECT(phb), "index", phb_id,
                            &error_fatal);

    if (!sysbus_realize(SYS_BUS_DEVICE(phb), errp)) {
        return NULL;
    }
    return phb;
}

#define   XPEC_P9_PCI_LANE_CFG                  PPC_BITMASK(10, 11)
#define   XPEC_P10_PCI_LANE_CFG                 PPC_BITMASK(0, 1)

static void pnv_pec_realize(DeviceState *dev, Error **errp)
{
    PnvPhb4PecState *pec = PNV_PHB4_PEC(dev);
    PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec);
    char name[64];
    int i;

    if (pec->index >= PNV_CHIP_GET_CLASS(pec->chip)->num_pecs) {
        error_setg(errp, "invalid PEC index: %d", pec->index);
        return;
    }

    pec->num_phbs = pecc->num_phbs[pec->index];

    /* Pervasive chiplet */
    object_initialize_child(OBJECT(pec), "nest-pervasive-common",
                            &pec->nest_pervasive,
                            TYPE_PNV_NEST_CHIPLET_PERVASIVE);
    if (!qdev_realize(DEVICE(&pec->nest_pervasive), NULL, errp)) {
        return;
    }

    /* Set up pervasive chiplet registers */
    /*
     * Most registers are not set up, this just sets the PCI CONF1 link-width
     * field because skiboot probes it.
     */
    if (pecc->version == PNV_PHB4_VERSION) {
        /*
         * On P9, PEC2 has configurable 1/2/3-furcation).
         * Make it trifurcated (x8, x4, x4) to match pnv_pec_num_phbs.
         */
        if (pec->index == 2) {
            pec->nest_pervasive.control_regs.cplt_cfg1 =
                    SETFIELD(XPEC_P9_PCI_LANE_CFG,
                             pec->nest_pervasive.control_regs.cplt_cfg1,
                             0b10);
        }
    } else if (pecc->version == PNV_PHB5_VERSION) {
        /*
         * On P10, both PECs are configurable 1/2/3-furcation).
         * Both are trifurcated to match pnv_phb5_pec_num_stacks.
         */
        pec->nest_pervasive.control_regs.cplt_cfg1 =
                SETFIELD(XPEC_P10_PCI_LANE_CFG,
                         pec->nest_pervasive.control_regs.cplt_cfg1,
                         0b10);
    } else {
        g_assert_not_reached();
    }

    /* Create PHBs if running with defaults */
    if (defaults_enabled()) {
        g_assert(pec->num_phbs <= MAX_PHBS_PER_PEC);
        for (i = 0; i < pec->num_phbs; i++) {
            pec->phbs[i] = pnv_pec_default_phb_realize(pec, i, errp);
        }
    }

    /* Initialize the XSCOM regions for the PEC registers */
    snprintf(name, sizeof(name), "xscom-pec-%d.%d-nest", pec->chip_id,
             pec->index);
    pnv_xscom_region_init(&pec->nest_regs_mr, OBJECT(dev),
                          &pnv_pec_nest_xscom_ops, pec, name,
                          PHB4_PEC_NEST_REGS_COUNT);

    snprintf(name, sizeof(name), "xscom-pec-%d.%d-pci", pec->chip_id,
             pec->index);
    pnv_xscom_region_init(&pec->pci_regs_mr, OBJECT(dev),
                          &pnv_pec_pci_xscom_ops, pec, name,
                          PHB4_PEC_PCI_REGS_COUNT);
}

static int pnv_pec_dt_xscom(PnvXScomInterface *dev, void *fdt,
                            int xscom_offset)
{
    PnvPhb4PecState *pec = PNV_PHB4_PEC(dev);
    PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(dev);
    uint32_t nbase = pecc->xscom_nest_base(pec);
    uint32_t pbase = pecc->xscom_pci_base(pec);
    int offset, i;
    char *name;
    uint32_t reg[] = {
        cpu_to_be32(nbase),
        cpu_to_be32(pecc->xscom_nest_size),
        cpu_to_be32(pbase),
        cpu_to_be32(pecc->xscom_pci_size),
    };

    name = g_strdup_printf("pbcq@%x", nbase);
    offset = fdt_add_subnode(fdt, xscom_offset, name);
    _FDT(offset);
    g_free(name);

    _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));

    _FDT((fdt_setprop_cell(fdt, offset, "ibm,pec-index", pec->index)));
    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 1)));
    _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0)));
    _FDT((fdt_setprop(fdt, offset, "compatible", pecc->compat,
                      pecc->compat_size)));

    for (i = 0; i < pec->num_phbs; i++) {
        int stk_offset;

        if (!pec->phbs[i]) {
            continue;
        }

        name = g_strdup_printf("stack@%x", i);
        stk_offset = fdt_add_subnode(fdt, offset, name);
        _FDT(stk_offset);
        g_free(name);
        _FDT((fdt_setprop(fdt, stk_offset, "compatible", pecc->stk_compat,
                          pecc->stk_compat_size)));
        _FDT((fdt_setprop_cell(fdt, stk_offset, "reg", i)));
        _FDT((fdt_setprop_cell(fdt, stk_offset, "ibm,phb-index",
                               pec->phbs[i]->phb_id)));
    }

    return 0;
}

static const Property pnv_pec_properties[] = {
    DEFINE_PROP_UINT32("index", PnvPhb4PecState, index, 0),
    DEFINE_PROP_UINT32("chip-id", PnvPhb4PecState, chip_id, 0),
    DEFINE_PROP_LINK("chip", PnvPhb4PecState, chip, TYPE_PNV_CHIP,
                     PnvChip *),
};

#define XPEC_PCI_CPLT_OFFSET                        0x1000000ULL

static uint32_t pnv_pec_xscom_cplt_base(PnvPhb4PecState *pec)
{
    return PNV9_XSCOM_PEC_NEST_CPLT_BASE + XPEC_PCI_CPLT_OFFSET * pec->index;
}

static uint32_t pnv_pec_xscom_pci_base(PnvPhb4PecState *pec)
{
    return PNV9_XSCOM_PEC_PCI_BASE + XPEC_PCI_CPLT_OFFSET * pec->index;
}

static uint32_t pnv_pec_xscom_nest_base(PnvPhb4PecState *pec)
{
    return PNV9_XSCOM_PEC_NEST_BASE + 0x400 * pec->index;
}

/*
 * PEC0 -> 1 phb
 * PEC1 -> 2 phb
 * PEC2 -> 3 phbs
 */
static const uint32_t pnv_pec_num_phbs[] = { 1, 2, 3 };

static void pnv_pec_class_init(ObjectClass *klass, const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
    PnvPhb4PecClass *pecc = PNV_PHB4_PEC_CLASS(klass);
    static const char compat[] = "ibm,power9-pbcq";
    static const char stk_compat[] = "ibm,power9-phb-stack";

    xdc->dt_xscom = pnv_pec_dt_xscom;

    dc->realize = pnv_pec_realize;
    device_class_set_props(dc, pnv_pec_properties);
    dc->user_creatable = false;

    pecc->xscom_cplt_base = pnv_pec_xscom_cplt_base;
    pecc->xscom_nest_base = pnv_pec_xscom_nest_base;
    pecc->xscom_pci_base  = pnv_pec_xscom_pci_base;
    pecc->xscom_nest_size = PNV9_XSCOM_PEC_NEST_SIZE;
    pecc->xscom_pci_size  = PNV9_XSCOM_PEC_PCI_SIZE;
    pecc->compat = compat;
    pecc->compat_size = sizeof(compat);
    pecc->stk_compat = stk_compat;
    pecc->stk_compat_size = sizeof(stk_compat);
    pecc->version = PNV_PHB4_VERSION;
    pecc->phb_type = TYPE_PNV_PHB4;
    pecc->num_phbs = pnv_pec_num_phbs;
}

static const TypeInfo pnv_pec_type_info = {
    .name          = TYPE_PNV_PHB4_PEC,
    .parent        = TYPE_DEVICE,
    .instance_size = sizeof(PnvPhb4PecState),
    .class_init    = pnv_pec_class_init,
    .class_size    = sizeof(PnvPhb4PecClass),
    .interfaces    = (const InterfaceInfo[]) {
        { TYPE_PNV_XSCOM_INTERFACE },
        { }
    }
};

/*
 * POWER10 definitions
 */
static uint32_t pnv_phb5_pec_xscom_cplt_base(PnvPhb4PecState *pec)
{
    return PNV10_XSCOM_PEC_NEST_CPLT_BASE + XPEC_PCI_CPLT_OFFSET * pec->index;
}

static uint32_t pnv_phb5_pec_xscom_pci_base(PnvPhb4PecState *pec)
{
    return PNV10_XSCOM_PEC_PCI_BASE + 0x1000000 * pec->index;
}

static uint32_t pnv_phb5_pec_xscom_nest_base(PnvPhb4PecState *pec)
{
    /* index goes down ... */
    return PNV10_XSCOM_PEC_NEST_BASE - 0x1000000 * pec->index;
}

/*
 * PEC0 -> 3 stacks
 * PEC1 -> 3 stacks
 */
static const uint32_t pnv_phb5_pec_num_stacks[] = { 3, 3 };

static void pnv_phb5_pec_class_init(ObjectClass *klass, const void *data)
{
    PnvPhb4PecClass *pecc = PNV_PHB4_PEC_CLASS(klass);
    static const char compat[] = "ibm,power10-pbcq";
    static const char stk_compat[] = "ibm,power10-phb-stack";

    pecc->xscom_cplt_base = pnv_phb5_pec_xscom_cplt_base;
    pecc->xscom_nest_base = pnv_phb5_pec_xscom_nest_base;
    pecc->xscom_pci_base  = pnv_phb5_pec_xscom_pci_base;
    pecc->xscom_nest_size = PNV10_XSCOM_PEC_NEST_SIZE;
    pecc->xscom_pci_size  = PNV10_XSCOM_PEC_PCI_SIZE;
    pecc->compat = compat;
    pecc->compat_size = sizeof(compat);
    pecc->stk_compat = stk_compat;
    pecc->stk_compat_size = sizeof(stk_compat);
    pecc->version = PNV_PHB5_VERSION;
    pecc->phb_type = TYPE_PNV_PHB5;
    pecc->num_phbs = pnv_phb5_pec_num_stacks;
}

static const TypeInfo pnv_phb5_pec_type_info = {
    .name          = TYPE_PNV_PHB5_PEC,
    .parent        = TYPE_PNV_PHB4_PEC,
    .instance_size = sizeof(PnvPhb4PecState),
    .class_init    = pnv_phb5_pec_class_init,
    .class_size    = sizeof(PnvPhb4PecClass),
    .interfaces    = (const InterfaceInfo[]) {
        { TYPE_PNV_XSCOM_INTERFACE },
        { }
    }
};

static void pnv_pec_register_types(void)
{
    type_register_static(&pnv_pec_type_info);
    type_register_static(&pnv_phb5_pec_type_info);
}

type_init(pnv_pec_register_types);
