Commit 3e7f0bd8 authored by Sugar Zhang's avatar Sugar Zhang Committed by Vinod Koul
Browse files

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: default avatarSugar 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: default avatarVinod Koul <vkoul@kernel.org>
parent 05611a93
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -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
 * for mem-to-mem.
 * only the unaligned burst transfers have the dregs.
 * 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[],
		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)
		return off;

	switch (pxs->desc->rqtype) {
	case DMA_MEM_TO_DEV:
		/* fall through */
	case DMA_DEV_TO_MEM:
		off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs,
			transfer_length, SINGLE);
		break;

	case DMA_MEM_TO_MEM:
	/*
	 * dregs_len = (total bytes - BURST_TO_BYTE(bursts, ccr)) /
	 *             BRST_SIZE(ccr)
	 * the dregs len must be smaller than burst len,
	 * so, for higher efficiency, we can modify CCR
	 * to use a reduced size burst len for the dregs.
	 */
	dregs_ccr = pxs->ccr;
	dregs_ccr &= ~((0xf << CC_SRCBRSTLEN_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);
	dregs_ccr |= (((transfer_length - 1) & 0xf) <<
		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 += _ldst_memtomem(dry_run, &buf[off], pxs, 1);
		break;