/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2016 Imagination Technologies
 */

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "qemu/timer.h"
#include "hw/timer/mips_gictimer.h"

#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */

uint32_t mips_gictimer_get_freq(MIPSGICTimerState *gic)
{
    return NANOSECONDS_PER_SECOND / TIMER_PERIOD;
}

static void gic_vptimer_update(MIPSGICTimerState *gictimer,
                                   uint32_t vp_index, uint64_t now)
{
    uint64_t next;
    uint32_t wait;

    wait = gictimer->vptimers[vp_index].comparelo - gictimer->sh_counterlo -
           (uint32_t)(now / TIMER_PERIOD);
    next = now + (uint64_t)wait * TIMER_PERIOD;

    timer_mod(gictimer->vptimers[vp_index].qtimer, next);
}

static void gic_vptimer_expire(MIPSGICTimerState *gictimer, uint32_t vp_index,
                               uint64_t now)
{
    if (gictimer->countstop) {
        /* timer stopped */
        return;
    }
    gictimer->cb(gictimer->opaque, vp_index);
    gic_vptimer_update(gictimer, vp_index, now);
}

static void gic_vptimer_cb(void *opaque)
{
    MIPSGICTimerVPState *vptimer = opaque;
    MIPSGICTimerState *gictimer = vptimer->gictimer;
    gic_vptimer_expire(gictimer, vptimer->vp_index,
                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
}

uint32_t mips_gictimer_get_sh_count(MIPSGICTimerState *gictimer)
{
    int i;
    if (gictimer->countstop) {
        return gictimer->sh_counterlo;
    } else {
        uint64_t now;
        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        for (i = 0; i < gictimer->num_vps; i++) {
            if (timer_pending(gictimer->vptimers[i].qtimer)
                && timer_expired(gictimer->vptimers[i].qtimer, now)) {
                /* The timer has already expired.  */
                gic_vptimer_expire(gictimer, i, now);
            }
        }
        return gictimer->sh_counterlo + (uint32_t)(now / TIMER_PERIOD);
    }
}

void mips_gictimer_store_sh_count(MIPSGICTimerState *gictimer, uint64_t count)
{
    int i;
    uint64_t now;

    if (gictimer->countstop || !gictimer->vptimers[0].qtimer) {
        gictimer->sh_counterlo = count;
    } else {
        /* Store new count register */
        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        gictimer->sh_counterlo = count - (uint32_t)(now / TIMER_PERIOD);
        /* Update timer timer */
        for (i = 0; i < gictimer->num_vps; i++) {
            gic_vptimer_update(gictimer, i, now);
        }
    }
}

uint32_t mips_gictimer_get_vp_compare(MIPSGICTimerState *gictimer,
                                      uint32_t vp_index)
{
    return gictimer->vptimers[vp_index].comparelo;
}

void mips_gictimer_store_vp_compare(MIPSGICTimerState *gictimer,
                                    uint32_t vp_index, uint64_t compare)
{
    gictimer->vptimers[vp_index].comparelo = (uint32_t) compare;
    gic_vptimer_update(gictimer, vp_index,
                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
}

uint8_t mips_gictimer_get_countstop(MIPSGICTimerState *gictimer)
{
    return gictimer->countstop;
}

void mips_gictimer_start_count(MIPSGICTimerState *gictimer)
{
    gictimer->countstop = 0;
    mips_gictimer_store_sh_count(gictimer, gictimer->sh_counterlo);
}

void mips_gictimer_stop_count(MIPSGICTimerState *gictimer)
{
    int i;

    gictimer->countstop = 1;
    /* Store the current value */
    gictimer->sh_counterlo +=
        (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD);
    for (i = 0; i < gictimer->num_vps; i++) {
        timer_del(gictimer->vptimers[i].qtimer);
    }
}

MIPSGICTimerState *mips_gictimer_init(void *opaque, uint32_t nvps,
                                      MIPSGICTimerCB *cb)
{
    int i;
    MIPSGICTimerState *gictimer = g_new(MIPSGICTimerState, 1);
    gictimer->vptimers = g_new(MIPSGICTimerVPState, nvps);
    gictimer->countstop = 1;
    gictimer->num_vps = nvps;
    gictimer->opaque = opaque;
    gictimer->cb = cb;
    for (i = 0; i < nvps; i++) {
        gictimer->vptimers[i].gictimer = gictimer;
        gictimer->vptimers[i].vp_index = i;
        gictimer->vptimers[i].qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                            &gic_vptimer_cb,
                                            &gictimer->vptimers[i]);
    }
    return gictimer;
}
