/*
 *  QEMU model of the Milkymist High Performance Dynamic Memory Controller.
 *
 *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Specification available at:
 *   http://milkymist.walle.cc/socdoc/hpdmc.pdf
 */

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "trace.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qom/object.h"

enum {
    R_SYSTEM = 0,
    R_BYPASS,
    R_TIMING,
    R_IODELAY,
    R_MAX
};

enum {
    IODELAY_DQSDELAY_RDY = (1<<5),
    IODELAY_PLL1_LOCKED  = (1<<6),
    IODELAY_PLL2_LOCKED  = (1<<7),
};

#define TYPE_MILKYMIST_HPDMC "milkymist-hpdmc"
OBJECT_DECLARE_SIMPLE_TYPE(MilkymistHpdmcState, MILKYMIST_HPDMC)

struct MilkymistHpdmcState {
    SysBusDevice parent_obj;

    MemoryRegion regs_region;

    uint32_t regs[R_MAX];
};

static uint64_t hpdmc_read(void *opaque, hwaddr addr,
                           unsigned size)
{
    MilkymistHpdmcState *s = opaque;
    uint32_t r = 0;

    addr >>= 2;
    switch (addr) {
    case R_SYSTEM:
    case R_BYPASS:
    case R_TIMING:
    case R_IODELAY:
        r = s->regs[addr];
        break;

    default:
        error_report("milkymist_hpdmc: read access to unknown register 0x"
                TARGET_FMT_plx, addr << 2);
        break;
    }

    trace_milkymist_hpdmc_memory_read(addr << 2, r);

    return r;
}

static void hpdmc_write(void *opaque, hwaddr addr, uint64_t value,
                        unsigned size)
{
    MilkymistHpdmcState *s = opaque;

    trace_milkymist_hpdmc_memory_write(addr, value);

    addr >>= 2;
    switch (addr) {
    case R_SYSTEM:
    case R_BYPASS:
    case R_TIMING:
        s->regs[addr] = value;
        break;
    case R_IODELAY:
        /* ignore writes */
        break;

    default:
        error_report("milkymist_hpdmc: write access to unknown register 0x"
                TARGET_FMT_plx, addr << 2);
        break;
    }
}

static const MemoryRegionOps hpdmc_mmio_ops = {
    .read = hpdmc_read,
    .write = hpdmc_write,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void milkymist_hpdmc_reset(DeviceState *d)
{
    MilkymistHpdmcState *s = MILKYMIST_HPDMC(d);
    int i;

    for (i = 0; i < R_MAX; i++) {
        s->regs[i] = 0;
    }

    /* defaults */
    s->regs[R_IODELAY] = IODELAY_DQSDELAY_RDY | IODELAY_PLL1_LOCKED
                         | IODELAY_PLL2_LOCKED;
}

static void milkymist_hpdmc_realize(DeviceState *dev, Error **errp)
{
    MilkymistHpdmcState *s = MILKYMIST_HPDMC(dev);

    memory_region_init_io(&s->regs_region, OBJECT(dev), &hpdmc_mmio_ops, s,
            "milkymist-hpdmc", R_MAX * 4);
    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs_region);
}

static const VMStateDescription vmstate_milkymist_hpdmc = {
    .name = "milkymist-hpdmc",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, MilkymistHpdmcState, R_MAX),
        VMSTATE_END_OF_LIST()
    }
};

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

    dc->realize = milkymist_hpdmc_realize;
    dc->reset = milkymist_hpdmc_reset;
    dc->vmsd = &vmstate_milkymist_hpdmc;
}

static const TypeInfo milkymist_hpdmc_info = {
    .name          = TYPE_MILKYMIST_HPDMC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(MilkymistHpdmcState),
    .class_init    = milkymist_hpdmc_class_init,
};

static void milkymist_hpdmc_register_types(void)
{
    type_register_static(&milkymist_hpdmc_info);
}

type_init(milkymist_hpdmc_register_types)
