From patchwork Fri May 29 03:59:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 199773 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA189C433E0 for ; Fri, 29 May 2020 04:01:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B238B20707 for ; Fri, 29 May 2020 04:01:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388571AbgE2D7g (ORCPT ); Thu, 28 May 2020 23:59:36 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45330 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388513AbgE2D7f (ORCPT ); Thu, 28 May 2020 23:59:35 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 5E3B78030807; Fri, 29 May 2020 03:59:32 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id IZwmH6hUhcpO; Fri, 29 May 2020 06:59:31 +0300 (MSK) From: Serge Semin To: Mark Brown CC: Serge Semin , Serge Semin , Georgy Vlasov , Ramil Zaripov , Alexey Malahov , Thomas Bogendoerfer , Arnd Bergmann , Andy Shevchenko , Feng Tang , Rob Herring , , , , Subject: [PATCH v5 02/16] spi: dw: Return any value retrieved from the dma_transfer callback Date: Fri, 29 May 2020 06:59:00 +0300 Message-ID: <20200529035915.20790-3-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> References: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org DW APB SSI DMA may need to perform the synchronous operations. In that case the dma_transfer() callback will return 0 as a marker of the SPI transfer being finished so the SPI core can proceed with the SPI message trasnfers pumping procedure. This will be needed to fix the problem when DMA transactions are finished, but there is still data left in the SPI Tx/Rx buffers. But for now make dma_transfer to return 1 as the normal dw_spi_transfer_one() method. Signed-off-by: Serge Semin Cc: Georgy Vlasov Cc: Ramil Zaripov Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Andy Shevchenko Cc: Feng Tang Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org --- drivers/spi/spi-dw-mid.c | 2 +- drivers/spi/spi-dw.c | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index b1710132b7b2..7ff1acaa55f8 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -288,7 +288,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) dma_async_issue_pending(dws->txchan); } - return 0; + return 1; } static void mid_spi_dma_stop(struct dw_spi *dws) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 050cb2ea0812..6939e003e3e9 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -389,11 +389,8 @@ static int dw_spi_transfer_one(struct spi_controller *master, spi_enable_chip(dws, 1); - if (dws->dma_mapped) { - ret = dws->dma_ops->dma_transfer(dws, transfer); - if (ret < 0) - return ret; - } + if (dws->dma_mapped) + return dws->dma_ops->dma_transfer(dws, transfer); return 1; } From patchwork Fri May 29 03:59:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 199774 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E46DC433E3 for ; Fri, 29 May 2020 04:01:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 66EE720707 for ; Fri, 29 May 2020 04:01:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389352AbgE2D7i (ORCPT ); Thu, 28 May 2020 23:59:38 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45374 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388525AbgE2D7h (ORCPT ); Thu, 28 May 2020 23:59:37 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 4FB7C8030777; Fri, 29 May 2020 03:59:34 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fyflqadrPR6g; Fri, 29 May 2020 06:59:33 +0300 (MSK) From: Serge Semin To: Mark Brown , Vinod Koul , Feng Tang , Linus Walleij , Alan Cox , Grant Likely CC: Serge Semin , Serge Semin , Georgy Vlasov , Ramil Zaripov , Alexey Malahov , Thomas Bogendoerfer , Arnd Bergmann , Andy Shevchenko , Rob Herring , , , , Subject: [PATCH v5 04/16] spi: dw: Add SPI Tx-done wait method to DMA-based transfer Date: Fri, 29 May 2020 06:59:02 +0300 Message-ID: <20200529035915.20790-5-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> References: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Since DMA transfers are performed asynchronously with actual SPI bus transfers, then even if DMA transactions are finished it doesn't mean all data is actually pushed to the SPI bus. Some data might still be in the controller FIFO. This is specifically true for Tx-only transfers. In this case if the next SPI transfer is recharged while a tail of the previous one is still in FIFO, we'll loose that tail data. In order to fix that problem let's add the wait procedure of the Tx SPI transfer completion after the DMA transactions are finished. Fixes: 7063c0d942a1 ("spi/dw_spi: add DMA support") Co-developed-by: Georgy Vlasov Signed-off-by: Georgy Vlasov Signed-off-by: Serge Semin Cc: Ramil Zaripov Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Andy Shevchenko Cc: Feng Tang Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org --- Changelog v2: - Use conditional statement instead of the ternary operator in the ref clock getter. - Move the patch to the head of the series so one could be picked up to the stable kernels as a fix. Changelog v3: - Use spi_delay_exec() method to wait for the current operation completion. Changelog v4: - Get back ndelay() method to wait for an SPI transfer completion. spi_delay_exec() isn't suitable for the atomic context. Changelog v5: - Add more detailed description of the problems the patch fixes. - Wait for the SPI Tx transfer finish in the mid_spi_dma_transfer() method executed in the task context. - Use spi_delay_exec() to wait for the SPI Tx completion, since now the driver does in the kernel thread context. - Use SPI_DELAY_UNIT_SCK spi_delay unit, since SPI xfer's are now have the effective_speed_hz initialized. --- drivers/spi/spi-dw-mid.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 355b641c4483..846e3db91329 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -19,6 +19,7 @@ #include #include +#define WAIT_RETRIES 5 #define RX_BUSY 0 #define TX_BUSY 1 @@ -171,6 +172,33 @@ static int dw_spi_dma_wait(struct dw_spi *dws, struct spi_transfer *xfer) return 0; } +static inline bool dw_spi_dma_tx_busy(struct dw_spi *dws) +{ + return !(dw_readl(dws, DW_SPI_SR) & SR_TF_EMPT); +} + +static int dw_spi_dma_wait_tx_done(struct dw_spi *dws, + struct spi_transfer *xfer) +{ + int retry = WAIT_RETRIES; + struct spi_delay delay; + u32 nents; + + nents = dw_readl(dws, DW_SPI_TXFLR); + delay.unit = SPI_DELAY_UNIT_SCK; + delay.value = nents * dws->n_bytes * BITS_PER_BYTE; + + while (dw_spi_dma_tx_busy(dws) && retry--) + spi_delay_exec(&delay, xfer); + + if (retry < 0) { + dev_err(&dws->master->dev, "Tx hanged up\n"); + return -EIO; + } + + return 0; +} + /* * dws->dma_chan_busy is set before the dma transfer starts, callback for tx * channel will clear a corresponding bit. @@ -324,6 +352,12 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) if (ret) return ret; + if (txdesc && dws->master->cur_msg->status == -EINPROGRESS) { + ret = dw_spi_dma_wait_tx_done(dws, xfer); + if (ret) + return ret; + } + return 0; } From patchwork Fri May 29 03:59:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 199775 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDB06C433E7 for ; Fri, 29 May 2020 04:01:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B663220707 for ; Fri, 29 May 2020 04:01:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391701AbgE2EBA (ORCPT ); Fri, 29 May 2020 00:01:00 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45410 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388570AbgE2D7i (ORCPT ); Thu, 28 May 2020 23:59:38 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id A4EC38030772; Fri, 29 May 2020 03:59:34 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QASSozuuX7L8; Fri, 29 May 2020 06:59:34 +0300 (MSK) From: Serge Semin To: Mark Brown , Grant Likely , Linus Walleij , Feng Tang , Alan Cox , Vinod Koul CC: Serge Semin , Serge Semin , Georgy Vlasov , Ramil Zaripov , Alexey Malahov , Thomas Bogendoerfer , Arnd Bergmann , Andy Shevchenko , Rob Herring , , , , Subject: [PATCH v5 05/16] spi: dw: Add SPI Rx-done wait method to DMA-based transfer Date: Fri, 29 May 2020 06:59:03 +0300 Message-ID: <20200529035915.20790-6-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> References: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Having any data left in the Rx FIFO after the DMA engine claimed it has finished all DMA transactions is an abnormal situation, since the DW SPI controller driver expects to have all the data being fetched and placed into the SPI Rx buffer at that moment. In case if this has happened we assume that DMA engine still may be doing the data fetching, thus we give it sometime to finish. If after a short period of time the data is still left in the Rx FIFO, the driver will give up waiting and return an error indicating that the SPI controller/DMA engine must have hung up or failed at some point of doing their duties. Fixes: 7063c0d942a1 ("spi/dw_spi: add DMA support") Co-developed-by: Georgy Vlasov Signed-off-by: Georgy Vlasov Signed-off-by: Serge Semin Cc: Ramil Zaripov Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Andy Shevchenko Cc: Feng Tang Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org --- Changelog v5: - Create a dedicated patch which adds the Rx-done wait method. - Add more detailed description of the problem the patch fixes. - Wait for the SPI Rx transfer finish in the mid_spi_dma_transfer() method executed in the task context. - Use spi_delay_exec() to wait for the SPI Rx completion, since now the driver does in the kernel thread context. - Wait for a delay correlated with the APB/SSI synchronous clock rate instead of using the SPI bus clock rate. --- drivers/spi/spi-dw-mid.c | 48 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 846e3db91329..4345881ebf66 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -248,6 +248,49 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws, return txdesc; } +static inline bool dw_spi_dma_rx_busy(struct dw_spi *dws) +{ + return !!(dw_readl(dws, DW_SPI_SR) & SR_RF_NOT_EMPT); +} + +static int dw_spi_dma_wait_rx_done(struct dw_spi *dws) +{ + int retry = WAIT_RETRIES; + struct spi_delay delay; + unsigned long ns, us; + u32 nents; + + /* + * It's unlikely that DMA engine is still doing the data fetching, but + * if it's let's give it some reasonable time. The timeout calculation + * is based on the synchronous APB/SSI reference clock rate, on a + * number of data entries left in the Rx FIFO, times a number of clock + * periods normally needed for a single APB read/write transaction + * without PREADY signal utilized (which is true for the DW APB SSI + * controller). + */ + nents = dw_readl(dws, DW_SPI_RXFLR); + ns = NSEC_PER_SEC / dws->max_freq * 4 * nents; + if (ns <= NSEC_PER_USEC) { + delay.unit = SPI_DELAY_UNIT_NSECS; + delay.value = ns; + } else { + us = DIV_ROUND_UP(ns, NSEC_PER_USEC); + delay.unit = SPI_DELAY_UNIT_USECS; + delay.value = clamp_val(us, 0, USHRT_MAX); + } + + while (dw_spi_dma_rx_busy(dws) && retry--) + spi_delay_exec(&delay, NULL); + + if (retry < 0) { + dev_err(&dws->master->dev, "Rx hanged up\n"); + return -EIO; + } + + return 0; +} + /* * dws->dma_chan_busy is set before the dma transfer starts, callback for rx * channel will clear a corresponding bit. @@ -358,7 +401,10 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) return ret; } - return 0; + if (rxdesc && dws->master->cur_msg->status == -EINPROGRESS) + ret = dw_spi_dma_wait_rx_done(dws); + + return ret; } static void mid_spi_dma_stop(struct dw_spi *dws) From patchwork Fri May 29 03:59:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 199776 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5024EC433E4 for ; Fri, 29 May 2020 04:01:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3540320707 for ; Fri, 29 May 2020 04:01:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389391AbgE2D7j (ORCPT ); Thu, 28 May 2020 23:59:39 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45412 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388565AbgE2D7h (ORCPT ); Thu, 28 May 2020 23:59:37 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 36C9A8030839; Fri, 29 May 2020 03:59:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id USMqH9NTirNC; Fri, 29 May 2020 06:59:34 +0300 (MSK) From: Serge Semin To: Mark Brown CC: Serge Semin , Serge Semin , Georgy Vlasov , Ramil Zaripov , Andy Shevchenko , Alexey Malahov , Thomas Bogendoerfer , Arnd Bergmann , Feng Tang , Rob Herring , , , , Subject: [PATCH v5 06/16] spi: dw: Parameterize the DMA Rx/Tx burst length Date: Fri, 29 May 2020 06:59:04 +0300 Message-ID: <20200529035915.20790-7-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> References: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org It isn't good to have numeric literals in the code especially if there are multiple of them and they are related. Let's replace the Tx and Rx burst level literals with the corresponding constants. Co-developed-by: Georgy Vlasov Signed-off-by: Georgy Vlasov Co-developed-by: Ramil Zaripov Signed-off-by: Ramil Zaripov Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Feng Tang Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org --- Changelog v3: - Discard the dws->fifo_len utilization in the Tx FIFO DMA threshold setting. --- drivers/spi/spi-dw-mid.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 4345881ebf66..93463bdba0f8 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -21,7 +21,9 @@ #define WAIT_RETRIES 5 #define RX_BUSY 0 +#define RX_BURST_LEVEL 16 #define TX_BUSY 1 +#define TX_BURST_LEVEL 16 static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param) { @@ -227,7 +229,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws, memset(&txconf, 0, sizeof(txconf)); txconf.direction = DMA_MEM_TO_DEV; txconf.dst_addr = dws->dma_addr; - txconf.dst_maxburst = 16; + txconf.dst_maxburst = TX_BURST_LEVEL; txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; txconf.dst_addr_width = convert_dma_width(dws->n_bytes); txconf.device_fc = false; @@ -319,7 +321,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws, memset(&rxconf, 0, sizeof(rxconf)); rxconf.direction = DMA_DEV_TO_MEM; rxconf.src_addr = dws->dma_addr; - rxconf.src_maxburst = 16; + rxconf.src_maxburst = RX_BURST_LEVEL; rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; rxconf.src_addr_width = convert_dma_width(dws->n_bytes); rxconf.device_fc = false; @@ -344,8 +346,8 @@ static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer) { u16 imr = 0, dma_ctrl = 0; - dw_writel(dws, DW_SPI_DMARDLR, 0xf); - dw_writel(dws, DW_SPI_DMATDLR, 0x10); + dw_writel(dws, DW_SPI_DMARDLR, RX_BURST_LEVEL - 1); + dw_writel(dws, DW_SPI_DMATDLR, TX_BURST_LEVEL); if (xfer->tx_buf) { dma_ctrl |= SPI_DMA_TDMAE; From patchwork Fri May 29 03:59:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 199780 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D49C9C433E4 for ; Fri, 29 May 2020 03:59:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B36622074D for ; Fri, 29 May 2020 03:59:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390278AbgE2D7n (ORCPT ); Thu, 28 May 2020 23:59:43 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45418 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388744AbgE2D7k (ORCPT ); Thu, 28 May 2020 23:59:40 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id EC5DF8030779; Fri, 29 May 2020 03:59:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xT5FdjWP_obT; Fri, 29 May 2020 06:59:35 +0300 (MSK) From: Serge Semin To: Mark Brown CC: Serge Semin , Serge Semin , Andy Shevchenko , Alexey Malahov , Thomas Bogendoerfer , Arnd Bergmann , Feng Tang , Rob Herring , , , , Subject: [PATCH v5 07/16] spi: dw: Use DMA max burst to set the request thresholds Date: Fri, 29 May 2020 06:59:05 +0300 Message-ID: <20200529035915.20790-8-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> References: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Each channel of DMA controller may have a limited length of burst transaction (number of IO operations performed at ones in a single DMA client request). This parameter can be used to setup the most optimal DMA Tx/Rx data level values. In order to avoid the Tx buffer overrun we can set the DMA Tx level to be of FIFO depth minus the maximum burst transactions length. To prevent the Rx buffer underflow the DMA Rx level should be set to the maximum burst transactions length. This commit setups the DMA channels and the DW SPI DMA Tx/Rx levels in accordance with these rules. Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Feng Tang Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org --- Changelog v3: - Use min() method to calculate the optimal burst values. --- drivers/spi/spi-dw-mid.c | 37 +++++++++++++++++++++++++++++++++---- drivers/spi/spi-dw.h | 2 ++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 93463bdba0f8..ff79b4239d68 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -36,6 +36,31 @@ static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param) return true; } +static void mid_spi_maxburst_init(struct dw_spi *dws) +{ + struct dma_slave_caps caps; + u32 max_burst, def_burst; + int ret; + + def_burst = dws->fifo_len / 2; + + ret = dma_get_slave_caps(dws->rxchan, &caps); + if (!ret && caps.max_burst) + max_burst = caps.max_burst; + else + max_burst = RX_BURST_LEVEL; + + dws->rxburst = min(max_burst, def_burst); + + ret = dma_get_slave_caps(dws->txchan, &caps); + if (!ret && caps.max_burst) + max_burst = caps.max_burst; + else + max_burst = TX_BURST_LEVEL; + + dws->txburst = min(max_burst, def_burst); +} + static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws) { struct dw_dma_slave slave = { @@ -73,6 +98,8 @@ static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws) init_completion(&dws->dma_completion); + mid_spi_maxburst_init(dws); + return 0; free_rxchan: @@ -100,6 +127,8 @@ static int mid_spi_dma_init_generic(struct device *dev, struct dw_spi *dws) init_completion(&dws->dma_completion); + mid_spi_maxburst_init(dws); + return 0; } @@ -229,7 +258,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws, memset(&txconf, 0, sizeof(txconf)); txconf.direction = DMA_MEM_TO_DEV; txconf.dst_addr = dws->dma_addr; - txconf.dst_maxburst = TX_BURST_LEVEL; + txconf.dst_maxburst = dws->txburst; txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; txconf.dst_addr_width = convert_dma_width(dws->n_bytes); txconf.device_fc = false; @@ -321,7 +350,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws, memset(&rxconf, 0, sizeof(rxconf)); rxconf.direction = DMA_DEV_TO_MEM; rxconf.src_addr = dws->dma_addr; - rxconf.src_maxburst = RX_BURST_LEVEL; + rxconf.src_maxburst = dws->rxburst; rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; rxconf.src_addr_width = convert_dma_width(dws->n_bytes); rxconf.device_fc = false; @@ -346,8 +375,8 @@ static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer) { u16 imr = 0, dma_ctrl = 0; - dw_writel(dws, DW_SPI_DMARDLR, RX_BURST_LEVEL - 1); - dw_writel(dws, DW_SPI_DMATDLR, TX_BURST_LEVEL); + dw_writel(dws, DW_SPI_DMARDLR, dws->rxburst - 1); + dw_writel(dws, DW_SPI_DMATDLR, dws->fifo_len - dws->txburst); if (xfer->tx_buf) { dma_ctrl |= SPI_DMA_TDMAE; diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 9585d0c83a6d..9247670fcdfb 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -142,7 +142,9 @@ struct dw_spi { /* DMA info */ struct dma_chan *txchan; + u32 txburst; struct dma_chan *rxchan; + u32 rxburst; unsigned long dma_chan_busy; dma_addr_t dma_addr; /* phy address of the Data register */ const struct dw_spi_dma_ops *dma_ops; From patchwork Fri May 29 03:59:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 199777 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 34D72C433E2 for ; Fri, 29 May 2020 04:00:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 136D320707 for ; Fri, 29 May 2020 04:00:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389498AbgE2EAq (ORCPT ); Fri, 29 May 2020 00:00:46 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45492 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389465AbgE2D7m (ORCPT ); Thu, 28 May 2020 23:59:42 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id EB7DE8029EA0; Fri, 29 May 2020 03:59:39 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mxHYci5PNTca; Fri, 29 May 2020 06:59:39 +0300 (MSK) From: Serge Semin To: Mark Brown CC: Serge Semin , Serge Semin , Georgy Vlasov , Ramil Zaripov , Andy Shevchenko , Alexey Malahov , Thomas Bogendoerfer , Arnd Bergmann , Feng Tang , Rob Herring , , , , Subject: [PATCH v5 12/16] spi: dw: Add DW SPI DMA/PCI/MMIO dependency on the DW SPI core Date: Fri, 29 May 2020 06:59:10 +0300 Message-ID: <20200529035915.20790-13-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> References: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Seeing all of the DW SPI driver components like DW SPI DMA/PCI/MMIO depend on the DW SPI core code it's better to use the if-endif conditional kernel config statement to signify that common dependency. Co-developed-by: Georgy Vlasov Signed-off-by: Georgy Vlasov Co-developed-by: Ramil Zaripov Signed-off-by: Ramil Zaripov Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Feng Tang Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org --- drivers/spi/Kconfig | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 6a84f3dad35c..3cdf8310d185 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -226,17 +226,20 @@ config SPI_DESIGNWARE help general driver for SPI controller core from DesignWare +if SPI_DESIGNWARE + config SPI_DW_DMA bool "DMA support for DW SPI controller" - depends on SPI_DESIGNWARE config SPI_DW_PCI tristate "PCI interface driver for DW SPI core" - depends on SPI_DESIGNWARE && PCI + depends on PCI config SPI_DW_MMIO tristate "Memory-mapped io interface driver for DW SPI core" - depends on SPI_DESIGNWARE + depends on HAS_IOMEM + +endif config SPI_DLN2 tristate "Diolan DLN-2 USB SPI adapter" From patchwork Fri May 29 03:59:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 199778 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ACE0EC433E0 for ; Fri, 29 May 2020 04:00:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 87CC02074D for ; Fri, 29 May 2020 04:00:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726109AbgE2EAQ (ORCPT ); Fri, 29 May 2020 00:00:16 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45432 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389498AbgE2D7n (ORCPT ); Thu, 28 May 2020 23:59:43 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 3954F8029EA3; Fri, 29 May 2020 03:59:41 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ygwuWnJksRuj; Fri, 29 May 2020 06:59:40 +0300 (MSK) From: Serge Semin To: Mark Brown CC: Serge Semin , Serge Semin , Georgy Vlasov , Ramil Zaripov , Andy Shevchenko , Alexey Malahov , Thomas Bogendoerfer , Arnd Bergmann , Feng Tang , Rob Herring , , , , Subject: [PATCH v5 13/16] spi: dw: Cleanup generic DW DMA code namings Date: Fri, 29 May 2020 06:59:11 +0300 Message-ID: <20200529035915.20790-14-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> References: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Since from now the former Intel MID platform layer is used as a generic DW SPI DMA module, let's alter the internal methods naming to be DMA-related instead of having the "mid_" prefix. Co-developed-by: Georgy Vlasov Signed-off-by: Georgy Vlasov Co-developed-by: Ramil Zaripov Signed-off-by: Ramil Zaripov Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Feng Tang Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org --- Changelog v2: - Leave the DMA setup method suffixes to be mfld and generic. --- drivers/spi/spi-dw-dma.c | 85 ++++++++++++++++++++-------------------- drivers/spi/spi-dw-pci.c | 4 +- drivers/spi/spi-dw.h | 8 ++-- 3 files changed, 49 insertions(+), 48 deletions(-) diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c index 30bd9800f2df..69b7051e5323 100644 --- a/drivers/spi/spi-dw-dma.c +++ b/drivers/spi/spi-dw-dma.c @@ -23,7 +23,7 @@ #define TX_BUSY 1 #define TX_BURST_LEVEL 16 -static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param) +static bool dw_spi_dma_chan_filter(struct dma_chan *chan, void *param) { struct dw_dma_slave *s = param; @@ -34,7 +34,7 @@ static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param) return true; } -static void mid_spi_maxburst_init(struct dw_spi *dws) +static void dw_spi_dma_maxburst_init(struct dw_spi *dws) { struct dma_slave_caps caps; u32 max_burst, def_burst; @@ -59,7 +59,7 @@ static void mid_spi_maxburst_init(struct dw_spi *dws) dws->txburst = min(max_burst, def_burst); } -static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws) +static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws) { struct dw_dma_slave slave = { .src_id = 0, @@ -81,13 +81,13 @@ static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws) /* 1. Init rx channel */ slave.dma_dev = &dma_dev->dev; - dws->rxchan = dma_request_channel(mask, mid_spi_dma_chan_filter, &slave); + dws->rxchan = dma_request_channel(mask, dw_spi_dma_chan_filter, &slave); if (!dws->rxchan) goto err_exit; /* 2. Init tx channel */ slave.dst_id = 1; - dws->txchan = dma_request_channel(mask, mid_spi_dma_chan_filter, &slave); + dws->txchan = dma_request_channel(mask, dw_spi_dma_chan_filter, &slave); if (!dws->txchan) goto free_rxchan; @@ -96,7 +96,7 @@ static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws) init_completion(&dws->dma_completion); - mid_spi_maxburst_init(dws); + dw_spi_dma_maxburst_init(dws); return 0; @@ -107,7 +107,7 @@ static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws) return -EBUSY; } -static int mid_spi_dma_init_generic(struct device *dev, struct dw_spi *dws) +static int dw_spi_dma_init_generic(struct device *dev, struct dw_spi *dws) { dws->rxchan = dma_request_slave_channel(dev, "rx"); if (!dws->rxchan) @@ -125,12 +125,12 @@ static int mid_spi_dma_init_generic(struct device *dev, struct dw_spi *dws) init_completion(&dws->dma_completion); - mid_spi_maxburst_init(dws); + dw_spi_dma_maxburst_init(dws); return 0; } -static void mid_spi_dma_exit(struct dw_spi *dws) +static void dw_spi_dma_exit(struct dw_spi *dws) { if (dws->txchan) { dmaengine_terminate_sync(dws->txchan); @@ -145,7 +145,7 @@ static void mid_spi_dma_exit(struct dw_spi *dws) dw_writel(dws, DW_SPI_DMACR, 0); } -static irqreturn_t dma_transfer(struct dw_spi *dws) +static irqreturn_t dw_spi_dma_transfer_handler(struct dw_spi *dws) { u16 irq_status = dw_readl(dws, DW_SPI_ISR); @@ -161,15 +161,16 @@ static irqreturn_t dma_transfer(struct dw_spi *dws) return IRQ_HANDLED; } -static bool mid_spi_can_dma(struct spi_controller *master, - struct spi_device *spi, struct spi_transfer *xfer) +static bool dw_spi_can_dma(struct spi_controller *master, + struct spi_device *spi, struct spi_transfer *xfer) { struct dw_spi *dws = spi_controller_get_devdata(master); return xfer->len > dws->fifo_len; } -static enum dma_slave_buswidth convert_dma_width(u8 n_bytes) { +static enum dma_slave_buswidth dw_spi_dma_convert_width(u8 n_bytes) +{ if (n_bytes == 1) return DMA_SLAVE_BUSWIDTH_1_BYTE; else if (n_bytes == 2) @@ -244,8 +245,8 @@ static void dw_spi_dma_tx_done(void *arg) complete(&dws->dma_completion); } -static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws, - struct spi_transfer *xfer) +static struct dma_async_tx_descriptor * +dw_spi_dma_prepare_tx(struct dw_spi *dws, struct spi_transfer *xfer) { struct dma_slave_config txconf; struct dma_async_tx_descriptor *txdesc; @@ -258,7 +259,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws, txconf.dst_addr = dws->dma_addr; txconf.dst_maxburst = dws->txburst; txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - txconf.dst_addr_width = convert_dma_width(dws->n_bytes); + txconf.dst_addr_width = dw_spi_dma_convert_width(dws->n_bytes); txconf.device_fc = false; dmaengine_slave_config(dws->txchan, &txconf); @@ -350,7 +351,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws, rxconf.src_addr = dws->dma_addr; rxconf.src_maxburst = dws->rxburst; rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - rxconf.src_addr_width = convert_dma_width(dws->n_bytes); + rxconf.src_addr_width = dw_spi_dma_convert_width(dws->n_bytes); rxconf.device_fc = false; dmaengine_slave_config(dws->rxchan, &rxconf); @@ -369,7 +370,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws, return rxdesc; } -static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer) +static int dw_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer) { u16 imr = 0, dma_ctrl = 0; @@ -391,12 +392,12 @@ static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer) reinit_completion(&dws->dma_completion); - dws->transfer_handler = dma_transfer; + dws->transfer_handler = dw_spi_dma_transfer_handler; return 0; } -static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) +static int dw_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) { struct dma_async_tx_descriptor *txdesc, *rxdesc; int ret; @@ -436,7 +437,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) return ret; } -static void mid_spi_dma_stop(struct dw_spi *dws) +static void dw_spi_dma_stop(struct dw_spi *dws) { if (test_bit(TX_BUSY, &dws->dma_chan_busy)) { dmaengine_terminate_sync(dws->txchan); @@ -450,32 +451,32 @@ static void mid_spi_dma_stop(struct dw_spi *dws) dw_writel(dws, DW_SPI_DMACR, 0); } -static const struct dw_spi_dma_ops mfld_dma_ops = { - .dma_init = mid_spi_dma_init_mfld, - .dma_exit = mid_spi_dma_exit, - .dma_setup = mid_spi_dma_setup, - .can_dma = mid_spi_can_dma, - .dma_transfer = mid_spi_dma_transfer, - .dma_stop = mid_spi_dma_stop, +static const struct dw_spi_dma_ops dw_spi_dma_mfld_ops = { + .dma_init = dw_spi_dma_init_mfld, + .dma_exit = dw_spi_dma_exit, + .dma_setup = dw_spi_dma_setup, + .can_dma = dw_spi_can_dma, + .dma_transfer = dw_spi_dma_transfer, + .dma_stop = dw_spi_dma_stop, }; -void dw_spi_mid_setup_dma_mfld(struct dw_spi *dws) +void dw_spi_dma_setup_mfld(struct dw_spi *dws) { - dws->dma_ops = &mfld_dma_ops; + dws->dma_ops = &dw_spi_dma_mfld_ops; } -EXPORT_SYMBOL_GPL(dw_spi_mid_setup_dma_mfld); - -static const struct dw_spi_dma_ops generic_dma_ops = { - .dma_init = mid_spi_dma_init_generic, - .dma_exit = mid_spi_dma_exit, - .dma_setup = mid_spi_dma_setup, - .can_dma = mid_spi_can_dma, - .dma_transfer = mid_spi_dma_transfer, - .dma_stop = mid_spi_dma_stop, +EXPORT_SYMBOL_GPL(dw_spi_dma_setup_mfld); + +static const struct dw_spi_dma_ops dw_spi_dma_generic_ops = { + .dma_init = dw_spi_dma_init_generic, + .dma_exit = dw_spi_dma_exit, + .dma_setup = dw_spi_dma_setup, + .can_dma = dw_spi_can_dma, + .dma_transfer = dw_spi_dma_transfer, + .dma_stop = dw_spi_dma_stop, }; -void dw_spi_mid_setup_dma_generic(struct dw_spi *dws) +void dw_spi_dma_setup_generic(struct dw_spi *dws) { - dws->dma_ops = &generic_dma_ops; + dws->dma_ops = &dw_spi_dma_generic_ops; } -EXPORT_SYMBOL_GPL(dw_spi_mid_setup_dma_generic); +EXPORT_SYMBOL_GPL(dw_spi_dma_setup_generic); diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index c13707b8493e..2ea73809ca34 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -51,7 +51,7 @@ static int spi_mid_init(struct dw_spi *dws) /* Register hook to configure CTRLR0 */ dws->update_cr0 = dw_spi_update_cr0; - dw_spi_mid_setup_dma_mfld(dws); + dw_spi_dma_setup_mfld(dws); return 0; } @@ -61,7 +61,7 @@ static int spi_generic_init(struct dw_spi *dws) /* Register hook to configure CTRLR0 */ dws->update_cr0 = dw_spi_update_cr0; - dw_spi_mid_setup_dma_generic(dws); + dw_spi_dma_setup_generic(dws); return 0; } diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 91608cf12636..0b2cd7994513 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -259,13 +259,13 @@ extern u32 dw_spi_update_cr0_v1_01a(struct spi_controller *master, #ifdef CONFIG_SPI_DW_DMA -extern void dw_spi_mid_setup_dma_mfld(struct dw_spi *dws); -extern void dw_spi_mid_setup_dma_generic(struct dw_spi *dws); +extern void dw_spi_dma_setup_mfld(struct dw_spi *dws); +extern void dw_spi_dma_setup_generic(struct dw_spi *dws); #else -static inline void dw_spi_mid_setup_dma_mfld(struct dw_spi *dws) {} -static inline void dw_spi_mid_setup_dma_generic(struct dw_spi *dws) {} +static inline void dw_spi_dma_setup_mfld(struct dw_spi *dws) {} +static inline void dw_spi_dma_setup_generic(struct dw_spi *dws) {} #endif /* !CONFIG_SPI_DW_DMA */ From patchwork Fri May 29 03:59:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 199779 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07793C433DF for ; Fri, 29 May 2020 04:00:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E3A2220707 for ; Fri, 29 May 2020 04:00:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726057AbgE2EAP (ORCPT ); Fri, 29 May 2020 00:00:15 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45410 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389579AbgE2D7o (ORCPT ); Thu, 28 May 2020 23:59:44 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id B29FE8029EA1; Fri, 29 May 2020 03:59:42 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id W0w-AkINMplP; Fri, 29 May 2020 06:59:42 +0300 (MSK) From: Serge Semin To: Mark Brown CC: Serge Semin , Serge Semin , Andy Shevchenko , Georgy Vlasov , Ramil Zaripov , Alexey Malahov , Thomas Bogendoerfer , Arnd Bergmann , Feng Tang , Rob Herring , , , , Subject: [PATCH v5 15/16] spi: dw: Use regset32 DebugFS method to create regdump file Date: Fri, 29 May 2020 06:59:13 +0300 Message-ID: <20200529035915.20790-16-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> References: <20200529035915.20790-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org DebugFS kernel interface provides a dedicated method to create the registers dump file. Use it instead of creating a generic DebugFS file with manually written read callback function. Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Cc: Georgy Vlasov Cc: Ramil Zaripov Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Feng Tang Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org --- Changelog v3: - Add commas in the debugfs_reg32 structure initializer and after the last item of the array dw_spi_dbgfs_regs. --- drivers/spi/spi-dw-core.c | 86 ++++++++++++--------------------------- drivers/spi/spi-dw.h | 2 + 2 files changed, 28 insertions(+), 60 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 4d1849699a12..323c66c5db50 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -29,66 +29,29 @@ struct chip_data { }; #ifdef CONFIG_DEBUG_FS -#define SPI_REGS_BUFSIZE 1024 -static ssize_t dw_spi_show_regs(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct dw_spi *dws = file->private_data; - char *buf; - u32 len = 0; - ssize_t ret; - - buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL); - if (!buf) - return 0; - - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "%s registers:\n", dev_name(&dws->master->dev)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "=================================\n"); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "CTRLR0: \t0x%08x\n", dw_readl(dws, DW_SPI_CTRLR0)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "CTRLR1: \t0x%08x\n", dw_readl(dws, DW_SPI_CTRLR1)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "SSIENR: \t0x%08x\n", dw_readl(dws, DW_SPI_SSIENR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "SER: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SER)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "BAUDR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_BAUDR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "TXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_TXFTLR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "RXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_RXFTLR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "TXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_TXFLR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "RXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_RXFLR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "SR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "IMR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_IMR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "ISR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_ISR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "DMACR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_DMACR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "DMATDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMATDLR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "DMARDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMARDLR)); - len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len, - "=================================\n"); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return ret; + +#define DW_SPI_DBGFS_REG(_name, _off) \ +{ \ + .name = _name, \ + .offset = _off, \ } -static const struct file_operations dw_spi_regs_ops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = dw_spi_show_regs, - .llseek = default_llseek, +static const struct debugfs_reg32 dw_spi_dbgfs_regs[] = { + DW_SPI_DBGFS_REG("CTRLR0", DW_SPI_CTRLR0), + DW_SPI_DBGFS_REG("CTRLR1", DW_SPI_CTRLR1), + DW_SPI_DBGFS_REG("SSIENR", DW_SPI_SSIENR), + DW_SPI_DBGFS_REG("SER", DW_SPI_SER), + DW_SPI_DBGFS_REG("BAUDR", DW_SPI_BAUDR), + DW_SPI_DBGFS_REG("TXFTLR", DW_SPI_TXFTLR), + DW_SPI_DBGFS_REG("RXFTLR", DW_SPI_RXFTLR), + DW_SPI_DBGFS_REG("TXFLR", DW_SPI_TXFLR), + DW_SPI_DBGFS_REG("RXFLR", DW_SPI_RXFLR), + DW_SPI_DBGFS_REG("SR", DW_SPI_SR), + DW_SPI_DBGFS_REG("IMR", DW_SPI_IMR), + DW_SPI_DBGFS_REG("ISR", DW_SPI_ISR), + DW_SPI_DBGFS_REG("DMACR", DW_SPI_DMACR), + DW_SPI_DBGFS_REG("DMATDLR", DW_SPI_DMATDLR), + DW_SPI_DBGFS_REG("DMARDLR", DW_SPI_DMARDLR), }; static int dw_spi_debugfs_init(struct dw_spi *dws) @@ -100,8 +63,11 @@ static int dw_spi_debugfs_init(struct dw_spi *dws) if (!dws->debugfs) return -ENOMEM; - debugfs_create_file("registers", S_IFREG | S_IRUGO, - dws->debugfs, (void *)dws, &dw_spi_regs_ops); + dws->regset.regs = dw_spi_dbgfs_regs; + dws->regset.nregs = ARRAY_SIZE(dw_spi_dbgfs_regs); + dws->regset.base = dws->regs; + debugfs_create_regset32("registers", 0400, dws->debugfs, &dws->regset); + return 0; } diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 0b2cd7994513..151ba316619e 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -3,6 +3,7 @@ #define DW_SPI_HEADER_H #include +#include #include #include #include @@ -152,6 +153,7 @@ struct dw_spi { #ifdef CONFIG_DEBUG_FS struct dentry *debugfs; + struct debugfs_regset32 regset; #endif };