diff options
author | Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com> | 2010-12-01 05:49:48 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2010-12-07 18:07:08 -0500 |
commit | 943d8d8bca431d6c93f17bf38f4b09c65e0a81d7 (patch) | |
tree | e9b81cba5e8c3f761a4848c4e7de73e4ab0b5aab /drivers/dma/pch_dma.c | |
parent | cf2f9c59807f173b1c6a537fde7c83c8da876e56 (diff) |
dma : EG20T PCH: Fix miss-setting DMA descriptor
Currently, in case of using scatter/gather mode, head of data is not sent to
destination. The cause is second descriptor address is set to NEXT.
The NEXT must have head of descriptor address.
This patch sets head of descriptor address to the NEXT.
Acked-by: Yong Wang <youg.y.wang@intel.com>
Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
[dan.j.williams@intel.com: fixed up usage of virt_to_phys()]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma/pch_dma.c')
-rw-r--r-- | drivers/dma/pch_dma.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 92b679024fed..c064c89420d0 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c | |||
@@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
259 | return; | 259 | return; |
260 | } | 260 | } |
261 | 261 | ||
262 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
263 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
264 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
265 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
266 | |||
267 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", | 262 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", |
268 | pd_chan->chan.chan_id, desc->regs.dev_addr); | 263 | pd_chan->chan.chan_id, desc->regs.dev_addr); |
269 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", | 264 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", |
@@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
273 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", | 268 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", |
274 | pd_chan->chan.chan_id, desc->regs.next); | 269 | pd_chan->chan.chan_id, desc->regs.next); |
275 | 270 | ||
276 | if (list_empty(&desc->tx_list)) | 271 | if (list_empty(&desc->tx_list)) { |
272 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
273 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
274 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
275 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
277 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); | 276 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); |
278 | else | 277 | } else { |
278 | channel_writel(pd_chan, NEXT, desc->txd.phys); | ||
279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); | 279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); |
280 | } | ||
280 | 281 | ||
281 | val = dma_readl(pd, CTL2); | 282 | val = dma_readl(pd, CTL2); |
282 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); | 283 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); |