/*
 * Copyright (c) 2019 Interay Solutions B.V.
 * Copyright (c) 2019 Oane Kingma
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT silabs_gecko_wdog

#include <soc.h>
#include <drivers/watchdog.h>
#include <em_wdog.h>
#include <em_cmu.h>

#include <logging/log.h>
LOG_MODULE_REGISTER(wdt_gecko, CONFIG_WDT_LOG_LEVEL);

#ifdef cmuClock_CORELE
#define CLOCK_DEF(id) cmuClock_CORELE
#else
#define CLOCK_DEF(id) cmuClock_WDOG##id
#endif /* cmuClock_CORELE */
#define CLOCK_ID(id) CLOCK_DEF(id)

/* Defines maximum WDOG_CTRL.PERSEL value which is used by the watchdog module
 * to select its timeout period.
 */
#define WDT_GECKO_MAX_PERIOD_SELECT_VALUE 15

/* Device constant configuration parameters */
struct wdt_gecko_cfg {
	WDOG_TypeDef *base;
	CMU_Clock_TypeDef clock;
	void (*irq_cfg_func)(void);
};

struct wdt_gecko_data {
	wdt_callback_t callback;
	WDOG_Init_TypeDef wdog_config;
	bool timeout_installed;
};

#define DEV_NAME(dev) ((dev)->name)
#define DEV_DATA(dev) \
	((struct wdt_gecko_data *)(dev)->data)
#define DEV_CFG(dev) \
	((const struct wdt_gecko_cfg *)(dev)->config)

static uint32_t wdt_gecko_get_timeout_from_persel(int perSel)
{
	return (8 << perSel) + 1;
}

/* Find the rounded up value of cycles for supplied timeout. When using ULFRCO
 * (default), 1 cycle is 1 ms +/- 12%.
 */
static int wdt_gecko_get_persel_from_timeout(uint32_t timeout)
{
	int idx;

	for (idx = 0; idx < WDT_GECKO_MAX_PERIOD_SELECT_VALUE; idx++) {
		if (wdt_gecko_get_timeout_from_persel(idx) >= timeout) {
			break;
		}
	}

	return idx;
}

static int wdt_gecko_convert_window(uint32_t window, uint32_t period)
{
	int idx = 0;
	uint32_t incr_val, comp_val;

	incr_val = period / 8;
	comp_val = 0; /* Initially 0, disable */

	/* Valid window settings range from 12.5% of the calculated
	 * timeout period up to 87.5% (= 7 * 12.5%)
	 */
	while (idx < 7) {
		if (window > comp_val) {
			comp_val += incr_val;
			idx++;
			continue;
		}

		break;
	}

	return idx;
}

static int wdt_gecko_setup(const struct device *dev, uint8_t options)
{
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);
	struct wdt_gecko_data *data = DEV_DATA(dev);
	WDOG_TypeDef *wdog = config->base;

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

	data->wdog_config.em2Run =
		(options & WDT_OPT_PAUSE_IN_SLEEP) == 0U;
	data->wdog_config.em3Run =
		(options & WDT_OPT_PAUSE_IN_SLEEP) == 0U;

	data->wdog_config.debugRun =
		(options & WDT_OPT_PAUSE_HALTED_BY_DBG) == 0U;

	if (data->callback != NULL) {
		/* Interrupt mode for window */
		/* Clear possible lingering interrupts */
		WDOGn_IntClear(wdog, WDOG_IEN_TOUT);
		/* Enable timeout interrupt */
		WDOGn_IntEnable(wdog, WDOG_IEN_TOUT);
	} else {
		/* Disable timeout interrupt */
		WDOGn_IntDisable(wdog, WDOG_IEN_TOUT);
	}

	/* Watchdog is started after initialization */
	WDOGn_Init(wdog, &data->wdog_config);
	LOG_DBG("Setup the watchdog");

	return 0;
}

static int wdt_gecko_disable(const struct device *dev)
{
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);
	struct wdt_gecko_data *data = DEV_DATA(dev);
	WDOG_TypeDef *wdog = config->base;

	WDOGn_Enable(wdog, false);
	data->timeout_installed = false;
	LOG_DBG("Disabled the watchdog");

	return 0;
}

static int wdt_gecko_install_timeout(const struct device *dev,
				     const struct wdt_timeout_cfg *cfg)
{
	struct wdt_gecko_data *data = DEV_DATA(dev);
	data->wdog_config = (WDOG_Init_TypeDef)WDOG_INIT_DEFAULT;
	uint32_t installed_timeout;

	if (data->timeout_installed) {
		LOG_ERR("No more timeouts can be installed");
		return -ENOMEM;
	}

	if ((cfg->window.max < wdt_gecko_get_timeout_from_persel(0)) ||
		(cfg->window.max > wdt_gecko_get_timeout_from_persel(
			WDT_GECKO_MAX_PERIOD_SELECT_VALUE))) {
		LOG_ERR("Upper limit timeout out of range");
		return -EINVAL;
	}

#if defined(_WDOG_CTRL_CLKSEL_MASK)
	data->wdog_config.clkSel = wdogClkSelULFRCO;
#endif

	data->wdog_config.perSel = (WDOG_PeriodSel_TypeDef)
		wdt_gecko_get_persel_from_timeout(cfg->window.max);

	installed_timeout = wdt_gecko_get_timeout_from_persel(
		data->wdog_config.perSel);
	LOG_INF("Installed timeout value: %u", installed_timeout);

	if (cfg->window.min > 0) {
		/* Window mode. Use rounded up timeout value to
		 * calculate minimum window setting.
		 */
		data->wdog_config.winSel = (WDOG_WinSel_TypeDef)
			wdt_gecko_convert_window(cfg->window.min,
						installed_timeout);

		LOG_INF("Installed window value: %u",
			(installed_timeout / 8) * data->wdog_config.winSel);
	} else {
		/* Normal mode */
		data->wdog_config.winSel = wdogIllegalWindowDisable;
	}

	/* Set mode of watchdog and callback */
	switch (cfg->flags) {
	case WDT_FLAG_RESET_SOC:
	case WDT_FLAG_RESET_CPU_CORE:
		if (cfg->callback != NULL) {
			LOG_ERR("Reset mode with callback not supported\n");
			return -ENOTSUP;
		}
		data->wdog_config.resetDisable = false;
		LOG_DBG("Configuring reset CPU/SoC mode\n");
		break;

	case WDT_FLAG_RESET_NONE:
		data->wdog_config.resetDisable = true;
		data->callback = cfg->callback;
		LOG_DBG("Configuring non-reset mode\n");
		break;

	default:
		LOG_ERR("Unsupported watchdog config flag");
		return -EINVAL;
	}

	data->timeout_installed = true;

	return 0;
}

static int wdt_gecko_feed(const struct device *dev, int channel_id)
{
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);
	WDOG_TypeDef *wdog = config->base;

	if (channel_id != 0) {
		LOG_ERR("Invalid channel id");
		return -EINVAL;
	}

	WDOGn_Feed(wdog);
	LOG_DBG("Fed the watchdog");

	return 0;
}

static void wdt_gecko_isr(const struct device *dev)
{
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);
	struct wdt_gecko_data *data = DEV_DATA(dev);
	WDOG_TypeDef *wdog = config->base;
	uint32_t flags;

	/* Clear IRQ flags */
	flags = WDOGn_IntGet(wdog);
	WDOGn_IntClear(wdog, flags);

	if (data->callback != NULL) {
		data->callback(dev, 0);
	}
}

static int wdt_gecko_init(const struct device *dev)
{
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);

#ifdef CONFIG_WDT_DISABLE_AT_BOOT
	/* Ignore any errors */
	wdt_gecko_disable(dev);
#endif

	/* Enable ULFRCO (1KHz) oscillator */
	CMU_OscillatorEnable(cmuOsc_ULFRCO, true, false);

#if !defined(_SILICON_LABS_32B_SERIES_2)
	/* Ensure LE modules are clocked */
	CMU_ClockEnable(config->clock, true);
#else
	CMU_ClockSelectSet(config->clock, cmuSelect_ULFRCO);
#endif

	/* Enable IRQs */
	config->irq_cfg_func();

	LOG_INF("Device %s initialized", DEV_NAME(dev));

	return 0;
}

static const struct wdt_driver_api wdt_gecko_driver_api = {
	.setup = wdt_gecko_setup,
	.disable = wdt_gecko_disable,
	.install_timeout = wdt_gecko_install_timeout,
	.feed = wdt_gecko_feed,
};

#define GECKO_WDT_INIT(index)						\
									\
	static void wdt_gecko_cfg_func_##index(void);			\
									\
	static const struct wdt_gecko_cfg wdt_gecko_cfg_##index = {	\
		.base = (WDOG_TypeDef *)				\
			DT_INST_REG_ADDR(index),\
		.clock = CLOCK_ID(DT_INST_PROP(index, peripheral_id)),  \
		.irq_cfg_func = wdt_gecko_cfg_func_##index,		\
	};								\
	static struct wdt_gecko_data wdt_gecko_data_##index;		\
									\
	DEVICE_DT_INST_DEFINE(index,					\
				&wdt_gecko_init, device_pm_control_nop,	\
				&wdt_gecko_data_##index,		\
				&wdt_gecko_cfg_##index, POST_KERNEL,	\
				CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,	\
				&wdt_gecko_driver_api);			\
									\
	static void wdt_gecko_cfg_func_##index(void)			\
	{								\
		IRQ_CONNECT(DT_INST_IRQN(index),	\
			DT_INST_IRQ(index, priority),\
			wdt_gecko_isr, DEVICE_DT_INST_GET(index), 0);	\
		irq_enable(DT_INST_IRQN(index));	\
	}

DT_INST_FOREACH_STATUS_OKAY(GECKO_WDT_INIT)
