Have you ever tried to do GPMC I/O with the EDMA engine - and failed?
No wonder: there are some common pitfalls.
(Assuming you are using Linux)
1) EDMA event processing
=====================
If you call edma_start(), a list of unused (==free) channels is used to determine if the channel is started per software (for free channels) or per event (for non-free channels).
The GPMC platform data has no DMA channel allocated, so every time you try to start the DMA engine, you will get the software start. This is not what you want!
So, add a DMA channel to the platform data in arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -1335,15 +1335,21 @@ static struct omap_hwmod_ocp_if *am33xx_gpmc_slaves[] = {
static struct omap_hwmod_irq_info am33xx_gpmc_irqs[] = {
{ .irq = 100 },
{ .irq = -1 }
};
+static struct omap_hwmod_dma_info am33xx_gpmc_edma_reqs[] = {
+ { .name = "dma", .dma_req = AM33XX_DMA_GPM },
+ { .dma_req = -1 },
+};
+
static struct omap_hwmod am33xx_gpmc_hwmod = {
.name = "gpmc",
.class = &am33xx_gpmc_hwmod_class,
.clkdm_name = "l3s_clkdm",
.mpu_irqs = am33xx_gpmc_irqs,
+ .sdma_reqs = am33xx_gpmc_edma_reqs,
.main_clk = "gpmc_fck",
.prcm = {
.omap4 = {
.clkctrl_offs = AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
2) GPMC FIFO handling
===================
The GPMC has a FIFO for prefetch/post operations. So the first thing you do is to set the DAM or SAM field of the DMA parameters to FIFO mode.
This will not work. For unknown reasons, the DMA transfer is only able to transfer data from/to GPMC if you use the normal address increment mode.
3) Prefetch engine startup
====================
For the prefetch engine, it is documented that the DMA request flag is cleared AT THE START of the engine,
so the requested sequence is to first start the prefetch engine, and then start the DMA engine.
This will not work.
Starting the DMA engine with edma_start() will clear the DMA event register, and it is very likely that at this moment in time, the prefetch engine has transfered the first 32 Bytes and rised the DMA event flag. The DMA event will get lost. That's it.
So what to do?
- start the prefetch engine with a terminal count of 0 bytes.
- stop the pretech engine.
This sequence will erase any spurious DMA flag inside the prefetch engine.
- start the DMA channel.
- start the prefetch engine.
This will give you a working DMA over GPMC + Prefetch engine.
regards
Wolfgang