/*
 * QEMU GRLIB GPTimer Emulator
 *
 * Copyright (c) 2010-2019 AdaCore
 *
 * 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 "hw/sparc/grlib.h"
#include "hw/sysbus.h"
#include "qemu/timer.h"
#include "hw/irq.h"
#include "hw/ptimer.h"
#include "hw/qdev-properties.h"
#include "qemu/module.h"

#include "trace.h"

#define UNIT_REG_SIZE    16     /* Size of memory mapped regs for the unit */
#define GPTIMER_REG_SIZE 16     /* Size of memory mapped regs for a GPTimer */

#define GPTIMER_MAX_TIMERS 8

/* GPTimer Config register fields */
#define GPTIMER_ENABLE      (1 << 0)
#define GPTIMER_RESTART     (1 << 1)
#define GPTIMER_LOAD        (1 << 2)
#define GPTIMER_INT_ENABLE  (1 << 3)
#define GPTIMER_INT_PENDING (1 << 4)
#define GPTIMER_CHAIN       (1 << 5) /* Not supported */
#define GPTIMER_DEBUG_HALT  (1 << 6) /* Not supported */

/* Memory mapped register offsets */
#define SCALER_OFFSET         0x00
#define SCALER_RELOAD_OFFSET  0x04
#define CONFIG_OFFSET         0x08
#define COUNTER_OFFSET        0x00
#define COUNTER_RELOAD_OFFSET 0x04
#define TIMER_BASE            0x10

#define GRLIB_GPTIMER(obj) \
    OBJECT_CHECK(GPTimerUnit, (obj), TYPE_GRLIB_GPTIMER)

typedef struct GPTimer     GPTimer;
typedef struct GPTimerUnit GPTimerUnit;

struct GPTimer {
    struct ptimer_state *ptimer;

    qemu_irq     irq;
    int          id;
    GPTimerUnit *unit;

    /* registers */
    uint32_t counter;
    uint32_t reload;
    uint32_t config;
};

struct GPTimerUnit {
    SysBusDevice  parent_obj;

    MemoryRegion iomem;

    uint32_t nr_timers;         /* Number of timers available */
    uint32_t freq_hz;           /* System frequency */
    uint32_t irq_line;          /* Base irq line */

    GPTimer *timers;

    /* registers */
    uint32_t scaler;
    uint32_t reload;
    uint32_t config;
};

static void grlib_gptimer_tx_begin(GPTimer *timer)
{
    ptimer_transaction_begin(timer->ptimer);
}

static void grlib_gptimer_tx_commit(GPTimer *timer)
{
    ptimer_transaction_commit(timer->ptimer);
}

/* Must be called within grlib_gptimer_tx_begin/commit block */
static void grlib_gptimer_enable(GPTimer *timer)
{
    assert(timer != NULL);


    ptimer_stop(timer->ptimer);

    if (!(timer->config & GPTIMER_ENABLE)) {
        /* Timer disabled */
        trace_grlib_gptimer_disabled(timer->id, timer->config);
        return;
    }

    /* ptimer is triggered when the counter reach 0 but GPTimer is triggered at
       underflow. Set count + 1 to simulate the GPTimer behavior. */

    trace_grlib_gptimer_enable(timer->id, timer->counter);

    ptimer_set_count(timer->ptimer, (uint64_t)timer->counter + 1);
    ptimer_run(timer->ptimer, 1);
}

/* Must be called within grlib_gptimer_tx_begin/commit block */
static void grlib_gptimer_restart(GPTimer *timer)
{
    assert(timer != NULL);

    trace_grlib_gptimer_restart(timer->id, timer->reload);

    timer->counter = timer->reload;
    grlib_gptimer_enable(timer);
}

static void grlib_gptimer_set_scaler(GPTimerUnit *unit, uint32_t scaler)
{
    int i = 0;
    uint32_t value = 0;

    assert(unit != NULL);

    if (scaler > 0) {
        value = unit->freq_hz / (scaler + 1);
    } else {
        value = unit->freq_hz;
    }

    trace_grlib_gptimer_set_scaler(scaler, value);

    for (i = 0; i < unit->nr_timers; i++) {
        ptimer_transaction_begin(unit->timers[i].ptimer);
        ptimer_set_freq(unit->timers[i].ptimer, value);
        ptimer_transaction_commit(unit->timers[i].ptimer);
    }
}

static void grlib_gptimer_hit(void *opaque)
{
    GPTimer *timer = opaque;
    assert(timer != NULL);

    trace_grlib_gptimer_hit(timer->id);

    /* Timer expired */

    if (timer->config & GPTIMER_INT_ENABLE) {
        /* Set the pending bit (only unset by write in the config register) */
        timer->config |= GPTIMER_INT_PENDING;
        qemu_irq_pulse(timer->irq);
    }

    if (timer->config & GPTIMER_RESTART) {
        grlib_gptimer_restart(timer);
    }
}

static uint64_t grlib_gptimer_read(void *opaque, hwaddr addr,
                                   unsigned size)
{
    GPTimerUnit        *unit  = opaque;
    hwaddr  timer_addr;
    int                 id;
    uint32_t            value = 0;

    addr &= 0xff;

    /* Unit registers */
    switch (addr) {
    case SCALER_OFFSET:
        trace_grlib_gptimer_readl(-1, addr, unit->scaler);
        return unit->scaler;

    case SCALER_RELOAD_OFFSET:
        trace_grlib_gptimer_readl(-1, addr, unit->reload);
        return unit->reload;

    case CONFIG_OFFSET:
        trace_grlib_gptimer_readl(-1, addr, unit->config);
        return unit->config;

    default:
        break;
    }

    timer_addr = (addr % TIMER_BASE);
    id         = (addr - TIMER_BASE) / TIMER_BASE;

    if (id >= 0 && id < unit->nr_timers) {

        /* GPTimer registers */
        switch (timer_addr) {
        case COUNTER_OFFSET:
            value = ptimer_get_count(unit->timers[id].ptimer);
            trace_grlib_gptimer_readl(id, addr, value);
            return value;

        case COUNTER_RELOAD_OFFSET:
            value = unit->timers[id].reload;
            trace_grlib_gptimer_readl(id, addr, value);
            return value;

        case CONFIG_OFFSET:
            trace_grlib_gptimer_readl(id, addr, unit->timers[id].config);
            return unit->timers[id].config;

        default:
            break;
        }

    }

    trace_grlib_gptimer_readl(-1, addr, 0);
    return 0;
}

static void grlib_gptimer_write(void *opaque, hwaddr addr,
                                uint64_t value, unsigned size)
{
    GPTimerUnit        *unit = opaque;
    hwaddr  timer_addr;
    int                 id;

    addr &= 0xff;

    /* Unit registers */
    switch (addr) {
    case SCALER_OFFSET:
        value &= 0xFFFF; /* clean up the value */
        unit->scaler = value;
        trace_grlib_gptimer_writel(-1, addr, unit->scaler);
        return;

    case SCALER_RELOAD_OFFSET:
        value &= 0xFFFF; /* clean up the value */
        unit->reload = value;
        trace_grlib_gptimer_writel(-1, addr, unit->reload);
        grlib_gptimer_set_scaler(unit, value);
        return;

    case CONFIG_OFFSET:
        /* Read Only (disable timer freeze not supported) */
        trace_grlib_gptimer_writel(-1, addr, 0);
        return;

    default:
        break;
    }

    timer_addr = (addr % TIMER_BASE);
    id         = (addr - TIMER_BASE) / TIMER_BASE;

    if (id >= 0 && id < unit->nr_timers) {

        /* GPTimer registers */
        switch (timer_addr) {
        case COUNTER_OFFSET:
            trace_grlib_gptimer_writel(id, addr, value);
            grlib_gptimer_tx_begin(&unit->timers[id]);
            unit->timers[id].counter = value;
            grlib_gptimer_enable(&unit->timers[id]);
            grlib_gptimer_tx_commit(&unit->timers[id]);
            return;

        case COUNTER_RELOAD_OFFSET:
            trace_grlib_gptimer_writel(id, addr, value);
            unit->timers[id].reload = value;
            return;

        case CONFIG_OFFSET:
            trace_grlib_gptimer_writel(id, addr, value);

            if (value & GPTIMER_INT_PENDING) {
                /* clear pending bit */
                value &= ~GPTIMER_INT_PENDING;
            } else {
                /* keep pending bit */
                value |= unit->timers[id].config & GPTIMER_INT_PENDING;
            }

            unit->timers[id].config = value;

            /* gptimer_restart calls gptimer_enable, so if "enable" and "load"
               bits are present, we just have to call restart. */

            grlib_gptimer_tx_begin(&unit->timers[id]);
            if (value & GPTIMER_LOAD) {
                grlib_gptimer_restart(&unit->timers[id]);
            } else if (value & GPTIMER_ENABLE) {
                grlib_gptimer_enable(&unit->timers[id]);
            }

            /* These fields must always be read as 0 */
            value &= ~(GPTIMER_LOAD & GPTIMER_DEBUG_HALT);

            unit->timers[id].config = value;
            grlib_gptimer_tx_commit(&unit->timers[id]);
            return;

        default:
            break;
        }

    }

    trace_grlib_gptimer_writel(-1, addr, value);
}

static const MemoryRegionOps grlib_gptimer_ops = {
    .read = grlib_gptimer_read,
    .write = grlib_gptimer_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void grlib_gptimer_reset(DeviceState *d)
{
    GPTimerUnit *unit = GRLIB_GPTIMER(d);
    int          i    = 0;

    assert(unit != NULL);

    unit->scaler = 0;
    unit->reload = 0;

    unit->config  = unit->nr_timers;
    unit->config |= unit->irq_line << 3;
    unit->config |= 1 << 8;     /* separate interrupt */
    unit->config |= 1 << 9;     /* Disable timer freeze */


    for (i = 0; i < unit->nr_timers; i++) {
        GPTimer *timer = &unit->timers[i];

        timer->counter = 0;
        timer->reload = 0;
        timer->config = 0;
        ptimer_transaction_begin(timer->ptimer);
        ptimer_stop(timer->ptimer);
        ptimer_set_count(timer->ptimer, 0);
        ptimer_set_freq(timer->ptimer, unit->freq_hz);
        ptimer_transaction_commit(timer->ptimer);
    }
}

static void grlib_gptimer_realize(DeviceState *dev, Error **errp)
{
    GPTimerUnit  *unit = GRLIB_GPTIMER(dev);
    unsigned int  i;
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    assert(unit->nr_timers > 0);
    assert(unit->nr_timers <= GPTIMER_MAX_TIMERS);

    unit->timers = g_malloc0(sizeof unit->timers[0] * unit->nr_timers);

    for (i = 0; i < unit->nr_timers; i++) {
        GPTimer *timer = &unit->timers[i];

        timer->unit   = unit;
        timer->ptimer = ptimer_init(grlib_gptimer_hit, timer,
                                    PTIMER_POLICY_DEFAULT);
        timer->id     = i;

        /* One IRQ line for each timer */
        sysbus_init_irq(sbd, &timer->irq);

        ptimer_transaction_begin(timer->ptimer);
        ptimer_set_freq(timer->ptimer, unit->freq_hz);
        ptimer_transaction_commit(timer->ptimer);
    }

    memory_region_init_io(&unit->iomem, OBJECT(unit), &grlib_gptimer_ops,
                          unit, "gptimer",
                          UNIT_REG_SIZE + GPTIMER_REG_SIZE * unit->nr_timers);

    sysbus_init_mmio(sbd, &unit->iomem);
}

static Property grlib_gptimer_properties[] = {
    DEFINE_PROP_UINT32("frequency", GPTimerUnit, freq_hz,   40000000),
    DEFINE_PROP_UINT32("irq-line",  GPTimerUnit, irq_line,  8),
    DEFINE_PROP_UINT32("nr-timers", GPTimerUnit, nr_timers, 2),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->realize = grlib_gptimer_realize;
    dc->reset = grlib_gptimer_reset;
    device_class_set_props(dc, grlib_gptimer_properties);
}

static const TypeInfo grlib_gptimer_info = {
    .name          = TYPE_GRLIB_GPTIMER,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(GPTimerUnit),
    .class_init    = grlib_gptimer_class_init,
};

static void grlib_gptimer_register_types(void)
{
    type_register_static(&grlib_gptimer_info);
}

type_init(grlib_gptimer_register_types)
