/*
 * ASPEED Real Time Clock
 * Joel Stanley <joel@jms.id.au>
 *
 * Copyright 2019 IBM Corp
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu-common.h"
#include "hw/rtc/aspeed_rtc.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/timer.h"

#include "trace.h"

#define COUNTER1        (0x00 / 4)
#define COUNTER2        (0x04 / 4)
#define ALARM           (0x08 / 4)
#define CONTROL         (0x10 / 4)
#define ALARM_STATUS    (0x14 / 4)

#define RTC_UNLOCKED    BIT(1)
#define RTC_ENABLED     BIT(0)

static void aspeed_rtc_calc_offset(AspeedRtcState *rtc)
{
    struct tm tm;
    uint32_t year, cent;
    uint32_t reg1 = rtc->reg[COUNTER1];
    uint32_t reg2 = rtc->reg[COUNTER2];

    tm.tm_mday = (reg1 >> 24) & 0x1f;
    tm.tm_hour = (reg1 >> 16) & 0x1f;
    tm.tm_min = (reg1 >> 8) & 0x3f;
    tm.tm_sec = (reg1 >> 0) & 0x3f;

    cent = (reg2 >> 16) & 0x1f;
    year = (reg2 >> 8) & 0x7f;
    tm.tm_mon = ((reg2 >>  0) & 0x0f) - 1;
    tm.tm_year = year + (cent * 100) - 1900;

    rtc->offset = qemu_timedate_diff(&tm);
}

static uint32_t aspeed_rtc_get_counter(AspeedRtcState *rtc, int r)
{
    uint32_t year, cent;
    struct tm now;

    qemu_get_timedate(&now, rtc->offset);

    switch (r) {
    case COUNTER1:
        return (now.tm_mday << 24) | (now.tm_hour << 16) |
            (now.tm_min << 8) | now.tm_sec;
    case COUNTER2:
        cent = (now.tm_year + 1900) / 100;
        year = now.tm_year % 100;
        return ((cent & 0x1f) << 16) | ((year & 0x7f) << 8) |
            ((now.tm_mon + 1) & 0xf);
    default:
        g_assert_not_reached();
    }
}

static uint64_t aspeed_rtc_read(void *opaque, hwaddr addr,
                                unsigned size)
{
    AspeedRtcState *rtc = opaque;
    uint64_t val;
    uint32_t r = addr >> 2;

    switch (r) {
    case COUNTER1:
    case COUNTER2:
        if (rtc->reg[CONTROL] & RTC_ENABLED) {
            rtc->reg[r] = aspeed_rtc_get_counter(rtc, r);
        }
        /* fall through */
    case CONTROL:
        val = rtc->reg[r];
        break;
    case ALARM:
    case ALARM_STATUS:
    default:
        qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx "\n", __func__, addr);
        return 0;
    }

    trace_aspeed_rtc_read(addr, val);

    return val;
}

static void aspeed_rtc_write(void *opaque, hwaddr addr,
                             uint64_t val, unsigned size)
{
    AspeedRtcState *rtc = opaque;
    uint32_t r = addr >> 2;

    switch (r) {
    case COUNTER1:
    case COUNTER2:
        if (!(rtc->reg[CONTROL] & RTC_UNLOCKED)) {
            break;
        }
        /* fall through */
    case CONTROL:
        rtc->reg[r] = val;
        aspeed_rtc_calc_offset(rtc);
        break;
    case ALARM:
    case ALARM_STATUS:
    default:
        qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx "\n", __func__, addr);
        break;
    }
    trace_aspeed_rtc_write(addr, val);
}

static void aspeed_rtc_reset(DeviceState *d)
{
    AspeedRtcState *rtc = ASPEED_RTC(d);

    rtc->offset = 0;
    memset(rtc->reg, 0, sizeof(rtc->reg));
}

static const MemoryRegionOps aspeed_rtc_ops = {
    .read = aspeed_rtc_read,
    .write = aspeed_rtc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static const VMStateDescription vmstate_aspeed_rtc = {
    .name = TYPE_ASPEED_RTC,
    .version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(reg, AspeedRtcState, 0x18),
        VMSTATE_INT32(offset, AspeedRtcState),
        VMSTATE_INT32(offset, AspeedRtcState),
        VMSTATE_END_OF_LIST()
    }
};

static void aspeed_rtc_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    AspeedRtcState *s = ASPEED_RTC(dev);

    sysbus_init_irq(sbd, &s->irq);

    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_rtc_ops, s,
                          "aspeed-rtc", 0x18ULL);
    sysbus_init_mmio(sbd, &s->iomem);
}

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

    dc->realize = aspeed_rtc_realize;
    dc->vmsd = &vmstate_aspeed_rtc;
    dc->reset = aspeed_rtc_reset;
}

static const TypeInfo aspeed_rtc_info = {
    .name          = TYPE_ASPEED_RTC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(AspeedRtcState),
    .class_init    = aspeed_rtc_class_init,
};

static void aspeed_rtc_register_types(void)
{
    type_register_static(&aspeed_rtc_info);
}

type_init(aspeed_rtc_register_types)
