/*
 * Block model of System timer present in
 * Microsemi's SmartFusion2 and SmartFusion SoCs.
 *
 * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "qemu/log.h"
#include "hw/timer/mss-timer.h"

#ifndef MSS_TIMER_ERR_DEBUG
#define MSS_TIMER_ERR_DEBUG  0
#endif

#define DB_PRINT_L(lvl, fmt, args...) do { \
    if (MSS_TIMER_ERR_DEBUG >= lvl) { \
        qemu_log("%s: " fmt "\n", __func__, ## args); \
    } \
} while (0)

#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

#define R_TIM_VAL         0
#define R_TIM_LOADVAL     1
#define R_TIM_BGLOADVAL   2
#define R_TIM_CTRL        3
#define R_TIM_RIS         4
#define R_TIM_MIS         5

#define TIMER_CTRL_ENBL     (1 << 0)
#define TIMER_CTRL_ONESHOT  (1 << 1)
#define TIMER_CTRL_INTR     (1 << 2)
#define TIMER_RIS_ACK       (1 << 0)
#define TIMER_RST_CLR       (1 << 6)
#define TIMER_MODE          (1 << 0)

static void timer_update_irq(struct Msf2Timer *st)
{
    bool isr, ier;

    isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
    ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
    qemu_set_irq(st->irq, (ier && isr));
}

static void timer_update(struct Msf2Timer *st)
{
    uint64_t count;

    if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
        ptimer_stop(st->ptimer);
        return;
    }

    count = st->regs[R_TIM_LOADVAL];
    ptimer_set_limit(st->ptimer, count, 1);
    ptimer_run(st->ptimer, 1);
}

static uint64_t
timer_read(void *opaque, hwaddr offset, unsigned int size)
{
    MSSTimerState *t = opaque;
    hwaddr addr;
    struct Msf2Timer *st;
    uint32_t ret = 0;
    int timer = 0;
    int isr;
    int ier;

    addr = offset >> 2;
    /*
     * Two independent timers has same base address.
     * Based on address passed figure out which timer is being used.
     */
    if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
        timer = 1;
        addr -= R_TIM1_MAX;
    }

    st = &t->timers[timer];

    switch (addr) {
    case R_TIM_VAL:
        ret = ptimer_get_count(st->ptimer);
        break;

    case R_TIM_MIS:
        isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
        ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
        ret = ier & isr;
        break;

    default:
        if (addr < R_TIM1_MAX) {
            ret = st->regs[addr];
        } else {
            qemu_log_mask(LOG_GUEST_ERROR,
                        TYPE_MSS_TIMER": 64-bit mode not supported\n");
            return ret;
        }
        break;
    }

    DB_PRINT("timer=%d 0x%" HWADDR_PRIx "=0x%" PRIx32, timer, offset,
            ret);
    return ret;
}

static void
timer_write(void *opaque, hwaddr offset,
            uint64_t val64, unsigned int size)
{
    MSSTimerState *t = opaque;
    hwaddr addr;
    struct Msf2Timer *st;
    int timer = 0;
    uint32_t value = val64;

    addr = offset >> 2;
    /*
     * Two independent timers has same base address.
     * Based on addr passed figure out which timer is being used.
     */
    if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
        timer = 1;
        addr -= R_TIM1_MAX;
    }

    st = &t->timers[timer];

    DB_PRINT("addr=0x%" HWADDR_PRIx " val=0x%" PRIx32 " (timer=%d)", offset,
            value, timer);

    switch (addr) {
    case R_TIM_CTRL:
        st->regs[R_TIM_CTRL] = value;
        timer_update(st);
        break;

    case R_TIM_RIS:
        if (value & TIMER_RIS_ACK) {
            st->regs[R_TIM_RIS] &= ~TIMER_RIS_ACK;
        }
        break;

    case R_TIM_LOADVAL:
        st->regs[R_TIM_LOADVAL] = value;
        if (st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL) {
            timer_update(st);
        }
        break;

    case R_TIM_BGLOADVAL:
        st->regs[R_TIM_BGLOADVAL] = value;
        st->regs[R_TIM_LOADVAL] = value;
        break;

    case R_TIM_VAL:
    case R_TIM_MIS:
        break;

    default:
        if (addr < R_TIM1_MAX) {
            st->regs[addr] = value;
        } else {
            qemu_log_mask(LOG_GUEST_ERROR,
                        TYPE_MSS_TIMER": 64-bit mode not supported\n");
            return;
        }
        break;
    }
    timer_update_irq(st);
}

static const MemoryRegionOps timer_ops = {
    .read = timer_read,
    .write = timer_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4
    }
};

static void timer_hit(void *opaque)
{
    struct Msf2Timer *st = opaque;

    st->regs[R_TIM_RIS] |= TIMER_RIS_ACK;

    if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ONESHOT)) {
        timer_update(st);
    }
    timer_update_irq(st);
}

static void mss_timer_init(Object *obj)
{
    MSSTimerState *t = MSS_TIMER(obj);
    int i;

    /* Init all the ptimers.  */
    for (i = 0; i < NUM_TIMERS; i++) {
        struct Msf2Timer *st = &t->timers[i];

        st->bh = qemu_bh_new(timer_hit, st);
        st->ptimer = ptimer_init(st->bh, PTIMER_POLICY_DEFAULT);
        ptimer_set_freq(st->ptimer, t->freq_hz);
        sysbus_init_irq(SYS_BUS_DEVICE(obj), &st->irq);
    }

    memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, TYPE_MSS_TIMER,
                          NUM_TIMERS * R_TIM1_MAX * 4);
    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &t->mmio);
}

static const VMStateDescription vmstate_timers = {
    .name = "mss-timer-block",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_PTIMER(ptimer, struct Msf2Timer),
        VMSTATE_UINT32_ARRAY(regs, struct Msf2Timer, R_TIM1_MAX),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_mss_timer = {
    .name = TYPE_MSS_TIMER,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(freq_hz, MSSTimerState),
        VMSTATE_STRUCT_ARRAY(timers, MSSTimerState, NUM_TIMERS, 0,
                vmstate_timers, struct Msf2Timer),
        VMSTATE_END_OF_LIST()
    }
};

static Property mss_timer_properties[] = {
    /* Libero GUI shows 100Mhz as default for clocks */
    DEFINE_PROP_UINT32("clock-frequency", MSSTimerState, freq_hz,
                      100 * 1000000),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->props = mss_timer_properties;
    dc->vmsd = &vmstate_mss_timer;
}

static const TypeInfo mss_timer_info = {
    .name          = TYPE_MSS_TIMER,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(MSSTimerState),
    .instance_init = mss_timer_init,
    .class_init    = mss_timer_class_init,
};

static void mss_timer_register_types(void)
{
    type_register_static(&mss_timer_info);
}

type_init(mss_timer_register_types)
