diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/avic-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c index 6b64bfad77..ce2932a13f 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | |||
@@ -74,9 +74,9 @@ void __attribute__((naked)) irq_handler(void) | |||
74 | void __attribute__((naked)) fiq_handler(void) | 74 | void __attribute__((naked)) fiq_handler(void) |
75 | { | 75 | { |
76 | asm volatile ( | 76 | asm volatile ( |
77 | "mov r10, #0x6c000000 \n" /* load AVIC base address */ | 77 | "mov r10, #0x68000000 \n" /* load AVIC base address */ |
78 | "ldr r9, [r10, #0x44] \n" /* read FIVECSR of AVIC */ | 78 | "ldr r9, [r10, #0x44] \n" /* read FIVECSR of AVIC */ |
79 | "add r10, r10, #100 \n" /* move pointer to base of VECTOR table */ | 79 | "add r10, r10, #0x100 \n" /* move pointer to base of VECTOR table */ |
80 | "ldr r8, [r10, r9, lsl #2] \n" /* read FIQ vector from VECTOR table */ | 80 | "ldr r8, [r10, r9, lsl #2] \n" /* read FIQ vector from VECTOR table */ |
81 | "bx r8 \n" /* jump to FIQ service routine */ | 81 | "bx r8 \n" /* jump to FIQ service routine */ |
82 | ); | 82 | ); |
@@ -84,23 +84,24 @@ void __attribute__((naked)) fiq_handler(void) | |||
84 | 84 | ||
85 | void avic_init(void) | 85 | void avic_init(void) |
86 | { | 86 | { |
87 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; | ||
87 | int i; | 88 | int i; |
88 | 89 | ||
89 | /* Disable all interrupts and set to unhandled */ | 90 | /* Disable all interrupts and set to unhandled */ |
90 | avic_disable_int(ALL); | 91 | avic_disable_int(ALL); |
91 | 92 | ||
92 | /* Reset AVIC control */ | 93 | /* Reset AVIC control */ |
93 | INTCNTL = 0; | 94 | avic->intcntl = 0; |
94 | 95 | ||
95 | /* Init all interrupts to type IRQ */ | 96 | /* Init all interrupts to type IRQ */ |
96 | avic_set_int_type(ALL, IRQ); | 97 | avic_set_int_type(ALL, IRQ); |
97 | 98 | ||
98 | /* Set all normal to lowest priority */ | 99 | /* Set all normal to lowest priority */ |
99 | for (i = 0; i < 8; i++) | 100 | for (i = 0; i < 8; i++) |
100 | NIPRIORITY(i) = 0; | 101 | avic->nipriority[i] = 0; |
101 | 102 | ||
102 | /* Set NM bit to enable VIC */ | 103 | /* Set NM bit to enable VIC */ |
103 | INTCNTL |= INTCNTL_NM; | 104 | avic->intcntl |= INTCNTL_NM; |
104 | 105 | ||
105 | /* Enable VE bit in CP15 Control reg to enable VIC */ | 106 | /* Enable VE bit in CP15 Control reg to enable VIC */ |
106 | asm volatile ( | 107 | asm volatile ( |
@@ -110,28 +111,30 @@ void avic_init(void) | |||
110 | : : : "r0"); | 111 | : : : "r0"); |
111 | 112 | ||
112 | /* Enable normal interrupts at all priorities */ | 113 | /* Enable normal interrupts at all priorities */ |
113 | NIMASK = 0x1f; | 114 | avic->nimask = 0x1f; |
114 | } | 115 | } |
115 | 116 | ||
116 | void avic_set_int_priority(enum IMX31_INT_LIST ints, | 117 | void avic_set_int_priority(enum IMX31_INT_LIST ints, |
117 | unsigned long ni_priority) | 118 | unsigned long ni_priority) |
118 | { | 119 | { |
119 | volatile unsigned long *reg = &NIPRIORITY((63 - ints) / 8); | 120 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; |
120 | unsigned int shift = 4*(ints % 8); | 121 | volatile uint32_t *reg = &avic->nipriority[7 - (ints >> 3)]; |
121 | unsigned long mask = 0xful << shift; | 122 | unsigned int shift = (ints & 0x7) << 2; |
123 | uint32_t mask = 0xful << shift; | ||
122 | *reg = (*reg & ~mask) | ((ni_priority << shift) & mask); | 124 | *reg = (*reg & ~mask) | ((ni_priority << shift) & mask); |
123 | } | 125 | } |
124 | 126 | ||
125 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | 127 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, |
126 | unsigned long ni_priority, void (*handler)(void)) | 128 | unsigned long ni_priority, void (*handler)(void)) |
127 | { | 129 | { |
130 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; | ||
128 | int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); | 131 | int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); |
129 | 132 | ||
130 | if (ints != ALL) /* No mass-enable allowed */ | 133 | if (ints != ALL) /* No mass-enable allowed */ |
131 | { | 134 | { |
132 | avic_set_int_type(ints, intstype); | 135 | avic_set_int_type(ints, intstype); |
133 | VECTOR(ints) = (long)handler; | 136 | avic->vector[ints] = (long)handler; |
134 | INTENNUM = ints; | 137 | avic->intennum = ints; |
135 | avic_set_int_priority(ints, ni_priority); | 138 | avic_set_int_priority(ints, ni_priority); |
136 | } | 139 | } |
137 | 140 | ||
@@ -140,38 +143,30 @@ void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | |||
140 | 143 | ||
141 | void avic_disable_int(enum IMX31_INT_LIST ints) | 144 | void avic_disable_int(enum IMX31_INT_LIST ints) |
142 | { | 145 | { |
143 | long i; | 146 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; |
147 | uint32_t i; | ||
144 | 148 | ||
145 | if (ints == ALL) | 149 | if (ints == ALL) |
146 | { | 150 | { |
147 | for (i = 0; i < 64; i++) | 151 | for (i = 0; i < 64; i++) |
148 | { | 152 | { |
149 | INTDISNUM = i; | 153 | avic->intdisnum = i; |
150 | VECTOR(i) = (long)UIE_VECTOR; | 154 | avic->vector[i] = (long)UIE_VECTOR; |
151 | } | 155 | } |
152 | } | 156 | } |
153 | else | 157 | else |
154 | { | 158 | { |
155 | INTDISNUM = ints; | 159 | avic->intdisnum = ints; |
156 | VECTOR(ints) = (long)UIE_VECTOR; | 160 | avic->vector[ints] = (long)UIE_VECTOR; |
157 | } | 161 | } |
158 | } | 162 | } |
159 | 163 | ||
160 | static void set_int_type(int i, enum INT_TYPE intstype) | 164 | static void set_int_type(int i, enum INT_TYPE intstype) |
161 | { | 165 | { |
162 | volatile unsigned long *reg; | 166 | /* INTTYPEH: vectors 63-32, INTTYPEL: vectors 31-0 */ |
163 | long val; | 167 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; |
164 | 168 | volatile uint32_t *reg = &avic->inttype[1 - (i >> 5)]; | |
165 | if (i >= 32) | 169 | uint32_t val = 1L << (i & 0x1f); |
166 | { | ||
167 | reg = &INTTYPEH; | ||
168 | val = 1L << (i - 32); | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 | reg = &INTTYPEL; | ||
173 | val = 1L << i; | ||
174 | } | ||
175 | 170 | ||
176 | if (intstype == IRQ) | 171 | if (intstype == IRQ) |
177 | val = *reg & ~val; | 172 | val = *reg & ~val; |