/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <drivers/timer/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 (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;
}
