summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/avic-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/avic-imx31.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
index fa74d3bb9f..b04b22911a 100644
--- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
@@ -84,18 +84,24 @@ void __attribute__((naked)) fiq_handler(void)
84 84
85void avic_init(void) 85void avic_init(void)
86{ 86{
87 int i;
88
87 /* Disable all interrupts and set to unhandled */ 89 /* Disable all interrupts and set to unhandled */
88 avic_disable_int(ALL); 90 avic_disable_int(ALL);
89 91
92 /* Reset AVIC control */
93 INTCNTL = 0;
94
90 /* Init all interrupts to type IRQ */ 95 /* Init all interrupts to type IRQ */
91 avic_set_int_type(ALL, IRQ); 96 avic_set_int_type(ALL, IRQ);
92 97
98 /* Set all normal to lowest priority */
99 for (i = 0; i < 8; i++)
100 NIPRIORITY(i) = 0;
101
93 /* Set NM bit to enable VIC */ 102 /* Set NM bit to enable VIC */
94 INTCNTL |= INTCNTL_NM; 103 INTCNTL |= INTCNTL_NM;
95 104
96 /* Enable IRQ/FIQ in imx31 INTCNTL reg */
97 INTCNTL &= ~(INTCNTL_ABFEN | INTCNTL_NIDIS | INTCNTL_FIDIS);
98
99 /* Enable VE bit in CP15 Control reg to enable VIC */ 105 /* Enable VE bit in CP15 Control reg to enable VIC */
100 asm volatile ( 106 asm volatile (
101 "mrc p15, 0, r0, c1, c0, 0 \n" 107 "mrc p15, 0, r0, c1, c0, 0 \n"
@@ -104,11 +110,20 @@ void avic_init(void)
104 : : : "r0"); 110 : : : "r0");
105 111
106 /* Enable normal interrupts at all priorities */ 112 /* Enable normal interrupts at all priorities */
107 NIMASK = 16; 113 NIMASK = 0x1f;
114}
115
116void avic_set_int_priority(enum IMX31_INT_LIST ints,
117 unsigned long ni_priority)
118{
119 volatile unsigned long *reg = &NIPRIORITY((63 - ints) / 8);
120 unsigned int shift = 4*(ints % 8);
121 unsigned long mask = 0xful << shift;
122 *reg = (*reg & ~mask) | ((ni_priority << shift) & mask);
108} 123}
109 124
110void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, 125void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
111 void (*handler)(void)) 126 unsigned long ni_priority, void (*handler)(void))
112{ 127{
113 int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, 128 int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED,
114 IRQ_FIQ_STATUS); 129 IRQ_FIQ_STATUS);
@@ -118,6 +133,7 @@ void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
118 avic_set_int_type(ints, intstype); 133 avic_set_int_type(ints, intstype);
119 VECTOR(ints) = (long)handler; 134 VECTOR(ints) = (long)handler;
120 INTENNUM = ints; 135 INTENNUM = ints;
136 avic_set_int_priority(ints, ni_priority);
121 } 137 }
122 138
123 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); 139 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS);