/*
 * Copyright (c) 2019, Texas Instruments Incorporated
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ti_cc13xx_cc26xx_rtc

/*
 * TI SimpleLink CC13X2/CC26X2 RTC-based system timer
 *
 * This system timer implementation supports both tickless and ticking modes.
 * RTC counts continually in 64-bit mode and timeouts are
 * scheduled using the RTC comparator. An interrupt is triggered whenever
 * the comparator value set is reached.
 */

#include <device.h>
#include <soc.h>
#include <drivers/clock_control.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>

#include <driverlib/interrupt.h>
#include <driverlib/aon_rtc.h>
#include <driverlib/aon_event.h>

#define RTC_COUNTS_PER_SEC 0x100000000ULL

/* Number of counts per rtc timer cycle */
#define RTC_COUNTS_PER_CYCLE (RTC_COUNTS_PER_SEC / \
	sys_clock_hw_cycles_per_sec())

/* Number of counts per system clock tick */
#define RTC_COUNTS_PER_TICK (RTC_COUNTS_PER_SEC / \
	CONFIG_SYS_CLOCK_TICKS_PER_SEC)

/* Number of RTC cycles per system clock tick */
#define CYCLES_PER_TICK (sys_clock_hw_cycles_per_sec() / \
	CONFIG_SYS_CLOCK_TICKS_PER_SEC)

/*
 * Maximum number of ticks.
 */
#define MAX_CYC 0x7FFFFFFFFFFFULL
#define MAX_TICKS (MAX_CYC / RTC_COUNTS_PER_TICK)

/*
 * Due to the nature of clock synchronization, the comparator cannot be set
 * to a value that is too close to the current time. This constant defines
 * a safe threshold for the comparator.
 */
#define COMPARE_MARGIN 6

/* RTC count of the last announce call, rounded down to tick boundary. */
static volatile uint64_t rtc_last;

#ifdef CONFIG_TICKLESS_KERNEL
static struct k_spinlock lock;
#else
static uint64_t nextThreshold = RTC_COUNTS_PER_TICK;
#endif /* CONFIG_TICKLESS_KERNEL */


static void setThreshold(uint32_t next)
{
	uint32_t now;
	unsigned int key;

	key = irq_lock();

	/* get the current RTC count corresponding to compare window */
	now = AONRTCCurrentCompareValueGet();

	/* if next is too soon, set at least one RTC tick in future */
	/* assume next never be more than half the maximum 32 bit count value */
	if ((next - now) > (uint32_t)0x80000000) {
		/* now is past next */
		next = now + COMPARE_MARGIN;
	} else if ((now + COMPARE_MARGIN - next) < (uint32_t)0x80000000) {
		if (next < now + COMPARE_MARGIN) {
			next = now + COMPARE_MARGIN;
		}
	}

	/* set next compare threshold in RTC */
	AONRTCCompareValueSet(AON_RTC_CH0, next);

	irq_unlock(key);
}

void rtc_isr(const void *arg)
{
#ifndef CONFIG_TICKLESS_KERNEL
	uint64_t newThreshold;
	uint32_t next;
#else
	uint64_t ticks, currCount;
#endif

	ARG_UNUSED(arg);

	AONRTCEventClear(AON_RTC_CH0);

#ifdef CONFIG_TICKLESS_KERNEL
	k_spinlock_key_t key = k_spin_lock(&lock);
	currCount = (uint64_t)AONRTCCurrent64BitValueGet();
	ticks = (currCount - rtc_last) / RTC_COUNTS_PER_TICK;

	rtc_last += ticks * RTC_COUNTS_PER_TICK;
	k_spin_unlock(&lock, key);

	sys_clock_announce(ticks);

#else /* !CONFIG_TICKLESS_KERNEL */

	/* calculate new 64-bit RTC count for next interrupt */
	newThreshold = nextThreshold + RTC_COUNTS_PER_TICK;

	next = (uint32_t)((uint64_t)newThreshold >> 16);
	setThreshold(next);

	nextThreshold = newThreshold;

	rtc_last += RTC_COUNTS_PER_TICK;

	sys_clock_announce(1);

#endif /* CONFIG_TICKLESS_KERNEL */
}

static void initDevice(void)
{
	AONRTCDisable();
	AONRTCReset();

	HWREG(AON_RTC_BASE + AON_RTC_O_SYNC) = 1;
	/* read sync register to complete reset */
	HWREG(AON_RTC_BASE + AON_RTC_O_SYNC);

	AONRTCEventClear(AON_RTC_CH0);
	IntPendClear(INT_AON_RTC_COMB);

	HWREG(AON_RTC_BASE + AON_RTC_O_SYNC);
}

static void startDevice(void)
{
	uint32_t compare;
	uint64_t period;
	unsigned int key;

	key = irq_lock();

	/* reset timer */
	AONRTCReset();
	AONRTCEventClear(AON_RTC_CH0);
	IntPendClear(INT_AON_RTC_COMB);

	/*
	 * set the compare register to one period.
	 * For a very small period round up to interrupt upon 4th tick in
	 * compare register
	 */
	period = RTC_COUNTS_PER_TICK;
	if (period < 0x40000) {
		compare = 0x4; /* 4 * 15.5us ~= 62us */
	} else {
		/* else, interrupt on first period expiration */
		compare = period >> 16;
	}

	/* set the compare value at the RTC */
	AONRTCCompareValueSet(AON_RTC_CH0, compare);

	/* enable compare channel 0 */
	AONEventMcuWakeUpSet(AON_EVENT_MCU_WU0, AON_EVENT_RTC0);
	AONRTCChannelEnable(AON_RTC_CH0);
	AONRTCCombinedEventConfig(AON_RTC_CH0);

	/* start timer */
	AONRTCEnable();

	irq_unlock(key);
}

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

#ifdef CONFIG_TICKLESS_KERNEL

	ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks;
	ticks = CLAMP(ticks - 1, 0, (int32_t) MAX_TICKS);

	k_spinlock_key_t key = k_spin_lock(&lock);

	/* Compute number of RTC cycles until the next timeout. */
	uint64_t count = AONRTCCurrent64BitValueGet();
	uint64_t timeout = ticks * RTC_COUNTS_PER_TICK +
		(count - rtc_last);

	/* Round to the nearest tick boundary. */
	timeout = (timeout + RTC_COUNTS_PER_TICK - 1) / RTC_COUNTS_PER_TICK
		  * RTC_COUNTS_PER_TICK;
	timeout = MIN(timeout, MAX_CYC);
	timeout += rtc_last;

	/* Set the comparator */
	setThreshold(timeout >> 16);

	k_spin_unlock(&lock, key);
#endif /* CONFIG_TICKLESS_KERNEL */
}

uint32_t sys_clock_elapsed(void)
{
	uint32_t ret = (AONRTCCurrent64BitValueGet() - rtc_last) /
		RTC_COUNTS_PER_TICK;

	return ret;
}

uint32_t sys_clock_cycle_get_32(void)
{
	return (uint32_t)(AONRTCCurrent64BitValueGet() / RTC_COUNTS_PER_CYCLE);
}

uint64_t sys_clock_cycle_get_64(void)
{
	return AONRTCCurrent64BitValueGet() / RTC_COUNTS_PER_CYCLE;
}

static int sys_clock_driver_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	rtc_last = 0U;

	initDevice();
	startDevice();

	/* Enable RTC interrupt. */
	IRQ_CONNECT(DT_INST_IRQN(0),
		DT_INST_IRQ(0, priority),
		rtc_isr, 0, 0);
	irq_enable(DT_INST_IRQN(0));

	return 0;
}

SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
	 CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
