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

#include <kernel.h>

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

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

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

#define SCG_LPFLL_DISABLE 0U

static 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 z_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 z_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 z_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 {
			u32_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_get_binding(DT_OPENISA_RV32M1_INTMUX_INTMUX_LABEL);
		__ASSERT(dev_intmux, "no INTMUX device found");
	}
}

/**
 * @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 Perform basic hardware initialization
 *
 * Initializes the base clocks and LPFLL using helpers provided by the HAL.
 *
 * @return 0
 */
static int soc_rv32m1_init(struct device *arg)
{
	unsigned int key;

	ARG_UNUSED(arg);

	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);

	irq_unlock(key);

	return 0;
}

SYS_INIT(soc_rv32m1_init, PRE_KERNEL_1, 0);
