diff options
Diffstat (limited to 'firmware/target/arm/imx31/avic-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/avic-imx31.c | 65 |
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 | ||
28 | static 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 | |||
44 | static 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 | ||
48 | void UIE_VECTOR(void) | 64 | void 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 */ |
71 | void __attribute__((interrupt("IRQ"))) irq_handler(void) | 86 | void __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 | ||
104 | void avic_init(void) | 119 | void 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 | ||
138 | void avic_set_int_priority(enum IMX31_INT_LIST ints, | 152 | void 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 | ||
148 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | 161 | void 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 | ||
165 | void avic_disable_int(enum IMX31_INT_LIST ints) | 177 | void 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 | ||
185 | static void set_int_type(int i, enum INT_TYPE intstype) | 195 | static 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 | } |