Skip to content

Commit ef8446d

Browse files
author
Tavish Naruka
committed
drivers: intc: add vim_tms570 interrupt controller
Add TI VIM driver specific to the TMS570 chips. This driver/peripheral is not compatible with the existing intc_vim.c for some other TI chips. Signed-off-by: Tavish Naruka <[email protected]>
1 parent e60b552 commit ef8446d

File tree

7 files changed

+244
-3
lines changed

7 files changed

+244
-3
lines changed

drivers/interrupt_controller/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ zephyr_library_sources_ifdef(CONFIG_INTC_ESP32 intc_esp32.c)
3333
zephyr_library_sources_ifdef(CONFIG_SWERV_PIC intc_swerv_pic.c)
3434
zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex.c)
3535
zephyr_library_sources_ifdef(CONFIG_VIM intc_vim.c)
36+
zephyr_library_sources_ifdef(CONFIG_TMS570_VIM intc_tms570_vim.c)
3637
zephyr_library_sources_ifdef(CONFIG_CLIC intc_clic.c)
3738
zephyr_library_sources_ifdef(CONFIG_CLIC intc_clic.S)
3839
zephyr_library_sources_ifdef(CONFIG_NRFX_CLIC intc_nrfx_clic.c)

drivers/interrupt_controller/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ source "drivers/interrupt_controller/Kconfig.nxp_pint"
102102

103103
source "drivers/interrupt_controller/Kconfig.vim"
104104

105+
source "drivers/interrupt_controller/Kconfig.tms570_vim"
106+
105107
source "drivers/interrupt_controller/Kconfig.renesas_rz"
106108

107109
source "drivers/interrupt_controller/Kconfig.nxp_irqsteer"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (C) 2025 ispace, inc.
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
config TMS570_VIM
6+
bool "TI Vectored Interrupt Manager (TMS570)"
7+
default y
8+
depends on DT_HAS_TI_TMS570_VIM_ENABLED
9+
help
10+
The TI Vectored Interrupt Manager provides hardware assistance for prioritizing
11+
and aggregating the interrupt sources for TI herules ARM Cortex-R4/R5 processor cores.
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
* Copyright (C) 2025 ispace, inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include <zephyr/irq.h>
7+
#include <zephyr/devicetree.h>
8+
#include <zephyr/sys/printk.h>
9+
#include <zephyr/sys/reboot.h>
10+
#include "soc_internal.h"
11+
#include <string.h>
12+
13+
#define DT_DRV_COMPAT ti_tms570_vim
14+
15+
#define DRV_CONTROL_REG DT_INST_REG_ADDR_BY_IDX(0, 0)
16+
#define DRV_ECC_REG DT_INST_REG_ADDR_BY_IDX(0, 1)
17+
#define DRV_VIMRAM_REG DT_INST_REG_ADDR_BY_IDX(0, 2)
18+
#define DRV_VIMRAM_REG_SIZE DT_INST_REG_SIZE_BY_IDX(0, 2)
19+
20+
/* control registers */
21+
#define VIM_REG_IRQINDEX (DRV_CONTROL_REG + 0x00)
22+
#define VIM_REG_FIQINDEX (DRV_CONTROL_REG + 0x04)
23+
#define VIM_REG_REQMASKSET_0 (DRV_CONTROL_REG + 0x30)
24+
#define VIM_REG_REQMASKCLR_0 (DRV_CONTROL_REG + 0x40)
25+
26+
/* ECC related registers */
27+
#define VIM_ECC_CTL (DRV_ECC_REG + 0xF0)
28+
29+
#define REQUMASK_IRQ_PER_REG (32u)
30+
31+
static inline void set_reqmask_bit(unsigned int irq, uintptr_t reg_0_addr)
32+
{
33+
sys_write32(1 << (irq % REQUMASK_IRQ_PER_REG),
34+
reg_0_addr + (irq / REQUMASK_IRQ_PER_REG) * sizeof(uint32_t));
35+
}
36+
37+
static inline int get_reqmask_bit(unsigned int irq, uintptr_t reg_0_addr)
38+
{
39+
return sys_read32(reg_0_addr + (irq / REQUMASK_IRQ_PER_REG) * sizeof(uint32_t));
40+
}
41+
42+
/* count of number of times the phantom interrupt happened */
43+
unsigned int nr_phantom_isr;
44+
45+
static void phantom_isr(void)
46+
{
47+
/**
48+
* we don't want this to call the z_spurious_irq because we have seen
49+
* phantom irq happen even though we don't expect it to happen.
50+
*/
51+
nr_phantom_isr++;
52+
}
53+
54+
#if defined(CONFIG_RUNTIME_NMI)
55+
static void tms570_nmi_handler(void)
56+
{
57+
uint32_t vec = sys_read32(REG_ESM_IOFFHR) - 1;
58+
59+
if (vec < 32) {
60+
sys_write32(1 << vec, REG_ESM_SR1_0);
61+
printk("\nESM Group 1 chan %u\n", vec);
62+
} else if (vec < 64) {
63+
sys_write32(1 << (vec - 32), REG_ESM_SR1_1);
64+
printk("\nESM Group 2 chan %u\n", vec - 32);
65+
} else if (vec < 96U) {
66+
sys_write32(1 << (vec - 64), REG_ESM_SR4_0);
67+
printk("\nESM Group 1 chan %u\n", vec - 32);
68+
} else if ((vec >= 128U) && (vec < 160U)) {
69+
sys_write32(1 << (vec - 128), REG_ESM_SR7_0);
70+
printk("\nESM Group 1 chan %u\n", vec - 96);
71+
} else {
72+
sys_write32(0xFFFFFFFF, REG_ESM_SR7_0);
73+
sys_write32(0xFFFFFFFF, REG_ESM_SR4_0);
74+
sys_write32(0xFFFFFFFF, REG_ESM_SR1_0);
75+
sys_write32(0xFFFFFFFF, REG_ESM_SR1_1);
76+
}
77+
78+
sys_reboot(SYS_REBOOT_WARM);
79+
}
80+
#endif
81+
82+
/**
83+
* @brief Get active interrupt ID (IRQ only)
84+
*
85+
* @return Returns the ID of an active interrupt
86+
*/
87+
unsigned int z_soc_irq_get_active(void)
88+
{
89+
unsigned int irq_idx;
90+
91+
/* a 0 means phantom ISR, channel 0 starts from index 1 */
92+
irq_idx = sys_read32(VIM_REG_IRQINDEX);
93+
if (irq_idx > 0) {
94+
z_soc_irq_disable(irq_idx - 1);
95+
return irq_idx - 1;
96+
97+
} else {
98+
phantom_isr();
99+
}
100+
101+
return (CONFIG_NUM_IRQS + 1);
102+
}
103+
104+
void z_soc_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
105+
{
106+
/**
107+
* not supported, all IRQ sources generate IRQ, instead of FIQ,
108+
* and with the default priority.
109+
*/
110+
}
111+
112+
void z_soc_irq_enable(unsigned int irq)
113+
{
114+
set_reqmask_bit(irq, VIM_REG_REQMASKSET_0);
115+
}
116+
117+
void z_soc_irq_disable(unsigned int irq)
118+
{
119+
set_reqmask_bit(irq, VIM_REG_REQMASKCLR_0);
120+
}
121+
122+
int z_soc_irq_is_enabled(unsigned int irq)
123+
{
124+
return get_reqmask_bit(irq, VIM_REG_REQMASKSET_0);
125+
}
126+
127+
/**
128+
* @brief Signal end-of-interrupt
129+
*
130+
* @param irq interrupt ID
131+
*/
132+
void z_soc_irq_eoi(unsigned int irq)
133+
{
134+
z_soc_irq_enable(irq);
135+
}
136+
137+
void z_soc_irq_init(void)
138+
{
139+
/**
140+
* ref. SPNA218.pdf
141+
* We are implementing what is referred to as "Legacy ARM7 Interrupts".
142+
* We do not use the VIM_RAM at all.
143+
* Sequence is like this:
144+
* 1. Interrupt request happens
145+
* 2. Exception vector 0x18 (IRQ) or 0x1C (FIQ) is taken
146+
* - in case of IRQ "ldr pc, =_isr_wrapper"
147+
* - in case of FIQ "ldr pc, =z_arm_nmi"
148+
* 3. _isr_wrapper uses z_soc_irq_get_active to get index into
149+
* _sw_isr_table for arg and ISR handler
150+
* 4. run ISR handler
151+
*
152+
* Drivers attach interrupts using IRQ_CONNECT/IRQ_DIRECT_CONNECT like:
153+
* IRQ_CONNECT(irqnum, irqnum, z_irq_spurious, NULL, 0);
154+
*/
155+
156+
/* Errata VIM#28 Workaround: Disable Single Bit error correction */
157+
sys_write32((0xAU << 0U) | (0x5U << 16U), VIM_ECC_CTL);
158+
159+
/**
160+
* We do not use VIM RAM, or need to care about ECC, but if we do not set
161+
* the VIM RAM locations to a _valid_ memory address (memset to 0 doesn't work),
162+
* it keeps generating ESM NMI with ESM group 1 status = 0x80008000.
163+
* Doing the following stops it.
164+
*/
165+
uint32_t *p = (void *) DRV_VIMRAM_REG;
166+
167+
for (int i = 0; i < DRV_VIMRAM_REG_SIZE / 4; i++) {
168+
*(p + i) = (uint32_t) &z_irq_spurious;
169+
}
170+
171+
#if defined(CONFIG_RUNTIME_NMI)
172+
z_arm_nmi_set_handler(tms570_nmi_handler);
173+
#endif
174+
175+
/* enable interrupt */
176+
arch_irq_unlock(0);
177+
}

dts/arm/ti/tms570.dtsi

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,17 @@
9494
status = "okay";
9595
};
9696

97+
vim: interrupt-controller@fffffe00 {
98+
compatible = "ti,tms570-vim";
99+
reg = <0xfffffe00 0x00000100>, /* VIM control */
100+
<0xfffffd00 0x00000100>, /* ECC related */
101+
<0xfff82000 128>; /* VIM_RAM */
102+
status = "okay";
103+
interrupt-controller;
104+
#interrupt-cells = <2>;
105+
#address-cells = <1>;
106+
};
107+
97108
sci1: uart@fff7e400 {
98109
compatible = "ti,tms570-uart";
99110
reg = <0xfff7e400 256>;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) 2025 ispace, inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: VIM for TMS570
5+
6+
compatible: "ti,tms570-vim"
7+
8+
include: [interrupt-controller.yaml, base.yaml]
9+
10+
11+
properties:
12+
# NOTE: Register ranges:
13+
# - 0 : VIM control registers
14+
# - 1 : VIM ECC related registers
15+
# - 2 : VIM RAM
16+
reg:
17+
required: true
18+
19+
"#interrupt-cells":
20+
const: 2
21+
22+
interrupt-cells:
23+
- irq
24+
- priority

soc/ti/hercules/ti_tms570lc43x/Kconfig.defconfig

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,33 @@
44
if SOC_TI_TMS570LC43X
55

66
config SYS_CLOCK_EXISTS
7-
default n
7+
default y
88

99
config MULTITHREADING
10+
default y
11+
12+
config DYNAMIC_INTERRUPTS
1013
default n
1114

1215
config GEN_SW_ISR_TABLE
13-
default n
16+
default y
1417

1518
config GEN_ISR_TABLES
19+
default y
20+
21+
config GEN_IRQ_VECTOR_TABLE
1622
default n
1723

18-
# launchpad is 16MHz
24+
config USE_SWITCH
25+
default n
26+
27+
config RUNTIME_NMI
28+
default y
29+
30+
# 10ms OS tick from a 1MHz free-running clock
31+
config SYS_CLOCK_TICKS_PER_SEC
32+
default 100
33+
1934
config SYS_CLOCK_HW_CYCLES_PER_SEC
2035
default $(dt_node_int_prop_int,/soc/rti,clock-frequency)
2136

0 commit comments

Comments
 (0)