Skip to content

Commit

Permalink
dmaengine: xilinx_dma: Fix SG internal error in cdma prep_dma_sg mode
Browse files Browse the repository at this point in the history
In CDMA prep_dma_sg mode when source and destination scatterlist length
has more than one element, interrupt is generated on the first segment
(since IRQThreshold=1) instead of complete descriptor. In the driver we
free all descriptor segments on IOC but IP is still working on remaining
descriptor segments and as a result we see an SG internal error. To fix
this behavior set CDMACR.IRQThreshold to numbers of segments in a cdma
descriptor.

Signed-off-by: Radhey Shyam Pandey <[email protected]>
Acked-by: Appana Durga Kedareswara rao <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
  • Loading branch information
radheyxilinx authored and Michal Simek committed Sep 13, 2019
1 parent 0bac081 commit 552d3f1
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion drivers/dma/xilinx/xilinx_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1578,7 +1578,12 @@ static void append_desc_queue(struct xilinx_dma_chan *chan,
*/
append:
list_add_tail(&desc->node, &chan->pending_list);
chan->desc_pendingcount++;
/*
* In CDMA each segment is considered as a descriptor, so increment
* pending count in prep_slave_* implementation.
*/
if (chan->xdev->dma_config->dmatype != XDMA_TYPE_CDMA)
chan->desc_pendingcount++;

if (chan->has_sg && (chan->xdev->dma_config->dmatype == XDMA_TYPE_VDMA)
&& unlikely(chan->desc_pendingcount > chan->num_frms)) {
Expand Down Expand Up @@ -1758,6 +1763,7 @@ xilinx_cdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst,

/* Insert the segment into the descriptor segments list. */
list_add_tail(&segment->node, &desc->segments);
chan->desc_pendingcount++;

desc->async_tx.phys = segment->phys;
hw->next_desc = segment->phys;
Expand Down Expand Up @@ -1842,6 +1848,7 @@ static struct dma_async_tx_descriptor *xilinx_cdma_prep_sg(
dst_avail -= len;
src_avail -= len;
list_add_tail(&segment->node, &desc->segments);
chan->desc_pendingcount++;

fetch:
/* Fetch the next dst scatterlist entry */
Expand Down

0 comments on commit 552d3f1

Please sign in to comment.