summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/dma-pl081.c
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2008-12-04 20:48:19 +0000
committerRafaël Carré <rafael.carre@gmail.com>2008-12-04 20:48:19 +0000
commit1ab08e6879b1fe50102fe68a1326db05891e6faa (patch)
treeb066febe812ae945fe1c91781338b0334edf0a00 /firmware/target/arm/as3525/dma-pl081.c
parent76617c8f9444bfc24744e6e4faeff06d25372fa8 (diff)
downloadrockbox-1ab08e6879b1fe50102fe68a1326db05891e6faa.tar.gz
rockbox-1ab08e6879b1fe50102fe68a1326db05891e6faa.zip
Sansa AMS: updates DMA API
* Adds a callback to be called on end of transfer * Add a function to disable a channel * Services the 2 channels if both are active in the isr SD driver: panics on error git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19333 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/as3525/dma-pl081.c')
-rw-r--r--firmware/target/arm/as3525/dma-pl081.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/firmware/target/arm/as3525/dma-pl081.c b/firmware/target/arm/as3525/dma-pl081.c
index fbe488ce05..3de4e73c12 100644
--- a/firmware/target/arm/as3525/dma-pl081.c
+++ b/firmware/target/arm/as3525/dma-pl081.c
@@ -27,6 +27,7 @@
27#include "kernel.h" 27#include "kernel.h"
28 28
29static struct wakeup transfer_completion_signal[2]; /* 2 channels */ 29static struct wakeup transfer_completion_signal[2]; /* 2 channels */
30static void (*dma_callback[2])(void); /* 2 channels */
30 31
31inline void dma_wait_transfer(int channel) 32inline void dma_wait_transfer(int channel)
32{ 33{
@@ -45,10 +46,17 @@ void dma_init(void)
45 wakeup_init(&transfer_completion_signal[1]); 46 wakeup_init(&transfer_completion_signal[1]);
46} 47}
47 48
49inline void dma_disable_channel(int channel)
50{
51 DMAC_CH_CONFIGURATION(channel) &= ~(1<<0);
52}
53
48void dma_enable_channel(int channel, void *src, void *dst, int peri, 54void dma_enable_channel(int channel, void *src, void *dst, int peri,
49 int flow_controller, bool src_inc, bool dst_inc, 55 int flow_controller, bool src_inc, bool dst_inc,
50 size_t size, int nwords) 56 size_t size, int nwords, void (*callback)(void))
51{ 57{
58 dma_callback[channel] = callback;
59
52 int control = 0; 60 int control = 0;
53 61
54 DMAC_CH_SRC_ADDR(channel) = (int)src; 62 DMAC_CH_SRC_ADDR(channel) = (int)src;
@@ -92,12 +100,21 @@ void dma_enable_channel(int channel, void *src, void *dst, int peri,
92/* isr */ 100/* isr */
93void INT_DMAC(void) 101void INT_DMAC(void)
94{ 102{
95 int channel = (DMAC_INT_STATUS & (1<<0)) ? 0 : 1; 103 unsigned int channel;
104
105 /* SD channel is serviced first */
106 for(channel = 0; channel < 2; channel++)
107 if(DMAC_INT_STATUS & (1<<channel))
108 {
109 if(DMAC_INT_ERROR_STATUS & (1<<channel))
110 panicf("DMA error, channel %d", channel);
96 111
97 if(DMAC_INT_ERROR_STATUS & (1<<channel)) 112 /* clear terminal count interrupt */
98 panicf("DMA error, channel %d", channel); 113 DMAC_INT_TC_CLEAR |= (1<<channel);
99 114
100 DMAC_INT_TC_CLEAR |= (1<<channel); /* clear terminal count interrupt */ 115 if(dma_callback[channel])
116 dma_callback[channel]();
101 117
102 wakeup_signal(&transfer_completion_signal[channel]); 118 wakeup_signal(&transfer_completion_signal[channel]);
119 }
103} 120}