/*
 * Copyright (c) 2022 Renesas Electronics Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <assert.h>
#include <soc.h>
#include <zephyr/sys/onoff.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/smartbond_clock_control.h>
#include <zephyr/logging/log.h>
#include <da1469x_clock.h>

LOG_MODULE_REGISTER(clock_control, CONFIG_CLOCK_CONTROL_LOG_LEVEL);

#define DT_DRV_COMPAT smartbond_clock

struct lpc_clock_state {
	uint8_t rcx_started : 1;
	uint8_t rcx_ready : 1;
	uint8_t rc32k_started : 1;
	uint8_t rc32k_ready : 1;
	uint8_t xtal32k_started : 1;
	uint8_t xtal32k_ready : 1;
	uint32_t rcx_freq;
	uint32_t rc32k_freq;
} lpc_clock_state = {
	.rcx_freq = DT_PROP(DT_NODELABEL(rcx), clock_frequency),
	.rc32k_freq = DT_PROP(DT_NODELABEL(rc32k), clock_frequency),
};

#define CALIBRATION_INTERVAL (DT_NODE_HAS_STATUS(DT_NODELABEL(rcx), okay) ?	\
			DT_PROP(DT_NODELABEL(rcx), calibration_interval) :	\
			DT_PROP(DT_NODELABEL(rc32k), calibration_interval))

static void calibration_work_cb(struct k_work *work);
static void xtal32k_settle_work_cb(struct k_work *work);

static K_WORK_DELAYABLE_DEFINE(calibration_work, calibration_work_cb);
static K_WORK_DELAYABLE_DEFINE(xtal32k_settle_work, xtal32k_settle_work_cb);

static void calibration_work_cb(struct k_work *work)
{
	if (lpc_clock_state.rcx_started) {
		da1469x_clock_lp_rcx_calibrate();
		lpc_clock_state.rcx_ready = true;
		lpc_clock_state.rcx_freq = da1469x_clock_lp_rcx_freq_get();
		k_work_schedule(&calibration_work,
				K_MSEC(1000 * CALIBRATION_INTERVAL));
		LOG_DBG("RCX calibration done, RCX freq: %d",
			(int)lpc_clock_state.rcx_freq);
	} else if (lpc_clock_state.rc32k_started) {
		da1469x_clock_lp_rc32k_calibrate();
		lpc_clock_state.rc32k_ready = true;
		lpc_clock_state.rc32k_freq = da1469x_clock_lp_rc32k_freq_get();
		k_work_schedule(&calibration_work,
				K_MSEC(1000 * CALIBRATION_INTERVAL));
		LOG_DBG("RC32K calibration done, RC32K freq: %d",
			(int)lpc_clock_state.rc32k_freq);
	}
}

static void xtal32k_settle_work_cb(struct k_work *work)
{
	if (lpc_clock_state.xtal32k_started && !lpc_clock_state.xtal32k_ready) {
		LOG_DBG("XTAL32K settled.");
		lpc_clock_state.xtal32k_ready = true;
	}
}

static void smartbond_start_rc32k(void)
{
	if ((CRG_TOP->CLK_RC32K_REG & CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk) == 0) {
		CRG_TOP->CLK_RC32K_REG |= CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk;
		lpc_clock_state.rc32k_started = true;
	}
	if (!lpc_clock_state.rc32k_ready && (CALIBRATION_INTERVAL > 0)) {
		if (!k_work_is_pending(&calibration_work.work)) {
			k_work_schedule(&calibration_work,
					K_MSEC(1000 * CALIBRATION_INTERVAL));
		}
	}
}

static void smartbond_start_rcx(void)
{
	if (!lpc_clock_state.rcx_started) {
		lpc_clock_state.rcx_ready = false;
		da1469x_clock_lp_rcx_enable();
		lpc_clock_state.rcx_started = true;
	}
	if (!lpc_clock_state.rcx_ready && (CALIBRATION_INTERVAL > 0)) {
		if (!k_work_is_pending(&calibration_work.work)) {
			k_work_schedule(&calibration_work,
					K_MSEC(1000 * CALIBRATION_INTERVAL));
		}
	}
}

static void smartbond_start_xtal32k(void)
{
	if (!lpc_clock_state.xtal32k_started) {
		lpc_clock_state.xtal32k_ready = false;
		da1469x_clock_lp_xtal32k_enable();
		lpc_clock_state.xtal32k_started = true;
		k_work_schedule(&xtal32k_settle_work,
				K_MSEC(DT_PROP(DT_NODELABEL(xtal32k),
					       settle_time)));
	}
}

static inline int smartbond_clock_control_on(const struct device *dev,
					     clock_control_subsys_t sub_system)
{
	enum smartbond_clock clk = (enum smartbond_clock)(sub_system);

	ARG_UNUSED(dev);

	switch (clk) {
	case SMARTBOND_CLK_RC32K:
		smartbond_start_rc32k();
		break;
	case SMARTBOND_CLK_RCX:
		smartbond_start_rcx();
		break;
	case SMARTBOND_CLK_XTAL32K:
		smartbond_start_xtal32k();
		break;
	case SMARTBOND_CLK_RC32M:
		CRG_TOP->CLK_RC32M_REG |= CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Msk;
		break;
	case SMARTBOND_CLK_XTAL32M:
		da1469x_clock_sys_xtal32m_init();
		da1469x_clock_sys_xtal32m_enable();
		break;
	case SMARTBOND_CLK_PLL96M:
		if ((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk) == 0) {
			if ((CRG_TOP->CLK_CTRL_REG &
			     CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Msk) == 0) {
				da1469x_clock_sys_xtal32m_init();
				da1469x_clock_sys_xtal32m_enable();
				da1469x_clock_sys_xtal32m_wait_to_settle();
			}
			da1469x_clock_sys_pll_enable();
		}
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static inline int smartbond_clock_control_off(const struct device *dev,
					      clock_control_subsys_t sub_system)
{
	enum smartbond_clock clk = (enum smartbond_clock)(sub_system);

	ARG_UNUSED(dev);

	switch (clk) {
	case SMARTBOND_CLK_RC32K:
		if (((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >>
			   CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos) != 0) {
			CRG_TOP->CLK_RC32K_REG &= ~CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk;
			lpc_clock_state.rc32k_ready = false;
			lpc_clock_state.rc32k_started = false;
		}
		break;
	case SMARTBOND_CLK_RCX:
		if (((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >>
			   CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos) != 1) {
			CRG_TOP->CLK_RCX_REG &= ~CRG_TOP_CLK_RCX_REG_RCX_ENABLE_Msk;
			lpc_clock_state.rcx_ready = false;
			lpc_clock_state.rcx_started = false;
		}
		break;
	case SMARTBOND_CLK_XTAL32K:
		if (((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >>
			CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos) > 1) {
			CRG_TOP->CLK_XTAL32K_REG &= ~CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Msk;
			lpc_clock_state.xtal32k_ready = false;
			lpc_clock_state.xtal32k_started = false;
		}
		break;
	case SMARTBOND_CLK_RC32M:
		/* Disable rc32m only if not used as system clock */
		if ((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk) == 0) {
			da1469x_clock_sys_rc32m_disable();
		}
		break;
	case SMARTBOND_CLK_XTAL32M:
		da1469x_clock_sys_xtal32m_init();
		da1469x_clock_sys_xtal32m_enable();
		break;
	case SMARTBOND_CLK_PLL96M:
		da1469x_clock_sys_pll_disable();
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static enum smartbond_clock smartbond_source_clock(enum smartbond_clock clk)
{
	static const enum smartbond_clock lp_clk_src[] = {
		SMARTBOND_CLK_RC32K,
		SMARTBOND_CLK_RCX,
		SMARTBOND_CLK_XTAL32K,
		SMARTBOND_CLK_XTAL32K,
	};
	static const enum smartbond_clock sys_clk_src[] = {
		SMARTBOND_CLK_XTAL32M,
		SMARTBOND_CLK_RC32M,
		SMARTBOND_CLK_LP_CLK,
		SMARTBOND_CLK_PLL96M,
	};

	if (clk == SMARTBOND_CLK_SYS_CLK) {
		clk = sys_clk_src[CRG_TOP->CLK_CTRL_REG &
				  CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk];
	}
	/* System clock can be low power clock, so next check is not in else */
	if (clk == SMARTBOND_CLK_LP_CLK) {
		clk = lp_clk_src[(CRG_TOP->CLK_CTRL_REG &
				  CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >>
				 CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos];
	}
	return clk;
}

static int smartbond_clock_get_rate(enum smartbond_clock clk, uint32_t *rate)
{
	clk = smartbond_source_clock(clk);
	switch (clk) {
	case SMARTBOND_CLK_RC32K:
		*rate = lpc_clock_state.rc32k_freq;
		break;
	case SMARTBOND_CLK_RCX:
		*rate = lpc_clock_state.rcx_freq;
		break;
	case SMARTBOND_CLK_XTAL32K:
		*rate = DT_PROP(DT_NODELABEL(xtal32k), clock_frequency);
		break;
	case SMARTBOND_CLK_RC32M:
		*rate = DT_PROP(DT_NODELABEL(rc32m), clock_frequency);
		break;
	case SMARTBOND_CLK_XTAL32M:
		*rate = DT_PROP(DT_NODELABEL(xtal32m), clock_frequency);
		break;
	case SMARTBOND_CLK_PLL96M:
		*rate = DT_PROP(DT_NODELABEL(pll), clock_frequency);
		break;
	default:
		return -ENOTSUP;
	}
	return 0;
}

static int smartbond_clock_control_get_rate(const struct device *dev,
					    clock_control_subsys_t sub_system,
					    uint32_t *rate)
{
	ARG_UNUSED(dev);

	return smartbond_clock_get_rate((enum smartbond_clock)(sub_system), rate);
}

static enum smartbond_clock smartbond_dt_ord_to_clock(uint32_t dt_ord)
{
	switch (dt_ord) {
	case DT_DEP_ORD(DT_NODELABEL(rc32k)):
		return SMARTBOND_CLK_RC32K;
	case DT_DEP_ORD(DT_NODELABEL(rcx)):
		return SMARTBOND_CLK_RCX;
	case DT_DEP_ORD(DT_NODELABEL(xtal32k)):
		return SMARTBOND_CLK_XTAL32K;
	case DT_DEP_ORD(DT_NODELABEL(rc32m)):
		return SMARTBOND_CLK_RC32M;
	case DT_DEP_ORD(DT_NODELABEL(xtal32m)):
		return SMARTBOND_CLK_XTAL32M;
	case DT_DEP_ORD(DT_NODELABEL(pll)):
		return SMARTBOND_CLK_PLL96M;
	default:
		return SMARTBOND_CLK_NONE;
	}
}

static void smartbond_clock_control_on_by_ord(const struct device *dev,
					      uint32_t clock_id)
{
	enum smartbond_clock clk = smartbond_dt_ord_to_clock(clock_id);

	smartbond_clock_control_on(dev, (clock_control_subsys_rate_t)clk);
}

static void smartbond_clock_control_off_by_ord(const struct device *dev,
					       uint32_t clock_id)
{
	enum smartbond_clock clk = smartbond_dt_ord_to_clock(clock_id);

	smartbond_clock_control_off(dev, (clock_control_subsys_rate_t)clk);
}

static void
qspi_set_read_pipe_delay(uint8_t delay)
{
	QSPIC->QSPIC_CTRLMODE_REG =
		(QSPIC->QSPIC_CTRLMODE_REG & ~QSPIC_QSPIC_CTRLMODE_REG_QSPIC_PCLK_MD_Msk) |
		(delay << QSPIC_QSPIC_CTRLMODE_REG_QSPIC_PCLK_MD_Pos) |
		QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RPIPE_EN_Msk;
}

static void
qspi_set_cs_delay(uint32_t sys_clock_freq, uint32_t read_delay_ns, uint32_t erase_delay_ns)
{
	sys_clock_freq /= 100000;
	uint32_t read_delay_cyc = ((read_delay_ns * sys_clock_freq) + 9999) / 10000;
	uint32_t erase_delay_cyc = ((erase_delay_ns * sys_clock_freq) + 9999) / 10000;

	QSPIC->QSPIC_BURSTCMDB_REG =
		(QSPIC->QSPIC_BURSTCMDB_REG & ~QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Msk) |
		read_delay_cyc << QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Pos;
	QSPIC->QSPIC_ERASECMDB_REG =
		(QSPIC->QSPIC_ERASECMDB_REG & ~QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_CS_HI_Msk) |
		(erase_delay_cyc << QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_CS_HI_Pos);
}

int z_smartbond_select_lp_clk(enum smartbond_clock lp_clk)
{
	int rc = 0;
	uint32_t clk_sel = 0;
	uint32_t clk_sel_msk = CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk;

	switch (lp_clk) {
	case SMARTBOND_CLK_RC32K:
		clk_sel = 0;
		break;
	case SMARTBOND_CLK_RCX:
		clk_sel = 1 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos;
		break;
	case SMARTBOND_CLK_XTAL32K:
		clk_sel = 2 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos;
		break;
	default:
		rc = -EINVAL;
	}

	if (rc == 0) {
		CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & ~clk_sel_msk) | clk_sel;
	}

	return rc;
}

int z_smartbond_select_sys_clk(enum smartbond_clock sys_clk)
{
	uint32_t sys_clock_freq;
	uint32_t clk_sel;
	uint32_t clk_sel_msk = CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk;
	int res;

	res = smartbond_clock_get_rate(sys_clk, &sys_clock_freq);
	if (res != 0) {
		return -EINVAL;
	}

	/* When PLL is selected as system clock qspi read pipe delay must be set to 7 */
	if (sys_clock_freq > 32000000) {
		qspi_set_read_pipe_delay(7);
		qspi_set_cs_delay(SystemCoreClock,
				  DT_PROP(DT_NODELABEL(flash_controller),
					  read_cs_idle_delay),
				  DT_PROP(DT_NODELABEL(flash_controller),
					  erase_cs_idle_delay));
	}

	if (sys_clk == SMARTBOND_CLK_RC32M) {
		clk_sel = 1 << CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Pos;
		CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & ~clk_sel_msk) | clk_sel;
		SystemCoreClock = sys_clock_freq;
	} else if (sys_clk == SMARTBOND_CLK_PLL96M) {
		da1469x_clock_pll_wait_to_lock();
		da1469x_clock_sys_pll_switch();
	} else if (sys_clk == SMARTBOND_CLK_XTAL32M) {
		da1469x_clock_sys_xtal32m_switch_safe();
	}

	/* When switching back from PLL to 32MHz read pipe delay may be set to 2 */
	if (SystemCoreClock <= 32000000) {
		qspi_set_read_pipe_delay(2);
		qspi_set_cs_delay(SystemCoreClock,
				  DT_PROP(DT_NODELABEL(flash_controller),
					  read_cs_idle_delay),
				  DT_PROP(DT_NODELABEL(flash_controller),
					  erase_cs_idle_delay));
	}

	return 0;
}

/**
 * @brief Initialize clocks for the Smartbond
 *
 * This routine is called to enable and configure the clocks and PLL
 * of the soc on the board.
 *
 * @param dev clocks device struct
 *
 * @return 0
 */
int smartbond_clocks_init(const struct device *dev)
{
	uint32_t clk_id;
	enum smartbond_clock lp_clk;
	enum smartbond_clock sys_clk;

	ARG_UNUSED(dev);

#define ENABLE_OSC(clock) smartbond_clock_control_on_by_ord(dev, DT_DEP_ORD(clock))
#define DISABLE_OSC(clock) if (DT_NODE_HAS_STATUS(clock, disabled)) { \
		smartbond_clock_control_off_by_ord(dev, DT_DEP_ORD(clock)); \
	}

	/* Enable all oscillators with status "okay" */
	DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(crg, osc), ENABLE_OSC, (;));

	/* Make sure that selected sysclock is enabled */
	BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_PROP(DT_NODELABEL(sys_clk), clock_src), okay),
		     "Clock selected as system clock no enabled in DT");
	BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_PROP(DT_NODELABEL(lp_clk), clock_src), okay),
		     "Clock selected as LP clock no enabled in DT");
	BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(pll), disabled) ||
		     DT_NODE_HAS_STATUS(DT_NODELABEL(xtal32m), okay),
		     "PLL enabled in DT but XTAL32M is disabled");

	clk_id = DT_DEP_ORD(DT_PROP(DT_NODELABEL(lp_clk), clock_src));
	lp_clk = smartbond_dt_ord_to_clock(clk_id);
	z_smartbond_select_lp_clk(lp_clk);

	clk_id = DT_DEP_ORD(DT_PROP(DT_NODELABEL(sys_clk), clock_src));
	sys_clk = smartbond_dt_ord_to_clock(clk_id);
	smartbond_clock_control_on(dev,
				   (clock_control_subsys_rate_t)smartbond_source_clock(sys_clk));
	z_smartbond_select_sys_clk(sys_clk);

	/* Disable unwanted oscillators */
	DT_FOREACH_CHILD_SEP(DT_PATH(crg, osc), DISABLE_OSC, (;));

	return 0;
}

static struct clock_control_driver_api smartbond_clock_control_api = {
	.on = smartbond_clock_control_on,
	.off = smartbond_clock_control_off,
	.get_rate = smartbond_clock_control_get_rate,
};

DEVICE_DT_DEFINE(DT_NODELABEL(osc),
		 &smartbond_clocks_init,
		 NULL,
		 NULL, NULL,
		 PRE_KERNEL_1,
		 CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
		 &smartbond_clock_control_api);
