/*
 * Copyright (c) 2018 Foundries.io
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>

#include <zephyr/device.h>
#include <zephyr/init.h>
#include <fsl_clock.h>
#include <zephyr/sys/util.h>

#if defined(CONFIG_MULTI_LEVEL_INTERRUPTS)
#include <errno.h>
#include <zephyr/irq_nextlevel.h>
#endif

#include <soc.h>

#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(soc);

#define SCG_LPFLL_DISABLE 0U

static const struct device *dev_intmux;

/*
 * Run-mode configuration for the fast internal reference clock (FIRC).
 */
static const scg_firc_config_t rv32m1_firc_config = {
	.enableMode = kSCG_FircEnable,
	.div1 = kSCG_AsyncClkDivBy1,
	.div2 = kSCG_AsyncClkDivBy1,
	.div3 = kSCG_AsyncClkDivBy1,
	.range = kSCG_FircRange48M,
	.trimConfig = NULL,
};

/*
 * FIRC-based system clock configuration.
 */
static const scg_sys_clk_config_t rv32m1_sys_clk_config_firc = {
	.divSlow = kSCG_SysClkDivBy2,
	.divBus = kSCG_SysClkDivBy1,
	.divExt = kSCG_SysClkDivBy1,
	.divCore = kSCG_SysClkDivBy1,
	.src = kSCG_SysClkSrcFirc,
};

/*
 * LPFLL configuration.
 */
static const scg_lpfll_config_t rv32m1_lpfll_cfg = {
	.enableMode = SCG_LPFLL_DISABLE,
	.div1 = kSCG_AsyncClkDivBy1,
	.div2 = kSCG_AsyncClkDisable,
	.div3 = kSCG_AsyncClkDisable,
	.range = kSCG_LpFllRange48M,
	.trimConfig = NULL,
};

void sys_arch_reboot(int type)
{
	ARG_UNUSED(type);

	EVENT_UNIT->SLPCTRL |= EVENT_SLPCTRL_SYSRSTREQST_MASK;
}

void arch_irq_enable(unsigned int irq)
{
	if (IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS)) {
		unsigned int level = rv32m1_irq_level(irq);

		if (level == 1U) {
			EVENT_UNIT->INTPTEN |= BIT(rv32m1_level1_irq(irq));
			/* Ensures write has finished: */
			(void)(EVENT_UNIT->INTPTEN);
		} else {
			irq_enable_next_level(dev_intmux, irq);
		}
	} else {
		EVENT_UNIT->INTPTEN |= BIT(rv32m1_level1_irq(irq));
		(void)(EVENT_UNIT->INTPTEN);
	}
}

void arch_irq_disable(unsigned int irq)
{
	if (IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS)) {
		unsigned int level = rv32m1_irq_level(irq);

		if (level == 1U) {
			EVENT_UNIT->INTPTEN &= ~BIT(rv32m1_level1_irq(irq));
			/* Ensures write has finished: */
			(void)(EVENT_UNIT->INTPTEN);
		} else {
			irq_disable_next_level(dev_intmux, irq);
		}
	} else {
		EVENT_UNIT->INTPTEN &= ~BIT(rv32m1_level1_irq(irq));
		(void)(EVENT_UNIT->INTPTEN);
	}
}

int arch_irq_is_enabled(unsigned int irq)
{
	if (IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS)) {
		unsigned int level = rv32m1_irq_level(irq);

		if (level == 1U) {
			return (EVENT_UNIT->INTPTEN &
				BIT(rv32m1_level1_irq(irq))) != 0;
		} else {
			uint32_t channel, line, ier;

			/*
			 * Here we break the abstraction and look
			 * directly at the INTMUX registers. We can't
			 * use the irq_nextlevel.h API, as that only
			 * tells us whether some IRQ at the next level
			 * is enabled or not.
			 */
			channel = rv32m1_intmux_channel(irq);
			line = rv32m1_intmux_line(irq);
			ier = INTMUX->CHANNEL[channel].CHn_IER_31_0 & BIT(line);

			return ier != 0U;
		}
	} else {
		return (EVENT_UNIT->INTPTEN & BIT(rv32m1_level1_irq(irq))) != 0;
	}
}

/*
 * SoC-level interrupt initialization. Clear any pending interrupts or
 * events, and find the INTMUX device if necessary.
 *
 * This gets called as almost the first thing z_cstart() does, so it
 * will happen before any calls to the _arch_irq_xxx() routines above.
 */
void soc_interrupt_init(void)
{
	EVENT_UNIT->INTPTPENDCLEAR = 0xFFFFFFFF;
	(void)(EVENT_UNIT->INTPTPENDCLEAR); /* Ensures write has finished. */
	EVENT_UNIT->EVTPENDCLEAR   = 0xFFFFFFFF;
	(void)(EVENT_UNIT->EVTPENDCLEAR); /* Ensures write has finished. */

	if (IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS)) {
		dev_intmux = DEVICE_DT_GET(DT_INST(0, openisa_rv32m1_intmux));
	}
}

/**
 * @brief Switch system clock configuration in run mode.
 *
 * Blocks until the updated configuration takes effect.
 *
 * @param cfg New system clock configuration
 */
static void rv32m1_switch_sys_clk(const scg_sys_clk_config_t *cfg)
{
	scg_sys_clk_config_t cur_cfg;

	CLOCK_SetRunModeSysClkConfig(cfg);
	do {
		CLOCK_GetCurSysClkConfig(&cur_cfg);
	} while (cur_cfg.src != cfg->src);
}

/**
 * @brief Initializes SIRC and switches system clock source to SIRC.
 */
static void rv32m1_switch_to_sirc(void)
{
	const scg_sirc_config_t sirc_config = {
		.enableMode = kSCG_SircEnable,
		.div1 = kSCG_AsyncClkDisable,
		.div2 = kSCG_AsyncClkDivBy2,
		.range = kSCG_SircRangeHigh,
	};
	const scg_sys_clk_config_t sys_clk_config_sirc = {
		.divSlow = kSCG_SysClkDivBy4,
		.divCore = kSCG_SysClkDivBy1,
		.src = kSCG_SysClkSrcSirc,
	};

	CLOCK_InitSirc(&sirc_config);
	rv32m1_switch_sys_clk(&sys_clk_config_sirc);
}

/**
 * @brief Setup peripheral clocks
 *
 * Setup the peripheral clock sources.
 */
static void rv32m1_setup_peripheral_clocks(void)
{
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(tpm0))
	CLOCK_SetIpSrc(kCLOCK_Tpm0, kCLOCK_IpSrcFircAsync);
#endif
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(tpm1))
	CLOCK_SetIpSrc(kCLOCK_Tpm1, kCLOCK_IpSrcFircAsync);
#endif
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(tpm2))
	CLOCK_SetIpSrc(kCLOCK_Tpm2, kCLOCK_IpSrcFircAsync);
#endif
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(tpm3))
	CLOCK_SetIpSrc(kCLOCK_Tpm3, kCLOCK_IpSrcFircAsync);
#endif
}

/**
 * @brief Perform basic hardware initialization
 *
 * Initializes the base clocks and LPFLL using helpers provided by the HAL.
 *
 * @return 0
 */
void soc_early_init_hook(void)
{
	unsigned int key;


	key = irq_lock();

	/* Switch to SIRC so we can initialize the FIRC. */
	rv32m1_switch_to_sirc();

	/* Now that we're running off of SIRC, set up and switch to FIRC. */
	CLOCK_InitFirc(&rv32m1_firc_config);
	rv32m1_switch_sys_clk(&rv32m1_sys_clk_config_firc);

	/* Initialize LPFLL */
	CLOCK_InitLpFll(&rv32m1_lpfll_cfg);

	/* Initialize peripheral clocks */
	rv32m1_setup_peripheral_clocks();

	irq_unlock(key);
}
