Skip to content

Commit

Permalink
dmaengine: edma: Align the memcpy acnt array size with the transfer
Browse files Browse the repository at this point in the history
commit 87a2f62 upstream.

Memory to Memory transfers does not have any special alignment needs
regarding to acnt array size, but if one of the areas are in memory mapped
regions (like PCIe memory), we need to make sure that the acnt array size
is aligned with the mem copy parameters.

Before "dmaengine: edma: Optimize memcpy operation" change the memcpy was set
up in a different way: acnt == number of bytes in a word based on
__ffs((src | dest | len), bcnt and ccnt for looping the necessary number of
words to comlete the trasnfer.

Instead of reverting the commit we can fix it to make sure that the ACNT size
is aligned to the traswnfer.

Fixes: df6694f (dmaengine: edma: Optimize memcpy operation)
Signed-off-by: Peter Ujfalusi <[email protected]>
Signed-off-by: Vinod Koul <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
Peter Ujfalusi authored and gregkh committed Oct 18, 2017
1 parent 29b202e commit e7485f0
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions drivers/dma/edma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1126,11 +1126,24 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
struct edma_desc *edesc;
struct device *dev = chan->device->dev;
struct edma_chan *echan = to_edma_chan(chan);
unsigned int width, pset_len;
unsigned int width, pset_len, array_size;

if (unlikely(!echan || !len))
return NULL;

/* Align the array size (acnt block) with the transfer properties */
switch (__ffs((src | dest | len))) {
case 0:
array_size = SZ_32K - 1;
break;
case 1:
array_size = SZ_32K - 2;
break;
default:
array_size = SZ_32K - 4;
break;
}

if (len < SZ_64K) {
/*
* Transfer size less than 64K can be handled with one paRAM
Expand All @@ -1152,7 +1165,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
* When the full_length is multibple of 32767 one slot can be
* used to complete the transfer.
*/
width = SZ_32K - 1;
width = array_size;
pset_len = rounddown(len, width);
/* One slot is enough for lengths multiple of (SZ_32K -1) */
if (unlikely(pset_len == len))
Expand Down Expand Up @@ -1202,7 +1215,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
}
dest += pset_len;
src += pset_len;
pset_len = width = len % (SZ_32K - 1);
pset_len = width = len % array_size;

ret = edma_config_pset(chan, &edesc->pset[1], src, dest, 1,
width, pset_len, DMA_MEM_TO_MEM);
Expand Down

0 comments on commit e7485f0

Please sign in to comment.