/*
 * Copyright (c) 2022, Jamie McCrae
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT raspberrypi_pico_watchdog

#include <hardware/watchdog.h>
#include <hardware/structs/psm.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/watchdog.h>
#include <zephyr/sys_clock.h>

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

/* Maximum watchdog time is halved due to errata RP2040-E1 */
#define RPI_PICO_MAX_WDT_TIME (0xffffff / 2)
#define RPI_PICO_WDT_TIME_MULTIPLICATION_FACTOR 2

/* Watchdog requires a 1MHz clock source, divided from the crystal oscillator */
#define RPI_PICO_CLK_REF_FREQ_WDT_TICK_DIVISOR 1000000

struct wdt_rpi_pico_data {
	uint8_t reset_type;
	uint32_t load;
	bool enabled;
};

struct wdt_rpi_pico_config {
	const struct device *clk_dev;
	clock_control_subsys_t clk_id;
};

static int wdt_rpi_pico_setup(const struct device *dev, uint8_t options)
{
	const struct wdt_rpi_pico_config *config = dev->config;
	struct wdt_rpi_pico_data *data = dev->data;
	uint32_t ref_clk;
	int err;

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

	hw_clear_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_ENABLE_BITS);

	psm_hw->wdsel = 0;

	/* TODO: Handle individual core reset when SMP support for RP2040 is added */
	if (data->reset_type == WDT_FLAG_RESET_SOC) {
		hw_set_bits(&psm_hw->wdsel, PSM_WDSEL_BITS);
	} else if (data->reset_type == WDT_FLAG_RESET_CPU_CORE) {
		hw_set_bits(&psm_hw->wdsel, PSM_WDSEL_PROC0_BITS);
	}

	if ((options & WDT_OPT_PAUSE_HALTED_BY_DBG) == 0) {
		hw_clear_bits(&watchdog_hw->ctrl,
			      (WATCHDOG_CTRL_PAUSE_JTAG_BITS | WATCHDOG_CTRL_PAUSE_DBG0_BITS |
			       WATCHDOG_CTRL_PAUSE_DBG1_BITS));
	} else {
		hw_set_bits(&watchdog_hw->ctrl,
			    (WATCHDOG_CTRL_PAUSE_JTAG_BITS | WATCHDOG_CTRL_PAUSE_DBG0_BITS |
			     WATCHDOG_CTRL_PAUSE_DBG1_BITS));
	}

	watchdog_hw->load = data->load;

	/* Zero out the scratch registers so that the module reboots at the
	 * default program counter
	 */
	watchdog_hw->scratch[4] = 0;
	watchdog_hw->scratch[5] = 0;
	watchdog_hw->scratch[6] = 0;
	watchdog_hw->scratch[7] = 0;

	hw_set_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_ENABLE_BITS);

	data->enabled = true;

	err = clock_control_on(config->clk_dev, config->clk_id);
	if (err < 0) {
		return err;
	}

	err = clock_control_get_rate(config->clk_dev, config->clk_id, &ref_clk);
	if (err < 0) {
		return err;
	}

	watchdog_hw->tick = (ref_clk / RPI_PICO_CLK_REF_FREQ_WDT_TICK_DIVISOR) |
			    WATCHDOG_TICK_ENABLE_BITS;

	return 0;
}

static int wdt_rpi_pico_disable(const struct device *dev)
{
	struct wdt_rpi_pico_data *data = dev->data;

	if (data->enabled == false) {
		return -EFAULT;
	}

	hw_clear_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_ENABLE_BITS);

	data->enabled = false;

	return 0;
}

static int wdt_rpi_pico_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *cfg)
{
	struct wdt_rpi_pico_data *data = dev->data;

	if (cfg->window.min != 0U || cfg->window.max == 0U) {
		return -EINVAL;
	} else if (cfg->window.max * USEC_PER_MSEC > RPI_PICO_MAX_WDT_TIME) {
		return -EINVAL;
	} else if (cfg->callback != NULL) {
		return -ENOTSUP;
	} else if ((cfg->flags & WDT_FLAG_RESET_MASK) == WDT_FLAG_RESET_NONE) {
		/* The RP2040 does technically support this mode, but requires
		 * a program counter and stack pointer value to be set,
		 * therefore do not allow configuring in this mode
		 */
		return -EINVAL;
	}

	data->load = (cfg->window.max * USEC_PER_MSEC * RPI_PICO_WDT_TIME_MULTIPLICATION_FACTOR);
	data->reset_type = (cfg->flags & WDT_FLAG_RESET_MASK);

	return 0;
}

static int wdt_rpi_pico_feed(const struct device *dev, int channel_id)
{
	struct wdt_rpi_pico_data *data = dev->data;

	if (channel_id != 0) {
		/* There is only one input to the watchdog */
		return -EINVAL;
	}

	if (data->enabled == false) {
		/* Watchdog is not running so does not need to be fed */
		return -EINVAL;
	}

	watchdog_hw->load = data->load;

	return 0;
}

static int wdt_rpi_pico_init(const struct device *dev)
{
#ifndef CONFIG_WDT_DISABLE_AT_BOOT
	return wdt_rpi_pico_setup(dev, WDT_OPT_PAUSE_HALTED_BY_DBG);
#endif

	return 0;
}

static const struct wdt_driver_api wdt_rpi_pico_driver_api = {
	.setup = wdt_rpi_pico_setup,
	.disable = wdt_rpi_pico_disable,
	.install_timeout = wdt_rpi_pico_install_timeout,
	.feed = wdt_rpi_pico_feed,
};

#define WDT_RPI_PICO_WDT_DEVICE(idx)                                                               \
	static const struct wdt_rpi_pico_config wdt_##idx##_config = {                             \
		.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)),				   \
		.clk_id = (clock_control_subsys_t)DT_INST_PHA_BY_IDX(idx, clocks, 0, clk_id),	   \
	};                                                                                         \
	static struct wdt_rpi_pico_data wdt_##idx##_data = {                                       \
		.reset_type = WDT_FLAG_RESET_SOC,                                                  \
		.load = (CONFIG_WDT_RPI_PICO_INITIAL_TIMEOUT *                                     \
			 RPI_PICO_WDT_TIME_MULTIPLICATION_FACTOR),                                 \
		.enabled = false                                                                   \
	};                                                                                         \
	DEVICE_DT_DEFINE(DT_NODELABEL(wdt##idx), wdt_rpi_pico_init, NULL, &wdt_##idx##_data,       \
			 &wdt_##idx##_config, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,    \
			 &wdt_rpi_pico_driver_api)

DT_INST_FOREACH_STATUS_OKAY(WDT_RPI_PICO_WDT_DEVICE);
