/*
 * Copyright (c) 2022 TOKITA Hiroshi
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT gd_gd32_wwdgt

#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/gd32.h>
#include <zephyr/drivers/reset.h>
#include <zephyr/drivers/watchdog.h>
#include <zephyr/irq.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys_clock.h>

#include <gd32_wwdgt.h>

LOG_MODULE_REGISTER(wdt_wwdgt_gd32, CONFIG_WDT_LOG_LEVEL);

#define WWDGT_PRESCALER_EXP_MAX (3U)
#define WWDGT_COUNTER_MIN	(0x40U)
#define WWDGT_COUNTER_MAX	(0x7fU)
#define WWDGT_INTERNAL_DIVIDER	(4096ULL)

struct gd32_wwdgt_config {
	uint16_t clkid;
	struct reset_dt_spec reset;
};

/* mutable driver data */
struct gd32_wwdgt_data {
	/* counter update value*/
	uint8_t counter;
	/* user defined callback */
	wdt_callback_t callback;
};

static void gd32_wwdgt_irq_config(const struct device *dev);

/**
 * @param timeout Timeout value in milliseconds.
 * @param exp exponent part of prescaler
 *
 * @return ticks count calculated by this formula.
 *
 *  timeout = pclk * INTERNAL_DIVIDER * (2^prescaler_exp) * (count + 1)
 *  transform as
 *  count = (timeout * pclk / INTERNAL_DIVIDER * (2^prescaler_exp) ) - 1
 *
 *  and add WWDGT_COUNTER_MIN to this as a offset value.
 */
static inline uint32_t gd32_wwdgt_calc_ticks(const struct device *dev,
					    uint32_t timeout, uint32_t exp)
{
	const struct gd32_wwdgt_config *config = dev->config;
	uint32_t pclk;

	(void)clock_control_get_rate(GD32_CLOCK_CONTROLLER,
				       (clock_control_subsys_t)&config->clkid,
				       &pclk);

	return ((timeout * pclk)
		/ (WWDGT_INTERNAL_DIVIDER * (1 << exp) * MSEC_PER_SEC) - 1)
		+ WWDGT_COUNTER_MIN;
}

/**
 * @brief Calculates WWDGT config value from timeout window.
 *
 * @param win Pointer to timeout window struct.
 * @param counter Pointer to the storage of counter value.
 * @param wval Pointer to the storage of window value.
 * @param prescaler Pointer to the storage of prescaler value.
 *
 * @return 0 on success, -EINVAL if the window-max is out of range
 */
static int gd32_wwdgt_calc_window(const struct device *dev,
				  const struct wdt_window *win,
				  uint32_t *counter, uint32_t *wval,
				  uint32_t *prescaler)
{
	for (uint32_t shift = 0U; shift <= WWDGT_PRESCALER_EXP_MAX; shift++) {
		uint32_t max_count = gd32_wwdgt_calc_ticks(dev, win->max, shift);

		if (max_count <= WWDGT_COUNTER_MAX) {
			*counter = max_count;
			*prescaler = CFG_PSC(shift);
			if (win->min == 0U) {
				*wval = max_count;
			} else {
				*wval = gd32_wwdgt_calc_ticks(dev, win->min, shift);
			}

			return 0;
		}
	}

	return -EINVAL;
}

static int gd32_wwdgt_setup(const struct device *dev, uint8_t options)
{
	ARG_UNUSED(dev);

	if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) {
#if CONFIG_GD32_DBG_SUPPORT
		dbg_periph_enable(DBG_WWDGT_HOLD);
#else
		LOG_ERR("Debug support not enabled");
		return -ENOTSUP;
#endif
	}

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

	wwdgt_enable();
	wwdgt_flag_clear();
	wwdgt_interrupt_enable();

	return 0;
}

static int gd32_wwdgt_disable(const struct device *dev)
{
	/* watchdog cannot be stopped once started */
	ARG_UNUSED(dev);

	return -EPERM;
}

static int gd32_wwdgt_install_timeout(const struct device *dev,
				      const struct wdt_timeout_cfg *config)
{
	uint32_t prescaler = 0U;
	uint32_t counter = 0U;
	uint32_t window = 0U;
	struct gd32_wwdgt_data *data = dev->data;

	if (config->window.max == 0U) {
		LOG_ERR("window.max must be non-zero");
		return -EINVAL;
	}

	if (gd32_wwdgt_calc_window(dev, &config->window, &counter, &window,
				   &prescaler) != 0) {
		LOG_ERR("window.max in out of range");
		return -EINVAL;
	}

	data->callback = config->callback;
	data->counter = counter;

	wwdgt_config(counter, window, prescaler);

	return 0;
}

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

	ARG_UNUSED(channel_id);

	wwdgt_counter_update(data->counter);

	return 0;
}

static void gd32_wwdgt_isr(const struct device *dev)
{
	struct gd32_wwdgt_data *data = dev->data;

	if (wwdgt_flag_get() != 0) {
		wwdgt_flag_clear();

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

static void gd32_wwdgt_irq_config(const struct device *dev)
{
	ARG_UNUSED(dev);

	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), gd32_wwdgt_isr,
		    DEVICE_DT_INST_GET(0), 0);
	irq_enable(DT_INST_IRQN(0));
}

static const struct wdt_driver_api wwdgt_gd32_api = {
	.setup = gd32_wwdgt_setup,
	.disable = gd32_wwdgt_disable,
	.install_timeout = gd32_wwdgt_install_timeout,
	.feed = gd32_wwdgt_feed,
};

static int gd32_wwdgt_init(const struct device *dev)
{
	const struct gd32_wwdgt_config *config = dev->config;

	(void)clock_control_on(GD32_CLOCK_CONTROLLER,
			       (clock_control_subsys_t)&config->clkid);
	(void)reset_line_toggle_dt(&config->reset);
	gd32_wwdgt_irq_config(dev);

	return 0;
}

static const struct gd32_wwdgt_config wwdgt_cfg = {
	.clkid = DT_INST_CLOCKS_CELL(0, id),
	.reset = RESET_DT_SPEC_INST_GET(0),
};

static struct gd32_wwdgt_data wwdgt_data = {
	.counter = WWDGT_COUNTER_MIN,
	.callback = NULL
};

DEVICE_DT_INST_DEFINE(0, gd32_wwdgt_init, NULL, &wwdgt_data, &wwdgt_cfg, POST_KERNEL,
		      CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &wwdgt_gd32_api);
