/*
 * Copyright (c) 2023 Antmicro <www.antmicro.com>
 *
 * Based on:
 *  sam0_rtc_timer.c Copyright (c) 2018 omSquare s.r.o.
 *  intel_adsp_timer.c Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT silabs_gecko_burtc

/**
 * @file
 * @brief SiLabs Gecko BURTC-based sys_clock driver
 *
 */

#include <zephyr/device.h>
#include <soc.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/timer/system_timer.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/sys_clock.h>
#include <zephyr/irq.h>
#include <zephyr/spinlock.h>
#include <zephyr/logging/log.h>

#include "em_device.h"
#include "em_cmu.h"
#include "em_burtc.h"


LOG_MODULE_REGISTER(gecko_burtc_timer);


/* Maximum time interval between timer interrupts (in hw_cycles) */
#define MAX_TIMEOUT_CYC (UINT32_MAX >> 1)

/*
 * Mininum time interval between now and IRQ firing that can be scheduled.
 * The main cause for this is LFSYNC register update, which requires several
 * LF clk cycles for synchronization.
 * Seee e.g. "4.2.4.4.4 LFSYNC Registers" in "EFR32xG22 Reference Manual"
 */
#define MIN_DELAY_CYC (6u)

#define TIMER_IRQ (DT_INST_IRQN(0))

#if defined(CONFIG_TEST)
/* See tests/kernel/context */
const int32_t z_sys_timer_irq_for_test = TIMER_IRQ;
#endif

/* With CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME, that's where we
 * should write hw_cycles timer clock frequency upon init
 */
extern int z_clock_hw_cycles_per_sec;

/* Number of hw_cycles clocks per 1 kernel tick */
static uint32_t g_cyc_per_tick;

/* MAX_TIMEOUT_CYC expressed as ticks */
static uint32_t g_max_timeout_ticks;

/* Value of BURTC counter when the previous kernel tick was announced */
static atomic_t g_last_count;

/* Spinlock to sync between Compare ISR and update of Compare register */
static struct k_spinlock g_lock;

/* Set to true when timer is initialized */
static bool g_init;

static void burtc_isr(const void *arg)
{
	ARG_UNUSED(arg);

	/* Clear the interrupt */
	BURTC_IntClear(BURTC_IF_COMP);

	uint32_t curr = BURTC_CounterGet();

	/* NOTE: this is the only place where g_last_count is modified,
	 * so we don't need to do make the whole read-and-modify atomic, just
	 * writing it behind the memory barrier is enough
	 */
	uint32_t prev = atomic_get(&g_last_count);

	/* How many ticks have we not announced since the last announcement */
	uint32_t unannounced = (curr - prev) / g_cyc_per_tick;

	atomic_set(&g_last_count, prev + unannounced * g_cyc_per_tick);

	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		/* Counter value on which announcement should be made */
		uint32_t next = prev + g_cyc_per_tick;

		/* `next` can be too close in the future since we're trying to
		 * announce the very next tick - in that case we skip one and
		 * announce the one after it instead
		 */
		if ((next - curr) < MIN_DELAY_CYC) {
			next += g_cyc_per_tick;
		}

		BURTC_CompareSet(0, next);
	}

	sys_clock_announce(unannounced);
}

void sys_clock_set_timeout(int32_t ticks, bool idle)
{
	ARG_UNUSED(idle);

	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		return;
	}

	/*
	 * calculate 'ticks' value that specifies which tick to announce,
	 * beginning from the closest upcoming one:
	 * 0 - announce upcoming tick itself
	 * 1 - skip upcoming one, but announce the one after it, etc.
	 */
	ticks = (ticks == K_TICKS_FOREVER) ? g_max_timeout_ticks : ticks;
	ticks = CLAMP(ticks - 1, 0, g_max_timeout_ticks);

	k_spinlock_key_t key = k_spin_lock(&g_lock);

	uint32_t curr = BURTC_CounterGet();
	uint32_t prev = atomic_get(&g_last_count);

	/* How many ticks have we not announced since the last announcement */
	uint32_t unannounced = (curr - prev) / g_cyc_per_tick;

	/* Which tick to announce (counting from the last announced one) */
	uint32_t to_announce = unannounced + ticks + 1;

	/* Force maximum interval between announcements. If we sit without
	 * announcements for too long, counter will roll over and we'll lose
	 * track of unannounced ticks.
	 */
	to_announce = MIN(to_announce, g_max_timeout_ticks);

	/* Counter value on which announcement should be made */
	uint32_t next = prev + to_announce * g_cyc_per_tick;

	/* `next` can be too close in the future if we're trying to announce
	 * the very next tick - in that case we skip one and announce the one
	 * after it instead
	 */
	if ((next - curr) < MIN_DELAY_CYC) {
		next += g_cyc_per_tick;
	}

	BURTC_CompareSet(0, next);
	k_spin_unlock(&g_lock, key);
}

uint32_t sys_clock_elapsed(void)
{
	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL) || !g_init) {
		return 0;
	} else {
		return (BURTC_CounterGet() - g_last_count) / g_cyc_per_tick;
	}
}

uint32_t sys_clock_cycle_get_32(void)
{
	/* API note: this function is unrelated to kernel ticks, it returns
	 * a value of some 32-bit hw_cycles counter which counts with
	 * z_clock_hw_cycles_per_sec frequency
	 */
	if (!g_init) {
		return 0;
	} else {
		return BURTC_CounterGet();
	}
}

static int burtc_init(void)
{
	uint32_t hw_clock_freq;
	BURTC_Init_TypeDef init = BURTC_INIT_DEFAULT;

	/* Enable clock for BURTC CSRs on APB */
	CMU_ClockEnable(cmuClock_BURTC, true);

	/* Configure BURTC LF clocksource according to Kconfig */
#if defined(CONFIG_CMU_BURTCCLK_LFXO)
	CMU_ClockSelectSet(cmuClock_BURTC, cmuSelect_LFXO);
#elif defined(CONFIG_CMU_BURTCCLK_LFRCO)
	CMU_ClockSelectSet(cmuClock_BURTC, cmuSelect_LFRCO);
#elif defined(CONFIG_CMU_BURTCCLK_ULFRCO)
	CMU_ClockSelectSet(cmuClock_BURTC, cmuSelect_ULFRCO);
#else
#error "Unsupported BURTC clock specified"
#endif

	/* Calculate timing constants and init BURTC */
	hw_clock_freq = CMU_ClockFreqGet(cmuClock_BURTC);
	z_clock_hw_cycles_per_sec = hw_clock_freq;

	BUILD_ASSERT(CONFIG_SYS_CLOCK_TICKS_PER_SEC > 0,
			"Invalid CONFIG_SYS_CLOCK_TICKS_PER_SEC value");
	g_cyc_per_tick = hw_clock_freq / CONFIG_SYS_CLOCK_TICKS_PER_SEC;

	__ASSERT(g_cyc_per_tick >= MIN_DELAY_CYC,
		"%u cycle-long tick is too short to be scheduled "
		"(min is %u). Config: SYS_CLOCK_TICKS_PER_SEC is "
		"%d and timer frequency is %u",
		g_cyc_per_tick, MIN_DELAY_CYC, CONFIG_SYS_CLOCK_TICKS_PER_SEC,
		hw_clock_freq);

	g_max_timeout_ticks = MAX_TIMEOUT_CYC / g_cyc_per_tick;

	init.clkDiv = 1;
	init.start = false;
	BURTC_Init(&init);
	g_init = true;

	/* Enable compare match interrupt */
	BURTC_IntClear(BURTC_IF_COMP);
	BURTC_IntEnable(BURTC_IF_COMP);
	NVIC_ClearPendingIRQ(TIMER_IRQ);
	IRQ_CONNECT(TIMER_IRQ, DT_INST_IRQ(0, priority), burtc_isr, 0, 0);
	irq_enable(TIMER_IRQ);

	/* Start the timer and announce 1 kernel tick */
	atomic_set(&g_last_count, 0);
	BURTC_CompareSet(0, g_cyc_per_tick);

	BURTC_SyncWait();
	BURTC->CNT = 0;
	BURTC_Start();

	return 0;
}

SYS_INIT(burtc_init, PRE_KERNEL_2,
	 CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
