/*
 * QEMU GRLIB GPTimer Emulator
 *
 * SPDX-License-Identifier: MIT
 *
 * Copyright (c) 2010-2024 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/timer/grlib_gptimer.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"
#include "qom/object.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

OBJECT_DECLARE_SIMPLE_TYPE(GPTimerUnit, GRLIB_GPTIMER)

typedef struct GPTimer     GPTimer;

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_LEGACY);
        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)
