/*
 * Copyright (c) 2022 Andes Technology
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/counter.h>
#include <string.h>

#define DT_DRV_COMPAT andestech_atcpit100

/* register definitions */
#define REG_IDR   0x00 /* ID and Revision Reg.   */
#define REG_CFG   0x10 /* Configuration Reg.     */
#define REG_INTE  0x14 /* Interrupt Enable Reg.  */
#define REG_ISTA  0x18 /* Interrupt Status Reg.  */
#define REG_CHEN  0x1C /* Channel Enable Reg.    */
#define REG_CTRL0 0x20 /* Channel 0 Control Reg. */
#define REG_RELD0 0x24 /* Channel 0 Reload Reg.  */
#define REG_CNTR0 0x28 /* Channel 0 Counter Reg. */
#define REG_CTRL1 0x30 /* Channel 1 Control Reg. */
#define REG_RELD1 0x34 /* Channel 1 Reload Reg.  */
#define REG_CNTR1 0x38 /* Channel 1 Counter Reg. */
#define REG_CTRL2 0x40 /* Channel 2 Control Reg. */
#define REG_RELD2 0x44 /* Channel 2 Reload Reg.  */
#define REG_CNTR2 0x48 /* Channel 2 Counter Reg. */
#define REG_CTRL3 0x50 /* Channel 3 Control Reg. */
#define REG_RELD3 0x54 /* Channel 3 Reload Reg.  */
#define REG_CNTR3 0x58 /* Channel 3 Counter Reg. */

#define PIT_BASE (((const struct atcpit100_config *)(dev)->config)->base)
#define PIT_INTE(dev) (PIT_BASE + REG_INTE)
#define PIT_ISTA(dev) (PIT_BASE + REG_ISTA)
#define PIT_CHEN(dev) (PIT_BASE + REG_CHEN)
#define PIT_CH_CTRL(dev, ch) (PIT_BASE + REG_CTRL0 + (ch << 4))
#define PIT_CH_RELD(dev, ch) (PIT_BASE + REG_RELD0 + (ch << 4))
#define PIT_CH_CNTR(dev, ch) (PIT_BASE + REG_CNTR0 + (ch << 4))

#define CTRL_CH_SRC_PCLK BIT(3)
#define CTRL_CH_MODE_32BIT BIT(0)

#define CHANNEL_NUM (4)
#define CH_NUM_PER_COUNTER (CHANNEL_NUM - 1)
#define TIMER0_CHANNEL(ch) BIT(((ch) * CHANNEL_NUM))

typedef void (*atcpit100_cfg_func_t)(void);

struct atcpit100_config {
	struct counter_config_info info;
	uint32_t base;
	uint32_t divider;
	uint32_t irq_num;
	atcpit100_cfg_func_t cfg_func;
};

struct counter_atcpit100_ch_data {
	counter_alarm_callback_t alarm_callback;
	void *alarm_user_data;
};

struct atcpit100_data {
	counter_top_callback_t top_callback;
	void *top_user_data;
	uint32_t guard_period;
	struct k_spinlock lock;
	struct counter_atcpit100_ch_data ch_data[CH_NUM_PER_COUNTER];
};

static inline uint32_t get_current_tick(const struct device *dev, uint32_t ch)
{
	const struct atcpit100_config *config = dev->config;
	uint32_t top, now_cnt;

	/* Preload cycles is reload register + 1 */
	top = sys_read32(PIT_CH_RELD(dev, ch)) + 1;
	now_cnt = top - sys_read32(PIT_CH_CNTR(dev, ch));

	return (now_cnt / config->divider);
}

static void atcpit100_irq_handler(void *arg)
{
	struct device *dev = (struct device *)arg;
	struct atcpit100_data *data = dev->data;
	counter_alarm_callback_t cb;
	uint32_t int_status, int_enable, ch_enable, cur_ticks;
	uint8_t i;

	ch_enable = sys_read32(PIT_CHEN(dev));
	int_enable = sys_read32(PIT_INTE(dev));
	int_status = sys_read32(PIT_ISTA(dev));

	if (int_status & TIMER0_CHANNEL(3)) {
		if (data->top_callback) {
			data->top_callback(dev, data->top_user_data);
		}
	}

	for (i = 0; i < CH_NUM_PER_COUNTER; i++) {
		if (int_status & TIMER0_CHANNEL(i)) {
			int_enable &= ~TIMER0_CHANNEL(i);
			ch_enable &= ~TIMER0_CHANNEL(i);

			cb = data->ch_data[i].alarm_callback;
			data->ch_data[i].alarm_callback = NULL;

			cur_ticks = get_current_tick(dev, 3);
			cb(dev, i, cur_ticks, data->ch_data[i].alarm_user_data);
		}
	}

	/* Disable channel and interrupt */
	sys_write32(int_enable, PIT_INTE(dev));
	sys_write32(ch_enable, PIT_CHEN(dev));

	/* Clear interrupt status */
	sys_write32(int_status, PIT_ISTA(dev));
}

static int counter_atcpit100_init(const struct device *dev)
{
	const struct atcpit100_config *config = dev->config;
	uint32_t reg;

	/* Disable all channels */
	sys_write32(0, PIT_CHEN(dev));

	/* Channel 0 ~ 3, 32 bits timer, PCLK source */
	reg = CTRL_CH_MODE_32BIT | CTRL_CH_SRC_PCLK;
	sys_write32(reg, PIT_CH_CTRL(dev, 0));
	sys_write32(reg, PIT_CH_CTRL(dev, 1));
	sys_write32(reg, PIT_CH_CTRL(dev, 2));
	sys_write32(reg, PIT_CH_CTRL(dev, 3));

	/* Disable all interrupt and clear all pending interrupt */
	sys_write32(0, PIT_INTE(dev));
	sys_write32(UINT32_MAX, PIT_ISTA(dev));

	/* Select channel 3 as default counter and set max top value */
	reg = config->info.max_top_value * config->divider;

	/* Set cycle - 1 to reload register */
	sys_write32((reg - 1), PIT_CH_RELD(dev, 3));

	config->cfg_func();

	irq_enable(config->irq_num);

	return 0;
}

static int atcpit100_start(const struct device *dev)
{
	struct atcpit100_data *data = dev->data;
	k_spinlock_key_t key;
	uint32_t reg;

	key = k_spin_lock(&data->lock);

	/* Enable channel */
	reg = sys_read32(PIT_CHEN(dev));
	reg |= TIMER0_CHANNEL(3);
	sys_write32(reg, PIT_CHEN(dev));

	k_spin_unlock(&data->lock, key);

	return 0;
}

static int atcpit100_stop(const struct device *dev)
{
	struct atcpit100_data *data = dev->data;
	k_spinlock_key_t key;
	uint32_t reg;

	key = k_spin_lock(&data->lock);

	/* Disable channel interrupt */
	reg = sys_read32(PIT_INTE(dev));
	reg &= ~TIMER0_CHANNEL(3);
	sys_write32(reg, PIT_INTE(dev));

	/* Disable channel */
	reg = sys_read32(PIT_CHEN(dev));
	reg &= ~TIMER0_CHANNEL(3);
	sys_write32(reg, PIT_CHEN(dev));

	/* Clear interrupt status */
	sys_write32(TIMER0_CHANNEL(3), PIT_ISTA(dev));

	k_spin_unlock(&data->lock, key);

	return 0;
}

static int atcpit100_get_value(const struct device *dev, uint32_t *ticks)
{
	struct atcpit100_data *data = dev->data;
	k_spinlock_key_t key;

	key = k_spin_lock(&data->lock);

	*ticks = get_current_tick(dev, 3);

	k_spin_unlock(&data->lock, key);

	return 0;
}

static int atcpit100_set_alarm(const struct device *dev, uint8_t chan_id,
			       const struct counter_alarm_cfg *alarm_cfg)
{
	const struct atcpit100_config *config = dev->config;
	struct atcpit100_data *data = dev->data;
	uint32_t top, now_cnt, remain_cnt, alarm_cnt, flags, reg;
	k_spinlock_key_t key;
	int err = 0;

	if (chan_id >= CH_NUM_PER_COUNTER) {
		return -ENOTSUP;
	}

	if (!alarm_cfg->callback) {
		return -EINVAL;
	}

	if (data->ch_data[chan_id].alarm_callback) {
		return -EBUSY;
	}

	key = k_spin_lock(&data->lock);

	/* Preload cycles is reload register + 1 */
	top = sys_read32(PIT_CH_RELD(dev, 3)) + 1;
	remain_cnt = sys_read32(PIT_CH_CNTR(dev, 3));
	alarm_cnt = alarm_cfg->ticks * config->divider;

	if (alarm_cnt > top) {
		err = -EINVAL;
		goto out;
	}

	flags = alarm_cfg->flags;
	data->ch_data[chan_id].alarm_callback = alarm_cfg->callback;
	data->ch_data[chan_id].alarm_user_data = alarm_cfg->user_data;

	if (flags & COUNTER_ALARM_CFG_ABSOLUTE) {
		uint32_t irq_on_late, max_rel_val;

		now_cnt = top - remain_cnt;
		max_rel_val = top - (data->guard_period * config->divider);
		irq_on_late = flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;

		if (now_cnt < alarm_cnt) {
			/* Absolute alarm is in this round counting */
			reg = alarm_cnt - now_cnt;
			irq_on_late = 0;
		} else {
			/* Absolute alarm is in the next round counting */
			reg = alarm_cnt + remain_cnt;
		}

		if (reg > max_rel_val) {
			/* Absolute alarm is in the guard period */
			err = -ETIME;
			if (!irq_on_late) {
				data->ch_data[chan_id].alarm_callback = NULL;
				goto out;
			}
		}

		if (irq_on_late) {
			/* Trigger interrupt immediately */
			reg = 1;
		}
	} else {
		/* Round up decreasing counter to tick boundary */
		now_cnt = remain_cnt + config->divider - 1;
		now_cnt = (now_cnt / config->divider) * config->divider;

		/* Adjusting relative alarm counter to tick boundary */
		reg = alarm_cnt - (now_cnt - remain_cnt);
	}

	/* Set cycle - 1 to reload register */
	sys_write32((reg - 1), PIT_CH_RELD(dev, chan_id));

	/* Enable channel interrupt */
	reg = sys_read32(PIT_INTE(dev));
	reg |= TIMER0_CHANNEL(chan_id);
	sys_write32(reg, PIT_INTE(dev));

	/* Enable channel */
	reg = sys_read32(PIT_CHEN(dev));
	reg |= TIMER0_CHANNEL(chan_id);
	sys_write32(reg, PIT_CHEN(dev));

out:
	k_spin_unlock(&data->lock, key);

	return err;
}

static int atcpit100_cancel_alarm(const struct device *dev, uint8_t chan_id)
{
	struct atcpit100_data *data = dev->data;
	k_spinlock_key_t key;
	uint32_t reg;

	if (chan_id >= CH_NUM_PER_COUNTER) {
		return -ENOTSUP;
	}

	key = k_spin_lock(&data->lock);

	/* Disable channel interrupt */
	reg = sys_read32(PIT_INTE(dev));
	reg &= ~TIMER0_CHANNEL(chan_id);
	sys_write32(reg, PIT_INTE(dev));

	/* Disable channel */
	reg = sys_read32(PIT_CHEN(dev));
	reg &= ~TIMER0_CHANNEL(chan_id);
	sys_write32(reg, PIT_CHEN(dev));

	/* Clear interrupt status */
	sys_write32(TIMER0_CHANNEL(chan_id), PIT_ISTA(dev));

	data->ch_data[chan_id].alarm_callback = NULL;

	k_spin_unlock(&data->lock, key);

	return 0;
}

static int atcpit100_set_top_value(const struct device *dev,
				   const struct counter_top_cfg *cfg)
{
	const struct atcpit100_config *config = dev->config;
	struct atcpit100_data *data = dev->data;
	uint32_t ticks, reg, reset_counter = 1;
	k_spinlock_key_t key;
	int err = 0;
	uint8_t i;

	for (i = 0; i < counter_get_num_of_channels(dev); i++) {
		if (data->ch_data[i].alarm_callback) {
			return -EBUSY;
		}
	}

	if (cfg->ticks > config->info.max_top_value) {
		return -ENOTSUP;
	}

	key = k_spin_lock(&data->lock);

	if (cfg->callback) {
		/* Disable channel interrupt */
		reg = sys_read32(PIT_INTE(dev));
		reg &= ~TIMER0_CHANNEL(3);
		sys_write32(reg, PIT_INTE(dev));

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

		/* Enable channel interrupt */
		reg = sys_read32(PIT_INTE(dev));
		reg |= TIMER0_CHANNEL(3);
		sys_write32(reg, PIT_INTE(dev));
	}

	if (cfg->flags & COUNTER_TOP_CFG_DONT_RESET) {
		/* Don't reset counter */
		reset_counter = 0;
		ticks = get_current_tick(dev, 3);
		if (ticks >= cfg->ticks) {
			err = -ETIME;
			if (cfg->flags & COUNTER_TOP_CFG_RESET_WHEN_LATE) {
				/* Reset counter if current is late */
				reset_counter = 1;
			}
		}
	}

	/* Set cycle - 1 to reload register */
	reg = cfg->ticks * config->divider;
	sys_write32((reg - 1), PIT_CH_RELD(dev, 3));

	if (reset_counter) {
		/* Disable channel */
		reg = sys_read32(PIT_CHEN(dev));
		reg &= ~TIMER0_CHANNEL(3);
		sys_write32(reg, PIT_CHEN(dev));

		/* Clear interrupt status */
		sys_write32(TIMER0_CHANNEL(3), PIT_ISTA(dev));

		/* Enable channel interrupt */
		reg = sys_read32(PIT_INTE(dev));
		reg |= TIMER0_CHANNEL(3);
		sys_write32(reg, PIT_INTE(dev));

		/* Enable channel */
		reg = sys_read32(PIT_CHEN(dev));
		reg |= TIMER0_CHANNEL(3);
		sys_write32(reg, PIT_CHEN(dev));
	}

	k_spin_unlock(&data->lock, key);

	return err;
}

static uint32_t atcpit100_get_pending_int(const struct device *dev)
{
	uint32_t reg = sys_read32(PIT_ISTA(dev));

	reg &= (TIMER0_CHANNEL(0) | TIMER0_CHANNEL(1) |
		TIMER0_CHANNEL(2) | TIMER0_CHANNEL(3));

	return !(!reg);
}

static uint32_t atcpit100_get_top_value(const struct device *dev)
{
	const struct atcpit100_config *config = dev->config;
	uint32_t top = sys_read32(PIT_CH_RELD(dev, 3)) + 1;

	return (top / config->divider);
}

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

	return data->guard_period;
}

static int atcpit100_set_guard_period(const struct device *dev,
				      uint32_t ticks, uint32_t flags)
{
	const struct atcpit100_config *config = dev->config;
	struct atcpit100_data *data = dev->data;
	uint32_t top = sys_read32(PIT_CH_RELD(dev, 3)) + 1;

	if ((ticks * config->divider) > top) {
		return -EINVAL;
	}

	data->guard_period = ticks;

	return 0;
}

static const struct counter_driver_api atcpit100_driver_api = {
	.start = atcpit100_start,
	.stop = atcpit100_stop,
	.get_value = atcpit100_get_value,
	.set_alarm = atcpit100_set_alarm,
	.cancel_alarm = atcpit100_cancel_alarm,
	.set_top_value = atcpit100_set_top_value,
	.get_pending_int = atcpit100_get_pending_int,
	.get_top_value = atcpit100_get_top_value,
	.get_guard_period = atcpit100_get_guard_period,
	.set_guard_period = atcpit100_set_guard_period,
};

#define COUNTER_ATCPIT100_INIT(n)					\
	static void counter_atcpit100_cfg_##n(void);			\
	static struct atcpit100_data atcpit100_data_##n;		\
									\
	static const struct atcpit100_config atcpit100_config_##n = {	\
		.info = {						\
			.max_top_value =				\
				(UINT32_MAX/DT_INST_PROP(n, prescaler)),\
			.freq = (DT_INST_PROP(n, clock_frequency) /	\
				DT_INST_PROP(n, prescaler)),		\
			.flags = COUNTER_CONFIG_INFO_COUNT_UP,		\
			.channels = CH_NUM_PER_COUNTER,			\
		},							\
		.base = DT_INST_REG_ADDR(n),				\
		.divider = DT_INST_PROP(n, prescaler),			\
		.irq_num = DT_INST_IRQN(n),				\
		.cfg_func = counter_atcpit100_cfg_##n,			\
	};								\
									\
	DEVICE_DT_INST_DEFINE(n,					\
		counter_atcpit100_init,					\
		NULL,							\
		&atcpit100_data_##n,					\
		&atcpit100_config_##n,					\
		POST_KERNEL,						\
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,			\
		&atcpit100_driver_api);					\
									\
	static void counter_atcpit100_cfg_##n(void)			\
	{								\
		IRQ_CONNECT(DT_INST_IRQN(n),				\
			    DT_INST_IRQ(n, priority),			\
			    atcpit100_irq_handler,			\
			    DEVICE_DT_INST_GET(n),			\
			    0);						\
	}

DT_INST_FOREACH_STATUS_OKAY(COUNTER_ATCPIT100_INIT)
