/*
 * Copyright (c) 2020, Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/ztest.h>
#include <hal/nrf_clock.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>

static nrf_clock_lfclk_t clk_type;
static bool clk_on;
static uint32_t rtc_cnt;

static void xtal_check(bool on, nrf_clock_lfclk_t type)
{
	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
		zassert_false(on, "Clock should be off");
	} else if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY)) {
		bool is_running =
			rtc_cnt || (on && (type == NRF_CLOCK_LFCLK_RC));

		zassert_true(is_running, "Clock should be on");
	} else {
		zassert_true(on, "Clock should be on");
		zassert_equal(type, NRF_CLOCK_LFCLK_XTAL);
	}
}

static void rc_check(bool on, nrf_clock_lfclk_t type)
{
	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
		zassert_false(on, "Clock should be off");
	} else {
		zassert_true(on, "Clock should be on");
		zassert_equal(type, NRF_CLOCK_LFCLK_RC);
	}
}

static void synth_check(bool on, nrf_clock_lfclk_t type)
{
	#if !defined(CLOCK_LFCLKSRC_SRC_Synth) && \
	    !defined(CLOCK_LFCLKSRC_SRC_LFSYNT)
	#define NRF_CLOCK_LFCLK_SYNTH 0
	#endif

	if (!IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
		zassert_true(on, "Clock should be on");
		zassert_equal(type, NRF_CLOCK_LFCLK_SYNTH);
	}
}

ZTEST(nrf_lf_clock_start, test_clock_check)
{
	bool xtal;

	xtal = IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL) |
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING) |
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING);

	if (xtal) {
		xtal_check(clk_on, clk_type);
	} else if (IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC)) {
		rc_check(clk_on, clk_type);
	} else {
		synth_check(clk_on, clk_type);
	}
}

ZTEST(nrf_lf_clock_start, test_wait_in_thread)
{
	nrf_clock_lfclk_t t;
	bool o;

	if (!(IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) &&
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL))) {
		return;
	}

	z_nrf_clock_control_lf_on(CLOCK_CONTROL_NRF_LF_START_AVAILABLE);
	o = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &t);
	zassert_false((t == NRF_CLOCK_LFCLK_XTAL) && o);
	k_busy_wait(35);
	zassert_true(k_cycle_get_32() > 0);

	z_nrf_clock_control_lf_on(CLOCK_CONTROL_NRF_LF_START_STABLE);
	o = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &t);
	zassert_true((t == NRF_CLOCK_LFCLK_XTAL) && o);
}

void *test_init(void)
{
	TC_PRINT("CLOCK_CONTROL_NRF_K32SRC=%s\n",
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC)    ? "RC" :
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH) ? "SYNTH" :
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL)  ? "XTAL"
								  : "???");
	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
		TC_PRINT("SYSTEM_CLOCK_NO_WAIT=y\n");
	}
	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY)) {
		TC_PRINT("SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY=y\n");
	}
	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_STABILITY)) {
		TC_PRINT("SYSTEM_CLOCK_WAIT_FOR_STABILITY=y\n");
	}
	return NULL;
}
ZTEST_SUITE(nrf_lf_clock_start, NULL, test_init, NULL, NULL, NULL);

/* This test needs to read the LF clock state soon after the system clock is
 * started (to check if the starting routine waits for the LF clock or not),
 * so do it at the beginning of the POST_KERNEL stage (the system clock is
 * started in PRE_KERNEL_2). Reading of the clock state in the ZTEST setup
 * function turns out to be too late.
 */
static int get_lfclk_state(void)
{

	/* Do clock state read as early as possible. When RC is already running
	 * and XTAL has been started then LFSRCSTAT register content might be
	 * not valid, in that case read system clock to check if it has
	 * progressed.
	 */
	clk_on = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &clk_type);
	k_busy_wait(100);
	rtc_cnt = k_cycle_get_32();

	return 0;
}
SYS_INIT(get_lfclk_state, POST_KERNEL, 0);
