/*
 * Copyright (C) 2024 Vogl Electronic GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT litex_watchdog

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

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

#include <soc.h>

struct wdt_litex_data {
	wdt_callback_t callback;
	uint32_t timeout;
	bool reset_soc_mode;
	bool pause_halted;
};

struct wdt_litex_config {
	uint32_t control_addr;
	uint32_t cycles_addr;
	uint32_t cycles_size;
	uint32_t remaining_addr;
	uint32_t ev_status_addr;
	uint32_t ev_pending_addr;
	uint32_t ev_enable_addr;
	void (*irq_cfg_func)(void);
};

#define CONTROL_FEED_BIT         BIT(0)
#define CONTROL_ENABLE_BIT       BIT(8)
#define CONTROL_RESET_BIT        BIT(16)
#define CONTROL_PAUSE_HALTED_BIT BIT(24)

static bool wdt_litex_is_enabled(const struct device *dev)
{
	const struct wdt_litex_config *config = dev->config;

	return litex_read8(config->control_addr) & BIT(0);
}

static void wdt_litex_irq_enable(const struct device *dev)
{
	const struct wdt_litex_config *config = dev->config;
	struct wdt_litex_data *data = dev->data;

	if (!data->callback) {
		return;
	}

	litex_write8(BIT(0), config->ev_pending_addr);

	litex_write8(BIT(0), config->ev_enable_addr);
}

static void wdt_litex_enable(const struct device *dev)
{
	const struct wdt_litex_config *config = dev->config;
	struct wdt_litex_data *data = dev->data;
	uint32_t control;

	if (config->cycles_size <= 4) {
		litex_write32(k_ms_to_cyc_floor32(data->timeout), config->cycles_addr);
	} else {
		litex_write64(k_ms_to_cyc_floor64(data->timeout), config->cycles_addr);
	}

	control = CONTROL_FEED_BIT | CONTROL_ENABLE_BIT;

	if (data->reset_soc_mode) {
		control |= CONTROL_RESET_BIT;
	}
	if (data->pause_halted) {
		control |= CONTROL_PAUSE_HALTED_BIT;
	}

	litex_write32(control, config->control_addr);

	wdt_litex_irq_enable(dev);
}

static int wdt_litex_disable(const struct device *dev)
{
	const struct wdt_litex_config *config = dev->config;

	litex_write8(0, config->ev_enable_addr);

	if (!wdt_litex_is_enabled(dev)) {
		return -EFAULT;
	}
	litex_write16(CONTROL_ENABLE_BIT, config->control_addr);

	return 0;
}

static int wdt_litex_feed(const struct device *dev, int channel_id)
{
	const struct wdt_litex_config *config = dev->config;

	if (channel_id != 0) {
		return -EINVAL;
	}

	litex_write8(CONTROL_FEED_BIT, config->control_addr);

	return 0;
}

static int wdt_litex_setup(const struct device *dev, uint8_t options)
{
	struct wdt_litex_data *data = dev->data;

	data->pause_halted = !!(options & WDT_OPT_PAUSE_HALTED_BY_DBG);

	if (options & WDT_OPT_PAUSE_IN_SLEEP) {
		return -ENOTSUP;
	}

	if (wdt_litex_is_enabled(dev)) {
		return -EBUSY;
	}

	wdt_litex_enable(dev);
	wdt_litex_feed(dev, 0);

	return 0;
}

static int wdt_litex_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *cfg)
{
	const struct wdt_litex_config *config = dev->config;
	struct wdt_litex_data *data = dev->data;

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

	if (cfg->window.max > (config->cycles_size <= 4 ? k_cyc_to_ms_floor32(UINT32_MAX)
							: k_cyc_to_ms_floor64(UINT64_MAX))) {
		return -EINVAL;
	}

	if (wdt_litex_is_enabled(dev)) {
		return -EBUSY;
	}

	data->timeout = cfg->window.max;
	data->callback = cfg->callback;

	/* Set mode of watchdog and callback */
	switch (cfg->flags) {
	case WDT_FLAG_RESET_SOC:
		LOG_DBG("Configuring reset SOC mode");
		data->reset_soc_mode = true;
		break;

	case WDT_FLAG_RESET_NONE:
		LOG_DBG("Configuring non-reset mode");
		data->reset_soc_mode = false;
		break;

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

	return 0;
}

static void wdt_litex_isr(void *arg)
{
	const struct device *dev = (const struct device *)arg;
	const struct wdt_litex_config *config = dev->config;
	struct wdt_litex_data *data = dev->data;
	unsigned int key = irq_lock();

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

	litex_write8(BIT(0), config->ev_pending_addr);

	irq_unlock(key);
}

static int wdt_litex_init(const struct device *dev)
{
	const struct wdt_litex_config *const config = dev->config;

	config->irq_cfg_func();

#ifndef CONFIG_WDT_DISABLE_AT_BOOT
	wdt_litex_enable(dev);
#endif

	return 0;
}

static const struct wdt_driver_api wdt_api = {
	.setup = wdt_litex_setup,
	.disable = wdt_litex_disable,
	.install_timeout = wdt_litex_install_timeout,
	.feed = wdt_litex_feed,
};

#define LITEX_WDT_INIT(n)                                                                          \
	static void wdt_litex_cfg_func_##n(void);                                                  \
                                                                                                   \
	static struct wdt_litex_data wdt_litex_data##n;                                            \
	static struct wdt_litex_config wdt_litex_config##n = {                                     \
		.control_addr = DT_INST_REG_ADDR_BY_NAME(n, control),                              \
		.cycles_addr = DT_INST_REG_ADDR_BY_NAME(n, cycles),                                \
		.cycles_size = DT_INST_REG_SIZE_BY_NAME(n, cycles),                                \
		.remaining_addr = DT_INST_REG_ADDR_BY_NAME(n, remaining),                          \
		.ev_status_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_status),                          \
		.ev_pending_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_pending),                        \
		.ev_enable_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_enable),                          \
		.irq_cfg_func = wdt_litex_cfg_func_##n,                                            \
	};                                                                                         \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(n, wdt_litex_init, NULL, &wdt_litex_data##n, &wdt_litex_config##n,   \
			      PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &wdt_api)          \
                                                                                                   \
	static void wdt_litex_cfg_func_##n(void)                                                   \
	{                                                                                          \
		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), wdt_litex_isr,              \
			    DEVICE_DT_INST_GET(n), 0);                                             \
		irq_enable(DT_INST_IRQN(n));                                                       \
	}

DT_INST_FOREACH_STATUS_OKAY(LITEX_WDT_INIT)
