On Wed, Mar 09, 2022 at 03:12:01PM -0600, Frank Li wrote: > From: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> > > When eDMA is controlled by the Endpoint (EP), the current logic incorrectly > programs the source and destination addresses for read and write. Since the > Root complex and Endpoint uses the opposite channels for read/write, fix the > issue by finding out the read operation first and program the eDMA accordingly. > > Cc: stable@xxxxxxxxxxxxxxx > Fixes: bd96f1b2f43a ("dmaengine: dw-edma: support local dma device transfer semantics") > Fixes: e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver") > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> > Signed-off-by: Frank Li <Frank.Li@xxxxxxx> > --- > No change between v1 to v4 > > drivers/dma/dw-edma/dw-edma-core.c | 32 +++++++++++++++++++++++++++++- > 1 file changed, 31 insertions(+), 1 deletion(-) > > diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c > index 66dc650577919..507f08db1aad3 100644 > --- a/drivers/dma/dw-edma/dw-edma-core.c > +++ b/drivers/dma/dw-edma/dw-edma-core.c > @@ -334,6 +334,7 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) > struct dw_edma_chunk *chunk; > struct dw_edma_burst *burst; > struct dw_edma_desc *desc; > + bool read = false; > u32 cnt = 0; > int i; > > @@ -424,7 +425,36 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) > chunk->ll_region.sz += burst->sz; > desc->alloc_sz += burst->sz; > > - if (chan->dir == EDMA_DIR_WRITE) { > + /**************************************************************** > + * > + * Root Complex Endpoint > + * +-----------------------+ +----------------------+ > + * | | TX CH | | > + * | | | | > + * | DEV_TO_MEM <-------------+ MEM_TO_DEV | > + * | | | | > + * | | | | > + * | MEM_TO_DEV +-------------> DEV_TO_MEM | > + * | | | | > + * | | RX CH | | > + * +-----------------------+ +----------------------+ > + * > + * If eDMA is controlled by the Root complex, TX channel > + * (EDMA_DIR_WRITE) is used for memory read (DEV_TO_MEM) and RX > + * channel (EDMA_DIR_READ) is used for memory write (MEM_TO_DEV). > + * > + * If eDMA is controlled by the endpoint, RX channel > + * (EDMA_DIR_READ) is used for memory read (DEV_TO_MEM) and TX > + * channel (EDMA_DIR_WRITE) is used for memory write (MEM_TO_DEV). Either I have some wrong notion about this issue, or something wrong with the explanation above and with this fix below.