diff options
-rw-r--r-- | firmware/export/as3525.h | 31 | ||||
-rw-r--r-- | firmware/target/arm/as3525/system-as3525.c | 72 |
2 files changed, 74 insertions, 29 deletions
diff --git a/firmware/export/as3525.h b/firmware/export/as3525.h index be373f31fd..ea3c5784cb 100644 --- a/firmware/export/as3525.h +++ b/firmware/export/as3525.h | |||
@@ -369,8 +369,37 @@ interface */ | |||
369 | #define VIC_PROTECTION (*(volatile unsigned long*)(VIC_BASE+0x20)) | 369 | #define VIC_PROTECTION (*(volatile unsigned long*)(VIC_BASE+0x20)) |
370 | #define VIC_VECT_ADDR (*(volatile unsigned long*)(VIC_BASE+0x30)) | 370 | #define VIC_VECT_ADDR (*(volatile unsigned long*)(VIC_BASE+0x30)) |
371 | #define VIC_DEF_VECT_ADDR (*(volatile unsigned long*)(VIC_BASE+0x34)) | 371 | #define VIC_DEF_VECT_ADDR (*(volatile unsigned long*)(VIC_BASE+0x34)) |
372 | #define VIC_VECT_ADDRS ((volatile unsigned long*)(VIC_BASE+0x100)) | ||
373 | #define VIC_VECT_CNTLS ((volatile unsigned long*)(VIC_BASE+0x200)) | ||
374 | |||
375 | /* Interrupt sources (for vectors setup) */ | ||
376 | #define INT_SRC_WATCHDOG 0 | ||
377 | #define INT_SRC_TIMER1 1 | ||
378 | #define INT_SRC_TIMER2 2 | ||
379 | #define INT_SRC_USB 3 | ||
380 | #define INT_SRC_DMAC 4 | ||
381 | #define INT_SRC_NAND 5 | ||
382 | #define INT_SRC_IDE 6 | ||
383 | #define INT_SRC_MCI0 7 | ||
384 | #define INT_SRC_MCI1 8 | ||
385 | #define INT_SRC_AUDIO 9 | ||
386 | #define INT_SRC_SSP 10 | ||
387 | #define INT_SRC_I2C_MS 11 | ||
388 | #define INT_SRC_I2C_AUDIO 12 | ||
389 | #define INT_SRC_I2SIN 13 | ||
390 | #define INT_SRC_I2SOUT 14 | ||
391 | #define INT_SRC_UART 15 | ||
392 | #define INT_SRC_GPIOD 16 | ||
393 | /* 17 reserved */ | ||
394 | #define INT_SRC_CGU 18 | ||
395 | #define INT_SRC_MEMORY_STICK 19 | ||
396 | #define INT_SRC_DBOP 20 | ||
397 | /* 21-28 reserved */ | ||
398 | #define INT_SRC_GPIOA 29 | ||
399 | #define INT_SRC_GPIOB 30 | ||
400 | #define INT_SRC_GPIOC 31 | ||
372 | 401 | ||
373 | /* Interrupts */ | 402 | /* Interrupt sources bitmask */ |
374 | #define INTERRUPT_WATCHDOG (1<<0) | 403 | #define INTERRUPT_WATCHDOG (1<<0) |
375 | #define INTERRUPT_TIMER1 (1<<1) | 404 | #define INTERRUPT_TIMER1 (1<<1) |
376 | #define INTERRUPT_TIMER2 (1<<2) | 405 | #define INTERRUPT_TIMER2 (1<<2) |
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index 649ba77527..c2a2e4f47d 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c | |||
@@ -66,18 +66,6 @@ default_interrupt(INT_GPIOA); | |||
66 | default_interrupt(INT_GPIOB); | 66 | default_interrupt(INT_GPIOB); |
67 | default_interrupt(INT_GPIOC); | 67 | default_interrupt(INT_GPIOC); |
68 | 68 | ||
69 | |||
70 | |||
71 | static void (* const irqvector[])(void) = | ||
72 | { | ||
73 | INT_WATCHDOG, INT_TIMER1, INT_TIMER2, INT_USB, INT_DMAC, INT_NAND, INT_IDE, INT_MCI0, | ||
74 | INT_MCI1, INT_AUDIO, INT_SSP, INT_I2C_MS, INT_I2C_AUDIO, INT_I2SIN, INT_I2SOUT, | ||
75 | INT_UART, INT_GPIOD, RESERVED1 /* 17 */ ,INT_CGU, INT_MEMORY_STICK, INT_DBOP, | ||
76 | RESERVED2 /* 21 */, RESERVED3 /* 22 */, RESERVED4 /* 23 */, RESERVED5 /* 24 */, | ||
77 | RESERVED6 /* 25 */, RESERVED7 /* 26 */, RESERVED8 /* 27 */, RESERVED9 /* 28 */, | ||
78 | INT_GPIOA, INT_GPIOB, INT_GPIOC | ||
79 | }; | ||
80 | |||
81 | static const char * const irqname[] = | 69 | static const char * const irqname[] = |
82 | { | 70 | { |
83 | "INT_WATCHDOG", "INT_TIMER1", "INT_TIMER2", "INT_USB", "INT_DMAC", "INT_NAND", | 71 | "INT_WATCHDOG", "INT_TIMER1", "INT_TIMER2", "INT_USB", "INT_DMAC", "INT_NAND", |
@@ -98,23 +86,54 @@ static void UIRQ(void) | |||
98 | panicf("Unhandled IRQ %02X: %s", irq_no, irqname[irq_no]); | 86 | panicf("Unhandled IRQ %02X: %s", irq_no, irqname[irq_no]); |
99 | } | 87 | } |
100 | 88 | ||
101 | void irq_handler(void) | 89 | struct vec_int_src |
102 | { | 90 | { |
103 | /* | 91 | int source; |
104 | * Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c | 92 | void (*isr) (void); |
105 | */ | 93 | }; |
106 | 94 | ||
107 | asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" );/* Store context */ | 95 | /* Vectored interrupts (16 available) */ |
96 | struct vec_int_src vec_int_srcs[] = | ||
97 | { | ||
98 | { INT_SRC_TIMER1, INT_TIMER1 }, | ||
99 | { INT_SRC_TIMER2, INT_TIMER2 }, | ||
100 | { INT_SRC_DMAC, INT_DMAC }, | ||
101 | { INT_SRC_NAND, INT_NAND }, | ||
102 | { INT_SRC_MCI0, INT_MCI0 }, | ||
103 | { INT_SRC_GPIOA, INT_GPIOA, }, | ||
104 | { INT_SRC_GPIOB, INT_GPIOB, }, | ||
105 | }; | ||
108 | 106 | ||
109 | unsigned int irq_no = 0; | 107 | static void setup_vic(void) |
110 | int status = VIC_IRQ_STATUS; | 108 | { |
111 | while((status >>= 1)) | 109 | volatile unsigned long *vic_vect_addrs = VIC_VECT_ADDRS; |
112 | irq_no++; | 110 | volatile unsigned long *vic_vect_cntls = VIC_VECT_CNTLS; |
111 | const unsigned int n = sizeof(vec_int_srcs)/sizeof(vec_int_srcs[0]); | ||
112 | unsigned int i; | ||
113 | |||
114 | CGU_PERI |= CGU_VIC_CLOCK_ENABLE; /* enable VIC */ | ||
115 | VIC_INT_EN_CLEAR = 0xffffffff; /* disable all interrupt lines */ | ||
116 | VIC_INT_SELECT = 0; /* only IRQ, no FIQ */ | ||
113 | 117 | ||
114 | irqvector[irq_no](); | 118 | VIC_DEF_VECT_ADDR = (unsigned long)UIRQ; |
115 | 119 | ||
116 | asm volatile( "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ | 120 | for(i = 0; i < n; i++) |
117 | "subs pc, lr, #4 \n"); /* Return from IRQ */ | 121 | { |
122 | vic_vect_addrs[i] = (unsigned long)vec_int_srcs[i].isr; | ||
123 | vic_vect_cntls[i] = (1<<5) | vec_int_srcs[i].source; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | void irq_handler(void) | ||
128 | { | ||
129 | asm volatile( "stmfd sp!, {r0-r5,ip,lr} \n" /* Store context */ | ||
130 | "ldr r5, =0xC6010030 \n" /* VIC_VECT_ADDR */ | ||
131 | "mov lr, pc \n" /* Return from ISR */ | ||
132 | "ldr pc, [r5] \n" /* execute ISR */ | ||
133 | "str r0, [r5] \n" /* Ack interrupt */ | ||
134 | "ldmfd sp!, {r0-r5,ip,lr} \n" /* Restore context */ | ||
135 | "subs pc, lr, #4 \n" /* Return from IRQ */ | ||
136 | ); | ||
118 | } | 137 | } |
119 | 138 | ||
120 | void fiq_handler(void) | 139 | void fiq_handler(void) |
@@ -235,10 +254,7 @@ void system_init(void) | |||
235 | /* enable timer interface for TIMER1 & TIMER2 */ | 254 | /* enable timer interface for TIMER1 & TIMER2 */ |
236 | CGU_PERI |= CGU_TIMERIF_CLOCK_ENABLE; | 255 | CGU_PERI |= CGU_TIMERIF_CLOCK_ENABLE; |
237 | 256 | ||
238 | /* enable VIC */ | 257 | setup_vic(); |
239 | VIC_INT_EN_CLEAR = 0xffffffff; /* disable all interrupt lines */ | ||
240 | CGU_PERI |= CGU_VIC_CLOCK_ENABLE; | ||
241 | VIC_INT_SELECT = 0; /* only IRQ, no FIQ */ | ||
242 | 258 | ||
243 | dma_init(); | 259 | dma_init(); |
244 | 260 | ||