/* wdt_xec.c - Microchip XEC watchdog driver */

#define DT_DRV_COMPAT microchip_xec_watchdog

/*
 * Copyright (c) 2019 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(wdt_mchp_xec);

#include <zephyr/drivers/watchdog.h>
#include <soc.h>
#include <errno.h>

BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1,
	     "add exactly one wdog node to the devicetree");

struct wdt_xec_config {
	struct wdt_regs *regs;
	uint8_t girq;
	uint8_t girq_pos;
};

struct wdt_xec_data {
	wdt_callback_t cb;
	bool timeout_installed;
};

static int wdt_xec_setup(const struct device *dev, uint8_t options)
{
	struct wdt_xec_config const *cfg = dev->config;
	struct wdt_xec_data *data = dev->data;
	struct wdt_regs *regs = cfg->regs;

	if (regs->CTRL & MCHP_WDT_CTRL_EN) {
		return -EBUSY;
	}

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

	if (options & WDT_OPT_PAUSE_IN_SLEEP) {
		LOG_WRN("WDT_OPT_PAUSE_IN_SLEEP is not supported");
		return -ENOTSUP;
	}

	if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) {
		regs->CTRL |= MCHP_WDT_CTRL_JTAG_STALL_EN;
	} else {
		regs->CTRL &= ~MCHP_WDT_CTRL_JTAG_STALL_EN;
	}

	regs->CTRL |= MCHP_WDT_CTRL_EN;

	LOG_DBG("WDT Setup and enabled");

	return 0;
}

static int wdt_xec_disable(const struct device *dev)
{
	struct wdt_xec_config const *cfg = dev->config;
	struct wdt_xec_data *data = dev->data;
	struct wdt_regs *regs = cfg->regs;

	if (!(regs->CTRL & MCHP_WDT_CTRL_EN)) {
		return -EALREADY;
	}

	regs->CTRL &= ~MCHP_WDT_CTRL_EN;
	data->timeout_installed = false;

	LOG_DBG("WDT Disabled");

	return 0;
}

static int wdt_xec_install_timeout(const struct device *dev,
				   const struct wdt_timeout_cfg *config)
{
	struct wdt_xec_config const *cfg = dev->config;
	struct wdt_xec_data *data = dev->data;
	struct wdt_regs *regs = cfg->regs;

	if (regs->CTRL & MCHP_WDT_CTRL_EN) {
		return -EBUSY;
	}

	if (config->window.min > 0U) {
		data->timeout_installed = false;
		return -EINVAL;
	}

	regs->LOAD = 0;

	data->cb = config->callback;
	if (data->cb) {
		regs->CTRL |= MCHP_WDT_CTRL_MODE_IRQ;
		regs->IEN |= MCHP_WDT_IEN_EVENT_IRQ_EN;

		LOG_DBG("WDT callback enabled");
	} else {
		/* Setting WDT_FLAG_RESET_SOC or not will have no effect:
		 * even after the cb, if anything is done, SoC will reset
		 */
		regs->CTRL &= ~MCHP_WDT_CTRL_MODE_IRQ;
		regs->IEN &= ~MCHP_WDT_IEN_EVENT_IRQ_EN;

		LOG_DBG("WDT Reset enabled");
	}

	/* Since it almost takes 1ms to decrement the load register
	 * (See datasheet 18.6.1.4: 33/32.768 KHz = 1.007ms)
	 * Let's use the given window directly.
	 */
	regs->LOAD = config->window.max;

	data->timeout_installed = true;

	return 0;
}

static int wdt_xec_feed(const struct device *dev, int channel_id)
{
	struct wdt_xec_config const *cfg = dev->config;
	struct wdt_regs *regs = cfg->regs;

	ARG_UNUSED(dev);
	ARG_UNUSED(channel_id);

	if (!(regs->CTRL & MCHP_WDT_CTRL_EN)) {
		return -EINVAL;
	}

	LOG_DBG("WDT Kicking");

	regs->KICK = 1;

	return 0;
}

static void wdt_xec_isr(const struct device *dev)
{
	struct wdt_xec_config const *cfg = dev->config;
	struct wdt_xec_data *data = dev->data;
	struct wdt_regs *regs = cfg->regs;

	LOG_DBG("WDT ISR");

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

#ifdef CONFIG_SOC_SERIES_MEC172X
	mchp_soc_ecia_girq_src_clr(cfg->girq, cfg->girq_pos);
#else
	MCHP_GIRQ_SRC(MCHP_WDT_GIRQ) = BIT(cfg->girq_pos);
#endif
	regs->IEN &= ~MCHP_WDT_IEN_EVENT_IRQ_EN;
}

static const struct wdt_driver_api wdt_xec_api = {
	.setup = wdt_xec_setup,
	.disable = wdt_xec_disable,
	.install_timeout = wdt_xec_install_timeout,
	.feed = wdt_xec_feed,
};

static int wdt_xec_init(const struct device *dev)
{
	struct wdt_xec_config const *cfg = dev->config;

	if (IS_ENABLED(CONFIG_WDT_DISABLE_AT_BOOT)) {
		wdt_xec_disable(dev);
	}

#ifdef CONFIG_SOC_SERIES_MEC172X
	mchp_soc_ecia_girq_src_en(cfg->girq, cfg->girq_pos);
#else
	MCHP_GIRQ_ENSET(MCHP_WDT_GIRQ) = BIT(cfg->girq_pos);
#endif

	IRQ_CONNECT(DT_INST_IRQN(0),
		    DT_INST_IRQ(0, priority),
		    wdt_xec_isr, DEVICE_DT_INST_GET(0), 0);
	irq_enable(DT_INST_IRQN(0));

	return 0;
}

static const struct wdt_xec_config wdt_xec_config_0 = {
	.regs = (struct wdt_regs *)(DT_INST_REG_ADDR(0)),
	.girq = DT_INST_PROP_BY_IDX(0, girqs, 0),
	.girq_pos = DT_INST_PROP_BY_IDX(0, girqs, 1),
};

static struct wdt_xec_data wdt_xec_dev_data;

DEVICE_DT_INST_DEFINE(0, wdt_xec_init, NULL,
		    &wdt_xec_dev_data, &wdt_xec_config_0,
		    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &wdt_xec_api);
