summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/imx233/dma-imx233.c
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-07-23 11:45:22 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-07-23 11:45:22 +0000
commiteb90d956935019f577311ebc7aec3a7898d76019 (patch)
treec4ac810faaf390b9020c46dc2197008679099034 /firmware/target/arm/imx233/dma-imx233.c
parent06c94740e510d0ce04e069f34631a0539e9e6742 (diff)
downloadrockbox-eb90d956935019f577311ebc7aec3a7898d76019.tar.gz
rockbox-eb90d956935019f577311ebc7aec3a7898d76019.tar.bz2
rockbox-eb90d956935019f577311ebc7aec3a7898d76019.zip
imx233/fuze+: huge rework
- enable MMU -rework lcd frame buffer - add rtc/adc/power stubs (or not) - fix a few MMC related defines (hopefully) - implement cache handling for DMA - more SD work - add keymap (based on clip) - add virtual buttons - update linker scripts - big step toward apps actually compiling git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30200 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx233/dma-imx233.c')
-rw-r--r--firmware/target/arm/imx233/dma-imx233.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/firmware/target/arm/imx233/dma-imx233.c b/firmware/target/arm/imx233/dma-imx233.c
index d75c334aeb..8a42bd12da 100644
--- a/firmware/target/arm/imx233/dma-imx233.c
+++ b/firmware/target/arm/imx233/dma-imx233.c
@@ -106,8 +106,54 @@ bool imx233_dma_is_channel_error_irq(unsigned chan)
HW_APBH_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan)));
}
+/* Commit and/or discard all DMA descriptors and buffers pointed by them,
+ * handle circular lists */
+static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd)
+{
+ /* We handle circular descriptors by using unused bits:
+ * bits 8-11 are not used by the hardware so we first go through the whole
+ * list and mark them all a special value at the same time we commit buffers
+ * and then we go through the list another time to clear the mark and
+ * commit the descriptors */
+ struct apb_dma_command_t *cur = cmd;
+
+ while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != HW_APB_CHx_CMD__UNUSED_MAGIC)
+ {
+ cur->cmd = (cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM) | HW_APB_CHx_CMD__UNUSED_MAGIC;
+ int op = cur->cmd & HW_APB_CHx_CMD__COMMAND_BM;
+ int sz = (cur->cmd & HW_APB_CHx_CMD__XFER_COUNT_BM) >> HW_APB_CHx_CMD__XFER_COUNT_BP;
+ /* device > host: discard */
+ if(op == HW_APB_CHx_CMD__COMMAND__WRITE)
+ discard_dcache_range(cur->buffer, sz);
+ /* host > device: commit and discard */
+ else if(op == HW_APB_CHx_CMD__COMMAND__READ)
+ commit_discard_dcache_range(cur->buffer, sz);
+ /* chain ? */
+ if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
+ cur = cur->next;
+ else
+ break;
+ }
+
+ cur = cmd;
+ while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0)
+ {
+ cur->cmd = cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM;
+ int sz = (cur->cmd & HW_APB_CHx_CMD__CMDWORDS_BM) >> HW_APB_CHx_CMD__CMDWORDS_BP;
+ /* commit descriptor (don't discard since we access it after) */
+ commit_dcache_range(cur,
+ sizeof(struct apb_dma_command_t) + sizeof(uint32_t) * sz);
+ /* chain ? */
+ if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
+ cur = cur->next;
+ else
+ break;
+ }
+}
+
void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
{
+ imx233_dma_commit_and_discard(cmd);
if(APB_IS_APBX_CHANNEL(chan))
{
HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
@@ -129,5 +175,5 @@ void imx233_dma_wait_completion(unsigned chan)
sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
while(*sema & HW_APB_CHx_SEMA__PHORE_BM)
- ;
+ yield();
}