/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <drivers/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
#include <arch/arm/cortex_m/cmsis.h>

void z_ExcExit(void);

#define COUNTER_MAX 0x00ffffff
#define TIMER_STOPPED 0xff000000

#define CYC_PER_TICK (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC	\
		      / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
#define MAX_TICKS ((COUNTER_MAX / CYC_PER_TICK) - 1)
#define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK)

/* Minimum cycles in the future to try to program.  Note that this is
 * NOT simply "enough cycles to get the counter read and reprogrammed
 * reliably" -- it becomes the minimum value of the LOAD register, and
 * thus reflects how much time we can reliably see expire between
 * calls to elapsed() to read the COUNTFLAG bit.  So it needs to be
 * set to be larger than the maximum time the interrupt might be
 * masked.  Choosing a fraction of a tick is probably a good enough
 * default, with an absolute minimum of 1k cyc.
 */
#define MIN_DELAY MAX(1024, (CYC_PER_TICK/16))

#define TICKLESS (IS_ENABLED(CONFIG_TICKLESS_KERNEL) &&			\
		  !IS_ENABLED(CONFIG_QEMU_TICKLESS_WORKAROUND))

/* VAL value above which we assume that a subsequent COUNTFLAG
 * overflow seen in CTRL is real and not an artifact of wraparound
 * timing.
 */
#define VAL_ABOUT_TO_WRAP 8

static struct k_spinlock lock;

static u32_t last_load;

static u32_t cycle_count;

static u32_t announced_cycles;

static volatile u32_t overflow_cyc;

static u32_t elapsed(void)
{
	u32_t val, ctrl1, ctrl2;

	/* SysTick is infuriatingly racy.  The counter wraps at zero
	 * automatically, setting a 1 in the COUNTFLAG bit of the CTRL
	 * register when it does.  But reading the control register
	 * automatically resets that bit, so we need to save it for
	 * future calls.  And ordering is critical and race-prone: if
	 * we read CTRL first, then it is possible for VAL to wrap
	 * after that read but before we read VAL and we'll miss the
	 * overflow.  If we read VAL first, then it can wrap after we
	 * read it and we'll see an "extra" overflow in CTRL.  And we
	 * want to handle multiple overflows, so we effectively must
	 * read CTRL first otherwise there will be no way to detect
	 * the double-overflow if called at the end of a cycle.  There
	 * is no safe algorithm here, so we split the difference by
	 * reading CTRL twice, suppressing the second overflow bit if
	 * VAL was "about to overflow".
	 */
	ctrl1 = SysTick->CTRL;
	val = SysTick->VAL & COUNTER_MAX;
	ctrl2 = SysTick->CTRL;

	overflow_cyc += (ctrl1 & SysTick_CTRL_COUNTFLAG_Msk) ? last_load : 0;
	if (val > VAL_ABOUT_TO_WRAP) {
		int wrap = ctrl2 & SysTick_CTRL_COUNTFLAG_Msk;

		overflow_cyc += (wrap != 0) ? last_load : 0;
	}

	return (last_load - val) + overflow_cyc;
}

/* Callout out of platform assembly, not hooked via IRQ_CONNECT... */
void z_clock_isr(void *arg)
{
	ARG_UNUSED(arg);
	u32_t dticks;

	cycle_count += last_load;
	dticks = (cycle_count - announced_cycles) / CYC_PER_TICK;
	announced_cycles += dticks * CYC_PER_TICK;

	overflow_cyc = SysTick->CTRL; /* Reset overflow flag */
	overflow_cyc = 0U;

	z_clock_announce(TICKLESS ? dticks : 1);
	z_ExcExit();
}

int z_clock_driver_init(struct device *device)
{
	NVIC_SetPriority(SysTick_IRQn, _IRQ_PRIO_OFFSET);
	last_load = CYC_PER_TICK - 1;
	overflow_cyc = 0U;
	SysTick->LOAD = last_load;
	SysTick->VAL = 0; /* resets timer to last_load */
	SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk |
			  SysTick_CTRL_TICKINT_Msk |
			  SysTick_CTRL_CLKSOURCE_Msk);
	return 0;
}

void z_clock_set_timeout(s32_t ticks, bool idle)
{
	/* Fast CPUs and a 24 bit counter mean that even idle systems
	 * need to wake up multiple times per second.  If the kernel
	 * allows us to miss tick announcements in idle, then shut off
	 * the counter. (Note: we can assume if idle==true that
	 * interrupts are already disabled)
	 */
	if (IS_ENABLED(CONFIG_TICKLESS_IDLE) && idle && ticks == K_FOREVER) {
		SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
		last_load = TIMER_STOPPED;
		return;
	}

#if defined(CONFIG_TICKLESS_KERNEL) && !defined(CONFIG_QEMU_TICKLESS_WORKAROUND)
	u32_t delay;

	ticks = MIN(MAX_TICKS, MAX(ticks - 1, 0));

	/* Desired delay in the future */
	delay = (ticks == 0) ? MIN_DELAY : ticks * CYC_PER_TICK;

	k_spinlock_key_t key = k_spin_lock(&lock);

	cycle_count += elapsed();

	/* Round delay up to next tick boundary */
	delay = delay + (cycle_count - announced_cycles);
	delay = ((delay + CYC_PER_TICK - 1) / CYC_PER_TICK) * CYC_PER_TICK;
	last_load = delay - (cycle_count - announced_cycles);

	overflow_cyc = 0U;
	SysTick->LOAD = last_load - 1;
	SysTick->VAL = 0; /* resets timer to last_load */

	k_spin_unlock(&lock, key);
#endif
}

u32_t z_clock_elapsed(void)
{
	if (!TICKLESS) {
		return 0;
	}

	k_spinlock_key_t key = k_spin_lock(&lock);
	u32_t cyc = elapsed() + cycle_count - announced_cycles;

	k_spin_unlock(&lock, key);
	return cyc / CYC_PER_TICK;
}

u32_t z_timer_cycle_get_32(void)
{
	k_spinlock_key_t key = k_spin_lock(&lock);
	u32_t ret = elapsed() + cycle_count;

	k_spin_unlock(&lock, key);
	return ret;
}

void z_clock_idle_exit(void)
{
	if (last_load == TIMER_STOPPED) {
		SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
	}
}

void sys_clock_disable(void)
{
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
