/*
 * QEMU model of the VersalUsb2CtrlRegs Register control/Status block for
 * USB2.0 controller
 *
 * This module should control phy_reset, permanent device plugs, frame length
 * time adjust & setting of coherency paths. None of which are emulated in
 * present model.
 *
 * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal <fnu.vikram@xilinx.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "hw/register.h"
#include "qemu/bitops.h"
#include "qom/object.h"
#include "migration/vmstate.h"
#include "hw/usb/xlnx-versal-usb2-ctrl-regs.h"

#ifndef XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG
#define XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG 0
#endif

REG32(BUS_FILTER, 0x30)
    FIELD(BUS_FILTER, BYPASS, 0, 4)
REG32(PORT, 0x34)
    FIELD(PORT, HOST_SMI_BAR_WR, 4, 1)
    FIELD(PORT, HOST_SMI_PCI_CMD_REG_WR, 3, 1)
    FIELD(PORT, HOST_MSI_ENABLE, 2, 1)
    FIELD(PORT, PWR_CTRL_PRSNT, 1, 1)
    FIELD(PORT, HUB_PERM_ATTACH, 0, 1)
REG32(JITTER_ADJUST, 0x38)
    FIELD(JITTER_ADJUST, FLADJ, 0, 6)
REG32(BIGENDIAN, 0x40)
    FIELD(BIGENDIAN, ENDIAN_GS, 0, 1)
REG32(COHERENCY, 0x44)
    FIELD(COHERENCY, USB_COHERENCY, 0, 1)
REG32(XHC_BME, 0x48)
    FIELD(XHC_BME, XHC_BME, 0, 1)
REG32(REG_CTRL, 0x60)
    FIELD(REG_CTRL, SLVERR_ENABLE, 0, 1)
REG32(IR_STATUS, 0x64)
    FIELD(IR_STATUS, HOST_SYS_ERR, 1, 1)
    FIELD(IR_STATUS, ADDR_DEC_ERR, 0, 1)
REG32(IR_MASK, 0x68)
    FIELD(IR_MASK, HOST_SYS_ERR, 1, 1)
    FIELD(IR_MASK, ADDR_DEC_ERR, 0, 1)
REG32(IR_ENABLE, 0x6c)
    FIELD(IR_ENABLE, HOST_SYS_ERR, 1, 1)
    FIELD(IR_ENABLE, ADDR_DEC_ERR, 0, 1)
REG32(IR_DISABLE, 0x70)
    FIELD(IR_DISABLE, HOST_SYS_ERR, 1, 1)
    FIELD(IR_DISABLE, ADDR_DEC_ERR, 0, 1)
REG32(USB3, 0x78)

static void ir_update_irq(VersalUsb2CtrlRegs *s)
{
    bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
    qemu_set_irq(s->irq_ir, pending);
}

static void ir_status_postw(RegisterInfo *reg, uint64_t val64)
{
    VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque);
    /*
     * TODO: This should also clear USBSTS.HSE field in USB XHCI register.
     * May be combine both the modules.
     */
    ir_update_irq(s);
}

static uint64_t ir_enable_prew(RegisterInfo *reg, uint64_t val64)
{
    VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque);
    uint32_t val = val64;

    s->regs[R_IR_MASK] &= ~val;
    ir_update_irq(s);
    return 0;
}

static uint64_t ir_disable_prew(RegisterInfo *reg, uint64_t val64)
{
    VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque);
    uint32_t val = val64;

    s->regs[R_IR_MASK] |= val;
    ir_update_irq(s);
    return 0;
}

static const RegisterAccessInfo usb2_ctrl_regs_regs_info[] = {
    {   .name = "BUS_FILTER",  .addr = A_BUS_FILTER,
        .rsvd = 0xfffffff0,
    },{ .name = "PORT",  .addr = A_PORT,
        .rsvd = 0xffffffe0,
    },{ .name = "JITTER_ADJUST",  .addr = A_JITTER_ADJUST,
        .reset = 0x20,
        .rsvd = 0xffffffc0,
    },{ .name = "BIGENDIAN",  .addr = A_BIGENDIAN,
        .rsvd = 0xfffffffe,
    },{ .name = "COHERENCY",  .addr = A_COHERENCY,
        .rsvd = 0xfffffffe,
    },{ .name = "XHC_BME",  .addr = A_XHC_BME,
        .reset = 0x1,
        .rsvd = 0xfffffffe,
    },{ .name = "REG_CTRL",  .addr = A_REG_CTRL,
        .rsvd = 0xfffffffe,
    },{ .name = "IR_STATUS",  .addr = A_IR_STATUS,
        .rsvd = 0xfffffffc,
        .w1c = 0x3,
        .post_write = ir_status_postw,
    },{ .name = "IR_MASK",  .addr = A_IR_MASK,
        .reset = 0x3,
        .rsvd = 0xfffffffc,
        .ro = 0x3,
    },{ .name = "IR_ENABLE",  .addr = A_IR_ENABLE,
        .rsvd = 0xfffffffc,
        .pre_write = ir_enable_prew,
    },{ .name = "IR_DISABLE",  .addr = A_IR_DISABLE,
        .rsvd = 0xfffffffc,
        .pre_write = ir_disable_prew,
    },{ .name = "USB3",  .addr = A_USB3,
    }
};

static void usb2_ctrl_regs_reset_init(Object *obj, ResetType type)
{
    VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj);
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
        register_reset(&s->regs_info[i]);
    }
}

static void usb2_ctrl_regs_reset_hold(Object *obj)
{
    VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj);

    ir_update_irq(s);
}

static const MemoryRegionOps usb2_ctrl_regs_ops = {
    .read = register_read_memory,
    .write = register_write_memory,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void usb2_ctrl_regs_init(Object *obj)
{
    VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    RegisterInfoArray *reg_array;

    memory_region_init(&s->iomem, obj, TYPE_XILINX_VERSAL_USB2_CTRL_REGS,
                       USB2_REGS_R_MAX * 4);
    reg_array =
        register_init_block32(DEVICE(obj), usb2_ctrl_regs_regs_info,
                              ARRAY_SIZE(usb2_ctrl_regs_regs_info),
                              s->regs_info, s->regs,
                              &usb2_ctrl_regs_ops,
                              XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG,
                              USB2_REGS_R_MAX * 4);
    memory_region_add_subregion(&s->iomem,
                                0x0,
                                &reg_array->mem);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->irq_ir);
}

static const VMStateDescription vmstate_usb2_ctrl_regs = {
    .name = TYPE_XILINX_VERSAL_USB2_CTRL_REGS,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, VersalUsb2CtrlRegs, USB2_REGS_R_MAX),
        VMSTATE_END_OF_LIST(),
    }
};

static void usb2_ctrl_regs_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ResettableClass *rc = RESETTABLE_CLASS(klass);

    rc->phases.enter = usb2_ctrl_regs_reset_init;
    rc->phases.hold  = usb2_ctrl_regs_reset_hold;
    dc->vmsd = &vmstate_usb2_ctrl_regs;
}

static const TypeInfo usb2_ctrl_regs_info = {
    .name          = TYPE_XILINX_VERSAL_USB2_CTRL_REGS,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(VersalUsb2CtrlRegs),
    .class_init    = usb2_ctrl_regs_class_init,
    .instance_init = usb2_ctrl_regs_init,
};

static void usb2_ctrl_regs_register_types(void)
{
    type_register_static(&usb2_ctrl_regs_info);
}

type_init(usb2_ctrl_regs_register_types)
