Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e538578 authored by Maxime Ripard's avatar Maxime Ripard Committed by Vinod Koul
Browse files

dmaengine: at_xdmac: handle numf > 1



Handle 'numf > 1' case for interleaved mode.

Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: default avatarLudovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
parent 1a492ac2
Loading
Loading
Loading
Loading
+50 −54
Original line number Diff line number Diff line
@@ -929,13 +929,19 @@ at_xdmac_prep_interleaved(struct dma_chan *chan,
{
	struct at_xdmac_chan	*atchan = to_at_xdmac_chan(chan);
	struct at_xdmac_desc	*prev = NULL, *first = NULL;
	struct data_chunk	*chunk, *prev_chunk = NULL;
	dma_addr_t		dst_addr, src_addr;
	size_t			dst_skip, src_skip, len = 0;
	size_t			prev_dst_icg = 0, prev_src_icg = 0;
	size_t			src_skip = 0, dst_skip = 0, len = 0;
	struct data_chunk	*chunk;
	int			i;

	if (!xt || (xt->numf != 1) || (xt->dir != DMA_MEM_TO_MEM))
	if (!xt || !xt->numf || (xt->dir != DMA_MEM_TO_MEM))
		return NULL;

	/*
	 * TODO: Handle the case where we have to repeat a chain of
	 * descriptors...
	 */
	if ((xt->numf > 1) && (xt->frame_size > 1))
		return NULL;

	dev_dbg(chan2dev(chan), "%s: src=0x%08x, dest=0x%08x, numf=%d, frame_size=%d, flags=0x%lx\n",
@@ -945,9 +951,17 @@ at_xdmac_prep_interleaved(struct dma_chan *chan,
	src_addr = xt->src_start;
	dst_addr = xt->dst_start;

	if (xt->numf > 1) {
		first = at_xdmac_interleaved_queue_desc(chan, atchan,
							NULL,
							src_addr, dst_addr,
							xt, xt->sgl);
		for (i = 0; i < xt->numf; i++)
			at_xdmac_increment_block_count(chan, first);
	} else {
		for (i = 0; i < xt->frame_size; i++) {
			size_t src_icg = 0, dst_icg = 0;
			struct at_xdmac_desc *desc;
		size_t src_icg, dst_icg;

			chunk = xt->sgl + i;

@@ -961,22 +975,6 @@ at_xdmac_prep_interleaved(struct dma_chan *chan,
				"%s: chunk size=%d, src icg=%d, dst icg=%d\n",
				__func__, chunk->size, src_icg, dst_icg);

		/*
		 * Handle the case where we just have the same
		 * transfer to setup, we can just increase the
		 * block number and reuse the same descriptor.
		 */
		if (prev_chunk && prev &&
		    (prev_chunk->size == chunk->size) &&
		    (prev_src_icg == src_icg) &&
		    (prev_dst_icg == dst_icg)) {
			dev_dbg(chan2dev(chan),
				"%s: same configuration that the previous chunk, merging the descriptors...\n",
				__func__);
			at_xdmac_increment_block_count(chan, prev);
			continue;
		}

			desc = at_xdmac_interleaved_queue_desc(chan, atchan,
							       prev,
							       src_addr, dst_addr,
@@ -1001,11 +999,9 @@ at_xdmac_prep_interleaved(struct dma_chan *chan,
				dst_addr += dst_skip;

			len += chunk->size;
		prev_chunk = chunk;
		prev_dst_icg = dst_icg;
		prev_src_icg = src_icg;
			prev = desc;
		}
	}

	first->tx_dma_desc.cookie = -EBUSY;
	first->tx_dma_desc.flags = flags;