/*
 * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
 * Copyright (c) 2022 TOKITA Hiroshi <tokita.hiroshi@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT gd_gd32_timer

#include <zephyr/device.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/gd32.h>
#include <zephyr/drivers/counter.h>
#include <zephyr/drivers/reset.h>
#include <zephyr/irq.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/atomic.h>

#include <gd32_timer.h>

LOG_MODULE_REGISTER(counter_gd32_timer);

#define TIMER_INT_CH(ch)  (TIMER_INT_CH0 << ch)
#define TIMER_FLAG_CH(ch) (TIMER_FLAG_CH0 << ch)
#define TIMER_INT_ALL	  (0xFFu)

struct counter_gd32_ch_data {
	counter_alarm_callback_t callback;
	void *user_data;
};

struct counter_gd32_data {
	counter_top_callback_t top_cb;
	void *top_user_data;
	uint32_t guard_period;
	atomic_t cc_int_pending;
	uint32_t freq;
	struct counter_gd32_ch_data alarm[];
};

struct counter_gd32_config {
	struct counter_config_info counter_info;
	uint32_t reg;
	uint16_t clkid;
	struct reset_dt_spec reset;
	uint16_t prescaler;
	void (*irq_config)(const struct device *dev);
	void (*set_irq_pending)(void);
	uint32_t (*get_irq_pending)(void);
};

static uint32_t get_autoreload_value(const struct device *dev)
{
	const struct counter_gd32_config *config = dev->config;

	return TIMER_CAR(config->reg);
}

static void set_autoreload_value(const struct device *dev, uint32_t value)
{
	const struct counter_gd32_config *config = dev->config;

	TIMER_CAR(config->reg) = value;
}

static uint32_t get_counter(const struct device *dev)
{
	const struct counter_gd32_config *config = dev->config;

	return TIMER_CNT(config->reg);
}

static void set_counter(const struct device *dev, uint32_t value)
{
	const struct counter_gd32_config *config = dev->config;

	TIMER_CNT(config->reg) = value;
}

static void set_software_event_gen(const struct device *dev, uint8_t evt)
{
	const struct counter_gd32_config *config = dev->config;

	TIMER_SWEVG(config->reg) |= evt;
}

static void set_prescaler(const struct device *dev, uint16_t prescaler)
{
	const struct counter_gd32_config *config = dev->config;

	TIMER_PSC(config->reg) = prescaler;
}

static void set_compare_value(const struct device *dev, uint16_t chan,
			      uint32_t compare_value)
{
	const struct counter_gd32_config *config = dev->config;

	switch (chan) {
	case 0:
		TIMER_CH0CV(config->reg) = compare_value;
		break;
	case 1:
		TIMER_CH1CV(config->reg) = compare_value;
		break;
	case 2:
		TIMER_CH2CV(config->reg) = compare_value;
		break;
	case 3:
		TIMER_CH3CV(config->reg) = compare_value;
		break;
	}
}

static void interrupt_enable(const struct device *dev, uint32_t interrupt)
{
	const struct counter_gd32_config *config = dev->config;

	TIMER_DMAINTEN(config->reg) |= interrupt;
}

static void interrupt_disable(const struct device *dev, uint32_t interrupt)
{
	const struct counter_gd32_config *config = dev->config;

	TIMER_DMAINTEN(config->reg) &= ~interrupt;
}

static uint32_t interrupt_flag_get(const struct device *dev, uint32_t interrupt)
{
	const struct counter_gd32_config *config = dev->config;

	return (TIMER_DMAINTEN(config->reg) & TIMER_INTF(config->reg) &
		interrupt);
}

static void interrupt_flag_clear(const struct device *dev, uint32_t interrupt)
{
	const struct counter_gd32_config *config = dev->config;

	TIMER_INTF(config->reg) &= ~interrupt;
}

static int counter_gd32_timer_start(const struct device *dev)
{
	const struct counter_gd32_config *config = dev->config;

	TIMER_CTL0(config->reg) |= (uint32_t)TIMER_CTL0_CEN;

	return 0;
}

static int counter_gd32_timer_stop(const struct device *dev)
{
	const struct counter_gd32_config *config = dev->config;

	TIMER_CTL0(config->reg) &= ~(uint32_t)TIMER_CTL0_CEN;

	return 0;
}

static int counter_gd32_timer_get_value(const struct device *dev,
					uint32_t *ticks)
{
	*ticks = get_counter(dev);

	return 0;
}

static uint32_t counter_gd32_timer_get_top_value(const struct device *dev)
{
	return get_autoreload_value(dev);
}

static uint32_t ticks_add(uint32_t val1, uint32_t val2, uint32_t top)
{
	uint32_t to_top;

	if (likely(IS_BIT_MASK(top))) {
		return (val1 + val2) & top;
	}

	to_top = top - val1;

	return (val2 <= to_top) ? val1 + val2 : val2 - to_top;
}

static uint32_t ticks_sub(uint32_t val, uint32_t old, uint32_t top)
{
	if (likely(IS_BIT_MASK(top))) {
		return (val - old) & top;
	}

	/* if top is not 2^n-1 */
	return (val >= old) ? (val - old) : val + top + 1 - old;
}

static void set_cc_int_pending(const struct device *dev, uint8_t chan)
{
	const struct counter_gd32_config *config = dev->config;
	struct counter_gd32_data *data = dev->data;

	atomic_or(&data->cc_int_pending, TIMER_INT_CH(chan));
	config->set_irq_pending();
}

static int set_cc(const struct device *dev, uint8_t chan, uint32_t val,
		  uint32_t flags)
{
	const struct counter_gd32_config *config = dev->config;
	struct counter_gd32_data *data = dev->data;

	__ASSERT_NO_MSG(data->guard_period <
			counter_gd32_timer_get_top_value(dev));
	bool absolute = flags & COUNTER_ALARM_CFG_ABSOLUTE;
	uint32_t top = counter_gd32_timer_get_top_value(dev);
	uint32_t now, diff, max_rel_val;
	bool irq_on_late;
	int err = 0;

	ARG_UNUSED(config);
	__ASSERT(!(TIMER_DMAINTEN(config->reg) & TIMER_INT_CH(chan)),
		 "Expected that CC interrupt is disabled.");

	/* First take care of a risk of an event coming from CC being set to
	 * next tick. Reconfigure CC to future (now tick is the furthest
	 * future).
	 */
	now = get_counter(dev);
	set_compare_value(dev, chan, now);
	interrupt_flag_clear(dev, TIMER_FLAG_CH(chan));

	if (absolute) {
		max_rel_val = top - data->guard_period;
		irq_on_late = flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
	} else {
		/* If relative value is smaller than half of the counter range
		 * it is assumed that there is a risk of setting value too late
		 * and late detection algorithm must be applied. When late
		 * setting is detected, interrupt shall be triggered for
		 * immediate expiration of the timer. Detection is performed
		 * by limiting relative distance between CC and counter.
		 *
		 * Note that half of counter range is an arbitrary value.
		 */
		irq_on_late = val < (top / 2);
		/* limit max to detect short relative being set too late. */
		max_rel_val = irq_on_late ? top / 2 : top;
		val = ticks_add(now, val, top);
	}

	set_compare_value(dev, chan, val);

	/* decrement value to detect also case when val == get_counter(dev).
	 * Otherwise, condition would need to include comparing diff against 0.
	 */
	diff = ticks_sub(val - 1, get_counter(dev), top);
	if (diff > max_rel_val) {
		if (absolute) {
			err = -ETIME;
		}

		/* Interrupt is triggered always for relative alarm and
		 * for absolute depending on the flag.
		 */
		if (irq_on_late) {
			set_cc_int_pending(dev, chan);
		} else {
			data->alarm[chan].callback = NULL;
		}
	} else {
		interrupt_enable(dev, TIMER_INT_CH(chan));
	}

	return err;
}

static int
counter_gd32_timer_set_alarm(const struct device *dev, uint8_t chan,
			     const struct counter_alarm_cfg *alarm_cfg)
{
	struct counter_gd32_data *data = dev->data;
	struct counter_gd32_ch_data *chdata = &data->alarm[chan];

	if (alarm_cfg->ticks > counter_gd32_timer_get_top_value(dev)) {
		return -EINVAL;
	}

	if (chdata->callback) {
		return -EBUSY;
	}

	chdata->callback = alarm_cfg->callback;
	chdata->user_data = alarm_cfg->user_data;

	return set_cc(dev, chan, alarm_cfg->ticks, alarm_cfg->flags);
}

static int counter_gd32_timer_cancel_alarm(const struct device *dev,
					   uint8_t chan)
{
	struct counter_gd32_data *data = dev->data;

	interrupt_disable(dev, TIMER_INT_CH(chan));
	data->alarm[chan].callback = NULL;

	return 0;
}

static int counter_gd32_timer_set_top_value(const struct device *dev,
					    const struct counter_top_cfg *cfg)
{
	const struct counter_gd32_config *config = dev->config;
	struct counter_gd32_data *data = dev->data;
	int err = 0;

	for (uint32_t i = 0; i < config->counter_info.channels; i++) {
		/* Overflow can be changed only when all alarms are
		 * disables.
		 */
		if (data->alarm[i].callback) {
			return -EBUSY;
		}
	}

	interrupt_disable(dev, TIMER_INT_UP);
	set_autoreload_value(dev, cfg->ticks);
	interrupt_flag_clear(dev, TIMER_INT_FLAG_UP);

	data->top_cb = cfg->callback;
	data->top_user_data = cfg->user_data;

	if (!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
		set_counter(dev, 0);
	} else if (get_counter(dev) >= cfg->ticks) {
		err = -ETIME;
		if (cfg->flags & COUNTER_TOP_CFG_RESET_WHEN_LATE) {
			set_counter(dev, 0);
		}
	}

	if (cfg->callback) {
		interrupt_enable(dev, TIMER_INT_UP);
	}

	return err;
}

static uint32_t counter_gd32_timer_get_pending_int(const struct device *dev)
{
	const struct counter_gd32_config *cfg = dev->config;

	return cfg->get_irq_pending();
}

static uint32_t counter_gd32_timer_get_freq(const struct device *dev)
{
	struct counter_gd32_data *data = dev->data;

	return data->freq;
}

static uint32_t counter_gd32_timer_get_guard_period(const struct device *dev,
						    uint32_t flags)
{
	struct counter_gd32_data *data = dev->data;

	return data->guard_period;
}

static int counter_gd32_timer_set_guard_period(const struct device *dev,
					       uint32_t guard, uint32_t flags)
{
	struct counter_gd32_data *data = dev->data;

	__ASSERT_NO_MSG(guard < counter_gd32_timer_get_top_value(dev));

	data->guard_period = guard;
	return 0;
}

static void top_irq_handle(const struct device *dev)
{
	struct counter_gd32_data *data = dev->data;
	counter_top_callback_t cb = data->top_cb;

	if (interrupt_flag_get(dev, TIMER_INT_FLAG_UP) != 0) {
		interrupt_flag_clear(dev, TIMER_INT_FLAG_UP);
		__ASSERT(cb != NULL, "top event enabled - expecting callback");
		cb(dev, data->top_user_data);
	}
}

static void alarm_irq_handle(const struct device *dev, uint32_t chan)
{
	struct counter_gd32_data *data = dev->data;
	struct counter_gd32_ch_data *alarm = &data->alarm[chan];
	counter_alarm_callback_t cb;
	bool hw_irq_pending = !!(interrupt_flag_get(dev, TIMER_FLAG_CH(chan)));
	bool sw_irq_pending = data->cc_int_pending & TIMER_INT_CH(chan);

	if (hw_irq_pending || sw_irq_pending) {
		atomic_and(&data->cc_int_pending, ~TIMER_INT_CH(chan));
		interrupt_disable(dev, TIMER_INT_CH(chan));
		interrupt_flag_clear(dev, TIMER_FLAG_CH(chan));

		cb = alarm->callback;
		alarm->callback = NULL;

		if (cb) {
			cb(dev, chan, get_counter(dev), alarm->user_data);
		}
	}
}

static void irq_handler(const struct device *dev)
{
	const struct counter_gd32_config *cfg = dev->config;

	top_irq_handle(dev);

	for (uint32_t i = 0; i < cfg->counter_info.channels; i++) {
		alarm_irq_handle(dev, i);
	}
}

static int counter_gd32_timer_init(const struct device *dev)
{
	const struct counter_gd32_config *cfg = dev->config;
	struct counter_gd32_data *data = dev->data;
	uint32_t pclk;

	clock_control_on(GD32_CLOCK_CONTROLLER,
			 (clock_control_subsys_t)&cfg->clkid);
	clock_control_get_rate(GD32_CLOCK_CONTROLLER,
			       (clock_control_subsys_t)&cfg->clkid, &pclk);

	data->freq = pclk / (cfg->prescaler + 1);

	interrupt_disable(dev, TIMER_INT_ALL);
	reset_line_toggle_dt(&cfg->reset);

	cfg->irq_config(dev);
	set_prescaler(dev, cfg->prescaler);
	set_autoreload_value(dev, cfg->counter_info.max_top_value);
	set_software_event_gen(dev, TIMER_SWEVG_UPG);

	return 0;
}

static const struct counter_driver_api counter_api = {
	.start = counter_gd32_timer_start,
	.stop = counter_gd32_timer_stop,
	.get_value = counter_gd32_timer_get_value,
	.set_alarm = counter_gd32_timer_set_alarm,
	.cancel_alarm = counter_gd32_timer_cancel_alarm,
	.set_top_value = counter_gd32_timer_set_top_value,
	.get_pending_int = counter_gd32_timer_get_pending_int,
	.get_top_value = counter_gd32_timer_get_top_value,
	.get_guard_period = counter_gd32_timer_get_guard_period,
	.set_guard_period = counter_gd32_timer_set_guard_period,
	.get_freq = counter_gd32_timer_get_freq,
};

#define TIMER_IRQ_CONFIG(n)                                                    \
	static void irq_config_##n(const struct device *dev)                   \
	{                                                                      \
		IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, global, irq),               \
			    DT_INST_IRQ_BY_NAME(n, global, priority),          \
			    irq_handler, DEVICE_DT_INST_GET(n), 0);            \
		irq_enable(DT_INST_IRQ_BY_NAME(n, global, irq));               \
	}                                                                      \
	static void set_irq_pending_##n(void)                                  \
	{                                                                      \
		(NVIC_SetPendingIRQ(DT_INST_IRQ_BY_NAME(n, global, irq)));     \
	}                                                                      \
	static uint32_t get_irq_pending_##n(void)                              \
	{                                                                      \
		return NVIC_GetPendingIRQ(                                     \
			DT_INST_IRQ_BY_NAME(n, global, irq));                  \
	}

#define TIMER_IRQ_CONFIG_ADVANCED(n)                                           \
	static void irq_config_##n(const struct device *dev)                   \
	{                                                                      \
		IRQ_CONNECT((DT_INST_IRQ_BY_NAME(n, up, irq)),                 \
			    (DT_INST_IRQ_BY_NAME(n, up, priority)),            \
			    irq_handler, (DEVICE_DT_INST_GET(n)), 0);          \
		irq_enable((DT_INST_IRQ_BY_NAME(n, up, irq)));                 \
		IRQ_CONNECT((DT_INST_IRQ_BY_NAME(n, cc, irq)),                 \
			    (DT_INST_IRQ_BY_NAME(n, cc, priority)),            \
			    irq_handler, (DEVICE_DT_INST_GET(n)), 0);          \
		irq_enable((DT_INST_IRQ_BY_NAME(n, cc, irq)));                 \
	}                                                                      \
	static void set_irq_pending_##n(void)                                  \
	{                                                                      \
		(NVIC_SetPendingIRQ(DT_INST_IRQ_BY_NAME(n, cc, irq)));         \
	}                                                                      \
	static uint32_t get_irq_pending_##n(void)                              \
	{                                                                      \
		return NVIC_GetPendingIRQ(DT_INST_IRQ_BY_NAME(n, cc, irq));    \
	}

#define GD32_TIMER_INIT(n)                                                     \
	COND_CODE_1(DT_INST_PROP(n, is_advanced),                              \
		    (TIMER_IRQ_CONFIG_ADVANCED(n)), (TIMER_IRQ_CONFIG(n)));    \
	static struct counter_gd32_data_##n {                                  \
		struct counter_gd32_data data;                                 \
		struct counter_gd32_ch_data alarm[DT_INST_PROP(n, channels)];  \
	} timer_data_##n = {0};                                                \
	static const struct counter_gd32_config timer_config_##n = {           \
		.counter_info = {.max_top_value = COND_CODE_1(                 \
					 DT_INST_PROP(n, is_32bit),            \
					 (UINT32_MAX), (UINT16_MAX)),          \
				 .flags = COUNTER_CONFIG_INFO_COUNT_UP,        \
				 .freq = 0,                                    \
				 .channels = DT_INST_PROP(n, channels)},       \
		.reg = DT_INST_REG_ADDR(n),                                    \
		.clkid = DT_INST_CLOCKS_CELL(n, id),                           \
		.reset = RESET_DT_SPEC_INST_GET(n),                            \
		.prescaler = DT_INST_PROP(n, prescaler),                       \
		.irq_config = irq_config_##n,                                  \
		.set_irq_pending = set_irq_pending_##n,                        \
		.get_irq_pending = get_irq_pending_##n,                        \
	};                                                                     \
                                                                               \
	DEVICE_DT_INST_DEFINE(n, counter_gd32_timer_init, NULL,                \
			      &timer_data_##n, &timer_config_##n,              \
			      PRE_KERNEL_1, CONFIG_COUNTER_INIT_PRIORITY,      \
			      &counter_api);

DT_INST_FOREACH_STATUS_OKAY(GD32_TIMER_INIT);
