lkml.org 
[lkml]   [2022]   [Aug]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.19 0737/1157] dmaengine: dw-edma: Fix eDMA Rd/Wr-channels and DMA-direction semantics
    Date
    From: Serge Semin <Sergey.Semin@baikalelectronics.ru>

    [ Upstream commit c1e33979171da63cf47e56243ccb8ba82363c7d3 ]

    In accordance with [1, 2] the DW eDMA controller has been created to be
    part of the DW PCIe Root Port and DW PCIe End-point controllers and to
    offload the transferring of large blocks of data between application and
    remote PCIe domains leaving the system CPU free for other tasks. In the
    first case (eDMA being part of DW PCIe Root Port) the eDMA controller is
    always accessible via the CPU DBI interface and never over the PCIe wire.

    The latter case is more complex. Depending on the DW PCIe End-Point IP-core
    synthesize parameters it's possible to have the eDMA registers accessible
    not only from the application CPU side, but also via mapping the eDMA CSRs
    over a dedicated endpoint BAR. So based on the specifics denoted above the
    eDMA driver is supposed to support two types of the DMA controller setups:

    1) eDMA embedded into the DW PCIe Root Port/End-point and accessible over
    the local CPU from the application side.

    2) eDMA embedded into the DW PCIe End-point and accessible via the PCIe
    wire with MWr/MRd TLPs generated by the CPU PCIe host controller.

    Since the CPU memory resides different sides in these cases the semantics
    of the MEM_TO_DEV and DEV_TO_MEM operations is flipped with respect to the
    Tx and Rx DMA channels. So MEM_TO_DEV/DEV_TO_MEM corresponds to the Tx/Rx
    channels in setup 1) and to the Rx/Tx channels in case of setup 2).

    The DW eDMA driver has supported the case 2) since e63d79d1ffcd
    ("dmaengine: Add Synopsys eDMA IP core driver") in the framework of the
    drivers/dma/dw-edma/dw-edma-pcie.c driver.

    The case 1) support was added later by bd96f1b2f43a ("dmaengine: dw-edma:
    support local dma device transfer semantics"). Afterwards the driver was
    supposed to cover the both possible eDMA setups, but the latter commit
    turned out to be not fully correct.

    The problem was that the commit together with the new functionality support
    also changed the channel direction semantics so the eDMA Read-channel
    (corresponding to the DMA_DEV_TO_MEM direction for case 1) now uses the
    sgl/cyclic base addresses as the Source addresses of the DMA transfers and
    dma_slave_config.dst_addr as the Destination address of the DMA transfers.

    Similarly the eDMA Write-channel (corresponding to the DMA_MEM_TO_DEV
    direction for case 1) now uses dma_slave_config.src_addr as a source
    address of the DMA transfers and sgl/cyclic base address as the Destination
    address of the DMA transfers. This contradicts the logic of the
    DMA-interface, which implies that DEV side is supposed to belong to the
    PCIe device memory and MEM - to the CPU/Application memory. Indeed it seems
    irrational to have the SG-list defined in the PCIe bus space, while
    expecting a contiguous buffer allocated in the CPU memory. Moreover the
    passed SG-list and cyclic DMA buffers are supposed to be mapped in a way so
    to be seen by the DW eDMA Application (CPU) interface.

    So in order to have the correct DW eDMA interface we need to invert the
    eDMA Rd/Wr-channels and DMA-slave directions semantics by selecting the
    src/dst addresses based on the DMA transfer direction instead of using the
    channel direction capability.

    [1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
    v.5.40a, March 2019, p.1092
    [2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Endpoint,
    v.5.40a, March 2019, p.1189

    Co-developed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
    Fixes: bd96f1b2f43a ("dmaengine: dw-edma: support local dma device transfer semantics")
    Link: https://lore.kernel.org/r/20220524152159.2370739-7-Frank.Li@nxp.com
    Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
    Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
    Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
    Signed-off-by: Frank Li <Frank.Li@nxp.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    Acked-By: Vinod Koul <vkoul@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/dma/dw-edma/dw-edma-core.c | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
    index 468d1097a1ec..f23569e4b0bd 100644
    --- a/drivers/dma/dw-edma/dw-edma-core.c
    +++ b/drivers/dma/dw-edma/dw-edma-core.c
    @@ -423,7 +423,7 @@ 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) {
    + if (dir == DMA_DEV_TO_MEM) {
    burst->sar = src_addr;
    if (xfer->type == EDMA_XFER_CYCLIC) {
    burst->dar = xfer->xfer.cyclic.paddr;
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-08-16 06:39    [W:2.677 / U:0.692 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site