summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2008-11-05 07:20:37 -0500
committerMike Frysinger <vapier@gentoo.org>2009-02-02 12:24:46 -0500
commite347c092a3b3a2ce1e72f25f4829163634d09fbe (patch)
tree31860ae31f070abf8e75900e64bfa55de3bb32bb
parentfdce83c108846d6f0d5b1774e1cc29f2573a6ad3 (diff)
downloadu-boot-imx-e347c092a3b3a2ce1e72f25f4829163634d09fbe.zip
u-boot-imx-e347c092a3b3a2ce1e72f25f4829163634d09fbe.tar.gz
u-boot-imx-e347c092a3b3a2ce1e72f25f4829163634d09fbe.tar.bz2
Blackfin: dma_memcpy(): fix random failures
We have to make sure the DMA channel is actually disabled in hardware before attempting to reprogram it. Otherwise the new settings are ignored and we end up with random hangs/failures. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--lib_blackfin/string.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/lib_blackfin/string.c b/lib_blackfin/string.c
index 36eecdf..e458718 100644
--- a/lib_blackfin/string.c
+++ b/lib_blackfin/string.c
@@ -136,6 +136,14 @@ int strncmp(const char *cs, const char *ct, size_t count)
*/
void dma_memcpy_nocache(void *dst, const void *src, size_t count)
{
+ /* Disable DMA in case it's still running (older u-boot's did not
+ * always turn them off). Do it before the if statement below so
+ * we can be cheap and not do a SSYNC() due to the forced abort.
+ */
+ bfin_write_MDMA_D0_CONFIG(0);
+ bfin_write_MDMA_S0_CONFIG(0);
+ bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR);
+
/* Scratchpad cannot be a DMA source or destination */
if (((unsigned long)src >= L1_SRAM_SCRATCH &&
(unsigned long)src < L1_SRAM_SCRATCH_END) ||
@@ -143,10 +151,6 @@ void dma_memcpy_nocache(void *dst, const void *src, size_t count)
(unsigned long)dst < L1_SRAM_SCRATCH_END))
hang();
- bfin_write_MDMA_S0_CONFIG(0);
- bfin_write_MDMA_D0_CONFIG(0);
- bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR);
-
/* Copy sram functions from sdram to sram */
/* Setup destination start address */
bfin_write_MDMA_D0_START_ADDR(dst);
@@ -164,14 +168,13 @@ void dma_memcpy_nocache(void *dst, const void *src, size_t count)
/* Enable source DMA */
bfin_write_MDMA_S0_CONFIG(DMAEN);
-
- bfin_write_MDMA_D0_CONFIG(WNR | DMAEN);
+ bfin_write_MDMA_D0_CONFIG(WNR | DMAEN | DI_EN);
SSYNC();
- while (bfin_read_MDMA_D0_IRQ_STATUS() & DMA_RUN)
+ while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE))
continue;
- bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_RUN | DMA_DONE | DMA_ERR);
+ bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR);
bfin_write_MDMA_D0_CONFIG(0);
bfin_write_MDMA_S0_CONFIG(0);
}