aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2011-10-16 09:59:30 +0300
committerSimon Wilson <simonwilson@google.com>2011-10-17 14:22:14 -0700
commit2bff37ce695b31db5a6405ffc990396710e94524 (patch)
treed4fb78b0394dd7fb49e782c7caafadffa5d001a8 /arch/arm
parenta2d3bcfe878b8ab28e60474d2f1a35332acf98ae (diff)
downloadkernel_samsung_tuna-2bff37ce695b31db5a6405ffc990396710e94524.zip
kernel_samsung_tuna-2bff37ce695b31db5a6405ffc990396710e94524.tar.gz
kernel_samsung_tuna-2bff37ce695b31db5a6405ffc990396710e94524.tar.bz2
OMAP2+: DMA: Workaround for invalid source position
If the DMA source position has been asked before the first actual data transfer has been done, the CSAC register does not contain valid information. We can identify this situation by checking the CDAC register: CDAC != 0 indicates that the DMA transfer on the channel has been started already. If CDAC == 0, we can not trust the CSAC value since it has not been updated, and can contain random number. Return the start address in case the DMA has not yet started. This is valid since in fact the DMA has not yet progressed. Note: The CDAC register has been initialized to 0 at dma_start time. Change-Id: Iebbf4660945d5ee204f06916e023da958de45be6 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/plat-omap/dma.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c22217c..3ec7ec5 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1024,12 +1024,26 @@ EXPORT_SYMBOL(omap_set_dma_callback);
*/
dma_addr_t omap_get_dma_src_pos(int lch)
{
+ u32 cdac;
dma_addr_t offset = 0;
if (cpu_is_omap15xx())
offset = p->dma_read(CPC, lch);
- else
- offset = p->dma_read(CSAC, lch);
+ else {
+ /*
+ * CDAC != 0 indicates that the DMA transfer on the channel has
+ * been started already.
+ * If CDAC == 0, we can not trust the CSAC value since it has
+ * not been updated, and can contain random number.
+ * Return the start address in case the DMA has not jet started.
+ * This is valid since in fact the DMA has not yet progressed.
+ */
+ cdac = p->dma_read(CDAC, lch);
+ if (likely(cdac))
+ offset = p->dma_read(CSAC, lch);
+ else
+ offset = p->dma_read(CSSA, lch);
+ }
if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0)
offset = p->dma_read(CSAC, lch);