diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2012-08-18 15:22:51 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2012-08-18 15:22:51 +0200 |
commit | 246c2127a7fb9001781dff5bff41b53cc2215e98 (patch) | |
tree | 55bb40152bd5cc28822fbc3caa3a0d363a3f5030 /firmware/target/arm/imx233/dma-imx233.c | |
parent | 51919937a9ecd2264fbac0e64a2737aaac8e2243 (diff) | |
download | rockbox-246c2127a7fb9001781dff5bff41b53cc2215e98.tar.gz rockbox-246c2127a7fb9001781dff5bff41b53cc2215e98.zip |
imx233: small dma changes, update debug screen
Reduce DMA maximum transfer size since transfering 64Kb requires
to set a size of 0 and it's not worth adding checks everywhere
to handle this special case. Also add statistics about unaligned
transfer (wrt to cache). Update debug screen accordingly and
simplify it so it can fit smaller screens too.
Change-Id: I18391702f5e100a21f6f8d1ebab28d9f2bd8c66f
Diffstat (limited to 'firmware/target/arm/imx233/dma-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/dma-imx233.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/firmware/target/arm/imx233/dma-imx233.c b/firmware/target/arm/imx233/dma-imx233.c index 8dac284a38..cba1317f4f 100644 --- a/firmware/target/arm/imx233/dma-imx233.c +++ b/firmware/target/arm/imx233/dma-imx233.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #include "lcd.h" | 27 | #include "lcd.h" |
28 | #include "string.h" | 28 | #include "string.h" |
29 | 29 | ||
30 | // statistics about unaligned transfers | ||
31 | static int apb_nr_unaligned[32]; | ||
32 | |||
30 | void imx233_dma_init(void) | 33 | void imx233_dma_init(void) |
31 | { | 34 | { |
32 | /* Enable APHB and APBX */ | 35 | /* Enable APHB and APBX */ |
@@ -142,7 +145,7 @@ bool imx233_dma_is_channel_error_irq(unsigned chan) | |||
142 | /* Commit and/or discard all DMA descriptors and buffers pointed by them, | 145 | /* Commit and/or discard all DMA descriptors and buffers pointed by them, |
143 | * handle circular lists. At the same time, convert virtual pointers to | 146 | * handle circular lists. At the same time, convert virtual pointers to |
144 | * real ones */ | 147 | * real ones */ |
145 | static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd) | 148 | static void imx233_dma_commit_and_discard(unsigned chan, struct apb_dma_command_t *cmd) |
146 | { | 149 | { |
147 | /* We handle circular descriptors by using unused bits: | 150 | /* We handle circular descriptors by using unused bits: |
148 | * bits 8-11 are not used by the hardware so we first go through the whole | 151 | * bits 8-11 are not used by the hardware so we first go through the whole |
@@ -162,6 +165,8 @@ static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd) | |||
162 | /* host > device: commit and discard */ | 165 | /* host > device: commit and discard */ |
163 | else if(op == HW_APB_CHx_CMD__COMMAND__READ) | 166 | else if(op == HW_APB_CHx_CMD__COMMAND__READ) |
164 | commit_discard_dcache_range(cur->buffer, sz); | 167 | commit_discard_dcache_range(cur->buffer, sz); |
168 | if((uint32_t)cur->buffer % CACHEALIGN_SIZE) | ||
169 | apb_nr_unaligned[chan]++; | ||
165 | /* Virtual to physical buffer pointer conversion */ | 170 | /* Virtual to physical buffer pointer conversion */ |
166 | cur->buffer = PHYSICAL_ADDR(cur->buffer); | 171 | cur->buffer = PHYSICAL_ADDR(cur->buffer); |
167 | /* chain ? */ | 172 | /* chain ? */ |
@@ -195,7 +200,7 @@ static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd) | |||
195 | 200 | ||
196 | void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd) | 201 | void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd) |
197 | { | 202 | { |
198 | imx233_dma_commit_and_discard(cmd); | 203 | imx233_dma_commit_and_discard(chan, cmd); |
199 | if(APB_IS_APBX_CHANNEL(chan)) | 204 | if(APB_IS_APBX_CHANNEL(chan)) |
200 | { | 205 | { |
201 | HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd); | 206 | HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd); |
@@ -208,16 +213,18 @@ void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd) | |||
208 | } | 213 | } |
209 | } | 214 | } |
210 | 215 | ||
211 | void imx233_dma_wait_completion(unsigned chan) | 216 | int imx233_dma_wait_completion(unsigned chan, unsigned tmo) |
212 | { | 217 | { |
218 | tmo += current_tick; | ||
213 | volatile uint32_t *sema; | 219 | volatile uint32_t *sema; |
214 | if(APB_IS_APBX_CHANNEL(chan)) | 220 | if(APB_IS_APBX_CHANNEL(chan)) |
215 | sema = &HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)); | 221 | sema = &HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)); |
216 | else | 222 | else |
217 | sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)); | 223 | sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)); |
218 | 224 | ||
219 | while(*sema & HW_APB_CHx_SEMA__PHORE_BM) | 225 | while(*sema & HW_APB_CHx_SEMA__PHORE_BM && !TIME_AFTER(current_tick, tmo)) |
220 | yield(); | 226 | yield(); |
227 | return __XTRACT_EX(*sema, HW_APB_CHx_SEMA__PHORE); | ||
221 | } | 228 | } |
222 | 229 | ||
223 | struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags) | 230 | struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags) |
@@ -254,6 +261,7 @@ struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags) | |||
254 | s.int_error = apbx ? HW_APBX_CTRL2 & HW_APBX_CTRL2__CHx_ERROR_IRQ(dmac) : | 261 | s.int_error = apbx ? HW_APBX_CTRL2 & HW_APBX_CTRL2__CHx_ERROR_IRQ(dmac) : |
255 | HW_APBH_CTRL2 & HW_APBH_CTRL2__CHx_ERROR_IRQ(dmac); | 262 | HW_APBH_CTRL2 & HW_APBH_CTRL2__CHx_ERROR_IRQ(dmac); |
256 | } | 263 | } |
264 | s.nr_unaligned = apb_nr_unaligned[chan]; | ||
257 | return s; | 265 | return s; |
258 | } | 266 | } |
259 | 267 | ||