/*
 * QEMU model of the Xilinx XRAM Controller.
 *
 * Copyright (c) 2021 Xilinx Inc.
 * SPDX-License-Identifier: GPL-2.0-or-later
 * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "migration/vmstate.h"
#include "hw/sysbus.h"
#include "hw/register.h"
#include "hw/qdev-properties.h"
#include "hw/irq.h"
#include "hw/misc/xlnx-versal-xramc.h"

#ifndef XLNX_XRAM_CTRL_ERR_DEBUG
#define XLNX_XRAM_CTRL_ERR_DEBUG 0
#endif

static void xram_update_irq(XlnxXramCtrl *s)
{
    bool pending = s->regs[R_XRAM_ISR] & ~s->regs[R_XRAM_IMR];
    qemu_set_irq(s->irq, pending);
}

static void xram_isr_postw(RegisterInfo *reg, uint64_t val64)
{
    XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
    xram_update_irq(s);
}

static uint64_t xram_ien_prew(RegisterInfo *reg, uint64_t val64)
{
    XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
    uint32_t val = val64;

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

static uint64_t xram_ids_prew(RegisterInfo *reg, uint64_t val64)
{
    XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
    uint32_t val = val64;

    s->regs[R_XRAM_IMR] |= val;
    xram_update_irq(s);
    return 0;
}

static const RegisterAccessInfo xram_ctrl_regs_info[] = {
    {   .name = "XRAM_ERR_CTRL",  .addr = A_XRAM_ERR_CTRL,
        .reset = 0xf,
        .rsvd = 0xfffffff0,
    },{ .name = "XRAM_ISR",  .addr = A_XRAM_ISR,
        .rsvd = 0xfffff800,
        .w1c = 0x7ff,
        .post_write = xram_isr_postw,
    },{ .name = "XRAM_IMR",  .addr = A_XRAM_IMR,
        .reset = 0x7ff,
        .rsvd = 0xfffff800,
        .ro = 0x7ff,
    },{ .name = "XRAM_IEN",  .addr = A_XRAM_IEN,
        .rsvd = 0xfffff800,
        .pre_write = xram_ien_prew,
    },{ .name = "XRAM_IDS",  .addr = A_XRAM_IDS,
        .rsvd = 0xfffff800,
        .pre_write = xram_ids_prew,
    },{ .name = "XRAM_ECC_CNTL",  .addr = A_XRAM_ECC_CNTL,
        .rsvd = 0xfffffff8,
    },{ .name = "XRAM_CLR_EXE",  .addr = A_XRAM_CLR_EXE,
        .rsvd = 0xffffff00,
    },{ .name = "XRAM_CE_FFA",  .addr = A_XRAM_CE_FFA,
        .rsvd = 0xfff00000,
        .ro = 0xfffff,
    },{ .name = "XRAM_CE_FFD0",  .addr = A_XRAM_CE_FFD0,
        .ro = 0xffffffff,
    },{ .name = "XRAM_CE_FFD1",  .addr = A_XRAM_CE_FFD1,
        .ro = 0xffffffff,
    },{ .name = "XRAM_CE_FFD2",  .addr = A_XRAM_CE_FFD2,
        .ro = 0xffffffff,
    },{ .name = "XRAM_CE_FFD3",  .addr = A_XRAM_CE_FFD3,
        .ro = 0xffffffff,
    },{ .name = "XRAM_CE_FFE",  .addr = A_XRAM_CE_FFE,
        .rsvd = 0xffff0000,
        .ro = 0xffff,
    },{ .name = "XRAM_UE_FFA",  .addr = A_XRAM_UE_FFA,
        .rsvd = 0xfff00000,
        .ro = 0xfffff,
    },{ .name = "XRAM_UE_FFD0",  .addr = A_XRAM_UE_FFD0,
        .ro = 0xffffffff,
    },{ .name = "XRAM_UE_FFD1",  .addr = A_XRAM_UE_FFD1,
        .ro = 0xffffffff,
    },{ .name = "XRAM_UE_FFD2",  .addr = A_XRAM_UE_FFD2,
        .ro = 0xffffffff,
    },{ .name = "XRAM_UE_FFD3",  .addr = A_XRAM_UE_FFD3,
        .ro = 0xffffffff,
    },{ .name = "XRAM_UE_FFE",  .addr = A_XRAM_UE_FFE,
        .rsvd = 0xffff0000,
        .ro = 0xffff,
    },{ .name = "XRAM_FI_D0",  .addr = A_XRAM_FI_D0,
    },{ .name = "XRAM_FI_D1",  .addr = A_XRAM_FI_D1,
    },{ .name = "XRAM_FI_D2",  .addr = A_XRAM_FI_D2,
    },{ .name = "XRAM_FI_D3",  .addr = A_XRAM_FI_D3,
    },{ .name = "XRAM_FI_SY",  .addr = A_XRAM_FI_SY,
        .rsvd = 0xffff0000,
    },{ .name = "XRAM_RMW_UE_FFA",  .addr = A_XRAM_RMW_UE_FFA,
        .rsvd = 0xfff00000,
        .ro = 0xfffff,
    },{ .name = "XRAM_FI_CNTR",  .addr = A_XRAM_FI_CNTR,
        .rsvd = 0xff000000,
    },{ .name = "XRAM_IMP",  .addr = A_XRAM_IMP,
        .reset = 0x4,
        .rsvd = 0xfffffff0,
        .ro = 0xf,
    },{ .name = "XRAM_PRDY_DBG",  .addr = A_XRAM_PRDY_DBG,
        .reset = 0xffff,
        .rsvd = 0xffff0000,
        .ro = 0xffff,
    },{ .name = "XRAM_SAFETY_CHK",  .addr = A_XRAM_SAFETY_CHK,
    }
};

static void xram_ctrl_reset_enter(Object *obj, ResetType type)
{
    XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
    unsigned int i;

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

    ARRAY_FIELD_DP32(s->regs, XRAM_IMP, SIZE, s->cfg.encoded_size);
}

static void xram_ctrl_reset_hold(Object *obj)
{
    XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);

    xram_update_irq(s);
}

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

static void xram_ctrl_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    XlnxXramCtrl *s = XLNX_XRAM_CTRL(dev);

    switch (s->cfg.size) {
    case 64 * KiB:
        s->cfg.encoded_size = 0;
        break;
    case 128 * KiB:
        s->cfg.encoded_size = 1;
        break;
    case 256 * KiB:
        s->cfg.encoded_size = 2;
        break;
    case 512 * KiB:
        s->cfg.encoded_size = 3;
        break;
    case 1 * MiB:
        s->cfg.encoded_size = 4;
        break;
    default:
        error_setg(errp, "Unsupported XRAM size %" PRId64, s->cfg.size);
        return;
    }

    memory_region_init_ram(&s->ram, OBJECT(s),
                           object_get_canonical_path_component(OBJECT(s)),
                           s->cfg.size, &error_fatal);
    sysbus_init_mmio(sbd, &s->ram);
}

static void xram_ctrl_init(Object *obj)
{
    XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    s->reg_array =
        register_init_block32(DEVICE(obj), xram_ctrl_regs_info,
                              ARRAY_SIZE(xram_ctrl_regs_info),
                              s->regs_info, s->regs,
                              &xram_ctrl_ops,
                              XLNX_XRAM_CTRL_ERR_DEBUG,
                              XRAM_CTRL_R_MAX * 4);
    sysbus_init_mmio(sbd, &s->reg_array->mem);
    sysbus_init_irq(sbd, &s->irq);
}

static void xram_ctrl_finalize(Object *obj)
{
    XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
    register_finalize_block(s->reg_array);
}

static const VMStateDescription vmstate_xram_ctrl = {
    .name = TYPE_XLNX_XRAM_CTRL,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, XlnxXramCtrl, XRAM_CTRL_R_MAX),
        VMSTATE_END_OF_LIST(),
    }
};

static Property xram_ctrl_properties[] = {
    DEFINE_PROP_UINT64("size", XlnxXramCtrl, cfg.size, 1 * MiB),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->realize = xram_ctrl_realize;
    dc->vmsd = &vmstate_xram_ctrl;
    device_class_set_props(dc, xram_ctrl_properties);

    rc->phases.enter = xram_ctrl_reset_enter;
    rc->phases.hold = xram_ctrl_reset_hold;
}

static const TypeInfo xram_ctrl_info = {
    .name              = TYPE_XLNX_XRAM_CTRL,
    .parent            = TYPE_SYS_BUS_DEVICE,
    .instance_size     = sizeof(XlnxXramCtrl),
    .class_init        = xram_ctrl_class_init,
    .instance_init     = xram_ctrl_init,
    .instance_finalize = xram_ctrl_finalize,
};

static void xram_ctrl_register_types(void)
{
    type_register_static(&xram_ctrl_info);
}

type_init(xram_ctrl_register_types)
