/*
 * ARM MPS2 SCC emulation
 *
 * Copyright (c) 2017 Linaro Limited
 * Written by Peter Maydell
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 or
 *  (at your option) any later version.
 */

/* This is a model of the SCC (Serial Communication Controller)
 * found in the FPGA images of MPS2 development boards.
 *
 * Documentation of it can be found in the MPS2 TRM:
 * https://developer.arm.com/documentation/100112/latest/
 * and also in the Application Notes documenting individual FPGA images.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/bitops.h"
#include "trace.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "hw/registerfields.h"
#include "hw/misc/mps2-scc.h"
#include "hw/misc/led.h"
#include "hw/qdev-properties.h"

REG32(CFG0, 0)
REG32(CFG1, 4)
REG32(CFG2, 8)
REG32(CFG3, 0xc)
REG32(CFG4, 0x10)
REG32(CFG5, 0x14)
REG32(CFG6, 0x18)
REG32(CFGDATA_RTN, 0xa0)
REG32(CFGDATA_OUT, 0xa4)
REG32(CFGCTRL, 0xa8)
    FIELD(CFGCTRL, DEVICE, 0, 12)
    FIELD(CFGCTRL, RES1, 12, 8)
    FIELD(CFGCTRL, FUNCTION, 20, 6)
    FIELD(CFGCTRL, RES2, 26, 4)
    FIELD(CFGCTRL, WRITE, 30, 1)
    FIELD(CFGCTRL, START, 31, 1)
REG32(CFGSTAT, 0xac)
    FIELD(CFGSTAT, DONE, 0, 1)
    FIELD(CFGSTAT, ERROR, 1, 1)
REG32(DLL, 0x100)
REG32(AID, 0xFF8)
REG32(ID, 0xFFC)

static int scc_partno(MPS2SCC *s)
{
    /* Return the partno field of the SCC_ID (0x524, 0x511, etc) */
    return extract32(s->id, 4, 8);
}

/* Handle a write via the SYS_CFG channel to the specified function/device.
 * Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
 */
static bool scc_cfg_write(MPS2SCC *s, unsigned function,
                          unsigned device, uint32_t value)
{
    trace_mps2_scc_cfg_write(function, device, value);

    if (function != 1 || device >= s->num_oscclk) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "MPS2 SCC config write: bad function %d device %d\n",
                      function, device);
        return false;
    }

    s->oscclk[device] = value;
    return true;
}

/* Handle a read via the SYS_CFG channel to the specified function/device.
 * Return false on error (reported to guest via SYS_CFGCTRL ERROR bit),
 * or set *value on success.
 */
static bool scc_cfg_read(MPS2SCC *s, unsigned function,
                         unsigned device, uint32_t *value)
{
    if (function != 1 || device >= s->num_oscclk) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "MPS2 SCC config read: bad function %d device %d\n",
                      function, device);
        return false;
    }

    *value = s->oscclk[device];

    trace_mps2_scc_cfg_read(function, device, *value);
    return true;
}

static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
{
    MPS2SCC *s = MPS2_SCC(opaque);
    uint64_t r;

    switch (offset) {
    case A_CFG0:
        r = s->cfg0;
        break;
    case A_CFG1:
        r = s->cfg1;
        break;
    case A_CFG2:
        if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
            /* CFG2 reserved on other boards */
            goto bad_offset;
        }
        r = s->cfg2;
        break;
    case A_CFG3:
        if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
            /* CFG3 reserved on AN524 */
            goto bad_offset;
        }
        /* These are user-settable DIP switches on the board. We don't
         * model that, so just return zeroes.
         */
        r = 0;
        break;
    case A_CFG4:
        r = s->cfg4;
        break;
    case A_CFG5:
        if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
            /* CFG5 reserved on other boards */
            goto bad_offset;
        }
        r = s->cfg5;
        break;
    case A_CFG6:
        if (scc_partno(s) != 0x524) {
            /* CFG6 reserved on other boards */
            goto bad_offset;
        }
        r = s->cfg6;
        break;
    case A_CFGDATA_RTN:
        r = s->cfgdata_rtn;
        break;
    case A_CFGDATA_OUT:
        r = s->cfgdata_out;
        break;
    case A_CFGCTRL:
        r = s->cfgctrl;
        break;
    case A_CFGSTAT:
        r = s->cfgstat;
        break;
    case A_DLL:
        r = s->dll;
        break;
    case A_AID:
        r = s->aid;
        break;
    case A_ID:
        r = s->id;
        break;
    default:
    bad_offset:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "MPS2 SCC read: bad offset %x\n", (int) offset);
        r = 0;
        break;
    }

    trace_mps2_scc_read(offset, r, size);
    return r;
}

static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
                           unsigned size)
{
    MPS2SCC *s = MPS2_SCC(opaque);

    trace_mps2_scc_write(offset, value, size);

    switch (offset) {
    case A_CFG0:
        /*
         * On some boards bit 0 controls board-specific remapping;
         * we always reflect bit 0 in the 'remap' GPIO output line,
         * and let the board wire it up or not as it chooses.
         * TODO on some boards bit 1 is CPU_WAIT.
         */
        s->cfg0 = value;
        qemu_set_irq(s->remap, s->cfg0 & 1);
        break;
    case A_CFG1:
        s->cfg1 = value;
        for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
            led_set_state(s->led[i], extract32(value, i, 1));
        }
        break;
    case A_CFG2:
        if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
            /* CFG2 reserved on other boards */
            goto bad_offset;
        }
        /* AN524: QSPI Select signal */
        s->cfg2 = value;
        break;
    case A_CFG5:
        if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
            /* CFG5 reserved on other boards */
            goto bad_offset;
        }
        /* AN524: ACLK frequency in Hz */
        s->cfg5 = value;
        break;
    case A_CFG6:
        if (scc_partno(s) != 0x524) {
            /* CFG6 reserved on other boards */
            goto bad_offset;
        }
        /* AN524: Clock divider for BRAM */
        s->cfg6 = value;
        break;
    case A_CFGDATA_OUT:
        s->cfgdata_out = value;
        break;
    case A_CFGCTRL:
        /* Writing to CFGCTRL clears SYS_CFGSTAT */
        s->cfgstat = 0;
        s->cfgctrl = value & ~(R_CFGCTRL_RES1_MASK |
                               R_CFGCTRL_RES2_MASK |
                               R_CFGCTRL_START_MASK);

        if (value & R_CFGCTRL_START_MASK) {
            /* Start bit set -- do a read or write (instantaneously) */
            int device = extract32(s->cfgctrl, R_CFGCTRL_DEVICE_SHIFT,
                                   R_CFGCTRL_DEVICE_LENGTH);
            int function = extract32(s->cfgctrl, R_CFGCTRL_FUNCTION_SHIFT,
                                     R_CFGCTRL_FUNCTION_LENGTH);

            s->cfgstat = R_CFGSTAT_DONE_MASK;
            if (s->cfgctrl & R_CFGCTRL_WRITE_MASK) {
                if (!scc_cfg_write(s, function, device, s->cfgdata_out)) {
                    s->cfgstat |= R_CFGSTAT_ERROR_MASK;
                }
            } else {
                uint32_t result;
                if (!scc_cfg_read(s, function, device, &result)) {
                    s->cfgstat |= R_CFGSTAT_ERROR_MASK;
                } else {
                    s->cfgdata_rtn = result;
                }
            }
        }
        break;
    case A_DLL:
        /* DLL stands for Digital Locked Loop.
         * Bits [31:24] (DLL_LOCK_MASK) are writable, and indicate a
         * mask of which of the DLL_LOCKED bits [16:23] should be ORed
         * together to determine the ALL_UNMASKED_DLLS_LOCKED bit [0].
         * For QEMU, our DLLs are always locked, so we can leave bit 0
         * as 1 always and don't need to recalculate it.
         */
        s->dll = deposit32(s->dll, 24, 8, extract32(value, 24, 8));
        break;
    default:
    bad_offset:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "MPS2 SCC write: bad offset 0x%x\n", (int) offset);
        break;
    }
}

static const MemoryRegionOps mps2_scc_ops = {
    .read = mps2_scc_read,
    .write = mps2_scc_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void mps2_scc_reset(DeviceState *dev)
{
    MPS2SCC *s = MPS2_SCC(dev);
    int i;

    trace_mps2_scc_reset();
    s->cfg0 = s->cfg0_reset;
    s->cfg1 = 0;
    s->cfg2 = 0;
    s->cfg5 = 0;
    s->cfg6 = 0;
    s->cfgdata_rtn = 0;
    s->cfgdata_out = 0;
    s->cfgctrl = 0x100000;
    s->cfgstat = 0;
    s->dll = 0xffff0001;
    for (i = 0; i < s->num_oscclk; i++) {
        s->oscclk[i] = s->oscclk_reset[i];
    }
    for (i = 0; i < ARRAY_SIZE(s->led); i++) {
        device_cold_reset(DEVICE(s->led[i]));
    }
}

static void mps2_scc_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    MPS2SCC *s = MPS2_SCC(obj);

    memory_region_init_io(&s->iomem, obj, &mps2_scc_ops, s, "mps2-scc", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
    qdev_init_gpio_out_named(DEVICE(obj), &s->remap, "remap", 1);
}

static void mps2_scc_realize(DeviceState *dev, Error **errp)
{
    MPS2SCC *s = MPS2_SCC(dev);

    for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
        char *name = g_strdup_printf("SCC LED%zu", i);
        s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
                                      LED_COLOR_GREEN, name);
        g_free(name);
    }

    s->oscclk = g_new0(uint32_t, s->num_oscclk);
}

static void mps2_scc_finalize(Object *obj)
{
    MPS2SCC *s = MPS2_SCC(obj);

    g_free(s->oscclk_reset);
}

static const VMStateDescription mps2_scc_vmstate = {
    .name = "mps2-scc",
    .version_id = 3,
    .minimum_version_id = 3,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(cfg0, MPS2SCC),
        VMSTATE_UINT32(cfg1, MPS2SCC),
        VMSTATE_UINT32(cfg2, MPS2SCC),
        /* cfg3, cfg4 are read-only so need not be migrated */
        VMSTATE_UINT32(cfg5, MPS2SCC),
        VMSTATE_UINT32(cfg6, MPS2SCC),
        VMSTATE_UINT32(cfgdata_rtn, MPS2SCC),
        VMSTATE_UINT32(cfgdata_out, MPS2SCC),
        VMSTATE_UINT32(cfgctrl, MPS2SCC),
        VMSTATE_UINT32(cfgstat, MPS2SCC),
        VMSTATE_UINT32(dll, MPS2SCC),
        VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
                              0, vmstate_info_uint32, uint32_t),
        VMSTATE_END_OF_LIST()
    }
};

static Property mps2_scc_properties[] = {
    /* Values for various read-only ID registers (which are specific
     * to the board model or FPGA image)
     */
    DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
    DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
    DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
    /* Reset value for CFG0 register */
    DEFINE_PROP_UINT32("scc-cfg0", MPS2SCC, cfg0_reset, 0),
    /*
     * These are the initial settings for the source clocks on the board.
     * In hardware they can be configured via a config file read by the
     * motherboard configuration controller to suit the FPGA image.
     */
    DEFINE_PROP_ARRAY("oscclk", MPS2SCC, num_oscclk, oscclk_reset,
                      qdev_prop_uint32, uint32_t),
    DEFINE_PROP_END_OF_LIST(),
};

static void mps2_scc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = mps2_scc_realize;
    dc->vmsd = &mps2_scc_vmstate;
    dc->reset = mps2_scc_reset;
    device_class_set_props(dc, mps2_scc_properties);
}

static const TypeInfo mps2_scc_info = {
    .name = TYPE_MPS2_SCC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(MPS2SCC),
    .instance_init = mps2_scc_init,
    .instance_finalize = mps2_scc_finalize,
    .class_init = mps2_scc_class_init,
};

static void mps2_scc_register_types(void)
{
    type_register_static(&mps2_scc_info);
}

type_init(mps2_scc_register_types);
