/*
 * 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 "system/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 WDT_SW_RESET_ENABLE             0xAEEDF123

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

static bool aspeed_wdt_is_soc_reset_mode(const AspeedWDTState *s)
{
    uint32_t mode;

    mode = extract32(s->regs[WDT_CTRL], 5, 2);
    return (mode == WDT_CTRL_RESET_MODE_SOC);
}

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_MASK1:
    case WDT_SW_RESET_MASK2:
        qemu_log_mask(LOG_UNIMP,
                      "%s: uninmplemented write at offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
        break;
    case WDT_SW_RESET_CTRL:
        if (aspeed_wdt_is_soc_reset_mode(s) &&
            (data == WDT_SW_RESET_ENABLE)) {
            watchdog_perform_action();
        }
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
    }
}

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 const Property aspeed_wdt_properties[] = {
    DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU,
                     AspeedSCUState *),
};

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

    dc->desc = "ASPEED Watchdog Controller";
    dc->realize = aspeed_wdt_realize;
    device_class_set_legacy_reset(dc, 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, const 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, const 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, const 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, const 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 aspeed_2700_wdt_class_init(ObjectClass *klass, const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);

    dc->desc = "ASPEED 2700 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_2700_wdt_info = {
    .name = TYPE_ASPEED_2700_WDT,
    .parent = TYPE_ASPEED_WDT,
    .instance_size = sizeof(AspeedWDTState),
    .class_init = aspeed_2700_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_2700_wdt_info);
    type_register_static(&aspeed_1030_wdt_info);
}

type_init(wdt_aspeed_register_types)
