From f0e2bab215756df212bc2836a5bc57c655a4b458 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 11 Oct 2010 14:18:56 -0700 Subject: [PATCH] --- yaml --- r: 217017 b: refs/heads/master c: 0e4905c0199d683497833be60a428c784d7575b8 h: refs/heads/master i: 217015: 38a50588a54f742052fba420105f75a171ed4364 v: v3 --- [refs] | 2 +- trunk/arch/arm/plat-omap/dma.c | 36 +++++++++++++++++++-- trunk/arch/arm/plat-omap/include/plat/dma.h | 3 ++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 8ee34cf7c840..50e34b71508d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3e57f1626b5febe5cc99aa6870377deef3ae03cc +refs/heads/master: 0e4905c0199d683497833be60a428c784d7575b8 diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index 420cef370b33..f5c5b8da9a87 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -1024,8 +1025,39 @@ void omap_stop_dma(int lch) dma_write(0, CICR(lch)); l = dma_read(CCR(lch)); - l &= ~OMAP_DMA_CCR_EN; - dma_write(l, CCR(lch)); + /* OMAP3 Errata i541: sDMA FIFO draining does not finish */ + if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) { + int i = 0; + u32 sys_cf; + + /* Configure No-Standby */ + l = dma_read(OCP_SYSCONFIG); + sys_cf = l; + l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK; + l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE); + dma_write(l , OCP_SYSCONFIG); + + l = dma_read(CCR(lch)); + l &= ~OMAP_DMA_CCR_EN; + dma_write(l, CCR(lch)); + + /* Wait for sDMA FIFO drain */ + l = dma_read(CCR(lch)); + while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE | + OMAP_DMA_CCR_WR_ACTIVE))) { + udelay(5); + i++; + l = dma_read(CCR(lch)); + } + if (i >= 100) + printk(KERN_ERR "DMA drain did not complete on " + "lch %d\n", lch); + /* Restore OCP_SYSCONFIG */ + dma_write(sys_cf, OCP_SYSCONFIG); + } else { + l &= ~OMAP_DMA_CCR_EN; + dma_write(l, CCR(lch)); + } if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch = lch; diff --git a/trunk/arch/arm/plat-omap/include/plat/dma.h b/trunk/arch/arm/plat-omap/include/plat/dma.h index 6f70f7cfe91d..0cce4ca83aa0 100644 --- a/trunk/arch/arm/plat-omap/include/plat/dma.h +++ b/trunk/arch/arm/plat-omap/include/plat/dma.h @@ -337,6 +337,9 @@ #define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11) #define OMAP_DMA_CCR_EN (1 << 7) +#define OMAP_DMA_CCR_RD_ACTIVE (1 << 9) +#define OMAP_DMA_CCR_WR_ACTIVE (1 << 10) +#define OMAP_DMA_CCR_SEL_SRC_DST_SYNC (1 << 24) #define OMAP_DMA_CCR_BUFFERING_DISABLE (1 << 25) #define OMAP_DMA_DATA_TYPE_S8 0x00