diff options
Diffstat (limited to 'firmware/target/arm/imx31')
-rw-r--r-- | firmware/target/arm/imx31/crt0.S | 422 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | 305 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | 124 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c | 55 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S | 222 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c | 224 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c | 4 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c | 8 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-imx31.c | 18 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-target.h | 20 |
10 files changed, 528 insertions, 874 deletions
diff --git a/firmware/target/arm/imx31/crt0.S b/firmware/target/arm/imx31/crt0.S index 2be2510bbd..9d50888536 100644 --- a/firmware/target/arm/imx31/crt0.S +++ b/firmware/target/arm/imx31/crt0.S | |||
@@ -24,7 +24,7 @@ | |||
24 | .global start | 24 | .global start |
25 | start: | 25 | start: |
26 | b newstart | 26 | b newstart |
27 | .space 4*16 | 27 | .space 4*12 /* Space for low vectors */ |
28 | 28 | ||
29 | 29 | ||
30 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader | 30 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader |
@@ -35,86 +35,53 @@ start: | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | newstart: | 37 | newstart: |
38 | msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ */ | 38 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ |
39 | 39 | ||
40 | #if !defined(BOOTLOADER) | 40 | #ifdef BOOTLOADER |
41 | #if !defined(DEBUG) | 41 | ldr r2, =remap_start |
42 | /* Copy exception handler code to address 0 */ | 42 | ldr r3, =remap_end |
43 | ldr r2, =_vectorsstart | 43 | ldr r5, =TTB_BASE_ADDR /* TTB pointer */ |
44 | ldr r3, =_vectorsend | 44 | ldr r6, =IRAM_BASE_ADDR |
45 | ldr r4, =_vectorscopy | 45 | mov r1, r6 |
46 | 1: | 46 | |
47 | cmp r3, r2 | 47 | 1: |
48 | ldrhi r5, [r4], #4 | 48 | cmp r3, r2 |
49 | strhi r5, [r2], #4 | 49 | ldrhi r4, [r2], #4 |
50 | bhi 1b | 50 | strhi r4, [r1], #4 |
51 | #else | 51 | bhi 1b |
52 | ldr r1, =vectors | 52 | |
53 | ldr r0, =irq_handler | 53 | mov pc, r6 |
54 | str r0, [r1, #24] | ||
55 | ldr r0, =fiq_handler | ||
56 | str r0, [r1, #28] | ||
57 | #endif | ||
58 | |||
59 | /* Zero out IBSS */ | ||
60 | ldr r2, =_iedata | ||
61 | ldr r3, =_iend | ||
62 | mov r4, #0 | ||
63 | 1: | ||
64 | cmp r3, r2 | ||
65 | strhi r4, [r2], #4 | ||
66 | bhi 1b | ||
67 | |||
68 | /* Copy the IRAM */ | ||
69 | ldr r2, =_iramcopy | ||
70 | ldr r3, =_iramstart | ||
71 | ldr r4, =_iramend | ||
72 | 1: | ||
73 | cmp r4, r3 | ||
74 | ldrhi r5, [r2], #4 | ||
75 | strhi r5, [r3], #4 | ||
76 | bhi 1b | ||
77 | #endif /* !BOOTLOADER */ | ||
78 | |||
79 | /* Initialise bss section to zero */ | ||
80 | ldr r2, =_edata | ||
81 | ldr r3, =_end | ||
82 | mov r4, #0 | ||
83 | 1: | ||
84 | cmp r3, r2 | ||
85 | strhi r4, [r2], #4 | ||
86 | bhi 1b | ||
87 | 54 | ||
88 | /* Set up some stack and munge it with 0xdeadbeef */ | 55 | remap_start: |
89 | ldr sp, =stackend | 56 | mrc p15, 0, r3, c1, c0, 0 /* perform writeback if D cache is enabled */ |
90 | mov r3, sp | 57 | tst r3, #(1 << 2) |
91 | ldr r2, =stackbegin | 58 | tsteq r3, #(1 << 12) |
92 | ldr r4, =0xdeadbeef | 59 | mcrne p15, 0, r0, c7, c10, 0 /* clean dcache */ |
93 | 1: | 60 | mov r0, #0 |
94 | cmp r3, r2 | 61 | mcrne p15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */ |
95 | strhi r4, [r2], #4 | 62 | mcr p15, 0, r0, c8, c7, 0 /* invalidate TLBs */ |
96 | bhi 1b | 63 | mcr p15, 0, r0, c7, c10, 4 /* Drain the write buffer */ |
97 | 64 | ||
98 | #ifdef BOOTLOADER | 65 | mcr p15, 0, r0, c13, c0, 0 |
99 | /* Code for ARM bootloader targets other than iPod go here */ | 66 | mcr p15, 0, r0, c13, c0, 1 |
100 | |||
101 | mov r0, #0 | ||
102 | mcr 15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */ | ||
103 | mcr 15, 0, r0, c8, c7, 0 /* invalidate TLBs */ | ||
104 | mcr 15, 0, r0, c7, c10, 4 /* Drain the write buffer */ | ||
105 | 67 | ||
106 | /* Also setup the Peripheral Port Remap register inside the core */ | 68 | /* Also setup the Peripheral Port Remap register inside the core */ |
107 | ldr r0, =0x40000015 /* start from AIPS 2GB region */ | 69 | mov r0, #0x40000000 /* start from AIPS 2GB region */ |
108 | mcr p15, 0, r0, c15, c2, 4 | 70 | add r0, r0, #0x15 |
71 | mcr p15, 0, r0, c15, c2, 4 | ||
109 | 72 | ||
110 | /*** L2 Cache setup/invalidation/disable ***/ | 73 | /*** L2 Cache setup/invalidation/disable ***/ |
111 | /* Disable L2 cache first */ | 74 | /* Disable L2 cache first */ |
112 | ldr r0, =L2CC_BASE_ADDR | 75 | mov r0, #L2CC_BASE_ADDR |
113 | ldr r2, [r0, #L2_CACHE_CTL_REG] | 76 | mov r1, #0 |
114 | bic r2, r2, #0x1 | 77 | str r1, [r0, #L2_CACHE_CTL_REG] |
115 | str r2, [r0, #L2_CACHE_CTL_REG] | 78 | |
116 | 79 | /* Disble L1 caches and memory manager */ | |
117 | 80 | bic r3, r3, #(1 << 1) | |
81 | bic r3, r3, #(1 << 2) | ||
82 | bic r3, r3, #(1 << 12) | ||
83 | mcr p15, 0, r3, c1, c0, 0 | ||
84 | |||
118 | /* | 85 | /* |
119 | * Configure L2 Cache: | 86 | * Configure L2 Cache: |
120 | * - 128k size(16k way) | 87 | * - 128k size(16k way) |
@@ -122,42 +89,21 @@ newstart: | |||
122 | * - 0 ws TAG/VALID/DIRTY | 89 | * - 0 ws TAG/VALID/DIRTY |
123 | * - 4 ws DATA R/W | 90 | * - 4 ws DATA R/W |
124 | */ | 91 | */ |
125 | ldr r1, [r0, #L2_CACHE_AUX_CTL_REG] | 92 | mov r1, #0x00130000 |
126 | and r1, r1, #0xFE000000 | 93 | orr r1, r1, #0x24 |
127 | ldr r2, =0x00030024 | 94 | str r1, [r0, #L2_CACHE_AUX_CTL_REG] |
128 | orr r1, r1, r2 | ||
129 | str r1, [r0, #L2_CACHE_AUX_CTL_REG] | ||
130 | 95 | ||
131 | /* Invalidate L2 */ | 96 | /* Invalidate L2 */ |
132 | ldr r1, =0x000000FF | 97 | mov r1, #0x000000FF |
133 | str r1, [r0, #L2_CACHE_INV_WAY_REG] | 98 | str r1, [r0, #L2_CACHE_INV_WAY_REG] |
134 | L2_loop: | 99 | L2_loop: |
135 | /* Poll Invalidate By Way register */ | 100 | /* Poll Invalidate By Way register */ |
136 | ldr r2, [r0, #L2_CACHE_INV_WAY_REG] | 101 | ldr r2, [r0, #L2_CACHE_INV_WAY_REG] |
137 | cmp r2, #0 | 102 | cmp r2, #0 |
138 | bne L2_loop | 103 | bne L2_loop |
104 | |||
139 | /*** End of L2 operations ***/ | 105 | /*** End of L2 operations ***/ |
140 | /* Set up stack for IRQ mode */ | ||
141 | mov r0,#0xd2 | ||
142 | msr cpsr, r0 | ||
143 | ldr sp, =irq_stack | ||
144 | /* Set up stack for FIQ mode */ | ||
145 | mov r0,#0xd1 | ||
146 | msr cpsr, r0 | ||
147 | ldr sp, =fiq_stack | ||
148 | 106 | ||
149 | /* Let abort and undefined modes use IRQ stack */ | ||
150 | mov r0,#0xd7 | ||
151 | msr cpsr, r0 | ||
152 | ldr sp, =irq_stack | ||
153 | mov r0,#0xdb | ||
154 | msr cpsr, r0 | ||
155 | ldr sp, =irq_stack | ||
156 | /* Switch to supervisor mode */ | ||
157 | mov r0,#0xd3 | ||
158 | msr cpsr, r0 | ||
159 | ldr sp, =stackend | ||
160 | |||
161 | /*remap memory as well as exception vectors*/ | 107 | /*remap memory as well as exception vectors*/ |
162 | /*for now this will be done in bootloader, especially | 108 | /*for now this will be done in bootloader, especially |
163 | if usb will be needed within the bootloader to load the | 109 | if usb will be needed within the bootloader to load the |
@@ -165,172 +111,155 @@ L2_loop: | |||
165 | (whether they be swi or irq)*/ | 111 | (whether they be swi or irq)*/ |
166 | 112 | ||
167 | /* TTB Initialisation */ | 113 | /* TTB Initialisation */ |
168 | ldr r3, =(0x80000000+64*1024*1024-TTB_SIZE) | 114 | mov r3, r5 |
169 | mov r1, #0 | 115 | add r2, r3, #TTB_SIZE |
170 | ldr r2, =(0x80000000+64*1024*1024) | 116 | mov r1, #0 |
171 | ttbloop: | 117 | ttbloop: |
172 | str r1, [r3], #4 | 118 | str r1, [r3], #4 |
173 | cmp r3, r2 | 119 | cmp r3, r2 |
174 | bne ttbloop | 120 | bne ttbloop |
175 | 121 | ||
176 | /* Set TTB base address */ | 122 | /* Set TTB base address */ |
177 | ldr r3, =(0x80000000+64*1024*1024-TTB_SIZE) | 123 | mov r3, r5 |
178 | mcr 15, 0 ,r3, cr2, cr0, 0 | 124 | mcr p15, 0, r3, c2, c0, 0 |
179 | /* Set all domains to manager status */ | 125 | /* Set all domains to manager status */ |
180 | mvn r3, #0 | 126 | mvn r3, #0 |
181 | mcr 15, 0, r3, cr3, cr0, 0 | 127 | mcr p15, 0, r3, c3, c0, 0 |
182 | 128 | ||
183 | /* Set page tables */ | 129 | /* Set page tables */ |
184 | 130 | ||
185 | /* Map each memory loc to itself, no cache */ | 131 | /* Map each memory loc to itself, no cache */ |
186 | mov r1, #0 /* Physical address */ | 132 | mov r1, #0 /* Physical address */ |
187 | ldr r3, =(0x80000000+64*1024*1024-TTB_SIZE) /* TTB pointer */ | 133 | mov r3, r5 |
188 | ldr r4, =(0x80000000+64*1024*1024-TTB_SIZE+0x4000) /* End position */ | 134 | add r4, r3, #TTB_SIZE /* End position */ |
189 | maploop1: | 135 | maploop1: |
190 | mov r2, r1 | 136 | mov r2, r1 |
191 | orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ | 137 | orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ |
192 | //orr r2, r2, #(0<<5) /* domain 0th */ | 138 | //orr r2, r2, #(0<<5) /* domain 0th */ |
193 | orr r2, r2, #(1<<4) /* should be "1" */ | 139 | orr r2, r2, #(1<<4) /* should be "1" */ |
194 | orr r2, r2, #(1<<1) /* Section signature */ | 140 | orr r2, r2, #(1<<1) /* Section signature */ |
195 | str r2, [r3], #4 | 141 | str r2, [r3], #4 |
196 | add r1, r1, #(1<<20) | 142 | add r1, r1, #(1<<20) |
197 | cmp r3, r4 | 143 | cmp r3, r4 |
198 | bne maploop1 | 144 | bne maploop1 |
199 | 145 | ||
200 | /* Map 0x80000000 -> 0x0, cached */ | 146 | /* Map 0x80000000 -> 0x0, cached */ |
201 | mov r1, #0x80000000 /* Physical address */ | 147 | mov r1, #0x80000000 /* Physical address */ |
202 | ldr r3, =(0x80000000+64*1024*1024-TTB_SIZE) /* TTB pointer */ | 148 | mov r3, r5 /* TTB pointer */ |
203 | ldr r4, =(0x80000000+64*1024*1024-TTB_SIZE+256) /* End position */ | 149 | add r4, r3, #64*4 /* End position */ |
204 | maploop2: | 150 | maploop2: |
205 | mov r2, r1 | 151 | mov r2, r1 |
206 | orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ | 152 | orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ |
207 | //orr r2, r2, #(0<<5) /* domain 0th */ | 153 | //orr r2, r2, #(0<<5) /* domain 0th */ |
208 | orr r2, r2, #(1<<4) /* should be "1" */ | 154 | orr r2, r2, #(1<<4) /* should be "1" */ |
209 | orr r2, r2, #(1<<3) /* cache flags */ | 155 | orr r2, r2, #(1<<3) /* cache flags */ |
210 | orr r2, r2, #(1<<2) /* more cache stuff */ | 156 | orr r2, r2, #(1<<2) /* more cache stuff */ |
211 | orr r2, r2, #(1<<1) /* Section signature */ | 157 | orr r2, r2, #(1<<1) /* Section signature */ |
212 | str r2, [r3], #4 | 158 | str r2, [r3], #4 |
213 | add r1, r1, #(1<<20) | 159 | add r1, r1, #(1<<20) |
214 | cmp r3, r4 | 160 | bic r6, r1, #0xf0000000 |
215 | bne maploop2 | 161 | cmp r6, #0x00100000 /* Skip framebuffer */ |
162 | addeq r1, r1, #(1<<20) | ||
163 | cmp r3, r4 | ||
164 | bne maploop2 | ||
216 | 165 | ||
217 | /* Enable MMU */ | 166 | /* Enable MMU */ |
218 | mrc 15, 0, r3, cr1, cr0, 0 | 167 | |
219 | tst r3, #0x4 | 168 | mov r0, #0 |
220 | bleq clean_dcache | 169 | mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLB */ |
221 | tst r3, #0x1000 | 170 | mcr p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */ |
222 | bleq clean_dcache | 171 | #if 1 |
223 | mov r0, #0 | 172 | mrc p15, 0, r0, c1, c0, 1 |
224 | 173 | bic r0, r0, #0x70 | |
225 | mcr 15, 0, r0, cr8, cr7, 0 /* Invalidate TLB */ | 174 | bic r0, r0, #0x07 |
226 | mcr 15, 0, r0, cr7, cr7, 0 /* Invalidate icache and dcache */ | 175 | mcr p15, 0, r0, c1, c0, 1 |
227 | mrc 15, 0, r0, cr1, cr0, 0 | 176 | #endif |
228 | orr r0, r0, #1 /* enable mmu bit */ | 177 | mrc p15, 0, r0, c1, c0, 0 |
229 | orr r0, r0, #(1<<2) /* enable dcache */ | 178 | orr r0, r0, #(1 << 0) /* enable mmu bit */ |
230 | orr r0, r0, #(1<<12) /* enable icache */ | 179 | orr r0, r0, #(1 << 2) /* enable dcache */ |
231 | mcr 15, 0, r0, cr1, cr0, 0 | 180 | bic r0, r0, #(1 << 11) /* no program flow prediction */ |
181 | orr r0, r0, #(1 << 12) /* enable icache */ | ||
182 | bic r0, r0, #(1 << 13) /* low vectors */ | ||
183 | orr r0, r0, #(1 << 14) /* Round-robin */ | ||
184 | bic r0, r0, #(1 << 21) /* No low latency interrupt */ | ||
185 | mcr p15, 0, r0, c1, c0, 0 | ||
232 | nop | 186 | nop |
233 | nop | 187 | nop |
234 | nop | 188 | nop |
235 | nop | 189 | nop |
190 | ldr pc, L_post_remap | ||
191 | L_post_remap: | ||
192 | .word remap_end | ||
193 | remap_end: | ||
236 | 194 | ||
237 | mov r0,#0 | 195 | #endif /* BOOTLOADER */ |
238 | ldr r1,=_vectorstart | ||
239 | mov r2,#0 | ||
240 | |||
241 | lp: ldr r3,[r1] | ||
242 | add r1,r1,#4 | ||
243 | str r3,[r0] | ||
244 | add r0,r0,#4 | ||
245 | add r2,r2,#1 | ||
246 | cmp r2,#16 | ||
247 | bne lp | ||
248 | bl main | ||
249 | |||
250 | .section .vectors,"aw" | ||
251 | _vectorstart: | ||
252 | ldr pc, [pc, #24] | ||
253 | ldr pc, [pc, #24] | ||
254 | ldr pc, [pc, #24] | ||
255 | ldr pc, [pc, #24] | ||
256 | ldr pc, [pc, #24] | ||
257 | ldr pc, [pc, #24] | ||
258 | ldr pc, [pc, #24] | ||
259 | ldr pc, [pc, #24] | ||
260 | |||
261 | /* Exception vectors */ | ||
262 | .global vectors | ||
263 | vectors: | ||
264 | .word start | ||
265 | .word undef_instr_handler | ||
266 | .word software_int_handler | ||
267 | .word prefetch_abort_handler | ||
268 | .word data_abort_handler | ||
269 | .word reserved_handler | ||
270 | .word irqz | ||
271 | .word fiqz | ||
272 | |||
273 | .text | ||
274 | .global irq | ||
275 | .global fiq | ||
276 | .global UIE | ||
277 | |||
278 | undef_instr_handler: | ||
279 | mov r0, lr | ||
280 | mov r1, #0 | ||
281 | b UIE | ||
282 | |||
283 | software_int_handler: | ||
284 | reserved_handler: | ||
285 | bl irq_handler | ||
286 | movs pc, lr | ||
287 | |||
288 | prefetch_abort_handler: | ||
289 | sub r0, lr, #4 | ||
290 | mov r1, #1 | ||
291 | b UIE | ||
292 | |||
293 | data_abort_handler: | ||
294 | sub r0, lr, #8 | ||
295 | mov r1, #2 | ||
296 | b UIE | ||
297 | |||
298 | /*not working....if we get here, let someone | ||
299 | know....*/ | ||
300 | irqz: bl irq_handler | ||
301 | fiqz: bl fiq_handler | ||
302 | |||
303 | UIE: | ||
304 | b UIE | ||
305 | 196 | ||
306 | /* 256 words of IRQ stack */ | 197 | #ifndef BOOTLOADER |
307 | .space 256*4 | 198 | /* Copy exception handler code to address 0 */ |
308 | irq_stack: | 199 | ldr r2, =_vectorsstart |
200 | ldr r3, =_vectorsend | ||
201 | ldr r4, =_vectorscopy | ||
202 | 1: | ||
203 | cmp r3, r2 | ||
204 | ldrhi r5, [r4], #4 | ||
205 | strhi r5, [r2], #4 | ||
206 | bhi 1b | ||
309 | 207 | ||
310 | /* 256 words of FIQ stack */ | 208 | /* Zero out IBSS */ |
311 | .space 256*4 | 209 | ldr r2, =_iedata |
312 | fiq_stack: | 210 | ldr r3, =_iend |
211 | mov r4, #0 | ||
212 | 1: | ||
213 | cmp r3, r2 | ||
214 | strhi r4, [r2], #4 | ||
215 | bhi 1b | ||
313 | 216 | ||
217 | /* Copy the IRAM */ | ||
218 | ldr r2, =_iramcopy | ||
219 | ldr r3, =_iramstart | ||
220 | ldr r4, =_iramend | ||
221 | 1: | ||
222 | cmp r4, r3 | ||
223 | ldrhi r5, [r2], #4 | ||
224 | strhi r5, [r3], #4 | ||
225 | bhi 1b | ||
226 | #endif /* BOOTLOADER */ | ||
314 | 227 | ||
315 | #else /* BOOTLOADER */ | 228 | /* Initialise bss section to zero */ |
229 | ldr r2, =_edata | ||
230 | ldr r3, =_end | ||
231 | mov r4, #0 | ||
232 | 1: | ||
233 | cmp r3, r2 | ||
234 | strhi r4, [r2], #4 | ||
235 | bhi 1b | ||
236 | |||
237 | /* Set up some stack and munge it with 0xdeadbeef */ | ||
238 | ldr sp, =stackend | ||
239 | ldr r2, =stackbegin | ||
240 | ldr r3, =0xdeadbeef | ||
241 | 1: | ||
242 | cmp sp, r2 | ||
243 | strhi r3, [r2], #4 | ||
244 | bhi 1b | ||
245 | |||
246 | /* Set up stack for IRQ mode */ | ||
247 | msr cpsr_c, #0xd2 | ||
248 | ldr sp, =irq_stack | ||
316 | 249 | ||
317 | /* Set up stack for IRQ mode */ | ||
318 | msr cpsr_c, #0xd2 | ||
319 | ldr sp, =irq_stack | ||
320 | /* Set up stack for FIQ mode */ | 250 | /* Set up stack for FIQ mode */ |
321 | msr cpsr_c, #0xd1 | 251 | msr cpsr_c, #0xd1 |
322 | ldr sp, =fiq_stack | 252 | ldr sp, =fiq_stack |
323 | 253 | ||
324 | /* Let abort and undefined modes use IRQ stack */ | 254 | /* Let abort and undefined modes use IRQ stack */ |
325 | msr cpsr_c, #0xd7 | 255 | msr cpsr_c, #0xd7 |
326 | ldr sp, =irq_stack | 256 | ldr sp, =irq_stack |
327 | msr cpsr_c, #0xdb | 257 | msr cpsr_c, #0xdb |
328 | ldr sp, =irq_stack | 258 | ldr sp, =irq_stack |
329 | /* Switch to supervisor mode */ | 259 | |
330 | msr cpsr_c, #0xd3 | 260 | /* Switch back to supervisor mode */ |
331 | ldr sp, =stackend | 261 | msr cpsr_c, #0xd3 |
332 | bl main | 262 | bl main |
333 | /* main() should never return */ | ||
334 | 263 | ||
335 | /* Exception handlers. Will be copied to address 0 after memory remapping */ | 264 | /* Exception handlers. Will be copied to address 0 after memory remapping */ |
336 | _vectorstart: | 265 | _vectorstart: |
@@ -358,8 +287,6 @@ vectors: | |||
358 | 287 | ||
359 | .text | 288 | .text |
360 | 289 | ||
361 | .global irq | ||
362 | .global fiq | ||
363 | .global UIE | 290 | .global UIE |
364 | 291 | ||
365 | /* All illegal exceptions call into UIE with exception address as first | 292 | /* All illegal exceptions call into UIE with exception address as first |
@@ -389,6 +316,11 @@ data_abort_handler: | |||
389 | mov r1, #2 | 316 | mov r1, #2 |
390 | b UIE | 317 | b UIE |
391 | 318 | ||
319 | #ifdef BOOTLOADER | ||
320 | UIE: | ||
321 | b UIE | ||
322 | #endif | ||
323 | |||
392 | /* 256 words of IRQ stack */ | 324 | /* 256 words of IRQ stack */ |
393 | .space 256*4 | 325 | .space 256*4 |
394 | irq_stack: | 326 | irq_stack: |
@@ -396,5 +328,3 @@ irq_stack: | |||
396 | /* 256 words of FIQ stack */ | 328 | /* 256 words of FIQ stack */ |
397 | .space 256*4 | 329 | .space 256*4 |
398 | fiq_stack: | 330 | fiq_stack: |
399 | |||
400 | #endif /* BOOTLOADER */ | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c index 8236a38014..99a52e56d5 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | |||
@@ -20,204 +20,161 @@ | |||
20 | #include "system.h" | 20 | #include "system.h" |
21 | #include "imx31l.h" | 21 | #include "imx31l.h" |
22 | #include "avic-imx31.h" | 22 | #include "avic-imx31.h" |
23 | #include "panic.h" | ||
23 | #include "debug.h" | 24 | #include "debug.h" |
24 | 25 | ||
26 | static const char * avic_int_names[64] = | ||
27 | { | ||
28 | "RESERVED0", "RESERVED1", "RESERVED2", "I2C3", | ||
29 | "I2C2", "MPEG4_ENCODER", "RTIC", "FIR", | ||
30 | "MMC/SDHC2", "MMC/SDHC1", "I2C1", "SSI2", | ||
31 | "SSI1", "CSPI2", "CSPI1", "ATA", | ||
32 | "MBX", "CSPI3", "UART3", "IIM", | ||
33 | "SIM1", "SIM2", "RNGA", "EVTMON", | ||
34 | "KPP", "RTC", "PWN", "EPIT2", | ||
35 | "EPIT1", "GPT", "PWR_FAIL", "CCM_DVFS", | ||
36 | "UART2", "NANDFC", "SDMA", "USB_HOST1", | ||
37 | "USB_HOST2", "USB_OTG", "RESERVED3", "MSHC1", | ||
38 | "MSHC2", "IPU_ERR", "IPU", "RESERVED4", | ||
39 | "RESERVED5", "UART1", "UART4", "UART5", | ||
40 | "ETC_IRQ", "SCC_SCM", "SCC_SMN", "GPIO2", | ||
41 | "GPIO1", "CCM_CLK", "PCMCIA", "WDOG", | ||
42 | "GPIO3", "RESERVED6", "EXT_PWMG", "EXT_TEMP", | ||
43 | "EXT_SENS1", "EXT_SENS2", "EXT_WDOG", "EXT_TV" | ||
44 | }; | ||
45 | |||
46 | static void UIE_VECTOR(void) | ||
47 | { | ||
48 | set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS); | ||
49 | long offset = FIVECSR; | ||
50 | long offsetn = (long)NIVECSR >> 16; | ||
51 | |||
52 | if (offsetn == -1) | ||
53 | offset = offsetn; /* Could be FIQ */ | ||
54 | |||
55 | panicf("Unhandled %s %ld: %s", | ||
56 | offsetn >= 0 ? "IRQ" : "FIQ", offset, | ||
57 | offset >= 0 ? avic_int_names[offset] : ""); | ||
58 | } | ||
59 | |||
60 | /* We use the AVIC */ | ||
61 | void __attribute__((naked)) irq_handler(void) | ||
62 | { | ||
63 | panicf("Unhandled IRQ"); | ||
64 | } | ||
65 | |||
66 | /* Accoring to section 9.3.5 of the UM, the AVIC doesn't accelerate | ||
67 | * fast interrupts and they must be dispatched */ | ||
68 | void __attribute__((naked)) fiq_handler(void) | ||
69 | { | ||
70 | asm volatile ( | ||
71 | "mov r10, #0x6c000000 \n" /* load AVIC base address */ | ||
72 | "ldr r9, [r10, #0x44] \n" /* read FIVECSR of AVIC */ | ||
73 | "add r10, r10, #100 \n" /* move pointer to base of VECTOR table */ | ||
74 | "ldr r8, [r10, r9, lsl #2] \n" /* read FIQ vector from VECTOR table */ | ||
75 | "bx r8 \n" /* jump to FIQ service routine */ | ||
76 | ); | ||
77 | } | ||
78 | |||
25 | void avic_init(void) | 79 | void avic_init(void) |
26 | { | 80 | { |
27 | /*following the steps in the AVIC setup in imx31 man*/ | 81 | /* Disable all interrupts and set to unhandled */ |
82 | avic_disable_int(ALL); | ||
28 | 83 | ||
29 | /*Initialize interrupt structures*/ | 84 | /* Init all interrupts to type IRQ */ |
30 | int i,avicstart; | 85 | avic_set_int_type(ALL, IRQ); |
31 | /*get start of avic_init section for address calculation*/ | ||
32 | __asm__ ("ldr %0,=_avicstart\n\t" | ||
33 | :"=r"(avicstart):); | ||
34 | 86 | ||
35 | for(i=0; i < 64;i++) | 87 | /* Set NM bit to enable VIC */ |
36 | { | 88 | INTCNTL |= INTCNTL_NM; |
37 | imx31_int[i].name = (char *)&imx31_int_names[i]; | ||
38 | imx31_int[i].int_type=IRQ; | ||
39 | /*integer i MUST be multiplied by 8 b/c gnu as | ||
40 | generates 2 instructions for each vector instruction | ||
41 | in vector_init(). Hence the value of 8 byte intervals | ||
42 | between each vector start address*/ | ||
43 | imx31_int[i].addr=(avicstart+(i*8)); | ||
44 | imx31_int[i].priority=0; | ||
45 | imx31_int[i].pInt_Handler=Unhandled_Int; | ||
46 | } | ||
47 | |||
48 | /*enable all Interrupts*/ | ||
49 | avic_enable_int(ALL,IRQ,0); | ||
50 | |||
51 | /*Setup all interrupt type IRQ*/ | ||
52 | avic_set_int_type(ALL,IRQ); | ||
53 | |||
54 | /*Set NM bit to enable VIC*/ | ||
55 | INTCNTL |= (1 << 18); | ||
56 | 89 | ||
57 | /*Setup Registers Vector0-Vector63 for interrupt handler functions*/ | 90 | /* Enable IRQ/FIQ in imx31 INTCNTL reg */ |
58 | for(i=0; i < 64;i++) | 91 | INTCNTL &= ~(INTCNTL_ABFEN | INTCNTL_NIDIS | INTCNTL_FIDIS); |
59 | writel(imx31_int[i].addr,(VECTOR_BASE_ADDR+(i*8))); | 92 | |
60 | 93 | /* Enable VE bit in CP15 Control reg to enable VIC */ | |
61 | /*disable FIQ for now until the interrupt handlers are more mature...*/ | 94 | asm volatile ( |
62 | disable_fiq(); | 95 | "mrc p15, 0, r0, c1, c0, 0 \n" |
63 | /*enable_fiq();*/ | 96 | "orr r0, r0, #(1 << 24) \n" |
64 | 97 | "mcr p15, 0, r0, c1, c0, 0 \n" | |
65 | /*enable IRQ in imx31 INTCNTL reg*/ | 98 | : : : "r0"); |
66 | INTCNTL &= ~(NIDIS); | 99 | |
67 | /*disable FIQ in imx31 INTCNTL reg*/ | 100 | /* Enable normal interrupts at all priorities */ |
68 | INTCNTL |= FIDIS; | 101 | NIMASK = 16; |
69 | |||
70 | /*enable IRQ in ARM11 core, enable VE bit in CP15 Control reg to enable VIC*/ | ||
71 | __asm__ ("mrs r0,cpsr\t\n" | ||
72 | "bic r0,r0,#0x80\t\n" | ||
73 | "msr cpsr,r0\t\n" | ||
74 | "mrc p15,0,r0,c1,c0,0\n\t" | ||
75 | "orr r0,r0,#0x1000000\n\t" | ||
76 | "mcr p15,0,r0,c1,c0,0\n\t"::: | ||
77 | "r0"); | ||
78 | } | 102 | } |
79 | 103 | ||
80 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | 104 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, |
81 | void (*pInt_Handler) (void)) | 105 | void (*handler)(void)) |
82 | { | 106 | { |
83 | int i; | 107 | int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, |
108 | IRQ_FIQ_STATUS); | ||
84 | 109 | ||
85 | if(ints == ALL) | 110 | if (ints != ALL) /* No mass-enable allowed */ |
86 | { | 111 | { |
87 | avic_set_int_type(ALL,intstype); | 112 | avic_set_int_type(ints, intstype); |
88 | for(i=0;i<64;i++) | 113 | VECTOR(ints) = (long)handler; |
89 | INTENNUM= (long)i; | 114 | INTENNUM = ints; |
90 | if(!(*pInt_Handler)) | 115 | } |
91 | pInt_Handler=Unhandled_Int; | 116 | |
92 | return; | 117 | set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); |
93 | } | ||
94 | |||
95 | imx31_int[ints].int_type=intstype; | ||
96 | imx31_int[ints].pInt_Handler=pInt_Handler; | ||
97 | avic_set_int_type(ints,intstype); | ||
98 | INTENNUM=(long)ints; | ||
99 | } | 118 | } |
100 | 119 | ||
101 | void avic_disable_int(enum IMX31_INT_LIST ints) | 120 | void avic_disable_int(enum IMX31_INT_LIST ints) |
102 | { | 121 | { |
103 | int i; | 122 | long i; |
104 | 123 | ||
105 | if(ints == ALL) | 124 | if (ints == ALL) |
106 | { | 125 | { |
107 | for(i=0;i<64;i++) | 126 | for (i = 0; i < 64; i++) |
108 | INTDISNUM=(long)i; | 127 | { |
109 | imx31_int[ints].pInt_Handler=Unhandled_Int; | 128 | INTDISNUM = i; |
110 | return; | 129 | VECTOR(i) = (long)UIE_VECTOR; |
130 | } | ||
111 | } | 131 | } |
112 | 132 | else | |
113 | INTDISNUM=(long)ints; | 133 | { |
134 | INTDISNUM = ints; | ||
135 | VECTOR(ints) = (long)UIE_VECTOR; | ||
136 | } | ||
114 | } | 137 | } |
115 | 138 | ||
116 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype) | 139 | static void set_int_type(int i, enum INT_TYPE intstype) |
117 | { | 140 | { |
118 | int i; | 141 | volatile unsigned long *reg; |
119 | if(ints == ALL) | 142 | long val; |
120 | { | ||
121 | imx31_int[ints].int_type=intstype; | ||
122 | for(i=0;i<64;i++) | ||
123 | { | ||
124 | if(intstype > CCM_DVFS) | ||
125 | INTTYPEH=(long)(intstype-32); | ||
126 | else INTTYPEL=(long)intstype; | ||
127 | } | ||
128 | return; | ||
129 | } | ||
130 | |||
131 | imx31_int[ints].int_type=intstype; | ||
132 | if(intstype > CCM_DVFS) | ||
133 | INTTYPEH=(long)(intstype-32); | ||
134 | else INTTYPEL=(long)intstype; | ||
135 | } | ||
136 | 143 | ||
137 | void Unhandled_Int(void) | 144 | if (i >= 32) |
138 | { | 145 | { |
139 | enum IMX31_INT_LIST ints = 0; | 146 | reg = &INTTYPEH; |
140 | DEBUGF("Unhandled Interrupt:\n"); | 147 | val = 1L << (i - 32); |
141 | DEBUGF("Name : %s\n",imx31_int[ints].name); | 148 | } |
142 | DEBUGF("Interrupt Type : "); | 149 | else |
143 | if(imx31_int[ints].int_type==IRQ) | 150 | { |
144 | DEBUGF("IRQ\n"); | 151 | reg = &INTTYPEL; |
145 | else DEBUGF("FIQ\n"); | 152 | val = 1L << i; |
146 | DEBUGF("Handler Address : 0x%x\n",imx31_int[ints].addr); | 153 | } |
147 | DEBUGF("Priority : %d",imx31_int[ints].priority); | 154 | |
155 | if (intstype == IRQ) | ||
156 | val = *reg & ~val; | ||
157 | else | ||
158 | val = *reg | val; | ||
159 | |||
160 | *reg = val; | ||
148 | } | 161 | } |
149 | 162 | ||
150 | void vector_init(void) | 163 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype) |
151 | { | 164 | { |
152 | 165 | int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, | |
153 | /*64 branch instructions, one for every vector in avic | 166 | IRQ_FIQ_STATUS); |
154 | A better idea would to calculate the shellcode for each of these | 167 | |
155 | instructions...*/ | 168 | if (ints == ALL) |
156 | 169 | { | |
157 | 170 | int i; | |
158 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED0].pInt_Handler)); | 171 | for (i = 0; i < 64; i++) |
159 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED1].pInt_Handler)); | 172 | set_int_type(i, intstype); |
160 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED2].pInt_Handler)); | 173 | } |
161 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C3].pInt_Handler)); | 174 | else |
162 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C2].pInt_Handler)); | 175 | { |
163 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MPEG4_ENCODER].pInt_Handler)); | 176 | set_int_type(ints, intstype); |
164 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RTIC].pInt_Handler)); | 177 | } |
165 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[FIR].pInt_Handler)); | 178 | |
166 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MMC_SDHC2].pInt_Handler)); | 179 | set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); |
167 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MMC_SDHC1].pInt_Handler)); | ||
168 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C1].pInt_Handler)); | ||
169 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SSI2].pInt_Handler)); | ||
170 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SSI1].pInt_Handler)); | ||
171 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI2].pInt_Handler)); | ||
172 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI1].pInt_Handler)); | ||
173 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[ATA].pInt_Handler)); | ||
174 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MBX].pInt_Handler)); | ||
175 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI3].pInt_Handler)); | ||
176 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART3].pInt_Handler)); | ||
177 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IIM].pInt_Handler)); | ||
178 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SIM1].pInt_Handler)); | ||
179 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SIM2].pInt_Handler)); | ||
180 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RNGA].pInt_Handler)); | ||
181 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EVTMON].pInt_Handler)); | ||
182 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[KPP].pInt_Handler)); | ||
183 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RTC].pInt_Handler)); | ||
184 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PWN].pInt_Handler)); | ||
185 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EPIT2].pInt_Handler)); | ||
186 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EPIT1].pInt_Handler)); | ||
187 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPT].pInt_Handler)); | ||
188 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PWR_FAIL].pInt_Handler)); | ||
189 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CCM_DVFS].pInt_Handler)); | ||
190 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART2].pInt_Handler)); | ||
191 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[NANDFC].pInt_Handler)); | ||
192 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SDMA].pInt_Handler)); | ||
193 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_HOST1].pInt_Handler)); | ||
194 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_HOST2].pInt_Handler)); | ||
195 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_OTG].pInt_Handler)); | ||
196 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED3].pInt_Handler)); | ||
197 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MSHC1].pInt_Handler)); | ||
198 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MSHC2].pInt_Handler)); | ||
199 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IPU_ERR].pInt_Handler)); | ||
200 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IPU].pInt_Handler)); | ||
201 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED4].pInt_Handler)); | ||
202 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED5].pInt_Handler)); | ||
203 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART1].pInt_Handler)); | ||
204 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART4].pInt_Handler)); | ||
205 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART5].pInt_Handler)); | ||
206 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[ETC_IRQ].pInt_Handler)); | ||
207 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SCC_SCM].pInt_Handler)); | ||
208 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SCC_SMN].pInt_Handler)); | ||
209 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO2].pInt_Handler)); | ||
210 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO1].pInt_Handler)); | ||
211 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CCM_CLK].pInt_Handler)); | ||
212 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PCMCIA].pInt_Handler)); | ||
213 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[WDOG].pInt_Handler)); | ||
214 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO3].pInt_Handler)); | ||
215 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED6].pInt_Handler)); | ||
216 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_PWMG].pInt_Handler)); | ||
217 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_TEMP].pInt_Handler)); | ||
218 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_SENS1].pInt_Handler)); | ||
219 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_SENS2].pInt_Handler)); | ||
220 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_WDOG].pInt_Handler)); | ||
221 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_TV].pInt_Handler)); | ||
222 | |||
223 | } | 180 | } |
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h index 53a37b353b..29a3ec8dd0 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | |||
@@ -19,107 +19,37 @@ | |||
19 | #ifndef AVIC_IMX31_H | 19 | #ifndef AVIC_IMX31_H |
20 | #define AVIC_IMX31_H | 20 | #define AVIC_IMX31_H |
21 | 21 | ||
22 | 22 | enum INT_TYPE | |
23 | enum INT_TYPE {IRQ=0,FIQ}; | 23 | { |
24 | 24 | IRQ = 0, | |
25 | struct int_names { | 25 | FIQ |
26 | char name[16]; | ||
27 | }; | 26 | }; |
28 | 27 | ||
29 | static const struct int_names imx31_int_names[64] = | 28 | enum IMX31_INT_LIST |
30 | { {"RESERVED0"}, | 29 | { |
31 | {"RESERVED1"}, | 30 | __IMX31_INT_FIRST = -1, |
32 | {"RESERVED2"}, | 31 | RESERVED0, RESERVED1, RESERVED2, I2C3, |
33 | {"I2C3"}, | 32 | I2C2, MPEG4_ENCODER, RTIC, FIR, |
34 | {"I2C2"}, | 33 | MMC_SDHC2, MMC_SDHC1, I2C1, SSI2, |
35 | {"MPEG4_ENCODER"}, | 34 | SSI1, CSPI2, CSPI1, ATA, |
36 | {"RTIC"}, | 35 | MBX, CSPI3, UART3, IIM, |
37 | {"FIR"}, | 36 | SIM1, SIM2, RNGA, EVTMON, |
38 | {"MMC/SDHC2"}, | 37 | KPP, RTC, PWN, EPIT2, |
39 | {"MMC/SDHC1"}, | 38 | EPIT1, GPT, PWR_FAIL, CCM_DVFS, |
40 | {"I2C1"}, | 39 | UART2, NANDFC, SDMA, USB_HOST1, |
41 | {"SSI2"}, | 40 | USB_HOST2, USB_OTG, RESERVED3, MSHC1, |
42 | {"SSI1"}, | 41 | MSHC2, IPU_ERR, IPU, RESERVED4, |
43 | {"CSPI2"}, | 42 | RESERVED5, UART1, UART4, UART5, |
44 | {"CSPI1"}, | 43 | ETC_IRQ, SCC_SCM, SCC_SMN, GPIO2, |
45 | {"ATA"}, | 44 | GPIO1, CCM_CLK, PCMCIA, WDOG, |
46 | {"MBX"}, | 45 | GPIO3, RESERVED6, EXT_PWMG, EXT_TEMP, |
47 | {"CSPI3"}, | 46 | EXT_SENS1, EXT_SENS2, EXT_WDOG, EXT_TV, |
48 | {"UART3"}, | 47 | ALL |
49 | {"IIM"}, | 48 | }; |
50 | {"SIM1"}, | ||
51 | {"SIM2"}, | ||
52 | {"RNGA"}, | ||
53 | {"EVTMON"}, | ||
54 | {"KPP"}, | ||
55 | {"RTC"}, | ||
56 | {"PWN"}, | ||
57 | {"EPIT2"}, | ||
58 | {"EPIT1"}, | ||
59 | {"GPT"}, | ||
60 | {"PWR_FAIL"}, | ||
61 | {"CCM_DVFS"}, | ||
62 | {"UART2"}, | ||
63 | {"NANDFC"}, | ||
64 | {"SDMA"}, | ||
65 | {"USB_HOST1"}, | ||
66 | {"USB_HOST2"}, | ||
67 | {"USB_OTG"}, | ||
68 | {"RESERVED3"}, | ||
69 | {"MSHC1"}, | ||
70 | {"MSHC2"}, | ||
71 | {"IPU_ERR"}, | ||
72 | {"IPU"}, | ||
73 | {"RESERVED4"}, | ||
74 | {"RESERVED5"}, | ||
75 | {"UART1"}, | ||
76 | {"UART4"}, | ||
77 | {"UART5"}, | ||
78 | {"ETC_IRQ"}, | ||
79 | {"SCC_SCM"}, | ||
80 | {"SCC_SMN"}, | ||
81 | {"GPIO2"}, | ||
82 | {"GPIO1"}, | ||
83 | {"CCM_CLK"}, | ||
84 | {"PCMCIA"}, | ||
85 | {"WDOG"}, | ||
86 | {"GPIO3"}, | ||
87 | {"RESERVED6"}, | ||
88 | {"EXT_PWMG"}, | ||
89 | {"EXT_TEMP"}, | ||
90 | {"EXT_SENS1"}, | ||
91 | {"EXT_SENS2"}, | ||
92 | {"EXT_WDOG"}, | ||
93 | {"EXT_TV"} }; | ||
94 | |||
95 | enum IMX31_INT_LIST { | ||
96 | RESERVED0 = 0,RESERVED1,RESERVED2,I2C3, | ||
97 | I2C2,MPEG4_ENCODER,RTIC,FIR,MMC_SDHC2, | ||
98 | MMC_SDHC1,I2C1,SSI2,SSI1,CSPI2,CSPI1, | ||
99 | ATA,MBX,CSPI3,UART3,IIM,SIM1,SIM2, | ||
100 | RNGA,EVTMON,KPP,RTC,PWN,EPIT2,EPIT1, | ||
101 | GPT,PWR_FAIL,CCM_DVFS,UART2,NANDFC, | ||
102 | SDMA,USB_HOST1,USB_HOST2,USB_OTG, | ||
103 | RESERVED3,MSHC1,MSHC2,IPU_ERR,IPU, | ||
104 | RESERVED4,RESERVED5,UART1,UART4,UART5, | ||
105 | ETC_IRQ,SCC_SCM,SCC_SMN,GPIO2,GPIO1, | ||
106 | CCM_CLK,PCMCIA,WDOG,GPIO3,RESERVED6, | ||
107 | EXT_PWMG,EXT_TEMP,EXT_SENS1,EXT_SENS2, | ||
108 | EXT_WDOG,EXT_TV,ALL }; | ||
109 | |||
110 | static struct avic_int { | ||
111 | char * name; | ||
112 | enum INT_TYPE int_type; | ||
113 | unsigned int addr; | ||
114 | unsigned int priority; | ||
115 | void (*pInt_Handler) (void); | ||
116 | } imx31_int[64]; | ||
117 | 49 | ||
118 | void avic_init(void); | 50 | void avic_init(void); |
119 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | 51 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, |
120 | void (*pInt_Handler) (void)); | 52 | void (*handler)(void)); |
121 | void avic_disable_int(enum IMX31_INT_LIST ints) ; | 53 | void avic_disable_int(enum IMX31_INT_LIST ints); |
122 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); | 54 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); |
123 | void Unhandled_Int(void); | ||
124 | void vector_init(void) __attribute__ ((section(".avic_int"),naked)); | ||
125 | #endif | 55 | #endif |
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c index 9df90a2344..7f882405a5 100644 --- a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c | |||
@@ -1,25 +1,60 @@ | |||
1 | #include "config.h" | ||
2 | #include "system.h" | ||
3 | #include "avic-imx31.h" | ||
1 | #include "kernel.h" | 4 | #include "kernel.h" |
2 | #include "thread.h" | 5 | #include "thread.h" |
3 | |||
4 | #include <stdio.h> | 6 | #include <stdio.h> |
5 | #include "lcd.h" | ||
6 | 7 | ||
7 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); | 8 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); |
8 | 9 | ||
9 | void timer4(void) { | 10 | #ifndef BOOTLOADER |
10 | int i; | 11 | static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) |
12 | { | ||
13 | int i; | ||
14 | |||
15 | EPITSR1 = 1; /* Clear the pending status */ | ||
16 | |||
11 | /* Run through the list of tick tasks */ | 17 | /* Run through the list of tick tasks */ |
12 | for(i = 0; i < MAX_NUM_TICK_TASKS; i++) | 18 | for(i = 0;i < MAX_NUM_TICK_TASKS;i++) |
13 | { | 19 | { |
14 | if(tick_funcs[i]) | 20 | if(tick_funcs[i]) |
15 | { | ||
16 | tick_funcs[i](); | 21 | tick_funcs[i](); |
17 | } | ||
18 | } | 22 | } |
19 | 23 | ||
20 | current_tick++; | 24 | current_tick++; |
21 | |||
22 | /* following needs to be fixed. */ | ||
23 | /*wake_up_thread();*/ | ||
24 | } | 25 | } |
26 | #endif | ||
27 | |||
28 | void tick_start(unsigned int interval_in_ms) | ||
29 | { | ||
30 | EPITCR1 &= ~(1 << 0); /* Disable the counter */ | ||
31 | EPITCR1 |= (1 << 16); /* Reset */ | ||
25 | 32 | ||
33 | CLKCTL_CGR0 |= (0x3 << 6); /* Clock ON */ | ||
34 | CLKCTL_WIMR0 &= ~(1 << 23); /* Clear wakeup mask */ | ||
35 | |||
36 | /* NOTE: This isn't really accurate yet but it's close enough to work | ||
37 | * with for the moment */ | ||
38 | |||
39 | /* CLKSRC=32KHz, EPIT Output Disconnected, Enabled | ||
40 | * prescale 1/32, Reload from modulus register, Compare interrupt enabled, | ||
41 | * Count from load value */ | ||
42 | EPITCR1 = (0x3 << 24) | (1 << 19) | (32 << 4) | | ||
43 | (1 << 3) | (1 << 2) | (1 << 1); | ||
44 | EPITSR1 = 1; /* Clear any pending interrupt */ | ||
45 | #ifndef BOOTLOADER | ||
46 | EPITLR1 = interval_in_ms; | ||
47 | EPITCMPR1 = 0; /* Event when counter reaches 0 */ | ||
48 | avic_enable_int(EPIT1, IRQ, EPIT1_HANDLER); | ||
49 | #else | ||
50 | (void)interval_in_ms; | ||
51 | #endif | ||
52 | |||
53 | EPITCR1 |= (1 << 0); /* Enable the counter */ | ||
54 | |||
55 | /* Why does only this trigger the counter? Remove when we find out. */ | ||
56 | asm volatile ( | ||
57 | "mcr p15, 0, %0, c7, c0, 4 \n" | ||
58 | : : "r" (0) | ||
59 | ); | ||
60 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S b/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S deleted file mode 100644 index d431c95f29..0000000000 --- a/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S +++ /dev/null | |||
@@ -1,222 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Michael Sevakis | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "cpu.h" | ||
22 | |||
23 | /**************************************************************************** | ||
24 | * void lcd_write_yuv_420_lines(fb_data *dst, | ||
25 | * unsigned char chroma_buf[LCD_HEIGHT/2*3], | ||
26 | unsigned char const * const src[3], | ||
27 | * int width, | ||
28 | * int stride); | ||
29 | * | ||
30 | * |R| |1.000000 -0.000001 1.402000| |Y'| | ||
31 | * |G| = |1.000000 -0.334136 -0.714136| |Pb| | ||
32 | * |B| |1.000000 1.772000 0.000000| |Pr| | ||
33 | * Scaled, normalized, rounded and tweaked to yield RGB 565: | ||
34 | * |R| |74 0 101| |Y' - 16| >> 9 | ||
35 | * |G| = |74 -24 -51| |Cb - 128| >> 8 | ||
36 | * |B| |74 128 0| |Cr - 128| >> 9 | ||
37 | */ | ||
38 | .section .icode, "ax", %progbits | ||
39 | .align 2 | ||
40 | .global lcd_write_yuv420_lines | ||
41 | .type lcd_write_yuv420_lines, %function | ||
42 | lcd_write_yuv420_lines: | ||
43 | @ r0 = dst | ||
44 | @ r1 = chroma_buf | ||
45 | @ r2 = yuv_src | ||
46 | @ r3 = width | ||
47 | @ [sp] = stride | ||
48 | stmdb sp!, { r4-r12, lr } @ save non-scratch | ||
49 | stmdb sp!, { r0, r3 } @ save dst and width | ||
50 | mov r14, #74 @ r14 = Y factor | ||
51 | ldmia r2, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p | ||
52 | @ r5 = yuv_src[1] = Cb_p | ||
53 | @ r6 = yuv_src[2] = Cr_p | ||
54 | 10: @ loop line 1 @ | ||
55 | ldrb r2, [r4], #1 @ r2 = *Y'_p++; | ||
56 | ldrb r8, [r5], #1 @ r8 = *Cb_p++; | ||
57 | ldrb r11, [r6], #1 @ r11 = *Cr_p++; | ||
58 | @ | ||
59 | @ compute Y | ||
60 | sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 | ||
61 | mul r7, r2, r14 @ | ||
62 | @ | ||
63 | sub r8, r8, #128 @ Cb -= 128 | ||
64 | sub r11, r11, #128 @ Cr -= 128 | ||
65 | @ | ||
66 | mvn r2, #24 @ compute guv | ||
67 | mul r10, r2, r8 @ r10 = Cb*-24 | ||
68 | mvn r2, #51 @ | ||
69 | mla r10, r2, r11, r10 @ r10 = r10 + Cr*-51 | ||
70 | @ | ||
71 | mov r2, #101 @ compute rv | ||
72 | mul r9, r11, r2 @ r9 = rv = Cr*101 | ||
73 | @ | ||
74 | @ store chromas in line buffer | ||
75 | add r8, r8, #2 @ bu = (Cb + 2) >> 2 | ||
76 | mov r8, r8, asr #2 @ | ||
77 | strb r8, [r1], #1 @ | ||
78 | add r9, r9, #256 @ rv = (Cr + 256) >> 9 | ||
79 | mov r9, r9, asr #9 @ | ||
80 | strb r9, [r1], #1 @ | ||
81 | mov r10, r10, asr #8 @ guv >>= 8 | ||
82 | strb r10, [r1], #1 @ | ||
83 | @ compute R, G, and B | ||
84 | add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu | ||
85 | add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv | ||
86 | add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv | ||
87 | @ | ||
88 | orr r12, r2, r11 @ check if clamping is needed... | ||
89 | orr r12, r12, r7, asr #1 @ ...at all | ||
90 | cmp r12, #31 @ | ||
91 | bls 15f @ no clamp @ | ||
92 | mov r12, #31 @ | ||
93 | cmp r12, r2 @ clamp b | ||
94 | andlo r2, r12, r2, asr #31 @ | ||
95 | eorlo r2, r2, r12 @ | ||
96 | cmp r12, r11 @ clamp r | ||
97 | andlo r11, r12, r11, asr #31 @ | ||
98 | eorlo r11, r11, r12 @ | ||
99 | cmp r12, r7, asr #1 @ clamp g | ||
100 | andlo r7, r12, r7, asr #31 @ | ||
101 | eorlo r7, r7, r12 @ | ||
102 | orrlo r7, r7, r7, asl #1 @ | ||
103 | 15: @ no clamp @ | ||
104 | @ | ||
105 | orr r12, r2, r7, lsl #5 @ r4 |= (g << 5) | ||
106 | ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ | ||
107 | orr r12, r12, r11, lsl #11 @ r4 = b | (r << 11) | ||
108 | strh r12, [r0], #240 @ store pixel | ||
109 | @ | ||
110 | sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 | ||
111 | mul r7, r2, r14 @ next Y | ||
112 | @ compute R, G, and B | ||
113 | add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu | ||
114 | add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv | ||
115 | add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv | ||
116 | @ | ||
117 | orr r12, r2, r11 @ check if clamping is needed... | ||
118 | orr r12, r12, r7, asr #1 @ ...at all | ||
119 | cmp r12, #31 @ | ||
120 | bls 15f @ no clamp @ | ||
121 | mov r12, #31 @ | ||
122 | cmp r12, r2 @ clamp b | ||
123 | andlo r2, r12, r2, asr #31 @ | ||
124 | eorlo r2, r2, r12 @ | ||
125 | cmp r12, r11 @ clamp r | ||
126 | andlo r11, r12, r11, asr #31 @ | ||
127 | eorlo r11, r11, r12 @ | ||
128 | cmp r12, r7, asr #1 @ clamp g | ||
129 | andlo r7, r12, r7, asr #31 @ | ||
130 | eorlo r7, r7, r12 @ | ||
131 | orrlo r7, r7, r7, asl #1 @ | ||
132 | 15: @ no clamp @ | ||
133 | @ | ||
134 | orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) | ||
135 | orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) | ||
136 | strh r12, [r0, #240]! @ store pixel | ||
137 | add r0, r0, #2*240 @ | ||
138 | @ | ||
139 | subs r3, r3, #2 @ | ||
140 | bgt 10b @ loop line 1 @ | ||
141 | @ do second line | ||
142 | @ | ||
143 | ldmia sp!, { r0, r3 } @ pop dst and width | ||
144 | sub r0, r0, #2 @ set dst to start of next line | ||
145 | sub r1, r1, r3, asl #1 @ rewind chroma pointer... | ||
146 | ldr r2, [sp, #40] @ r2 = stride | ||
147 | add r1, r1, r3, asr #1 @ ... (r1 -= width/2*3) | ||
148 | @ move sources to start of next line | ||
149 | sub r2, r2, r3 @ r2 = skip = stride - width | ||
150 | add r4, r4, r2 @ r4 = Y'_p + skip | ||
151 | @ | ||
152 | 20: @ loop line 2 @ | ||
153 | ldrb r2, [r4], #1 @ r7 = Y' = *Y'_p++ | ||
154 | ldrsb r8, [r1], #1 @ reload saved chromas | ||
155 | ldrsb r9, [r1], #1 @ | ||
156 | ldrsb r10, [r1], #1 @ | ||
157 | @ | ||
158 | sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 | ||
159 | mul r7, r2, r14 @ | ||
160 | @ compute R, G, and B | ||
161 | add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu | ||
162 | add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv | ||
163 | add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv | ||
164 | @ | ||
165 | orr r12, r2, r11 @ check if clamping is needed... | ||
166 | orr r12, r12, r7, asr #1 @ ...at all | ||
167 | cmp r12, #31 @ | ||
168 | bls 25f @ no clamp @ | ||
169 | mov r12, #31 @ | ||
170 | cmp r12, r2 @ clamp b | ||
171 | andlo r2, r12, r2, asr #31 @ | ||
172 | eorlo r2, r2, r12 @ | ||
173 | cmp r12, r11 @ clamp r | ||
174 | andlo r11, r12, r11, asr #31 @ | ||
175 | eorlo r11, r11, r12 @ | ||
176 | cmp r12, r7, asr #1 @ clamp g | ||
177 | andlo r7, r12, r7, asr #31 @ | ||
178 | eorlo r7, r7, r12 @ | ||
179 | orrlo r7, r7, r7, asl #1 @ | ||
180 | 25: @ no clamp @ | ||
181 | @ | ||
182 | orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) | ||
183 | ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ | ||
184 | orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) | ||
185 | strh r12, [r0], #240 @ store pixel | ||
186 | @ | ||
187 | @ do second pixel | ||
188 | @ | ||
189 | sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 | ||
190 | mul r7, r2, r14 @ | ||
191 | @ compute R, G, and B | ||
192 | add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu | ||
193 | add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv | ||
194 | add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv | ||
195 | @ | ||
196 | orr r12, r2, r11 @ check if clamping is needed... | ||
197 | orr r12, r12, r7, asr #1 @ ...at all | ||
198 | cmp r12, #31 @ | ||
199 | bls 25f @ no clamp @ | ||
200 | mov r12, #31 @ | ||
201 | cmp r12, r2 @ clamp b | ||
202 | andlo r2, r12, r2, asr #31 @ | ||
203 | eorlo r2, r2, r12 @ | ||
204 | cmp r12, r11 @ clamp r | ||
205 | andlo r11, r12, r11, asr #31 @ | ||
206 | eorlo r11, r11, r12 @ | ||
207 | cmp r12, r7, asr #1 @ clamp g | ||
208 | andlo r7, r12, r7, asr #31 @ | ||
209 | eorlo r7, r7, r12 @ | ||
210 | orrlo r7, r7, r7, asl #1 @ | ||
211 | 25: @ no clamp @ | ||
212 | @ | ||
213 | orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) | ||
214 | orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) | ||
215 | strh r12, [r0, #240]! @ store pixel | ||
216 | add r0, r0, #2*240 @ | ||
217 | @ | ||
218 | subs r3, r3, #2 @ | ||
219 | bgt 20b @ loop line 2 @ | ||
220 | @ | ||
221 | ldmia sp!, { r4-r12, pc } @ restore registers and return | ||
222 | .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c index c9cce6d653..b39ddbe77d 100644 --- a/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c | |||
@@ -9,12 +9,15 @@ | |||
9 | 9 | ||
10 | static volatile bool lcd_on = true; | 10 | static volatile bool lcd_on = true; |
11 | volatile bool lcd_poweroff = false; | 11 | volatile bool lcd_poweroff = false; |
12 | static unsigned lcd_yuv_options = 0; | ||
12 | /* | 13 | /* |
13 | ** These are imported from lcd-16bit.c | 14 | ** These are imported from lcd-16bit.c |
14 | */ | 15 | */ |
15 | extern unsigned fg_pattern; | 16 | extern unsigned fg_pattern; |
16 | extern unsigned bg_pattern; | 17 | extern unsigned bg_pattern; |
17 | 18 | ||
19 | extern struct viewport* current_vp; | ||
20 | |||
18 | #if 0 | 21 | #if 0 |
19 | bool lcd_enabled() | 22 | bool lcd_enabled() |
20 | { | 23 | { |
@@ -22,68 +25,60 @@ bool lcd_enabled() | |||
22 | } | 25 | } |
23 | #endif | 26 | #endif |
24 | 27 | ||
25 | void printscreen(unsigned int colour) { | 28 | void printscreen(unsigned int colour) |
29 | { | ||
26 | int i; | 30 | int i; |
27 | int base = 0x84100000; | 31 | char * base = (char *)FRAME; |
28 | for(i=0;i<(320*240*2);i++) { | 32 | for(i = 0; i < (320*240*2); i++) |
29 | writel(colour,base); | 33 | { |
34 | writel(colour, base); | ||
30 | base++; | 35 | base++; |
31 | } | 36 | } |
32 | } | 37 | } |
33 | 38 | ||
34 | unsigned int LCDBANK(unsigned int address) | ||
35 | { | ||
36 | return ((address >> 22) & 0xff); | ||
37 | } | ||
38 | |||
39 | unsigned int LCDBASEU(unsigned int address) | ||
40 | { | ||
41 | return (address & ((1 << 22)-1)) >> 1; | ||
42 | } | ||
43 | |||
44 | unsigned int LCDBASEL(unsigned int address) | ||
45 | { | ||
46 | address += 320*240*2; | ||
47 | return (address & ((1 << 22)-1)) >> 1; | ||
48 | } | ||
49 | |||
50 | |||
51 | /* LCD init */ | 39 | /* LCD init */ |
52 | void lcd_init_device(void) | 40 | void lcd_init_device(void) |
53 | { | 41 | { |
54 | int i; | ||
55 | #ifdef BOOTLOADER | ||
56 | /* When the Rockbox bootloader starts, we are changing framebuffer address, | ||
57 | but we don't want what's shown on the LCD to change until we do an | ||
58 | lcd_update(), so copy the data from the old framebuffer to the new one */ | ||
59 | unsigned short *buf = (unsigned short*)FRAME1; | ||
60 | |||
61 | memcpy(FRAME1, (short *)((LCDSADDR1)<<1), 320*240*2); | ||
62 | |||
63 | /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode | ||
64 | so convert the frambuffer data accordingly */ | ||
65 | for(i=0; i< 320*240; i++){ | ||
66 | *buf = ((*buf>>1) & 0x1F) | (*buf & 0xffc0); | ||
67 | buf++; | ||
68 | } | ||
69 | return; | ||
70 | #endif | ||
71 | } | 42 | } |
72 | 43 | ||
73 | /* Update a fraction of the display. */ | 44 | /* Update a fraction of the display. */ |
74 | void lcd_update_rect(int x, int y, int width, int height) | 45 | void lcd_update_rect(int x, int y, int width, int height) |
75 | { | 46 | { |
76 | (void)x; | 47 | fb_data *dst, *src; |
77 | (void)width; | ||
78 | (void)y; | ||
79 | (void)height; | ||
80 | 48 | ||
81 | if(!lcd_on) | 49 | if (!lcd_on) |
82 | { | ||
83 | sleep(200); | ||
84 | return; | 50 | return; |
51 | |||
52 | if (x + width > LCD_WIDTH) | ||
53 | width = LCD_WIDTH - x; /* Clip right */ | ||
54 | if (x < 0) | ||
55 | width += x, x = 0; /* Clip left */ | ||
56 | if (width <= 0) | ||
57 | return; /* nothing left to do */ | ||
58 | |||
59 | if (y + height > LCD_HEIGHT) | ||
60 | height = LCD_HEIGHT - y; /* Clip bottom */ | ||
61 | if (y < 0) | ||
62 | height += y, y = 0; /* Clip top */ | ||
63 | if (height <= 0) | ||
64 | return; /* nothing left to do */ | ||
65 | |||
66 | /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer | ||
67 | * and lcd_framebuffer */ | ||
68 | dst = (fb_data *)FRAME + LCD_WIDTH*y + x; | ||
69 | src = &lcd_framebuffer[y][x]; | ||
70 | |||
71 | /* Copy part of the Rockbox framebuffer to the second framebuffer */ | ||
72 | if (width < LCD_WIDTH) | ||
73 | { | ||
74 | /* Not full width - do line-by-line */ | ||
75 | lcd_copy_buffer_rect(dst, src, width, height); | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | /* Full width - copy as one line */ | ||
80 | lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); | ||
85 | } | 81 | } |
86 | memcpy(((char*)FRAME2) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); | ||
87 | } | 82 | } |
88 | 83 | ||
89 | void lcd_enable(bool state) | 84 | void lcd_enable(bool state) |
@@ -100,68 +95,82 @@ bool lcd_enabled(void) | |||
100 | This must be called after all other LCD functions that change the display. */ | 95 | This must be called after all other LCD functions that change the display. */ |
101 | void lcd_update(void) | 96 | void lcd_update(void) |
102 | { | 97 | { |
103 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | 98 | if (!lcd_on) |
99 | return; | ||
100 | |||
101 | lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], | ||
102 | LCD_WIDTH*LCD_HEIGHT, 1); | ||
104 | } | 103 | } |
105 | 104 | ||
106 | void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | 105 | void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, |
107 | int stride, int x, int y, int width, | 106 | int stride, int x, int y, int width, |
108 | int height) | 107 | int height) |
109 | { | 108 | { |
110 | fb_data *dst, *dst_end; | 109 | #if 0 |
111 | unsigned int transcolor; | 110 | int w, px; |
112 | 111 | fb_data *dst; | |
113 | /* nothing to draw? */ | ||
114 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
115 | || (x + width <= 0) || (y + height <= 0)) | ||
116 | return; | ||
117 | 112 | ||
118 | /* clipping */ | ||
119 | if (x < 0) | ||
120 | { | ||
121 | width += x; | ||
122 | src_x -= x; | ||
123 | x = 0; | ||
124 | } | ||
125 | if (y < 0) | ||
126 | { | ||
127 | height += y; | ||
128 | src_y -= y; | ||
129 | y = 0; | ||
130 | } | ||
131 | if (x + width > LCD_WIDTH) | 113 | if (x + width > LCD_WIDTH) |
132 | width = LCD_WIDTH - x; | 114 | width = LCD_WIDTH - x; /* Clip right */ |
115 | if (x < 0) | ||
116 | width += x, x = 0; /* Clip left */ | ||
117 | if (width <= 0) | ||
118 | return; /* nothing left to do */ | ||
119 | |||
133 | if (y + height > LCD_HEIGHT) | 120 | if (y + height > LCD_HEIGHT) |
134 | height = LCD_HEIGHT - y; | 121 | height = LCD_HEIGHT - y; /* Clip bottom */ |
122 | if (y < 0) | ||
123 | height += y, y = 0; /* Clip top */ | ||
124 | if (height <= 0) | ||
125 | return; /* nothing left to do */ | ||
135 | 126 | ||
136 | src += stride * src_y + src_x; /* move starting point */ | 127 | src += stride * src_y + src_x; /* move starting point */ |
137 | dst = &lcd_framebuffer[(y)][(x)]; | 128 | dst = &lcd_framebuffer[y][x]; |
138 | dst_end = dst + height * LCD_WIDTH; | 129 | |
139 | width *= 2; | 130 | asm volatile ( |
140 | stride *= 2; | 131 | ".rowstart: \r\n" |
141 | transcolor = TRANSPARENT_COLOR; | 132 | "mov %[w], %[width] \r\n" /* Load width for inner loop */ |
142 | asm volatile( | 133 | ".nextpixel: \r\n" |
143 | "rowstart: \n" | 134 | "ldrh %[px], [%[s]], #2 \r\n" /* Load src pixel */ |
144 | "mov r0, #0 \n" | 135 | "add %[d], %[d], #2 \r\n" /* Uncoditionally increment dst */ |
145 | "nextpixel: \n" | 136 | "cmp %[px], %[fgcolor] \r\n" /* Compare to foreground color */ |
146 | "ldrh r1, [%0, r0] \n" /* Load word src+r0 */ | 137 | "streqh %[fgpat], [%[d], #-2] \r\n" /* Store foregroud if match */ |
147 | "cmp r1, %5 \n" /* Compare to transparent color */ | 138 | "cmpne %[px], %[transcolor] \r\n" /* Compare to transparent color */ |
148 | "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */ | 139 | "strneh %[px], [%[d], #-2] \r\n" /* Store dst if not transparent */ |
149 | "add r0, r0, #2 \n" | 140 | "subs %[w], %[w], #1 \r\n" /* Width counter has run down? */ |
150 | "cmp r0, %2 \n" /* r0 == width? */ | 141 | "bgt .nextpixel \r\n" /* More in this row? */ |
151 | "bne nextpixel \n" /* More in this row? */ | 142 | "add %[s], %[s], %[sstp], lsl #1 \r\n" /* Skip over to start of next line */ |
152 | "add %0, %0, %4 \n" /* src += stride */ | 143 | "add %[d], %[d], %[dstp], lsl #1 \r\n" |
153 | "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */ | 144 | "subs %[h], %[h], #1 \r\n" /* Height counter has run down? */ |
154 | "cmp %1, %3 \n" | 145 | "bgt .rowstart \r\n" /* More rows? */ |
155 | "bne rowstart \n" /* if(dst != dst_end), keep going */ | 146 | : [w]"=&r"(w), [h]"+&r"(height), [px]"=&r"(px), |
156 | : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" ); | 147 | [s]"+&r"(src), [d]"+&r"(dst) |
148 | : [width]"r"(width), | ||
149 | [sstp]"r"(stride - width), | ||
150 | [dstp]"r"(LCD_WIDTH - width), | ||
151 | [transcolor]"r"(TRANSPARENT_COLOR), | ||
152 | [fgcolor]"r"(REPLACEWITHFG_COLOR), | ||
153 | [fgpat]"r"(current_vp->fg_pattern) | ||
154 | ); | ||
155 | #endif | ||
156 | } | ||
157 | |||
158 | void lcd_yuv_set_options(unsigned options) | ||
159 | { | ||
160 | lcd_yuv_options = options; | ||
157 | } | 161 | } |
158 | 162 | ||
159 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | 163 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ |
160 | extern void lcd_write_yuv420_lines(fb_data *dst, | 164 | extern void lcd_write_yuv420_lines(fb_data *dst, |
161 | unsigned char chroma_buf[LCD_HEIGHT/2*3], | ||
162 | unsigned char const * const src[3], | 165 | unsigned char const * const src[3], |
163 | int width, | 166 | int width, |
164 | int stride); | 167 | int stride); |
168 | extern void lcd_write_yuv420_lines_odither(fb_data *dst, | ||
169 | unsigned char const * const src[3], | ||
170 | int width, | ||
171 | int stride, | ||
172 | int x_screen, /* To align dither pattern */ | ||
173 | int y_screen); | ||
165 | /* Performance function to blit a YUV bitmap directly to the LCD */ | 174 | /* Performance function to blit a YUV bitmap directly to the LCD */ |
166 | /* For the Gigabeat - show it rotated */ | 175 | /* For the Gigabeat - show it rotated */ |
167 | /* So the LCD_WIDTH is now the height */ | 176 | /* So the LCD_WIDTH is now the height */ |
@@ -171,7 +180,6 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
171 | { | 180 | { |
172 | /* Caches for chroma data so it only need be recaculated every other | 181 | /* Caches for chroma data so it only need be recaculated every other |
173 | line */ | 182 | line */ |
174 | unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ | ||
175 | unsigned char const * yuv_src[3]; | 183 | unsigned char const * yuv_src[3]; |
176 | off_t z; | 184 | off_t z; |
177 | 185 | ||
@@ -182,23 +190,39 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
182 | width &= ~1; | 190 | width &= ~1; |
183 | height >>= 1; | 191 | height >>= 1; |
184 | 192 | ||
185 | fb_data *dst = (fb_data*)FRAME1 + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; | 193 | y = LCD_WIDTH - 1 - y; |
194 | fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + y; | ||
186 | 195 | ||
187 | z = stride*src_y; | 196 | z = stride*src_y; |
188 | yuv_src[0] = src[0] + z + src_x; | 197 | yuv_src[0] = src[0] + z + src_x; |
189 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | 198 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); |
190 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | 199 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); |
191 | 200 | ||
192 | do | 201 | if (lcd_yuv_options & LCD_YUV_DITHER) |
202 | { | ||
203 | do | ||
204 | { | ||
205 | lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); | ||
206 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
207 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
208 | yuv_src[2] += stride >> 1; | ||
209 | dst -= 2; | ||
210 | y -= 2; | ||
211 | } | ||
212 | while (--height > 0); | ||
213 | } | ||
214 | else | ||
193 | { | 215 | { |
194 | lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, | 216 | do |
195 | stride); | 217 | { |
196 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | 218 | lcd_write_yuv420_lines(dst, yuv_src, width, stride); |
197 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | 219 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ |
198 | yuv_src[2] += stride >> 1; | 220 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ |
199 | dst -= 2; | 221 | yuv_src[2] += stride >> 1; |
222 | dst -= 2; | ||
223 | } | ||
224 | while (--height > 0); | ||
200 | } | 225 | } |
201 | while (--height > 0); | ||
202 | } | 226 | } |
203 | 227 | ||
204 | void lcd_set_contrast(int val) { | 228 | void lcd_set_contrast(int val) { |
diff --git a/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c index e8ec495449..e116439217 100644 --- a/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c | |||
@@ -21,16 +21,20 @@ | |||
21 | #include "mmu-arm.h" | 21 | #include "mmu-arm.h" |
22 | 22 | ||
23 | void memory_init(void) { | 23 | void memory_init(void) { |
24 | #if 0 | ||
24 | ttb_init(); | 25 | ttb_init(); |
25 | set_page_tables(); | 26 | set_page_tables(); |
26 | enable_mmu(); | 27 | enable_mmu(); |
28 | #endif | ||
27 | } | 29 | } |
28 | 30 | ||
29 | void set_page_tables() { | 31 | void set_page_tables() { |
32 | #if 0 | ||
30 | map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */ | 33 | map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */ |
31 | /*This pa *might* change*/ | 34 | /*This pa *might* change*/ |
32 | map_section(0x80000000, 0, 64, CACHE_ALL); /* map RAM to 0 and enable caching for it */ | 35 | map_section(0x80000000, 0, 64, CACHE_ALL); /* map RAM to 0 and enable caching for it */ |
33 | map_section((int)FRAME1, (int)FRAME1, 1, BUFFERED); /* enable buffered writing for the framebuffer */ | 36 | map_section((int)FRAME1, (int)FRAME1, 1, BUFFERED); /* enable buffered writing for the framebuffer */ |
34 | map_section((int)FRAME2, (int)FRAME2, 1, BUFFERED); | 37 | map_section((int)FRAME2, (int)FRAME2, 1, BUFFERED); |
38 | #endif | ||
35 | } | 39 | } |
36 | 40 | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c index b62051e41d..8485679aa4 100644 --- a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c | |||
@@ -27,8 +27,6 @@ | |||
27 | 27 | ||
28 | static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ | 28 | static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ |
29 | 29 | ||
30 | void fiq_handler(void) __attribute__((naked)); | ||
31 | |||
32 | void pcm_play_lock(void) | 30 | void pcm_play_lock(void) |
33 | { | 31 | { |
34 | } | 32 | } |
@@ -77,12 +75,6 @@ void pcm_play_dma_pause(bool pause) | |||
77 | { | 75 | { |
78 | } | 76 | } |
79 | 77 | ||
80 | /* Get more samples to play out - call pcm_play_dma_stop and | ||
81 | pcm_play_dma_stopped_callback if the data runs out */ | ||
82 | void fiq_handler(void) | ||
83 | { | ||
84 | } | ||
85 | |||
86 | /* Set the pcm frequency hardware will use when play is next started or | 78 | /* Set the pcm frequency hardware will use when play is next started or |
87 | when pcm_apply_settings is called. Do not apply the setting to the | 79 | when pcm_apply_settings is called. Do not apply the setting to the |
88 | hardware here but simply cache it. */ | 80 | hardware here but simply cache it. */ |
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c index 544ae3afe6..ed5a26cd6e 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c | |||
@@ -13,27 +13,15 @@ int system_memory_guard(int newmode) | |||
13 | return 0; | 13 | return 0; |
14 | } | 14 | } |
15 | 15 | ||
16 | extern void timer4(void); | ||
17 | extern void dma0(void); /* free */ | ||
18 | extern void dma1(void); | ||
19 | extern void dma3(void); | ||
20 | |||
21 | void irq_handler(void) | ||
22 | { | ||
23 | } | ||
24 | |||
25 | #ifdef BOOTLOADER | ||
26 | void fiq_handler(void) | ||
27 | { | ||
28 | } | ||
29 | #endif | ||
30 | |||
31 | void system_reboot(void) | 16 | void system_reboot(void) |
32 | { | 17 | { |
33 | } | 18 | } |
34 | 19 | ||
35 | void system_init(void) | 20 | void system_init(void) |
36 | { | 21 | { |
22 | #ifndef BOOTLOADER | ||
23 | avic_init(); | ||
24 | #endif | ||
37 | } | 25 | } |
38 | 26 | ||
39 | inline void dumpregs(void) | 27 | inline void dumpregs(void) |
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h index e87b93b13a..1f7a2475af 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h | |||
@@ -19,15 +19,15 @@ | |||
19 | #ifndef SYSTEM_TARGET_H | 19 | #ifndef SYSTEM_TARGET_H |
20 | #define SYSTEM_TARGET_H | 20 | #define SYSTEM_TARGET_H |
21 | 21 | ||
22 | #include "mmu-imx31.h" | ||
23 | #include "system-arm.h" | 22 | #include "system-arm.h" |
23 | #include "mmu-arm.h" | ||
24 | 24 | ||
25 | #define CPUFREQ_NORMAL 532000000 | 25 | #define CPUFREQ_NORMAL 532000000 |
26 | 26 | ||
27 | static inline void udelay(unsigned int usecs) | 27 | static inline void udelay(unsigned int usecs) |
28 | { | 28 | { |
29 | volatile signed int stop = EPITCNT1 - usecs; | 29 | volatile signed int stop = EPITCNT1 - usecs; |
30 | while (EPITCNT1 > stop); | 30 | while ((signed int)EPITCNT1 > stop); |
31 | } | 31 | } |
32 | 32 | ||
33 | #define __dbg_hw_info(...) 0 | 33 | #define __dbg_hw_info(...) 0 |
@@ -36,6 +36,22 @@ static inline void udelay(unsigned int usecs) | |||
36 | #define HAVE_INVALIDATE_ICACHE | 36 | #define HAVE_INVALIDATE_ICACHE |
37 | static inline void invalidate_icache(void) | 37 | static inline void invalidate_icache(void) |
38 | { | 38 | { |
39 | long rd = 0; | ||
40 | asm volatile( | ||
41 | "mcr p15, 0, %0, c7, c10, 0 \n" | ||
42 | "mcr p15, 0, %0, c7, c5, 0 \n" | ||
43 | : : "r"(rd) | ||
44 | ); | ||
45 | } | ||
46 | |||
47 | #define HAVE_FLUSH_ICACHE | ||
48 | static inline void flush_icache(void) | ||
49 | { | ||
50 | long rd = 0; | ||
51 | asm volatile ( | ||
52 | "mcr p15, 0, %0, c7, c10, 0 \n" | ||
53 | : : "r"(rd) | ||
54 | ); | ||
39 | } | 55 | } |
40 | 56 | ||
41 | struct ARM_REGS { | 57 | struct ARM_REGS { |