/*
 * Allwinner Real Time Clock emulation
 *
 * Copyright (C) 2019 Niek Linnenbank <nieklinnenbank@gmail.com>
 *
 * 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.
 *
 * 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/units.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu-common.h"
#include "hw/qdev-properties.h"
#include "hw/rtc/allwinner-rtc.h"
#include "trace.h"

/* RTC registers */
enum {
    REG_LOSC = 1,        /* Low Oscillator Control */
    REG_YYMMDD,          /* RTC Year-Month-Day */
    REG_HHMMSS,          /* RTC Hour-Minute-Second */
    REG_ALARM1_WKHHMMSS, /* Alarm1 Week Hour-Minute-Second */
    REG_ALARM1_EN,       /* Alarm1 Enable */
    REG_ALARM1_IRQ_EN,   /* Alarm1 IRQ Enable */
    REG_ALARM1_IRQ_STA,  /* Alarm1 IRQ Status */
    REG_GP0,             /* General Purpose Register 0 */
    REG_GP1,             /* General Purpose Register 1 */
    REG_GP2,             /* General Purpose Register 2 */
    REG_GP3,             /* General Purpose Register 3 */

    /* sun4i registers */
    REG_ALARM1_DDHHMMSS, /* Alarm1 Day Hour-Minute-Second */
    REG_CPUCFG,          /* CPU Configuration Register */

    /* sun6i registers */
    REG_LOSC_AUTOSTA,    /* LOSC Auto Switch Status */
    REG_INT_OSC_PRE,     /* Internal OSC Clock Prescaler */
    REG_ALARM0_COUNTER,  /* Alarm0 Counter */
    REG_ALARM0_CUR_VLU,  /* Alarm0 Counter Current Value */
    REG_ALARM0_ENABLE,   /* Alarm0 Enable */
    REG_ALARM0_IRQ_EN,   /* Alarm0 IRQ Enable */
    REG_ALARM0_IRQ_STA,  /* Alarm0 IRQ Status */
    REG_ALARM_CONFIG,    /* Alarm Config */
    REG_LOSC_OUT_GATING, /* LOSC Output Gating Register */
    REG_GP4,             /* General Purpose Register 4 */
    REG_GP5,             /* General Purpose Register 5 */
    REG_GP6,             /* General Purpose Register 6 */
    REG_GP7,             /* General Purpose Register 7 */
    REG_RTC_DBG,         /* RTC Debug Register */
    REG_GPL_HOLD_OUT,    /* GPL Hold Output Register */
    REG_VDD_RTC,         /* VDD RTC Regulate Register */
    REG_IC_CHARA,        /* IC Characteristics Register */
};

/* RTC register flags */
enum {
    REG_LOSC_YMD   = (1 << 7),
    REG_LOSC_HMS   = (1 << 8),
};

/* RTC sun4i register map (offset to name) */
const uint8_t allwinner_rtc_sun4i_regmap[] = {
    [0x0000] = REG_LOSC,
    [0x0004] = REG_YYMMDD,
    [0x0008] = REG_HHMMSS,
    [0x000C] = REG_ALARM1_DDHHMMSS,
    [0x0010] = REG_ALARM1_WKHHMMSS,
    [0x0014] = REG_ALARM1_EN,
    [0x0018] = REG_ALARM1_IRQ_EN,
    [0x001C] = REG_ALARM1_IRQ_STA,
    [0x0020] = REG_GP0,
    [0x0024] = REG_GP1,
    [0x0028] = REG_GP2,
    [0x002C] = REG_GP3,
    [0x003C] = REG_CPUCFG,
};

/* RTC sun6i register map (offset to name) */
const uint8_t allwinner_rtc_sun6i_regmap[] = {
    [0x0000] = REG_LOSC,
    [0x0004] = REG_LOSC_AUTOSTA,
    [0x0008] = REG_INT_OSC_PRE,
    [0x0010] = REG_YYMMDD,
    [0x0014] = REG_HHMMSS,
    [0x0020] = REG_ALARM0_COUNTER,
    [0x0024] = REG_ALARM0_CUR_VLU,
    [0x0028] = REG_ALARM0_ENABLE,
    [0x002C] = REG_ALARM0_IRQ_EN,
    [0x0030] = REG_ALARM0_IRQ_STA,
    [0x0040] = REG_ALARM1_WKHHMMSS,
    [0x0044] = REG_ALARM1_EN,
    [0x0048] = REG_ALARM1_IRQ_EN,
    [0x004C] = REG_ALARM1_IRQ_STA,
    [0x0050] = REG_ALARM_CONFIG,
    [0x0060] = REG_LOSC_OUT_GATING,
    [0x0100] = REG_GP0,
    [0x0104] = REG_GP1,
    [0x0108] = REG_GP2,
    [0x010C] = REG_GP3,
    [0x0110] = REG_GP4,
    [0x0114] = REG_GP5,
    [0x0118] = REG_GP6,
    [0x011C] = REG_GP7,
    [0x0170] = REG_RTC_DBG,
    [0x0180] = REG_GPL_HOLD_OUT,
    [0x0190] = REG_VDD_RTC,
    [0x01F0] = REG_IC_CHARA,
};

static bool allwinner_rtc_sun4i_read(AwRtcState *s, uint32_t offset)
{
    /* no sun4i specific registers currently implemented */
    return false;
}

static bool allwinner_rtc_sun4i_write(AwRtcState *s, uint32_t offset,
                                      uint32_t data)
{
    /* no sun4i specific registers currently implemented */
    return false;
}

static bool allwinner_rtc_sun6i_read(AwRtcState *s, uint32_t offset)
{
    const AwRtcClass *c = AW_RTC_GET_CLASS(s);

    switch (c->regmap[offset]) {
    case REG_GP4:             /* General Purpose Register 4 */
    case REG_GP5:             /* General Purpose Register 5 */
    case REG_GP6:             /* General Purpose Register 6 */
    case REG_GP7:             /* General Purpose Register 7 */
        return true;
    default:
        break;
    }
    return false;
}

static bool allwinner_rtc_sun6i_write(AwRtcState *s, uint32_t offset,
                                      uint32_t data)
{
    const AwRtcClass *c = AW_RTC_GET_CLASS(s);

    switch (c->regmap[offset]) {
    case REG_GP4:             /* General Purpose Register 4 */
    case REG_GP5:             /* General Purpose Register 5 */
    case REG_GP6:             /* General Purpose Register 6 */
    case REG_GP7:             /* General Purpose Register 7 */
        return true;
    default:
        break;
    }
    return false;
}

static uint64_t allwinner_rtc_read(void *opaque, hwaddr offset,
                                   unsigned size)
{
    AwRtcState *s = AW_RTC(opaque);
    const AwRtcClass *c = AW_RTC_GET_CLASS(s);
    uint64_t val = 0;

    if (offset >= c->regmap_size) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
                      __func__, (uint32_t)offset);
        return 0;
    }

    if (!c->regmap[offset]) {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid register 0x%04x\n",
                          __func__, (uint32_t)offset);
        return 0;
    }

    switch (c->regmap[offset]) {
    case REG_LOSC:       /* Low Oscillator Control */
        val = s->regs[REG_LOSC];
        s->regs[REG_LOSC] &= ~(REG_LOSC_YMD | REG_LOSC_HMS);
        break;
    case REG_YYMMDD:     /* RTC Year-Month-Day */
    case REG_HHMMSS:     /* RTC Hour-Minute-Second */
    case REG_GP0:        /* General Purpose Register 0 */
    case REG_GP1:        /* General Purpose Register 1 */
    case REG_GP2:        /* General Purpose Register 2 */
    case REG_GP3:        /* General Purpose Register 3 */
        val = s->regs[c->regmap[offset]];
        break;
    default:
        if (!c->read(s, offset)) {
            qemu_log_mask(LOG_UNIMP, "%s: unimplemented register 0x%04x\n",
                          __func__, (uint32_t)offset);
        }
        val = s->regs[c->regmap[offset]];
        break;
    }

    trace_allwinner_rtc_read(offset, val);
    return val;
}

static void allwinner_rtc_write(void *opaque, hwaddr offset,
                                uint64_t val, unsigned size)
{
    AwRtcState *s = AW_RTC(opaque);
    const AwRtcClass *c = AW_RTC_GET_CLASS(s);

    if (offset >= c->regmap_size) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
                      __func__, (uint32_t)offset);
        return;
    }

    if (!c->regmap[offset]) {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid register 0x%04x\n",
                          __func__, (uint32_t)offset);
        return;
    }

    trace_allwinner_rtc_write(offset, val);

    switch (c->regmap[offset]) {
    case REG_YYMMDD:     /* RTC Year-Month-Day */
        s->regs[REG_YYMMDD] = val;
        s->regs[REG_LOSC]  |= REG_LOSC_YMD;
        break;
    case REG_HHMMSS:     /* RTC Hour-Minute-Second */
        s->regs[REG_HHMMSS] = val;
        s->regs[REG_LOSC]  |= REG_LOSC_HMS;
        break;
    case REG_GP0:        /* General Purpose Register 0 */
    case REG_GP1:        /* General Purpose Register 1 */
    case REG_GP2:        /* General Purpose Register 2 */
    case REG_GP3:        /* General Purpose Register 3 */
        s->regs[c->regmap[offset]] = val;
        break;
    default:
        if (!c->write(s, offset, val)) {
            qemu_log_mask(LOG_UNIMP, "%s: unimplemented register 0x%04x\n",
                          __func__, (uint32_t)offset);
        }
        break;
    }
}

static const MemoryRegionOps allwinner_rtc_ops = {
    .read = allwinner_rtc_read,
    .write = allwinner_rtc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .impl.min_access_size = 4,
};

static void allwinner_rtc_reset(DeviceState *dev)
{
    AwRtcState *s = AW_RTC(dev);
    struct tm now;

    /* Clear registers */
    memset(s->regs, 0, sizeof(s->regs));

    /* Get current datetime */
    qemu_get_timedate(&now, 0);

    /* Set RTC with current datetime */
    if (s->base_year > 1900) {
        s->regs[REG_YYMMDD] =  ((now.tm_year + 1900 - s->base_year) << 16) |
                               ((now.tm_mon + 1) << 8) |
                                 now.tm_mday;
        s->regs[REG_HHMMSS] = (((now.tm_wday + 6) % 7) << 29) |
                                  (now.tm_hour << 16) |
                                  (now.tm_min << 8) |
                                   now.tm_sec;
    }
}

static void allwinner_rtc_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    AwRtcState *s = AW_RTC(obj);

    /* Memory mapping */
    memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_rtc_ops, s,
                          TYPE_AW_RTC, 1 * KiB);
    sysbus_init_mmio(sbd, &s->iomem);
}

static const VMStateDescription allwinner_rtc_vmstate = {
    .name = "allwinner-rtc",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, AwRtcState, AW_RTC_REGS_NUM),
        VMSTATE_END_OF_LIST()
    }
};

static Property allwinner_rtc_properties[] = {
    DEFINE_PROP_INT32("base-year", AwRtcState, base_year, 0),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->reset = allwinner_rtc_reset;
    dc->vmsd = &allwinner_rtc_vmstate;
    device_class_set_props(dc, allwinner_rtc_properties);
}

static void allwinner_rtc_sun4i_init(Object *obj)
{
    AwRtcState *s = AW_RTC(obj);
    s->base_year = 2010;
}

static void allwinner_rtc_sun4i_class_init(ObjectClass *klass, void *data)
{
    AwRtcClass *arc = AW_RTC_CLASS(klass);

    arc->regmap = allwinner_rtc_sun4i_regmap;
    arc->regmap_size = sizeof(allwinner_rtc_sun4i_regmap);
    arc->read = allwinner_rtc_sun4i_read;
    arc->write = allwinner_rtc_sun4i_write;
}

static void allwinner_rtc_sun6i_init(Object *obj)
{
    AwRtcState *s = AW_RTC(obj);
    s->base_year = 1970;
}

static void allwinner_rtc_sun6i_class_init(ObjectClass *klass, void *data)
{
    AwRtcClass *arc = AW_RTC_CLASS(klass);

    arc->regmap = allwinner_rtc_sun6i_regmap;
    arc->regmap_size = sizeof(allwinner_rtc_sun6i_regmap);
    arc->read = allwinner_rtc_sun6i_read;
    arc->write = allwinner_rtc_sun6i_write;
}

static void allwinner_rtc_sun7i_init(Object *obj)
{
    AwRtcState *s = AW_RTC(obj);
    s->base_year = 1970;
}

static void allwinner_rtc_sun7i_class_init(ObjectClass *klass, void *data)
{
    AwRtcClass *arc = AW_RTC_CLASS(klass);
    allwinner_rtc_sun4i_class_init(klass, arc);
}

static const TypeInfo allwinner_rtc_info = {
    .name          = TYPE_AW_RTC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_init = allwinner_rtc_init,
    .instance_size = sizeof(AwRtcState),
    .class_init    = allwinner_rtc_class_init,
    .class_size    = sizeof(AwRtcClass),
    .abstract      = true,
};

static const TypeInfo allwinner_rtc_sun4i_info = {
    .name          = TYPE_AW_RTC_SUN4I,
    .parent        = TYPE_AW_RTC,
    .class_init    = allwinner_rtc_sun4i_class_init,
    .instance_init = allwinner_rtc_sun4i_init,
};

static const TypeInfo allwinner_rtc_sun6i_info = {
    .name          = TYPE_AW_RTC_SUN6I,
    .parent        = TYPE_AW_RTC,
    .class_init    = allwinner_rtc_sun6i_class_init,
    .instance_init = allwinner_rtc_sun6i_init,
};

static const TypeInfo allwinner_rtc_sun7i_info = {
    .name          = TYPE_AW_RTC_SUN7I,
    .parent        = TYPE_AW_RTC,
    .class_init    = allwinner_rtc_sun7i_class_init,
    .instance_init = allwinner_rtc_sun7i_init,
};

static void allwinner_rtc_register(void)
{
    type_register_static(&allwinner_rtc_info);
    type_register_static(&allwinner_rtc_sun4i_info);
    type_register_static(&allwinner_rtc_sun6i_info);
    type_register_static(&allwinner_rtc_sun7i_info);
}

type_init(allwinner_rtc_register)
