diff options
author | Huang Shijie <b32955@freescale.com> | 2012-01-16 17:39:12 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-07-20 13:20:07 +0800 |
commit | d63a1b6eab2f26b27fe6556dc373532954555b54 (patch) | |
tree | c41f87ff9cd3b1c9cb4435cde41802dbdfa82d8a /drivers/dma | |
parent | 339d83818dd524e39a3c296dedff66ed353403ea (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.c | 12 |
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; } } } |