]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dmaengine: fsl-edma: change the memory access from local into remote mode in i.MX 8QM
authorJoy Zou <joy.zou@nxp.com>
Fri, 10 May 2024 03:09:34 +0000 (11:09 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 3 Aug 2024 07:00:46 +0000 (09:00 +0200)
commit 8ddad558997002ce67980e30c9e8dfaa696e163b upstream.

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: 72f5801a4e2b ("dmaengine: fsl-edma: integrate v3 support")
Signed-off-by: Joy Zou <joy.zou@nxp.com>
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20240510030959.703663-1-joy.zou@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/dma/fsl-edma-common.c
drivers/dma/fsl-edma-common.h
drivers/dma/fsl-edma-main.c

index 3af4307873157e6cfbf44009e56f83645911b412..0af934b56a6cbcff16c0a0cb3e9d0d0130884b04 100644 (file)
@@ -758,6 +758,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,
@@ -837,6 +839,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);
 }
index ac66222c160405efa939d8eeac993c4e295f1663..268db3876787cbc1a266bd61e481df0aef4ca4fb 100644 (file)
@@ -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)
index 391e4f13dfeb036cb2db4e04878fc55401799f52..43d84cfefbe20b819006c1c53c1a95047ab1a4eb 100644 (file)
@@ -342,7 +342,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,