Received: by 2002:a05:6512:2355:0:0:0:0 with SMTP id p21csp5516793lfu; Mon, 28 Mar 2022 15:49:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxH00wPOqeCg8iexQIeMEiSAFficmV5wGpVkeL+TwUbYIVeZBJeUqfLoW6V+FS+in8v+gFl X-Received: by 2002:a54:4010:0:b0:2ec:af98:5dc2 with SMTP id x16-20020a544010000000b002ecaf985dc2mr770773oie.195.1648507750523; Mon, 28 Mar 2022 15:49:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648507750; cv=none; d=google.com; s=arc-20160816; b=buD0nwNZ/SOcz/x+qFgpB/EePfTVQak3C8c/klM4kSx0r4YJqJz72gUNtZd+RWR1MB +8TlaBdyVhxWQqHc0oLiv2EWPsi8SNnBG/+1cuWgfPMRFVApodinQItbmkH48JYVdOWj AIw7w0j3Lt7SWp8SDdAlN9pRxzUEX7ai6HYfchL52pbbhl5hXP74Gtv/LQrOGpK2+Sra 6mSujx077qVLUq6zdTOpeFjE+3mUjTX5mxUHJ8L4G6jGgC4tnVoTlRQ9jfoYwNKn0KRY 0lg6Xt/Ku/mUcpOpSKxXgTFEhyzPPnih2LA/4nAmeItLEfnS5sCkVlT2w2ajabDN0C5k vB6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-filter; bh=SFhcRli5fTa9nfSVuvk4sCn/C3IPtvAiXy7J7sidjKw=; b=JuXGPtQnoFk4vZUMWU9iGxAcgxVrTNDcbK6IiHz0Kr9kYE/OCo/tMQW28YNx8Fn3V8 SZIwAMFtuezEce2taznaaX4uKRfRPrRdZOO/982Pd3wNd6hihUMJI+uaRA6rCreHVeZs oM/zlva6wSdKKitkWXPCd1mLds084tXjfS18S+UnmBhm8H4pvK8QjFa4Lv2ycxgtA+/d G39wJP0EKxnG1iXJq3XpvSeZQWfVuiF7xA0C+lYouyyvFKK8NiwGa+cUyLJNvAsIeqIq mC88ENlun55nzb4gT3TLOLc8LnvJ74gEoLXSfyrAaOig9U4IN0xOLxi33P/zd3XkxUfO Q96g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baikalelectronics.ru header.s=mail header.b=hetWlYdP; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id j22-20020a9d7d96000000b005cb2fc1378bsi10343457otn.7.2022.03.28.15.49.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Mar 2022 15:49:10 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@baikalelectronics.ru header.s=mail header.b=hetWlYdP; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 1760D20289B; Mon, 28 Mar 2022 14:53:31 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244127AbiC1Qrp (ORCPT + 99 others); Mon, 28 Mar 2022 12:47:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45144 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242821AbiC1QqC (ORCPT ); Mon, 28 Mar 2022 12:46:02 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 724AE21E25; Mon, 28 Mar 2022 09:44:16 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id C791C1E4946; Thu, 24 Mar 2022 04:48:44 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru C791C1E4946 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086524; bh=SFhcRli5fTa9nfSVuvk4sCn/C3IPtvAiXy7J7sidjKw=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=hetWlYdPNHHcfgiSSho0mz2Gl+aESHCewsqON6vPnnbDWObrn0vrYR/SoJ7QGJum5 E5WxsA1y5fusg4/2bLxcf9buGOXISaz0NqEW7+wFYwE5MCp1KSGCrw9CM4cwXGN9zz xllOy81/JbKv/lPHjQUbt/mDbUpygDx3EvfzmoAI= Received: from localhost (192.168.168.10) by mail (192.168.51.25) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Thu, 24 Mar 2022 04:48:44 +0300 From: Serge Semin To: Gustavo Pimentel , Vinod Koul , Jingoo Han , Bjorn Helgaas , Frank Li , Manivannan Sadhasivam CC: Serge Semin , Serge Semin , Alexey Malahov , Pavel Parkhomenko , Lorenzo Pieralisi , Rob Herring , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , , , Subject: [PATCH 09/25] dmaengine: dw-edma: Add CPU to PCIe bus address translation Date: Thu, 24 Mar 2022 04:48:20 +0300 Message-ID: <20220324014836.19149-10-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20220324014836.19149-1-Sergey.Semin@baikalelectronics.ru> References: <20220324014836.19149-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Starting from commit 9575632052ba ("dmaengine: make slave address physical") the source and destination addresses of the DMA-slave device have been converted to being defined in CPU address space. It's DMA-device driver responsibility to properly convert them to the reachable DMA bus spaces. In case of the DW eDMA device, the source or destination peripheral (slave) devices reside PCIe bus space. Thus we need to perform the PCIe Host/EP windows-based (i.e. ranges DT-property) addresses translation otherwise the eDMA transactions won't work as expected (or can be even harmful) in case if the CPU and PCIe address spaces don't match. Note 1. Even though the DMA interleaved template has both source and destination addresses declared of dma_addr_t type only CPU memory range is supposed to be mapped in a way so to be seen by the DMA device since it's a subject of the DMA getting towards the system side. The device part must not be mapped since slave device resides in the PCIe bus space, which isn't affected by IOMMUs or iATU translations. DW PCIe eDMA generates corresponding MWr/MRd TLPs on its own. Note 2. This functionality is mainly required for the remote eDMA setup since the CPU address must be manually translated into the PCIe bus space before being written to LLI.{SAR,DAR}. If eDMA is embedded into the locally accessible DW PCIe RP/EP software-based translation isn't required since it will be done by hardware by means of the Outbound iATU as long as the DMA_BYPASS flag is cleared. If the later flag is set or there is no Outbound iATU entry found to which the SAR or DAR falls in (for Read and Write channel respectfully), there won't be any translation performed but DMA will proceed with the corresponding source/destination address as is. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 18 +++++++++++++++++- include/linux/dma/edma.h | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index 97743fe44ebf..418b201fef67 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -40,6 +40,17 @@ struct dw_edma_desc *vd2dw_edma_desc(struct virt_dma_desc *vd) return container_of(vd, struct dw_edma_desc, vd); } +static inline +u64 dw_edma_get_pci_address(struct dw_edma_chan *chan, phys_addr_t cpu_addr) +{ + struct dw_edma_chip *chip = chan->dw->chip; + + if (chip->ops->pci_address) + return chip->ops->pci_address(chip->dev, cpu_addr); + + return cpu_addr; +} + static struct dw_edma_burst *dw_edma_alloc_burst(struct dw_edma_chunk *chunk) { struct dw_edma_burst *burst; @@ -328,11 +339,11 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) { struct dw_edma_chan *chan = dchan2dw_edma_chan(xfer->dchan); enum dma_transfer_direction dir = xfer->direction; - phys_addr_t src_addr, dst_addr; struct scatterlist *sg = NULL; struct dw_edma_chunk *chunk; struct dw_edma_burst *burst; struct dw_edma_desc *desc; + u64 src_addr, dst_addr; size_t fsz = 0; u32 cnt = 0; int i; @@ -407,6 +418,11 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) dst_addr = chan->config.dst_addr; } + if (dir == DMA_DEV_TO_MEM) + src_addr = dw_edma_get_pci_address(chan, (phys_addr_t)src_addr); + else + dst_addr = dw_edma_get_pci_address(chan, (phys_addr_t)dst_addr); + if (xfer->type == EDMA_XFER_CYCLIC) { cnt = xfer->xfer.cyclic.cnt; } else if (xfer->type == EDMA_XFER_SCATTER_GATHER) { diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h index 5abac9640a4e..5cc87cfdd685 100644 --- a/include/linux/dma/edma.h +++ b/include/linux/dma/edma.h @@ -23,8 +23,23 @@ struct dw_edma_region { size_t sz; }; +/** + * struct dw_edma_core_ops - platform-specific eDMA methods + * @irq_vector: Get IRQ number of the passed eDMA channel. Note the + * method accepts the channel id in the end-to-end + * numbering with the eDMA write channels being placed + * first in the row. + * @pci_address: Get PCIe bus address corresponding to the passed CPU + * address. Note there is no need in specifying this + * function if the address translation is performed by + * the DW PCIe RP/EP controller with the DW eDMA device in + * subject and DMA_BYPASS isn't set for all the outbound + * iATU windows. That will be done by the controller + * automatically. + */ struct dw_edma_core_ops { int (*irq_vector)(struct device *dev, unsigned int nr); + u64 (*pci_address)(struct device *dev, phys_addr_t cpu_addr); }; enum dw_edma_map_format { -- 2.35.1