/*
 * ARM CMSDK APB timer 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 "APB timer" which is part of the Cortex-M
 * System Design Kit (CMSDK) and documented in the Cortex-M System
 * Design Kit Technical Reference Manual (ARM DDI0479C):
 * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
 *
 * The hardware has an EXTIN input wire, which can be configured
 * by the guest to act either as a 'timer enable' (timer does not run
 * when EXTIN is low), or as a 'timer clock' (timer runs at frequency
 * of EXTIN clock, not PCLK frequency). We don't model this.
 *
 * The documentation is not very clear about the exact behaviour;
 * we choose to implement that the interrupt is triggered when
 * the counter goes from 1 to 0, that the counter then holds at 0
 * for one clock cycle before reloading from the RELOAD register,
 * and that if the RELOAD register is 0 this does not cause an
 * interrupt (as there is no further 1->0 transition).
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "trace.h"
#include "hw/sysbus.h"
#include "hw/registerfields.h"
#include "hw/timer/cmsdk-apb-timer.h"

REG32(CTRL, 0)
    FIELD(CTRL, EN, 0, 1)
    FIELD(CTRL, SELEXTEN, 1, 1)
    FIELD(CTRL, SELEXTCLK, 2, 1)
    FIELD(CTRL, IRQEN, 3, 1)
REG32(VALUE, 4)
REG32(RELOAD, 8)
REG32(INTSTATUS, 0xc)
    FIELD(INTSTATUS, IRQ, 0, 1)
REG32(PID4, 0xFD0)
REG32(PID5, 0xFD4)
REG32(PID6, 0xFD8)
REG32(PID7, 0xFDC)
REG32(PID0, 0xFE0)
REG32(PID1, 0xFE4)
REG32(PID2, 0xFE8)
REG32(PID3, 0xFEC)
REG32(CID0, 0xFF0)
REG32(CID1, 0xFF4)
REG32(CID2, 0xFF8)
REG32(CID3, 0xFFC)

/* PID/CID values */
static const int timer_id[] = {
    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
    0x22, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};

static void cmsdk_apb_timer_update(CMSDKAPBTIMER *s)
{
    qemu_set_irq(s->timerint, !!(s->intstatus & R_INTSTATUS_IRQ_MASK));
}

static uint64_t cmsdk_apb_timer_read(void *opaque, hwaddr offset, unsigned size)
{
    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
    uint64_t r;

    switch (offset) {
    case A_CTRL:
        r = s->ctrl;
        break;
    case A_VALUE:
        r = ptimer_get_count(s->timer);
        break;
    case A_RELOAD:
        r = ptimer_get_limit(s->timer);
        break;
    case A_INTSTATUS:
        r = s->intstatus;
        break;
    case A_PID4 ... A_CID3:
        r = timer_id[(offset - A_PID4) / 4];
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "CMSDK APB timer read: bad offset %x\n", (int) offset);
        r = 0;
        break;
    }
    trace_cmsdk_apb_timer_read(offset, r, size);
    return r;
}

static void cmsdk_apb_timer_write(void *opaque, hwaddr offset, uint64_t value,
                                  unsigned size)
{
    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);

    trace_cmsdk_apb_timer_write(offset, value, size);

    switch (offset) {
    case A_CTRL:
        if (value & 6) {
            /* Bits [1] and [2] enable using EXTIN as either clock or
             * an enable line. We don't model this.
             */
            qemu_log_mask(LOG_UNIMP,
                          "CMSDK APB timer: EXTIN input not supported\n");
        }
        s->ctrl = value & 0xf;
        if (s->ctrl & R_CTRL_EN_MASK) {
            ptimer_run(s->timer, ptimer_get_limit(s->timer) == 0);
        } else {
            ptimer_stop(s->timer);
        }
        break;
    case A_RELOAD:
        /* Writing to reload also sets the current timer value */
        if (!value) {
            ptimer_stop(s->timer);
        }
        ptimer_set_limit(s->timer, value, 1);
        if (value && (s->ctrl & R_CTRL_EN_MASK)) {
            /*
             * Make sure timer is running (it might have stopped if this
             * was an expired one-shot timer)
             */
            ptimer_run(s->timer, 0);
        }
        break;
    case A_VALUE:
        if (!value && !ptimer_get_limit(s->timer)) {
            ptimer_stop(s->timer);
        }
        ptimer_set_count(s->timer, value);
        if (value && (s->ctrl & R_CTRL_EN_MASK)) {
            ptimer_run(s->timer, ptimer_get_limit(s->timer) == 0);
        }
        break;
    case A_INTSTATUS:
        /* Just one bit, which is W1C. */
        value &= 1;
        s->intstatus &= ~value;
        cmsdk_apb_timer_update(s);
        break;
    case A_PID4 ... A_CID3:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "CMSDK APB timer write: write to RO offset 0x%x\n",
                      (int)offset);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "CMSDK APB timer write: bad offset 0x%x\n", (int) offset);
        break;
    }
}

static const MemoryRegionOps cmsdk_apb_timer_ops = {
    .read = cmsdk_apb_timer_read,
    .write = cmsdk_apb_timer_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void cmsdk_apb_timer_tick(void *opaque)
{
    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);

    if (s->ctrl & R_CTRL_IRQEN_MASK) {
        s->intstatus |= R_INTSTATUS_IRQ_MASK;
        cmsdk_apb_timer_update(s);
    }
}

static void cmsdk_apb_timer_reset(DeviceState *dev)
{
    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);

    trace_cmsdk_apb_timer_reset();
    s->ctrl = 0;
    s->intstatus = 0;
    ptimer_stop(s->timer);
    /* Set the limit and the count */
    ptimer_set_limit(s->timer, 0, 1);
}

static void cmsdk_apb_timer_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(obj);

    memory_region_init_io(&s->iomem, obj, &cmsdk_apb_timer_ops,
                          s, "cmsdk-apb-timer", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->timerint);
}

static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
{
    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
    QEMUBH *bh;

    if (s->pclk_frq == 0) {
        error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
        return;
    }

    bh = qemu_bh_new(cmsdk_apb_timer_tick, s);
    s->timer = ptimer_init(bh,
                           PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
                           PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT |
                           PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
                           PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);

    ptimer_set_freq(s->timer, s->pclk_frq);
}

static const VMStateDescription cmsdk_apb_timer_vmstate = {
    .name = "cmsdk-apb-timer",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_PTIMER(timer, CMSDKAPBTIMER),
        VMSTATE_UINT32(ctrl, CMSDKAPBTIMER),
        VMSTATE_UINT32(value, CMSDKAPBTIMER),
        VMSTATE_UINT32(reload, CMSDKAPBTIMER),
        VMSTATE_UINT32(intstatus, CMSDKAPBTIMER),
        VMSTATE_END_OF_LIST()
    }
};

static Property cmsdk_apb_timer_properties[] = {
    DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTIMER, pclk_frq, 0),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->realize = cmsdk_apb_timer_realize;
    dc->vmsd = &cmsdk_apb_timer_vmstate;
    dc->reset = cmsdk_apb_timer_reset;
    dc->props = cmsdk_apb_timer_properties;
}

static const TypeInfo cmsdk_apb_timer_info = {
    .name = TYPE_CMSDK_APB_TIMER,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(CMSDKAPBTIMER),
    .instance_init = cmsdk_apb_timer_init,
    .class_init = cmsdk_apb_timer_class_init,
};

static void cmsdk_apb_timer_register_types(void)
{
    type_register_static(&cmsdk_apb_timer_info);
}

type_init(cmsdk_apb_timer_register_types);
