dmaengine: pl330: Improve transfer efficiency for the dregs

Only the unaligned burst transfers have the dregs.
so, still use BURST transfer with a reduced size
for better performance.

Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
Link: https://lore.kernel.org/r/1593439555-68130-3-git-send-email-sugar.zhang@rock-chips.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Sugar Zhang 2020-06-29 22:05:43 +08:00 committed by Vinod Koul
parent 05611a93b8
commit 3e7f0bd872

View File

@ -1228,8 +1228,9 @@ static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
} }
/* /*
* transfer dregs with single transfers to peripheral, or a reduced size burst * only the unaligned burst transfers have the dregs.
* for mem-to-mem. * so, still transfer dregs with a reduced size burst
* for mem-to-mem, mem-to-dev or dev-to-mem.
*/ */
static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[], static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[],
const struct _xfer_spec *pxs, int transfer_length) const struct _xfer_spec *pxs, int transfer_length)
@ -1240,15 +1241,13 @@ static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[],
if (transfer_length == 0) if (transfer_length == 0)
return off; return off;
switch (pxs->desc->rqtype) { /*
case DMA_MEM_TO_DEV: * dregs_len = (total bytes - BURST_TO_BYTE(bursts, ccr)) /
/* fall through */ * BRST_SIZE(ccr)
case DMA_DEV_TO_MEM: * the dregs len must be smaller than burst len,
off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs, * so, for higher efficiency, we can modify CCR
transfer_length, SINGLE); * to use a reduced size burst len for the dregs.
break; */
case DMA_MEM_TO_MEM:
dregs_ccr = pxs->ccr; dregs_ccr = pxs->ccr;
dregs_ccr &= ~((0xf << CC_SRCBRSTLEN_SHFT) | dregs_ccr &= ~((0xf << CC_SRCBRSTLEN_SHFT) |
(0xf << CC_DSTBRSTLEN_SHFT)); (0xf << CC_DSTBRSTLEN_SHFT));
@ -1256,6 +1255,17 @@ static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[],
CC_SRCBRSTLEN_SHFT); CC_SRCBRSTLEN_SHFT);
dregs_ccr |= (((transfer_length - 1) & 0xf) << dregs_ccr |= (((transfer_length - 1) & 0xf) <<
CC_DSTBRSTLEN_SHFT); CC_DSTBRSTLEN_SHFT);
switch (pxs->desc->rqtype) {
case DMA_MEM_TO_DEV:
/* fall through */
case DMA_DEV_TO_MEM:
off += _emit_MOV(dry_run, &buf[off], CCR, dregs_ccr);
off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs, 1,
BURST);
break;
case DMA_MEM_TO_MEM:
off += _emit_MOV(dry_run, &buf[off], CCR, dregs_ccr); off += _emit_MOV(dry_run, &buf[off], CCR, dregs_ccr);
off += _ldst_memtomem(dry_run, &buf[off], pxs, 1); off += _ldst_memtomem(dry_run, &buf[off], pxs, 1);
break; break;