/*
 * QEMU SiFive E PRCI (Power, Reset, Clock, Interrupt)
 *
 * Copyright (c) 2017 SiFive, Inc.
 *
 * Simple model of the PRCI to emulate register reads made by the SDK BSP
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "hw/hw.h"
#include "hw/riscv/sifive_e_prci.h"

static uint64_t sifive_e_prci_read(void *opaque, hwaddr addr, unsigned int size)
{
    SiFiveEPRCIState *s = opaque;
    switch (addr) {
    case SIFIVE_E_PRCI_HFROSCCFG:
        return s->hfrosccfg;
    case SIFIVE_E_PRCI_HFXOSCCFG:
        return s->hfxosccfg;
    case SIFIVE_E_PRCI_PLLCFG:
        return s->pllcfg;
    case SIFIVE_E_PRCI_PLLOUTDIV:
        return s->plloutdiv;
    }
    qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%x\n",
                  __func__, (int)addr);
    return 0;
}

static void sifive_e_prci_write(void *opaque, hwaddr addr,
                                uint64_t val64, unsigned int size)
{
    SiFiveEPRCIState *s = opaque;
    switch (addr) {
    case SIFIVE_E_PRCI_HFROSCCFG:
        s->hfrosccfg = (uint32_t) val64;
        /* OSC stays ready */
        s->hfrosccfg |= SIFIVE_E_PRCI_HFROSCCFG_RDY;
        break;
    case SIFIVE_E_PRCI_HFXOSCCFG:
        s->hfxosccfg = (uint32_t) val64;
        /* OSC stays ready */
        s->hfxosccfg |= SIFIVE_E_PRCI_HFXOSCCFG_RDY;
        break;
    case SIFIVE_E_PRCI_PLLCFG:
        s->pllcfg = (uint32_t) val64;
        /* PLL stays locked */
        s->pllcfg |= SIFIVE_E_PRCI_PLLCFG_LOCK;
        break;
    case SIFIVE_E_PRCI_PLLOUTDIV:
        s->plloutdiv = (uint32_t) val64;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%x v=0x%x\n",
                      __func__, (int)addr, (int)val64);
    }
}

static const MemoryRegionOps sifive_e_prci_ops = {
    .read = sifive_e_prci_read,
    .write = sifive_e_prci_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4
    }
};

static void sifive_e_prci_init(Object *obj)
{
    SiFiveEPRCIState *s = SIFIVE_E_PRCI(obj);

    memory_region_init_io(&s->mmio, obj, &sifive_e_prci_ops, s,
                          TYPE_SIFIVE_E_PRCI, SIFIVE_E_PRCI_REG_SIZE);
    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);

    s->hfrosccfg = (SIFIVE_E_PRCI_HFROSCCFG_RDY | SIFIVE_E_PRCI_HFROSCCFG_EN);
    s->hfxosccfg = (SIFIVE_E_PRCI_HFXOSCCFG_RDY | SIFIVE_E_PRCI_HFXOSCCFG_EN);
    s->pllcfg = (SIFIVE_E_PRCI_PLLCFG_REFSEL | SIFIVE_E_PRCI_PLLCFG_BYPASS |
                 SIFIVE_E_PRCI_PLLCFG_LOCK);
    s->plloutdiv = SIFIVE_E_PRCI_PLLOUTDIV_DIV1;
}

static const TypeInfo sifive_e_prci_info = {
    .name          = TYPE_SIFIVE_E_PRCI,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(SiFiveEPRCIState),
    .instance_init = sifive_e_prci_init,
};

static void sifive_e_prci_register_types(void)
{
    type_register_static(&sifive_e_prci_info);
}

type_init(sifive_e_prci_register_types)


/*
 * Create PRCI device.
 */
DeviceState *sifive_e_prci_create(hwaddr addr)
{
    DeviceState *dev = qdev_create(NULL, TYPE_SIFIVE_E_PRCI);
    qdev_init_nofail(dev);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
    return dev;
}
