summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2009-02-13 12:59:30 +0000
committerMichael Sevakis <jethead71@rockbox.org>2009-02-13 12:59:30 +0000
commit63404a7d5d8ea00b50ff25f19ceb0afe43c5c3c1 (patch)
treeb5bafcdab207f7fe96ec623dbbb31fa2d208928c
parenteb960582667bf92b3bbd19b7269c59beded15970 (diff)
downloadrockbox-63404a7d5d8ea00b50ff25f19ceb0afe43c5c3c1.tar.gz
rockbox-63404a7d5d8ea00b50ff25f19ceb0afe43c5c3c1.zip
Separate running an SDMA channel from resetting it. It should make usage more flexible since resets are needed only before restarting if aborting transfers (because the script is left awaiting requests, not the next start) which PCM does alot of but other things likely won't.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20000 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c17
-rw-r--r--firmware/target/arm/imx31/sdma-imx31.c12
-rw-r--r--firmware/target/arm/imx31/sdma-imx31.h2
3 files changed, 21 insertions, 10 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
index 39c0bc4969..9d2503f4e6 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
@@ -272,6 +272,12 @@ void pcm_play_dma_start(const void *addr, size_t size)
272 addr = (void *)(((unsigned long)addr + 3) & ~3); 272 addr = (void *)(((unsigned long)addr + 3) & ~3);
273 size &= ~3; 273 size &= ~3;
274 274
275 if (size <= 0)
276 return;
277
278 if (!sdma_channel_reset(DMA_PLAY_CH_NUM))
279 return;
280
275 clean_dcache_range(addr, size); 281 clean_dcache_range(addr, size);
276 dma_play_bd.buf_addr = 282 dma_play_bd.buf_addr =
277 (void *)addr_virt_to_phys((unsigned long)(void *)addr); 283 (void *)addr_virt_to_phys((unsigned long)(void *)addr);
@@ -280,7 +286,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
280 dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR; 286 dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
281 287
282 play_start_pcm(); 288 play_start_pcm();
283 sdma_channel_start(DMA_PLAY_CH_NUM); 289 sdma_channel_run(DMA_PLAY_CH_NUM);
284} 290}
285 291
286void pcm_play_dma_stop(void) 292void pcm_play_dma_stop(void)
@@ -463,6 +469,12 @@ void pcm_rec_dma_start(void *addr, size_t size)
463 addr = (void *)(((unsigned long)addr + 3) & ~3); 469 addr = (void *)(((unsigned long)addr + 3) & ~3);
464 size &= ~3; 470 size &= ~3;
465 471
472 if (size <= 0)
473 return;
474
475 if (!sdma_channel_reset(DMA_REC_CH_NUM))
476 return;
477
466 /* Invalidate - buffer must be coherent */ 478 /* Invalidate - buffer must be coherent */
467 dump_dcache_range(addr, size); 479 dump_dcache_range(addr, size);
468 480
@@ -483,8 +495,7 @@ void pcm_rec_dma_start(void *addr, size_t size)
483 495
484 /* Enable receive */ 496 /* Enable receive */
485 SSI_SCR2 |= SSI_SCR_RE; 497 SSI_SCR2 |= SSI_SCR_RE;
486 498 sdma_channel_run(DMA_REC_CH_NUM);
487 sdma_channel_start(DMA_REC_CH_NUM);
488} 499}
489 500
490void pcm_rec_dma_close(void) 501void pcm_rec_dma_close(void)
diff --git a/firmware/target/arm/imx31/sdma-imx31.c b/firmware/target/arm/imx31/sdma-imx31.c
index 0683ec3568..100bd51028 100644
--- a/firmware/target/arm/imx31/sdma-imx31.c
+++ b/firmware/target/arm/imx31/sdma-imx31.c
@@ -613,23 +613,23 @@ void sdma_channel_set_priority(unsigned int channel, unsigned int priority)
613 SDMA_CHNPRI(channel) = priority; 613 SDMA_CHNPRI(channel) = priority;
614} 614}
615 615
616/* Start a channel cold - resets execution to start of script */ 616/* Resets a channel to start of script next time it runs. */
617void sdma_channel_start(unsigned int channel) 617bool sdma_channel_reset(unsigned int channel)
618{ 618{
619 struct channel_control_block *ccb_p; 619 struct channel_control_block *ccb_p;
620 620
621 if (channel == 0 || channel >= CH_NUM) 621 if (channel == 0 || channel >= CH_NUM)
622 return; 622 return false;
623 623
624 ccb_p = &ccb_array[channel]; 624 ccb_p = &ccb_array[channel];
625 625
626 if (ccb_p->status.opened_init == 0) 626 if (ccb_p->status.opened_init == 0)
627 return; 627 return false;
628 628
629 if (!setup_channel(ccb_p)) 629 if (!setup_channel(ccb_p))
630 return; 630 return false;
631 631
632 SDMA_HSTART = 1ul << channel; 632 return true;
633} 633}
634 634
635/* Resume or start execution on a channel */ 635/* Resume or start execution on a channel */
diff --git a/firmware/target/arm/imx31/sdma-imx31.h b/firmware/target/arm/imx31/sdma-imx31.h
index fa8195198b..5daa33d7ba 100644
--- a/firmware/target/arm/imx31/sdma-imx31.h
+++ b/firmware/target/arm/imx31/sdma-imx31.h
@@ -212,7 +212,7 @@ void sdma_init(void);
212void sdma_read_words(unsigned long *buf, unsigned long start, int count); 212void sdma_read_words(unsigned long *buf, unsigned long start, int count);
213void sdma_write_words(const unsigned long *buf, unsigned long start, int count); 213void sdma_write_words(const unsigned long *buf, unsigned long start, int count);
214void sdma_channel_set_priority(unsigned int channel, unsigned int priority); 214void sdma_channel_set_priority(unsigned int channel, unsigned int priority);
215void sdma_channel_start(unsigned int channel); 215bool sdma_channel_reset(unsigned int channel);
216void sdma_channel_run(unsigned int channel); 216void sdma_channel_run(unsigned int channel);
217void sdma_channel_pause(unsigned int channel); 217void sdma_channel_pause(unsigned int channel);
218void sdma_channel_stop(unsigned int channel); 218void sdma_channel_stop(unsigned int channel);