summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/as3525.h31
-rw-r--r--firmware/target/arm/as3525/system-as3525.c72
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);
66default_interrupt(INT_GPIOB); 66default_interrupt(INT_GPIOB);
67default_interrupt(INT_GPIOC); 67default_interrupt(INT_GPIOC);
68 68
69
70
71static 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
81static const char * const irqname[] = 69static 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
101void irq_handler(void) 89struct 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) */
96struct 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; 107static 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
127void 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
120void fiq_handler(void) 139void 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