summaryrefslogtreecommitdiff
path: root/drivers/dma
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2012-01-16 17:39:12 +0800
committerJason Liu <r64343@freescale.com>2012-01-19 12:41:33 +0800
commita1a43335ccbf5578eb48edbf16c11e53d76c0123 (patch)
tree286503a98f72009d099444b9995047fc5cc8dcc6 /drivers/dma
parent4c752387bfcecfc5dbdc6b7cf87db420a5b89730 (diff)
ENGR00169906-4 MXS-DMA : change the last parameter of mxs_dma_prep_slave_sg()
For a long DMA chain which may have more then two DMA Command Structures, the current DMA code sets the WAIT4END bit at the last one, such as: +-----+ +-----+ +-----+ | cmd | ------------> | cmd | ------------------> | cmd | +-----+ +-----+ +-----+ ^ | | set WAIT4END here But in the NAND ECC read case, the WAIT4END bit should be set not only at the last DMA Command Structure, but also at the middle one, such as: +-----+ +-----+ +-----+ | cmd | ------------> | cmd | ------------------> | cmd | +-----+ +-----+ +-----+ ^ ^ | | | | set WAIT4END here too set WAIT4END here We set the WAIT4END in the middle DMA Command Structure to ensure the BCH module finishs its job. If we do not wait in this situation, the BCH module may be changed in the following DMA Command Structures, and it maybe becomes unstable which will cause a DMA timeout This has been catched in the MX6Q board. So rewrite the last parameter of mxs_dma_prep_slave_sg(). Add some more flags to let the driver sets the WAIT4END as it needs. Acked-by: Jason Liu <r64343@freescale.com> Signed-off-by: Huang Shijie <b32955@freescale.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/mxs-dma.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 6899f811ea1b..dda7525674b9 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* Refer to drivers/dma/imx-sdma.c
*
@@ -381,7 +381,7 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
struct dma_chan *chan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_data_direction direction,
- unsigned long append)
+ unsigned long flags)
{
struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
@@ -390,6 +390,7 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
int i, j;
u32 *pio;
static int idx;
+ bool append = flags & MXS_DMA_F_APPEND;
if (mxs_chan->status == DMA_IN_PROGRESS && !append)
return NULL;
@@ -415,7 +416,6 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
ccw->bits |= CCW_CHAIN;
ccw->bits &= ~CCW_IRQ;
ccw->bits &= ~CCW_DEC_SEM;
- ccw->bits &= ~CCW_WAIT4END;
} else {
idx = 0;
}
@@ -430,7 +430,8 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
ccw->bits = 0;
ccw->bits |= CCW_IRQ;
ccw->bits |= CCW_DEC_SEM;
- ccw->bits |= CCW_WAIT4END;
+ if (flags & MXS_DMA_F_WAIT4END)
+ ccw->bits |= CCW_WAIT4END;
ccw->bits |= CCW_HALT_ON_TERM;
ccw->bits |= CCW_TERM_FLUSH;
ccw->bits |= BF_CCW(sg_len, PIO_NUM);
@@ -461,7 +462,8 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
ccw->bits &= ~CCW_CHAIN;
ccw->bits |= CCW_IRQ;
ccw->bits |= CCW_DEC_SEM;
- ccw->bits |= CCW_WAIT4END;
+ if (flags & MXS_DMA_F_WAIT4END)
+ ccw->bits |= CCW_WAIT4END;
}
}
}