/*
 * Nuvoton NPCM7xx Clock Control Registers.
 *
 * Copyright 2020 Google LLC
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License
 * for more details.
 */

#include "qemu/osdep.h"

#include "hw/misc/npcm7xx_clk.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "qemu/units.h"
#include "trace.h"

#define PLLCON_LOKI     BIT(31)
#define PLLCON_LOKS     BIT(30)
#define PLLCON_PWDEN    BIT(12)

enum NPCM7xxCLKRegisters {
    NPCM7XX_CLK_CLKEN1,
    NPCM7XX_CLK_CLKSEL,
    NPCM7XX_CLK_CLKDIV1,
    NPCM7XX_CLK_PLLCON0,
    NPCM7XX_CLK_PLLCON1,
    NPCM7XX_CLK_SWRSTR,
    NPCM7XX_CLK_IPSRST1         = 0x20 / sizeof(uint32_t),
    NPCM7XX_CLK_IPSRST2,
    NPCM7XX_CLK_CLKEN2,
    NPCM7XX_CLK_CLKDIV2,
    NPCM7XX_CLK_CLKEN3,
    NPCM7XX_CLK_IPSRST3,
    NPCM7XX_CLK_WD0RCR,
    NPCM7XX_CLK_WD1RCR,
    NPCM7XX_CLK_WD2RCR,
    NPCM7XX_CLK_SWRSTC1,
    NPCM7XX_CLK_SWRSTC2,
    NPCM7XX_CLK_SWRSTC3,
    NPCM7XX_CLK_SWRSTC4,
    NPCM7XX_CLK_PLLCON2,
    NPCM7XX_CLK_CLKDIV3,
    NPCM7XX_CLK_CORSTC,
    NPCM7XX_CLK_PLLCONG,
    NPCM7XX_CLK_AHBCKFI,
    NPCM7XX_CLK_SECCNT,
    NPCM7XX_CLK_CNTR25M,
    NPCM7XX_CLK_REGS_END,
};

/*
 * These reset values were taken from version 0.91 of the NPCM750R data sheet.
 *
 * All are loaded on power-up reset. CLKENx and SWRSTR should also be loaded on
 * core domain reset, but this reset type is not yet supported by QEMU.
 */
static const uint32_t cold_reset_values[NPCM7XX_CLK_NR_REGS] = {
    [NPCM7XX_CLK_CLKEN1]        = 0xffffffff,
    [NPCM7XX_CLK_CLKSEL]        = 0x004aaaaa,
    [NPCM7XX_CLK_CLKDIV1]       = 0x5413f855,
    [NPCM7XX_CLK_PLLCON0]       = 0x00222101 | PLLCON_LOKI,
    [NPCM7XX_CLK_PLLCON1]       = 0x00202101 | PLLCON_LOKI,
    [NPCM7XX_CLK_IPSRST1]       = 0x00001000,
    [NPCM7XX_CLK_IPSRST2]       = 0x80000000,
    [NPCM7XX_CLK_CLKEN2]        = 0xffffffff,
    [NPCM7XX_CLK_CLKDIV2]       = 0xaa4f8f9f,
    [NPCM7XX_CLK_CLKEN3]        = 0xffffffff,
    [NPCM7XX_CLK_IPSRST3]       = 0x03000000,
    [NPCM7XX_CLK_WD0RCR]        = 0xffffffff,
    [NPCM7XX_CLK_WD1RCR]        = 0xffffffff,
    [NPCM7XX_CLK_WD2RCR]        = 0xffffffff,
    [NPCM7XX_CLK_SWRSTC1]       = 0x00000003,
    [NPCM7XX_CLK_PLLCON2]       = 0x00c02105 | PLLCON_LOKI,
    [NPCM7XX_CLK_CORSTC]        = 0x04000003,
    [NPCM7XX_CLK_PLLCONG]       = 0x01228606 | PLLCON_LOKI,
    [NPCM7XX_CLK_AHBCKFI]       = 0x000000c8,
};

static uint64_t npcm7xx_clk_read(void *opaque, hwaddr offset, unsigned size)
{
    uint32_t reg = offset / sizeof(uint32_t);
    NPCM7xxCLKState *s = opaque;
    int64_t now_ns;
    uint32_t value = 0;

    if (reg >= NPCM7XX_CLK_NR_REGS) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: offset 0x%04" HWADDR_PRIx " out of range\n",
                      __func__, offset);
        return 0;
    }

    switch (reg) {
    case NPCM7XX_CLK_SWRSTR:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: register @ 0x%04" HWADDR_PRIx " is write-only\n",
                      __func__, offset);
        break;

    case NPCM7XX_CLK_SECCNT:
        now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        value = (now_ns - s->ref_ns) / NANOSECONDS_PER_SECOND;
        break;

    case NPCM7XX_CLK_CNTR25M:
        now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        /*
         * This register counts 25 MHz cycles, updating every 640 ns. It rolls
         * over to zero every second.
         *
         * The 4 LSBs are always zero: (1e9 / 640) << 4 = 25000000.
         */
        value = (((now_ns - s->ref_ns) / 640) << 4) % NPCM7XX_TIMER_REF_HZ;
        break;

    default:
        value = s->regs[reg];
        break;
    };

    trace_npcm7xx_clk_read(offset, value);

    return value;
}

static void npcm7xx_clk_write(void *opaque, hwaddr offset,
                              uint64_t v, unsigned size)
{
    uint32_t reg = offset / sizeof(uint32_t);
    NPCM7xxCLKState *s = opaque;
    uint32_t value = v;

    trace_npcm7xx_clk_write(offset, value);

    if (reg >= NPCM7XX_CLK_NR_REGS) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: offset 0x%04" HWADDR_PRIx " out of range\n",
                      __func__, offset);
        return;
    }

    switch (reg) {
    case NPCM7XX_CLK_SWRSTR:
        qemu_log_mask(LOG_UNIMP, "%s: SW reset not implemented: 0x%02x\n",
                      __func__, value);
        value = 0;
        break;

    case NPCM7XX_CLK_PLLCON0:
    case NPCM7XX_CLK_PLLCON1:
    case NPCM7XX_CLK_PLLCON2:
    case NPCM7XX_CLK_PLLCONG:
        if (value & PLLCON_PWDEN) {
            /* Power down -- clear lock and indicate loss of lock */
            value &= ~PLLCON_LOKI;
            value |= PLLCON_LOKS;
        } else {
            /* Normal mode -- assume always locked */
            value |= PLLCON_LOKI;
            /* Keep LOKS unchanged unless cleared by writing 1 */
            if (value & PLLCON_LOKS) {
                value &= ~PLLCON_LOKS;
            } else {
                value |= (value & PLLCON_LOKS);
            }
        }
        break;

    case NPCM7XX_CLK_CNTR25M:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: register @ 0x%04" HWADDR_PRIx " is read-only\n",
                      __func__, offset);
        return;
    }

    s->regs[reg] = value;
}

static const struct MemoryRegionOps npcm7xx_clk_ops = {
    .read       = npcm7xx_clk_read,
    .write      = npcm7xx_clk_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid      = {
        .min_access_size        = 4,
        .max_access_size        = 4,
        .unaligned              = false,
    },
};

static void npcm7xx_clk_enter_reset(Object *obj, ResetType type)
{
    NPCM7xxCLKState *s = NPCM7XX_CLK(obj);

    QEMU_BUILD_BUG_ON(sizeof(s->regs) != sizeof(cold_reset_values));

    switch (type) {
    case RESET_TYPE_COLD:
        memcpy(s->regs, cold_reset_values, sizeof(cold_reset_values));
        s->ref_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        return;
    }

    /*
     * A small number of registers need to be reset on a core domain reset,
     * but no such reset type exists yet.
     */
    qemu_log_mask(LOG_UNIMP, "%s: reset type %d not implemented.",
                  __func__, type);
}

static void npcm7xx_clk_init(Object *obj)
{
    NPCM7xxCLKState *s = NPCM7XX_CLK(obj);

    memory_region_init_io(&s->iomem, obj, &npcm7xx_clk_ops, s,
                          TYPE_NPCM7XX_CLK, 4 * KiB);
    sysbus_init_mmio(&s->parent, &s->iomem);
}

static const VMStateDescription vmstate_npcm7xx_clk = {
    .name = "npcm7xx-clk",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, NPCM7xxCLKState, NPCM7XX_CLK_NR_REGS),
        VMSTATE_INT64(ref_ns, NPCM7xxCLKState),
        VMSTATE_END_OF_LIST(),
    },
};

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

    QEMU_BUILD_BUG_ON(NPCM7XX_CLK_REGS_END > NPCM7XX_CLK_NR_REGS);

    dc->desc = "NPCM7xx Clock Control Registers";
    dc->vmsd = &vmstate_npcm7xx_clk;
    rc->phases.enter = npcm7xx_clk_enter_reset;
}

static const TypeInfo npcm7xx_clk_info = {
    .name               = TYPE_NPCM7XX_CLK,
    .parent             = TYPE_SYS_BUS_DEVICE,
    .instance_size      = sizeof(NPCM7xxCLKState),
    .instance_init      = npcm7xx_clk_init,
    .class_init         = npcm7xx_clk_class_init,
};

static void npcm7xx_clk_register_type(void)
{
    type_register_static(&npcm7xx_clk_info);
}
type_init(npcm7xx_clk_register_type);
