From patchwork Thu Mar 24 01:48:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793913 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60227C433FE for ; Mon, 28 Mar 2022 16:46:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243410AbiC1QqS (ORCPT ); Mon, 28 Mar 2022 12:46:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242943AbiC1QqE (ORCPT ); Mon, 28 Mar 2022 12:46:04 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7AF962251A; Mon, 28 Mar 2022 09:44:17 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 15FF11E493B; Thu, 24 Mar 2022 04:48:39 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 15FF11E493B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086519; bh=qeD0LQB5yz0tEnI7peM/retOGT3xKLiWnq9l84RaXtg=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=pxMDwJ2d7YWS6glR8disDs7jCpmDaCgVA+5xJkDkOkmGxoz2qgRmveWL/Gu+8h+DS PVLhOsTKdCB/8/sfAGRbN9vLfWr0naiLFzI3GpZSKHllo1KcseFSI0z5btzIEztT5D 3qHlEjo6fE/SDvrCCK2B9sNCaHfz1Y1UkXRXDum8= 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:38 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 01/25] dmaengine: dw-edma: Drop dma_slave_config.direction field usage Date: Thu, 24 Mar 2022 04:48:12 +0300 Message-ID: <20220324014836.19149-2-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org The dma_slave_config.direction field usage in the DW eDMA driver has been introduced in the commit bd96f1b2f43a ("dmaengine: dw-edma: support local dma device transfer semantics"). Mainly the change introduced there was correct (indeed DEV_TO_MEM means using RD-channel and MEM_TO_DEV - WR-channel for the case of having eDMA accessed locally from CPU/Application side), but providing an additional MEM_TO_MEM/DEV_TO_DEV-based semantics was quite redundant if not to say potentially harmful (when it comes to removing the denoted field). First of all since the dma_slave_config.direction field has been marked as obsolete (see [1] and the structure dc [2]) and will be discarded in future, using it especially in a non-standard way is discouraged. Secondly in accordance with the commit denoted above the default dw_edma_device_transfer() semantics has been changed despite what it's message said. So claiming that the method was left backward compatible was wrong. Anyway let's fix the problems denoted above and simplify the dw_edma_device_transfer() method by dropping the parsing of the DMA-channel direction field. Instead of having that implicit dma_slave_config.direction field semantic we can use the recently added DW_EDMA_CHIP_LOCAL flag to distinguish between the local and remote DW eDMA setups thus preserving both cases support. In addition to that an ASCII-figure has been added to clarify the complication out. [1] Documentation/driver-api/dmaengine/provider.rst [2] include/linux/dmaengine.h: dma_slave_config.direction Co-developed-by: Manivannan Sadhasivam Signed-off-by: Manivannan Sadhasivam Signed-off-by: Serge Semin --- In accordance with agreement with Frank and Manivannan this patch is supposed to be moved to the series: Link: https://lore.kernel.org/dmaengine/20220310192457.3090-1-Frank.Li@nxp.com/ in place of the patch: [PATCH v5 6/9] dmaengine: dw-edma: Don't rely on the deprecated "direction" member Link: https://lore.kernel.org/dmaengine/20220310192457.3090-7-Frank.Li@nxp.com/ --- drivers/dma/dw-edma/dw-edma-core.c | 49 +++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index 5be8a5944714..e9e32ed74aa9 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -339,21 +339,40 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) 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; + /* + * Local Root Port/End-point Remote End-point + * +-----------------------+ PCIe bus +----------------------+ + * | | +-+ | | + * | DEV_TO_MEM Rx Ch <----+ +---+ Tx Ch DEV_TO_MEM | + * | | | | | | + * | MEM_TO_DEV Tx Ch +----+ +---> Rx Ch MEM_TO_DEV | + * | | +-+ | | + * +-----------------------+ +----------------------+ + * + * 1. Normal logic: + * If eDMA is embedded into the DW PCIe RP/EP and controlled from the + * CPU/Application side, the Rx channel (EDMA_DIR_READ) will be used + * for the device read operations (DEV_TO_MEM) and the Tx channel + * (EDMA_DIR_WRITE) - for the write operations (MEM_TO_DEV). + * + * 2. Inverted logic: + * If eDMA is embedded into a Remote PCIe EP and is controlled by the + * MWr/MRd TLPs sent from the CPU's PCIe host controller, the Tx + * channel (EDMA_DIR_WRITE) will be used for the device read operations + * (DEV_TO_MEM) and the Rx channel (EDMA_DIR_READ) - for the write + * operations (MEM_TO_DEV). + * + * It is the client driver responsibility to choose a proper channel + * for the DMA transfers. + */ + if (chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) { + if ((chan->dir == EDMA_DIR_READ && dir != DMA_DEV_TO_MEM) || + (chan->dir == EDMA_DIR_WRITE && dir != DMA_MEM_TO_DEV)) + return NULL; + } else { + if ((chan->dir == EDMA_DIR_WRITE && dir != DMA_DEV_TO_MEM) || + (chan->dir == EDMA_DIR_READ && dir != DMA_MEM_TO_DEV)) + return NULL; } if (xfer->type == EDMA_XFER_CYCLIC) { From patchwork Thu Mar 24 01:48:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793899 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38B18C3527B for ; Mon, 28 Mar 2022 16:44:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243025AbiC1QqI (ORCPT ); Mon, 28 Mar 2022 12:46:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242683AbiC1QqC (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 4DAA721801; Mon, 28 Mar 2022 09:44:13 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id BD16D1E493C; Thu, 24 Mar 2022 04:48:39 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru BD16D1E493C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086519; bh=phRjSo/+vSNUHm7b1Z6XFMjq89kQ6ugKnVFCikCw3QQ=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=WAML5i00dGv6ed5aqgZNQzibC7nU9u0igzV/9ydKlxS2zEPL8LEk1YnTKr4vTrLDK 5jL3+s2kmlL8fcq/2HNXP0lMLt3MyrC71kLQ+gwczxtqHstvcFCflGW8a1GQaA0AEW xC8cYDgexTm5eKvClSM8I0zfyOCcfbom8akvTGxY= 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:39 +0300 From: Serge Semin To: Gustavo Pimentel , Vinod Koul , Jingoo Han , Bjorn Helgaas , Frank Li , Manivannan Sadhasivam , Alan Mikhak CC: Serge Semin , Serge Semin , Alexey Malahov , Pavel Parkhomenko , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , , , Subject: [PATCH 02/25] dmaengine: dw-edma: Fix eDMA Rd/Wr-channels and DMA-direction semantics Date: Thu, 24 Mar 2022 04:48:13 +0300 Message-ID: <20220324014836.19149-3-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org 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 later 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 end-point 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 the initial commit 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 a bit later in commit bd96f1b2f43a ("dmaengine: dw-edma: support local dma device transfer semantics"). Afterwards the driver was supposed to cover the both possible eDMA setups, but the later commit turned to be not fully correct. The problem was that the commit together with the new functionality support also changed the channel direction semantics in a way so the eDMA Read-channel (corresponding to the DMA_DEV_TO_MEM direction for the 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 utilizes 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 to 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 Fixes: bd96f1b2f43a ("dmaengine: dw-edma: support local dma device transfer semantics") Co-developed-by: Manivannan Sadhasivam Signed-off-by: Manivannan Sadhasivam Signed-off-by: Serge Semin --- In accordance with agreement with Frank and Manivannan this patch is supposed to be moved to the series: Link: https://lore.kernel.org/dmaengine/20220310192457.3090-1-Frank.Li@nxp.com/ in place of the patch: [PATCH v5 5/9] dmaengine: dw-edma: Fix programming the source & dest addresses for ep Link: https://lore.kernel.org/dmaengine/20220310192457.3090-6-Frank.Li@nxp.com/ --- 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 e9e32ed74aa9..519d4b3c9fa0 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -442,7 +442,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; From patchwork Thu Mar 24 01:48:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793912 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F986C43219 for ; Mon, 28 Mar 2022 16:46:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243367AbiC1QqR (ORCPT ); Mon, 28 Mar 2022 12:46:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242935AbiC1QqE (ORCPT ); Mon, 28 Mar 2022 12:46:04 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 76B17222A1; Mon, 28 Mar 2022 09:44:17 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 8C8691E493D; Thu, 24 Mar 2022 04:48:40 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 8C8691E493D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086520; bh=AYgCGlj6XCp3KD2/KUlHJg+55HiFo50ys5cdSY8nwOc=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=Gdpk4DVTE1MY+dgZ0kGVMp67RyX8d1SyCg2QO2NJHj25IYEGxOxb8VC4cSyQcFRx4 sxb20q0ugu4aEjTmpg69ImHd3ruWyaaxda/H8iMTCWfSg/qZlBV6hI7F5qPAIl5pvM TH40nEUw788A0bI+6t728iRMW+6lqKWGI7yOKtds= 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:40 +0300 From: Serge Semin To: Gustavo Pimentel , Vinod Koul , Jingoo Han , Bjorn Helgaas , Frank Li , Manivannan Sadhasivam , Christoph Hellwig , Marek Szyprowski , Robin Murphy , Vladimir Murzin CC: Serge Semin , Serge Semin , Alexey Malahov , Pavel Parkhomenko , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , , , , Subject: [PATCH 03/25] dma-direct: take dma-ranges/offsets into account in resource mapping Date: Thu, 24 Mar 2022 04:48:14 +0300 Message-ID: <20220324014836.19149-4-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org A basic device-specific linear memory mapping was introduced back in commit ("dma: Take into account dma_pfn_offset") as a single-valued offset preserved in the device.dma_pfn_offset field, which was initialized for instance by means of the "dma-ranges" DT property. Afterwards the functionality was extended to support more than one device-specific region defined in the device.dma_range_map list of maps. But all of these improvements concerned a single pointer, page or sg DMA-mapping methods, while the system resource mapping function turned to miss the corresponding modification. Thus the dma_direct_map_resource() method now just casts the CPU physical address to the device DMA address with no dma-ranges-based mapping taking into account, which is obviously wrong. Let's fix it by using the phys_to_dma_direct() method to get the device-specific bus address from the passed memory resource for the case of the directly mapped DMA. Fixes: 25f1e1887088 ("dma: Take into account dma_pfn_offset") Signed-off-by: Serge Semin --- kernel/dma/direct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 50f48e9e4598..9ce8192b29ab 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -497,7 +497,7 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents, dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr, size_t size, enum dma_data_direction dir, unsigned long attrs) { - dma_addr_t dma_addr = paddr; + dma_addr_t dma_addr = phys_to_dma_direct(dev, paddr); if (unlikely(!dma_capable(dev, dma_addr, size, false))) { dev_err_once(dev, From patchwork Thu Mar 24 01:48:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 59601C433EF for ; Mon, 28 Mar 2022 16:44:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242771AbiC1QqC (ORCPT ); Mon, 28 Mar 2022 12:46:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242645AbiC1Qpw (ORCPT ); Mon, 28 Mar 2022 12:45:52 -0400 X-Greylist: delayed 4199 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Mon, 28 Mar 2022 09:44:08 PDT Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 61D8A205CB; Mon, 28 Mar 2022 09:44:07 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 324381E493E; Thu, 24 Mar 2022 04:48:41 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 324381E493E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086521; bh=45B91bTRPDAiVVFXTWFyOKTO4rQMMJ7SJOEIZd4mBWc=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=dVfKrMhpppasdM6ZNQchY65q3OjcV7bv4h6qHkClv1TE0UUtDK5Dsl0/17AKVVv74 EtW5Jl1AEs39t5gyGJzX8mqREeaGK3RMsA3uH2es9XaedS2ywgZyIFYCc7t9ZgxxGt hfDk87OB95UkS1yUXErO5TXCgfF9uFFyz19zEb8E= 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:41 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 04/25] dmaengine: Fix dma_slave_config.dst_addr description Date: Thu, 24 Mar 2022 04:48:15 +0300 Message-ID: <20220324014836.19149-5-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org Most likely due to a copy-paste mistake the dst_addr member of the dma_slave_config structure has been marked as ignored if the !source! address belong to the memory. That is relevant to the src_addr field of the structure while the dst_addr field as containing a destination device address is supposed to be ignored if the destination is the CPU memory. Let's fix the field description accordingly. Signed-off-by: Serge Semin --- include/linux/dmaengine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 842d4f7ca752..f204ea16ac1c 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -395,7 +395,7 @@ enum dma_slave_buswidth { * should be read (RX), if the source is memory this argument is * ignored. * @dst_addr: this is the physical address where DMA slave data - * should be written (TX), if the source is memory this argument + * should be written (TX), if the destination is memory this argument * is ignored. * @src_addr_width: this is the width in bytes of the source (RX) * register where DMA data shall be read. If the source From patchwork Thu Mar 24 01:48:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793908 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 094CCC43219 for ; Mon, 28 Mar 2022 16:44:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229463AbiC1QqV (ORCPT ); Mon, 28 Mar 2022 12:46:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242867AbiC1QqD (ORCPT ); Mon, 28 Mar 2022 12:46:03 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id CE03821E31; 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 EF50E1E4940; Thu, 24 Mar 2022 04:48:41 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru EF50E1E4940 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086521; bh=jEu2wUvM7pH5rgVAy75gfZMJJnSsEu5NWHk3/A0TPYc=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=aUCL31APiFO1HvyR7TBZJSlejnEyqsZ+oAx/sgRuFkH6uVF0OzoraFRG5oQGlkYkD ooM2mxv/Icyi+gfS8aXxUHhyfYtaF7ME+UA9mIByWENfQDbz/2IvD+ADWqhe9g0Iwh XXInaE8E8qXtZYWP/pTxJVIsUVGa4hxaJkj+Pg4U= 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:41 +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_Wilczy=C5=84ski?= , , , , Gustavo Pimentel Subject: [PATCH 05/25] dmaengine: dw-edma: Convert ll/dt phys-address to PCIe bus/DMA address Date: Thu, 24 Mar 2022 04:48:16 +0300 Message-ID: <20220324014836.19149-6-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org In accordance with the dw_edma_region.paddr field semantics it is supposed to be initialized with a memory base address visible by the DW eDMA controller. If the DMA engine is embedded into the DW PCIe Host/EP controller, then the address should belong to the Local CPU/Application memory. If eDMA is remotely accessible across the PCIe bus via the PCIe memory IOs, then the address needs to be a part of the PCIe bus memory space. The later case hasn't been well covered in the corresponding glue-driver. Since in general the PCIe memory space doesn't have to match the CPU memory space and the pci_dev.resource[] arrays contain the resources defined in the CPU memory space, a proper conversion needs to be performed, otherwise either the driver won't properly work or much worse the memory corruption will happen. The conversion can be done by means of the pci_bus_address() method. Let's use it to retrieve the LL, DT and CSRs PCIe memory ranges. Note in addition to that we need to extend the dw_edma_region.paddr field size. The field normally contains a memory range base address to be set in the DW eDMA Linked-List pointer register or as a base address of the Linked-List data buffer. In accordance with [1] the LL range is supposed to be created in the Local CPU/Application memory, but depending on the DW eDMA utilization the memory can be created as a part of the PCIe bus address space (as in the case of the DW PCIe EP prototype kit). Thus in the former case the dw_edma_region.paddr field should have the dma_addr_t type, while in the later one - pci_bus_addr_t. Seeing the corresponding CSRs are always 64-bits wide let's convert the dw_edma_region.paddr field type to be u64 and let the client code logic to make sure it has a valid address visible by the DW eDMA controller. For instance the DW eDMA PCIe glue-driver initializes the field with the addresses from the PCIe bus memory space. [1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, v.5.40a, March 2019, p.1103 Fixes: 41aaff2a2ac0 ("dmaengine: Add Synopsys eDMA IP PCIe glue-logic") Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-pcie.c | 8 ++++---- include/linux/dma/edma.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-pcie.c b/drivers/dma/dw-edma/dw-edma-pcie.c index d6b5e2463884..04c95cba1244 100644 --- a/drivers/dma/dw-edma/dw-edma-pcie.c +++ b/drivers/dma/dw-edma/dw-edma-pcie.c @@ -231,7 +231,7 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, return -ENOMEM; ll_region->vaddr += ll_block->off; - ll_region->paddr = pdev->resource[ll_block->bar].start; + ll_region->paddr = pci_bus_address(pdev, ll_block->bar); ll_region->paddr += ll_block->off; ll_region->sz = ll_block->sz; @@ -240,7 +240,7 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, return -ENOMEM; dt_region->vaddr += dt_block->off; - dt_region->paddr = pdev->resource[dt_block->bar].start; + dt_region->paddr = pci_bus_address(pdev, dt_block->bar); dt_region->paddr += dt_block->off; dt_region->sz = dt_block->sz; } @@ -256,7 +256,7 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, return -ENOMEM; ll_region->vaddr += ll_block->off; - ll_region->paddr = pdev->resource[ll_block->bar].start; + ll_region->paddr = pci_bus_address(pdev, ll_block->bar); ll_region->paddr += ll_block->off; ll_region->sz = ll_block->sz; @@ -265,7 +265,7 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, return -ENOMEM; dt_region->vaddr += dt_block->off; - dt_region->paddr = pdev->resource[dt_block->bar].start; + dt_region->paddr = pci_bus_address(pdev, dt_block->bar); dt_region->paddr += dt_block->off; dt_region->sz = dt_block->sz; } diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h index 8897f8a79b52..5abac9640a4e 100644 --- a/include/linux/dma/edma.h +++ b/include/linux/dma/edma.h @@ -18,7 +18,7 @@ struct dw_edma; struct dw_edma_region { - phys_addr_t paddr; + u64 paddr; void __iomem *vaddr; size_t sz; }; From patchwork Thu Mar 24 01:48:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793893 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F2DC2C4321E for ; Mon, 28 Mar 2022 16:44:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242997AbiC1QqE (ORCPT ); Mon, 28 Mar 2022 12:46:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44182 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242652AbiC1Qpx (ORCPT ); Mon, 28 Mar 2022 12:45:53 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id A2B72205E0; Mon, 28 Mar 2022 09:44:07 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id A349C1E4941; Thu, 24 Mar 2022 04:48:42 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru A349C1E4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086522; bh=+PyeNd0hg65b8eyuRBL15QKskXMg2W2V+ZBDs2t3IpM=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=W/6dwQoQaj2ECNHZTGewQ48hOrHMBVEXGZISA0qLmGLIzRCXYLBN2Xc1EBc9ogUIl 95BF+EtmJ7VdtbbcyW0qQKSmL+gg005CLCChrlR/rvbt0WT699sS7JOQ8qhJfyUTAl V7iocGT3BT4RGK16MgGwJnSc/SMaggn7dyF+W3GI= 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:42 +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_Wilczy=C5=84ski?= , , , , Gustavo Pimentel Subject: [PATCH 06/25] dmaengine: dw-edma: Fix missing src/dst address of the interleaved xfers Date: Thu, 24 Mar 2022 04:48:17 +0300 Message-ID: <20220324014836.19149-7-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org The interleaved DMA transfers support was added in the commit 85e7518f42c8 ("dmaengine: dw-edma: Add device_prep_interleave_dma() support"). It seems like the support was broken from the very beginning. Depending on the selected channel either source or destination address are left uninitialized which was obviously wrong. I don't really know how come the original modification was working for the commit author. Anyway let's fix it by initializing the destination address of the eDMA burst descriptors for the DEV_TO_MEM interleaved operations and by initializing the source address of the eDMA burst descriptors for the MEM_TO_DEV interleaved operations. Fixes: 85e7518f42c8 ("dmaengine: dw-edma: Add device_prep_interleave_dma() support") Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index 519d4b3c9fa0..2010d7f8191f 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -456,6 +456,8 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) * and destination addresses are increased * by the same portion (data length) */ + } else if (xfer->type == EDMA_XFER_INTERLEAVED) { + burst->dar = dst_addr; } } else { burst->dar = dst_addr; @@ -471,6 +473,8 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) * and destination addresses are increased * by the same portion (data length) */ + } else if (xfer->type == EDMA_XFER_INTERLEAVED) { + burst->sar = src_addr; } } From patchwork Thu Mar 24 01:48:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793895 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E644C4167D for ; Mon, 28 Mar 2022 16:44:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242645AbiC1QqG (ORCPT ); Mon, 28 Mar 2022 12:46:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242668AbiC1QqC (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 4D9C021800; Mon, 28 Mar 2022 09:44:13 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 628F11E4942; Thu, 24 Mar 2022 04:48:43 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 628F11E4942 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086523; bh=uq3F2gd1xa8DY2sr9sUsFpAH8Z8bBz3m4dAToaXUH6o=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=mI9DKh9w99KIIw8tn06S7NW/fYsCyW6YFqluSU7cwLL88FLLTWcklGNw61NkBQHlB F5B3CwhdAaHiRBnpa4+FOvXmo+73AK84Goc/f3Jq/fihaLMyuwyIPrCMn2mQPmqjsP IZDIHFlCWug3Mw6Y/vu2kB8OUSZ0KIW4wZD7TBec= 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:43 +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_Wilczy=C5=84ski?= , , , , Gustavo Pimentel Subject: [PATCH 07/25] dmaengine: dw-edma: Don't permit non-inc interleaved xfers Date: Thu, 24 Mar 2022 04:48:18 +0300 Message-ID: <20220324014836.19149-8-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org DW eDMA controller always increments both source and destination addresses. Permitting DMA interleaved transfers with no src_inc/dst_inc flags set may lead to unexpected behaviour for the device users. Let's fix that by terminating the interleaved transfers if at least one of the dma_interleaved_template.{src_inc,dst_inc} flag is initialized with false value. Note in addition to that we need we need to increase the source and destination addresses accordingly after each iteration. Fixes: 85e7518f42c8 ("dmaengine: dw-edma: Add device_prep_interleave_dma() support") Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index 2010d7f8191f..f41bde27795c 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -386,6 +386,8 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) return NULL; if (xfer->xfer.il->numf > 0 && xfer->xfer.il->frame_size > 0) return NULL; + if (!xfer->xfer.il->src_inc || !xfer->xfer.il->dst_inc) + return NULL; } else { return NULL; } @@ -485,15 +487,13 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) struct dma_interleaved_template *il = xfer->xfer.il; struct data_chunk *dc = &il->sgl[i]; - if (il->src_sgl) { - src_addr += burst->sz; + src_addr += burst->sz; + if (il->src_sgl) src_addr += dmaengine_get_src_icg(il, dc); - } - if (il->dst_sgl) { - dst_addr += burst->sz; + dst_addr += burst->sz; + if (il->dst_sgl) dst_addr += dmaengine_get_dst_icg(il, dc); - } } } From patchwork Thu Mar 24 01:48:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793914 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C25EC433EF for ; Mon, 28 Mar 2022 16:46:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236217AbiC1Qs3 (ORCPT ); Mon, 28 Mar 2022 12:48:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242739AbiC1QqC (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 2D0FA2183C; Mon, 28 Mar 2022 09:44:15 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 07B241E4944; Thu, 24 Mar 2022 04:48:44 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 07B241E4944 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086524; bh=JyBVrXBeB4f1gDpmLax7fWQaZrqiLN49r1NgvwAubBU=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=kyG7eraqfK1fuxEzPFGi0KMFTNvcrl6nD7HSPzPZZeXTx0TcXysUjWdOp7qdN0q/I gKBlLRKebqXEuRscVUA47Qd3iP+ZwWaDwnU/Qjb/6Esdw1DUyl3Ud+hBCEHvTrUVtF heOyfkX0HsbgubbYqYrjzRmh++doZIJnG7qgaUWE= 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:43 +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_Wilczy=C5=84ski?= , , , , Gustavo Pimentel Subject: [PATCH 08/25] dmaengine: dw-edma: Fix invalid interleaved xfers semantics Date: Thu, 24 Mar 2022 04:48:19 +0300 Message-ID: <20220324014836.19149-9-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org The interleaved DMA transfer support added in commit 85e7518f42c8 ("dmaengine: dw-edma: Add device_prep_interleave_dma() support") seems contradicting to what the DMA-engine defines. The next conditional statements: if (!xfer->xfer.il->numf) return NULL; if (xfer->xfer.il->numf > 0 && xfer->xfer.il->frame_size > 0) return NULL; basically mean that numf can't be zero and frame_size must always be zero, otherwise the transfer won't be executed. But further the transfer execution method takes the frames size from the dma_interleaved_template.sgl[] array for each frame. That array in accordance with [1] is supposed to be of dma_interleaved_template.frame_size size, which as we discovered before the code expects to be zero. So judging by the dw_edma_device_transfer() implementation the method implies the dma_interleaved_template.sgl[] array being of dma_interleaved_template.numf size, which is wrong. Since the dw_edma_device_transfer() method doesn't permit dma_interleaved_template.frame_size being non-zero then actual multi-chunk interleaved transfer turns to be unsupported even though the code implies having it supported. Let's fix that by adding a fully functioning support of the interleaved DMA transfers. First of all dma_interleaved_template.frame_size is supposed to be greater or equal to one thus having at least simple linear chunked frames. Secondly we can create a walk-through all over the chunks and frames just by initializing the number of the eDMA burst transactios as a multiple of dma_interleaved_template.numf and dma_interleaved_template.frame_size and getting the frame_size-modulo of the iteration step as an index of the dma_interleaved_template.sgl[] array. The rest of the dw_edma_device_transfer() method code can be left unchanged. [1] include/linux/dmaengine.h: doc struct dma_interleaved_template Fixes: 85e7518f42c8 ("dmaengine: dw-edma: Add device_prep_interleave_dma() support") Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index f41bde27795c..97743fe44ebf 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -333,6 +333,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; + size_t fsz = 0; u32 cnt = 0; int i; @@ -382,9 +383,7 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) if (xfer->xfer.sg.len < 1) return NULL; } else if (xfer->type == EDMA_XFER_INTERLEAVED) { - if (!xfer->xfer.il->numf) - return NULL; - if (xfer->xfer.il->numf > 0 && xfer->xfer.il->frame_size > 0) + if (!xfer->xfer.il->numf || xfer->xfer.il->frame_size < 1) return NULL; if (!xfer->xfer.il->src_inc || !xfer->xfer.il->dst_inc) return NULL; @@ -414,10 +413,8 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) cnt = xfer->xfer.sg.len; sg = xfer->xfer.sg.sgl; } else if (xfer->type == EDMA_XFER_INTERLEAVED) { - if (xfer->xfer.il->numf > 0) - cnt = xfer->xfer.il->numf; - else - cnt = xfer->xfer.il->frame_size; + cnt = xfer->xfer.il->numf * xfer->xfer.il->frame_size; + fsz = xfer->xfer.il->frame_size; } for (i = 0; i < cnt; i++) { @@ -439,7 +436,7 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) else if (xfer->type == EDMA_XFER_SCATTER_GATHER) burst->sz = sg_dma_len(sg); else if (xfer->type == EDMA_XFER_INTERLEAVED) - burst->sz = xfer->xfer.il->sgl[i].size; + burst->sz = xfer->xfer.il->sgl[i % fsz].size; chunk->ll_region.sz += burst->sz; desc->alloc_sz += burst->sz; @@ -482,10 +479,9 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) if (xfer->type == EDMA_XFER_SCATTER_GATHER) { sg = sg_next(sg); - } else if (xfer->type == EDMA_XFER_INTERLEAVED && - xfer->xfer.il->frame_size > 0) { + } else if (xfer->type == EDMA_XFER_INTERLEAVED) { struct dma_interleaved_template *il = xfer->xfer.il; - struct data_chunk *dc = &il->sgl[i]; + struct data_chunk *dc = &il->sgl[i % fsz]; src_addr += burst->sz; if (il->src_sgl) From patchwork Thu Mar 24 01:48:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793909 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D351C433EF for ; Mon, 28 Mar 2022 16:44:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231903AbiC1QqV (ORCPT ); Mon, 28 Mar 2022 12:46:21 -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_Wilczy=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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@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 { From patchwork Thu Mar 24 01:48:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793905 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2040FC433FE for ; Mon, 28 Mar 2022 16:44:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242674AbiC1QqN (ORCPT ); Mon, 28 Mar 2022 12:46:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242900AbiC1QqD (ORCPT ); Mon, 28 Mar 2022 12:46:03 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 23BE5220D8; 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 80EAE1E4948; Thu, 24 Mar 2022 04:48:45 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 80EAE1E4948 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086525; bh=3nPjOLjzGYkPTmC45vtG0SxOCnuiuHJKeB2jpwkXC+g=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=rxyCCYq4auhTUcAFE7H/PSIUGJcHizoO/iZhOL5ZLgbHIn3csEt70ME+7gmjyMmdH JT1rA4yp19llwItStSCp8HaeHNOL2zCSljGMgMv+WxprkLX7GttyTCtgVimmbPGqf3 0r49hSlKfhU0+GaTQXTv+mphv8CMwer50WaKKEdY= 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:45 +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_Wilczy=C5=84ski?= , , , , Gustavo Pimentel Subject: [PATCH 10/25] dmaengine: dw-edma: Add PCIe bus address getter to the remote EP glue-driver Date: Thu, 24 Mar 2022 04:48:21 +0300 Message-ID: <20220324014836.19149-11-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org In general the Synopsys PCIe EndPoint IP prototype kit can be attached to a PCIe bus with any PCIe Host controller including to the one with distinctive from CPU address space. Due to that we need to make sure that the source and destination addresses of the DMA-slave devices are properly converted to the PCIe bus address space, otherwise the DMA transaction will not only work as expected, but may cause the memory corruption with subsequent system crash. Let's do that by introducing a new dw_edma_pcie_address() method defined in the dw-edma-pcie.c, which will perform the denoted translation by using the pcibios_resource_to_bus() method. Fixes: 41aaff2a2ac0 ("dmaengine: Add Synopsys eDMA IP PCIe glue-logic") Signed-off-by: Serge Semin --- Note this patch depends on the patch "dmaengine: dw-edma: Add CPU to PCIe bus address translation" from this series. --- drivers/dma/dw-edma/dw-edma-pcie.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/dma/dw-edma/dw-edma-pcie.c b/drivers/dma/dw-edma/dw-edma-pcie.c index 04c95cba1244..f530bacfd716 100644 --- a/drivers/dma/dw-edma/dw-edma-pcie.c +++ b/drivers/dma/dw-edma/dw-edma-pcie.c @@ -95,8 +95,23 @@ static int dw_edma_pcie_irq_vector(struct device *dev, unsigned int nr) return pci_irq_vector(to_pci_dev(dev), nr); } +static u64 dw_edma_pcie_address(struct device *dev, phys_addr_t cpu_addr) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct pci_bus_region region; + struct resource res = { + .flags = IORESOURCE_MEM, + .start = cpu_addr, + .end = cpu_addr, + }; + + pcibios_resource_to_bus(pdev->bus, ®ion, &res); + return region.start; +} + static const struct dw_edma_core_ops dw_edma_pcie_core_ops = { .irq_vector = dw_edma_pcie_irq_vector, + .pci_address = dw_edma_pcie_address, }; static void dw_edma_pcie_get_vsec_dma_data(struct pci_dev *pdev, From patchwork Thu Mar 24 01:48:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793902 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C20DC43217 for ; Mon, 28 Mar 2022 16:44:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243187AbiC1QqK (ORCPT ); Mon, 28 Mar 2022 12:46:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242662AbiC1QqC (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 4383521E17; 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 275821E4949; Thu, 24 Mar 2022 04:48:46 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 275821E4949 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086526; bh=TYvNf8iu0bXsZA6qu5zNMBzjycLwgfx75RSoOb+pG9s=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=X0DRTFhIp88+Rl/fRL+cl0sVwNtPkQ/rDwFSt+EiAtPbh5x1IH0yXxxav+igAaSlm uqiy6gN1ozKAHMJOHOAtRsC4Lk4axYxTjPmTvkdW+OWWVhD9af5EYkt+iGjm9dNi/S U7g9sUpoB78N1xanEKysQEt0xsz5n4PyGdeHI0rI= 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:46 +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_Wilczy=C5=84ski?= , , , , Gustavo Pimentel Subject: [PATCH 11/25] dmaengine: dw-edma: Drop chancnt initialization Date: Thu, 24 Mar 2022 04:48:22 +0300 Message-ID: <20220324014836.19149-12-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org DMA device drivers aren't supposed to initialize the dma_device.chancnt field. It will be done by the DMA-engine core in accordance with number of added virtual DMA-channels. Pre-initializing it with some value causes having a wrong number of channels printed in the device summary. Fixes: e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver") Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index 418b201fef67..cefa73412bf7 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -823,7 +823,6 @@ static int dw_edma_channel_setup(struct dw_edma_chip *chip, bool write, dma->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); dma->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); dma->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; - dma->chancnt = cnt; /* Set DMA channel callbacks */ dma->dev = chip->dev; From patchwork Thu Mar 24 01:48:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793903 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B9AEC4321E for ; Mon, 28 Mar 2022 16:44:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243207AbiC1QqL (ORCPT ); Mon, 28 Mar 2022 12:46:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242678AbiC1QqD (ORCPT ); Mon, 28 Mar 2022 12:46:03 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id E8C1B21E3D; 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 D0F2F1E494B; Thu, 24 Mar 2022 04:48:46 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru D0F2F1E494B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086526; bh=FMSz5zMuaHmaqav0lPq43UKO/Chw55VmoyBGraCce7Y=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=SL7h4pN9/6SGpVGqlT2MNtGklqb8g9EhQkzhNeIDpY9DiSkeIfsvD607yftsx9xEx aecc2asohi/6Ax+JhWfEjwGOjajMbsh9+LtHuQ967ClZeM6anpj/K8/s142RN2/Yf+ yXHojAAlsXyMKoKHJ9+DKRtQalu3D887FcXybi00= 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:46 +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_Wilczy=C5=84ski?= , , , , Gustavo Pimentel Subject: [PATCH 12/25] dmaengine: dw-edma: Fix DebugFS reg entry type Date: Thu, 24 Mar 2022 04:48:23 +0300 Message-ID: <20220324014836.19149-13-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org debugfs_entries structure declared in the dw-edma-v0-debugfs.c module contains the DebugFS node' register address. The address is declared as dma_addr_t type, but first it's assigned with virtual CPU IOMEM address and then it's cast back to the virtual address. Even though the castes sandwich will unlikely cause any problem since normally DMA address is at least of the same size as the CPU virtual address, it's at the very least redundant if not to say logically incorrect. Let's fix it by just stop casting the pointer back and worth and just preserve the address as a pointer to void with __iomem qualifier. Fixes: 305aebeff879 ("dmaengine: Add Synopsys eDMA IP version 0 debugfs support") Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-v0-debugfs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c index 3a899f7f4e8d..12845a2dc016 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c +++ b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c @@ -14,7 +14,7 @@ #include "dw-edma-core.h" #define REGS_ADDR(name) \ - ((void __force *)®s->name) + ((void __iomem *)®s->name) #define REGISTER(name) \ { #name, REGS_ADDR(name) } @@ -48,12 +48,13 @@ static struct { struct debugfs_entries { const char *name; - dma_addr_t *reg; + void __iomem *reg; }; static int dw_edma_debugfs_u32_get(void *data, u64 *val) { - void __iomem *reg = (void __force __iomem *)data; + void __iomem *reg = data; + if (dw->chip->mf == EDMA_MF_EDMA_LEGACY && reg >= (void __iomem *)®s->type.legacy.ch) { void __iomem *ptr = ®s->type.legacy.ch; From patchwork Thu Mar 24 01:48:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793896 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DAC96C4332F for ; Mon, 28 Mar 2022 16:44:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243073AbiC1QqG (ORCPT ); Mon, 28 Mar 2022 12:46:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242615AbiC1QqC (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 563AE21805; Mon, 28 Mar 2022 09:44:13 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 7E3AD1E494C; Thu, 24 Mar 2022 04:48:47 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 7E3AD1E494C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086527; bh=wLAPyaPtsPRVa1ND8kCXVeUvvhDUzzXQxRocrklWVbI=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=SY5I10w9NqJKooJI363WfAJDvIovar1ONLR0t/lJmRrbsiUtAAss9LhXJQzUrtzUj t3ZwDq/JLlpGUpmiqk4Kh7KIWpEt7dlE04UOJViyJNmaKVgirWT00nJoKbBZBNFWzP eczJWfhbEgyBtBX+owrnd93ZJiB7kyXURB5G4zVo= 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:47 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 13/25] dmaengine: dw-edma: Stop checking debugfs_create_*() return value Date: Thu, 24 Mar 2022 04:48:24 +0300 Message-ID: <20220324014836.19149-14-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org First of all they never return NULL. So checking their return value for being not NULL just pointless. Secondly the DebugFS subsystem is designed in a way to be used as simple as possible. So if one of the debugfs_create_*() method in a hierarchy fails, the following methods will just silently return the passed erroneous parental dentry. Finally the code is supposed to be working no matter whether anything DebugFS-related fails. So in order to make code simpler and DebugFS-independent let's drop the debugfs_create_*() methods return value checking in the same way as the most of the kernel drivers do. Note in order to preserve some memory space we suggest to skip the DebugFS nodes initialization if the file system in unavailable. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-v0-debugfs.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c index 12845a2dc016..808eed212be8 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c +++ b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c @@ -100,9 +100,8 @@ static void dw_edma_debugfs_create_x32(const struct debugfs_entries entries[], int i; for (i = 0; i < nr_entries; i++) { - if (!debugfs_create_file_unsafe(entries[i].name, 0444, dir, - entries[i].reg, &fops_x32)) - break; + debugfs_create_file_unsafe(entries[i].name, 0444, dir, + entries[i].reg, &fops_x32); } } @@ -168,8 +167,6 @@ static void dw_edma_debugfs_regs_wr(struct dentry *dir) char name[16]; regs_dir = debugfs_create_dir(WRITE_STR, dir); - if (!regs_dir) - return; nr_entries = ARRAY_SIZE(debugfs_regs); dw_edma_debugfs_create_x32(debugfs_regs, nr_entries, regs_dir); @@ -184,8 +181,6 @@ static void dw_edma_debugfs_regs_wr(struct dentry *dir) snprintf(name, sizeof(name), "%s:%d", CHANNEL_STR, i); ch_dir = debugfs_create_dir(name, regs_dir); - if (!ch_dir) - return; dw_edma_debugfs_regs_ch(®s->type.unroll.ch[i].wr, ch_dir); @@ -237,8 +232,6 @@ static void dw_edma_debugfs_regs_rd(struct dentry *dir) char name[16]; regs_dir = debugfs_create_dir(READ_STR, dir); - if (!regs_dir) - return; nr_entries = ARRAY_SIZE(debugfs_regs); dw_edma_debugfs_create_x32(debugfs_regs, nr_entries, regs_dir); @@ -253,8 +246,6 @@ static void dw_edma_debugfs_regs_rd(struct dentry *dir) snprintf(name, sizeof(name), "%s:%d", CHANNEL_STR, i); ch_dir = debugfs_create_dir(name, regs_dir); - if (!ch_dir) - return; dw_edma_debugfs_regs_ch(®s->type.unroll.ch[i].rd, ch_dir); @@ -273,8 +264,6 @@ static void dw_edma_debugfs_regs(void) int nr_entries; regs_dir = debugfs_create_dir(REGISTERS_STR, dw->debugfs); - if (!regs_dir) - return; nr_entries = ARRAY_SIZE(debugfs_regs); dw_edma_debugfs_create_x32(debugfs_regs, nr_entries, regs_dir); @@ -285,6 +274,9 @@ static void dw_edma_debugfs_regs(void) void dw_edma_v0_debugfs_on(struct dw_edma_chip *chip) { + if (!debugfs_initialized()) + return; + dw = chip->dw; if (!dw) return; @@ -294,8 +286,6 @@ void dw_edma_v0_debugfs_on(struct dw_edma_chip *chip) return; dw->debugfs = debugfs_create_dir(dw->name, NULL); - if (!dw->debugfs) - return; debugfs_create_u32("mf", 0444, dw->debugfs, &dw->chip->mf); debugfs_create_u16("wr_ch_cnt", 0444, dw->debugfs, &dw->wr_ch_cnt); From patchwork Thu Mar 24 01:48:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793910 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48DAEC433FE for ; Mon, 28 Mar 2022 16:44:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243450AbiC1QqX (ORCPT ); Mon, 28 Mar 2022 12:46:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242812AbiC1QqC (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 584F321E1F; 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 29F111E494E; Thu, 24 Mar 2022 04:48:48 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 29F111E494E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086528; bh=yRKAu/9goZY2CuhAhPZ9QnZ4PkDsLD/RYGgM0Q+DtC8=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=OvWOsR1RUWgtRc8GB5l1e+0O5kf1YTiVi1ymudckOkbaXZecCtUTJ3fsm2PXMcAge MwagEtmmLp96mECBvdSOviNSTGOnGu6PQv/G60JSqJdsDlXtQ/weYTOM5pWlC8T3ni McTGo6DAMKkz3xu2YCvTxPPJOLo6ixI9pV+tFdP0= 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:47 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 14/25] dmaengine: dw-edma: Add dw_edma prefix to the DebugFS nodes descriptor Date: Thu, 24 Mar 2022 04:48:25 +0300 Message-ID: <20220324014836.19149-15-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org The rest of the locally defined and used methods and structures have dw_edma prefix in their names. It's right in accordance with the kernel coding style to follow the locally defined rule of naming. Let's add that prefix to the debugfs_entries structure too especially seeing it's name may be confusing as if that structure belongs to the global DebugFS space. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-v0-debugfs.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c index 808eed212be8..afd519d9568b 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c +++ b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c @@ -46,7 +46,7 @@ static struct { void __iomem *end; } lim[2][EDMA_V0_MAX_NR_CH]; -struct debugfs_entries { +struct dw_edma_debugfs_entry { const char *name; void __iomem *reg; }; @@ -94,7 +94,7 @@ static int dw_edma_debugfs_u32_get(void *data, u64 *val) } DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_edma_debugfs_u32_get, NULL, "0x%08llx\n"); -static void dw_edma_debugfs_create_x32(const struct debugfs_entries entries[], +static void dw_edma_debugfs_create_x32(const struct dw_edma_debugfs_entry entries[], int nr_entries, struct dentry *dir) { int i; @@ -108,8 +108,7 @@ static void dw_edma_debugfs_create_x32(const struct debugfs_entries entries[], static void dw_edma_debugfs_regs_ch(struct dw_edma_v0_ch_regs __iomem *regs, struct dentry *dir) { - int nr_entries; - const struct debugfs_entries debugfs_regs[] = { + const struct dw_edma_debugfs_entry debugfs_regs[] = { REGISTER(ch_control1), REGISTER(ch_control2), REGISTER(transfer_size), @@ -120,6 +119,7 @@ static void dw_edma_debugfs_regs_ch(struct dw_edma_v0_ch_regs __iomem *regs, REGISTER(llp.lsb), REGISTER(llp.msb), }; + int nr_entries; nr_entries = ARRAY_SIZE(debugfs_regs); dw_edma_debugfs_create_x32(debugfs_regs, nr_entries, dir); @@ -127,7 +127,7 @@ static void dw_edma_debugfs_regs_ch(struct dw_edma_v0_ch_regs __iomem *regs, static void dw_edma_debugfs_regs_wr(struct dentry *dir) { - const struct debugfs_entries debugfs_regs[] = { + const struct dw_edma_debugfs_entry debugfs_regs[] = { /* eDMA global registers */ WR_REGISTER(engine_en), WR_REGISTER(doorbell), @@ -148,7 +148,7 @@ static void dw_edma_debugfs_regs_wr(struct dentry *dir) WR_REGISTER(ch67_imwr_data), WR_REGISTER(linked_list_err_en), }; - const struct debugfs_entries debugfs_unroll_regs[] = { + const struct dw_edma_debugfs_entry debugfs_unroll_regs[] = { /* eDMA channel context grouping */ WR_REGISTER_UNROLL(engine_chgroup), WR_REGISTER_UNROLL(engine_hshake_cnt.lsb), @@ -191,7 +191,7 @@ static void dw_edma_debugfs_regs_wr(struct dentry *dir) static void dw_edma_debugfs_regs_rd(struct dentry *dir) { - const struct debugfs_entries debugfs_regs[] = { + const struct dw_edma_debugfs_entry debugfs_regs[] = { /* eDMA global registers */ RD_REGISTER(engine_en), RD_REGISTER(doorbell), @@ -213,7 +213,7 @@ static void dw_edma_debugfs_regs_rd(struct dentry *dir) RD_REGISTER(ch45_imwr_data), RD_REGISTER(ch67_imwr_data), }; - const struct debugfs_entries debugfs_unroll_regs[] = { + const struct dw_edma_debugfs_entry debugfs_unroll_regs[] = { /* eDMA channel context grouping */ RD_REGISTER_UNROLL(engine_chgroup), RD_REGISTER_UNROLL(engine_hshake_cnt.lsb), @@ -256,7 +256,7 @@ static void dw_edma_debugfs_regs_rd(struct dentry *dir) static void dw_edma_debugfs_regs(void) { - const struct debugfs_entries debugfs_regs[] = { + const struct dw_edma_debugfs_entry debugfs_regs[] = { REGISTER(ctrl_data_arb_prior), REGISTER(ctrl), }; From patchwork Thu Mar 24 01:48:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793901 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69D7CC4332F for ; Mon, 28 Mar 2022 16:44:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243003AbiC1QqJ (ORCPT ); Mon, 28 Mar 2022 12:46:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242797AbiC1QqC (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 2D32821E13; 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 CE2FC1E4950; Thu, 24 Mar 2022 04:48:48 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru CE2FC1E4950 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086528; bh=07SRlapZtu731QyO68AdsHUcdhg+LQaXPzJQDvb9RUM=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=eD8bqqoWrLE5KJtuTrjuEOsU/DEtGiVtOjb4KxjWS5T5oGoWlp56moVhVyGRAhhB0 n3KHkXc2wudCIyXK5Zw9meNV1AbiK6kh1pBVfyWJK3ZjLNG7kwo4QbKMf+7PkCJuVw rC0UmfcBs0P8pKNDIVyWUaCddfgatAyeTOgVNLs4= 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:48 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 15/25] dmaengine: dw-edma: Convert DebugFS descs to being kz-allocated Date: Thu, 24 Mar 2022 04:48:26 +0300 Message-ID: <20220324014836.19149-16-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org Currently all the DW eDMA DebugFS nodes descriptors are allocated on stack, while the DW eDMA driver private data and CSR limits are statically preserved. Such design won't work for the multi-eDMA platforms. As a preparation to adding the multi-eDMA system setups support we need to have each DebugFS node separately allocated and described. Afterwards we'll put an addition info there like Read/Write channel flag, channel ID, DW eDMA private data reference. Note this conversion is mainly required due to having the legacy DW eDMA controllers with indirect Read/Write channels context CSRs access. If we didn't need to have a synchronized access to these registers the DebugFS code of the driver would have been much simpler. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-v0-debugfs.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c index afd519d9568b..7eb0147912fa 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c +++ b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c @@ -53,7 +53,8 @@ struct dw_edma_debugfs_entry { static int dw_edma_debugfs_u32_get(void *data, u64 *val) { - void __iomem *reg = data; + struct dw_edma_debugfs_entry __iomem *entry = data; + void __iomem *reg = entry->reg; if (dw->chip->mf == EDMA_MF_EDMA_LEGACY && reg >= (void __iomem *)®s->type.legacy.ch) { @@ -94,14 +95,22 @@ static int dw_edma_debugfs_u32_get(void *data, u64 *val) } DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_edma_debugfs_u32_get, NULL, "0x%08llx\n"); -static void dw_edma_debugfs_create_x32(const struct dw_edma_debugfs_entry entries[], +static void dw_edma_debugfs_create_x32(const struct dw_edma_debugfs_entry ini[], int nr_entries, struct dentry *dir) { + struct dw_edma_debugfs_entry *entries; int i; + entries = devm_kcalloc(dw->chip->dev, nr_entries, sizeof(*entries), + GFP_KERNEL); + if (!entries) + return; + for (i = 0; i < nr_entries; i++) { + entries[i] = ini[i]; + debugfs_create_file_unsafe(entries[i].name, 0444, dir, - entries[i].reg, &fops_x32); + &entries[i], &fops_x32); } } From patchwork Thu Mar 24 01:48:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793898 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0AD3EC35274 for ; Mon, 28 Mar 2022 16:44:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242961AbiC1QqI (ORCPT ); Mon, 28 Mar 2022 12:46:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242682AbiC1QqC (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 4D8C42124E; Mon, 28 Mar 2022 09:44:13 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 77E261E4953; Thu, 24 Mar 2022 04:48:49 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 77E261E4953 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086529; bh=JZJEWqKdQKr9YbeOdHWYdW7S8s++tuhxSseVhFiJlis=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=OE+34ruEddDfe5ozzL2W92f3nyXDBc7rUdir0Ep/t8inu9R9DYB9c0ELcVuu1gHgb UkhLuGYiF65zoei7a2IsN7TiSjB8UvGIXsZ+2I+vhb6tjpn93GSuyKTAQ+aTGSoO2o Yq+yLceowDJlBr8KbUYWjiUmmiuibUTTrPbtBs24= 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:49 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 16/25] dmaengine: dw-edma: Simplify the DebugFS context CSRs init procedure Date: Thu, 24 Mar 2022 04:48:27 +0300 Message-ID: <20220324014836.19149-17-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org DW eDMA v4.70a and older have the read and write channels context CSRs indirectly accessible. It means the CSRs like Channel Control, Xfer size, SAR, DAR and LLP address are accessed over at a fixed MMIO address, but their reference to the corresponding channel is determined by the Viewport CSR. In order to have a coherent access to these registers the CSR IOs are supposed to be protected with a spin-lock. DW eDMA v4.80a and newer normally have unrolled Read/Write channel context registers. That is all CSRs denoted before are directly mapped in the controller MMIO space. Since both normal and viewport-based registers are exposed via the DebugFS nodes, the original code author decided to implement an algorithm based on the unrolled CSRs mapping with the viewport addresses recalculation if it's required. The problem is that such implementation turned to be first unscalable (supports a platform with only single eDMA available since a base address statically preserved) and second needlessly overcomplicated (it loops over all Rd/Wr context addresses and re-calculates the viewport base address on each DebugFS node access). The algorithm can be greatly simplified just by adding the channel ID and it's direction fields in the eDMA DebugFS node descriptor. These new parameters can be used to find a CSR offset within the corresponding channel registers space. The DW eDMA DebugFS node getter afterwards will also use them in order to activate the respective context CSRs viewport before reading data from the specified register. In case of the unrolled version of the CSRs mapping there won't be any spin-lock taken/released, no viewport activation as before this modification. Note this modification fixes the REGISTER() macros using an externally defined local variable. The same problem with the rest of the macro will be fixed in the next commit. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-v0-debugfs.c | 84 +++++++++++------------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c index 7eb0147912fa..b34a68964232 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c +++ b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c @@ -15,9 +15,27 @@ #define REGS_ADDR(name) \ ((void __iomem *)®s->name) + +#define REGS_CH_ADDR(name, _dir, _ch) \ + ({ \ + struct dw_edma_v0_ch_regs __iomem *__ch_regs; \ + \ + if ((dw)->chip->mf == EDMA_MF_EDMA_LEGACY) \ + __ch_regs = ®s->type.legacy.ch; \ + else if (_dir == EDMA_DIR_READ) \ + __ch_regs = ®s->type.unroll.ch[_ch].rd; \ + else \ + __ch_regs = ®s->type.unroll.ch[_ch].wr; \ + \ + (void __iomem *)&__ch_regs->name; \ + }) + #define REGISTER(name) \ { #name, REGS_ADDR(name) } +#define CTX_REGISTER(name, dir, ch) \ + { #name, REGS_CH_ADDR(name, dir, ch), dir, ch } + #define WR_REGISTER(name) \ { #name, REGS_ADDR(wr_##name) } #define RD_REGISTER(name) \ @@ -41,14 +59,11 @@ static struct dw_edma *dw; static struct dw_edma_v0_regs __iomem *regs; -static struct { - void __iomem *start; - void __iomem *end; -} lim[2][EDMA_V0_MAX_NR_CH]; - struct dw_edma_debugfs_entry { const char *name; void __iomem *reg; + enum dw_edma_dir dir; + u16 ch; }; static int dw_edma_debugfs_u32_get(void *data, u64 *val) @@ -58,33 +73,16 @@ static int dw_edma_debugfs_u32_get(void *data, u64 *val) if (dw->chip->mf == EDMA_MF_EDMA_LEGACY && reg >= (void __iomem *)®s->type.legacy.ch) { - void __iomem *ptr = ®s->type.legacy.ch; - u32 viewport_sel = 0; unsigned long flags; - u16 ch; - - for (ch = 0; ch < dw->wr_ch_cnt; ch++) - if (lim[0][ch].start >= reg && reg < lim[0][ch].end) { - ptr += (reg - lim[0][ch].start); - goto legacy_sel_wr; - } - - for (ch = 0; ch < dw->rd_ch_cnt; ch++) - if (lim[1][ch].start >= reg && reg < lim[1][ch].end) { - ptr += (reg - lim[1][ch].start); - goto legacy_sel_rd; - } - - return 0; -legacy_sel_rd: - viewport_sel = BIT(31); -legacy_sel_wr: - viewport_sel |= FIELD_PREP(EDMA_V0_VIEWPORT_MASK, ch); + u32 viewport_sel; + + viewport_sel = entry->dir == EDMA_DIR_READ ? BIT(31) : 0; + viewport_sel |= FIELD_PREP(EDMA_V0_VIEWPORT_MASK, entry->ch); raw_spin_lock_irqsave(&dw->lock, flags); writel(viewport_sel, ®s->type.legacy.viewport_sel); - *val = readl(ptr); + *val = readl(reg); raw_spin_unlock_irqrestore(&dw->lock, flags); } else { @@ -114,19 +112,19 @@ static void dw_edma_debugfs_create_x32(const struct dw_edma_debugfs_entry ini[], } } -static void dw_edma_debugfs_regs_ch(struct dw_edma_v0_ch_regs __iomem *regs, +static void dw_edma_debugfs_regs_ch(enum dw_edma_dir edma_dir, u16 ch, struct dentry *dir) { - const struct dw_edma_debugfs_entry debugfs_regs[] = { - REGISTER(ch_control1), - REGISTER(ch_control2), - REGISTER(transfer_size), - REGISTER(sar.lsb), - REGISTER(sar.msb), - REGISTER(dar.lsb), - REGISTER(dar.msb), - REGISTER(llp.lsb), - REGISTER(llp.msb), + struct dw_edma_debugfs_entry debugfs_regs[] = { + CTX_REGISTER(ch_control1, edma_dir, ch), + CTX_REGISTER(ch_control2, edma_dir, ch), + CTX_REGISTER(transfer_size, edma_dir, ch), + CTX_REGISTER(sar.lsb, edma_dir, ch), + CTX_REGISTER(sar.msb, edma_dir, ch), + CTX_REGISTER(dar.lsb, edma_dir, ch), + CTX_REGISTER(dar.msb, edma_dir, ch), + CTX_REGISTER(llp.lsb, edma_dir, ch), + CTX_REGISTER(llp.msb, edma_dir, ch), }; int nr_entries; @@ -191,10 +189,7 @@ static void dw_edma_debugfs_regs_wr(struct dentry *dir) ch_dir = debugfs_create_dir(name, regs_dir); - dw_edma_debugfs_regs_ch(®s->type.unroll.ch[i].wr, ch_dir); - - lim[0][i].start = ®s->type.unroll.ch[i].wr; - lim[0][i].end = ®s->type.unroll.ch[i].padding_1[0]; + dw_edma_debugfs_regs_ch(EDMA_DIR_WRITE, i, ch_dir); } } @@ -256,10 +251,7 @@ static void dw_edma_debugfs_regs_rd(struct dentry *dir) ch_dir = debugfs_create_dir(name, regs_dir); - dw_edma_debugfs_regs_ch(®s->type.unroll.ch[i].rd, ch_dir); - - lim[1][i].start = ®s->type.unroll.ch[i].rd; - lim[1][i].end = ®s->type.unroll.ch[i].padding_2[0]; + dw_edma_debugfs_regs_ch(EDMA_DIR_READ, i, ch_dir); } } From patchwork Thu Mar 24 01:48:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793897 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAB8BC433FE for ; Mon, 28 Mar 2022 16:44:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243083AbiC1QqH (ORCPT ); Mon, 28 Mar 2022 12:46:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242665AbiC1QqB (ORCPT ); Mon, 28 Mar 2022 12:46:01 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id D1B6F20F76; Mon, 28 Mar 2022 09:44:07 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 306FE1E4954; Thu, 24 Mar 2022 04:48:50 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 306FE1E4954 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086530; bh=bPT+ehskV44eMcrbKqD+tgd1O/+hr3UFlbh4X/fJRgA=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=fBuLh/EieZAOj0XmDRCUXOY3SlPruKzuite0yLG48dgkJTwLhn2PP9azf9FWs2QRg yg5Mj+IvMrGRbPT85n5phHE1Gf2FFRQ6pBDK9RC1Zyq4kKFrNbyBv3AWmjSGo8HOqS Jvm5aNXV/ru/bCLK4EtOPa9QQB0Q5QbXwCMKMn3g= 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:49 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 17/25] dmaengine: dw-edma: Move eDMA data pointer to DebugFS node descriptor Date: Thu, 24 Mar 2022 04:48:28 +0300 Message-ID: <20220324014836.19149-18-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org The last thing that really stops the DebugFS part of the eDMA driver from supporting the multi-eDMA platform in is keeping the eDMA private data pointer in the static area of the DebugFS module. Since the DebugFS node descriptors are now kz-allocated we can freely move that pointer to being preserved in the descriptors. After the DebugFS initialization procedure that pointer will be used in the DebugFS files getter to access the common CSRs space and the context CSRs spin-lock. So the main part of this change is connected with the DebugFS nodes descriptors initialization macros, which aside with already defined prototypes now require to have the DW eDMA private data pointer passed. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-v0-debugfs.c | 240 +++++++++++------------ 1 file changed, 118 insertions(+), 122 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c index b34a68964232..353269a3680b 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c +++ b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c @@ -13,53 +13,55 @@ #include "dw-edma-v0-regs.h" #include "dw-edma-core.h" -#define REGS_ADDR(name) \ - ((void __iomem *)®s->name) +#define REGS_ADDR(dw, name) \ + ({ \ + struct dw_edma_v0_regs __iomem *__regs = (dw)->chip->reg_base; \ + \ + (void __iomem *)&__regs->name; \ + }) -#define REGS_CH_ADDR(name, _dir, _ch) \ +#define REGS_CH_ADDR(dw, name, _dir, _ch) \ ({ \ struct dw_edma_v0_ch_regs __iomem *__ch_regs; \ \ if ((dw)->chip->mf == EDMA_MF_EDMA_LEGACY) \ - __ch_regs = ®s->type.legacy.ch; \ + __ch_regs = REGS_ADDR(dw, type.legacy.ch); \ else if (_dir == EDMA_DIR_READ) \ - __ch_regs = ®s->type.unroll.ch[_ch].rd; \ + __ch_regs = REGS_ADDR(dw, type.unroll.ch[_ch].rd); \ else \ - __ch_regs = ®s->type.unroll.ch[_ch].wr; \ + __ch_regs = REGS_ADDR(dw, type.unroll.ch[_ch].wr); \ \ (void __iomem *)&__ch_regs->name; \ }) -#define REGISTER(name) \ - { #name, REGS_ADDR(name) } +#define REGISTER(dw, name) \ + { dw, #name, REGS_ADDR(dw, name) } -#define CTX_REGISTER(name, dir, ch) \ - { #name, REGS_CH_ADDR(name, dir, ch), dir, ch } +#define CTX_REGISTER(dw, name, dir, ch) \ + { dw, #name, REGS_CH_ADDR(dw, name, dir, ch), dir, ch } -#define WR_REGISTER(name) \ - { #name, REGS_ADDR(wr_##name) } -#define RD_REGISTER(name) \ - { #name, REGS_ADDR(rd_##name) } +#define WR_REGISTER(dw, name) \ + { dw, #name, REGS_ADDR(dw, wr_##name) } +#define RD_REGISTER(dw, name) \ + { dw, #name, REGS_ADDR(dw, rd_##name) } -#define WR_REGISTER_LEGACY(name) \ - { #name, REGS_ADDR(type.legacy.wr_##name) } +#define WR_REGISTER_LEGACY(dw, name) \ + { dw, #name, REGS_ADDR(dw, type.legacy.wr_##name) } #define RD_REGISTER_LEGACY(name) \ - { #name, REGS_ADDR(type.legacy.rd_##name) } + { dw, #name, REGS_ADDR(dw, type.legacy.rd_##name) } -#define WR_REGISTER_UNROLL(name) \ - { #name, REGS_ADDR(type.unroll.wr_##name) } -#define RD_REGISTER_UNROLL(name) \ - { #name, REGS_ADDR(type.unroll.rd_##name) } +#define WR_REGISTER_UNROLL(dw, name) \ + { dw, #name, REGS_ADDR(dw, type.unroll.wr_##name) } +#define RD_REGISTER_UNROLL(dw, name) \ + { dw, #name, REGS_ADDR(dw, type.unroll.rd_##name) } #define WRITE_STR "write" #define READ_STR "read" #define CHANNEL_STR "channel" #define REGISTERS_STR "registers" -static struct dw_edma *dw; -static struct dw_edma_v0_regs __iomem *regs; - struct dw_edma_debugfs_entry { + struct dw_edma *dw; const char *name; void __iomem *reg; enum dw_edma_dir dir; @@ -69,10 +71,11 @@ struct dw_edma_debugfs_entry { static int dw_edma_debugfs_u32_get(void *data, u64 *val) { struct dw_edma_debugfs_entry __iomem *entry = data; + struct dw_edma *dw = entry->dw; void __iomem *reg = entry->reg; if (dw->chip->mf == EDMA_MF_EDMA_LEGACY && - reg >= (void __iomem *)®s->type.legacy.ch) { + reg >= REGS_ADDR(dw, type.legacy.ch)) { unsigned long flags; u32 viewport_sel; @@ -81,7 +84,7 @@ static int dw_edma_debugfs_u32_get(void *data, u64 *val) raw_spin_lock_irqsave(&dw->lock, flags); - writel(viewport_sel, ®s->type.legacy.viewport_sel); + writel(viewport_sel, REGS_ADDR(dw, type.legacy.viewport_sel)); *val = readl(reg); raw_spin_unlock_irqrestore(&dw->lock, flags); @@ -93,7 +96,8 @@ static int dw_edma_debugfs_u32_get(void *data, u64 *val) } DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_edma_debugfs_u32_get, NULL, "0x%08llx\n"); -static void dw_edma_debugfs_create_x32(const struct dw_edma_debugfs_entry ini[], +static void dw_edma_debugfs_create_x32(struct dw_edma *dw, + const struct dw_edma_debugfs_entry ini[], int nr_entries, struct dentry *dir) { struct dw_edma_debugfs_entry *entries; @@ -112,62 +116,62 @@ static void dw_edma_debugfs_create_x32(const struct dw_edma_debugfs_entry ini[], } } -static void dw_edma_debugfs_regs_ch(enum dw_edma_dir edma_dir, u16 ch, - struct dentry *dir) +static void dw_edma_debugfs_regs_ch(struct dw_edma *dw, enum dw_edma_dir edma_dir, + u16 ch, struct dentry *dir) { struct dw_edma_debugfs_entry debugfs_regs[] = { - CTX_REGISTER(ch_control1, edma_dir, ch), - CTX_REGISTER(ch_control2, edma_dir, ch), - CTX_REGISTER(transfer_size, edma_dir, ch), - CTX_REGISTER(sar.lsb, edma_dir, ch), - CTX_REGISTER(sar.msb, edma_dir, ch), - CTX_REGISTER(dar.lsb, edma_dir, ch), - CTX_REGISTER(dar.msb, edma_dir, ch), - CTX_REGISTER(llp.lsb, edma_dir, ch), - CTX_REGISTER(llp.msb, edma_dir, ch), + CTX_REGISTER(dw, ch_control1, edma_dir, ch), + CTX_REGISTER(dw, ch_control2, edma_dir, ch), + CTX_REGISTER(dw, transfer_size, edma_dir, ch), + CTX_REGISTER(dw, sar.lsb, edma_dir, ch), + CTX_REGISTER(dw, sar.msb, edma_dir, ch), + CTX_REGISTER(dw, dar.lsb, edma_dir, ch), + CTX_REGISTER(dw, dar.msb, edma_dir, ch), + CTX_REGISTER(dw, llp.lsb, edma_dir, ch), + CTX_REGISTER(dw, llp.msb, edma_dir, ch), }; int nr_entries; nr_entries = ARRAY_SIZE(debugfs_regs); - dw_edma_debugfs_create_x32(debugfs_regs, nr_entries, dir); + dw_edma_debugfs_create_x32(dw, debugfs_regs, nr_entries, dir); } -static void dw_edma_debugfs_regs_wr(struct dentry *dir) +static void dw_edma_debugfs_regs_wr(struct dw_edma *dw, struct dentry *dir) { const struct dw_edma_debugfs_entry debugfs_regs[] = { /* eDMA global registers */ - WR_REGISTER(engine_en), - WR_REGISTER(doorbell), - WR_REGISTER(ch_arb_weight.lsb), - WR_REGISTER(ch_arb_weight.msb), + WR_REGISTER(dw, engine_en), + WR_REGISTER(dw, doorbell), + WR_REGISTER(dw, ch_arb_weight.lsb), + WR_REGISTER(dw, ch_arb_weight.msb), /* eDMA interrupts registers */ - WR_REGISTER(int_status), - WR_REGISTER(int_mask), - WR_REGISTER(int_clear), - WR_REGISTER(err_status), - WR_REGISTER(done_imwr.lsb), - WR_REGISTER(done_imwr.msb), - WR_REGISTER(abort_imwr.lsb), - WR_REGISTER(abort_imwr.msb), - WR_REGISTER(ch01_imwr_data), - WR_REGISTER(ch23_imwr_data), - WR_REGISTER(ch45_imwr_data), - WR_REGISTER(ch67_imwr_data), - WR_REGISTER(linked_list_err_en), + WR_REGISTER(dw, int_status), + WR_REGISTER(dw, int_mask), + WR_REGISTER(dw, int_clear), + WR_REGISTER(dw, err_status), + WR_REGISTER(dw, done_imwr.lsb), + WR_REGISTER(dw, done_imwr.msb), + WR_REGISTER(dw, abort_imwr.lsb), + WR_REGISTER(dw, abort_imwr.msb), + WR_REGISTER(dw, ch01_imwr_data), + WR_REGISTER(dw, ch23_imwr_data), + WR_REGISTER(dw, ch45_imwr_data), + WR_REGISTER(dw, ch67_imwr_data), + WR_REGISTER(dw, linked_list_err_en), }; const struct dw_edma_debugfs_entry debugfs_unroll_regs[] = { /* eDMA channel context grouping */ - WR_REGISTER_UNROLL(engine_chgroup), - WR_REGISTER_UNROLL(engine_hshake_cnt.lsb), - WR_REGISTER_UNROLL(engine_hshake_cnt.msb), - WR_REGISTER_UNROLL(ch0_pwr_en), - WR_REGISTER_UNROLL(ch1_pwr_en), - WR_REGISTER_UNROLL(ch2_pwr_en), - WR_REGISTER_UNROLL(ch3_pwr_en), - WR_REGISTER_UNROLL(ch4_pwr_en), - WR_REGISTER_UNROLL(ch5_pwr_en), - WR_REGISTER_UNROLL(ch6_pwr_en), - WR_REGISTER_UNROLL(ch7_pwr_en), + WR_REGISTER_UNROLL(dw, engine_chgroup), + WR_REGISTER_UNROLL(dw, engine_hshake_cnt.lsb), + WR_REGISTER_UNROLL(dw, engine_hshake_cnt.msb), + WR_REGISTER_UNROLL(dw, ch0_pwr_en), + WR_REGISTER_UNROLL(dw, ch1_pwr_en), + WR_REGISTER_UNROLL(dw, ch2_pwr_en), + WR_REGISTER_UNROLL(dw, ch3_pwr_en), + WR_REGISTER_UNROLL(dw, ch4_pwr_en), + WR_REGISTER_UNROLL(dw, ch5_pwr_en), + WR_REGISTER_UNROLL(dw, ch6_pwr_en), + WR_REGISTER_UNROLL(dw, ch7_pwr_en), }; struct dentry *regs_dir, *ch_dir; int nr_entries, i; @@ -176,11 +180,11 @@ static void dw_edma_debugfs_regs_wr(struct dentry *dir) regs_dir = debugfs_create_dir(WRITE_STR, dir); nr_entries = ARRAY_SIZE(debugfs_regs); - dw_edma_debugfs_create_x32(debugfs_regs, nr_entries, regs_dir); + dw_edma_debugfs_create_x32(dw, debugfs_regs, nr_entries, regs_dir); if (dw->chip->mf == EDMA_MF_HDMA_COMPAT) { nr_entries = ARRAY_SIZE(debugfs_unroll_regs); - dw_edma_debugfs_create_x32(debugfs_unroll_regs, nr_entries, + dw_edma_debugfs_create_x32(dw, debugfs_unroll_regs, nr_entries, regs_dir); } @@ -189,47 +193,47 @@ static void dw_edma_debugfs_regs_wr(struct dentry *dir) ch_dir = debugfs_create_dir(name, regs_dir); - dw_edma_debugfs_regs_ch(EDMA_DIR_WRITE, i, ch_dir); + dw_edma_debugfs_regs_ch(dw, EDMA_DIR_WRITE, i, ch_dir); } } -static void dw_edma_debugfs_regs_rd(struct dentry *dir) +static void dw_edma_debugfs_regs_rd(struct dw_edma *dw, struct dentry *dir) { const struct dw_edma_debugfs_entry debugfs_regs[] = { /* eDMA global registers */ - RD_REGISTER(engine_en), - RD_REGISTER(doorbell), - RD_REGISTER(ch_arb_weight.lsb), - RD_REGISTER(ch_arb_weight.msb), + RD_REGISTER(dw, engine_en), + RD_REGISTER(dw, doorbell), + RD_REGISTER(dw, ch_arb_weight.lsb), + RD_REGISTER(dw, ch_arb_weight.msb), /* eDMA interrupts registers */ - RD_REGISTER(int_status), - RD_REGISTER(int_mask), - RD_REGISTER(int_clear), - RD_REGISTER(err_status.lsb), - RD_REGISTER(err_status.msb), - RD_REGISTER(linked_list_err_en), - RD_REGISTER(done_imwr.lsb), - RD_REGISTER(done_imwr.msb), - RD_REGISTER(abort_imwr.lsb), - RD_REGISTER(abort_imwr.msb), - RD_REGISTER(ch01_imwr_data), - RD_REGISTER(ch23_imwr_data), - RD_REGISTER(ch45_imwr_data), - RD_REGISTER(ch67_imwr_data), + RD_REGISTER(dw, int_status), + RD_REGISTER(dw, int_mask), + RD_REGISTER(dw, int_clear), + RD_REGISTER(dw, err_status.lsb), + RD_REGISTER(dw, err_status.msb), + RD_REGISTER(dw, linked_list_err_en), + RD_REGISTER(dw, done_imwr.lsb), + RD_REGISTER(dw, done_imwr.msb), + RD_REGISTER(dw, abort_imwr.lsb), + RD_REGISTER(dw, abort_imwr.msb), + RD_REGISTER(dw, ch01_imwr_data), + RD_REGISTER(dw, ch23_imwr_data), + RD_REGISTER(dw, ch45_imwr_data), + RD_REGISTER(dw, ch67_imwr_data), }; const struct dw_edma_debugfs_entry debugfs_unroll_regs[] = { /* eDMA channel context grouping */ - RD_REGISTER_UNROLL(engine_chgroup), - RD_REGISTER_UNROLL(engine_hshake_cnt.lsb), - RD_REGISTER_UNROLL(engine_hshake_cnt.msb), - RD_REGISTER_UNROLL(ch0_pwr_en), - RD_REGISTER_UNROLL(ch1_pwr_en), - RD_REGISTER_UNROLL(ch2_pwr_en), - RD_REGISTER_UNROLL(ch3_pwr_en), - RD_REGISTER_UNROLL(ch4_pwr_en), - RD_REGISTER_UNROLL(ch5_pwr_en), - RD_REGISTER_UNROLL(ch6_pwr_en), - RD_REGISTER_UNROLL(ch7_pwr_en), + RD_REGISTER_UNROLL(dw, engine_chgroup), + RD_REGISTER_UNROLL(dw, engine_hshake_cnt.lsb), + RD_REGISTER_UNROLL(dw, engine_hshake_cnt.msb), + RD_REGISTER_UNROLL(dw, ch0_pwr_en), + RD_REGISTER_UNROLL(dw, ch1_pwr_en), + RD_REGISTER_UNROLL(dw, ch2_pwr_en), + RD_REGISTER_UNROLL(dw, ch3_pwr_en), + RD_REGISTER_UNROLL(dw, ch4_pwr_en), + RD_REGISTER_UNROLL(dw, ch5_pwr_en), + RD_REGISTER_UNROLL(dw, ch6_pwr_en), + RD_REGISTER_UNROLL(dw, ch7_pwr_en), }; struct dentry *regs_dir, *ch_dir; int nr_entries, i; @@ -238,11 +242,11 @@ static void dw_edma_debugfs_regs_rd(struct dentry *dir) regs_dir = debugfs_create_dir(READ_STR, dir); nr_entries = ARRAY_SIZE(debugfs_regs); - dw_edma_debugfs_create_x32(debugfs_regs, nr_entries, regs_dir); + dw_edma_debugfs_create_x32(dw, debugfs_regs, nr_entries, regs_dir); if (dw->chip->mf == EDMA_MF_HDMA_COMPAT) { nr_entries = ARRAY_SIZE(debugfs_unroll_regs); - dw_edma_debugfs_create_x32(debugfs_unroll_regs, nr_entries, + dw_edma_debugfs_create_x32(dw, debugfs_unroll_regs, nr_entries, regs_dir); } @@ -251,15 +255,15 @@ static void dw_edma_debugfs_regs_rd(struct dentry *dir) ch_dir = debugfs_create_dir(name, regs_dir); - dw_edma_debugfs_regs_ch(EDMA_DIR_READ, i, ch_dir); + dw_edma_debugfs_regs_ch(dw, EDMA_DIR_READ, i, ch_dir); } } -static void dw_edma_debugfs_regs(void) +static void dw_edma_debugfs_regs(struct dw_edma *dw) { const struct dw_edma_debugfs_entry debugfs_regs[] = { - REGISTER(ctrl_data_arb_prior), - REGISTER(ctrl), + REGISTER(dw, ctrl_data_arb_prior), + REGISTER(dw, ctrl), }; struct dentry *regs_dir; int nr_entries; @@ -267,23 +271,17 @@ static void dw_edma_debugfs_regs(void) regs_dir = debugfs_create_dir(REGISTERS_STR, dw->debugfs); nr_entries = ARRAY_SIZE(debugfs_regs); - dw_edma_debugfs_create_x32(debugfs_regs, nr_entries, regs_dir); + dw_edma_debugfs_create_x32(dw, debugfs_regs, nr_entries, regs_dir); - dw_edma_debugfs_regs_wr(regs_dir); - dw_edma_debugfs_regs_rd(regs_dir); + dw_edma_debugfs_regs_wr(dw, regs_dir); + dw_edma_debugfs_regs_rd(dw, regs_dir); } void dw_edma_v0_debugfs_on(struct dw_edma_chip *chip) { - if (!debugfs_initialized()) - return; - - dw = chip->dw; - if (!dw) - return; + struct dw_edma *dw = chip->dw; - regs = dw->chip->reg_base; - if (!regs) + if (!debugfs_initialized()) return; dw->debugfs = debugfs_create_dir(dw->name, NULL); @@ -292,14 +290,12 @@ void dw_edma_v0_debugfs_on(struct dw_edma_chip *chip) debugfs_create_u16("wr_ch_cnt", 0444, dw->debugfs, &dw->wr_ch_cnt); debugfs_create_u16("rd_ch_cnt", 0444, dw->debugfs, &dw->rd_ch_cnt); - dw_edma_debugfs_regs(); + dw_edma_debugfs_regs(dw); } void dw_edma_v0_debugfs_off(struct dw_edma_chip *chip) { - dw = chip->dw; - if (!dw) - return; + struct dw_edma *dw = chip->dw; debugfs_remove_recursive(dw->debugfs); dw->debugfs = NULL; From patchwork Thu Mar 24 01:48:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793900 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E74FFC4167D for ; Mon, 28 Mar 2022 16:44:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242998AbiC1QqJ (ORCPT ); Mon, 28 Mar 2022 12:46:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242793AbiC1QqC (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 F3D8621E12; Mon, 28 Mar 2022 09:44:15 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id E1B5C1E4956; Thu, 24 Mar 2022 04:48:50 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru E1B5C1E4956 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086530; bh=emy75h2x2fdP3KqcUyYAO2rgjkVHZk1TC8qe3kkwqpA=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=SaF9z9wTxCdEjnUOTuC+IjXg9GdEBW8+qeLQdLvajvIyFtRJttfCMMiq06FSO14Uk 00nOVDqz21/88QDZ9KwBymC9WnA17xA6xtiTLpcA+A+CoWM2rUYrm8XH5Vz0xMUx6j JkfzKXWuLKR+0hRExncPv1uYDDrsB+rIa2v0HdzI= 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:50 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 18/25] dmaengine: dw-edma: Join Write/Read channels into a single device Date: Thu, 24 Mar 2022 04:48:29 +0300 Message-ID: <20220324014836.19149-19-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org Indeed there is no point in such split up because due to multiple reasons. First of all eDMA read and write channels belong to one physical controller. Splitting them up illogical. Secondly the channels differentiating can be done by means of the filtering and the dma_get_slave_caps() method. Finally having these channels handled separately not only needlessly complicates the code, but also causes the DebugFS error printed to console: >> Debugfs: Directory '1f052000.pcie' with parent 'dmaengine' already present! So to speak let's join the read/write channels into a single DMA device. The client drivers will be able to choose the channel with required capability by getting the DMA slave direction setting. It's default value is overridden by the dw_edma_device_caps() callback in accordance with the channel nature. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 117 +++++++++++++++-------------- drivers/dma/dw-edma/dw-edma-core.h | 5 +- 2 files changed, 62 insertions(+), 60 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index cefa73412bf7..a391e44da039 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -209,6 +209,24 @@ static void dw_edma_start_transfer(struct dw_edma_chan *chan) desc->chunks_alloc--; } +static void dw_edma_device_caps(struct dma_chan *dchan, + struct dma_slave_caps *caps) +{ + struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan); + + if (chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) { + if (chan->dir == EDMA_DIR_READ) + caps->directions = BIT(DMA_DEV_TO_MEM); + else + caps->directions = BIT(DMA_MEM_TO_DEV); + } else { + if (chan->dir == EDMA_DIR_WRITE) + caps->directions = BIT(DMA_DEV_TO_MEM); + else + caps->directions = BIT(DMA_MEM_TO_DEV); + } +} + static int dw_edma_device_config(struct dma_chan *dchan, struct dma_slave_config *config) { @@ -723,8 +741,8 @@ static void dw_edma_free_chan_resources(struct dma_chan *dchan) pm_runtime_put(chan->dw->chip->dev); } -static int dw_edma_channel_setup(struct dw_edma_chip *chip, bool write, - u32 wr_alloc, u32 rd_alloc) +static int dw_edma_channel_setup(struct dw_edma_chip *chip, u32 wr_alloc, + u32 rd_alloc) { struct dw_edma_region *dt_region; struct device *dev = chip->dev; @@ -732,27 +750,15 @@ static int dw_edma_channel_setup(struct dw_edma_chip *chip, bool write, struct dw_edma_chan *chan; struct dw_edma_irq *irq; struct dma_device *dma; - u32 alloc, off_alloc; - u32 i, j, cnt; - int err = 0; + u32 i, ch_cnt; u32 pos; - if (write) { - i = 0; - cnt = dw->wr_ch_cnt; - dma = &dw->wr_edma; - alloc = wr_alloc; - off_alloc = 0; - } else { - i = dw->wr_ch_cnt; - cnt = dw->rd_ch_cnt; - dma = &dw->rd_edma; - alloc = rd_alloc; - off_alloc = wr_alloc; - } + ch_cnt = dw->wr_ch_cnt + dw->rd_ch_cnt; + dma = &dw->dma; INIT_LIST_HEAD(&dma->channels); - for (j = 0; (alloc || chip->nr_irqs == 1) && j < cnt; j++, i++) { + + for (i = 0; i < ch_cnt; i++) { chan = &dw->chan[i]; dt_region = devm_kzalloc(dev, sizeof(*dt_region), GFP_KERNEL); @@ -762,52 +768,62 @@ static int dw_edma_channel_setup(struct dw_edma_chip *chip, bool write, chan->vc.chan.private = dt_region; chan->dw = dw; - chan->id = j; - chan->dir = write ? EDMA_DIR_WRITE : EDMA_DIR_READ; + + if (i < dw->wr_ch_cnt) { + chan->id = i; + chan->dir = EDMA_DIR_WRITE; + } else { + chan->id = i - dw->wr_ch_cnt; + chan->dir = EDMA_DIR_READ; + } + chan->configured = false; chan->request = EDMA_REQ_NONE; chan->status = EDMA_ST_IDLE; - if (write) - chan->ll_max = (chip->ll_region_wr[j].sz / EDMA_LL_SZ); + if (chan->dir == EDMA_DIR_WRITE) + chan->ll_max = (chip->ll_region_wr[chan->id].sz / EDMA_LL_SZ); else - chan->ll_max = (chip->ll_region_rd[j].sz / EDMA_LL_SZ); + chan->ll_max = (chip->ll_region_rd[chan->id].sz / EDMA_LL_SZ); chan->ll_max -= 1; dev_vdbg(dev, "L. List:\tChannel %s[%u] max_cnt=%u\n", - write ? "write" : "read", j, chan->ll_max); + chan->dir == EDMA_DIR_WRITE ? "write" : "read", + chan->id, chan->ll_max); if (chip->nr_irqs == 1) pos = 0; + else if (chan->dir == EDMA_DIR_WRITE) + pos = chan->id % wr_alloc; else - pos = off_alloc + (j % alloc); + pos = wr_alloc + chan->id % rd_alloc; irq = &dw->irq[pos]; - if (write) - irq->wr_mask |= BIT(j); + if (chan->dir == EDMA_DIR_WRITE) + irq->wr_mask |= BIT(chan->id); else - irq->rd_mask |= BIT(j); + irq->rd_mask |= BIT(chan->id); irq->dw = dw; memcpy(&chan->msi, &irq->msi, sizeof(chan->msi)); dev_vdbg(dev, "MSI:\t\tChannel %s[%u] addr=0x%.8x%.8x, data=0x%.8x\n", - write ? "write" : "read", j, + chan->dir == EDMA_DIR_WRITE ? "write" : "read", chan->id, chan->msi.address_hi, chan->msi.address_lo, chan->msi.data); chan->vc.desc_free = vchan_free_desc; vchan_init(&chan->vc, dma); - if (write) { - dt_region->paddr = chip->dt_region_wr[j].paddr; - dt_region->vaddr = chip->dt_region_wr[j].vaddr; - dt_region->sz = chip->dt_region_wr[j].sz; + if (chan->dir == EDMA_DIR_WRITE) { + dt_region->paddr = chip->dt_region_wr[chan->id].paddr; + dt_region->vaddr = chip->dt_region_wr[chan->id].vaddr; + dt_region->sz = chip->dt_region_wr[chan->id].sz; } else { - dt_region->paddr = chip->dt_region_rd[j].paddr; - dt_region->vaddr = chip->dt_region_rd[j].vaddr; - dt_region->sz = chip->dt_region_rd[j].sz; + dt_region->paddr = chip->dt_region_rd[chan->id].paddr; + dt_region->vaddr = chip->dt_region_rd[chan->id].vaddr; + dt_region->sz = chip->dt_region_rd[chan->id].sz; } dw_edma_v0_core_device_config(chan); @@ -819,7 +835,7 @@ static int dw_edma_channel_setup(struct dw_edma_chip *chip, bool write, dma_cap_set(DMA_CYCLIC, dma->cap_mask); dma_cap_set(DMA_PRIVATE, dma->cap_mask); dma_cap_set(DMA_INTERLEAVE, dma->cap_mask); - dma->directions = BIT(write ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV); + dma->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); dma->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); dma->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); dma->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; @@ -828,6 +844,7 @@ static int dw_edma_channel_setup(struct dw_edma_chip *chip, bool write, dma->dev = chip->dev; dma->device_alloc_chan_resources = dw_edma_alloc_chan_resources; dma->device_free_chan_resources = dw_edma_free_chan_resources; + dma->device_caps = dw_edma_device_caps; dma->device_config = dw_edma_device_config; dma->device_pause = dw_edma_device_pause; dma->device_resume = dw_edma_device_resume; @@ -841,9 +858,7 @@ static int dw_edma_channel_setup(struct dw_edma_chip *chip, bool write, dma_set_max_seg_size(dma->dev, U32_MAX); /* Register DMA device */ - err = dma_async_device_register(dma); - - return err; + return dma_async_device_register(dma); } static inline void dw_edma_dec_irq_alloc(int *nr_irqs, u32 *alloc, u16 cnt) @@ -982,13 +997,8 @@ int dw_edma_probe(struct dw_edma_chip *chip) if (err) return err; - /* Setup write channels */ - err = dw_edma_channel_setup(chip, true, wr_alloc, rd_alloc); - if (err) - goto err_irq_free; - - /* Setup read channels */ - err = dw_edma_channel_setup(chip, false, wr_alloc, rd_alloc); + /* Setup write/read channels */ + err = dw_edma_channel_setup(chip, wr_alloc, rd_alloc); if (err) goto err_irq_free; @@ -1028,15 +1038,8 @@ int dw_edma_remove(struct dw_edma_chip *chip) pm_runtime_disable(dev); /* Deregister eDMA device */ - dma_async_device_unregister(&dw->wr_edma); - list_for_each_entry_safe(chan, _chan, &dw->wr_edma.channels, - vc.chan.device_node) { - tasklet_kill(&chan->vc.task); - list_del(&chan->vc.chan.device_node); - } - - dma_async_device_unregister(&dw->rd_edma); - list_for_each_entry_safe(chan, _chan, &dw->rd_edma.channels, + dma_async_device_unregister(&dw->dma); + list_for_each_entry_safe(chan, _chan, &dw->dma.channels, vc.chan.device_node) { tasklet_kill(&chan->vc.task); list_del(&chan->vc.chan.device_node); diff --git a/drivers/dma/dw-edma/dw-edma-core.h b/drivers/dma/dw-edma/dw-edma-core.h index e254c2fc3d9c..ec9f84a857d1 100644 --- a/drivers/dma/dw-edma/dw-edma-core.h +++ b/drivers/dma/dw-edma/dw-edma-core.h @@ -98,10 +98,9 @@ struct dw_edma_irq { struct dw_edma { char name[20]; - struct dma_device wr_edma; - u16 wr_ch_cnt; + struct dma_device dma; - struct dma_device rd_edma; + u16 wr_ch_cnt; u16 rd_ch_cnt; struct dw_edma_irq *irq; From patchwork Thu Mar 24 01:48:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793911 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79E1DC4332F for ; Mon, 28 Mar 2022 16:44:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239197AbiC1QqY (ORCPT ); Mon, 28 Mar 2022 12:46:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242764AbiC1QqC (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 A524E21E06; Mon, 28 Mar 2022 09:44:15 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 0D8591E4957; Thu, 24 Mar 2022 04:48:52 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 0D8591E4957 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086532; bh=6r8gaQsOYq/p4RX7+mLlgeUaSGu+wrHHd6FACxtxVx4=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=baS8gS76iAlILpvT5olXT8ykmqBOamm4ZjLq1TSMgcAqYxgSX82luvDPyZ91MN7gn uqX+PS84so5Bk7Ix79JAMIwOVB7WkXtXVkM/phh5vjHmxrSk0ejqs4c0pFruT8xLQb tki+Xst7GsH9ZR8DlwZTMX4m8oOsQKAXHTE11UU8= 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:51 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 19/25] dmaengine: dw-edma: Use DMA-engine device DebugFS subdirectory Date: Thu, 24 Mar 2022 04:48:30 +0300 Message-ID: <20220324014836.19149-20-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org Since all DW eDMA read and write channels are now installed in a framework of a single DMA-engine device, we can freely move all the DW eDMA-specific DebugFS nodes into a ready-to-use DMA-engine DebugFS subdirectory. It's created during the DMA-device registration and can be found in the dma_device.dbg_dev_root field. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 3 --- drivers/dma/dw-edma/dw-edma-core.h | 3 --- drivers/dma/dw-edma/dw-edma-v0-core.c | 5 ----- drivers/dma/dw-edma/dw-edma-v0-core.h | 1 - drivers/dma/dw-edma/dw-edma-v0-debugfs.c | 18 ++++-------------- drivers/dma/dw-edma/dw-edma-v0-debugfs.h | 5 ----- 6 files changed, 4 insertions(+), 31 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index a391e44da039..bc530f0a2468 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -1045,9 +1045,6 @@ int dw_edma_remove(struct dw_edma_chip *chip) list_del(&chan->vc.chan.device_node); } - /* Turn debugfs off */ - dw_edma_v0_core_debugfs_off(chip); - return 0; } EXPORT_SYMBOL_GPL(dw_edma_remove); diff --git a/drivers/dma/dw-edma/dw-edma-core.h b/drivers/dma/dw-edma/dw-edma-core.h index ec9f84a857d1..980adb079182 100644 --- a/drivers/dma/dw-edma/dw-edma-core.h +++ b/drivers/dma/dw-edma/dw-edma-core.h @@ -110,9 +110,6 @@ struct dw_edma { raw_spinlock_t lock; /* Only for legacy */ struct dw_edma_chip *chip; -#ifdef CONFIG_DEBUG_FS - struct dentry *debugfs; -#endif /* CONFIG_DEBUG_FS */ }; struct dw_edma_sg { diff --git a/drivers/dma/dw-edma/dw-edma-v0-core.c b/drivers/dma/dw-edma/dw-edma-v0-core.c index 013d9a9cb991..6b303d5a6b2a 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-core.c +++ b/drivers/dma/dw-edma/dw-edma-v0-core.c @@ -511,8 +511,3 @@ void dw_edma_v0_core_debugfs_on(struct dw_edma_chip *chip) { dw_edma_v0_debugfs_on(chip); } - -void dw_edma_v0_core_debugfs_off(struct dw_edma_chip *chip) -{ - dw_edma_v0_debugfs_off(chip); -} diff --git a/drivers/dma/dw-edma/dw-edma-v0-core.h b/drivers/dma/dw-edma/dw-edma-v0-core.h index 2afa626b8300..43e01844375a 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-core.h +++ b/drivers/dma/dw-edma/dw-edma-v0-core.h @@ -23,6 +23,5 @@ void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first); int dw_edma_v0_core_device_config(struct dw_edma_chan *chan); /* eDMA debug fs callbacks */ void dw_edma_v0_core_debugfs_on(struct dw_edma_chip *chip); -void dw_edma_v0_core_debugfs_off(struct dw_edma_chip *chip); #endif /* _DW_EDMA_V0_CORE_H */ diff --git a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c index 353269a3680b..319a3c790dc4 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-debugfs.c +++ b/drivers/dma/dw-edma/dw-edma-v0-debugfs.c @@ -268,7 +268,7 @@ static void dw_edma_debugfs_regs(struct dw_edma *dw) struct dentry *regs_dir; int nr_entries; - regs_dir = debugfs_create_dir(REGISTERS_STR, dw->debugfs); + regs_dir = debugfs_create_dir(REGISTERS_STR, dw->dma.dbg_dev_root); nr_entries = ARRAY_SIZE(debugfs_regs); dw_edma_debugfs_create_x32(dw, debugfs_regs, nr_entries, regs_dir); @@ -284,19 +284,9 @@ void dw_edma_v0_debugfs_on(struct dw_edma_chip *chip) if (!debugfs_initialized()) return; - dw->debugfs = debugfs_create_dir(dw->name, NULL); - - debugfs_create_u32("mf", 0444, dw->debugfs, &dw->chip->mf); - debugfs_create_u16("wr_ch_cnt", 0444, dw->debugfs, &dw->wr_ch_cnt); - debugfs_create_u16("rd_ch_cnt", 0444, dw->debugfs, &dw->rd_ch_cnt); + debugfs_create_u32("mf", 0444, dw->dma.dbg_dev_root, &dw->chip->mf); + debugfs_create_u16("wr_ch_cnt", 0444, dw->dma.dbg_dev_root, &dw->wr_ch_cnt); + debugfs_create_u16("rd_ch_cnt", 0444, dw->dma.dbg_dev_root, &dw->rd_ch_cnt); dw_edma_debugfs_regs(dw); } - -void dw_edma_v0_debugfs_off(struct dw_edma_chip *chip) -{ - struct dw_edma *dw = chip->dw; - - debugfs_remove_recursive(dw->debugfs); - dw->debugfs = NULL; -} diff --git a/drivers/dma/dw-edma/dw-edma-v0-debugfs.h b/drivers/dma/dw-edma/dw-edma-v0-debugfs.h index d0ff25a9ea5c..eb11802c2b76 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-debugfs.h +++ b/drivers/dma/dw-edma/dw-edma-v0-debugfs.h @@ -13,15 +13,10 @@ #ifdef CONFIG_DEBUG_FS void dw_edma_v0_debugfs_on(struct dw_edma_chip *chip); -void dw_edma_v0_debugfs_off(struct dw_edma_chip *chip); #else static inline void dw_edma_v0_debugfs_on(struct dw_edma_chip *chip) { } - -static inline void dw_edma_v0_debugfs_off(struct dw_edma_chip *chip) -{ -} #endif /* CONFIG_DEBUG_FS */ #endif /* _DW_EDMA_V0_DEBUG_FS_H */ From patchwork Thu Mar 24 01:48:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793892 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28855C433FE for ; Mon, 28 Mar 2022 16:44:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242694AbiC1QqD (ORCPT ); Mon, 28 Mar 2022 12:46:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242654AbiC1Qpy (ORCPT ); Mon, 28 Mar 2022 12:45:54 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id D130A20F75; Mon, 28 Mar 2022 09:44:07 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id AEF031E4959; Thu, 24 Mar 2022 04:48:52 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru AEF031E4959 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086532; bh=+IEDsRaJtaAOEVZuZm2s1zd6/7iKdTGU1JFLulsvSLI=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=p48lkGjl46eibcqigaSeooGcXN4oiX+1XKr8udykhWbY8ex1r/lUwcp59IYwaRUBl Qy1nG9u0NO4V2EBXDZN/LWdzirJDaNo3cnD5oj1bfw1PWSQL8tdFGADIldlH6NDeZ9 QQaHR7/ToedaDDQu/AuYbZ2d+/auA43JRGLxzyJk= 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:52 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 20/25] dmaengine: dw-edma: Use non-atomic io-64 methods Date: Thu, 24 Mar 2022 04:48:31 +0300 Message-ID: <20220324014836.19149-21-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org Instead of splitting the 64-bits IOs up into two 32-bits ones it's possible to use an available set of the non-atomic readq/writeq methods implemented exactly for such cases. They are defined in the dedicated header files io-64-nonatomic-lo-hi.h/io-64-nonatomic-hi-lo.h. So in case if the 64-bits readq/writeq methods are unavailable on some platforms at consideration, the corresponding drivers can have any of these headers included and stop locally re-implementing the 64-bits IO accessors taking into account the non-atomic nature of the included methods. Let's do that in the DW eDMA driver too. Note by doing so we can discard the CONFIG_64BIT config ifdefs from the code. Also note that if a platform doesn't support 64-bit DBI IOs then the corresponding accessors will just directly call the lo_hi_readq()/lo_hi_writeq() methods. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-v0-core.c | 71 +++++++++------------------ 1 file changed, 24 insertions(+), 47 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-v0-core.c b/drivers/dma/dw-edma/dw-edma-v0-core.c index 6b303d5a6b2a..ebb860e19c75 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-core.c +++ b/drivers/dma/dw-edma/dw-edma-v0-core.c @@ -8,6 +8,8 @@ #include +#include + #include "dw-edma-core.h" #include "dw-edma-v0-core.h" #include "dw-edma-v0-regs.h" @@ -53,8 +55,6 @@ static inline struct dw_edma_v0_regs __iomem *__dw_regs(struct dw_edma *dw) SET_32(dw, rd_##name, value); \ } while (0) -#ifdef CONFIG_64BIT - #define SET_64(dw, name, value) \ writeq(value, &(__dw_regs(dw)->name)) @@ -80,8 +80,6 @@ static inline struct dw_edma_v0_regs __iomem *__dw_regs(struct dw_edma *dw) SET_64(dw, rd_##name, value); \ } while (0) -#endif /* CONFIG_64BIT */ - #define SET_COMPAT(dw, name, value) \ writel(value, &(__dw_regs(dw)->type.unroll.name)) @@ -164,14 +162,13 @@ static inline u32 readl_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch, #define SET_LL_32(ll, value) \ writel(value, ll) -#ifdef CONFIG_64BIT - static inline void writeq_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch, u64 value, void __iomem *addr) { + unsigned long flags; + if (dw->chip->mf == EDMA_MF_EDMA_LEGACY) { u32 viewport_sel; - unsigned long flags; raw_spin_lock_irqsave(&dw->lock, flags); @@ -181,22 +178,25 @@ static inline void writeq_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch, writel(viewport_sel, &(__dw_regs(dw)->type.legacy.viewport_sel)); + } + + if (dw->chip->flags & DW_EDMA_CHIP_32BIT_DBI) + lo_hi_writeq(value, addr); + else writeq(value, addr); + if (dw->chip->mf == EDMA_MF_EDMA_LEGACY) raw_spin_unlock_irqrestore(&dw->lock, flags); - } else { - writeq(value, addr); - } } static inline u64 readq_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch, const void __iomem *addr) { - u32 value; + unsigned long flags; + u64 value; if (dw->chip->mf == EDMA_MF_EDMA_LEGACY) { u32 viewport_sel; - unsigned long flags; raw_spin_lock_irqsave(&dw->lock, flags); @@ -206,12 +206,15 @@ static inline u64 readq_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch, writel(viewport_sel, &(__dw_regs(dw)->type.legacy.viewport_sel)); + } + + if (dw->chip->flags & DW_EDMA_CHIP_32BIT_DBI) + value = lo_hi_readq(addr); + else value = readq(addr); + if (dw->chip->mf == EDMA_MF_EDMA_LEGACY) raw_spin_unlock_irqrestore(&dw->lock, flags); - } else { - value = readq(addr); - } return value; } @@ -225,8 +228,6 @@ static inline u64 readq_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch, #define SET_LL_64(ll, value) \ writeq(value, ll) -#endif /* CONFIG_64BIT */ - /* eDMA management callbacks */ void dw_edma_v0_core_off(struct dw_edma *dw) { @@ -325,19 +326,10 @@ static void dw_edma_v0_core_write_chunk(struct dw_edma_chunk *chunk) /* Transfer size */ SET_LL_32(&lli[i].transfer_size, child->sz); /* SAR */ - #ifdef CONFIG_64BIT - SET_LL_64(&lli[i].sar.reg, child->sar); - #else /* CONFIG_64BIT */ - SET_LL_32(&lli[i].sar.lsb, lower_32_bits(child->sar)); - SET_LL_32(&lli[i].sar.msb, upper_32_bits(child->sar)); - #endif /* CONFIG_64BIT */ + SET_LL_64(&lli[i].sar.reg, child->sar); /* DAR */ - #ifdef CONFIG_64BIT - SET_LL_64(&lli[i].dar.reg, child->dar); - #else /* CONFIG_64BIT */ - SET_LL_32(&lli[i].dar.lsb, lower_32_bits(child->dar)); - SET_LL_32(&lli[i].dar.msb, upper_32_bits(child->dar)); - #endif /* CONFIG_64BIT */ + SET_LL_64(&lli[i].dar.reg, child->dar); + i++; } @@ -349,12 +341,7 @@ static void dw_edma_v0_core_write_chunk(struct dw_edma_chunk *chunk) /* Channel control */ SET_LL_32(&llp->control, control); /* Linked list */ - #ifdef CONFIG_64BIT - SET_LL_64(&llp->llp.reg, chunk->ll_region.paddr); - #else /* CONFIG_64BIT */ - SET_LL_32(&llp->llp.lsb, lower_32_bits(chunk->ll_region.paddr)); - SET_LL_32(&llp->llp.msb, upper_32_bits(chunk->ll_region.paddr)); - #endif /* CONFIG_64BIT */ + SET_LL_64(&llp->llp.reg, chunk->ll_region.paddr); } void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first) @@ -417,18 +404,8 @@ void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first) SET_CH_32(dw, chan->dir, chan->id, ch_control1, (DW_EDMA_V0_CCS | DW_EDMA_V0_LLE)); /* Linked list */ - if ((chan->dw->chip->flags & DW_EDMA_CHIP_32BIT_DBI) || - !IS_ENABLED(CONFIG_64BIT)) { - SET_CH_32(dw, chan->dir, chan->id, llp.lsb, - lower_32_bits(chunk->ll_region.paddr)); - SET_CH_32(dw, chan->dir, chan->id, llp.msb, - upper_32_bits(chunk->ll_region.paddr)); - } else { - #ifdef CONFIG_64BIT - SET_CH_64(dw, chan->dir, chan->id, llp.reg, - chunk->ll_region.paddr); - #endif - } + SET_CH_64(dw, chan->dir, chan->id, llp.reg, + chunk->ll_region.paddr); } /* Doorbell */ SET_RW_32(dw, chan->dir, doorbell, From patchwork Thu Mar 24 01:48:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793907 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1BC17C4332F for ; Mon, 28 Mar 2022 16:44:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243017AbiC1QqQ (ORCPT ); Mon, 28 Mar 2022 12:46:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45152 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242855AbiC1QqD (ORCPT ); Mon, 28 Mar 2022 12:46:03 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8F44921E2D; 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 583BA1E495A; Thu, 24 Mar 2022 04:48:53 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 583BA1E495A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086533; bh=iq392ifBKJNeXd07OpQlSazUKapg75sZrK0PlOvjOHo=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=QmjmIg4dvnszJpqrvsQpKe9XCdhnitbukZUqOSIt212Mwr/eZ5j7q3ZQL+7Dhu7nW v1s3M6sGrv+7HO47I0Lv8Nx/zpk+XlFBZ5s2wZwbJe9czZuy27jLhxVhz8Icz+YkIl VcRvVrp2mJmyZob0iP3ncz8G2sSj7HhKmLivI7pc= 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:53 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 21/25] dmaengine: dw-edma: Drop DT-region allocation Date: Thu, 24 Mar 2022 04:48:32 +0300 Message-ID: <20220324014836.19149-22-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org There is no point in allocating an additional memory for the data target regions passed then to the client drivers. Just use the already available structures defined in the dw_edma_chip instance. Note these regions are unused in normal circumstances since they are specific to the case of eDMA being embedded into the DW PCIe End-point and having it's CSRs accessible over a End-point' BAR. This case is only known to be implemented as a part of the Synopsys PCIe EndPoint IP prototype kit. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index bc530f0a2468..dbe1119fd1d2 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -744,7 +744,6 @@ static void dw_edma_free_chan_resources(struct dma_chan *dchan) static int dw_edma_channel_setup(struct dw_edma_chip *chip, u32 wr_alloc, u32 rd_alloc) { - struct dw_edma_region *dt_region; struct device *dev = chip->dev; struct dw_edma *dw = chip->dw; struct dw_edma_chan *chan; @@ -761,12 +760,6 @@ static int dw_edma_channel_setup(struct dw_edma_chip *chip, u32 wr_alloc, for (i = 0; i < ch_cnt; i++) { chan = &dw->chan[i]; - dt_region = devm_kzalloc(dev, sizeof(*dt_region), GFP_KERNEL); - if (!dt_region) - return -ENOMEM; - - chan->vc.chan.private = dt_region; - chan->dw = dw; if (i < dw->wr_ch_cnt) { @@ -814,17 +807,11 @@ static int dw_edma_channel_setup(struct dw_edma_chip *chip, u32 wr_alloc, chan->msi.data); chan->vc.desc_free = vchan_free_desc; - vchan_init(&chan->vc, dma); + chan->vc.chan.private = chan->dir == EDMA_DIR_WRITE ? + &dw->chip->dt_region_wr[chan->id] : + &dw->chip->dt_region_rd[chan->id]; - if (chan->dir == EDMA_DIR_WRITE) { - dt_region->paddr = chip->dt_region_wr[chan->id].paddr; - dt_region->vaddr = chip->dt_region_wr[chan->id].vaddr; - dt_region->sz = chip->dt_region_wr[chan->id].sz; - } else { - dt_region->paddr = chip->dt_region_rd[chan->id].paddr; - dt_region->vaddr = chip->dt_region_rd[chan->id].vaddr; - dt_region->sz = chip->dt_region_rd[chan->id].sz; - } + vchan_init(&chan->vc, dma); dw_edma_v0_core_device_config(chan); } From patchwork Thu Mar 24 01:48:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793916 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8AB5C433FE for ; Mon, 28 Mar 2022 16:46:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240853AbiC1Qsb (ORCPT ); Mon, 28 Mar 2022 12:48:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242731AbiC1QqC (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 28FD12182E; Mon, 28 Mar 2022 09:44:15 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 6CFA51E495B; Thu, 24 Mar 2022 04:48:54 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 6CFA51E495B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086534; bh=6NSTRCoVzt81JyA6QUO5cIP2eDNgzFkfTxM4XjlryDw=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=NvFah7HZvSrT0KQVpWhAoFO1ZvuZwLY+HDDwBvpE2d9oaQwJoczT9p6xitDMIv0/Z KkA27dWuRMtEZwU8tpLrkuTUE+/YQghjb/wtoTAIwY6IkKNaGWs+XUi8EnQA9wJ8on IaKhwxNMBQR676ALcQ/zh0dZbvOZWiabqQHUkBV4= 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:54 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 22/25] dmaengine: dw-edma: Replace chip ID number with device name Date: Thu, 24 Mar 2022 04:48:33 +0300 Message-ID: <20220324014836.19149-23-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org Using some abstract number as the DW eDMA chip identifier isn't really practical. First of all there can be more than one DW eDMA controller on the platform some of them can be detected as the PCIe end-points, some of them can be embedded into the DW PCIe Root Port/End-point controllers. Seeing some abstract number in for instance IRQ handlers list doesn't give a notion regarding their reference to the particular DMA controller. Secondly current DW eDMA chip id implementation doesn't provide the multi-eDMA platforms support for same reason of possibly having eDMA detected on different system buses. At the same time re-implementing something ida-based won't give much benefits especially seeing the DW eDMA chip ID is only used in the IRQ request procedure. So to speak in order to preserve the code simplicity and get to have the multi-eDMA platforms support let's just use the parental device name to create the DW eDMA controller name. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 3 ++- drivers/dma/dw-edma/dw-edma-core.h | 2 +- drivers/dma/dw-edma/dw-edma-pcie.c | 1 - include/linux/dma/edma.h | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index dbe1119fd1d2..72a51970bfba 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -970,7 +970,8 @@ int dw_edma_probe(struct dw_edma_chip *chip) if (!dw->chan) return -ENOMEM; - snprintf(dw->name, sizeof(dw->name), "dw-edma-core:%d", chip->id); + snprintf(dw->name, sizeof(dw->name), "dw-edma-core:%s", + dev_name(chip->dev)); /* Disable eDMA, only to establish the ideal initial conditions */ dw_edma_v0_core_off(dw); diff --git a/drivers/dma/dw-edma/dw-edma-core.h b/drivers/dma/dw-edma/dw-edma-core.h index 980adb079182..dc25798d4ba9 100644 --- a/drivers/dma/dw-edma/dw-edma-core.h +++ b/drivers/dma/dw-edma/dw-edma-core.h @@ -96,7 +96,7 @@ struct dw_edma_irq { }; struct dw_edma { - char name[20]; + char name[30]; struct dma_device dma; diff --git a/drivers/dma/dw-edma/dw-edma-pcie.c b/drivers/dma/dw-edma/dw-edma-pcie.c index f530bacfd716..3f9dadc73854 100644 --- a/drivers/dma/dw-edma/dw-edma-pcie.c +++ b/drivers/dma/dw-edma/dw-edma-pcie.c @@ -222,7 +222,6 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, /* Data structure initialization */ chip->dev = dev; - chip->id = pdev->devfn; chip->mf = vsec_data.mf; chip->nr_irqs = nr_irqs; diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h index 5cc87cfdd685..241c5a97ddf4 100644 --- a/include/linux/dma/edma.h +++ b/include/linux/dma/edma.h @@ -73,7 +73,6 @@ enum dw_edma_map_format { */ struct dw_edma_chip { struct device *dev; - int id; int nr_irqs; const struct dw_edma_core_ops *ops; u32 flags; From patchwork Thu Mar 24 01:48:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793894 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A10FC433EF for ; Mon, 28 Mar 2022 16:44:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242808AbiC1QqF (ORCPT ); Mon, 28 Mar 2022 12:46:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44352 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242660AbiC1Qpz (ORCPT ); Mon, 28 Mar 2022 12:45:55 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id D1F4421246; Mon, 28 Mar 2022 09:44:07 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 348211E495D; Thu, 24 Mar 2022 04:48:55 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 348211E495D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086535; bh=9SPPRQfYXqos/xXWWQfUIiy2dltWIdc2l/4SV3Of+L8=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=U+76/BpfTNVjj2/LrtAZkiu6zTfxaNNdNJs1UFeTaUJPp9ltn5HI/uoY4fx2HJ8Hw cPbj+O+3w1WocZap4Q6GIfF5OCCb0sPoE+8/H9kPvuCO6gR3VCwkSKZ16DhDj51gWF JqYmjaH9/k0Ty6agwY3hQNMaxxpkLnkVF/E1rEKU= 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:54 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 23/25] dmaengine: dw-edma: Bypass dma-ranges mapping for the local setup Date: Thu, 24 Mar 2022 04:48:34 +0300 Message-ID: <20220324014836.19149-24-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org DW eDMA doesn't perform any translation of the traffic generated on the CPU/Application side. It just generates read/write AXI-bus requests with the specified addresses. But in case if the dma-ranges DT-property is specified for a platform device node, Linux will use it to map the CPU memory regions into the DMAable bus ranges. This isn't what we want for the eDMA embedded into the locally accessed DW PCIe Root Port and End-point. In order to work that around let's set the chan_dma_dev flag for each DW eDMA channel thus forcing the client drivers to getting a custom dma-ranges-less parental device for the mappings. Note it will only work for the client drivers using the dmaengine_get_dma_device() method to get the parental DMA device. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index 72a51970bfba..ca5cd7c99571 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -716,6 +716,21 @@ static int dw_edma_alloc_chan_resources(struct dma_chan *dchan) if (chan->status != EDMA_ST_IDLE) return -EBUSY; + /* Bypass the dma-ranges based memory regions mapping since the + * inbound iATU only affects the traffic incoming from the + * PCIe bus. + */ + if (chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) { + dchan->dev->chan_dma_dev = true; + + dchan->dev->device.dma_coherent = chan->dw->chip->dev->dma_coherent; + dma_coerce_mask_and_coherent(&dchan->dev->device, + dma_get_mask(chan->dw->chip->dev)); + dchan->dev->device.dma_parms = chan->dw->chip->dev->dma_parms; + } else { + dchan->dev->chan_dma_dev = false; + } + pm_runtime_get(chan->dw->chip->dev); return 0; From patchwork Thu Mar 24 01:48:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793904 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A330C433EF for ; Mon, 28 Mar 2022 16:44:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243239AbiC1QqM (ORCPT ); Mon, 28 Mar 2022 12:46:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242857AbiC1QqD (ORCPT ); Mon, 28 Mar 2022 12:46:03 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8F60821E2E; 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 CD1311E495F; Thu, 24 Mar 2022 04:48:55 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru CD1311E495F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086535; bh=5JPForGhV2V31tLsfIwP1/NlSFrmm3Bd9JfGRQxegGU=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=jkcksY3ycZa8ZXlHgE2JDvJWMAJ3jRRZow1FiPP8NRoNPTnxFUoKsL7OE0pSwjQdd /FajhnkDKloH97IMUBEiOG02Guc0Ybyg3wilurvNe0WEwAQ3Uq5kzVniu59IHUWsV3 TjYmxgPRKP/UTurAk9ZEHdZyNMsKftKhE7t/IzLU= 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:55 +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_Wilczy=C5=84ski?= , , , Subject: [PATCH 24/25] dmaengine: dw-edma: Skip cleanup procedure if no private data found Date: Thu, 24 Mar 2022 04:48:35 +0300 Message-ID: <20220324014836.19149-25-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org DW eDMA driver private data is preserved in the passed DW eDMA chip info structure. If either probe procedure failed or for some reason the passed info object doesn't have private data pointer initialized we need to halt the DMA device cleanup procedure in order to prevent possible system crashes. Signed-off-by: Serge Semin --- drivers/dma/dw-edma/dw-edma-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index ca5cd7c99571..b932682a8ba8 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -1030,6 +1030,10 @@ int dw_edma_remove(struct dw_edma_chip *chip) struct dw_edma *dw = chip->dw; int i; + /* Skip removal if no private data found */ + if (!dw) + return -ENODEV; + /* Disable eDMA */ dw_edma_v0_core_off(dw); From patchwork Thu Mar 24 01:48:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12793915 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E3DCC35274 for ; Mon, 28 Mar 2022 16:46:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239185AbiC1Qsb (ORCPT ); Mon, 28 Mar 2022 12:48:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242791AbiC1QqC (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 AF64921E07; Mon, 28 Mar 2022 09:44:15 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 012521E28C1; Thu, 24 Mar 2022 04:48:57 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 012521E28C1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648086537; bh=qzYBz7H8E6U/5witePOjzf4Q2pfPLZU2uG2a8K4iWSs=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=ZBkBX475GRJ2za0btGRtYVt8c0ZMzTici3wSHFXbNXWPP9ez7rpzwMSq2/KBhrpZi qcqtQ+9rk6+KSIsafsACRajSM0MEivk2hfYH2pNUWqAQDkdL0iHLI/1ZzlnSc7XkTi qsifmGe4Joc0JYkiQdeFf2AsoPImjYJ+zw6lbfzs= 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:56 +0300 From: Serge Semin To: Gustavo Pimentel , Vinod Koul , Jingoo Han , Bjorn Helgaas , Frank Li , Manivannan Sadhasivam , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= CC: Serge Semin , Serge Semin , Alexey Malahov , Pavel Parkhomenko , , , Subject: [PATCH 25/25] PCI: dwc: Add DW eDMA engine support Date: Thu, 24 Mar 2022 04:48:36 +0300 Message-ID: <20220324014836.19149-26-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 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org Since the DW eDMA driver now supports eDMA controllers embedded into the locally accessible DW PCIe Root Ports and End-points, we can use the updated interface to register DW eDMA as DMA engine device if it's available. In order to successfully do that the DW PCIe core driver need to perform some preparations first. First of all it needs to find out the eDMA controller CSRs base address, whether they are accessible over the Port Logic or iATU unrolled space. Afterwards it can try to auto-detect the eDMA controller availability and number of it's read/write channels. If none was found the procedure will just silently halt with no error returned. Secondly the platform is supposed to provide either combined or per-channel IRQ signals. If no valid IRQs set is found the procedure will also halt with no error returned so to be backward compatible with platforms where DW PCIe controllers have eDMA embedded but lack of the IRQs defined for them. Finally before actually probing the eDMA device we need to allocate LLP items buffers. After that the DW eDMA can be registered. If registration is successful the info-message regarding the number of detected Read/Write eDMA channels will be printed to the system log in the same way as it's done for iATU settings. Signed-off-by: Serge Semin --- .../pci/controller/dwc/pcie-designware-ep.c | 4 + .../pci/controller/dwc/pcie-designware-host.c | 13 +- drivers/pci/controller/dwc/pcie-designware.c | 188 ++++++++++++++++++ drivers/pci/controller/dwc/pcie-designware.h | 23 ++- 4 files changed, 225 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 23401f17e8f0..b2840d1a5b9a 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -712,6 +712,10 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) dw_pcie_iatu_detect(pci); + ret = dw_pcie_edma_detect(pci); + if (ret) + return ret; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); if (!res) return -EINVAL; diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 715a13b90e43..048b452ee4f3 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -405,14 +405,18 @@ int dw_pcie_host_init(struct pcie_port *pp) dw_pcie_iatu_detect(pci); - ret = dw_pcie_setup_rc(pp); + ret = dw_pcie_edma_detect(pci); if (ret) goto err_free_msi; + ret = dw_pcie_setup_rc(pp); + if (ret) + goto err_edma_remove; + if (!dw_pcie_link_up(pci) && pci->ops && pci->ops->start_link) { ret = pci->ops->start_link(pci); if (ret) - goto err_free_msi; + goto err_edma_remove; } /* Ignore errors, the link may come up later */ @@ -430,6 +434,9 @@ int dw_pcie_host_init(struct pcie_port *pp) if (pci->ops && pci->ops->stop_link) pci->ops->stop_link(pci); +err_edma_remove: + dw_pcie_edma_remove(pci); + err_free_msi: if (pp->has_msi_ctrl) dw_pcie_free_msi(pp); @@ -452,6 +459,8 @@ void dw_pcie_host_deinit(struct pcie_port *pp) if (pci->ops && pci->ops->stop_link) pci->ops->stop_link(pci); + dw_pcie_edma_remove(pci); + if (pp->has_msi_ctrl) dw_pcie_free_msi(pp); diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 4a95a7b112e9..dbe39a7ecb71 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -680,6 +681,193 @@ void dw_pcie_iatu_detect(struct dw_pcie *pci) pci->region_align / SZ_1K, (pci->region_limit + 1) / SZ_1G); } +static u32 dw_pcie_readl_dma(struct dw_pcie *pci, u32 reg) +{ + u32 val = 0; + int ret; + + if (pci->ops && pci->ops->read_dbi) + return pci->ops->read_dbi(pci, pci->edma.reg_base, reg, 4); + + ret = dw_pcie_read(pci->edma.reg_base + reg, 4, &val); + if (ret) + dev_err(pci->dev, "Read DMA address failed\n"); + + return val; +} + +static bool dw_pcie_edma_unroll_enabled(struct dw_pcie *pci) +{ + u32 val; + + val = dw_pcie_readl_dbi(pci, PCIE_DMA_VIEWPORT_BASE + PCIE_DMA_CTRL); + if (val == 0xffffffff) + return true; + + return false; +} + +static int dw_pcie_edma_irq_vector(struct device *dev, unsigned int nr) +{ + struct platform_device *pdev = to_platform_device(dev); + char name[6]; + int ret; + + if (nr >= EDMA_MAX_WR_CH + EDMA_MAX_RD_CH) + return -EINVAL; + + ret = platform_get_irq_byname_optional(pdev, "dma"); + if (ret > 0) + return ret; + + snprintf(name, sizeof(name), "dma%u", nr); + + return platform_get_irq_byname_optional(pdev, name); +} + +static struct dw_edma_core_ops dw_pcie_edma_ops = { + .irq_vector = dw_pcie_edma_irq_vector, +}; + +static int dw_pcie_edma_detect_channels(struct dw_pcie *pci) +{ + u32 val; + + val = dw_pcie_readl_dma(pci, PCIE_DMA_CTRL); + if (!val || val == 0xffffffff) + return 0; + + pci->edma.ll_wr_cnt = FIELD_GET(PCIE_DMA_NUM_WR_CHAN, val); + pci->edma.ll_rd_cnt = FIELD_GET(PCIE_DMA_NUM_RD_CHAN, val); + + if (pci->edma.ll_wr_cnt > EDMA_MAX_WR_CH || + pci->edma.ll_rd_cnt > EDMA_MAX_RD_CH) + return -EINVAL; + + return 0; +} + +static int dw_pcie_edma_irq_verify(struct dw_pcie *pci) +{ + struct platform_device *pdev = to_platform_device(pci->dev); + u16 ch_cnt = pci->edma.ll_wr_cnt + pci->edma.ll_rd_cnt; + char name[6]; + int ret; + + if (pci->edma.nr_irqs == 1) + return 0; + else if (pci->edma.nr_irqs > 1) + return pci->edma.nr_irqs != ch_cnt ? -EINVAL : 0; + + ret = platform_get_irq_byname_optional(pdev, "dma"); + if (ret > 0) { + pci->edma.nr_irqs = 1; + return 0; + } + + for (; pci->edma.nr_irqs < ch_cnt; pci->edma.nr_irqs++) { + snprintf(name, sizeof(name), "dma%d", pci->edma.nr_irqs); + + ret = platform_get_irq_byname_optional(pdev, name); + if (ret <= 0) + return -EINVAL; + } + + return 0; +} + +static int dw_pcie_edma_ll_alloc(struct dw_pcie *pci) +{ + struct dw_edma_region *ll; + dma_addr_t paddr; + int i; + + for (i = 0; i < pci->edma.ll_wr_cnt; i++) { + ll = &pci->edma.ll_region_wr[i]; + ll->sz = DMA_LLP_MEM_SIZE; + ll->vaddr = dmam_alloc_coherent(pci->dev, ll->sz, + &paddr, GFP_KERNEL); + if (!ll->vaddr) + return -ENOMEM; + + ll->paddr = paddr; + } + + for (i = 0; i < pci->edma.ll_rd_cnt; i++) { + ll = &pci->edma.ll_region_rd[i]; + ll->sz = DMA_LLP_MEM_SIZE; + ll->vaddr = dmam_alloc_coherent(pci->dev, ll->sz, + &paddr, GFP_KERNEL); + if (!ll->vaddr) + return -ENOMEM; + + ll->paddr = paddr; + } + + return 0; +} + +int dw_pcie_edma_detect(struct dw_pcie *pci) +{ + int ret; + + pci->edma.dev = pci->dev; + if (!pci->edma.ops) + pci->edma.ops = &dw_pcie_edma_ops; + pci->edma.flags |= DW_EDMA_CHIP_LOCAL; + + pci->edma_unroll_enabled = dw_pcie_edma_unroll_enabled(pci); + if (pci->edma_unroll_enabled && pci->iatu_unroll_enabled) { + pci->edma.mf = EDMA_MF_EDMA_UNROLL; + if (pci->atu_base != pci->dbi_base + DEFAULT_DBI_ATU_OFFSET) + pci->edma.reg_base = pci->atu_base + PCIE_DMA_UNROLL_BASE; + else + pci->edma.reg_base = pci->dbi_base + DEFAULT_DBI_DMA_OFFSET; + } else { + pci->edma.mf = EDMA_MF_EDMA_LEGACY; + pci->edma.reg_base = pci->dbi_base + PCIE_DMA_VIEWPORT_BASE; + } + + ret = dw_pcie_edma_detect_channels(pci); + if (ret) { + dev_err(pci->dev, "Unexpected NoF eDMA channels found\n"); + return ret; + } + + /* Skip any further initialization if no eDMA found */ + if (!pci->edma.ll_wr_cnt && !pci->edma.ll_rd_cnt) + return 0; + + /* Don't return failure here for the backward compatibility */ + ret = dw_pcie_edma_irq_verify(pci); + if (ret) { + dev_err(pci->dev, "No valid eDMA IRQs set found\n"); + return 0; + } + + ret = dw_pcie_edma_ll_alloc(pci); + if (ret) { + dev_err(pci->dev, "Couldn't allocate LLP memory\n"); + return ret; + } + + ret = dw_edma_probe(&pci->edma); + if (ret) { + dev_err(pci->dev, "Couldn't register eDMA device\n"); + return ret; + } + + dev_info(pci->dev, "eDMA channels: %hu wr, %hu rd\n", + pci->edma.ll_wr_cnt, pci->edma.ll_rd_cnt); + + return 0; +} + +void dw_pcie_edma_remove(struct dw_pcie *pci) +{ + dw_edma_remove(&pci->edma); +} + void dw_pcie_setup(struct dw_pcie *pci) { u32 val; diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 11c52d2eaf79..9b92f79664f2 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -144,6 +145,18 @@ #define PCIE_MSIX_DOORBELL 0x948 #define PCIE_MSIX_DOORBELL_PF_SHIFT 24 +/* + * eDMA CSRs. DW PCIe IP-core v4.70a and older had the eDMA registers accessible + * over the Port Logic registers space. Afterwords the unrolled mapping was + * introduced so eDMA and iATU could be accessed via a dedicated registers + * space. + */ +#define PCIE_DMA_VIEWPORT_BASE 0x970 +#define PCIE_DMA_UNROLL_BASE 0x80000 +#define PCIE_DMA_CTRL 0x008 +#define PCIE_DMA_NUM_WR_CHAN GENMASK(3, 0) +#define PCIE_DMA_NUM_RD_CHAN GENMASK(19, 16) + #define PCIE_PL_CHK_REG_CONTROL_STATUS 0xB20 #define PCIE_PL_CHK_REG_CHK_REG_START BIT(0) #define PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS BIT(1) @@ -160,6 +173,7 @@ * this offset, if atu_base not set. */ #define DEFAULT_DBI_ATU_OFFSET (0x3 << 20) +#define DEFAULT_DBI_DMA_OFFSET (0x7 << 19) #define MAX_MSI_IRQS 256 #define MAX_MSI_IRQS_PER_CTRL 32 @@ -171,6 +185,9 @@ #define MAX_IATU_IN 256 #define MAX_IATU_OUT 256 +/* Default eDMA LLP memory size */ +#define DMA_LLP_MEM_SIZE PAGE_SIZE + struct pcie_port; struct dw_pcie; struct dw_pcie_ep; @@ -295,7 +312,7 @@ struct dw_pcie { struct device *dev; void __iomem *dbi_base; void __iomem *dbi_base2; - /* Used when iatu_unroll_enabled is true */ + /* Used when {iatu,edma}_unroll_enabled is true */ void __iomem *atu_base; size_t atu_size; u32 num_ib_windows; @@ -310,7 +327,9 @@ struct dw_pcie { int num_lanes; int link_gen; u8 n_fts[2]; + struct dw_edma_chip edma; bool iatu_unroll_enabled: 1; + bool edma_unroll_enabled: 1; bool io_cfg_atu_shared: 1; }; @@ -344,6 +363,8 @@ int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index, void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index); void dw_pcie_setup(struct dw_pcie *pci); void dw_pcie_iatu_detect(struct dw_pcie *pci); +int dw_pcie_edma_detect(struct dw_pcie *pci); +void dw_pcie_edma_remove(struct dw_pcie *pci); static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) {