/*
 * 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)

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->config;
	struct wdt_gecko_data *data = dev->data;
	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->config;
	struct wdt_gecko_data *data = dev->data;
	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;
	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->config;
	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->config;
	struct wdt_gecko_data *data = dev->data;
	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->config;

#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, NULL,			\
				&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)
