/*
 * QEMU model of the Canon DIGIC timer block.
 *
 * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
 *
 * This model is based on reverse engineering efforts
 * made by CHDK (http://chdk.wikia.com) and
 * Magic Lantern (http://www.magiclantern.fm) projects
 * contributors.
 *
 * See "Timer/Clock Module" docs here:
 *   http://magiclantern.wikia.com/wiki/Register_Map
 *
 * The QEMU model of the OSTimer in PKUnity SoC by Guan Xuetao
 * is used as a template.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 */

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "hw/ptimer.h"
#include "qemu/module.h"
#include "qemu/log.h"

#include "hw/timer/digic-timer.h"
#include "migration/vmstate.h"

static const VMStateDescription vmstate_digic_timer = {
    .name = "digic.timer",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_PTIMER(ptimer, DigicTimerState),
        VMSTATE_UINT32(control, DigicTimerState),
        VMSTATE_UINT32(relvalue, DigicTimerState),
        VMSTATE_END_OF_LIST()
    }
};

static void digic_timer_reset(DeviceState *dev)
{
    DigicTimerState *s = DIGIC_TIMER(dev);

    ptimer_transaction_begin(s->ptimer);
    ptimer_stop(s->ptimer);
    ptimer_transaction_commit(s->ptimer);
    s->control = 0;
    s->relvalue = 0;
}

static uint64_t digic_timer_read(void *opaque, hwaddr offset, unsigned size)
{
    DigicTimerState *s = opaque;
    uint64_t ret = 0;

    switch (offset) {
    case DIGIC_TIMER_CONTROL:
        ret = s->control;
        break;
    case DIGIC_TIMER_RELVALUE:
        ret = s->relvalue;
        break;
    case DIGIC_TIMER_VALUE:
        ret = ptimer_get_count(s->ptimer) & 0xffff;
        break;
    default:
        qemu_log_mask(LOG_UNIMP,
                      "digic-timer: read access to unknown register 0x"
                      HWADDR_FMT_plx "\n", offset);
    }

    return ret;
}

static void digic_timer_write(void *opaque, hwaddr offset,
                              uint64_t value, unsigned size)
{
    DigicTimerState *s = opaque;

    switch (offset) {
    case DIGIC_TIMER_CONTROL:
        if (value & DIGIC_TIMER_CONTROL_RST) {
            digic_timer_reset((DeviceState *)s);
            break;
        }

        ptimer_transaction_begin(s->ptimer);
        if (value & DIGIC_TIMER_CONTROL_EN) {
            ptimer_run(s->ptimer, 0);
        }

        s->control = (uint32_t)value;
        ptimer_transaction_commit(s->ptimer);
        break;

    case DIGIC_TIMER_RELVALUE:
        s->relvalue = extract32(value, 0, 16);
        ptimer_transaction_begin(s->ptimer);
        ptimer_set_limit(s->ptimer, s->relvalue, 1);
        ptimer_transaction_commit(s->ptimer);
        break;

    case DIGIC_TIMER_VALUE:
        break;

    default:
        qemu_log_mask(LOG_UNIMP,
                      "digic-timer: read access to unknown register 0x"
                      HWADDR_FMT_plx "\n", offset);
    }
}

static const MemoryRegionOps digic_timer_ops = {
    .read = digic_timer_read,
    .write = digic_timer_write,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void digic_timer_tick(void *opaque)
{
    /* Nothing to do on timer rollover */
}

static void digic_timer_init(Object *obj)
{
    DigicTimerState *s = DIGIC_TIMER(obj);

    s->ptimer = ptimer_init(digic_timer_tick, NULL, PTIMER_POLICY_LEGACY);

    /*
     * FIXME: there is no documentation on Digic timer
     * frequency setup so let it always run at 1 MHz
     */
    ptimer_transaction_begin(s->ptimer);
    ptimer_set_freq(s->ptimer, 1 * 1000 * 1000);
    ptimer_transaction_commit(s->ptimer);

    memory_region_init_io(&s->iomem, OBJECT(s), &digic_timer_ops, s,
                          TYPE_DIGIC_TIMER, 0x100);
    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
}

static void digic_timer_finalize(Object *obj)
{
    DigicTimerState *s = DIGIC_TIMER(obj);

    ptimer_free(s->ptimer);
}

static void digic_timer_class_init(ObjectClass *klass, void *class_data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    device_class_set_legacy_reset(dc, digic_timer_reset);
    dc->vmsd = &vmstate_digic_timer;
}

static const TypeInfo digic_timer_info = {
    .name = TYPE_DIGIC_TIMER,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(DigicTimerState),
    .instance_init = digic_timer_init,
    .instance_finalize = digic_timer_finalize,
    .class_init = digic_timer_class_init,
};

static void digic_timer_register_type(void)
{
    type_register_static(&digic_timer_info);
}

type_init(digic_timer_register_type)
