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.zip
rockbox-63404a7d5d8ea00b50ff25f19ceb0afe43c5c3c1.tar.gz
rockbox-63404a7d5d8ea00b50ff25f19ceb0afe43c5c3c1.tar.bz2
rockbox-63404a7d5d8ea00b50ff25f19ceb0afe43c5c3c1.tar.xz
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 39c0bc4..9d2503f 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)
addr = (void *)(((unsigned long)addr + 3) & ~3);
size &= ~3;
+ if (size <= 0)
+ return;
+
+ if (!sdma_channel_reset(DMA_PLAY_CH_NUM))
+ return;
+
clean_dcache_range(addr, size);
dma_play_bd.buf_addr =
(void *)addr_virt_to_phys((unsigned long)(void *)addr);
@@ -280,7 +286,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
play_start_pcm();
- sdma_channel_start(DMA_PLAY_CH_NUM);
+ sdma_channel_run(DMA_PLAY_CH_NUM);
}
void pcm_play_dma_stop(void)
@@ -463,6 +469,12 @@ void pcm_rec_dma_start(void *addr, size_t size)
addr = (void *)(((unsigned long)addr + 3) & ~3);
size &= ~3;
+ if (size <= 0)
+ return;
+
+ if (!sdma_channel_reset(DMA_REC_CH_NUM))
+ return;
+
/* Invalidate - buffer must be coherent */
dump_dcache_range(addr, size);
@@ -483,8 +495,7 @@ void pcm_rec_dma_start(void *addr, size_t size)
/* Enable receive */
SSI_SCR2 |= SSI_SCR_RE;
-
- sdma_channel_start(DMA_REC_CH_NUM);
+ sdma_channel_run(DMA_REC_CH_NUM);
}
void pcm_rec_dma_close(void)
diff --git a/firmware/target/arm/imx31/sdma-imx31.c b/firmware/target/arm/imx31/sdma-imx31.c
index 0683ec3..100bd51 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)
SDMA_CHNPRI(channel) = priority;
}
-/* Start a channel cold - resets execution to start of script */
-void sdma_channel_start(unsigned int channel)
+/* Resets a channel to start of script next time it runs. */
+bool sdma_channel_reset(unsigned int channel)
{
struct channel_control_block *ccb_p;
if (channel == 0 || channel >= CH_NUM)
- return;
+ return false;
ccb_p = &ccb_array[channel];
if (ccb_p->status.opened_init == 0)
- return;
+ return false;
if (!setup_channel(ccb_p))
- return;
+ return false;
- SDMA_HSTART = 1ul << channel;
+ return true;
}
/* 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 fa81951..5daa33d 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);
void sdma_read_words(unsigned long *buf, unsigned long start, int count);
void sdma_write_words(const unsigned long *buf, unsigned long start, int count);
void sdma_channel_set_priority(unsigned int channel, unsigned int priority);
-void sdma_channel_start(unsigned int channel);
+bool sdma_channel_reset(unsigned int channel);
void sdma_channel_run(unsigned int channel);
void sdma_channel_pause(unsigned int channel);
void sdma_channel_stop(unsigned int channel);