/*
 * ASPEED Watchdog Controller
 *
 * Copyright (C) 2016-2017 IBM Corp.
 *
 * This code is licensed under the GPL version 2 or later. See the
 * COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"

#include "qapi/error.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "sysemu/watchdog.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "hw/watchdog/wdt_aspeed.h"
#include "migration/vmstate.h"
#include "trace.h"

#define WDT_STATUS                      (0x00 / 4)
#define WDT_RELOAD_VALUE                (0x04 / 4)
#define WDT_RESTART                     (0x08 / 4)
#define WDT_CTRL                        (0x0C / 4)
#define   WDT_CTRL_RESET_MODE_SOC       (0x00 << 5)
#define   WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5)
#define   WDT_CTRL_1MHZ_CLK             BIT(4)
#define   WDT_CTRL_WDT_EXT              BIT(3)
#define   WDT_CTRL_WDT_INTR             BIT(2)
#define   WDT_CTRL_RESET_SYSTEM         BIT(1)
#define   WDT_CTRL_ENABLE               BIT(0)
#define WDT_RESET_WIDTH                 (0x18 / 4)
#define   WDT_RESET_WIDTH_ACTIVE_HIGH   BIT(31)
#define     WDT_POLARITY_MASK           (0xFF << 24)
#define     WDT_ACTIVE_HIGH_MAGIC       (0xA5 << 24)
#define     WDT_ACTIVE_LOW_MAGIC        (0x5A << 24)
#define   WDT_RESET_WIDTH_PUSH_PULL     BIT(30)
#define     WDT_DRIVE_TYPE_MASK         (0xFF << 24)
#define     WDT_PUSH_PULL_MAGIC         (0xA8 << 24)
#define     WDT_OPEN_DRAIN_MAGIC        (0x8A << 24)
#define WDT_RESET_MASK1                 (0x1c / 4)
#define WDT_RESET_MASK2                 (0x20 / 4)

#define WDT_SW_RESET_CTRL               (0x24 / 4)
#define WDT_SW_RESET_MASK1              (0x28 / 4)
#define WDT_SW_RESET_MASK2              (0x2c / 4)

#define WDT_TIMEOUT_STATUS              (0x10 / 4)
#define WDT_TIMEOUT_CLEAR               (0x14 / 4)

#define WDT_RESTART_MAGIC               0x4755

#define AST2600_SCU_RESET_CONTROL1      (0x40 / 4)
#define SCU_RESET_CONTROL1              (0x04 / 4)
#define    SCU_RESET_SDRAM              BIT(0)

static bool aspeed_wdt_is_enabled(const AspeedWDTState *s)
{
    return s->regs[WDT_CTRL] & WDT_CTRL_ENABLE;
}

static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
{
    AspeedWDTState *s = ASPEED_WDT(opaque);

    trace_aspeed_wdt_read(offset, size);

    offset >>= 2;

    switch (offset) {
    case WDT_STATUS:
        return s->regs[WDT_STATUS];
    case WDT_RELOAD_VALUE:
        return s->regs[WDT_RELOAD_VALUE];
    case WDT_RESTART:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: read from write-only reg at offset 0x%"
                      HWADDR_PRIx "\n", __func__, offset);
        return 0;
    case WDT_CTRL:
        return s->regs[WDT_CTRL];
    case WDT_RESET_WIDTH:
        return s->regs[WDT_RESET_WIDTH];
    case WDT_RESET_MASK1:
        return s->regs[WDT_RESET_MASK1];
    case WDT_TIMEOUT_STATUS:
    case WDT_TIMEOUT_CLEAR:
    case WDT_RESET_MASK2:
    case WDT_SW_RESET_CTRL:
    case WDT_SW_RESET_MASK1:
    case WDT_SW_RESET_MASK2:
        qemu_log_mask(LOG_UNIMP,
                      "%s: uninmplemented read at offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
        return 0;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
        return 0;
    }

}

static void aspeed_wdt_reload(AspeedWDTState *s)
{
    uint64_t reload;

    if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) {
        reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
                          s->pclk_freq);
    } else {
        reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
    }

    if (aspeed_wdt_is_enabled(s)) {
        timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
    }
}

static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
{
    uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;

    if (aspeed_wdt_is_enabled(s)) {
        timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
    }
}

static uint64_t aspeed_2400_sanitize_ctrl(uint64_t data)
{
    return data & 0xffff;
}

static uint64_t aspeed_2500_sanitize_ctrl(uint64_t data)
{
    return (data & ~(0xfUL << 8)) | WDT_CTRL_1MHZ_CLK;
}

static uint64_t aspeed_2600_sanitize_ctrl(uint64_t data)
{
    return data & ~(0x7UL << 7);
}

static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
                             unsigned size)
{
    AspeedWDTState *s = ASPEED_WDT(opaque);
    AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
    bool enable;

    trace_aspeed_wdt_write(offset, size, data);

    offset >>= 2;

    switch (offset) {
    case WDT_STATUS:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: write to read-only reg at offset 0x%"
                      HWADDR_PRIx "\n", __func__, offset);
        break;
    case WDT_RELOAD_VALUE:
        s->regs[WDT_RELOAD_VALUE] = data;
        break;
    case WDT_RESTART:
        if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
            s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
            awc->wdt_reload(s);
        }
        break;
    case WDT_CTRL:
        data = awc->sanitize_ctrl(data);
        enable = data & WDT_CTRL_ENABLE;
        if (enable && !aspeed_wdt_is_enabled(s)) {
            s->regs[WDT_CTRL] = data;
            awc->wdt_reload(s);
        } else if (!enable && aspeed_wdt_is_enabled(s)) {
            s->regs[WDT_CTRL] = data;
            timer_del(s->timer);
        } else {
            s->regs[WDT_CTRL] = data;
        }
        break;
    case WDT_RESET_WIDTH:
        if (awc->reset_pulse) {
            awc->reset_pulse(s, data & WDT_POLARITY_MASK);
        }
        s->regs[WDT_RESET_WIDTH] &= ~awc->ext_pulse_width_mask;
        s->regs[WDT_RESET_WIDTH] |= data & awc->ext_pulse_width_mask;
        break;

    case WDT_RESET_MASK1:
        /* TODO: implement */
        s->regs[WDT_RESET_MASK1] = data;
        break;

    case WDT_TIMEOUT_STATUS:
    case WDT_TIMEOUT_CLEAR:
    case WDT_RESET_MASK2:
    case WDT_SW_RESET_CTRL:
    case WDT_SW_RESET_MASK1:
    case WDT_SW_RESET_MASK2:
        qemu_log_mask(LOG_UNIMP,
                      "%s: uninmplemented write at offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
    }
    return;
}

static const VMStateDescription vmstate_aspeed_wdt = {
    .name = "vmstate_aspeed_wdt",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (const VMStateField[]) {
        VMSTATE_TIMER_PTR(timer, AspeedWDTState),
        VMSTATE_UINT32_ARRAY(regs, AspeedWDTState, ASPEED_WDT_REGS_MAX),
        VMSTATE_END_OF_LIST()
    }
};

static const MemoryRegionOps aspeed_wdt_ops = {
    .read = aspeed_wdt_read,
    .write = aspeed_wdt_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
    .valid.unaligned = false,
};

static void aspeed_wdt_reset(DeviceState *dev)
{
    AspeedWDTState *s = ASPEED_WDT(dev);
    AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);

    s->regs[WDT_STATUS] = awc->default_status;
    s->regs[WDT_RELOAD_VALUE] = awc->default_reload_value;
    s->regs[WDT_RESTART] = 0;
    s->regs[WDT_CTRL] = awc->sanitize_ctrl(0);
    s->regs[WDT_RESET_WIDTH] = 0xFF;

    timer_del(s->timer);
}

static void aspeed_wdt_timer_expired(void *dev)
{
    AspeedWDTState *s = ASPEED_WDT(dev);
    uint32_t reset_ctrl_reg = ASPEED_WDT_GET_CLASS(s)->reset_ctrl_reg;

    /* Do not reset on SDRAM controller reset */
    if (s->scu->regs[reset_ctrl_reg] & SCU_RESET_SDRAM) {
        timer_del(s->timer);
        s->regs[WDT_CTRL] = 0;
        return;
    }

    qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n",
                  s->iomem.addr);
    watchdog_perform_action();
    timer_del(s->timer);
}

#define PCLK_HZ 24000000

static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    AspeedWDTState *s = ASPEED_WDT(dev);
    AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(dev);

    assert(s->scu);

    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);

    /* FIXME: This setting should be derived from the SCU hw strapping
     * register SCU70
     */
    s->pclk_freq = PCLK_HZ;

    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_wdt_ops, s,
                          TYPE_ASPEED_WDT, awc->iosize);
    sysbus_init_mmio(sbd, &s->iomem);
}

static Property aspeed_wdt_properties[] = {
    DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU,
                     AspeedSCUState *),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->desc = "ASPEED Watchdog Controller";
    dc->realize = aspeed_wdt_realize;
    dc->reset = aspeed_wdt_reset;
    set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
    dc->vmsd = &vmstate_aspeed_wdt;
    device_class_set_props(dc, aspeed_wdt_properties);
    dc->desc = "Aspeed watchdog device";
}

static const TypeInfo aspeed_wdt_info = {
    .parent = TYPE_SYS_BUS_DEVICE,
    .name  = TYPE_ASPEED_WDT,
    .instance_size  = sizeof(AspeedWDTState),
    .class_init = aspeed_wdt_class_init,
    .class_size    = sizeof(AspeedWDTClass),
    .abstract      = true,
};

static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);

    dc->desc = "ASPEED 2400 Watchdog Controller";
    awc->iosize = 0x20;
    awc->ext_pulse_width_mask = 0xff;
    awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
    awc->wdt_reload = aspeed_wdt_reload;
    awc->sanitize_ctrl = aspeed_2400_sanitize_ctrl;
    awc->default_status = 0x03EF1480;
    awc->default_reload_value = 0x03EF1480;
}

static const TypeInfo aspeed_2400_wdt_info = {
    .name = TYPE_ASPEED_2400_WDT,
    .parent = TYPE_ASPEED_WDT,
    .instance_size = sizeof(AspeedWDTState),
    .class_init = aspeed_2400_wdt_class_init,
};

static void aspeed_2500_wdt_reset_pulse(AspeedWDTState *s, uint32_t property)
{
    if (property) {
        if (property == WDT_ACTIVE_HIGH_MAGIC) {
            s->regs[WDT_RESET_WIDTH] |= WDT_RESET_WIDTH_ACTIVE_HIGH;
        } else if (property == WDT_ACTIVE_LOW_MAGIC) {
            s->regs[WDT_RESET_WIDTH] &= ~WDT_RESET_WIDTH_ACTIVE_HIGH;
        } else if (property == WDT_PUSH_PULL_MAGIC) {
            s->regs[WDT_RESET_WIDTH] |= WDT_RESET_WIDTH_PUSH_PULL;
        } else if (property == WDT_OPEN_DRAIN_MAGIC) {
            s->regs[WDT_RESET_WIDTH] &= ~WDT_RESET_WIDTH_PUSH_PULL;
        }
    }
}

static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);

    dc->desc = "ASPEED 2500 Watchdog Controller";
    awc->iosize = 0x20;
    awc->ext_pulse_width_mask = 0xfffff;
    awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
    awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
    awc->wdt_reload = aspeed_wdt_reload_1mhz;
    awc->sanitize_ctrl = aspeed_2500_sanitize_ctrl;
    awc->default_status = 0x014FB180;
    awc->default_reload_value = 0x014FB180;
}

static const TypeInfo aspeed_2500_wdt_info = {
    .name = TYPE_ASPEED_2500_WDT,
    .parent = TYPE_ASPEED_WDT,
    .instance_size = sizeof(AspeedWDTState),
    .class_init = aspeed_2500_wdt_class_init,
};

static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);

    dc->desc = "ASPEED 2600 Watchdog Controller";
    awc->iosize = 0x40;
    awc->ext_pulse_width_mask = 0xfffff; /* TODO */
    awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
    awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
    awc->wdt_reload = aspeed_wdt_reload_1mhz;
    awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
    awc->default_status = 0x014FB180;
    awc->default_reload_value = 0x014FB180;
}

static const TypeInfo aspeed_2600_wdt_info = {
    .name = TYPE_ASPEED_2600_WDT,
    .parent = TYPE_ASPEED_WDT,
    .instance_size = sizeof(AspeedWDTState),
    .class_init = aspeed_2600_wdt_class_init,
};

static void aspeed_1030_wdt_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);

    dc->desc = "ASPEED 1030 Watchdog Controller";
    awc->iosize = 0x80;
    awc->ext_pulse_width_mask = 0xfffff; /* TODO */
    awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
    awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
    awc->wdt_reload = aspeed_wdt_reload_1mhz;
    awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
    awc->default_status = 0x014FB180;
    awc->default_reload_value = 0x014FB180;
}

static const TypeInfo aspeed_1030_wdt_info = {
    .name = TYPE_ASPEED_1030_WDT,
    .parent = TYPE_ASPEED_WDT,
    .instance_size = sizeof(AspeedWDTState),
    .class_init = aspeed_1030_wdt_class_init,
};

static void wdt_aspeed_register_types(void)
{
    type_register_static(&aspeed_wdt_info);
    type_register_static(&aspeed_2400_wdt_info);
    type_register_static(&aspeed_2500_wdt_info);
    type_register_static(&aspeed_2600_wdt_info);
    type_register_static(&aspeed_1030_wdt_info);
}

type_init(wdt_aspeed_register_types)
