/*
 * IMX EPIT Timer
 *
 * Copyright (c) 2008 OK Labs
 * Copyright (c) 2011 NICTA Pty Ltd
 * Originally written by Hans Jiang
 * Updated by Peter Chubb
 * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
 * Updated by Axel Heider
 *
 * This code is licensed under GPL version 2 or later.  See
 * the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "hw/timer/imx_epit.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
#include "hw/misc/imx_ccm.h"
#include "qemu/module.h"
#include "qemu/log.h"

#ifndef DEBUG_IMX_EPIT
#define DEBUG_IMX_EPIT 0
#endif

#define DPRINTF(fmt, args...) \
    do { \
        if (DEBUG_IMX_EPIT) { \
            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_EPIT, \
                                             __func__, ##args); \
        } \
    } while (0)

static const char *imx_epit_reg_name(uint32_t reg)
{
    switch (reg) {
    case 0:
        return "CR";
    case 1:
        return "SR";
    case 2:
        return "LR";
    case 3:
        return "CMP";
    case 4:
        return "CNT";
    default:
        return "[?]";
    }
}

/*
 * Exact clock frequencies vary from board to board.
 * These are typical.
 */
static const IMXClk imx_epit_clocks[] =  {
    CLK_NONE,      /* 00 disabled */
    CLK_IPG,       /* 01 ipg_clk, ~532MHz */
    CLK_IPG_HIGH,  /* 10 ipg_clk_highfreq */
    CLK_32k,       /* 11 ipg_clk_32k -- ~32kHz */
};

/*
 * Update interrupt status
 */
static void imx_epit_update_int(IMXEPITState *s)
{
    if ((s->sr & SR_OCIF) && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
        qemu_irq_raise(s->irq);
    } else {
        qemu_irq_lower(s->irq);
    }
}

static uint32_t imx_epit_get_freq(IMXEPITState *s)
{
    uint32_t clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
    uint32_t prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
    uint32_t f_in = imx_ccm_get_clock_frequency(s->ccm, imx_epit_clocks[clksrc]);
    uint32_t freq = f_in / prescaler;
    DPRINTF("ptimer frequency is %u\n", freq);
    return freq;
}

/*
 * This is called both on hardware (device) reset and software reset.
 */
static void imx_epit_reset(IMXEPITState *s, bool is_hard_reset)
{
    /* Soft reset doesn't touch some bits; hard reset clears them */
    if (is_hard_reset) {
        s->cr = 0;
    } else {
        s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
    }
    s->sr = 0;
    s->lr = EPIT_TIMER_MAX;
    s->cmp = 0;
    ptimer_transaction_begin(s->timer_cmp);
    ptimer_transaction_begin(s->timer_reload);

    /*
     * The reset switches off the input clock, so even if the CR.EN is still
     * set, the timers are no longer running.
     */
    assert(imx_epit_get_freq(s) == 0);
    ptimer_stop(s->timer_cmp);
    ptimer_stop(s->timer_reload);
    /* init both timers to EPIT_TIMER_MAX */
    ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
    ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
    ptimer_transaction_commit(s->timer_cmp);
    ptimer_transaction_commit(s->timer_reload);
}

static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
{
    IMXEPITState *s = IMX_EPIT(opaque);
    uint32_t reg_value = 0;

    switch (offset >> 2) {
    case 0: /* Control Register */
        reg_value = s->cr;
        break;

    case 1: /* Status Register */
        reg_value = s->sr;
        break;

    case 2: /* LR - ticks*/
        reg_value = s->lr;
        break;

    case 3: /* CMP */
        reg_value = s->cmp;
        break;

    case 4: /* CNT */
        reg_value = ptimer_get_count(s->timer_reload);
        break;

    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
                      HWADDR_PRIx "\n", TYPE_IMX_EPIT, __func__, offset);
        break;
    }

    DPRINTF("(%s) = 0x%08x\n", imx_epit_reg_name(offset >> 2), reg_value);

    return reg_value;
}

/*
 * Must be called from a ptimer_transaction_begin/commit block for
 * s->timer_cmp, but outside of a transaction block of s->timer_reload,
 * so the proper counter value is read.
 */
static void imx_epit_update_compare_timer(IMXEPITState *s)
{
    uint64_t counter = 0;
    bool is_oneshot = false;
    /*
     * The compare timer only has to run if the timer peripheral is active
     * and there is an input clock, Otherwise it can be switched off.
     */
    bool is_active = (s->cr & CR_EN) && imx_epit_get_freq(s);
    if (is_active) {
        /*
         * Calculate next timeout for compare timer. Reading the reload
         * counter returns proper results only if pending transactions
         * on it are committed here. Otherwise stale values are be read.
         */
        counter = ptimer_get_count(s->timer_reload);
        uint64_t limit = ptimer_get_limit(s->timer_cmp);
        /*
         * The compare timer is a periodic timer if the limit is at least
         * the compare value. Otherwise it may fire at most once in the
         * current round.
         */
        is_oneshot = (limit < s->cmp);
        if (counter >= s->cmp) {
            /* The compare timer fires in the current round. */
            counter -= s->cmp;
        } else if (!is_oneshot) {
            /*
             * The compare timer fires after a reload, as it is below the
             * compare value already in this round. Note that the counter
             * value calculated below can be above the 32-bit limit, which
             * is legal here because the compare timer is an internal
             * helper ptimer only.
             */
            counter += limit - s->cmp;
        } else {
            /*
             * The compare timer won't fire in this round, and the limit is
             * set to a value below the compare value. This practically means
             * it will never fire, so it can be switched off.
             */
            is_active = false;
        }
    }

    /*
     * Set the compare timer and let it run, or stop it. This is agnostic
     * of CR.OCIEN bit, as this bit affects interrupt generation only. The
     * compare timer needs to run even if no interrupts are to be generated,
     * because the SR.OCIF bit must be updated also.
     * Note that the timer might already be stopped or be running with
     * counter values. However, finding out when an update is needed and
     * when not is not trivial. It's much easier applying the setting again,
     * as this does not harm either and the overhead is negligible.
     */
    if (is_active) {
        ptimer_set_count(s->timer_cmp, counter);
        ptimer_run(s->timer_cmp, is_oneshot ? 1 : 0);
    } else {
        ptimer_stop(s->timer_cmp);
    }

}

static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
{
    uint32_t oldcr = s->cr;

    s->cr = value & 0x03ffffff;

    if (s->cr & CR_SWR) {
        /*
         * Reset clears CR.SWR again. It does not touch CR.EN, but the timers
         * are still stopped because the input clock is disabled.
         */
        imx_epit_reset(s, false);
    } else {
        uint32_t freq;
        uint32_t toggled_cr_bits = oldcr ^ s->cr;
        /* re-initialize the limits if CR.RLD has changed */
        bool set_limit = toggled_cr_bits & CR_RLD;
        /* set the counter if the timer got just enabled and CR.ENMOD is set */
        bool is_switched_on = (toggled_cr_bits & s->cr) & CR_EN;
        bool set_counter = is_switched_on && (s->cr & CR_ENMOD);

        ptimer_transaction_begin(s->timer_cmp);
        ptimer_transaction_begin(s->timer_reload);
        freq = imx_epit_get_freq(s);
        if (freq) {
            ptimer_set_freq(s->timer_reload, freq);
            ptimer_set_freq(s->timer_cmp, freq);
        }

        if (set_limit || set_counter) {
            uint64_t limit = (s->cr & CR_RLD) ? s->lr : EPIT_TIMER_MAX;
            ptimer_set_limit(s->timer_reload, limit, set_counter ? 1 : 0);
            if (set_limit) {
                ptimer_set_limit(s->timer_cmp, limit, 0);
            }
        }
        /*
         * If there is an input clock and the peripheral is enabled, then
         * ensure the wall clock timer is ticking. Otherwise stop the timers.
         * The compare timer will be updated later.
         */
        if (freq && (s->cr & CR_EN)) {
            ptimer_run(s->timer_reload, 0);
        } else {
            ptimer_stop(s->timer_reload);
        }
        /* Commit changes to reload timer, so they can propagate. */
        ptimer_transaction_commit(s->timer_reload);
        /* Update compare timer based on the committed reload timer value. */
        imx_epit_update_compare_timer(s);
        ptimer_transaction_commit(s->timer_cmp);
    }

    /*
     * The interrupt state can change due to:
     * - reset clears both SR.OCIF and CR.OCIE
     * - write to CR.EN or CR.OCIE
     */
    imx_epit_update_int(s);
}

static void imx_epit_write_sr(IMXEPITState *s, uint32_t value)
{
    /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
    if (value & SR_OCIF) {
        s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
        imx_epit_update_int(s);
    }
}

static void imx_epit_write_lr(IMXEPITState *s, uint32_t value)
{
    s->lr = value;

    ptimer_transaction_begin(s->timer_cmp);
    ptimer_transaction_begin(s->timer_reload);
    if (s->cr & CR_RLD) {
        /* Also set the limit if the LRD bit is set */
        /* If IOVW bit is set then set the timer value */
        ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
        ptimer_set_limit(s->timer_cmp, s->lr, 0);
    } else if (s->cr & CR_IOVW) {
        /* If IOVW bit is set then set the timer value */
        ptimer_set_count(s->timer_reload, s->lr);
    }
    /* Commit the changes to s->timer_reload, so they can propagate. */
    ptimer_transaction_commit(s->timer_reload);
    /* Update the compare timer based on the committed reload timer value. */
    imx_epit_update_compare_timer(s);
    ptimer_transaction_commit(s->timer_cmp);
}

static void imx_epit_write_cmp(IMXEPITState *s, uint32_t value)
{
    s->cmp = value;

    /* Update the compare timer based on the committed reload timer value. */
    ptimer_transaction_begin(s->timer_cmp);
    imx_epit_update_compare_timer(s);
    ptimer_transaction_commit(s->timer_cmp);
}

static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
                           unsigned size)
{
    IMXEPITState *s = IMX_EPIT(opaque);

    DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(offset >> 2),
            (uint32_t)value);

    switch (offset >> 2) {
    case 0: /* CR */
        imx_epit_write_cr(s, (uint32_t)value);
        break;

    case 1: /* SR */
        imx_epit_write_sr(s, (uint32_t)value);
        break;

    case 2: /* LR */
        imx_epit_write_lr(s, (uint32_t)value);
        break;

    case 3: /* CMP */
        imx_epit_write_cmp(s, (uint32_t)value);
        break;

    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
                      HWADDR_PRIx "\n", TYPE_IMX_EPIT, __func__, offset);
        break;
    }
}

static void imx_epit_cmp(void *opaque)
{
    IMXEPITState *s = IMX_EPIT(opaque);

    /* The cmp ptimer can't be running when the peripheral is disabled */
    assert(s->cr & CR_EN);

    DPRINTF("sr was %d\n", s->sr);
    /* Set interrupt status bit SR.OCIF and update the interrupt state */
    s->sr |= SR_OCIF;
    imx_epit_update_int(s);
}

static void imx_epit_reload(void *opaque)
{
    /* No action required on rollover of timer_reload */
}

static const MemoryRegionOps imx_epit_ops = {
    .read = imx_epit_read,
    .write = imx_epit_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static const VMStateDescription vmstate_imx_timer_epit = {
    .name = TYPE_IMX_EPIT,
    .version_id = 3,
    .minimum_version_id = 3,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32(cr, IMXEPITState),
        VMSTATE_UINT32(sr, IMXEPITState),
        VMSTATE_UINT32(lr, IMXEPITState),
        VMSTATE_UINT32(cmp, IMXEPITState),
        VMSTATE_PTIMER(timer_reload, IMXEPITState),
        VMSTATE_PTIMER(timer_cmp, IMXEPITState),
        VMSTATE_END_OF_LIST()
    }
};

static void imx_epit_realize(DeviceState *dev, Error **errp)
{
    IMXEPITState *s = IMX_EPIT(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    DPRINTF("\n");

    sysbus_init_irq(sbd, &s->irq);
    memory_region_init_io(&s->iomem, OBJECT(s), &imx_epit_ops, s, TYPE_IMX_EPIT,
                          0x00001000);
    sysbus_init_mmio(sbd, &s->iomem);

    /*
     * The reload timer keeps running when the peripheral is enabled. It is a
     * kind of wall clock that does not generate any interrupts. The callback
     * needs to be provided, but it does nothing as the ptimer already supports
     * all necessary reloading functionality.
     */
    s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_LEGACY);

    /*
     * The compare timer is running only when the peripheral configuration is
     * in a state that will generate compare interrupts.
     */
    s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
}

static void imx_epit_dev_reset(DeviceState *dev)
{
    IMXEPITState *s = IMX_EPIT(dev);
    imx_epit_reset(s, true);
}

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

    dc->realize = imx_epit_realize;
    device_class_set_legacy_reset(dc, imx_epit_dev_reset);
    dc->vmsd = &vmstate_imx_timer_epit;
    dc->desc = "i.MX periodic timer";
}

static const TypeInfo imx_epit_info = {
    .name = TYPE_IMX_EPIT,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IMXEPITState),
    .class_init = imx_epit_class_init,
};

static void imx_epit_register_types(void)
{
    type_register_static(&imx_epit_info);
}

type_init(imx_epit_register_types)
