/*
 * 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 <misc/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 _arch_irq_enable(unsigned int irq)
{
	if (IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS)) {
		unsigned int level = rv32m1_irq_level(irq);

		if (level == 1) {
			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 == 1) {
			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 == 1) {
			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 != 0;
		}
	} 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 _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);
