/*
 * Copyright (c) 2016-2019 Nordic Semiconductor ASA
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <soc.h>
#include <drivers/clock_control.h>
#include <drivers/clock_control/nrf_clock_control.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <hal/nrf_timer.h>
#include <spinlock.h>

#define TIMER NRF_TIMER0

#define COUNTER_MAX 0xffffffff
#define CYC_PER_TICK (sys_clock_hw_cycles_per_sec()	\
		      / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
#define MAX_TICKS ((COUNTER_MAX - CYC_PER_TICK) / CYC_PER_TICK)

static struct k_spinlock lock;

static u32_t last_count;

static u32_t counter_sub(u32_t a, u32_t b)
{
	return (a - b) & COUNTER_MAX;
}

static void set_comparator(u32_t cyc)
{
	nrf_timer_cc_set(TIMER, 0, cyc & COUNTER_MAX);
}

static u32_t counter(void)
{
	nrf_timer_task_trigger(TIMER, nrf_timer_capture_task_get(1));

	return nrf_timer_cc_get(TIMER, 1);
}

void timer0_nrf_isr(void *arg)
{
	ARG_UNUSED(arg);
	TIMER->EVENTS_COMPARE[0] = 0;

	k_spinlock_key_t key = k_spin_lock(&lock);
	u32_t t = counter();
	u32_t dticks = counter_sub(t, last_count) / CYC_PER_TICK;

	last_count += dticks * CYC_PER_TICK;

	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		u32_t next = last_count + CYC_PER_TICK;

		/* As below: we're guaranteed to get an interrupt as
		 * long as it's set two or more cycles in the future
		 */
		if (counter_sub(next, t) < 3) {
			next += CYC_PER_TICK;
		}
		set_comparator(next);
	}

	k_spin_unlock(&lock, key);
	z_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
}

int z_clock_driver_init(struct device *device)
{
	struct device *clock;

	ARG_UNUSED(device);

	clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
	if (!clock) {
		return -1;
	}

	clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);

	nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_1MHz);
	nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32);
	nrf_timer_cc_set(TIMER, 0, CYC_PER_TICK);
	nrf_timer_int_enable(TIMER, TIMER_INTENSET_COMPARE0_Msk);

	/* Clear the event flag and possible pending interrupt */
	nrf_timer_event_clear(TIMER, NRF_TIMER_EVENT_COMPARE0);
	NVIC_ClearPendingIRQ(TIMER0_IRQn);

	IRQ_CONNECT(TIMER0_IRQn, 1, timer0_nrf_isr, 0, 0);
	irq_enable(TIMER0_IRQn);

	nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_CLEAR);
	nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_START);

	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		set_comparator(counter() + CYC_PER_TICK);
	}

	return 0;
}

void z_clock_set_timeout(s32_t ticks, bool idle)
{
	ARG_UNUSED(idle);

#ifdef CONFIG_TICKLESS_KERNEL
	ticks = (ticks == K_FOREVER) ? MAX_TICKS : ticks;
	ticks = MAX(MIN(ticks - 1, (s32_t)MAX_TICKS), 0);

	k_spinlock_key_t key = k_spin_lock(&lock);
	u32_t cyc, dt, t = counter();
	bool zli_fixup = IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS);

	/* Round up to next tick boundary */
	cyc = ticks * CYC_PER_TICK + 1 + counter_sub(t, last_count);
	cyc += (CYC_PER_TICK - 1);
	cyc = (cyc / CYC_PER_TICK) * CYC_PER_TICK;
	cyc += last_count;

	if (counter_sub(cyc, t) > 2) {
		set_comparator(cyc);
	} else {
		set_comparator(cyc);
		dt = counter_sub(cyc, counter());
		if (dt == 0 || dt > 0x7fffff) {
			/* Missed it! */
			NVIC_SetPendingIRQ(TIMER0_IRQn);
			if (IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS)) {
				zli_fixup = false;
			}
		} else if (dt == 1) {
			/* Too soon, interrupt won't arrive. */
			set_comparator(cyc + 2);
		}
		/* Otherwise it was two cycles out, we're fine */
	}

#ifdef CONFIG_ZERO_LATENCY_IRQS
	/* Failsafe.  ZLIs can preempt us even though interrupts are
	 * masked, blowing up the sensitive timing above.  If the
	 * feature is enabled and we haven't recorded the presence of
	 * a pending interrupt then we need a final check (in a loop!
	 * because this too can be interrupted) to confirm that the
	 * comparator is still in the future.  Don't bother being
	 * fancy with cycle counting here, just set an interrupt
	 * "soon" that we know will get the timer back to a known
	 * state.  This handles (via some hairy modular expressions)
	 * the wraparound cases where we are preempted for as much as
	 * half the counter space.
	 */
	if (zli_fixup && counter_sub(cyc, counter()) <= 0x7fffff) {
		while (counter_sub(cyc, counter() + 2) > 0x7fffff) {
			cyc = counter() + 3;
			set_comparator(cyc);
		}
	}
#endif

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

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

	k_spinlock_key_t key = k_spin_lock(&lock);
	u32_t ret = counter_sub(counter(), last_count) / CYC_PER_TICK;

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

u32_t z_timer_cycle_get_32(void)
{
	k_spinlock_key_t key = k_spin_lock(&lock);
	u32_t ret = counter_sub(counter(), last_count) + last_count;

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