/*
 * IMX GPT 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>
 *
 * 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/irq.h"
#include "hw/timer/imx_gpt.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "qemu/log.h"

#ifndef DEBUG_IMX_GPT
#define DEBUG_IMX_GPT 0
#endif

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

static const char *imx_gpt_reg_name(uint32_t reg)
{
    switch (reg) {
    case 0:
        return "CR";
    case 1:
        return "PR";
    case 2:
        return "SR";
    case 3:
        return "IR";
    case 4:
        return "OCR1";
    case 5:
        return "OCR2";
    case 6:
        return "OCR3";
    case 7:
        return "ICR1";
    case 8:
        return "ICR2";
    case 9:
        return "CNT";
    default:
        return "[?]";
    }
}

static const VMStateDescription vmstate_imx_timer_gpt = {
    .name = TYPE_IMX_GPT,
    .version_id = 3,
    .minimum_version_id = 3,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(cr, IMXGPTState),
        VMSTATE_UINT32(pr, IMXGPTState),
        VMSTATE_UINT32(sr, IMXGPTState),
        VMSTATE_UINT32(ir, IMXGPTState),
        VMSTATE_UINT32(ocr1, IMXGPTState),
        VMSTATE_UINT32(ocr2, IMXGPTState),
        VMSTATE_UINT32(ocr3, IMXGPTState),
        VMSTATE_UINT32(icr1, IMXGPTState),
        VMSTATE_UINT32(icr2, IMXGPTState),
        VMSTATE_UINT32(cnt, IMXGPTState),
        VMSTATE_UINT32(next_timeout, IMXGPTState),
        VMSTATE_UINT32(next_int, IMXGPTState),
        VMSTATE_UINT32(freq, IMXGPTState),
        VMSTATE_PTIMER(timer, IMXGPTState),
        VMSTATE_END_OF_LIST()
    }
};

static const IMXClk imx25_gpt_clocks[] = {
    CLK_NONE,      /* 000 No clock source */
    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    CLK_NONE,      /* 011 not defined */
    CLK_32k,       /* 100 ipg_clk_32k */
    CLK_32k,       /* 101 ipg_clk_32k */
    CLK_32k,       /* 110 ipg_clk_32k */
    CLK_32k,       /* 111 ipg_clk_32k */
};

static const IMXClk imx31_gpt_clocks[] = {
    CLK_NONE,      /* 000 No clock source */
    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    CLK_NONE,      /* 011 not defined */
    CLK_32k,       /* 100 ipg_clk_32k */
    CLK_NONE,      /* 101 not defined */
    CLK_NONE,      /* 110 not defined */
    CLK_NONE,      /* 111 not defined */
};

static const IMXClk imx6_gpt_clocks[] = {
    CLK_NONE,      /* 000 No clock source */
    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    CLK_EXT,       /* 011 External clock */
    CLK_32k,       /* 100 ipg_clk_32k */
    CLK_HIGH_DIV,  /* 101 reference clock / 8 */
    CLK_NONE,      /* 110 not defined */
    CLK_HIGH,      /* 111 reference clock */
};

static const IMXClk imx6ul_gpt_clocks[] = {
    CLK_NONE,      /* 000 No clock source */
    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    CLK_EXT,       /* 011 External clock */
    CLK_32k,       /* 100 ipg_clk_32k */
    CLK_NONE,      /* 101 not defined */
    CLK_NONE,      /* 110 not defined */
    CLK_NONE,      /* 111 not defined */
};

static const IMXClk imx7_gpt_clocks[] = {
    CLK_NONE,      /* 000 No clock source */
    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    CLK_EXT,       /* 011 External clock */
    CLK_32k,       /* 100 ipg_clk_32k */
    CLK_HIGH,      /* 101 reference clock */
    CLK_NONE,      /* 110 not defined */
    CLK_NONE,      /* 111 not defined */
};

/* Must be called from within ptimer_transaction_begin/commit block */
static void imx_gpt_set_freq(IMXGPTState *s)
{
    uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);

    s->freq = imx_ccm_get_clock_frequency(s->ccm,
                                          s->clocks[clksrc]) / (1 + s->pr);

    DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq);

    if (s->freq) {
        ptimer_set_freq(s->timer, s->freq);
    }
}

static void imx_gpt_update_int(IMXGPTState *s)
{
    if ((s->sr & s->ir) && (s->cr & GPT_CR_EN)) {
        qemu_irq_raise(s->irq);
    } else {
        qemu_irq_lower(s->irq);
    }
}

static uint32_t imx_gpt_update_count(IMXGPTState *s)
{
    s->cnt = s->next_timeout - (uint32_t)ptimer_get_count(s->timer);

    return s->cnt;
}

static inline uint32_t imx_gpt_find_limit(uint32_t count, uint32_t reg,
                                          uint32_t timeout)
{
    if ((count < reg) && (timeout > reg)) {
        timeout = reg;
    }

    return timeout;
}

/* Must be called from within ptimer_transaction_begin/commit block */
static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
{
    uint32_t timeout = GPT_TIMER_MAX;
    uint32_t count;
    long long limit;

    if (!(s->cr & GPT_CR_EN)) {
        /* if not enabled just return */
        return;
    }

    /* update the count */
    count = imx_gpt_update_count(s);

    if (event) {
        /*
         * This is an event (the ptimer reached 0 and stopped), and the
         * timer counter is now equal to s->next_timeout.
         */
        if (!(s->cr & GPT_CR_FRR) && (count == s->ocr1)) {
            /* We are in restart mode and we crossed the compare channel 1
             * value. We need to reset the counter to 0.
             */
            count = s->cnt = s->next_timeout = 0;
        } else if (count == GPT_TIMER_MAX) {
            /* We reached GPT_TIMER_MAX so we need to rollover */
            count = s->cnt = s->next_timeout = 0;
        }
    }

    /* now, find the next timeout related to count */

    if (s->ir & GPT_IR_OF1IE) {
        timeout = imx_gpt_find_limit(count, s->ocr1, timeout);
    }
    if (s->ir & GPT_IR_OF2IE) {
        timeout = imx_gpt_find_limit(count, s->ocr2, timeout);
    }
    if (s->ir & GPT_IR_OF3IE) {
        timeout = imx_gpt_find_limit(count, s->ocr3, timeout);
    }

    /* find the next set of interrupts to raise for next timer event */

    s->next_int = 0;
    if ((s->ir & GPT_IR_OF1IE) && (timeout == s->ocr1)) {
        s->next_int |= GPT_SR_OF1;
    }
    if ((s->ir & GPT_IR_OF2IE) && (timeout == s->ocr2)) {
        s->next_int |= GPT_SR_OF2;
    }
    if ((s->ir & GPT_IR_OF3IE) && (timeout == s->ocr3)) {
        s->next_int |= GPT_SR_OF3;
    }
    if ((s->ir & GPT_IR_ROVIE) && (timeout == GPT_TIMER_MAX)) {
        s->next_int |= GPT_SR_ROV;
    }

    /* the new range to count down from */
    limit = timeout - imx_gpt_update_count(s);

    if (limit < 0) {
        /*
         * if we reach here, then QEMU is running too slow and we pass the
         * timeout limit while computing it. Let's deliver the interrupt
         * and compute a new limit.
         */
        s->sr |= s->next_int;

        imx_gpt_compute_next_timeout(s, event);

        imx_gpt_update_int(s);
    } else {
        /* New timeout value */
        s->next_timeout = timeout;

        /* reset the limit to the computed range */
        ptimer_set_limit(s->timer, limit, 1);
    }
}

static uint64_t imx_gpt_read(void *opaque, hwaddr offset, unsigned size)
{
    IMXGPTState *s = IMX_GPT(opaque);
    uint32_t reg_value = 0;

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

    case 1: /* prescaler */
        reg_value = s->pr;
        break;

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

    case 3: /* Interrupt Register */
        reg_value = s->ir;
        break;

    case 4: /* Output Compare Register 1 */
        reg_value = s->ocr1;
        break;

    case 5: /* Output Compare Register 2 */
        reg_value = s->ocr2;
        break;

    case 6: /* Output Compare Register 3 */
        reg_value = s->ocr3;
        break;

    case 7: /* input Capture Register 1 */
        qemu_log_mask(LOG_UNIMP, "[%s]%s: icr1 feature is not implemented\n",
                      TYPE_IMX_GPT, __func__);
        reg_value = s->icr1;
        break;

    case 8: /* input Capture Register 2 */
        qemu_log_mask(LOG_UNIMP, "[%s]%s: icr2 feature is not implemented\n",
                      TYPE_IMX_GPT, __func__);
        reg_value = s->icr2;
        break;

    case 9: /* cnt */
        imx_gpt_update_count(s);
        reg_value = s->cnt;
        break;

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

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

    return reg_value;
}


static void imx_gpt_reset_common(IMXGPTState *s, bool is_soft_reset)
{
    ptimer_transaction_begin(s->timer);
    /* stop timer */
    ptimer_stop(s->timer);

    /* Soft reset and hard reset differ only in their handling of the CR
     * register -- soft reset preserves the values of some bits there.
     */
    if (is_soft_reset) {
        /* Clear all CR bits except those that are preserved by soft reset. */
        s->cr &= GPT_CR_EN | GPT_CR_ENMOD | GPT_CR_STOPEN | GPT_CR_DOZEN |
            GPT_CR_WAITEN | GPT_CR_DBGEN |
            (GPT_CR_CLKSRC_MASK << GPT_CR_CLKSRC_SHIFT);
    } else {
        s->cr = 0;
    }
    s->sr = 0;
    s->pr = 0;
    s->ir = 0;
    s->cnt = 0;
    s->ocr1 = GPT_TIMER_MAX;
    s->ocr2 = GPT_TIMER_MAX;
    s->ocr3 = GPT_TIMER_MAX;
    s->icr1 = 0;
    s->icr2 = 0;

    s->next_timeout = GPT_TIMER_MAX;
    s->next_int = 0;

    /* compute new freq */
    imx_gpt_set_freq(s);

    /* reset the limit to GPT_TIMER_MAX */
    ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1);

    /* if the timer is still enabled, restart it */
    if (s->freq && (s->cr & GPT_CR_EN)) {
        ptimer_run(s->timer, 1);
    }
    ptimer_transaction_commit(s->timer);
}

static void imx_gpt_soft_reset(DeviceState *dev)
{
    IMXGPTState *s = IMX_GPT(dev);
    imx_gpt_reset_common(s, true);
}

static void imx_gpt_reset(DeviceState *dev)
{
    IMXGPTState *s = IMX_GPT(dev);
    imx_gpt_reset_common(s, false);
}

static void imx_gpt_write(void *opaque, hwaddr offset, uint64_t value,
                          unsigned size)
{
    IMXGPTState *s = IMX_GPT(opaque);
    uint32_t oldreg;

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

    switch (offset >> 2) {
    case 0:
        oldreg = s->cr;
        s->cr = value & ~0x7c14;
        if (s->cr & GPT_CR_SWR) { /* force reset */
            /* handle the reset */
            imx_gpt_soft_reset(DEVICE(s));
        } else {
            /* set our freq, as the source might have changed */
            ptimer_transaction_begin(s->timer);
            imx_gpt_set_freq(s);

            if ((oldreg ^ s->cr) & GPT_CR_EN) {
                if (s->cr & GPT_CR_EN) {
                    if (s->cr & GPT_CR_ENMOD) {
                        s->next_timeout = GPT_TIMER_MAX;
                        ptimer_set_count(s->timer, GPT_TIMER_MAX);
                        imx_gpt_compute_next_timeout(s, false);
                    }
                    ptimer_run(s->timer, 1);
                } else {
                    /* stop timer */
                    ptimer_stop(s->timer);
                }
            }
            ptimer_transaction_commit(s->timer);
        }
        break;

    case 1: /* Prescaler */
        s->pr = value & 0xfff;
        ptimer_transaction_begin(s->timer);
        imx_gpt_set_freq(s);
        ptimer_transaction_commit(s->timer);
        break;

    case 2: /* SR */
        s->sr &= ~(value & 0x3f);
        imx_gpt_update_int(s);
        break;

    case 3: /* IR -- interrupt register */
        s->ir = value & 0x3f;
        imx_gpt_update_int(s);

        ptimer_transaction_begin(s->timer);
        imx_gpt_compute_next_timeout(s, false);
        ptimer_transaction_commit(s->timer);

        break;

    case 4: /* OCR1 -- output compare register */
        s->ocr1 = value;

        ptimer_transaction_begin(s->timer);
        /* In non-freerun mode, reset count when this register is written */
        if (!(s->cr & GPT_CR_FRR)) {
            s->next_timeout = GPT_TIMER_MAX;
            ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1);
        }

        /* compute the new timeout */
        imx_gpt_compute_next_timeout(s, false);
        ptimer_transaction_commit(s->timer);

        break;

    case 5: /* OCR2 -- output compare register */
        s->ocr2 = value;

        /* compute the new timeout */
        ptimer_transaction_begin(s->timer);
        imx_gpt_compute_next_timeout(s, false);
        ptimer_transaction_commit(s->timer);

        break;

    case 6: /* OCR3 -- output compare register */
        s->ocr3 = value;

        /* compute the new timeout */
        ptimer_transaction_begin(s->timer);
        imx_gpt_compute_next_timeout(s, false);
        ptimer_transaction_commit(s->timer);

        break;

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

static void imx_gpt_timeout(void *opaque)
{
    IMXGPTState *s = IMX_GPT(opaque);

    DPRINTF("\n");

    s->sr |= s->next_int;
    s->next_int = 0;

    imx_gpt_compute_next_timeout(s, true);

    imx_gpt_update_int(s);

    if (s->freq && (s->cr & GPT_CR_EN)) {
        ptimer_run(s->timer, 1);
    }
}

static const MemoryRegionOps imx_gpt_ops = {
    .read = imx_gpt_read,
    .write = imx_gpt_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};


static void imx_gpt_realize(DeviceState *dev, Error **errp)
{
    IMXGPTState *s = IMX_GPT(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

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

    s->timer = ptimer_init(imx_gpt_timeout, s, PTIMER_POLICY_LEGACY);
}

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

    dc->realize = imx_gpt_realize;
    dc->reset = imx_gpt_reset;
    dc->vmsd = &vmstate_imx_timer_gpt;
    dc->desc = "i.MX general timer";
}

static void imx25_gpt_init(Object *obj)
{
    IMXGPTState *s = IMX_GPT(obj);

    s->clocks = imx25_gpt_clocks;
}

static void imx31_gpt_init(Object *obj)
{
    IMXGPTState *s = IMX_GPT(obj);

    s->clocks = imx31_gpt_clocks;
}

static void imx6_gpt_init(Object *obj)
{
    IMXGPTState *s = IMX_GPT(obj);

    s->clocks = imx6_gpt_clocks;
}

static void imx6ul_gpt_init(Object *obj)
{
    IMXGPTState *s = IMX_GPT(obj);

    s->clocks = imx6ul_gpt_clocks;
}

static void imx7_gpt_init(Object *obj)
{
    IMXGPTState *s = IMX_GPT(obj);

    s->clocks = imx7_gpt_clocks;
}

static const TypeInfo imx25_gpt_info = {
    .name = TYPE_IMX25_GPT,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IMXGPTState),
    .instance_init = imx25_gpt_init,
    .class_init = imx_gpt_class_init,
};

static const TypeInfo imx31_gpt_info = {
    .name = TYPE_IMX31_GPT,
    .parent = TYPE_IMX25_GPT,
    .instance_init = imx31_gpt_init,
};

static const TypeInfo imx6_gpt_info = {
    .name = TYPE_IMX6_GPT,
    .parent = TYPE_IMX25_GPT,
    .instance_init = imx6_gpt_init,
};

static const TypeInfo imx6ul_gpt_info = {
    .name = TYPE_IMX6UL_GPT,
    .parent = TYPE_IMX25_GPT,
    .instance_init = imx6ul_gpt_init,
};

static const TypeInfo imx7_gpt_info = {
    .name = TYPE_IMX7_GPT,
    .parent = TYPE_IMX25_GPT,
    .instance_init = imx7_gpt_init,
};

static void imx_gpt_register_types(void)
{
    type_register_static(&imx25_gpt_info);
    type_register_static(&imx31_gpt_info);
    type_register_static(&imx6_gpt_info);
    type_register_static(&imx6ul_gpt_info);
    type_register_static(&imx7_gpt_info);
}

type_init(imx_gpt_register_types)
