Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers: interrupt-controller: Add VIM Interrupt Controller support
Add TI VIM (Vectored Interrupt Manager) interrupt controller support. VIM is a TI specific custom interrupt controller for ARM cores. In J721E soc, VIM aggregates interrupts to Cortex R5 cores. TRM for J721e https://www.ti.com/lit/zip/spruil1 File: spruil1c.pdf VIM: section 6.3.3.6 Signed-off-by: Prashanth S <slpp95prashanth@yahoo.com>
- Loading branch information
1 parent
d7c00ee
commit 5a00895
Showing
8 changed files
with
562 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.