diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2011-10-16 09:59:30 +0300 |
---|---|---|
committer | Simon Wilson <simonwilson@google.com> | 2011-10-17 14:22:14 -0700 |
commit | 2bff37ce695b31db5a6405ffc990396710e94524 (patch) | |
tree | d4fb78b0394dd7fb49e782c7caafadffa5d001a8 /arch/arm | |
parent | a2d3bcfe878b8ab28e60474d2f1a35332acf98ae (diff) | |
download | kernel_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.c | 18 |
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); |