/*
 * Copyright (c) 2021 Nuvoton Technology Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nuvoton_npcx_itim_timer

/**
 * @file
 * @brief Nuvoton NPCX kernel device driver for  "system clock driver" interface
 *
 * This file contains a kernel device driver implemented by the internal
 * 64/32-bit timers in Nuvoton NPCX series. Via these two kinds of timers, the
 * driver provides an standard "system clock driver" interface.
 *
 * It includes:
 * - A system timer based on an ITIM64 (Internal 64-bit timer) instance, clocked
 *   by APB2 which freq is the same as CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC.
 * - Provide a 64-bit cycles reading and ticks computation based on it.
 * - Its prescaler is set to 1 and provide the kernel cycles reading without
 *   handling overflow mechanism.
 * - After ec entered "sleep/deep sleep" power state which is used for better
 *   power consumption, then its clock will stop.
 *
 * - A event timer based on an ITIM32 (Internal 32-bit timer) instance, clocked
 *   by LFCLK which frequency is 32KHz and still activated when ec entered
 *   "sleep/deep sleep" power state.
 * - Provide a system clock timeout notification. In its ISR, the driver informs
 *   the kernel that the specified number of ticks have elapsed.
 * - Its prescaler is set to 1 and the formula between event timer's cycles and
 *   ticks is 'cycles = (ticks * 32768) / CONFIG_SYS_CLOCK_TICKS_PER_SEC'
 * - Compensate reading of ITIM64 which clock is gating after ec entered
 *   "sleep/deep sleep" power state if CONFIG_PM is enabled.
 */

#include <zephyr/init.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/timer/system_timer.h>
#include <zephyr/kernel.h>
#include <zephyr/sys_clock.h>
#include <zephyr/spinlock.h>
#include <soc.h>

#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
LOG_MODULE_REGISTER(itim, LOG_LEVEL_ERR);

#define NPCX_ITIM32_MAX_CNT 0xffffffff
#define NPCX_ITIM64_MAX_HALF_CNT 0xffffffff
#define EVT_CYCLES_PER_SEC LFCLK /* 32768 Hz */
#define SYS_CYCLES_PER_TICK (sys_clock_hw_cycles_per_sec() \
					/ CONFIG_SYS_CLOCK_TICKS_PER_SEC)
#define SYS_CYCLES_PER_USEC (sys_clock_hw_cycles_per_sec() / 1000000)
#define EVT_CYCLES_FROM_TICKS(ticks) \
	DIV_ROUND_UP(ticks * EVT_CYCLES_PER_SEC, \
			 CONFIG_SYS_CLOCK_TICKS_PER_SEC)
#define NPCX_ITIM_CLK_SEL_DELAY 92 /* Delay for clock selection (Unit:us) */
/* Timeout for enabling ITIM module: 100us (Unit:cycles) */
#define NPCX_ITIM_EN_TIMEOUT_CYCLES (100 * SYS_CYCLES_PER_USEC)
#define SYS_CYC_PER_EVT_CYC         (sys_clock_hw_cycles_per_sec() / EVT_CYCLES_PER_SEC)

/* Instance of system and event timers */
static struct itim64_reg *const sys_tmr = (struct itim64_reg *)
					DT_INST_REG_ADDR_BY_NAME(0, sys_itim);
static struct itim32_reg *const evt_tmr = (struct itim32_reg *)
					DT_INST_REG_ADDR_BY_NAME(0, evt_itim);

static const struct npcx_clk_cfg itim_clk_cfg[] = NPCX_DT_CLK_CFG_ITEMS_LIST(0);

static struct k_spinlock lock;
/* Announced cycles in system timer before executing sys_clock_announce() */
static uint64_t cyc_sys_announced;
static uint64_t last_ticks;
static uint32_t last_elapsed;

/* Current target cycles of time-out signal in event timer */
static uint32_t cyc_evt_timeout;
/* Total cycles of system timer stopped in "sleep/deep sleep" mode */
__unused static uint64_t cyc_sys_compensated;
/* Current cycles in event timer when ec entered "sleep/deep sleep" mode */
__unused static uint32_t cyc_evt_enter_deep_idle;

/* ITIM local inline functions */
static inline uint64_t npcx_itim_get_sys_cyc64(void)
{
	uint32_t cnt64h, cnt64h_check, cnt64l;

	/* Read 64-bit counter value from two 32-bit registers */
	do {
		cnt64h_check = sys_tmr->ITCNT64H;
		cnt64l = sys_tmr->ITCNT64L;
		cnt64h = sys_tmr->ITCNT64H;
	} while (cnt64h != cnt64h_check);

	cnt64h = NPCX_ITIM64_MAX_HALF_CNT - cnt64h;
	cnt64l = NPCX_ITIM64_MAX_HALF_CNT - cnt64l + 1;

	/* Return current value of 64-bit counter value of system timer */
	if (IS_ENABLED(CONFIG_PM)) {
		return ((((uint64_t)cnt64h) << 32) | cnt64l) +
							cyc_sys_compensated;
	} else {
		return (((uint64_t)cnt64h) << 32) | cnt64l;
	}
}

static inline int npcx_itim_evt_enable(void)
{
	uint64_t cyc_start;

	/* Enable event timer and wait for it to take effect */
	evt_tmr->ITCTS32 |= BIT(NPCX_ITCTSXX_ITEN);

	/*
	 * Usually, it need one clock (30.5 us) to take effect since
	 * asynchronization between core and itim32's source clock (LFCLK).
	 */
	cyc_start = npcx_itim_get_sys_cyc64();
	while (!IS_BIT_SET(evt_tmr->ITCTS32, NPCX_ITCTSXX_ITEN)) {
		if (npcx_itim_get_sys_cyc64() - cyc_start >
						NPCX_ITIM_EN_TIMEOUT_CYCLES) {
			/* ITEN bit is still unset? */
			if (!IS_BIT_SET(evt_tmr->ITCTS32, NPCX_ITCTSXX_ITEN)) {
				LOG_ERR("Timeout: enabling EVT timer!");
				return -ETIMEDOUT;
			}
		}
	}

	return 0;
}

static inline void npcx_itim_evt_disable(void)
{
	/* Disable event timer and no need to wait for it to take effect */
	evt_tmr->ITCTS32 &= ~BIT(NPCX_ITCTSXX_ITEN);
}

/* ITIM local functions */
static int npcx_itim_start_evt_tmr_by_tick(int32_t ticks)
{
	k_spinlock_key_t key = k_spin_lock(&lock);

	/*
	 * Get desired cycles of event timer from the requested ticks which
	 * round up to next tick boundary.
	 */

	if (ticks == K_TICKS_FOREVER) {
		cyc_evt_timeout = NPCX_ITIM32_MAX_CNT;
	} else {
		uint64_t next_cycs;
		uint64_t curr = npcx_itim_get_sys_cyc64();
		uint32_t dcycles;

		if (ticks <= 0) {
			ticks = 1;
		}

		next_cycs = (last_ticks + last_elapsed + ticks) * SYS_CYCLES_PER_TICK;
		if (unlikely(next_cycs <= curr)) {
			cyc_evt_timeout = 1;
		} else {
			dcycles = next_cycs - curr;
			cyc_evt_timeout =
				CLAMP((dcycles / SYS_CYC_PER_EVT_CYC), 1, NPCX_ITIM32_MAX_CNT);
		}

	}
	LOG_DBG("ticks %x, cyc_evt_timeout %x", ticks, cyc_evt_timeout);

	/* Disable event timer if needed before configuring counter */
	if (IS_BIT_SET(evt_tmr->ITCTS32, NPCX_ITCTSXX_ITEN)) {
		npcx_itim_evt_disable();
	}

	/* Upload counter of event timer */
	evt_tmr->ITCNT32 = MAX(cyc_evt_timeout - 1, 1);

	k_spin_unlock(&lock, key);
	/* Enable event timer and start ticking */
	return npcx_itim_evt_enable();
}

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

	/* Disable ITIM event module first */
	npcx_itim_evt_disable();
	/* Clear timeout status for event */
	evt_tmr->ITCTS32 |= BIT(NPCX_ITCTSXX_TO_STS);

	if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		k_spinlock_key_t key = k_spin_lock(&lock);
		uint64_t curr = npcx_itim_get_sys_cyc64();
		uint32_t delta_ticks = (uint32_t)((curr - cyc_sys_announced) / SYS_CYCLES_PER_TICK);

		cyc_sys_announced += delta_ticks * SYS_CYCLES_PER_TICK;
		last_ticks += delta_ticks;
		last_elapsed = 0;
		k_spin_unlock(&lock, key);

		/* Informs kernel that specified number of ticks have elapsed */
		sys_clock_announce(delta_ticks);
	} else {
		/* Enable event timer for ticking and wait to it take effect */
		npcx_itim_evt_enable();

		/* Informs kernel that one tick has elapsed */
		sys_clock_announce(1);
	}
}

#if defined(CONFIG_PM)
static inline uint32_t npcx_itim_get_evt_cyc32(void)
{
	uint32_t cnt1, cnt2;

	cnt1 = evt_tmr->ITCNT32;
	/*
	 * Wait for two consecutive equal values are read since the source clock
	 * of event timer is 32KHz.
	 */
	while ((cnt2 = evt_tmr->ITCNT32) != cnt1)
		cnt1 = cnt2;

	/* Return current value of 32-bit counter of event timer  */
	return cnt2;
}

static uint32_t npcx_itim_evt_elapsed_cyc32(void)
{
	uint32_t cnt1 = npcx_itim_get_evt_cyc32();
	uint8_t  sys_cts = evt_tmr->ITCTS32;
	uint16_t cnt2 = npcx_itim_get_evt_cyc32();

	/* Event has been triggered but timer ISR doesn't handle it */
	if (IS_BIT_SET(sys_cts, NPCX_ITCTSXX_TO_STS) || (cnt2 > cnt1)) {
		cnt2 = cyc_evt_timeout;
	} else {
		cnt2 = cyc_evt_timeout - cnt2;
	}

	/* Return elapsed cycles of 32-bit counter of event timer  */
	return cnt2;
}
#endif /* CONFIG_PM */

/* System timer api functions */
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
	ARG_UNUSED(idle);

	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		/* Only for tickless kernel system */
		return;
	}

	LOG_DBG("timeout is %d", ticks);
	/* Start a event timer in ticks */
	npcx_itim_start_evt_tmr_by_tick(ticks);
}

uint32_t sys_clock_elapsed(void)
{
	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		/* Always return 0 for tickful kernel system */
		return 0;
	}

	k_spinlock_key_t key = k_spin_lock(&lock);
	uint64_t delta_cycle = npcx_itim_get_sys_cyc64() - cyc_sys_announced;
	uint32_t delta_ticks = (uint32_t)delta_cycle / SYS_CYCLES_PER_TICK;

	last_elapsed = delta_ticks;
	k_spin_unlock(&lock, key);

	/* Return how many ticks elapsed since last sys_clock_announce() call */
	return delta_ticks;
}

uint32_t sys_clock_cycle_get_32(void)
{
	k_spinlock_key_t key = k_spin_lock(&lock);
	uint64_t current = npcx_itim_get_sys_cyc64();

	k_spin_unlock(&lock, key);

	/* Return how many cycles since system kernel timer start counting */
	return (uint32_t)(current);
}

uint64_t sys_clock_cycle_get_64(void)
{
	k_spinlock_key_t key = k_spin_lock(&lock);
	uint64_t current = npcx_itim_get_sys_cyc64();

	k_spin_unlock(&lock, key);

	/* Return how many cycles since system kernel timer start counting */
	return current;
}

/* Platform specific system timer functions */
#if defined(CONFIG_PM)
void npcx_clock_capture_low_freq_timer(void)
{
	cyc_evt_enter_deep_idle = npcx_itim_evt_elapsed_cyc32();
}

void npcx_clock_compensate_system_timer(void)
{
	uint32_t cyc_evt_elapsed_in_deep = npcx_itim_evt_elapsed_cyc32() -
							cyc_evt_enter_deep_idle;

	cyc_sys_compensated += ((uint64_t)cyc_evt_elapsed_in_deep *
			sys_clock_hw_cycles_per_sec()) / EVT_CYCLES_PER_SEC;
}

uint64_t npcx_clock_get_sleep_ticks(void)
{
	return  cyc_sys_compensated / SYS_CYCLES_PER_TICK;
}
#endif /* CONFIG_PM */

static int sys_clock_driver_init(void)
{
	int ret;
	uint32_t sys_tmr_rate;
	const struct device *const clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE);

	if (!device_is_ready(clk_dev)) {
		LOG_ERR("clock control device not ready");
		return -ENODEV;
	}

	/* Turn on all itim module clocks used for counting */
	for (int i = 0; i < ARRAY_SIZE(itim_clk_cfg); i++) {
		ret = clock_control_on(clk_dev, (clock_control_subsys_t)
				&itim_clk_cfg[i]);
		if (ret < 0) {
			LOG_ERR("Turn on timer %d clock failed.", i);
			return ret;
		}
	}

	/*
	 * In npcx series, we use ITIM64 as system kernel timer. Its source
	 * clock frequency must equal to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC.
	 */
	ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t)
			&itim_clk_cfg[1], &sys_tmr_rate);
	if (ret < 0) {
		LOG_ERR("Get ITIM64 clock rate failed %d", ret);
		return ret;
	}

	if (sys_tmr_rate != CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
		LOG_ERR("CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC doesn't match "
			"ITIM64 clock frequency %d", sys_tmr_rate);
		return -EINVAL;
	}

	/*
	 * Step 1. Use a ITIM64 timer as system kernel timer for counting.
	 * Configure 64-bit timer counter and its prescaler to 1 first.
	 */
	sys_tmr->ITPRE64 = 0;
	sys_tmr->ITCNT64L = NPCX_ITIM64_MAX_HALF_CNT;
	sys_tmr->ITCNT64H = NPCX_ITIM64_MAX_HALF_CNT;
	/*
	 * Select APB2 clock which freq is CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC,
	 * and clear timeout status bit before enabling the whole module.
	 */
	sys_tmr->ITCTS64 = BIT(NPCX_ITCTSXX_TO_STS);
	/* Enable 64-bit timer and start ticking */
	sys_tmr->ITCTS64 |= BIT(NPCX_ITCTSXX_ITEN);

	/*
	 * Step 2. Use a ITIM32 timer for event handling (ex. timeout event).
	 * Configure 32-bit timer's prescaler to 1 first.
	 */
	evt_tmr->ITPRE32 = 0;
	/*
	 * Select low frequency clock source (The freq is 32kHz), enable its
	 * interrupt/wake-up sources, and clear timeout status bit before
	 * enabling it.
	 */
	evt_tmr->ITCTS32 = BIT(NPCX_ITCTSXX_CKSEL) | BIT(NPCX_ITCTSXX_TO_WUE)
			 | BIT(NPCX_ITCTSXX_TO_IE) | BIT(NPCX_ITCTSXX_TO_STS);

	/* A delay for ITIM source clock selection */
	k_busy_wait(NPCX_ITIM_CLK_SEL_DELAY);

	/* Configure event timer's ISR */
	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
					npcx_itim_evt_isr, NULL, 0);
	/* Enable event timer interrupt */
	irq_enable(DT_INST_IRQN(0));

	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		/* Start a event timer in one tick */
		ret = npcx_itim_start_evt_tmr_by_tick(1);
		if (ret < 0) {
			return ret;
		}
	}

	return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
	 CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
