Skip to content

Commit 618c786

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

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

drivers/dma/edma.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,11 +1143,24 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
11431143
struct edma_desc *edesc;
11441144
struct device *dev = chan->device->dev;
11451145
struct edma_chan *echan = to_edma_chan(chan);
1146-
unsigned int width, pset_len;
1146+
unsigned int width, pset_len, array_size;
11471147

11481148
if (unlikely(!echan || !len))
11491149
return NULL;
11501150

1151+
/* Align the array size (acnt block) with the transfer properties */
1152+
switch (__ffs((src | dest | len))) {
1153+
case 0:
1154+
array_size = SZ_32K - 1;
1155+
break;
1156+
case 1:
1157+
array_size = SZ_32K - 2;
1158+
break;
1159+
default:
1160+
array_size = SZ_32K - 4;
1161+
break;
1162+
}
1163+
11511164
if (len < SZ_64K) {
11521165
/*
11531166
* Transfer size less than 64K can be handled with one paRAM
@@ -1169,7 +1182,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
11691182
* When the full_length is multibple of 32767 one slot can be
11701183
* used to complete the transfer.
11711184
*/
1172-
width = SZ_32K - 1;
1185+
width = array_size;
11731186
pset_len = rounddown(len, width);
11741187
/* One slot is enough for lengths multiple of (SZ_32K -1) */
11751188
if (unlikely(pset_len == len))
@@ -1217,7 +1230,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
12171230
}
12181231
dest += pset_len;
12191232
src += pset_len;
1220-
pset_len = width = len % (SZ_32K - 1);
1233+
pset_len = width = len % array_size;
12211234

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

0 commit comments

Comments
 (0)