Skip to content

Commit

Permalink
dmaengine: fsl-edma: change the memory access from local into remote …
Browse files Browse the repository at this point in the history
…mode in i.MX 8QM

[ Upstream commit 8ddad558997002ce67980e30c9e8dfaa696e163b ]

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: 72f5801 ("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: Sasha Levin <sashal@kernel.org>
(cherry picked from commit c91c8d3830faa9f6f3dd9b600419c3bd14c9589b)
  • Loading branch information
1991Joyzou authored and Avenger-285714 committed Aug 12, 2024
1 parent 067eb8c commit f1bdf2e
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 1 deletion.
3 changes: 3 additions & 0 deletions drivers/dma/fsl-edma-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,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,
Expand Down Expand Up @@ -825,6 +827,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);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/dma/fsl-edma-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/dma/fsl-edma-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,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,
Expand Down

0 comments on commit f1bdf2e

Please sign in to comment.