linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][next] dmaengine: dw-edma: support local dma device transfer semantics
@ 2020-04-29  1:10 Alan Mikhak
  2020-05-04  5:29 ` Vinod Koul
  0 siblings, 1 reply; 2+ messages in thread
From: Alan Mikhak @ 2020-04-29  1:10 UTC (permalink / raw)
  To: dmaengine, linux-kernel, linux-pci, gustavo.pimentel,
	dan.j.williams, vkoul, kishon, paul.walmsley
  Cc: Alan Mikhak

From: Alan Mikhak <alan.mikhak@sifive.com>

Modify dw_edma_device_transfer() to also support the semantics of dma
device transfer for additional use cases involving pcitest utility as a
local initiator.

For its original use case, dw-edma supported the semantics of dma device
transfer from the perspective of a remote initiator who is located across
the PCIe bus from dma channel hardware.

To a remote initiator, DMA_DEV_TO_MEM means using a remote dma WRITE
channel to transfer from remote memory to local memory. A WRITE channel
would be employed on the remote device in order to move the contents of
remote memory to the bus destined for local memory.

To a remote initiator, DMA_MEM_TO_DEV means using a remote dma READ
channel to transfer from local memory to remote memory. A READ channel
would be employed on the remote device in order to move the contents of
local memory to the bus destined for remote memory.

From the perspective of a local dma initiator who is co-located on the
same side of the PCIe bus as the dma channel hardware, the semantics of
dma device transfer are flipped.

To a local initiator, DMA_DEV_TO_MEM means using a local dma READ channel
to transfer from remote memory to local memory. A READ channel would be
employed on the local device in order to move the contents of remote
memory to the bus destined for local memory.

To a local initiator, DMA_MEM_TO_DEV means using a local dma WRITE channel
to transfer from local memory to remote memory. A WRITE channel would be
employed on the local device in order to move the contents of local memory
to the bus destined for remote memory.

To support local dma initiators, dw_edma_device_transfer() is modified to
now examine the direction field of struct dma_slave_config for the channel
which initiators can configure by calling dmaengine_slave_config().

If direction is configured as either DMA_DEV_TO_MEM or DMA_MEM_TO_DEV,
local initiator semantics are used. If direction is a value other than
DMA_DEV_TO_MEM nor DMA_MEM_TO_DEV, then remote initiator semantics are
used. This should maintain backward compatibility with the original use
case of dw-edma.

The dw-edma-test utility is an example of a remote initiator. From reading
its patch, dw-edma-test does not specifically set the direction field of
struct dma_slave_config. Since dw_edma_device_transfer() also does not
check the direction field of struct dma_slave_config, it seems safe to use
this convention in dw-edma to support both local and remote initiator
semantics.

Signed-off-by: Alan Mikhak <alan.mikhak@sifive.com>

This patch depends on the following patches:

[PATCH v2] dmaengine: dw-edma: Decouple dw-edma-core.c from struct pci_dev
https://patchwork.kernel.org/patch/11491757/

[PATCH v2,next] dmaengine: dw-edma: Check MSI descriptor before copying
https://patchwork.kernel.org/patch/11504849/

Rebased on linux-next next-20200428 which has above patches applied.
---
 drivers/dma/dw-edma/dw-edma-core.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
index 306ab50462be..ed430ad9b3dd 100644
--- a/drivers/dma/dw-edma/dw-edma-core.c
+++ b/drivers/dma/dw-edma/dw-edma-core.c
@@ -323,7 +323,7 @@ static struct dma_async_tx_descriptor *
 dw_edma_device_transfer(struct dw_edma_transfer *xfer)
 {
 	struct dw_edma_chan *chan = dchan2dw_edma_chan(xfer->dchan);
-	enum dma_transfer_direction direction = xfer->direction;
+	enum dma_transfer_direction dir = xfer->direction;
 	phys_addr_t src_addr, dst_addr;
 	struct scatterlist *sg = NULL;
 	struct dw_edma_chunk *chunk;
@@ -332,10 +332,26 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
 	u32 cnt;
 	int i;
 
-	if ((direction == DMA_MEM_TO_DEV && chan->dir == EDMA_DIR_WRITE) ||
-	    (direction == DMA_DEV_TO_MEM && chan->dir == EDMA_DIR_READ))
+	if (!chan->configured)
 		return NULL;
 
+	switch (chan->config.direction) {
+	case DMA_DEV_TO_MEM: /* local dma */
+		if (dir == DMA_DEV_TO_MEM && chan->dir == EDMA_DIR_READ)
+			break;
+		return NULL;
+	case DMA_MEM_TO_DEV: /* local dma */
+		if (dir == DMA_MEM_TO_DEV && chan->dir == EDMA_DIR_WRITE)
+			break;
+		return NULL;
+	default: /* remote dma */
+		if (dir == DMA_MEM_TO_DEV && chan->dir == EDMA_DIR_READ)
+			break;
+		if (dir == DMA_DEV_TO_MEM && chan->dir == EDMA_DIR_WRITE)
+			break;
+		return NULL;
+	}
+
 	if (xfer->cyclic) {
 		if (!xfer->xfer.cyclic.len || !xfer->xfer.cyclic.cnt)
 			return NULL;
@@ -344,9 +360,6 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
 			return NULL;
 	}
 
-	if (!chan->configured)
-		return NULL;
-
 	desc = dw_edma_alloc_desc(chan);
 	if (unlikely(!desc))
 		goto err_alloc;
@@ -387,7 +400,7 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
 		chunk->ll_region.sz += burst->sz;
 		desc->alloc_sz += burst->sz;
 
-		if (direction == DMA_DEV_TO_MEM) {
+		if (chan->dir == EDMA_DIR_WRITE) {
 			burst->sar = src_addr;
 			if (xfer->cyclic) {
 				burst->dar = xfer->xfer.cyclic.paddr;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH][next] dmaengine: dw-edma: support local dma device transfer semantics
  2020-04-29  1:10 [PATCH][next] dmaengine: dw-edma: support local dma device transfer semantics Alan Mikhak
@ 2020-05-04  5:29 ` Vinod Koul
  0 siblings, 0 replies; 2+ messages in thread
From: Vinod Koul @ 2020-05-04  5:29 UTC (permalink / raw)
  To: Alan Mikhak
  Cc: dmaengine, linux-kernel, linux-pci, gustavo.pimentel,
	dan.j.williams, kishon, paul.walmsley

On 28-04-20, 18:10, Alan Mikhak wrote:
> From: Alan Mikhak <alan.mikhak@sifive.com>
> 
> Modify dw_edma_device_transfer() to also support the semantics of dma
> device transfer for additional use cases involving pcitest utility as a
> local initiator.
> 
> For its original use case, dw-edma supported the semantics of dma device
> transfer from the perspective of a remote initiator who is located across
> the PCIe bus from dma channel hardware.
> 
> To a remote initiator, DMA_DEV_TO_MEM means using a remote dma WRITE
> channel to transfer from remote memory to local memory. A WRITE channel
> would be employed on the remote device in order to move the contents of
> remote memory to the bus destined for local memory.
> 
> To a remote initiator, DMA_MEM_TO_DEV means using a remote dma READ
> channel to transfer from local memory to remote memory. A READ channel
> would be employed on the remote device in order to move the contents of
> local memory to the bus destined for remote memory.
> 
> >From the perspective of a local dma initiator who is co-located on the
> same side of the PCIe bus as the dma channel hardware, the semantics of
> dma device transfer are flipped.
> 
> To a local initiator, DMA_DEV_TO_MEM means using a local dma READ channel
> to transfer from remote memory to local memory. A READ channel would be
> employed on the local device in order to move the contents of remote
> memory to the bus destined for local memory.
> 
> To a local initiator, DMA_MEM_TO_DEV means using a local dma WRITE channel
> to transfer from local memory to remote memory. A WRITE channel would be
> employed on the local device in order to move the contents of local memory
> to the bus destined for remote memory.
> 
> To support local dma initiators, dw_edma_device_transfer() is modified to
> now examine the direction field of struct dma_slave_config for the channel
> which initiators can configure by calling dmaengine_slave_config().
> 
> If direction is configured as either DMA_DEV_TO_MEM or DMA_MEM_TO_DEV,
> local initiator semantics are used. If direction is a value other than
> DMA_DEV_TO_MEM nor DMA_MEM_TO_DEV, then remote initiator semantics are
> used. This should maintain backward compatibility with the original use
> case of dw-edma.
> 
> The dw-edma-test utility is an example of a remote initiator. From reading
> its patch, dw-edma-test does not specifically set the direction field of
> struct dma_slave_config. Since dw_edma_device_transfer() also does not
> check the direction field of struct dma_slave_config, it seems safe to use
> this convention in dw-edma to support both local and remote initiator
> semantics.

Applied, thanks

-- 
~Vinod

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-05-04  5:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-29  1:10 [PATCH][next] dmaengine: dw-edma: support local dma device transfer semantics Alan Mikhak
2020-05-04  5:29 ` Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).