summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/avic-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/avic-imx31.c')
-rw-r--r--firmware/target/arm/imx31/avic-imx31.c65
1 files changed, 37 insertions, 28 deletions
diff --git a/firmware/target/arm/imx31/avic-imx31.c b/firmware/target/arm/imx31/avic-imx31.c
index e349c97d82..5bf7275e07 100644
--- a/firmware/target/arm/imx31/avic-imx31.c
+++ b/firmware/target/arm/imx31/avic-imx31.c
@@ -25,7 +25,23 @@
25#include "panic.h" 25#include "panic.h"
26#include "debug.h" 26#include "debug.h"
27 27
28static const char * avic_int_names[64] = 28#define avic ((unsigned long * const)AVIC_BASE_ADDR)
29#define INTCNTL (0x000 / sizeof (unsigned long)) /* 000h */
30#define NIMASK (0x004 / sizeof (unsigned long)) /* 004h */
31#define INTENNUM (0x008 / sizeof (unsigned long)) /* 008h */
32#define INTDISNUM (0x00c / sizeof (unsigned long)) /* 00Ch */
33#define INTENABLE (0x010 / sizeof (unsigned long)) /* 010h H,L */
34#define INTTYPE (0x018 / sizeof (unsigned long)) /* 018h H,L */
35#define NIPRIORITY (0x020 / sizeof (unsigned long)) /* 020h 7-0 */
36#define NIVECSR (0x040 / sizeof (unsigned long)) /* 040h */
37#define FIVECSR (0x044 / sizeof (unsigned long)) /* 044h */
38#define INTSRC (0x048 / sizeof (unsigned long)) /* 048h H,L */
39#define INTFRC (0x050 / sizeof (unsigned long)) /* 050h H,L */
40#define NIPND (0x058 / sizeof (unsigned long)) /* 058h H,L */
41#define FIPND (0x060 / sizeof (unsigned long)) /* 060h H,L */
42#define VECTOR (0x100 / sizeof (unsigned long)) /* 100h */
43
44static const char * const avic_int_names[64] =
29{ 45{
30 "RESERVED0", "RESERVED1", "RESERVED2", "I2C3", 46 "RESERVED0", "RESERVED1", "RESERVED2", "I2C3",
31 "I2C2", "MPEG4_ENCODER", "RTIC", "FIR", 47 "I2C2", "MPEG4_ENCODER", "RTIC", "FIR",
@@ -47,7 +63,7 @@ static const char * avic_int_names[64] =
47 63
48void UIE_VECTOR(void) 64void UIE_VECTOR(void)
49{ 65{
50 int mode; 66 unsigned long mode;
51 int offset; 67 int offset;
52 68
53 asm volatile ( 69 asm volatile (
@@ -58,8 +74,7 @@ void UIE_VECTOR(void)
58 : "=&r"(mode) 74 : "=&r"(mode)
59 ); 75 );
60 76
61 offset = mode == 0x11 ? 77 offset = mode == 0x11 ? (long)avic[FIVECSR] : ((long)avic[NIVECSR] >> 16);
62 (int32_t)AVIC_FIVECSR : ((int32_t)AVIC_NIVECSR >> 16);
63 78
64 panicf("Unhandled %s %d: %s", 79 panicf("Unhandled %s %d: %s",
65 mode == 0x11 ? "FIQ" : "IRQ", offset, 80 mode == 0x11 ? "FIQ" : "IRQ", offset,
@@ -70,7 +85,7 @@ void UIE_VECTOR(void)
70/* We use the AVIC */ 85/* We use the AVIC */
71void __attribute__((interrupt("IRQ"))) irq_handler(void) 86void __attribute__((interrupt("IRQ"))) irq_handler(void)
72{ 87{
73 const int offset = (int32_t)AVIC_NIVECSR >> 16; 88 int offset = (long)avic[NIVECSR] >> 16;
74 89
75 if (offset == -1) 90 if (offset == -1)
76 { 91 {
@@ -103,26 +118,25 @@ void __attribute__((naked)) fiq_handler(void)
103 118
104void avic_init(void) 119void avic_init(void)
105{ 120{
106 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
107 int i; 121 int i;
108 122
109 /* Disable all interrupts and set to unhandled */ 123 /* Disable all interrupts and set to unhandled */
110 avic_disable_int(INT_ALL); 124 avic_disable_int(INT_ALL);
111 125
112 /* Reset AVIC control */ 126 /* Reset AVIC control */
113 avic->intcntl = 0; 127 avic[INTCNTL] = 0;
114 128
115 /* Init all interrupts to type IRQ */ 129 /* Init all interrupts to type IRQ */
116 avic_set_int_type(INT_ALL, INT_TYPE_IRQ); 130 avic_set_int_type(INT_ALL, INT_TYPE_IRQ);
117 131
118 /* Set all normal to lowest priority */ 132 /* Set all normal to lowest priority */
119 for (i = 0; i < 8; i++) 133 for (i = 0; i < 8; i++)
120 avic->nipriority[i] = 0; 134 avic[NIPRIORITY + i] = 0;
121 135
122 /* Set NM bit to enable VIC. Mask fast interrupts. Core arbiter rise 136 /* Set NM bit to enable VIC. Mask fast interrupts. Core arbiter rise
123 * for normal interrupts (for lowest latency). */ 137 * for normal interrupts (for lowest latency). */
124 avic->intcntl |= AVIC_INTCNTL_NM | AVIC_INTCNTL_FIDIS | 138 avic[INTCNTL] |= AVIC_INTCNTL_NM | AVIC_INTCNTL_FIDIS |
125 AVIC_INTCNTL_NIAD; 139 AVIC_INTCNTL_NIAD;
126 140
127 /* Enable VE bit in CP15 Control reg to enable VIC */ 141 /* Enable VE bit in CP15 Control reg to enable VIC */
128 asm volatile ( 142 asm volatile (
@@ -132,30 +146,28 @@ void avic_init(void)
132 : : : "r0"); 146 : : : "r0");
133 147
134 /* Enable normal interrupts at all priorities */ 148 /* Enable normal interrupts at all priorities */
135 avic->nimask = AVIC_NIL_ENABLE; 149 avic[NIMASK] = AVIC_NIL_ENABLE;
136} 150}
137 151
138void avic_set_int_priority(enum IMX31_INT_LIST ints, 152void avic_set_int_priority(enum IMX31_INT_LIST ints,
139 unsigned long ni_priority) 153 unsigned long ni_priority)
140{ 154{
141 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; 155 volatile unsigned long * const reg = &avic[NIPRIORITY + 7 - (ints >> 3)];
142 volatile uint32_t *reg = &avic->nipriority[7 - (ints >> 3)];
143 unsigned int shift = (ints & 0x7) << 2; 156 unsigned int shift = (ints & 0x7) << 2;
144 uint32_t mask = 0xful << shift; 157 unsigned long mask = 0xful << shift;
145 *reg = (*reg & ~mask) | ((ni_priority << shift) & mask); 158 *reg = (*reg & ~mask) | ((ni_priority << shift) & mask);
146} 159}
147 160
148void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, 161void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
149 unsigned long ni_priority, void (*handler)(void)) 162 unsigned long ni_priority, void (*handler)(void))
150{ 163{
151 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
152 int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); 164 int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
153 165
154 if (ints != INT_ALL) /* No mass-enable allowed */ 166 if (ints != INT_ALL) /* No mass-enable allowed */
155 { 167 {
156 avic_set_int_type(ints, intstype); 168 avic_set_int_type(ints, intstype);
157 avic->vector[ints] = (long)handler; 169 avic[VECTOR + ints] = (unsigned long)handler;
158 avic->intennum = ints; 170 avic[INTENNUM] = ints;
159 avic_set_int_priority(ints, ni_priority); 171 avic_set_int_priority(ints, ni_priority);
160 } 172 }
161 173
@@ -164,30 +176,27 @@ void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
164 176
165void avic_disable_int(enum IMX31_INT_LIST ints) 177void avic_disable_int(enum IMX31_INT_LIST ints)
166{ 178{
167 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
168 uint32_t i;
169
170 if (ints == INT_ALL) 179 if (ints == INT_ALL)
171 { 180 {
181 int i;
172 for (i = 0; i < 64; i++) 182 for (i = 0; i < 64; i++)
173 { 183 {
174 avic->intdisnum = i; 184 avic[INTDISNUM] = i;
175 avic->vector[i] = (long)UIE_VECTOR; 185 avic[VECTOR + i] = (unsigned long)UIE_VECTOR;
176 } 186 }
177 } 187 }
178 else 188 else
179 { 189 {
180 avic->intdisnum = ints; 190 avic[INTDISNUM] = ints;
181 avic->vector[ints] = (long)UIE_VECTOR; 191 avic[VECTOR + ints] = (unsigned long)UIE_VECTOR;
182 } 192 }
183} 193}
184 194
185static void set_int_type(int i, enum INT_TYPE intstype) 195static void set_int_type(int i, enum INT_TYPE intstype)
186{ 196{
187 /* INTTYPEH: vectors 63-32, INTTYPEL: vectors 31-0 */ 197 /* INTTYPEH: vectors 63-32, INTTYPEL: vectors 31-0 */
188 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; 198 volatile unsigned long * const reg = &avic[INTTYPE + 1 - (i >> 5)];
189 volatile uint32_t *reg = &avic->inttype[1 - (i >> 5)]; 199 unsigned long val = 1L << (i & 0x1f);
190 uint32_t val = 1L << (i & 0x1f);
191 200
192 if (intstype == INT_TYPE_IRQ) 201 if (intstype == INT_TYPE_IRQ)
193 val = *reg & ~val; 202 val = *reg & ~val;
@@ -222,5 +231,5 @@ void avic_set_ni_level(int level)
222 else if (level > 15) 231 else if (level > 15)
223 level = 15; 232 level = 15;
224 233
225 AVIC_NIMASK = level; 234 avic[NIMASK] = level;
226} 235}