/*
 * ASPEED SDRAM Memory Controller
 *
 * Copyright (C) 2016 IBM Corp.
 *
 * 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 "qemu/log.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
#include "hw/misc/aspeed_sdmc.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "trace.h"
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qapi/visitor.h"

/* Protection Key Register */
#define R_PROT            (0x00 / 4)
#define   PROT_UNLOCKED      0x01
#define   PROT_HARDLOCKED    0x10  /* AST2600 */
#define   PROT_SOFTLOCKED    0x00

#define   PROT_KEY_UNLOCK     0xFC600309
#define   PROT_KEY_HARDLOCK   0xDEADDEAD /* AST2600 */

/* Configuration Register */
#define R_CONF            (0x04 / 4)

/* Interrupt control/status */
#define R_ISR             (0x50 / 4)

/* Control/Status Register #1 (ast2500) */
#define R_STATUS1         (0x60 / 4)
#define   PHY_BUSY_STATE      BIT(0)
#define   PHY_PLL_LOCK_STATUS BIT(4)

/* Reserved */
#define R_MCR6C           (0x6c / 4)

#define R_ECC_TEST_CTRL   (0x70 / 4)
#define   ECC_TEST_FINISHED   BIT(12)
#define   ECC_TEST_FAIL       BIT(13)

#define R_TEST_START_LEN  (0x74 / 4)
#define R_TEST_FAIL_DQ    (0x78 / 4)
#define R_TEST_INIT_VAL   (0x7c / 4)
#define R_DRAM_SW         (0x88 / 4)
#define R_DRAM_TIME       (0x8c / 4)
#define R_ECC_ERR_INJECT  (0xb4 / 4)

/*
 * Configuration register Ox4 (for Aspeed AST2400 SOC)
 *
 * These are for the record and future use. ASPEED_SDMC_DRAM_SIZE is
 * what we care about right now as it is checked by U-Boot to
 * determine the RAM size.
 */

#define ASPEED_SDMC_RESERVED            0xFFFFF800 /* 31:11 reserved */
#define ASPEED_SDMC_AST2300_COMPAT      (1 << 10)
#define ASPEED_SDMC_SCRAMBLE_PATTERN    (1 << 9)
#define ASPEED_SDMC_DATA_SCRAMBLE       (1 << 8)
#define ASPEED_SDMC_ECC_ENABLE          (1 << 7)
#define ASPEED_SDMC_VGA_COMPAT          (1 << 6) /* readonly */
#define ASPEED_SDMC_DRAM_BANK           (1 << 5)
#define ASPEED_SDMC_DRAM_BURST          (1 << 4)
#define ASPEED_SDMC_VGA_APERTURE(x)     ((x & 0x3) << 2) /* readonly */
#define     ASPEED_SDMC_VGA_8MB             0x0
#define     ASPEED_SDMC_VGA_16MB            0x1
#define     ASPEED_SDMC_VGA_32MB            0x2
#define     ASPEED_SDMC_VGA_64MB            0x3
#define ASPEED_SDMC_DRAM_SIZE(x)        (x & 0x3)
#define     ASPEED_SDMC_DRAM_64MB           0x0
#define     ASPEED_SDMC_DRAM_128MB          0x1
#define     ASPEED_SDMC_DRAM_256MB          0x2
#define     ASPEED_SDMC_DRAM_512MB          0x3

#define ASPEED_SDMC_READONLY_MASK                       \
    (ASPEED_SDMC_RESERVED | ASPEED_SDMC_VGA_COMPAT |    \
     ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
/*
 * Configuration register Ox4 (for Aspeed AST2500 SOC and higher)
 *
 * Incompatibilities are annotated in the list. ASPEED_SDMC_HW_VERSION
 * should be set to 1 for the AST2500 SOC.
 */
#define ASPEED_SDMC_HW_VERSION(x)       ((x & 0xf) << 28) /* readonly */
#define ASPEED_SDMC_SW_VERSION          ((x & 0xff) << 20)
#define ASPEED_SDMC_CACHE_INITIAL_DONE  (1 << 19)  /* readonly */
#define ASPEED_SDMC_AST2500_RESERVED    0x7C000 /* 18:14 reserved */
#define ASPEED_SDMC_CACHE_DDR4_CONF     (1 << 13)
#define ASPEED_SDMC_CACHE_INITIAL       (1 << 12)
#define ASPEED_SDMC_CACHE_RANGE_CTRL    (1 << 11)
#define ASPEED_SDMC_CACHE_ENABLE        (1 << 10) /* differs from AST2400 */
#define ASPEED_SDMC_DRAM_TYPE           (1 << 4)  /* differs from AST2400 */

/* DRAM size definitions differs */
#define     ASPEED_SDMC_AST2500_128MB       0x0
#define     ASPEED_SDMC_AST2500_256MB       0x1
#define     ASPEED_SDMC_AST2500_512MB       0x2
#define     ASPEED_SDMC_AST2500_1024MB      0x3

#define     ASPEED_SDMC_AST2600_256MB       0x0
#define     ASPEED_SDMC_AST2600_512MB       0x1
#define     ASPEED_SDMC_AST2600_1024MB      0x2
#define     ASPEED_SDMC_AST2600_2048MB      0x3

#define ASPEED_SDMC_AST2500_READONLY_MASK                               \
    (ASPEED_SDMC_HW_VERSION(0xf) | ASPEED_SDMC_CACHE_INITIAL_DONE |     \
     ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT |            \
     ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))

static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
{
    AspeedSDMCState *s = ASPEED_SDMC(opaque);

    addr >>= 2;

    if (addr >= ARRAY_SIZE(s->regs)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
                      __func__, addr * 4);
        return 0;
    }

    trace_aspeed_sdmc_read(addr, s->regs[addr]);
    return s->regs[addr];
}

static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
                             unsigned int size)
{
    AspeedSDMCState *s = ASPEED_SDMC(opaque);
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);

    addr >>= 2;

    if (addr >= ARRAY_SIZE(s->regs)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
                      __func__, addr);
        return;
    }

    trace_aspeed_sdmc_write(addr, data);
    asc->write(s, addr, data);
}

static const MemoryRegionOps aspeed_sdmc_ops = {
    .read = aspeed_sdmc_read,
    .write = aspeed_sdmc_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
};

static void aspeed_sdmc_reset(DeviceState *dev)
{
    AspeedSDMCState *s = ASPEED_SDMC(dev);
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);

    memset(s->regs, 0, sizeof(s->regs));

    /* Set ram size bit and defaults values */
    s->regs[R_CONF] = asc->compute_conf(s, 0);

    /*
     * PHY status:
     *  - set phy status ok (set bit 1)
     *  - initial PVT calibration ok (clear bit 3)
     *  - runtime calibration ok (clear bit 5)
     */
    s->regs[0x100] = BIT(1);

    /* PHY eye window: set all as passing */
    s->regs[0x100 | (0x68 / 4)] = 0xff;
    s->regs[0x100 | (0x7c / 4)] = 0xff;
    s->regs[0x100 | (0x50 / 4)] = 0xfffffff;
}

static void aspeed_sdmc_get_ram_size(Object *obj, Visitor *v, const char *name,
                                     void *opaque, Error **errp)
{
    AspeedSDMCState *s = ASPEED_SDMC(obj);
    int64_t value = s->ram_size;

    visit_type_int(v, name, &value, errp);
}

static void aspeed_sdmc_set_ram_size(Object *obj, Visitor *v, const char *name,
                                     void *opaque, Error **errp)
{
    int i;
    char *sz;
    int64_t value;
    AspeedSDMCState *s = ASPEED_SDMC(obj);
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);

    if (!visit_type_int(v, name, &value, errp)) {
        return;
    }

    for (i = 0; asc->valid_ram_sizes[i]; i++) {
        if (value == asc->valid_ram_sizes[i]) {
            s->ram_size = value;
            return;
        }
    }

    sz = size_to_str(value);
    error_setg(errp, "Invalid RAM size %s", sz);
    g_free(sz);
}

static void aspeed_sdmc_initfn(Object *obj)
{
    object_property_add(obj, "ram-size", "int",
                        aspeed_sdmc_get_ram_size, aspeed_sdmc_set_ram_size,
                        NULL, NULL);
}

static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    AspeedSDMCState *s = ASPEED_SDMC(dev);
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);

    assert(asc->max_ram_size < 4 * GiB); /* 32-bit address bus */
    s->max_ram_size = asc->max_ram_size;

    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sdmc_ops, s,
                          TYPE_ASPEED_SDMC, 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
}

static const VMStateDescription vmstate_aspeed_sdmc = {
    .name = "aspeed.sdmc",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, AspeedSDMCState, ASPEED_SDMC_NR_REGS),
        VMSTATE_END_OF_LIST()
    }
};

static Property aspeed_sdmc_properties[] = {
    DEFINE_PROP_UINT64("max-ram-size", AspeedSDMCState, max_ram_size, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void aspeed_sdmc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    dc->realize = aspeed_sdmc_realize;
    dc->reset = aspeed_sdmc_reset;
    dc->desc = "ASPEED SDRAM Memory Controller";
    dc->vmsd = &vmstate_aspeed_sdmc;
    device_class_set_props(dc, aspeed_sdmc_properties);
}

static const TypeInfo aspeed_sdmc_info = {
    .name = TYPE_ASPEED_SDMC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(AspeedSDMCState),
    .instance_init = aspeed_sdmc_initfn,
    .class_init = aspeed_sdmc_class_init,
    .class_size = sizeof(AspeedSDMCClass),
    .abstract   = true,
};

static int aspeed_sdmc_get_ram_bits(AspeedSDMCState *s)
{
    AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
    int i;

    /*
     * The bitfield value encoding the RAM size is the index of the
     * possible RAM size array
     */
    for (i = 0; asc->valid_ram_sizes[i]; i++) {
        if (s->ram_size == asc->valid_ram_sizes[i]) {
            return i;
        }
    }

    /*
     * Invalid RAM sizes should have been excluded when setting the
     * SoC RAM size.
     */
    g_assert_not_reached();
}

static uint32_t aspeed_2400_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
{
    uint32_t fixed_conf = ASPEED_SDMC_VGA_COMPAT |
        ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));

    /* Make sure readonly bits are kept */
    data &= ~ASPEED_SDMC_READONLY_MASK;

    return data | fixed_conf;
}

static void aspeed_2400_sdmc_write(AspeedSDMCState *s, uint32_t reg,
                                   uint32_t data)
{
    if (reg == R_PROT) {
        s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
        return;
    }

    if (!s->regs[R_PROT]) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
        return;
    }

    switch (reg) {
    case R_CONF:
        data = aspeed_2400_sdmc_compute_conf(s, data);
        break;
    default:
        break;
    }

    s->regs[reg] = data;
}

static const uint64_t
aspeed_2400_ram_sizes[] = { 64 * MiB, 128 * MiB, 256 * MiB, 512 * MiB, 0};

static void aspeed_2400_sdmc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);

    dc->desc = "ASPEED 2400 SDRAM Memory Controller";
    asc->max_ram_size = 512 * MiB;
    asc->compute_conf = aspeed_2400_sdmc_compute_conf;
    asc->write = aspeed_2400_sdmc_write;
    asc->valid_ram_sizes = aspeed_2400_ram_sizes;
}

static const TypeInfo aspeed_2400_sdmc_info = {
    .name = TYPE_ASPEED_2400_SDMC,
    .parent = TYPE_ASPEED_SDMC,
    .class_init = aspeed_2400_sdmc_class_init,
};

static uint32_t aspeed_2500_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
{
    uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
        ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
        ASPEED_SDMC_CACHE_INITIAL_DONE |
        ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));

    /* Make sure readonly bits are kept */
    data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;

    return data | fixed_conf;
}

static void aspeed_2500_sdmc_write(AspeedSDMCState *s, uint32_t reg,
                                   uint32_t data)
{
    if (reg == R_PROT) {
        s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
        return;
    }

    if (!s->regs[R_PROT]) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
        return;
    }

    switch (reg) {
    case R_CONF:
        data = aspeed_2500_sdmc_compute_conf(s, data);
        break;
    case R_STATUS1:
        /* Will never return 'busy' */
        data &= ~PHY_BUSY_STATE;
        break;
    case R_ECC_TEST_CTRL:
        /* Always done, always happy */
        data |= ECC_TEST_FINISHED;
        data &= ~ECC_TEST_FAIL;
        break;
    default:
        break;
    }

    s->regs[reg] = data;
}

static const uint64_t
aspeed_2500_ram_sizes[] = { 128 * MiB, 256 * MiB, 512 * MiB, 1024 * MiB, 0};

static void aspeed_2500_sdmc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);

    dc->desc = "ASPEED 2500 SDRAM Memory Controller";
    asc->max_ram_size = 1 * GiB;
    asc->compute_conf = aspeed_2500_sdmc_compute_conf;
    asc->write = aspeed_2500_sdmc_write;
    asc->valid_ram_sizes = aspeed_2500_ram_sizes;
}

static const TypeInfo aspeed_2500_sdmc_info = {
    .name = TYPE_ASPEED_2500_SDMC,
    .parent = TYPE_ASPEED_SDMC,
    .class_init = aspeed_2500_sdmc_class_init,
};

static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
{
    uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(3) |
        ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
        ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));

    /* Make sure readonly bits are kept (use ast2500 mask) */
    data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;

    return data | fixed_conf;
}

static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg,
                                   uint32_t data)
{
    /* Unprotected registers */
    switch (reg) {
    case R_ISR:
    case R_MCR6C:
    case R_TEST_START_LEN:
    case R_TEST_FAIL_DQ:
    case R_TEST_INIT_VAL:
    case R_DRAM_SW:
    case R_DRAM_TIME:
    case R_ECC_ERR_INJECT:
        s->regs[reg] = data;
        return;
    }

    if (s->regs[R_PROT] == PROT_HARDLOCKED) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked until system reset!\n",
                __func__);
        return;
    }

    if (reg != R_PROT && s->regs[R_PROT] == PROT_SOFTLOCKED) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: SDMC is locked! (write to MCR%02x blocked)\n",
                      __func__, reg * 4);
        return;
    }

    switch (reg) {
    case R_PROT:
        if (data == PROT_KEY_UNLOCK)  {
            data = PROT_UNLOCKED;
        } else if (data == PROT_KEY_HARDLOCK) {
            data = PROT_HARDLOCKED;
        } else {
            data = PROT_SOFTLOCKED;
        }
        break;
    case R_CONF:
        data = aspeed_2600_sdmc_compute_conf(s, data);
        break;
    case R_STATUS1:
        /* Will never return 'busy'. 'lock status' is always set */
        data &= ~PHY_BUSY_STATE;
        data |= PHY_PLL_LOCK_STATUS;
        break;
    case R_ECC_TEST_CTRL:
        /* Always done, always happy */
        data |= ECC_TEST_FINISHED;
        data &= ~ECC_TEST_FAIL;
        break;
    default:
        break;
    }

    s->regs[reg] = data;
}

static const uint64_t
aspeed_2600_ram_sizes[] = { 256 * MiB, 512 * MiB, 1024 * MiB, 2048 * MiB, 0};

static void aspeed_2600_sdmc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);

    dc->desc = "ASPEED 2600 SDRAM Memory Controller";
    asc->max_ram_size = 2 * GiB;
    asc->compute_conf = aspeed_2600_sdmc_compute_conf;
    asc->write = aspeed_2600_sdmc_write;
    asc->valid_ram_sizes = aspeed_2600_ram_sizes;
}

static const TypeInfo aspeed_2600_sdmc_info = {
    .name = TYPE_ASPEED_2600_SDMC,
    .parent = TYPE_ASPEED_SDMC,
    .class_init = aspeed_2600_sdmc_class_init,
};

static void aspeed_sdmc_register_types(void)
{
    type_register_static(&aspeed_sdmc_info);
    type_register_static(&aspeed_2400_sdmc_info);
    type_register_static(&aspeed_2500_sdmc_info);
    type_register_static(&aspeed_2600_sdmc_info);
}

type_init(aspeed_sdmc_register_types);
