/*
 * Copyright (c) 2023 Andes Technology Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT andestech_atcwdt200

#include <zephyr/kernel.h>
#include <zephyr/drivers/watchdog.h>

#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
#include <zephyr/drivers/counter.h>
#include <zephyr/drivers/syscon.h>
LOG_MODULE_REGISTER(wdt_andes);

/* Watchdog register */
#define REG_IDR			0x00
#define REG_CTRL		0x10
#define REG_RESTAR		0x14
#define REG_WREN		0x18
#define REG_STATUS		0x1c

#define WDT_CTRL(addr)		(addr + REG_CTRL)
#define WDT_RESTAR(addr)	(addr + REG_RESTAR)
#define WDT_WREN(addr)		(addr + REG_WREN)
#define WDT_STATUS(addr)	(addr + REG_STATUS)

/* Atcwdt200 magic number */
/* 0x10 Control Register */

#define WDT_CTRL_RSTTIME_POW_2_7	0x000
#define WDT_CTRL_RSTTIME_POW_2_8	0x100
#define WDT_CTRL_RSTTIME_POW_2_9	0x200
#define WDT_CTRL_RSTTIME_POW_2_10	0x300
#define WDT_CTRL_RSTTIME_POW_2_11	0x400
#define WDT_CTRL_RSTTIME_POW_2_12	0x500
#define WDT_CTRL_RSTTIME_POW_2_13	0x600
#define WDT_CTRL_RSTTIME_POW_2_14	0x700

#define WDT_CTRL_INTTIME_POW_2_6	0x000
#define WDT_CTRL_INTTIME_POW_2_8	0x010
#define WDT_CTRL_INTTIME_POW_2_10	0x020
#define WDT_CTRL_INTTIME_POW_2_11	0x030
#define WDT_CTRL_INTTIME_POW_2_12	0x040
#define WDT_CTRL_INTTIME_POW_2_13	0x050
#define WDT_CTRL_INTTIME_POW_2_14	0x060
#define WDT_CTRL_INTTIME_POW_2_15	0x070
#define WDT_CTRL_INTTIME_POW_2_17	0x080
#define WDT_CTRL_INTTIME_POW_2_19	0x090
#define WDT_CTRL_INTTIME_POW_2_21	0x0A0
#define WDT_CTRL_INTTIME_POW_2_23	0x0B0
#define WDT_CTRL_INTTIME_POW_2_25	0x0C0
#define WDT_CTRL_INTTIME_POW_2_27	0x0D0
#define WDT_CTRL_INTTIME_POW_2_29	0x0E0
#define WDT_CTRL_INTTIME_POW_2_31	0x0F0

#define WDT_CTRL_RSTEN			0x8
#define WDT_CTRL_INTEN			0x4
#define WDT_CTRL_APBCLK			0x2
#define WDT_CTRL_EXTCLK			0x0
#define WDT_CTRL_EN			0x1

/* Magic Number for Restart Register */
#define WDT_RESTART_NUM                 0xcafe

/* Magic Number for Write Enable Register */
#define WDT_WREN_NUM                    0x5aa5

/* 0x1C Status Register */
#define WDT_ST_INTEXPIRED               0x1
#define WDT_ST_INTEXPIRED_CLR           0x1

/*
 * SMU(System Management Unit) Registers for hwinfo driver
 */

/* Register offset*/
#define SMU_RESET_WRSR			0x10
#define SMU_RESET_REGHI			0x60
#define SMU_RESET_REGLO			0x50
#define SMU_CMD				0x14

#define SMU_RESET_CMD			0x3c

#define WDOGCFG_PERIOD_MIN		BIT(7)
#define WDOGCFG_PERIOD_MAX		BIT(14)
#define EXT_CLOCK_FREQ			BIT(15)

static const struct device *const syscon_dev =
				DEVICE_DT_GET(DT_NODELABEL(syscon));
static const struct device *const pit_counter_dev =
				DEVICE_DT_GET(DT_NODELABEL(pit0));

struct counter_alarm_cfg alarm_cfg;

struct wdt_atcwdt200_config {
	uintptr_t base;
};

struct wdt_atcwdt200_dev_data {
	bool timeout_valid;
	counter_alarm_callback_t counter_callback;
	struct k_spinlock lock;
};

static int wdt_atcwdt200_disable(const struct device *dev);

static void wdt_counter_cb(const struct device *counter_dev, uint8_t chan_id,
			uint32_t counter,
			void *user_data)
{
	const struct device *dev = DEVICE_DT_INST_GET(0);
	struct wdt_atcwdt200_dev_data *wdt_data = dev->data;
	uint32_t wdt_addr = ((const struct wdt_atcwdt200_config *)(dev->config))->base;
	k_spinlock_key_t key;

	key = k_spin_lock(&wdt_data->lock);

	sys_write32(WDT_WREN_NUM, WDT_WREN(wdt_addr));
	sys_write32(WDT_RESTART_NUM, WDT_RESTAR(wdt_addr));

	counter_set_channel_alarm(counter_dev, 2, &alarm_cfg);

	k_spin_unlock(&wdt_data->lock, key);
}

/**
 * @brief Set maximum length of timeout to watchdog
 *
 * @param dev Watchdog device struct
 */
static void wdt_atcwdt200_set_max_timeout(const struct device *dev)
{
	struct wdt_atcwdt200_dev_data *data = dev->data;
	k_spinlock_key_t key;
	uint32_t wdt_addr = ((const struct wdt_atcwdt200_config *)(dev->config))->base;
	uint32_t reg, counter_freq;

	key = k_spin_lock(&data->lock);

	counter_freq = counter_get_frequency(pit_counter_dev);

	alarm_cfg.flags = 0;
	alarm_cfg.callback = wdt_counter_cb;
	alarm_cfg.user_data = &alarm_cfg;
	alarm_cfg.ticks = ((WDOGCFG_PERIOD_MAX * counter_freq) / EXT_CLOCK_FREQ) >> 1;

	reg = WDT_CTRL_RSTTIME_POW_2_14;

	sys_write32(WDT_WREN_NUM, WDT_WREN(wdt_addr));
	sys_write32(reg, WDT_CTRL(wdt_addr));

	data->timeout_valid = true;

	k_spin_unlock(&data->lock, key);
}

static int wdt_atcwdt200_disable(const struct device *dev)
{
	struct wdt_atcwdt200_dev_data *data = dev->data;
	uint32_t wdt_addr = ((const struct wdt_atcwdt200_config *)(dev->config))->base;
	k_spinlock_key_t key;
	uint32_t reg;

	key = k_spin_lock(&data->lock);

	reg = sys_read32(WDT_CTRL(wdt_addr));
	reg &= ~(WDT_CTRL_RSTEN | WDT_CTRL_EN);

	sys_write32(WDT_WREN_NUM, WDT_WREN(wdt_addr));
	sys_write32(reg, WDT_CTRL(wdt_addr));

	k_spin_unlock(&data->lock, key);

	wdt_atcwdt200_set_max_timeout(dev);
	counter_cancel_channel_alarm(pit_counter_dev, 2);

	return 0;
}

static int wdt_atcwdt200_setup(const struct device *dev, uint8_t options)
{
	struct wdt_atcwdt200_dev_data *data = dev->data;
	uint32_t wdt_addr = ((const struct wdt_atcwdt200_config *)(dev->config))->base;
	k_spinlock_key_t key;
	uint32_t reg;
	uint32_t ret = 0;

	if (!data->timeout_valid) {
		LOG_ERR("No valid timeouts installed");
		return -EINVAL;
	}

	key = k_spin_lock(&data->lock);

	reg = sys_read32(WDT_CTRL(wdt_addr));
	reg |= (WDT_CTRL_RSTEN | WDT_CTRL_EN);

	if ((options & WDT_OPT_PAUSE_HALTED_BY_DBG) ==
			WDT_OPT_PAUSE_HALTED_BY_DBG) {
		counter_cancel_channel_alarm(pit_counter_dev, 2);
		sys_write32(WDT_WREN_NUM, WDT_WREN(wdt_addr));
		sys_write32(reg, WDT_CTRL(wdt_addr));
		goto out;
	} else {
		ret = counter_set_channel_alarm(pit_counter_dev, 2, &alarm_cfg);
		if (ret != 0) {
			ret = -EINVAL;
			goto out;
		}

		sys_write32(WDT_WREN_NUM, WDT_WREN(wdt_addr));
		sys_write32(reg, WDT_CTRL(wdt_addr));
	}

out:
	k_spin_unlock(&data->lock, key);
	return ret;
}

/**
 * @brief Calculates the watchdog counter value (wdogcmp0) and
 *        scaler (wdogscale) to be installed in the watchdog timer
 *
 * @param timeout Timeout value in milliseconds.
 * @param scaler  Pointer to return scaler power of 2
 *
 * @return Watchdog counter value
 */
static uint32_t wdt_atcwdt200_convtime(uint32_t timeout, uint32_t *scaler)
{
	int i;
	uint32_t rst_period, cnt;

	cnt = (uint32_t)((timeout * EXT_CLOCK_FREQ) / 1000);
	rst_period = cnt;

	for (i = 0; i < 14 && cnt > 0; i++) {
		cnt >>= 1;
	}

	*scaler = i;

	return rst_period;
}

static int wdt_atcwdt200_install_timeout(const struct device *dev,
				      const struct wdt_timeout_cfg *cfg)
{
	struct wdt_atcwdt200_dev_data *data = dev->data;
	uint32_t wdt_addr = ((const struct wdt_atcwdt200_config *)(dev->config))->base;
	k_spinlock_key_t key;
	uint32_t rst_period, reg, counter_freq, scaler;

	if (cfg->window.min != 0U || cfg->window.max == 0U) {
		return -EINVAL;
	}

	counter_freq = counter_get_frequency(pit_counter_dev);
	rst_period = wdt_atcwdt200_convtime(cfg->window.max, &scaler);

	if (rst_period < 0 || WDOGCFG_PERIOD_MAX < rst_period) {
		LOG_ERR("Unsupported watchdog timeout\n");
		return -EINVAL;
	}

	wdt_atcwdt200_disable(dev);

	key = k_spin_lock(&data->lock);

	switch (cfg->flags) {
	case WDT_FLAG_RESET_SOC:
		if (scaler < 7) {
			reg = WDT_CTRL_RSTTIME_POW_2_7;
		} else {
			scaler = scaler - 7;
			reg = scaler << 8;
		}

		alarm_cfg.flags = 0;
		alarm_cfg.callback = wdt_counter_cb;
		alarm_cfg.user_data = &alarm_cfg;
		alarm_cfg.ticks = (((cfg->window.max * counter_freq) / 1000) >> 1);

		break;
	case WDT_FLAG_RESET_NONE:
	case WDT_FLAG_RESET_CPU_CORE:
	default:
		LOG_ERR("Unsupported watchdog config flags\n");
		k_spin_unlock(&data->lock, key);
		return -ENOTSUP;
	}

	sys_write32(WDT_WREN_NUM, WDT_WREN(wdt_addr));
	sys_write32(reg, WDT_CTRL(wdt_addr));

	k_spin_unlock(&data->lock, key);
	return 0;
}

static int wdt_atcwdt200_feed(const struct device *dev, int channel_id)
{
	uint32_t wdt_addr = ((const struct wdt_atcwdt200_config *)(dev->config))->base;

	ARG_UNUSED(channel_id);

	sys_write32(WDT_WREN_NUM, WDT_WREN(wdt_addr));
	sys_write32(WDT_RESTART_NUM, WDT_RESTAR(wdt_addr));

	return 0;
}

static const struct wdt_driver_api wdt_atcwdt200_api = {
	.setup = wdt_atcwdt200_setup,
	.disable = wdt_atcwdt200_disable,
	.install_timeout = wdt_atcwdt200_install_timeout,
	.feed = wdt_atcwdt200_feed,
};

static int wdt_atcwdt200_init(const struct device *dev)
{
	struct wdt_atcwdt200_dev_data *data = dev->data;

	data->timeout_valid = false;
	data->counter_callback = wdt_counter_cb;
	uint32_t ret;

	counter_start(pit_counter_dev);

	ret = syscon_write_reg(syscon_dev, SMU_RESET_REGLO,
				((uint32_t)((unsigned long)
					Z_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY))));
	if (ret < 0) {
		return -EINVAL;
	}

	ret = syscon_write_reg(syscon_dev, SMU_RESET_REGHI,
				((uint32_t)((uint64_t)((unsigned long)
						Z_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY)) >> 32)));
	if (ret < 0) {
		return -EINVAL;
	}

#ifdef CONFIG_WDT_DISABLE_AT_BOOT
	wdt_atcwdt200_disable(dev);
#else
	data->timeout_valid = true;
	wdt_atcwdt200_set_max_timeout(dev);
	wdt_atcwdt200_setup(dev, 0x0);
#endif
	return 0;
}

static struct wdt_atcwdt200_dev_data wdt_atcwdt200_data;

static const struct wdt_atcwdt200_config wdt_atcwdt200_cfg = {
	.base = DT_INST_REG_ADDR(0),
};

DEVICE_DT_INST_DEFINE(0, wdt_atcwdt200_init, NULL,
		      &wdt_atcwdt200_data, &wdt_atcwdt200_cfg, PRE_KERNEL_2,
		      CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &wdt_atcwdt200_api);
