/*
 * 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/timer/aspeed_rtc.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)
