Skip to content

Commit 1ecd8b6

Browse files
hanxu-nxpvinodkoul
authored andcommitted
dmaengine: fsl-edma: configure tcd attr with separate src and dst settings
Set the edma tcd transfer attribution settings for the src and dst based on their respective dma_addr values, to remove the previous 32-byte alignment limitation in the EDMA memcpy function. Signed-off-by: Han Xu <han.xu@nxp.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20251119163255.502070-1-han.xu@nxp.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent cd3ba11 commit 1ecd8b6

1 file changed

Lines changed: 33 additions & 12 deletions

File tree

drivers/dma/fsl-edma-common.c

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,19 @@ void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
206206
mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable);
207207
}
208208

209-
static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth addr_width)
209+
static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth src_addr_width,
210+
enum dma_slave_buswidth dst_addr_width)
210211
{
211-
u32 val;
212+
u32 src_val, dst_val;
212213

213-
if (addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
214-
addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
214+
if (src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
215+
src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
216+
if (dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
217+
dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
215218

216-
val = ffs(addr_width) - 1;
217-
return val | (val << 8);
219+
src_val = ffs(src_addr_width) - 1;
220+
dst_val = ffs(dst_addr_width) - 1;
221+
return dst_val | (src_val << 8);
218222
}
219223

220224
void fsl_edma_free_desc(struct virt_dma_desc *vdesc)
@@ -612,13 +616,19 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
612616

613617
dma_buf_next = dma_addr;
614618
if (direction == DMA_MEM_TO_DEV) {
619+
if (!fsl_chan->cfg.src_addr_width)
620+
fsl_chan->cfg.src_addr_width = fsl_chan->cfg.dst_addr_width;
615621
fsl_chan->attr =
616-
fsl_edma_get_tcd_attr(fsl_chan->cfg.dst_addr_width);
622+
fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width,
623+
fsl_chan->cfg.dst_addr_width);
617624
nbytes = fsl_chan->cfg.dst_addr_width *
618625
fsl_chan->cfg.dst_maxburst;
619626
} else {
627+
if (!fsl_chan->cfg.dst_addr_width)
628+
fsl_chan->cfg.dst_addr_width = fsl_chan->cfg.src_addr_width;
620629
fsl_chan->attr =
621-
fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width);
630+
fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width,
631+
fsl_chan->cfg.dst_addr_width);
622632
nbytes = fsl_chan->cfg.src_addr_width *
623633
fsl_chan->cfg.src_maxburst;
624634
}
@@ -689,13 +699,19 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
689699
fsl_desc->dirn = direction;
690700

691701
if (direction == DMA_MEM_TO_DEV) {
702+
if (!fsl_chan->cfg.src_addr_width)
703+
fsl_chan->cfg.src_addr_width = fsl_chan->cfg.dst_addr_width;
692704
fsl_chan->attr =
693-
fsl_edma_get_tcd_attr(fsl_chan->cfg.dst_addr_width);
705+
fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width,
706+
fsl_chan->cfg.dst_addr_width);
694707
nbytes = fsl_chan->cfg.dst_addr_width *
695708
fsl_chan->cfg.dst_maxburst;
696709
} else {
710+
if (!fsl_chan->cfg.dst_addr_width)
711+
fsl_chan->cfg.dst_addr_width = fsl_chan->cfg.src_addr_width;
697712
fsl_chan->attr =
698-
fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width);
713+
fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width,
714+
fsl_chan->cfg.dst_addr_width);
699715
nbytes = fsl_chan->cfg.src_addr_width *
700716
fsl_chan->cfg.src_maxburst;
701717
}
@@ -766,6 +782,10 @@ struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(struct dma_chan *chan,
766782
{
767783
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
768784
struct fsl_edma_desc *fsl_desc;
785+
u32 src_bus_width, dst_bus_width;
786+
787+
src_bus_width = min_t(u32, DMA_SLAVE_BUSWIDTH_32_BYTES, 1 << (ffs(dma_src) - 1));
788+
dst_bus_width = min_t(u32, DMA_SLAVE_BUSWIDTH_32_BYTES, 1 << (ffs(dma_dst) - 1));
769789

770790
fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1);
771791
if (!fsl_desc)
@@ -778,8 +798,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(struct dma_chan *chan,
778798

779799
/* To match with copy_align and max_seg_size so 1 tcd is enough */
780800
fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[0].vtcd, dma_src, dma_dst,
781-
fsl_edma_get_tcd_attr(DMA_SLAVE_BUSWIDTH_32_BYTES),
782-
32, len, 0, 1, 1, 32, 0, true, true, false);
801+
fsl_edma_get_tcd_attr(src_bus_width, dst_bus_width),
802+
src_bus_width, len, 0, 1, 1, dst_bus_width, 0, true,
803+
true, false);
783804

784805
return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
785806
}

0 commit comments

Comments
 (0)