/*
 * Copyright (c) 2016 Nordic Semiconductor ASA
 * Copyright (c) 2016 Vinayak Kariappa Chettimada
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <soc.h>
#include <errno.h>
#include <atomic.h>
#include <device.h>
#include <clock_control.h>
#include <misc/__assert.h>
#include <nrf_clock.h>
#if defined(CONFIG_USB) && defined(CONFIG_SOC_NRF52840)
#include <nrf_power.h>
#include <drivers/clock_control/nrf_clock_control.h>
#endif

static u8_t m16src_ref;
static u8_t m16src_grd;
static u8_t k32src_initialized;

static int _m16src_start(struct device *dev, clock_control_subsys_t sub_system)
{
	bool blocking;
	u32_t imask;
	u32_t stat;

	/* If the clock is already started then just increment refcount.
	 * If the start and stop don't happen in pairs, a rollover will
	 * be caught and in that case system should assert.
	 */

	/* Test for reference increment from zero and resource guard not taken.
	 */
	imask = irq_lock();

	if (m16src_ref++) {
		irq_unlock(imask);
		goto hf_already_started;
	}

	if (m16src_grd) {
		m16src_ref--;
		irq_unlock(imask);
		return -EAGAIN;
	}

	m16src_grd = 1U;

	irq_unlock(imask);

	/* If blocking then spin-wait in CPU sleep until 16MHz clock settles. */
	blocking = POINTER_TO_UINT(sub_system);
	if (blocking) {
		u32_t intenset;

		irq_disable(DT_NORDIC_NRF_CLOCK_0_IRQ_0);

		NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;

		intenset = NRF_CLOCK->INTENSET;
		nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK);

		nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART);

		while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {
			__WFE();
			__SEV();
			__WFE();
		}

		NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;

		if (!(intenset & CLOCK_INTENSET_HFCLKSTARTED_Msk)) {
			nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK);
		}

		NVIC_ClearPendingIRQ(DT_NORDIC_NRF_CLOCK_0_IRQ_0);

		irq_enable(DT_NORDIC_NRF_CLOCK_0_IRQ_0);
	} else {
		NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;

		nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART);
	}

	/* release resource guard */
	m16src_grd = 0U;

hf_already_started:
	/* rollover should not happen as start and stop shall be
	 * called in pairs.
	 */
	__ASSERT_NO_MSG(m16src_ref);

	stat = NRF_CLOCK_HFCLK_HIGH_ACCURACY | CLOCK_HFCLKSTAT_STATE_Msk;
	if ((NRF_CLOCK->HFCLKSTAT & stat) == stat) {
		return 0;
	} else {
		return -EINPROGRESS;
	}
}

static int _m16src_stop(struct device *dev, clock_control_subsys_t sub_system)
{
	u32_t imask;

	ARG_UNUSED(sub_system);

	/* Test for started resource, if so, decrement reference and acquire
	 * resource guard.
	 */
	imask = irq_lock();

	if (!m16src_ref) {
		irq_unlock(imask);
		return -EALREADY;
	}

	if (--m16src_ref) {
		irq_unlock(imask);
		return -EBUSY;
	}

	if (m16src_grd) {
		m16src_ref++;
		irq_unlock(imask);
		return -EAGAIN;
	}

	m16src_grd = 1U;

	irq_unlock(imask);

	/* re-entrancy and mult-context safe, and reference count is zero, */

	nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP);

	/* release resource guard */
	m16src_grd = 0U;

	return 0;
}

static int _k32src_start(struct device *dev, clock_control_subsys_t sub_system)
{
	u32_t lf_clk_src;
	u32_t imask;
	u32_t stat;

#if defined(CONFIG_CLOCK_CONTROL_NRF_K32SRC_BLOCKING)
	u32_t intenset;
#endif /* CONFIG_CLOCK_CONTROL_NRF_K32SRC_BLOCKING */

	/* If the LF clock is already started, but wasn't initialized with
	 * this function, allow it to run once. This is needed because if a
	 * soft reset is triggered while watchdog is active, the LF clock will
	 * already be running, but won't be configured yet (watchdog forces LF
	 * clock to be running).
	 *
	 * That is, a hardware check won't work here, because even if the LF
	 * clock is already running it might not be initialized. We need an
	 * initialized flag.
	 */

	imask = irq_lock();

	if (k32src_initialized) {
		irq_unlock(imask);
		goto lf_already_started;
	}

	k32src_initialized = 1U;

	irq_unlock(imask);

	/* Clear events if any */
	NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;

	/* Set LF Clock Source */
	lf_clk_src = POINTER_TO_UINT(sub_system);
	NRF_CLOCK->LFCLKSRC = lf_clk_src;

#if defined(CONFIG_CLOCK_CONTROL_NRF_K32SRC_BLOCKING)
	irq_disable(DT_NORDIC_NRF_CLOCK_0_IRQ_0);

	intenset = NRF_CLOCK->INTENSET;
	nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK);

	/* Start and spin-wait until clock settles */
	nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);

	while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
		__WFE();
		__SEV();
		__WFE();
	}

	NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;

	if (!(intenset & CLOCK_INTENSET_LFCLKSTARTED_Msk)) {
		nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK);
	}

	NVIC_ClearPendingIRQ(DT_NORDIC_NRF_CLOCK_0_IRQ_0);

	irq_enable(DT_NORDIC_NRF_CLOCK_0_IRQ_0);

#else /* !CONFIG_CLOCK_CONTROL_NRF_K32SRC_BLOCKING */
	/* NOTE: LFCLK will initially start running from the LFRC if LFXO is
	 *       selected.
	 */
	nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK);
	nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
#endif /* !CONFIG_CLOCK_CONTROL_NRF_K32SRC_BLOCKING */

#if NRF_CLOCK_HAS_CALIBRATION
	/* If RC selected, calibrate and start timer for consecutive
	 * calibrations.
	 */
	nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK |
			      NRF_CLOCK_INT_CTTO_MASK);
	NRF_CLOCK->EVENTS_DONE = 0;
	NRF_CLOCK->EVENTS_CTTO = 0;

	if ((lf_clk_src & CLOCK_LFCLKSRC_SRC_Msk) == CLOCK_LFCLKSRC_SRC_RC) {
		int err;

		/* Set the Calibration Timer Initial Value */
		NRF_CLOCK->CTIV = 16;	/* 4s in 0.25s units */

		/* Enable DONE and CTTO IRQs */
		nrf_clock_int_enable(NRF_CLOCK_INT_DONE_MASK |
				     NRF_CLOCK_INT_CTTO_MASK);

		/* If non-blocking LF clock start, then start HF clock in ISR */
		if ((NRF_CLOCK->LFCLKSTAT & CLOCK_LFCLKSTAT_STATE_Msk) == 0) {
			nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK);
			goto lf_already_started;
		}

		/* Start HF clock, if already started then explicitly
		 * assert IRQ.
		 * NOTE: The INTENSET is used as state flag to start
		 * calibration in ISR.
		 */
		nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK);

		err = _m16src_start(dev, false);
		if (!err) {
			NVIC_SetPendingIRQ(DT_NORDIC_NRF_CLOCK_0_IRQ_0);
		} else {
			__ASSERT_NO_MSG(err == -EINPROGRESS);
		}
	}
#endif /* NRF_CLOCK_HAS_CALIBRATION */

lf_already_started:
	stat = (NRF_CLOCK->LFCLKSRCCOPY & CLOCK_LFCLKSRCCOPY_SRC_Msk) |
	       CLOCK_LFCLKSTAT_STATE_Msk;
	if ((NRF_CLOCK->LFCLKSTAT & stat) == stat) {
		return 0;
	} else {
		return -EINPROGRESS;
	}
}

#if defined(CONFIG_USB) && defined(CONFIG_SOC_NRF52840)
static inline void power_event_cb(nrf_power_event_t event)
{
	extern void usb_dc_nrfx_power_event_callback(nrf_power_event_t event);

	usb_dc_nrfx_power_event_callback(event);
}
#endif

static void _power_clock_isr(void *arg)
{
	u8_t pof, hf_intenset, hf, lf_intenset, lf;
#if NRF_CLOCK_HAS_CALIBRATION
	u8_t ctto, done;
	struct device *dev = arg;
#endif
#if defined(CONFIG_USB) && defined(CONFIG_SOC_NRF52840)
	bool usb_detected, usb_pwr_rdy, usb_removed;
#endif

	pof = (NRF_POWER->EVENTS_POFWARN != 0);

	hf_intenset = ((NRF_CLOCK->INTENSET &
		       CLOCK_INTENSET_HFCLKSTARTED_Msk) != 0);
	hf = (NRF_CLOCK->EVENTS_HFCLKSTARTED != 0);

	lf_intenset = ((NRF_CLOCK->INTENSET &
		       CLOCK_INTENSET_LFCLKSTARTED_Msk) != 0);
	lf = (NRF_CLOCK->EVENTS_LFCLKSTARTED != 0);

#if NRF_CLOCK_HAS_CALIBRATION
	done = (NRF_CLOCK->EVENTS_DONE != 0);
	ctto = (NRF_CLOCK->EVENTS_CTTO != 0);
#endif
#if defined(CONFIG_USB) && defined(CONFIG_SOC_NRF52840)
	usb_detected = nrf_power_event_check(NRF_POWER_EVENT_USBDETECTED);
	usb_pwr_rdy = nrf_power_event_check(NRF_POWER_EVENT_USBPWRRDY);
	usb_removed = nrf_power_event_check(NRF_POWER_EVENT_USBREMOVED);
#endif

	__ASSERT_NO_MSG(pof || hf || hf_intenset || lf
#if NRF_CLOCK_HAS_CALIBRATION
			|| done || ctto
#endif
#if defined(CONFIG_USB) && defined(CONFIG_SOC_NRF52840)
			|| usb_detected || usb_pwr_rdy || usb_removed
#endif
	);

	if (pof) {
		NRF_POWER->EVENTS_POFWARN = 0;
	}

	if (hf) {
		NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
	}

	if (hf_intenset && (hf || ((NRF_CLOCK->HFCLKSTAT &
				    (CLOCK_HFCLKSTAT_STATE_Msk |
				     CLOCK_HFCLKSTAT_SRC_Msk)) ==
				   (CLOCK_HFCLKSTAT_STATE_Msk |
				    CLOCK_HFCLKSTAT_SRC_Msk)))){
		/* INTENSET is used as state flag to start calibration,
		 * hence clear it here.
		 */
		NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_HFCLKSTARTED_Msk;

#if defined(CONFIG_SOC_SERIES_NRF52X)
		/* NOTE: Errata [192] CLOCK: LFRC frequency offset after
		 * calibration.
		 * Calibration start, workaround.
		 */
		*(volatile u32_t *)0x40000C34 = 0x00000002;
#endif /* CONFIG_SOC_SERIES_NRF52X */

#if NRF_CLOCK_HAS_CALIBRATION
		/* Start Calibration */
		NRF_CLOCK->TASKS_CAL = 1;
#endif
	}

	if (lf) {
		NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;

		if (lf_intenset) {
			/* INTENSET is used as state flag to start calibration,
			 * hence clear it here.
			 */
			NRF_CLOCK->INTENCLR = CLOCK_INTENCLR_LFCLKSTARTED_Msk;

#if NRF_CLOCK_HAS_CALIBRATION
			/* Start HF Clock if LF RC is used. */
			if ((NRF_CLOCK->LFCLKSRCCOPY & CLOCK_LFCLKSRCCOPY_SRC_Msk) ==
			    CLOCK_LFCLKSRCCOPY_SRC_RC) {
				ctto = 1U;
			}
#endif
		}
	}

#if NRF_CLOCK_HAS_CALIBRATION
	if (done) {
		int err;

#if defined(CONFIG_SOC_SERIES_NRF52X)
		/* NOTE: Errata [192] CLOCK: LFRC frequency offset after
		 * calibration.
		 * Calibration done, workaround.
		 */
		*(volatile u32_t *)0x40000C34 = 0x00000000;
#endif /* CONFIG_SOC_SERIES_NRF52X */

		NRF_CLOCK->EVENTS_DONE = 0;

		/* Calibration done, stop 16M Xtal. */
		err = _m16src_stop(dev, NULL);
		__ASSERT_NO_MSG(!err || err == -EBUSY);

		/* Start timer for next calibration. */
		NRF_CLOCK->TASKS_CTSTART = 1;
	}

	if (ctto) {
		int err;

		NRF_CLOCK->EVENTS_CTTO = 0;

		/* Start HF clock, if already started
		 * then explicitly assert IRQ; we use the INTENSET
		 * as a state flag to start calibration.
		 */
		NRF_CLOCK->INTENSET = CLOCK_INTENSET_HFCLKSTARTED_Msk;

		err = _m16src_start(dev, false);
		if (!err) {
			NVIC_SetPendingIRQ(DT_NORDIC_NRF_CLOCK_0_IRQ_0);
		} else {
			__ASSERT_NO_MSG(err == -EINPROGRESS);
		}
	}
#endif /* NRF_CLOCK_HAS_CALIBRATION */

#if defined(CONFIG_USB) && defined(CONFIG_SOC_NRF52840)
	if (usb_detected) {
		nrf_power_event_clear(NRF_POWER_EVENT_USBDETECTED);
		power_event_cb(NRF_POWER_EVENT_USBDETECTED);
	}

	if (usb_pwr_rdy) {
		nrf_power_event_clear(NRF_POWER_EVENT_USBPWRRDY);
		power_event_cb(NRF_POWER_EVENT_USBPWRRDY);
	}

	if (usb_removed) {
		nrf_power_event_clear(NRF_POWER_EVENT_USBREMOVED);
		power_event_cb(NRF_POWER_EVENT_USBREMOVED);
	}
#endif
}

static int _clock_control_init(struct device *dev)
{
	/* TODO: Initialization will be called twice, once for 32KHz and then
	 * for 16 MHz clock. The vector is also shared for other power related
	 * features. Hence, design a better way to init IRQISR when adding
	 * power peripheral driver and/or new SoC series.
	 * NOTE: Currently the operations here are idempotent.
	 */
	IRQ_CONNECT(DT_NORDIC_NRF_CLOCK_0_IRQ_0,
		    CONFIG_CLOCK_CONTROL_NRF_IRQ_PRIORITY,
		    _power_clock_isr, 0, 0);

	irq_enable(DT_NORDIC_NRF_CLOCK_0_IRQ_0);

	return 0;
}

static const struct clock_control_driver_api _m16src_clock_control_api = {
	.on = _m16src_start,
	.off = _m16src_stop,
	.get_rate = NULL,
};

DEVICE_AND_API_INIT(clock_nrf5_m16src,
		    CONFIG_CLOCK_CONTROL_NRF_M16SRC_DRV_NAME,
		    _clock_control_init, NULL, NULL, PRE_KERNEL_1,
		    CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &_m16src_clock_control_api);

static const struct clock_control_driver_api _k32src_clock_control_api = {
	.on = _k32src_start,
	.off = NULL,
	.get_rate = NULL,
};

DEVICE_AND_API_INIT(clock_nrf5_k32src,
		    CONFIG_CLOCK_CONTROL_NRF_K32SRC_DRV_NAME,
		    _clock_control_init, NULL, NULL, PRE_KERNEL_1,
		    CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &_k32src_clock_control_api);

#if defined(CONFIG_USB) && defined(CONFIG_SOC_NRF52840)

void nrf5_power_usb_power_int_enable(bool enable)
{
	u32_t mask;


	mask = NRF_POWER_INT_USBDETECTED_MASK |
	       NRF_POWER_INT_USBREMOVED_MASK |
	       NRF_POWER_INT_USBPWRRDY_MASK;

	if (enable) {
		nrf_power_int_enable(mask);
		irq_enable(DT_NORDIC_NRF_CLOCK_0_IRQ_0);
	} else {
		nrf_power_int_disable(mask);
	}
}

#endif
