diff options
| -rw-r--r-- | arch/arm/plat-omap/dma.c | 36 | ||||
| -rw-r--r-- | arch/arm/plat-omap/include/plat/dma.h | 3 |
2 files changed, 37 insertions, 2 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 420cef370b3..f5c5b8da9a8 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
| 31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
| 32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 33 | #include <linux/delay.h> | ||
| 33 | 34 | ||
| 34 | #include <asm/system.h> | 35 | #include <asm/system.h> |
| 35 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
| @@ -1024,8 +1025,39 @@ void omap_stop_dma(int lch) | |||
| 1024 | dma_write(0, CICR(lch)); | 1025 | dma_write(0, CICR(lch)); |
| 1025 | 1026 | ||
| 1026 | l = dma_read(CCR(lch)); | 1027 | l = dma_read(CCR(lch)); |
| 1027 | l &= ~OMAP_DMA_CCR_EN; | 1028 | /* OMAP3 Errata i541: sDMA FIFO draining does not finish */ |
| 1028 | dma_write(l, CCR(lch)); | 1029 | if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) { |
| 1030 | int i = 0; | ||
| 1031 | u32 sys_cf; | ||
| 1032 | |||
| 1033 | /* Configure No-Standby */ | ||
| 1034 | l = dma_read(OCP_SYSCONFIG); | ||
| 1035 | sys_cf = l; | ||
| 1036 | l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK; | ||
| 1037 | l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE); | ||
| 1038 | dma_write(l , OCP_SYSCONFIG); | ||
| 1039 | |||
| 1040 | l = dma_read(CCR(lch)); | ||
| 1041 | l &= ~OMAP_DMA_CCR_EN; | ||
| 1042 | dma_write(l, CCR(lch)); | ||
| 1043 | |||
| 1044 | /* Wait for sDMA FIFO drain */ | ||
| 1045 | l = dma_read(CCR(lch)); | ||
| 1046 | while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE | | ||
| 1047 | OMAP_DMA_CCR_WR_ACTIVE))) { | ||
| 1048 | udelay(5); | ||
| 1049 | i++; | ||
| 1050 | l = dma_read(CCR(lch)); | ||
| 1051 | } | ||
| 1052 | if (i >= 100) | ||
| 1053 | printk(KERN_ERR "DMA drain did not complete on " | ||
| 1054 | "lch %d\n", lch); | ||
| 1055 | /* Restore OCP_SYSCONFIG */ | ||
| 1056 | dma_write(sys_cf, OCP_SYSCONFIG); | ||
| 1057 | } else { | ||
| 1058 | l &= ~OMAP_DMA_CCR_EN; | ||
| 1059 | dma_write(l, CCR(lch)); | ||
| 1060 | } | ||
| 1029 | 1061 | ||
| 1030 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { | 1062 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { |
| 1031 | int next_lch, cur_lch = lch; | 1063 | int next_lch, cur_lch = lch; |
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h index 6f70f7cfe91..0cce4ca83aa 100644 --- a/arch/arm/plat-omap/include/plat/dma.h +++ b/arch/arm/plat-omap/include/plat/dma.h | |||
| @@ -337,6 +337,9 @@ | |||
| 337 | #define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11) | 337 | #define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11) |
| 338 | 338 | ||
| 339 | #define OMAP_DMA_CCR_EN (1 << 7) | 339 | #define OMAP_DMA_CCR_EN (1 << 7) |
| 340 | #define OMAP_DMA_CCR_RD_ACTIVE (1 << 9) | ||
| 341 | #define OMAP_DMA_CCR_WR_ACTIVE (1 << 10) | ||
| 342 | #define OMAP_DMA_CCR_SEL_SRC_DST_SYNC (1 << 24) | ||
| 340 | #define OMAP_DMA_CCR_BUFFERING_DISABLE (1 << 25) | 343 | #define OMAP_DMA_CCR_BUFFERING_DISABLE (1 << 25) |
| 341 | 344 | ||
| 342 | #define OMAP_DMA_DATA_TYPE_S8 0x00 | 345 | #define OMAP_DMA_DATA_TYPE_S8 0x00 |
