summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-05-03 12:39:36 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-05-03 12:39:36 +0000
commitf48e0b514c6672b38d80a14a5779922253f1bbdc (patch)
treec5359a5e7abab9e0db20fe59336cfd98c7ce279a
parent7a2bc5272b295ab35796019b208c2956bc5c428f (diff)
downloadrockbox-f48e0b514c6672b38d80a14a5779922253f1bbdc.tar.gz
rockbox-f48e0b514c6672b38d80a14a5779922253f1bbdc.zip
Gigabeat: Get rid of the obsolete FIQ wrapper (not used on PP anymore FIY, but no change there). Use the FIQ stack for DMA address and size variables instead of globals.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13309 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/crt0.S8
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c71
2 files changed, 39 insertions, 40 deletions
diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S
index 581a997477..c513bd7ce7 100644
--- a/firmware/target/arm/crt0.S
+++ b/firmware/target/arm/crt0.S
@@ -193,14 +193,6 @@ prefetch_abort_handler:
193 mov r1, #1 193 mov r1, #1
194 b UIE 194 b UIE
195 195
196fiq_handler:
197 @ Branch straight to FIQ handler in pcm_playback.c. This also handles the
198 @ the correct return sequence.
199 stmfd sp!, {r0-r7, r12, lr}
200 bl fiq
201 ldmfd sp!, {r0-r7, r12, lr}
202 subs pc, lr, #4
203
204data_abort_handler: 196data_abort_handler:
205 sub r0, lr, #8 197 sub r0, lr, #8
206 mov r1, #2 198 mov r1, #2
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
index 2b4842f880..45558767d3 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
@@ -41,13 +41,11 @@ static int sr_ctrl = GIGABEAT_44100HZ;
41/* Setup for the DMA controller */ 41/* Setup for the DMA controller */
42#define DMA_CONTROL_SETUP ((1<<31) | (1<<29) | (1<<23) | (1<<22) | (1<<20)) 42#define DMA_CONTROL_SETUP ((1<<31) | (1<<29) | (1<<23) | (1<<22) | (1<<20))
43 43
44unsigned short * p;
45size_t p_size;
46
47/* DMA count has hit zero - no more data */ 44/* DMA count has hit zero - no more data */
48/* Get more data from the callback and top off the FIFO */ 45/* Get more data from the callback and top off the FIFO */
49//void fiq(void) __attribute__ ((interrupt ("naked"))); 46/* Uses explicitly coded prologue/epilogue code to get around complier bugs
50void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ"))); 47 in order to be able to use the stack */
48void fiq_handler(void) __attribute__((naked));
51 49
52static void _pcm_apply_settings(void) 50static void _pcm_apply_settings(void)
53{ 51{
@@ -98,14 +96,14 @@ void pcm_postinit(void)
98 96
99void pcm_play_dma_start(const void *addr, size_t size) 97void pcm_play_dma_start(const void *addr, size_t size)
100{ 98{
99 addr = (void *)((unsigned long)addr & ~3); /* Align data */
100 size &= ~3; /* Size must be multiple of 4 */
101
101 /* sanity check: bad pointer or too small file */ 102 /* sanity check: bad pointer or too small file */
102 if (NULL == addr || size <= IIS_FIFO_SIZE) return; 103 if (NULL == addr || size <= IIS_FIFO_SIZE) return;
103 104
104 disable_fiq(); 105 disable_fiq();
105 106
106 p = (unsigned short *)addr;
107 p_size = size;
108
109 /* Enable the IIS clock */ 107 /* Enable the IIS clock */
110 CLKCON |= (1<<17); 108 CLKCON |= (1<<17);
111 109
@@ -127,10 +125,10 @@ void pcm_play_dma_start(const void *addr, size_t size)
127 /* How many transfers to make - we transfer half-word at a time = 2 bytes */ 125 /* How many transfers to make - we transfer half-word at a time = 2 bytes */
128 /* DMA control: CURR_TC int, single service mode, I2SSDO int, HW trig */ 126 /* DMA control: CURR_TC int, single service mode, I2SSDO int, HW trig */
129 /* no auto-reload, half-word (16bit) */ 127 /* no auto-reload, half-word (16bit) */
130 DCON2 = DMA_CONTROL_SETUP | (p_size / 2); 128 DCON2 = DMA_CONTROL_SETUP | (size / 2);
131 129
132 /* set DMA source and options */ 130 /* set DMA source and options */
133 DISRC2 = (int)p + 0x30000000; 131 DISRC2 = (unsigned long)addr + 0x30000000;
134 DISRCC2 = 0x00; /* memory is on AHB bus, increment addresses */ 132 DISRCC2 = 0x00; /* memory is on AHB bus, increment addresses */
135 133
136 /* clear pending DMA interrupt */ 134 /* clear pending DMA interrupt */
@@ -140,8 +138,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
140 138
141 _pcm_apply_settings(); 139 _pcm_apply_settings();
142 140
143 set_fiq_handler(fiq);
144
145 /* unmask the DMA interrupt */ 141 /* unmask the DMA interrupt */
146 INTMSK &= ~(1<<19); 142 INTMSK &= ~(1<<19);
147 143
@@ -181,41 +177,52 @@ static void pcm_play_dma_stop_fiq(void)
181 CLKCON &= ~(1<<17); 177 CLKCON &= ~(1<<17);
182} 178}
183 179
184void fiq(void) 180void fiq_handler(void)
185{ 181{
182 /* r0-r7 are probably not all used by GCC but there's no way to know
183 otherwise this whole thing must be assembly */
184 asm volatile ("stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */
185 "sub sp, sp, #8 \n"); /* Reserve stack */
186 register pcm_more_callback_type get_more; /* No stack for this */
187 unsigned char *next_start; /* sp + #0 */
188 size_t next_size; /* sp + #4 */
189
186 /* clear any pending interrupt */ 190 /* clear any pending interrupt */
187 SRCPND = (1<<19); 191 SRCPND = (1<<19);
188 192
189 /* Buffer empty. Try to get more. */ 193 /* Buffer empty. Try to get more. */
190 if (pcm_callback_for_more) 194 get_more = pcm_callback_for_more;
191 { 195 if (get_more == NULL)
192 pcm_callback_for_more((unsigned char**)&p, &p_size);
193 }
194 else
195 { 196 {
196 /* callback func is missing? */ 197 /* Callback missing */
197 pcm_play_dma_stop_fiq(); 198 pcm_play_dma_stop_fiq();
198 return; 199 goto fiq_exit;
199 } 200 }
200 201
201 if (p_size) 202 next_size = 0;
202 { 203 get_more(&next_start, &next_size);
203 /* Flush any pending cache writes */
204 clean_dcache_range(p, p_size);
205
206 /* set the new DMA values */
207 DCON2 = DMA_CONTROL_SETUP | (p_size >> 1);
208 DISRC2 = (int)p + 0x30000000;
209 204
210 /* Re-Activate the channel */ 205 if (next_size == 0)
211 DMASKTRIG2 = 0x2;
212 }
213 else
214 { 206 {
215 /* No more DMA to do */ 207 /* No more DMA to do */
216 pcm_play_dma_stop_fiq(); 208 pcm_play_dma_stop_fiq();
209 goto fiq_exit;
217 } 210 }
218 211
212 /* Flush any pending cache writes */
213 clean_dcache_range(next_start, next_size);
214
215 /* set the new DMA values */
216 DCON2 = DMA_CONTROL_SETUP | (next_size >> 1);
217 DISRC2 = (unsigned long)next_start + 0x30000000;
218
219 /* Re-Activate the channel */
220 DMASKTRIG2 = 0x2;
221
222fiq_exit:
223 asm volatile("add sp, sp, #8 \n" /* Cleanup stack */
224 "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */
225 "subs pc, lr, #4 \n"); /* Return from FIQ */
219} 226}
220 227
221/* Disconnect the DMA and wait for the FIFO to clear */ 228/* Disconnect the DMA and wait for the FIFO to clear */