Commit 8ddad558 authored by Joy Zou's avatar Joy Zou Committed by Vinod Koul
Browse files

dmaengine: fsl-edma: change the memory access from local into remote mode in i.MX 8QM



Fix the issue where MEM_TO_MEM fail on i.MX8QM due to the requirement
that both source and destination addresses need pass through the IOMMU.
Typically, peripheral FIFO addresses bypass the IOMMU, necessitating
only one of the source or destination to go through it.

Set "is_remote" to true to ensure both source and destination
addresses pass through the IOMMU.

iMX8 Spec define "Local" and "Remote" bus as below.
Local bus: bypass IOMMU to directly access other peripheral register,
such as FIFO.
Remote bus: go through IOMMU to access system memory.

The test fail log as follow:
[ 66.268506] dmatest: dma0chan0-copy0: result #1: 'test timed out' with src_off=0x100 dst_off=0x80 len=0x3ec0 (0)
[ 66.278785] dmatest: dma0chan0-copy0: summary 1 tests, 1 failures 0.32 iops 4 KB/s (0)

Fixes: 72f5801a ("dmaengine: fsl-edma: integrate v3 support")
Signed-off-by: default avatarJoy Zou <joy.zou@nxp.com>
Cc: stable@vger.kernel.org
Reviewed-by: default avatarFrank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20240510030959.703663-1-joy.zou@nxp.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 7dcf9e82
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -755,6 +755,8 @@ struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(struct dma_chan *chan,
	fsl_desc->iscyclic = false;

	fsl_chan->is_sw = true;
	if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_MEM_REMOTE)
		fsl_chan->is_remote = true;

	/* To match with copy_align and max_seg_size so 1 tcd is enough */
	fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[0].vtcd, dma_src, dma_dst,
@@ -848,6 +850,7 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan)
	fsl_chan->tcd_pool = NULL;
	fsl_chan->is_sw = false;
	fsl_chan->srcid = 0;
	fsl_chan->is_remote = false;
	if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK)
		clk_disable_unprepare(fsl_chan->clk);
}
+1 −0
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ struct fsl_edma_desc {
#define FSL_EDMA_DRV_HAS_PD		BIT(5)
#define FSL_EDMA_DRV_HAS_CHCLK		BIT(6)
#define FSL_EDMA_DRV_HAS_CHMUX		BIT(7)
#define FSL_EDMA_DRV_MEM_REMOTE		BIT(8)
/* control and status register is in tcd address space, edma3 reg layout */
#define FSL_EDMA_DRV_SPLIT_REG		BIT(9)
#define FSL_EDMA_DRV_BUS_8BYTE		BIT(10)
+1 −1
Original line number Diff line number Diff line
@@ -343,7 +343,7 @@ static struct fsl_edma_drvdata imx7ulp_data = {
};

static struct fsl_edma_drvdata imx8qm_data = {
	.flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3,
	.flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MEM_REMOTE,
	.chreg_space_sz = 0x10000,
	.chreg_off = 0x10000,
	.setup_irq = fsl_edma3_irq_init,