summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Purchase <shotofadds@rockbox.org>2008-03-22 19:41:51 +0000
committerRob Purchase <shotofadds@rockbox.org>2008-03-22 19:41:51 +0000
commit4dc2d8ddba2b1a4da44864b10de628bc45b8f653 (patch)
tree83339568f95ead3ddf22e2911faaba52bd276d65
parentf061ba4ebbfcefb4613ea726104c1b3f9f1a528d (diff)
downloadrockbox-4dc2d8ddba2b1a4da44864b10de628bc45b8f653.tar.gz
rockbox-4dc2d8ddba2b1a4da44864b10de628bc45b8f653.zip
Enable tick IRQs on TCC780x. The main menu is now working on the D2.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16749 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--bootloader/telechips.c4
-rw-r--r--firmware/export/tcc780x.h9
-rw-r--r--firmware/target/arm/tcc780x/crt0.S83
-rw-r--r--firmware/target/arm/tcc780x/kernel-tcc780x.c6
-rw-r--r--firmware/target/arm/tcc780x/system-tcc780x.c144
-rw-r--r--firmware/target/arm/tcc780x/timer-tcc780x.c4
6 files changed, 162 insertions, 88 deletions
diff --git a/bootloader/telechips.c b/bootloader/telechips.c
index 8d2e36914b..305bdf3081 100644
--- a/bootloader/telechips.c
+++ b/bootloader/telechips.c
@@ -67,10 +67,6 @@ void* main(void)
67 power_init(); 67 power_init();
68 system_init(); 68 system_init();
69 lcd_init(); 69 lcd_init();
70
71#if defined(COWON_D2)
72 kernel_init();
73#endif
74 70
75 adc_init(); 71 adc_init();
76 button_init(); 72 button_init();
diff --git a/firmware/export/tcc780x.h b/firmware/export/tcc780x.h
index 78211acf0a..89c2fdd9c4 100644
--- a/firmware/export/tcc780x.h
+++ b/firmware/export/tcc780x.h
@@ -107,15 +107,22 @@
107#define CREQ (*(volatile unsigned long *)0xF3001004) 107#define CREQ (*(volatile unsigned long *)0xF3001004)
108#define IRQSEL (*(volatile unsigned long *)0xF300100C) 108#define IRQSEL (*(volatile unsigned long *)0xF300100C)
109#define MREQ (*(volatile unsigned long *)0xF3001014) 109#define MREQ (*(volatile unsigned long *)0xF3001014)
110#define POL (*(volatile unsigned long *)0xF300101C)
110#define MIRQ (*(volatile unsigned long *)0xF3001028) 111#define MIRQ (*(volatile unsigned long *)0xF3001028)
111#define MFIQ (*(volatile unsigned long *)0xF300102C) 112#define MFIQ (*(volatile unsigned long *)0xF300102C)
113#define MODE (*(volatile unsigned long *)0xF3001030)
112#define ALLMASK (*(volatile unsigned long *)0xF3001044) 114#define ALLMASK (*(volatile unsigned long *)0xF3001044)
113#define VAIRQ (*(volatile unsigned long *)0xF3001080) 115#define VAIRQ (*(volatile unsigned long *)0xF3001080)
114#define VAFIQ (*(volatile unsigned long *)0xF3001084) 116#define VAFIQ (*(volatile unsigned long *)0xF3001084)
115#define VNIRQ (*(volatile unsigned long *)0xF3001088) 117#define VNIRQ (*(volatile unsigned long *)0xF3001088)
116#define VNFIQ (*(volatile unsigned long *)0xF300108C) 118#define VNFIQ (*(volatile unsigned long *)0xF300108C)
119#define VCTRL (*(volatile unsigned long *)0xF3001090)
117 120
118#define TIMER_IRQ_MASK (1<<6) 121#define IRQ_PRIORITY_TABLE ((volatile unsigned int *)0xF30010A0)
122
123#define TIMER0_IRQ_MASK (1<<6)
124#define DAI_RX_IRQ_MASK (1<<14)
125#define DAI_TX_IRQ_MASK (1<<15)
119 126
120/* Timer / Counters */ 127/* Timer / Counters */
121 128
diff --git a/firmware/target/arm/tcc780x/crt0.S b/firmware/target/arm/tcc780x/crt0.S
index af37b40814..05a8868d51 100644
--- a/firmware/target/arm/tcc780x/crt0.S
+++ b/firmware/target/arm/tcc780x/crt0.S
@@ -121,6 +121,52 @@ copied_start:
121 msr cpsr, r0 121 msr cpsr, r0
122 ldr sp, =stackend 122 ldr sp, =stackend
123 123
124 /* Enable MMU & caches. At present this is just doing what the OF does.
125 Ensure TCMs are enabled before copying the exception vectors to 0x0. */
126
127 mov r1, #0xf7000000 /* Virtual MMU Table base */
128
129 ldr r0, =0x1fe0c /* Region 0: 0x00000000-0xffffffff (4Gb) */
130 str r0, [r1] /* AP: 3 EN: 1 DO: 0 CACHE_ALL */
131
132 ldr r0, =0x2801ae24 /* Region 1: 0x28000000-0x2fffffff (128Mb) */
133 str r0, [r1,#4] /* AP: 3 EN: 1 DO: 1 BUFFERED */
134
135 ldr r0, =0x13e44 /* Region 2: 0x00000000-0x000fffff (1Mb) */
136 str r0, [r1,#8] /* AP: 3 EN: 1 DO: 2 BUFFERED */
137
138 ldr r0, =0x4001ce60 /* Region 3: 0x40000000-0x5fffffff (512Mb) */
139 str r0, [r1,#0xc] /* AP: 3 EN: 1 DO: 3 CACHE_NONE */
140
141 ldr r0, =0x6001be80 /* Region 4: 0x60000000-0x6fffffff (256Mb) */
142 str r0, [r1,#0x10] /* AP: 3 EN: 1 DO: 4 CACHE_NONE */
143
144 ldr r0, =0x3801aea4 /* Region 5: 0x38000000-0x3fffffff (128Mb) */
145 str r0, [r1,#0x14] /* AP: 3 EN: 1 DO: 5 BUFFERED */
146
147 ldr r0, =0x8001eec0 /* Region 6: 0x80000000-0xffffffff (2Gb) */
148 str r0, [r1,#0x18] /* AP: 3 EN: 1 DO: 6 CACHE_NONE */
149
150 ldr r0, =0x1001aee0 /* Region 7: 0x10000000-0x17ffffff (128Mb) */
151 str r0, [r1,#0x1c] /* AP: 3 EN: 1 DO: 7 CACHE_NONE */
152
153 add r1, r1, #0x8000
154 mcr p15, 0, r1, c2, c0, 0 /* Set TTBR = TABBASE (Virtual TLB) */
155
156 ldr r0, =0x55555555
157 mcr p15, 0, r0, c3, c0, 0 /* Domain access d0-d15 = 'client' */
158
159 ldr r0, =0xa0000011
160 mcr p15, 0, r0, c9, c1, 0 /* Data TCM: 0xA0000000-0xA00001fff (8Kb) */
161 mov r0, #0xd
162 mcr p15, 0, r0, c9, c1, 1 /* Instr. TCM: 0x00000000-0x00000fff (4Kb) */
163
164 mov r0, #0
165 mcr p15, 0, r0, c7, c5, 0 /* Invalidate Icache */
166 ldr r2, =0x5507d
167 mcr p15, 0, r2, c1, c0, 0 /* Enable MMU, I & D caches */
168 mcr p15, 0, r0, c7, c6, 0 /* Invalidate Dcache */
169 mcr p15, 0, r1, c8, c7, 0 /* Invalidate TLB */
124 170
125#if !defined(BOOTLOADER) && !defined(STUB) 171#if !defined(BOOTLOADER) && !defined(STUB)
126 172
@@ -193,43 +239,6 @@ copied_start:
193 strhi r4, [r2], #4 239 strhi r4, [r2], #4
194 bhi 1b 240 bhi 1b
195 241
196 /*
197 Enable cache & TCM regions
198 TODO: This is just doing what the OF does at present. It needs to be
199 better understood and moved out to a separate MMU functions package.
200 */
201 ldr r1, =0x1fe0c
202 mov r0, #0xf7000000
203 str r1, [r0]
204 ldr r1, =0x2801ae24
205 str r1, [r0,#4]
206 ldr r1, =0x13e44
207 str r1, [r0,#8]
208 ldr r1, =0x4001ce60
209 str r1, [r0,#0xc]
210 ldr r1, =0x6001be80
211 str r1, [r0,#0x10]
212 ldr r1, =0x3801aea4
213 str r1, [r0,#0x14]
214 ldr r1, =0x8001eec0
215 str r1, [r0,#0x18]
216 ldr r1, =0x1001aee0
217 str r1, [r0,#0x1c]
218 add r1, r0, #0x8000 /* r1 now = 0xf7008000 */
219 ldr r0, =0xa0000011
220 ldr r2, =0x5507d
221 mcr p15, 0, r0,c9,c1 /* data tcm region (enabled; 8kb; 0xa0000000) */
222 mov r0, #0xd
223 mcr p15, 0, r0,c9,c1, 1 /* inst tcm region (enabled, 4kb, 0x00000000) */
224 ldr r0, =0x55555555
225 mcr p15, 0, r1,c2,c0 /* translation table base register = 0xf7008000 */
226 mcr p15, 0, r0,c3,c0 /* domain access d0-d15 = 'client' */
227 mov r0, #0
228 mcr p15, 0, r0,c7,c5 /* invalidate icache */
229 mcr p15, 0, r2,c1,c0 /* enable mmu, i & d caches */
230 mcr p15, 0, r0,c7,c6 /* invalidate dcache */
231 mcr p15, 0, r1,c8,c7 /* invalidate tlb */
232
233 bl main 242 bl main
234 /* main() should never return */ 243 /* main() should never return */
235 244
diff --git a/firmware/target/arm/tcc780x/kernel-tcc780x.c b/firmware/target/arm/tcc780x/kernel-tcc780x.c
index e0d9c3342e..333823eef9 100644
--- a/firmware/target/arm/tcc780x/kernel-tcc780x.c
+++ b/firmware/target/arm/tcc780x/kernel-tcc780x.c
@@ -36,8 +36,8 @@ void tick_start(unsigned int interval_in_ms)
36 TCFG0 = (1<<8) | (0<<4) | (1<<3) | 1; 36 TCFG0 = (1<<8) | (0<<4) | (1<<3) | 1;
37 37
38 /* Unmask timer IRQ */ 38 /* Unmask timer IRQ */
39 MIRQ &= ~TIMER_IRQ_MASK; 39 IEN |= TIMER0_IRQ_MASK;
40} 40}
41 41
42/* NB: Since the 7801 has a single timer IRQ, the tick tasks are dispatched 42/* NB: Since we are using a single timer IRQ, tick tasks are dispatched as
43 as part of the central timer IRQ processing in timer-tcc780x.c */ 43 part of the central timer IRQ processing in timer-tcc780x.c */
diff --git a/firmware/target/arm/tcc780x/system-tcc780x.c b/firmware/target/arm/tcc780x/system-tcc780x.c
index 30221d180e..cf4256e879 100644
--- a/firmware/target/arm/tcc780x/system-tcc780x.c
+++ b/firmware/target/arm/tcc780x/system-tcc780x.c
@@ -33,49 +33,86 @@ default_interrupt(EXT0);
33default_interrupt(EXT1); 33default_interrupt(EXT1);
34default_interrupt(EXT2); 34default_interrupt(EXT2);
35default_interrupt(EXT3); 35default_interrupt(EXT3);
36default_interrupt(IRQ4); 36default_interrupt(RTC);
37default_interrupt(IRQ5); 37default_interrupt(GPSB0);
38default_interrupt(TIMER); 38default_interrupt(TIMER0);
39default_interrupt(IRQ7); 39default_interrupt(TIMER1);
40default_interrupt(IRQ8); 40default_interrupt(SCORE);
41default_interrupt(IRQ9); 41default_interrupt(SPDTX);
42default_interrupt(IRQ10); 42default_interrupt(VIDEO);
43default_interrupt(IRQ11); 43default_interrupt(GSIO);
44default_interrupt(IRQ12); 44default_interrupt(SCALER);
45default_interrupt(IRQ13); 45default_interrupt(I2C);
46default_interrupt(DAI_RX); 46default_interrupt(DAI_RX);
47default_interrupt(DAI_TX); 47default_interrupt(DAI_TX);
48default_interrupt(IRQ16); 48default_interrupt(CDRX);
49default_interrupt(IRQ17); 49default_interrupt(HPI);
50default_interrupt(IRQ18); 50default_interrupt(UART0);
51default_interrupt(IRQ19); 51default_interrupt(UART1);
52default_interrupt(IRQ20); 52default_interrupt(G2D);
53default_interrupt(IRQ21); 53default_interrupt(USB_DEVICE);
54default_interrupt(IRQ22); 54default_interrupt(USB_HOST);
55default_interrupt(IRQ23); 55default_interrupt(DMA);
56default_interrupt(IRQ24); 56default_interrupt(HDD);
57default_interrupt(IRQ25); 57default_interrupt(MSTICK);
58default_interrupt(IRQ26); 58default_interrupt(NFC);
59default_interrupt(IRQ27); 59default_interrupt(SDMMC);
60default_interrupt(IRQ28); 60default_interrupt(CAM);
61default_interrupt(IRQ29); 61default_interrupt(LCD);
62default_interrupt(IRQ30); 62default_interrupt(ADC);
63default_interrupt(IRQ31); 63default_interrupt(GPSB1);
64
65/* TODO: Establish IRQ priorities (0 = highest priority) */
66static const char irqpriority[] =
67{
68 0, /* EXT0 */
69 1, /* EXT1 */
70 2, /* EXT2 */
71 3, /* EXT3 */
72 4, /* RTC */
73 5, /* GPSB0 */
74 6, /* TIMER0 */
75 7, /* TIMER1 */
76 8, /* SCORE */
77 9, /* SPDTX */
78 10, /* VIDEO */
79 11, /* GSIO */
80 12, /* SCALER */
81 13, /* I2C */
82 14, /* DAI_RX */
83 15, /* DAI_TX */
84 16, /* CDRX */
85 17, /* HPI */
86 18, /* UART0 */
87 19, /* UART1 */
88 20, /* G2D */
89 21, /* USB_DEVICE */
90 22, /* USB_HOST */
91 23, /* DMA */
92 24, /* HDD */
93 25, /* MSTICK */
94 26, /* NFC */
95 27, /* SDMMC */
96 28, /* CAM */
97 29, /* LCD */
98 30, /* ADC */
99 31, /* GPSB */
100};
64 101
65static void (* const irqvector[])(void) = 102static void (* const irqvector[])(void) =
66{ 103{
67 EXT0,EXT1,EXT2,EXT3,IRQ4,IRQ5,TIMER,IRQ7, 104 EXT0,EXT1,EXT2,EXT3,RTC,GPSB0,TIMER0,TIMER1,
68 IRQ8,IRQ9,IRQ10,IRQ11,IRQ12,IRQ13,DAI_RX,DAI_TX, 105 SCORE,SPDTX,VIDEO,GSIO,SCALER,I2C,DAI_RX,DAI_TX,
69 IRQ16,IRQ17,IRQ18,IRQ19,IRQ20,IRQ21,IRQ22,IRQ23, 106 CDRX,HPI,UART0,UART1,G2D,USB_DEVICE,USB_HOST,DMA,
70 IRQ24,IRQ25,IRQ26,IRQ27,IRQ28,IRQ29,IRQ30,IRQ31 107 HDD,MSTICK,NFC,SDMMC,CAM,LCD,ADC,GPSB1
71}; 108};
72 109
73static const char * const irqname[] = 110static const char * const irqname[] =
74{ 111{
75 "EXT0","EXT1","EXT2","EXT3","IRQ4","IRQ5","TIMER","IRQ7", 112 "EXT0","EXT1","EXT2","EXT3","RTC","GPSB0","TIMER0","TIMER1",
76 "IRQ8","IRQ9","IRQ10","IRQ11","IRQ12","IRQ13","DAI_RX","DAI_TX", 113 "SCORE","SPDTX","VIDEO","GSIO","SCALER","I2C","DAI_RX","DAI_TX",
77 "IRQ16","IRQ17","IRQ18","IRQ19","IRQ20","IRQ21","IRQ22","IRQ23", 114 "CDRX","HPI","UART0","UART1","G2D","USB_DEVICE","USB_HOST","DMA",
78 "IRQ24","IRQ25","IRQ26","IRQ27","IRQ28","IRQ29","IRQ30","IRQ31" 115 "HDD","MSTICK","NFC","SDMMC","CAM","LCD","ADC","GPSB1"
79}; 116};
80 117
81static void UIRQ(void) 118static void UIRQ(void)
@@ -92,17 +129,23 @@ void irq_handler(void)
92 129
93 asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ 130 asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */
94 "sub sp, sp, #8 \n"); /* Reserve stack */ 131 "sub sp, sp, #8 \n"); /* Reserve stack */
95 irqvector[VNIRQ](); 132
133 int irq_no = VNIRQ; /* Read clears the corresponding IRQ status */
134
135 if ((irq_no & (1<<31)) == 0) /* Ensure invalid flag is not set */
136 {
137 irqvector[irq_no]();
138 }
139
96 asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */ 140 asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */
97 "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ 141 "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */
98 "subs pc, lr, #4 \n"); /* Return from FIQ */ 142 "subs pc, lr, #4 \n"); /* Return from IRQ */
99} 143}
100 144
101void fiq_handler(void) 145void fiq_handler(void)
102{ 146{
103 asm volatile ( 147 asm volatile (
104 "sub lr, lr, #4 \r\n" 148 "subs pc, lr, #4 \r\n"
105 "movs lr,pc \r\n"
106 ); 149 );
107} 150}
108#endif /* !defined(BOOTLOADER) */ 151#endif /* !defined(BOOTLOADER) */
@@ -231,15 +274,36 @@ static void clock_init(void)
231#ifdef COWON_D2 274#ifdef COWON_D2
232void system_init(void) 275void system_init(void)
233{ 276{
277 int i;
278
234 MBCFG = 0x19; 279 MBCFG = 0x19;
235 280
236 if (TCC780_VER == 0) 281 if (TCC780_VER == 0)
237 ECFG0 = 0x309; 282 ECFG0 = 0x309;
238 else 283 else
239 ECFG0 = 0x30d; 284 ECFG0 = 0x30d;
240 285
241 /* mask all interrupts */ 286 /* mask all interrupts */
242 MIRQ = -1; 287 IEN = 0;
288
289#if !defined(BOOTLOADER)
290
291 IRQSEL = -1; /* set all interrupts to be IRQs not FIQs */
292
293 POL = 0x200108; /* IRQs 3,8,21 active low (as OF) */
294 MODE = 0x20ce07c0; /* IRQs 6-10,17-19,22-23,29 level-triggered (as OF) */
295
296 VCTRL |= (1<<31); /* Reading from VNIRQ clears that interrupt */
297
298 /* Write IRQ priority registers using ints - a freeze occurs otherwise */
299 for (i = 0; i < 7; i++)
300 {
301 IRQ_PRIORITY_TABLE[i] = ((int*)irqpriority)[i];
302 }
303
304 ALLMASK = 3; /* Global FIQ/IRQ unmask */
305
306#endif /* !defined(BOOTLOADER) */
243 307
244 gpio_init(); 308 gpio_init();
245 clock_init(); 309 clock_init();
diff --git a/firmware/target/arm/tcc780x/timer-tcc780x.c b/firmware/target/arm/tcc780x/timer-tcc780x.c
index c724c4b3a8..44a4cc0395 100644
--- a/firmware/target/arm/tcc780x/timer-tcc780x.c
+++ b/firmware/target/arm/tcc780x/timer-tcc780x.c
@@ -52,7 +52,7 @@ void __timer_unregister(void)
52 52
53extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 53extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
54 54
55void TIMER(void) 55void TIMER0(void)
56{ 56{
57 if (TIREQ & TF0) /* Timer0 reached ref value */ 57 if (TIREQ & TF0) /* Timer0 reached ref value */
58 { 58 {
@@ -77,6 +77,4 @@ void TIMER(void)
77 { 77 {
78 /* dispatch timer */ 78 /* dispatch timer */
79 } 79 }
80
81 CREQ |= TIMER_IRQ_MASK; /* clear IRQ */
82} 80}