/*
 * Renesas 8bit timer
 *
 * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
 *            (Rev.1.40 R01UH0033EJ0140)
 *
 * Copyright (c) 2019 Yoshinori Sato
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/irq.h"
#include "hw/registerfields.h"
#include "hw/qdev-properties.h"
#include "hw/timer/renesas_tmr.h"
#include "migration/vmstate.h"

REG8(TCR, 0)
  FIELD(TCR, CCLR,  3, 2)
  FIELD(TCR, OVIE,  5, 1)
  FIELD(TCR, CMIEA, 6, 1)
  FIELD(TCR, CMIEB, 7, 1)
REG8(TCSR, 2)
  FIELD(TCSR, OSA,  0, 2)
  FIELD(TCSR, OSB,  2, 2)
  FIELD(TCSR, ADTE, 4, 2)
REG8(TCORA, 4)
REG8(TCORB, 6)
REG8(TCNT, 8)
REG8(TCCR, 10)
  FIELD(TCCR, CKS,   0, 3)
  FIELD(TCCR, CSS,   3, 2)
  FIELD(TCCR, TMRIS, 7, 1)

#define CSS_EXTERNAL  0x00
#define CSS_INTERNAL  0x01
#define CSS_INVALID   0x02
#define CSS_CASCADING 0x03
#define CCLR_A    0x01
#define CCLR_B    0x02

static const int clkdiv[] = {0, 1, 2, 8, 32, 64, 1024, 8192};

static uint8_t concat_reg(uint8_t *reg)
{
    return (reg[0] << 8) | reg[1];
}

static void update_events(RTMRState *tmr, int ch)
{
    uint16_t diff[TMR_NR_EVENTS], min;
    int64_t next_time;
    int i, event;

    if (tmr->tccr[ch] == 0) {
        return ;
    }
    if (FIELD_EX8(tmr->tccr[ch], TCCR, CSS) == 0) {
        /* external clock mode */
        /* event not happened */
        return ;
    }
    if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) == CSS_CASCADING) {
        /* cascading mode */
        if (ch == 1) {
            tmr->next[ch] = none;
            return ;
        }
        diff[cmia] = concat_reg(tmr->tcora) - concat_reg(tmr->tcnt);
        diff[cmib] = concat_reg(tmr->tcorb) - concat_reg(tmr->tcnt);
        diff[ovi] = 0x10000 - concat_reg(tmr->tcnt);
    } else {
        /* separate mode */
        diff[cmia] = tmr->tcora[ch] - tmr->tcnt[ch];
        diff[cmib] = tmr->tcorb[ch] - tmr->tcnt[ch];
        diff[ovi] = 0x100 - tmr->tcnt[ch];
    }
    /* Search for the most recently occurring event. */
    for (event = 0, min = diff[0], i = 1; i < none; i++) {
        if (min > diff[i]) {
            event = i;
            min = diff[i];
        }
    }
    tmr->next[ch] = event;
    next_time = diff[event];
    next_time *= clkdiv[FIELD_EX8(tmr->tccr[ch], TCCR, CKS)];
    next_time *= NANOSECONDS_PER_SECOND;
    next_time /= tmr->input_freq;
    next_time += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    timer_mod(&tmr->timer[ch], next_time);
}

static int elapsed_time(RTMRState *tmr, int ch, int64_t delta)
{
    int divrate = clkdiv[FIELD_EX8(tmr->tccr[ch], TCCR, CKS)];
    int et;

    tmr->div_round[ch] += delta;
    if (divrate > 0) {
        et = tmr->div_round[ch] / divrate;
        tmr->div_round[ch] %= divrate;
    } else {
        /* disble clock. so no update */
        et = 0;
    }
    return et;
}

static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch)
{
    int64_t delta, now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    int elapsed, ovf = 0;
    uint16_t tcnt[2];
    uint32_t ret;

    delta = (now - tmr->tick) * NANOSECONDS_PER_SECOND / tmr->input_freq;
    if (delta > 0) {
        tmr->tick = now;

        switch (FIELD_EX8(tmr->tccr[1], TCCR, CSS)) {
        case CSS_INTERNAL:
            /* timer1 count update */
            elapsed = elapsed_time(tmr, 1, delta);
            if (elapsed >= 0x100) {
                ovf = elapsed >> 8;
            }
            tcnt[1] = tmr->tcnt[1] + (elapsed & 0xff);
            break;
        case CSS_INVALID: /* guest error to have set this */
        case CSS_EXTERNAL: /* QEMU doesn't implement these */
        case CSS_CASCADING:
            tcnt[1] = tmr->tcnt[1];
            break;
        default:
            g_assert_not_reached();
        }
        switch (FIELD_EX8(tmr->tccr[0], TCCR, CSS)) {
        case CSS_INTERNAL:
            elapsed = elapsed_time(tmr, 0, delta);
            tcnt[0] = tmr->tcnt[0] + elapsed;
            break;
        case CSS_CASCADING:
            tcnt[0] = tmr->tcnt[0] + ovf;
            break;
        case CSS_INVALID: /* guest error to have set this */
        case CSS_EXTERNAL: /* QEMU doesn't implement this */
            tcnt[0] = tmr->tcnt[0];
            break;
        default:
            g_assert_not_reached();
        }
    } else {
        tcnt[0] = tmr->tcnt[0];
        tcnt[1] = tmr->tcnt[1];
    }
    if (size == 1) {
        return tcnt[ch];
    } else {
        ret = 0;
        ret = deposit32(ret, 0, 8, tcnt[1]);
        ret = deposit32(ret, 8, 8, tcnt[0]);
        return ret;
    }
}

static uint8_t read_tccr(uint8_t r)
{
    uint8_t tccr = 0;
    tccr = FIELD_DP8(tccr, TCCR, TMRIS,
                     FIELD_EX8(r, TCCR, TMRIS));
    tccr = FIELD_DP8(tccr, TCCR, CSS,
                     FIELD_EX8(r, TCCR, CSS));
    tccr = FIELD_DP8(tccr, TCCR, CKS,
                     FIELD_EX8(r, TCCR, CKS));
    return tccr;
}

static uint64_t tmr_read(void *opaque, hwaddr addr, unsigned size)
{
    RTMRState *tmr = opaque;
    int ch = addr & 1;
    uint64_t ret;

    if (size == 2 && (ch != 0 || addr == A_TCR || addr == A_TCSR)) {
        qemu_log_mask(LOG_GUEST_ERROR, "renesas_tmr: Invalid read size 0x%"
                                       HWADDR_PRIX "\n",
                      addr);
        return UINT64_MAX;
    }
    switch (addr & 0x0e) {
    case A_TCR:
        ret = 0;
        ret = FIELD_DP8(ret, TCR, CCLR,
                        FIELD_EX8(tmr->tcr[ch], TCR, CCLR));
        ret = FIELD_DP8(ret, TCR, OVIE,
                        FIELD_EX8(tmr->tcr[ch], TCR, OVIE));
        ret = FIELD_DP8(ret, TCR, CMIEA,
                        FIELD_EX8(tmr->tcr[ch], TCR, CMIEA));
        ret = FIELD_DP8(ret, TCR, CMIEB,
                        FIELD_EX8(tmr->tcr[ch], TCR, CMIEB));
        return ret;
    case A_TCSR:
        ret = 0;
        ret = FIELD_DP8(ret, TCSR, OSA,
                        FIELD_EX8(tmr->tcsr[ch], TCSR, OSA));
        ret = FIELD_DP8(ret, TCSR, OSB,
                        FIELD_EX8(tmr->tcsr[ch], TCSR, OSB));
        switch (ch) {
        case 0:
            ret = FIELD_DP8(ret, TCSR, ADTE,
                            FIELD_EX8(tmr->tcsr[ch], TCSR, ADTE));
            break;
        case 1: /* CH1 ADTE unimplement always 1 */
            ret = FIELD_DP8(ret, TCSR, ADTE, 1);
            break;
        }
        return ret;
    case A_TCORA:
        if (size == 1) {
            return tmr->tcora[ch];
        } else if (ch == 0) {
            return concat_reg(tmr->tcora);
        }
        /* fall through */
    case A_TCORB:
        if (size == 1) {
            return tmr->tcorb[ch];
        } else {
            return concat_reg(tmr->tcorb);
        }
    case A_TCNT:
        return read_tcnt(tmr, size, ch);
    case A_TCCR:
        if (size == 1) {
            return read_tccr(tmr->tccr[ch]);
        } else {
            return read_tccr(tmr->tccr[0]) << 8 | read_tccr(tmr->tccr[1]);
        }
    default:
        qemu_log_mask(LOG_UNIMP, "renesas_tmr: Register 0x%" HWADDR_PRIX
                                 " not implemented\n",
                      addr);
        break;
    }
    return UINT64_MAX;
}

static void tmr_write_count(RTMRState *tmr, int ch, unsigned size,
                            uint8_t *reg, uint64_t val)
{
    if (size == 1) {
        reg[ch] = val;
        update_events(tmr, ch);
    } else {
        reg[0] = extract32(val, 8, 8);
        reg[1] = extract32(val, 0, 8);
        update_events(tmr, 0);
        update_events(tmr, 1);
    }
}

static void tmr_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
    RTMRState *tmr = opaque;
    int ch = addr & 1;

    if (size == 2 && (ch != 0 || addr == A_TCR || addr == A_TCSR)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "renesas_tmr: Invalid write size 0x%" HWADDR_PRIX "\n",
                      addr);
        return;
    }
    switch (addr & 0x0e) {
    case A_TCR:
        tmr->tcr[ch] = val;
        break;
    case A_TCSR:
        tmr->tcsr[ch] = val;
        break;
    case A_TCORA:
        tmr_write_count(tmr, ch, size, tmr->tcora, val);
        break;
    case A_TCORB:
        tmr_write_count(tmr, ch, size, tmr->tcorb, val);
        break;
    case A_TCNT:
        tmr_write_count(tmr, ch, size, tmr->tcnt, val);
        break;
    case A_TCCR:
        tmr_write_count(tmr, ch, size, tmr->tccr, val);
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "renesas_tmr: Register 0x%" HWADDR_PRIX
                                 " not implemented\n",
                      addr);
        break;
    }
}

static const MemoryRegionOps tmr_ops = {
    .write = tmr_write,
    .read  = tmr_read,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 2,
    },
    .valid = {
        .min_access_size = 1,
        .max_access_size = 2,
    },
};

static void timer_events(RTMRState *tmr, int ch);

static uint16_t issue_event(RTMRState *tmr, int ch, int sz,
                        uint16_t tcnt, uint16_t tcora, uint16_t tcorb)
{
    uint16_t ret = tcnt;

    switch (tmr->next[ch]) {
    case none:
        break;
    case cmia:
        if (tcnt >= tcora) {
            if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_A) {
                ret = tcnt - tcora;
            }
            if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEA)) {
                qemu_irq_pulse(tmr->cmia[ch]);
            }
            if (sz == 8 && ch == 0 &&
                FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CSS_CASCADING) {
                tmr->tcnt[1]++;
                timer_events(tmr, 1);
            }
        }
        break;
    case cmib:
        if (tcnt >= tcorb) {
            if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_B) {
                ret = tcnt - tcorb;
            }
            if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEB)) {
                qemu_irq_pulse(tmr->cmib[ch]);
            }
        }
        break;
    case ovi:
        if ((tcnt >= (1 << sz)) && FIELD_EX8(tmr->tcr[ch], TCR, OVIE)) {
            qemu_irq_pulse(tmr->ovi[ch]);
        }
        break;
    default:
        g_assert_not_reached();
    }
    return ret;
}

static void timer_events(RTMRState *tmr, int ch)
{
    uint16_t tcnt;

    tmr->tcnt[ch] = read_tcnt(tmr, 1, ch);
    if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) != CSS_CASCADING) {
        tmr->tcnt[ch] = issue_event(tmr, ch, 8,
                                    tmr->tcnt[ch],
                                    tmr->tcora[ch],
                                    tmr->tcorb[ch]) & 0xff;
    } else {
        if (ch == 1) {
            return ;
        }
        tcnt = issue_event(tmr, ch, 16,
                           concat_reg(tmr->tcnt),
                           concat_reg(tmr->tcora),
                           concat_reg(tmr->tcorb));
        tmr->tcnt[0] = (tcnt >> 8) & 0xff;
        tmr->tcnt[1] = tcnt & 0xff;
    }
    update_events(tmr, ch);
}

static void timer_event0(void *opaque)
{
    RTMRState *tmr = opaque;

    timer_events(tmr, 0);
}

static void timer_event1(void *opaque)
{
    RTMRState *tmr = opaque;

    timer_events(tmr, 1);
}

static void rtmr_reset(DeviceState *dev)
{
    RTMRState *tmr = RTMR(dev);
    tmr->tcr[0]   = tmr->tcr[1]   = 0x00;
    tmr->tcsr[0]  = 0x00;
    tmr->tcsr[1]  = 0x10;
    tmr->tcnt[0]  = tmr->tcnt[1]  = 0x00;
    tmr->tcora[0] = tmr->tcora[1] = 0xff;
    tmr->tcorb[0] = tmr->tcorb[1] = 0xff;
    tmr->tccr[0]  = tmr->tccr[1]  = 0x00;
    tmr->next[0]  = tmr->next[1]  = none;
    tmr->tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}

static void rtmr_init(Object *obj)
{
    SysBusDevice *d = SYS_BUS_DEVICE(obj);
    RTMRState *tmr = RTMR(obj);
    int i;

    memory_region_init_io(&tmr->memory, OBJECT(tmr), &tmr_ops,
                          tmr, "renesas-tmr", 0x10);
    sysbus_init_mmio(d, &tmr->memory);

    for (i = 0; i < ARRAY_SIZE(tmr->ovi); i++) {
        sysbus_init_irq(d, &tmr->cmia[i]);
        sysbus_init_irq(d, &tmr->cmib[i]);
        sysbus_init_irq(d, &tmr->ovi[i]);
    }
    timer_init_ns(&tmr->timer[0], QEMU_CLOCK_VIRTUAL, timer_event0, tmr);
    timer_init_ns(&tmr->timer[1], QEMU_CLOCK_VIRTUAL, timer_event1, tmr);
}

static const VMStateDescription vmstate_rtmr = {
    .name = "rx-tmr",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_INT64(tick, RTMRState),
        VMSTATE_UINT8_ARRAY(tcnt, RTMRState, TMR_CH),
        VMSTATE_UINT8_ARRAY(tcora, RTMRState, TMR_CH),
        VMSTATE_UINT8_ARRAY(tcorb, RTMRState, TMR_CH),
        VMSTATE_UINT8_ARRAY(tcr, RTMRState, TMR_CH),
        VMSTATE_UINT8_ARRAY(tccr, RTMRState, TMR_CH),
        VMSTATE_UINT8_ARRAY(tcor, RTMRState, TMR_CH),
        VMSTATE_UINT8_ARRAY(tcsr, RTMRState, TMR_CH),
        VMSTATE_INT64_ARRAY(div_round, RTMRState, TMR_CH),
        VMSTATE_UINT8_ARRAY(next, RTMRState, TMR_CH),
        VMSTATE_TIMER_ARRAY(timer, RTMRState, TMR_CH),
        VMSTATE_END_OF_LIST()
    }
};

static Property rtmr_properties[] = {
    DEFINE_PROP_UINT64("input-freq", RTMRState, input_freq, 0),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->vmsd = &vmstate_rtmr;
    dc->reset = rtmr_reset;
    device_class_set_props(dc, rtmr_properties);
}

static const TypeInfo rtmr_info = {
    .name = TYPE_RENESAS_TMR,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(RTMRState),
    .instance_init = rtmr_init,
    .class_init = rtmr_class_init,
};

static void rtmr_register_types(void)
{
    type_register_static(&rtmr_info);
}

type_init(rtmr_register_types)
