driver: interrupt_controller: intc_clic: rework to standard CLIC driver
Rework intc_clic to standard CLIC driver with Nuclei ECLIC extention. Signed-off-by: Jimmy Zheng <jimmyzhe@andestech.com>
This commit is contained in:
parent
21f0ee0383
commit
9349d54074
7 changed files with 166 additions and 75 deletions
|
@ -31,8 +31,8 @@ zephyr_library_sources_ifdef(CONFIG_INTC_ESP32 intc_esp32.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_SWERV_PIC intc_swerv_pic.c)
|
zephyr_library_sources_ifdef(CONFIG_SWERV_PIC intc_swerv_pic.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex.c)
|
zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_VIM intc_vim.c)
|
zephyr_library_sources_ifdef(CONFIG_VIM intc_vim.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_NUCLEI_ECLIC intc_clic.c)
|
zephyr_library_sources_ifdef(CONFIG_CLIC intc_clic.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_NUCLEI_ECLIC intc_clic.S)
|
zephyr_library_sources_ifdef(CONFIG_CLIC intc_clic.S)
|
||||||
zephyr_library_sources_ifdef(CONFIG_NRFX_CLIC intc_nrfx_clic.c)
|
zephyr_library_sources_ifdef(CONFIG_NRFX_CLIC intc_nrfx_clic.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_NRFX_CLIC intc_nrfx_clic.S)
|
zephyr_library_sources_ifdef(CONFIG_NRFX_CLIC intc_nrfx_clic.S)
|
||||||
zephyr_library_sources_ifdef(CONFIG_NXP_S32_EIRQ intc_eirq_nxp_s32.c)
|
zephyr_library_sources_ifdef(CONFIG_NXP_S32_EIRQ intc_eirq_nxp_s32.c)
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
# Copyright (c) 2021 Tokita, Hiroshi <tokita.hiroshi@gmail.com>
|
# Copyright (c) 2021 Tokita, Hiroshi <tokita.hiroshi@gmail.com>
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config CLIC
|
||||||
|
bool "RISC-V Core Local Interrupt Controller (CLIC)"
|
||||||
|
default y
|
||||||
|
depends on DT_HAS_NUCLEI_ECLIC_ENABLED || DT_HAS_RISCV_CLIC_ENABLED
|
||||||
|
select RISCV_SOC_HAS_CUSTOM_IRQ_HANDLING
|
||||||
|
help
|
||||||
|
Core Local Interrupt Controller provide low-latency, vectored,
|
||||||
|
preemptive interrupts for RISC-V systems.
|
||||||
|
|
||||||
config NUCLEI_ECLIC
|
config NUCLEI_ECLIC
|
||||||
bool "Enhanced Core Local Interrupt Controller (ECLIC)"
|
bool "Enhanced Core Local Interrupt Controller (ECLIC)"
|
||||||
default y
|
default y
|
||||||
depends on DT_HAS_NUCLEI_ECLIC_ENABLED
|
depends on DT_HAS_NUCLEI_ECLIC_ENABLED
|
||||||
select RISCV_SOC_HAS_CUSTOM_IRQ_HANDLING
|
select CLIC
|
||||||
select CLIC_SMCLICSHV_EXT if RISCV_VECTORED_MODE
|
select CLIC_SMCLICSHV_EXT if RISCV_VECTORED_MODE
|
||||||
help
|
help
|
||||||
Interrupt controller for Nuclei SoC core.
|
Interrupt controller for Nuclei SoC core.
|
||||||
|
@ -18,6 +27,8 @@ config NRFX_CLIC
|
||||||
help
|
help
|
||||||
Interrupt controller for Nordic VPR cores.
|
Interrupt controller for Nordic VPR cores.
|
||||||
|
|
||||||
|
if CLIC
|
||||||
|
|
||||||
config CLIC_SMCLICSHV_EXT
|
config CLIC_SMCLICSHV_EXT
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
|
@ -25,8 +36,6 @@ config CLIC_SMCLICSHV_EXT
|
||||||
to select the behavior for each interrupt. The CLIC driver needs to
|
to select the behavior for each interrupt. The CLIC driver needs to
|
||||||
implement the riscv_clic_irq_vector_set() function.
|
implement the riscv_clic_irq_vector_set() function.
|
||||||
|
|
||||||
if NUCLEI_ECLIC
|
|
||||||
|
|
||||||
config LEGACY_CLIC
|
config LEGACY_CLIC
|
||||||
bool "Use the legacy clic specification"
|
bool "Use the legacy clic specification"
|
||||||
depends on RISCV_HAS_CLIC
|
depends on RISCV_HAS_CLIC
|
||||||
|
@ -34,4 +43,4 @@ config LEGACY_CLIC
|
||||||
Enables legacy clic, where smclicshv extension is not supported and
|
Enables legacy clic, where smclicshv extension is not supported and
|
||||||
hardware vectoring is set via mode bits of mtvec.
|
hardware vectoring is set via mode bits of mtvec.
|
||||||
|
|
||||||
endif # NUCLEI_ECLIC
|
endif # CLIC
|
||||||
|
|
|
@ -5,15 +5,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Assembler-hooks specific to Nuclei's Extended Core Interrupt Controller
|
* @brief Assembler-hooks specific to RISC-V Core Local Interrupt Controller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <zephyr/arch/cpu.h>
|
#include <zephyr/arch/cpu.h>
|
||||||
|
#include "intc_clic.h"
|
||||||
|
|
||||||
|
|
||||||
GTEXT(__soc_handle_irq)
|
GTEXT(__soc_handle_irq)
|
||||||
/*
|
/*
|
||||||
* In an ECLIC, pending interrupts don't have to be cleared by hand.
|
* In an CLIC, pending interrupts don't have to be cleared by hand.
|
||||||
* In vectored mode, interrupts are cleared automatically.
|
* In vectored mode, interrupts are cleared automatically.
|
||||||
* In non-vectored mode, interrupts are cleared when writing the mnxti register (done in
|
* In non-vectored mode, interrupts are cleared when writing the mnxti register (done in
|
||||||
* __soc_handle_all_irqs).
|
* __soc_handle_all_irqs).
|
||||||
|
@ -31,7 +32,7 @@ GTEXT(sys_trace_isr_exit)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function services and clears all pending interrupts for an ECLIC in non-vectored mode.
|
* This function services and clears all pending interrupts for an CLIC in non-vectored mode.
|
||||||
*/
|
*/
|
||||||
SECTION_FUNC(exception.other, __soc_handle_all_irqs)
|
SECTION_FUNC(exception.other, __soc_handle_all_irqs)
|
||||||
addi sp, sp, -16
|
addi sp, sp, -16
|
||||||
|
@ -39,7 +40,7 @@ SECTION_FUNC(exception.other, __soc_handle_all_irqs)
|
||||||
|
|
||||||
/* Read and clear mnxti to get highest current interrupt and enable interrupts. Will return
|
/* Read and clear mnxti to get highest current interrupt and enable interrupts. Will return
|
||||||
* original interrupt if no others appear. */
|
* original interrupt if no others appear. */
|
||||||
csrrci a0, 0x345, MSTATUS_IEN
|
csrrci a0, CSR_MNXTI, MSTATUS_IEN
|
||||||
beqz a0, irq_done /* Check if original interrupt vanished. */
|
beqz a0, irq_done /* Check if original interrupt vanished. */
|
||||||
|
|
||||||
irq_loop:
|
irq_loop:
|
||||||
|
@ -50,7 +51,7 @@ irq_loop:
|
||||||
|
|
||||||
/* Call corresponding registered function in _sw_isr_table. a0 is offset in pointer with
|
/* Call corresponding registered function in _sw_isr_table. a0 is offset in pointer with
|
||||||
* the mtvt, sw irq table is 2-pointer wide -> shift by one. */
|
* the mtvt, sw irq table is 2-pointer wide -> shift by one. */
|
||||||
csrr t0, 0x307 /* mtvt */
|
csrr t0, CSR_MTVT
|
||||||
sub a0, a0, t0
|
sub a0, a0, t0
|
||||||
la t0, _sw_isr_table
|
la t0, _sw_isr_table
|
||||||
slli a0, a0, (1)
|
slli a0, a0, (1)
|
||||||
|
@ -70,7 +71,7 @@ irq_loop:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Read and clear mnxti to get highest current interrupt and enable interrupts. */
|
/* Read and clear mnxti to get highest current interrupt and enable interrupts. */
|
||||||
csrrci a0, 0x345, MSTATUS_IEN
|
csrrci a0, CSR_MNXTI, MSTATUS_IEN
|
||||||
bnez a0, irq_loop
|
bnez a0, irq_loop
|
||||||
|
|
||||||
irq_done:
|
irq_done:
|
||||||
|
|
|
@ -1,55 +1,47 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Tokita, Hiroshi <tokita.hiroshi@gmail.com>
|
* Copyright (c) 2021 Tokita, Hiroshi <tokita.hiroshi@gmail.com>
|
||||||
|
* Copyright (c) 2025 Andes Technology Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Driver for Nuclie's Extended Core Interrupt Controller
|
* @brief Driver for Core Local Interrupt Controller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/arch/cpu.h>
|
#include <zephyr/arch/riscv/csr.h>
|
||||||
#include <zephyr/sys/util.h>
|
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
|
|
||||||
#include <zephyr/sw_isr_table.h>
|
|
||||||
#include <zephyr/drivers/interrupt_controller/riscv_clic.h>
|
#include <zephyr/drivers/interrupt_controller/riscv_clic.h>
|
||||||
#include "intc_clic.h"
|
#include "intc_clic.h"
|
||||||
|
|
||||||
|
#if DT_HAS_COMPAT_STATUS_OKAY(riscv_clic)
|
||||||
|
#define DT_DRV_COMPAT riscv_clic
|
||||||
|
#elif DT_HAS_COMPAT_STATUS_OKAY(nuclei_eclic)
|
||||||
#define DT_DRV_COMPAT nuclei_eclic
|
#define DT_DRV_COMPAT nuclei_eclic
|
||||||
|
#else
|
||||||
|
#error "Unknown CLIC controller compatible for this configuration"
|
||||||
|
#endif
|
||||||
|
|
||||||
/** CLIC INTATTR: TRIG Mask */
|
struct clic_data {
|
||||||
#define CLIC_INTATTR_TRIG_Msk 0x3U
|
uint8_t nlbits;
|
||||||
|
uint8_t intctlbits;
|
||||||
|
};
|
||||||
|
|
||||||
#define ECLIC_CFG (*((volatile union CLICCFG *)(DT_REG_ADDR_BY_IDX(DT_NODELABEL(eclic), 0))))
|
struct clic_config {
|
||||||
#define ECLIC_INFO (*((volatile union CLICINFO *)(DT_REG_ADDR_BY_IDX(DT_NODELABEL(eclic), 1))))
|
mem_addr_t base;
|
||||||
#define ECLIC_MTH (*((volatile union CLICMTH *)(DT_REG_ADDR_BY_IDX(DT_NODELABEL(eclic), 2))))
|
};
|
||||||
#define ECLIC_CTRL ((volatile struct CLICCTRL *)(DT_REG_ADDR_BY_IDX(DT_NODELABEL(eclic), 3)))
|
|
||||||
#define ECLIC_CTRL_SIZE (DT_REG_SIZE_BY_IDX(DT_NODELABEL(eclic), 3))
|
|
||||||
|
|
||||||
static uint8_t nlbits;
|
|
||||||
static uint8_t intctlbits;
|
|
||||||
static uint8_t max_prio;
|
|
||||||
static uint8_t max_level;
|
|
||||||
static uint8_t intctrl_mask;
|
|
||||||
|
|
||||||
static inline uint8_t leftalign8(uint8_t val, uint8_t shift)
|
|
||||||
{
|
|
||||||
return (val << (8U - shift));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint8_t mask8(uint8_t len)
|
|
||||||
{
|
|
||||||
return ((1 << len) - 1) & 0xFFFFU;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable interrupt
|
* @brief Enable interrupt
|
||||||
*/
|
*/
|
||||||
void riscv_clic_irq_enable(uint32_t irq)
|
void riscv_clic_irq_enable(uint32_t irq)
|
||||||
{
|
{
|
||||||
ECLIC_CTRL[irq].INTIE.b.IE = 1;
|
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||||
|
const struct clic_config *config = dev->config;
|
||||||
|
union CLICINTIE clicintie = {.b = {.IE = 0x1}};
|
||||||
|
|
||||||
|
sys_write8(clicintie.w, config->base + CLIC_INTIE(irq));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,7 +49,11 @@ void riscv_clic_irq_enable(uint32_t irq)
|
||||||
*/
|
*/
|
||||||
void riscv_clic_irq_disable(uint32_t irq)
|
void riscv_clic_irq_disable(uint32_t irq)
|
||||||
{
|
{
|
||||||
ECLIC_CTRL[irq].INTIE.b.IE = 0;
|
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||||
|
const struct clic_config *config = dev->config;
|
||||||
|
union CLICINTIE clicintie = {.b = {.IE = 0x0}};
|
||||||
|
|
||||||
|
sys_write8(clicintie.w, config->base + CLIC_INTIE(irq));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +61,11 @@ void riscv_clic_irq_disable(uint32_t irq)
|
||||||
*/
|
*/
|
||||||
int riscv_clic_irq_is_enabled(uint32_t irq)
|
int riscv_clic_irq_is_enabled(uint32_t irq)
|
||||||
{
|
{
|
||||||
return ECLIC_CTRL[irq].INTIE.b.IE;
|
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||||
|
const struct clic_config *config = dev->config;
|
||||||
|
union CLICINTIE clicintie = {.w = sys_read8(config->base + CLIC_INTIE(irq))};
|
||||||
|
|
||||||
|
return clicintie.b.IE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,18 +73,35 @@ int riscv_clic_irq_is_enabled(uint32_t irq)
|
||||||
*/
|
*/
|
||||||
void riscv_clic_irq_priority_set(uint32_t irq, uint32_t pri, uint32_t flags)
|
void riscv_clic_irq_priority_set(uint32_t irq, uint32_t pri, uint32_t flags)
|
||||||
{
|
{
|
||||||
const uint8_t prio = leftalign8(MIN(pri, max_prio), intctlbits);
|
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||||
const uint8_t level = leftalign8(max_level, nlbits);
|
const struct clic_config *config = dev->config;
|
||||||
const uint8_t intctrl = (prio | level) | (~intctrl_mask);
|
const struct clic_data *data = dev->data;
|
||||||
|
|
||||||
ECLIC_CTRL[irq].INTCTRL = intctrl;
|
/*
|
||||||
|
* Set the interrupt level and the interrupt priority.
|
||||||
|
* Examples of mcliccfg settings:
|
||||||
|
* CLICINTCTLBITS mnlbits clicintctl[i] interrupt levels
|
||||||
|
* 0 2 ........ 255
|
||||||
|
* 1 2 l....... 127,255
|
||||||
|
* 2 2 ll...... 63,127,191,255
|
||||||
|
* 3 3 lll..... 31,63,95,127,159,191,223,255
|
||||||
|
* 4 1 lppp.... 127,255
|
||||||
|
* "." bits are non-existent bits for level encoding, assumed to be 1
|
||||||
|
* "l" bits are available variable bits in level specification
|
||||||
|
* "p" bits are available variable bits in priority specification
|
||||||
|
*/
|
||||||
|
const uint8_t max_level = BIT_MASK(data->nlbits);
|
||||||
|
const uint8_t max_prio = BIT_MASK(data->intctlbits - data->nlbits);
|
||||||
|
uint8_t intctrl = (MIN(pri, max_prio) << (8U - data->intctlbits)) |
|
||||||
|
(MIN(pri, max_level) << (8U - data->nlbits)) |
|
||||||
|
BIT_MASK(8U - data->intctlbits);
|
||||||
|
|
||||||
union CLICINTATTR intattr = {.w = 0};
|
sys_write8(intctrl, config->base + CLIC_INTCTRL(irq));
|
||||||
|
|
||||||
/* Set non-vectoring as default. */
|
/* Set the IRQ operates in machine mode, non-vectoring and the trigger type. */
|
||||||
intattr.b.shv = 0;
|
union CLICINTATTR clicattr = {.b = {.mode = 0x3, .shv = 0x0, .trg = flags & BIT_MASK(3)}};
|
||||||
intattr.b.trg = (uint8_t)(flags & CLIC_INTATTR_TRIG_Msk);
|
|
||||||
ECLIC_CTRL[irq].INTATTR = intattr;
|
sys_write8(clicattr.w, config->base + CLIC_INTATTR(irq));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,11 +109,13 @@ void riscv_clic_irq_priority_set(uint32_t irq, uint32_t pri, uint32_t flags)
|
||||||
*/
|
*/
|
||||||
void riscv_clic_irq_vector_set(uint32_t irq)
|
void riscv_clic_irq_vector_set(uint32_t irq)
|
||||||
{
|
{
|
||||||
/* Set Selective Hardware Vectoring. */
|
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||||
union CLICINTATTR intattr = ECLIC_CTRL[irq].INTATTR;
|
const struct clic_config *config = dev->config;
|
||||||
|
union CLICINTATTR clicattr = {.w = sys_read8(config->base + CLIC_INTATTR(irq))};
|
||||||
|
|
||||||
intattr.b.shv = 1;
|
/* Set Selective Hardware Vectoring. */
|
||||||
ECLIC_CTRL[irq].INTATTR = intattr;
|
clicattr.b.shv = 1;
|
||||||
|
sys_write8(clicattr.w, config->base + CLIC_INTATTR(irq));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,26 +123,64 @@ void riscv_clic_irq_vector_set(uint32_t irq)
|
||||||
*/
|
*/
|
||||||
void riscv_clic_irq_set_pending(uint32_t irq)
|
void riscv_clic_irq_set_pending(uint32_t irq)
|
||||||
{
|
{
|
||||||
ECLIC_CTRL[irq].INTIP.b.IP = 1;
|
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||||
|
const struct clic_config *config = dev->config;
|
||||||
|
union CLICINTIP clicintip = {.b = {.IP = 0x1}};
|
||||||
|
|
||||||
|
sys_write8(clicintip.w, config->base + CLIC_INTIP(irq));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nuclei_eclic_init(const struct device *dev)
|
static int clic_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
ECLIC_MTH.w = 0;
|
const struct clic_config *config = dev->config;
|
||||||
ECLIC_CFG.w = 0;
|
struct clic_data *data = dev->data;
|
||||||
ECLIC_CFG.b.nlbits = 0;
|
|
||||||
for (int i = 0; i < ECLIC_CTRL_SIZE; i++) {
|
if (IS_ENABLED(CONFIG_NUCLEI_ECLIC)) {
|
||||||
ECLIC_CTRL[i] = (struct CLICCTRL) { 0 };
|
/* Configure the interrupt level threshold. */
|
||||||
|
union CLICMTH clicmth = {.b = {.mth = 0x0}};
|
||||||
|
|
||||||
|
sys_write32(clicmth.qw, config->base + CLIC_MTH);
|
||||||
|
|
||||||
|
/* Detect the number of bits for the clicintctl register. */
|
||||||
|
union CLICINFO clicinfo = {.qw = sys_read32(config->base + CLIC_INFO)};
|
||||||
|
|
||||||
|
data->intctlbits = clicinfo.b.intctlbits;
|
||||||
|
|
||||||
|
if (data->nlbits > data->intctlbits) {
|
||||||
|
data->nlbits = data->intctlbits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure the number of bits assigned to interrupt levels. */
|
||||||
|
union CLICCFG cliccfg = {.qw = sys_read32(config->base + CLIC_CFG)};
|
||||||
|
|
||||||
|
cliccfg.w.nlbits = data->nlbits;
|
||||||
|
sys_write32(cliccfg.qw, config->base + CLIC_CFG);
|
||||||
|
} else {
|
||||||
|
/* Configure the interrupt level threshold by CSR mintthresh. */
|
||||||
|
csr_write(CSR_MINTTHRESH, 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
nlbits = ECLIC_CFG.b.nlbits;
|
/* Reset all interrupt control register */
|
||||||
intctlbits = ECLIC_INFO.b.intctlbits;
|
for (int i = 0; i < CONFIG_NUM_IRQS; i++) {
|
||||||
max_prio = mask8(intctlbits - nlbits);
|
sys_write32(0, config->base + CLIC_CTRL(i));
|
||||||
max_level = mask8(nlbits);
|
}
|
||||||
intctrl_mask = leftalign8(mask8(intctlbits), intctlbits);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEVICE_DT_INST_DEFINE(0, nuclei_eclic_init, NULL, NULL, NULL,
|
#define CLIC_INTC_DATA_INIT(n) \
|
||||||
PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL);
|
static struct clic_data clic_data_##n = { \
|
||||||
|
.nlbits = 0, \
|
||||||
|
.intctlbits = 8, \
|
||||||
|
};
|
||||||
|
#define CLIC_INTC_CONFIG_INIT(n) \
|
||||||
|
const static struct clic_config clic_config_##n = { \
|
||||||
|
.base = DT_REG_ADDR(DT_DRV_INST(n)), \
|
||||||
|
};
|
||||||
|
#define CLIC_INTC_DEVICE_INIT(n) \
|
||||||
|
CLIC_INTC_DATA_INIT(n) \
|
||||||
|
CLIC_INTC_CONFIG_INIT(n) \
|
||||||
|
DEVICE_DT_INST_DEFINE(n, &clic_init, NULL, &clic_data_##n, &clic_config_##n, PRE_KERNEL_1, \
|
||||||
|
CONFIG_INTC_INIT_PRIORITY, NULL);
|
||||||
|
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(CLIC_INTC_DEVICE_INIT)
|
||||||
|
|
|
@ -8,9 +8,33 @@
|
||||||
#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_CLIC_H_
|
#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_CLIC_H_
|
||||||
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_CLIC_H_
|
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_CLIC_H_
|
||||||
|
|
||||||
|
/* CLIC relative CSR number */
|
||||||
|
#define CSR_MTVT (0x307)
|
||||||
|
#define CSR_MNXTI (0x345)
|
||||||
|
#define CSR_MINTTHRESH (0x347)
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* CLIC Memory mapped register offset */
|
||||||
|
#define CLIC_CFG (0x0)
|
||||||
|
#define CLIC_CTRL(irq) (0x1000 + 4 * (irq))
|
||||||
|
#define CLIC_INTIP(irq) (CLIC_CTRL(irq) + offsetof(union CLICCTRL, w.INTIP))
|
||||||
|
#define CLIC_INTIE(irq) (CLIC_CTRL(irq) + offsetof(union CLICCTRL, w.INTIE))
|
||||||
|
#define CLIC_INTATTR(irq) (CLIC_CTRL(irq) + offsetof(union CLICCTRL, w.INTATTR))
|
||||||
|
#define CLIC_INTCTRL(irq) (CLIC_CTRL(irq) + offsetof(union CLICCTRL, w.INTCTRL))
|
||||||
|
|
||||||
|
/* Nuclei ECLIC memory mapped register offset */
|
||||||
|
#define CLIC_INFO (0x4)
|
||||||
|
#define CLIC_MTH (0x8)
|
||||||
|
|
||||||
|
/* CLIC register structure */
|
||||||
union CLICCFG {
|
union CLICCFG {
|
||||||
struct {
|
struct {
|
||||||
|
#ifdef CONFIG_NUCLEI_ECLIC
|
||||||
uint32_t _reserved0: 1;
|
uint32_t _reserved0: 1;
|
||||||
|
#endif /* CONFIG_NUCLEI_ECLIC */
|
||||||
/** number of interrupt level bits */
|
/** number of interrupt level bits */
|
||||||
uint32_t nlbits: 4;
|
uint32_t nlbits: 4;
|
||||||
/** number of clicintattr[i].MODE bits */
|
/** number of clicintattr[i].MODE bits */
|
||||||
|
@ -60,6 +84,7 @@ union CLICCTRL {
|
||||||
uint32_t qw;
|
uint32_t qw;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Nuclei ECLIC register structure */
|
||||||
union CLICINFO {
|
union CLICINFO {
|
||||||
struct {
|
struct {
|
||||||
/** number of max supported interrupts */
|
/** number of max supported interrupts */
|
||||||
|
@ -82,4 +107,6 @@ union CLICMTH {
|
||||||
uint32_t qw;
|
uint32_t qw;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /*__ASSEMBLER__*/
|
||||||
|
|
||||||
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_CLIC_H_ */
|
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_CLIC_H_ */
|
||||||
|
|
|
@ -52,10 +52,7 @@
|
||||||
#address-cells = <0>;
|
#address-cells = <0>;
|
||||||
#interrupt-cells = <2>;
|
#interrupt-cells = <2>;
|
||||||
interrupt-controller;
|
interrupt-controller;
|
||||||
reg = <0xd2000000 0x0001
|
reg = <0xd2000000 0x2000>;
|
||||||
0xd2000004 0x0004
|
|
||||||
0xd200000b 0x0001
|
|
||||||
0xd2001000 0x1000>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
rcu: reset-clock-controller@40021000 {
|
rcu: reset-clock-controller@40021000 {
|
||||||
|
|
|
@ -164,7 +164,7 @@ static inline void trigger_irq(int irq)
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(CONFIG_RISCV)
|
#elif defined(CONFIG_RISCV)
|
||||||
#if defined(CONFIG_NUCLEI_ECLIC) || defined(CONFIG_NRFX_CLIC)
|
#if defined(CONFIG_CLIC) || defined(CONFIG_NRFX_CLIC)
|
||||||
void riscv_clic_irq_set_pending(uint32_t irq);
|
void riscv_clic_irq_set_pending(uint32_t irq);
|
||||||
static inline void trigger_irq(int irq)
|
static inline void trigger_irq(int irq)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue