Skip to content

Commit e7485f0

Browse files
Peter Ujfalusigregkh
authored andcommitted
dmaengine: edma: Align the memcpy acnt array size with the transfer
commit 87a2f622cc6446c7d09ac655b7b9b04886f16a4c 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 <peter.ujfalusi@ti.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 29b202e commit e7485f0

1 file changed

Lines changed: 16 additions & 3 deletions

File tree

drivers/dma/edma.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,11 +1126,24 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
11261126
struct edma_desc *edesc;
11271127
struct device *dev = chan->device->dev;
11281128
struct edma_chan *echan = to_edma_chan(chan);
1129-
unsigned int width, pset_len;
1129+
unsigned int width, pset_len, array_size;
11301130

11311131
if (unlikely(!echan || !len))
11321132
return NULL;
11331133

1134+
/* Align the array size (acnt block) with the transfer properties */
1135+
switch (__ffs((src | dest | len))) {
1136+
case 0:
1137+
array_size = SZ_32K - 1;
1138+
break;
1139+
case 1:
1140+
array_size = SZ_32K - 2;
1141+
break;
1142+
default:
1143+
array_size = SZ_32K - 4;
1144+
break;
1145+
}
1146+
11341147
if (len < SZ_64K) {
11351148
/*
11361149
* Transfer size less than 64K can be handled with one paRAM
@@ -1152,7 +1165,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
11521165
* When the full_length is multibple of 32767 one slot can be
11531166
* used to complete the transfer.
11541167
*/
1155-
width = SZ_32K - 1;
1168+
width = array_size;
11561169
pset_len = rounddown(len, width);
11571170
/* One slot is enough for lengths multiple of (SZ_32K -1) */
11581171
if (unlikely(pset_len == len))
@@ -1202,7 +1215,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
12021215
}
12031216
dest += pset_len;
12041217
src += pset_len;
1205-
pset_len = width = len % (SZ_32K - 1);
1218+
pset_len = width = len % array_size;
12061219

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

0 commit comments

Comments
 (0)