/* SPDX-License-Identifier: Apache-2.0 */
/*
 * Copyright (c) 2023 Intel Corporation
 *
 * Author: Adrian Warecki <adrian.warecki@intel.com>
 */

/**
 * @file
 *
 * @brief Intel ACE per-core watchdogs driver
 *
 * The ace platform has a set of designware watchdogs, one for each core. This driver is responsible
 * for finding the base addresses of subordinate devices, controlling the pause signal and handling
 * interrupts. The registers from the DSP Core Watch Dog Timer Control & Status block are used for
 * this purpose. This block is shared by all per-core watchdogs.
 *
 * The base addresses of the subordinate watchdogs are read from the control registers. As a result,
 * in the device tree we have only one base address for the intel watchdog.
 *
 * The designware watchdog only supports a hardware pause signal. It cannot be paused
 * programmatically. On ace platform there are GPIO-like registers that allows control of a hardware
 * pause signal for subordinate watchdogs.
 *
 * All subordinate watchdog devices share the same interrupt number. Each watchdog reports
 * an interrupt to the core to which it has been assigned. The same interrupt number cannot
 * be used by multiple devices in the device tree. This driver handles interrupts from all
 * subordinate watchdogs and identifies which device signal it.
 */

#define DT_DRV_COMPAT intel_adsp_watchdog

#include <zephyr/drivers/watchdog.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys_clock.h>
#include <zephyr/math/ilog2.h>

#include "wdt_dw.h"
#include "wdt_dw_common.h"
#include "wdt_intel_adsp.h"

LOG_MODULE_REGISTER(wdt_intel_adsp, CONFIG_WDT_LOG_LEVEL);

#define DEV_NODE				DT_INST(0, DT_DRV_COMPAT)
#define WDT_INTEL_ADSP_INTERRUPT_SUPPORT	DT_NODE_HAS_PROP(DEV_NODE, interrupts)

/* Device run time data */
struct intel_adsp_wdt_dev_data {
	uint32_t core_wdt[CONFIG_MP_MAX_NUM_CPUS];
	uint32_t period_cfg;
	bool allow_reset;
#if WDT_INTEL_ADSP_INTERRUPT_SUPPORT
	wdt_callback_t callback;
#endif
};

/* Device constant configuration parameters */
struct intel_adsp_wdt_dev_cfg {
	uint32_t base;
	uint32_t clk_freq;
};

static int intel_adsp_wdt_setup(const struct device *dev, uint8_t options)
{
	const struct intel_adsp_wdt_dev_cfg *const dev_config = dev->config;
	struct intel_adsp_wdt_dev_data *const dev_data = dev->data;
	unsigned int i;
	int ret;

	ret = dw_wdt_check_options(options);
	if (ret) {
		return ret;
	}

	for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) {
		ret = dw_wdt_configure(dev_data->core_wdt[i], dev_data->period_cfg);
		if (ret) {
			return ret;
		}

#if WDT_INTEL_ADSP_INTERRUPT_SUPPORT
		dw_wdt_response_mode_set(dev_data->core_wdt[i], !!dev_data->callback);
#endif
		intel_adsp_wdt_reset_set(dev_config->base, i, dev_data->allow_reset);
	}

	return 0;
}

static int intel_adsp_wdt_install_timeout(const struct device *dev,
					  const struct wdt_timeout_cfg *config)
{
	const struct intel_adsp_wdt_dev_cfg *const dev_config = dev->config;
	struct intel_adsp_wdt_dev_data *const dev_data = dev->data;
	int ret;

#if WDT_INTEL_ADSP_INTERRUPT_SUPPORT
	dev_data->callback = config->callback;
#else
	if (config->callback) {
		LOG_ERR("Interrupt is not configured, can't set a callback.");
		return -ENOTSUP;
	}
#endif

	ret = dw_wdt_calc_period(dev_data->core_wdt[0], dev_config->clk_freq, config,
				 &dev_data->period_cfg);
	if (ret) {
		return ret;
	}

	if (config->flags & WDT_FLAG_RESET_CPU_CORE) {
		dev_data->allow_reset = true;
	}

	return 0;
}

static int intel_adsp_wdt_feed(const struct device *dev, int channel_id)
{
	struct intel_adsp_wdt_dev_data *const dev_data = dev->data;

	if (channel_id >= CONFIG_MP_MAX_NUM_CPUS) {
		return -EINVAL;
	}

	dw_wdt_counter_restart(dev_data->core_wdt[channel_id]);
	return 0;
}

#if WDT_INTEL_ADSP_INTERRUPT_SUPPORT
static void intel_adsp_wdt_isr(const struct device *dev)
{
	struct intel_adsp_wdt_dev_data *const dev_data = dev->data;
	const uint32_t cpu = arch_proc_id();
	const uint32_t base = dev_data->core_wdt[cpu];

	if (dw_wdt_interrupt_status_register_get(base)) {
		if (dev_data->callback) {
			dev_data->callback(dev, cpu);
		}

		dw_wdt_clear_interrupt(base);
	}
}
#endif

static int intel_adsp_wdt_init(const struct device *dev)
{
	const unsigned int reset_pulse_length =
		ilog2(DT_PROP(DEV_NODE, reset_pulse_length)) - 1;
	const struct intel_adsp_wdt_dev_cfg *const dev_config = dev->config;
	struct intel_adsp_wdt_dev_data *const dev_data = dev->data;
	unsigned int i;
	int ret;

	for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) {
		dev_data->core_wdt[i] = intel_adsp_wdt_pointer_get(dev_config->base, i);
		ret = dw_wdt_probe(dev_data->core_wdt[i], reset_pulse_length);
		if (ret) {
			return ret;
		}
	}

#if WDT_INTEL_ADSP_INTERRUPT_SUPPORT
	IRQ_CONNECT(DT_IRQN(DEV_NODE), DT_IRQ(DEV_NODE, priority), intel_adsp_wdt_isr,
		    DEVICE_DT_GET(DEV_NODE), DT_IRQ(DEV_NODE, sense));
	irq_enable(DT_IRQN(DEV_NODE));
#endif

	return 0;
}

/**
 * @brief Pause watchdog operation
 *
 * Sets the pause signal to stop the watchdog timing
 *
 * @param dev Pointer to the device structure
 * @param channel_id Channel identifier
 */
int intel_adsp_watchdog_pause(const struct device *dev, const int channel_id)
{
	const struct intel_adsp_wdt_dev_cfg *const dev_config = dev->config;

	if (channel_id >= CONFIG_MP_MAX_NUM_CPUS) {
		return -EINVAL;
	}

	intel_adsp_wdt_pause(dev_config->base, channel_id);
	return 0;
}

/**
 * @brief Resume watchdog operation
 *
 * Clears the pause signal to resume the watchdog timing
 *
 * @param dev Pointer to the device structure
 * @param channel_id Channel identifier
 */
int intel_adsp_watchdog_resume(const struct device *dev, const int channel_id)
{
	const struct intel_adsp_wdt_dev_cfg *const dev_config = dev->config;

	if (channel_id >= CONFIG_MP_MAX_NUM_CPUS) {
		return -EINVAL;
	}

	intel_adsp_wdt_resume(dev_config->base, channel_id);
	return 0;
}

static const struct wdt_driver_api intel_adsp_wdt_api = {
	.setup = intel_adsp_wdt_setup,
	.disable = dw_wdt_disable,
	.install_timeout = intel_adsp_wdt_install_timeout,
	.feed = intel_adsp_wdt_feed,
};

#if !(DT_NODE_HAS_PROP(DEV_NODE, clock_frequency) || DT_NODE_HAS_PROP(DEV_NODE, clocks))
#error Clock frequency not configured!
#endif

static const struct intel_adsp_wdt_dev_cfg wdt_intel_adsp_config = {
	.base = DT_REG_ADDR(DEV_NODE),
	COND_CODE_1(DT_NODE_HAS_PROP(DEV_NODE, clock_frequency),
		    (.clk_freq = DT_PROP(DEV_NODE, clock_frequency)),
		    (.clk_freq = DT_PROP_BY_PHANDLE(DEV_NODE, clocks, clock_frequency))
	),
};

static struct intel_adsp_wdt_dev_data wdt_intel_adsp_data;

DEVICE_DT_DEFINE(DEV_NODE, &intel_adsp_wdt_init, NULL, &wdt_intel_adsp_data, &wdt_intel_adsp_config,
		 POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &intel_adsp_wdt_api);
