Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/interrupt_controller/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ zephyr_library_sources_ifdef(CONFIG_INTC_ESP32 intc_esp32.c)
zephyr_library_sources_ifdef(CONFIG_INTC_ESP32C3 intc_esp32c3.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_VIM intc_vim.c)
zephyr_library_sources_ifdef(CONFIG_NUCLEI_ECLIC intc_nuclei_eclic.c)
zephyr_library_sources_ifdef(CONFIG_NXP_S32_EIRQ intc_eirq_nxp_s32.c)
zephyr_library_sources_ifdef(CONFIG_XMC4XXX_INTC intc_xmc4xxx.c)
Expand Down
2 changes: 2 additions & 0 deletions drivers/interrupt_controller/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,6 @@ source "drivers/interrupt_controller/Kconfig.xmc4xxx"

source "drivers/interrupt_controller/Kconfig.nxp_pint"

source "drivers/interrupt_controller/Kconfig.vim"

endmenu
16 changes: 16 additions & 0 deletions drivers/interrupt_controller/Kconfig.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (C) 2023 BeagleBoard.org Foundation
# Copyright (C) 2023 S Prashanth
#
# SPDX-License-Identifier: Apache-2.0

if CPU_CORTEX_R5

config VIM
bool "TI Vectored Interrupt Manager"
default y
depends on DT_HAS_TI_VIM_ENABLED
help
The TI Vectored Interrupt Manager provides hardware assistance for prioritizing
and aggregating the interrupt sources for ARM Cortex-R5 processor cores.

endif # CPU_CORTEX_R5
151 changes: 151 additions & 0 deletions drivers/interrupt_controller/intc_vim.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/* Copyright (C) 2023 BeagleBoard.org Foundation
* Copyright (C) 2023 S Prashanth
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT ti_vim

#include <stdint.h>

#include <zephyr/arch/arm/aarch32/irq.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/interrupt_controller/intc_vim.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util_macro.h>

LOG_MODULE_REGISTER(vim);

unsigned int z_vim_irq_get_active(void)
{
uint32_t irq_group_num, irq_bit_num;
uint32_t actirq, vec_addr;

/* Reading IRQVEC register, ACTIRQ gets loaded with valid IRQ values */
vec_addr = sys_read32(VIM_IRQVEC);

/* ACTIRQ register should be read only after reading IRQVEC register */
actirq = sys_read32(VIM_ACTIRQ);

/* Check if the irq number is valid, else return invalid irq number.
* which will be considered as spurious interrupt
*/
if ((actirq & (VIM_ACTIRQ_VALID_MASK)) == 0) {
return CONFIG_NUM_IRQS + 1;
}

irq_group_num = VIM_GET_IRQ_GROUP_NUM(actirq & VIM_PRIIRQ_NUM_MASK);
irq_bit_num = VIM_GET_IRQ_BIT_NUM(actirq & VIM_PRIIRQ_NUM_MASK);

/* Ack the interrupt in IRQSTS register */
sys_write32(BIT(irq_bit_num), VIM_IRQSTS(irq_group_num));

if (irq_group_num > VIM_MAX_GROUP_NUM) {
return (CONFIG_NUM_IRQS + 1);
}

return (actirq & VIM_ACTIRQ_NUM_MASK);
}

void z_vim_irq_eoi(unsigned int irq)
{
sys_write32(0, VIM_IRQVEC);
}

void z_vim_irq_init(void)
{
uint32_t num_of_irqs = sys_read32(VIM_INFO_INTERRUPTS_MASK);

LOG_DBG("VIM: Number of IRQs = %u\n", num_of_irqs);
}

void z_vim_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
{
uint32_t irq_group_num, irq_bit_num, regval;

if (irq > CONFIG_NUM_IRQS || prio > VIM_PRI_INT_MAX ||
(flags != IRQ_TYPE_EDGE && flags != IRQ_TYPE_LEVEL)) {
LOG_ERR("%s: Invalid argument irq = %u prio = %u flags = %u\n",
__func__, irq, prio, flags);
return;
}

sys_write8(prio, VIM_PRI_INT(irq));

irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

regval = sys_read32(VIM_INTTYPE(irq_group_num));

if (flags == IRQ_TYPE_EDGE) {
regval |= (BIT(irq_bit_num));
} else {
regval &= ~(BIT(irq_bit_num));
}

sys_write32(regval, VIM_INTTYPE(irq_group_num));
}

void z_vim_irq_enable(unsigned int irq)
{
uint32_t irq_group_num, irq_bit_num;

if (irq > CONFIG_NUM_IRQS) {
LOG_ERR("%s: Invalid irq number = %u\n", __func__, irq);
return;
}

irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

sys_write32(BIT(irq_bit_num), VIM_INTR_EN_SET(irq_group_num));
}

void z_vim_irq_disable(unsigned int irq)
{
uint32_t irq_group_num, irq_bit_num;

if (irq > CONFIG_NUM_IRQS) {
LOG_ERR("%s: Invalid irq number = %u\n", __func__, irq);
return;
}

irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

sys_write32(BIT(irq_bit_num), VIM_INTR_EN_CLR(irq_group_num));
}

int z_vim_irq_is_enabled(unsigned int irq)
{
uint32_t irq_group_num, irq_bit_num, regval;

if (irq > CONFIG_NUM_IRQS) {
LOG_ERR("%s: Invalid irq number = %u\n", __func__, irq);
return -EINVAL;
}

irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

regval = sys_read32(VIM_INTR_EN_SET(irq_group_num));

return !!(regval & (BIT(irq_bit_num)));
}

void z_vim_arm_enter_irq(int irq)
{
uint32_t irq_group_num, irq_bit_num;

if (irq > CONFIG_NUM_IRQS) {
LOG_ERR("%s: Invalid irq number = %u\n", __func__, irq);
return;
}

irq_group_num = VIM_GET_IRQ_GROUP_NUM(irq);
irq_bit_num = VIM_GET_IRQ_BIT_NUM(irq);

sys_write32(BIT(irq_bit_num), VIM_RAW(irq_group_num));
}
22 changes: 22 additions & 0 deletions dts/bindings/interrupt-controller/ti,vim.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (C) 2023 BeagleBoard.org Foundation
# Copyright (C) 2023 S Prashanth
#
# SPDX-License-Identifier: Apache-2.0

description: |
TI Vectored Interrupt Manager is a external interrupt controller
(TI specific IP) which is compatible with R5F VIC port.

compatible: "ti,vim"

include: base.yaml

properties:
reg:
required: true

interrupt-cells:
- type
- irq
- flags
- priority
Loading