diff options
author | Jack Halpin <jack.halpin@gmail.com> | 2009-11-23 19:44:13 +0000 |
---|---|---|
committer | Jack Halpin <jack.halpin@gmail.com> | 2009-11-23 19:44:13 +0000 |
commit | f5b59cdf5e6974ea2b23babfc7aa326df6f8a49e (patch) | |
tree | f02d02bd191bf5e2ced4d65d4e48ef9f944aa814 | |
parent | ae22ef13edf317137504770aadac429df3b0d53f (diff) | |
download | rockbox-f5b59cdf5e6974ea2b23babfc7aa326df6f8a49e.tar.gz rockbox-f5b59cdf5e6974ea2b23babfc7aa326df6f8a49e.zip |
AMS Sansa: dma-pl081.c: dma_enable_channel() Add step to clear pending interrupts from the previous operation. Add comments and make construction
of the CH_CONTROL and CH_CONFIGURATION registers easier to follow.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23725 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/target/arm/as3525/dma-pl081.c | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/firmware/target/arm/as3525/dma-pl081.c b/firmware/target/arm/as3525/dma-pl081.c index 52fd90f940..5bde46565b 100644 --- a/firmware/target/arm/as3525/dma-pl081.c +++ b/firmware/target/arm/as3525/dma-pl081.c | |||
@@ -63,41 +63,47 @@ void dma_enable_channel(int channel, void *src, void *dst, int peri, | |||
63 | { | 63 | { |
64 | dma_callback[channel] = callback; | 64 | dma_callback[channel] = callback; |
65 | 65 | ||
66 | int control = 0; | 66 | /* Clear any pending interrupts leftover from previous operation */ |
67 | DMAC_INT_TC_CLEAR = (1<<channel); | ||
68 | DMAC_INT_ERR_CLEAR = (1<<channel); | ||
67 | 69 | ||
68 | DMAC_CH_SRC_ADDR(channel) = (int)src; | 70 | DMAC_CH_SRC_ADDR(channel) = (int)src; |
69 | DMAC_CH_DST_ADDR(channel) = (int)dst; | 71 | DMAC_CH_DST_ADDR(channel) = (int)dst; |
70 | 72 | ||
71 | DMAC_CH_LLI(channel) = 0; /* we use contigous memory, so don't use the LLI */ | 73 | /* When LLI is 0 channel is disabled upon transfer completion */ |
72 | 74 | DMAC_CH_LLI(channel) = 0; | |
73 | /* specify address increment */ | 75 | |
74 | if(src_inc) | 76 | /* Channel Control Register */ |
75 | control |= (1<<26); | 77 | DMAC_CH_CONTROL(channel) = |
76 | 78 | ((1<<31) /* LLI triggers terminal count interrupt */ | |
77 | if(dst_inc) | 79 | /* | (1<<30) */ /* cacheable = 1, non = 0 */ |
78 | control |= (1<<27); | 80 | /* | (1<<29) */ /* bufferable = 1, non = 0 */ |
79 | 81 | /* | (1<<28) */ /* privileged = 1, user = 0 */ | |
80 | /* OF use transfers of 4 * 32 bits words on memory, i2sin, i2sout */ | 82 | | (dst_inc? (1<<27): 0) /* specify address increment */ |
81 | /* OF use transfers of 8 * 32 bits words on SD */ | 83 | | (src_inc? (1<<26): 0) /* specify address increment */ |
82 | 84 | /* [25:24] */ /* undefined */ | |
83 | control |= (2<<21) | (2<<18); /* dst/src width = word, 32bit */ | 85 | | (2<<21) /* dst width = word, 32bit */ |
84 | control |= (nwords<<15) | (nwords<<12); /* dst/src size */ | 86 | | (2<<18) /* src width = word, 32bit */ |
85 | control |= (size & 0x7ff); /* transfer size */ | 87 | /* OF uses transfers of 4 * 32 bits words on memory, i2sin, i2sout */ |
86 | 88 | /* OF uses transfers of 8 * 32 bits words on SD */ | |
87 | control |= (1<<31); /* current LLI is expected to trigger terminal count interrupt */ | 89 | | (nwords<<15) /* dst size */ |
88 | 90 | | (nwords<<12) /* src size */ | |
89 | DMAC_CH_CONTROL(channel) = control; | 91 | | ((size & 0x7ff)<<0)); /* transfer size */ |
90 | 92 | ||
91 | /* we set the same peripheral as source and destination because we always | 93 | /* Channel Config Register */ |
92 | * use memory-to-peripheral or peripheral-to-memory transfers */ | ||
93 | DMAC_CH_CONFIGURATION(channel) = | 94 | DMAC_CH_CONFIGURATION(channel) = |
94 | (flow_controller<<11) /* flow controller is peripheral */ | 95 | /* [31:19] */ /* Read undefined. Write as zero */ |
95 | | (1<<15) /* terminal count interrupt mask */ | 96 | /* (0<<18) */ /* Halt Bit */ |
96 | | (1<<14) /* interrupt error mask */ | 97 | /* (0<<17) */ /* Active Bit */ |
97 | | (peri<<6) /* dst peripheral */ | 98 | /* (0<<16) */ /* Lock Bit */ |
98 | | (peri<<1) /* src peripheral */ | 99 | (1<<15) /* terminal count interrupt mask */ |
99 | | (1<<0) /* enable channel */ | 100 | | (1<<14) /* interrupt error mask */ |
100 | ; | 101 | | (flow_controller<<11) /* flow controller is peripheral or SDMAC */ |
102 | /* we set the same peripheral as source and destination because we | ||
103 | * always use memory-to-peripheral or peripheral-to-memory transfers */ | ||
104 | | (peri<<6) /* dst peripheral */ | ||
105 | | (peri<<1) /* src peripheral */ | ||
106 | | (1<<0); /* enable channel */ | ||
101 | } | 107 | } |
102 | 108 | ||
103 | /* isr */ | 109 | /* isr */ |