|
@@ -1143,11 +1143,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
|
|
@@ -1169,7 +1182,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))
|
|
@@ -1217,7 +1230,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);
|