riscv32: rename to riscv
With the upcoming riscv64 support, it is best to use "riscv" as the subdirectory name and common symbols as riscv32 and riscv64 support code is almost identical. Then later decide whether 32-bit or 64-bit compilation is wanted. Redirects for the web documentation are also included. Then zephyrbot complained about this: " New files added that are not covered in CODEOWNERS: dts/riscv/microsemi-miv.dtsi dts/riscv/riscv32-fe310.dtsi Please add one or more entries in the CODEOWNERS file to cover those files " So I assigned them to those who created them. Feel free to readjust as necessary. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
48b4ad4b33
commit
1f4b5ddd0f
159 changed files with 125 additions and 118 deletions
222
soc/riscv/openisa_rv32m1/soc.c
Normal file
222
soc/riscv/openisa_rv32m1/soc.c
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* 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);
|
Loading…
Add table
Add a link
Reference in a new issue