aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-01-27 11:33:29 -0500
committerVinod Koul <vinod.koul@intel.com>2015-02-15 23:03:34 -0500
commit3f46306127bb7d8a69078ff9ef8a5827677c2159 (patch)
treee1f0acc09d71f37b906cc56901392496ce83ea8a /drivers/dma
parent6a634808e315a148dfe8db925215cbaaa3ea1831 (diff)
dmaengine: rcar-dmac: Work around descriptor mode IOMMU errata
When descriptor memory is accessed through an IOMMU the DMADAR register isn't initialized automatically from the first descriptor at beginning of transfer by the DMAC like it should. Initialize it manually with the destination address of the first chunk. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Acked-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/sh/rcar-dmac.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index bb93038c48b9..711da01a200b 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -325,6 +325,8 @@ static void rcar_dmac_chan_start_xfer(struct rcar_dmac_chan *chan)
325 rcar_dmac_chan_write(chan, RCAR_DMARS, chan->mid_rid); 325 rcar_dmac_chan_write(chan, RCAR_DMARS, chan->mid_rid);
326 326
327 if (desc->hwdescs.use) { 327 if (desc->hwdescs.use) {
328 struct rcar_dmac_xfer_chunk *chunk;
329
328 dev_dbg(chan->chan.device->dev, 330 dev_dbg(chan->chan.device->dev,
329 "chan%u: queue desc %p: %u@%pad\n", 331 "chan%u: queue desc %p: %u@%pad\n",
330 chan->index, desc, desc->nchunks, &desc->hwdescs.dma); 332 chan->index, desc, desc->nchunks, &desc->hwdescs.dma);
@@ -341,6 +343,18 @@ static void rcar_dmac_chan_start_xfer(struct rcar_dmac_chan *chan)
341 RCAR_DMACHCRB_DRST); 343 RCAR_DMACHCRB_DRST);
342 344
343 /* 345 /*
346 * Errata: When descriptor memory is accessed through an IOMMU
347 * the DMADAR register isn't initialized automatically from the
348 * first descriptor at beginning of transfer by the DMAC like it
349 * should. Initialize it manually with the destination address
350 * of the first chunk.
351 */
352 chunk = list_first_entry(&desc->chunks,
353 struct rcar_dmac_xfer_chunk, node);
354 rcar_dmac_chan_write(chan, RCAR_DMADAR,
355 chunk->dst_addr & 0xffffffff);
356
357 /*
344 * Program the descriptor stage interrupt to occur after the end 358 * Program the descriptor stage interrupt to occur after the end
345 * of the first stage. 359 * of the first stage.
346 */ 360 */