Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: interrupt-controller: Add TI VIM Interrupt Controller support #60856

Merged
merged 1 commit into from Sep 4, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/interrupt_controller/CMakeLists.txt
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
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
@@ -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

slpp95prashanth marked this conversation as resolved.
Show resolved Hide resolved
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
@@ -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
@@ -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