From patchwork Sun Jul 22 21:20:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 10539415 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6C53014BC for ; Sun, 22 Jul 2018 21:20:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C8652843B for ; Sun, 22 Jul 2018 21:20:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3CA8D28449; Sun, 22 Jul 2018 21:20:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 162B42843B for ; Sun, 22 Jul 2018 21:20:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387794AbeGVWS0 (ORCPT ); Sun, 22 Jul 2018 18:18:26 -0400 Received: from mx2.suse.de ([195.135.220.15]:38774 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2387731AbeGVWS0 (ORCPT ); Sun, 22 Jul 2018 18:18:26 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 5F820AFD0; Sun, 22 Jul 2018 21:20:22 +0000 (UTC) From: =?utf-8?q?Andreas_F=C3=A4rber?= To: linux-mips@linux-mips.org Cc: Ralf Baechle , Paul Burton , James Hogan , linux-kernel@vger.kernel.org, Ionela Voinescu , Ezequiel Garcia , =?utf-8?q?Andreas_F=C3=A4rber?= , Mark Brown , linux-spi@vger.kernel.org Subject: [PATCH 10/15] spi: img-spfi: Implement dual and quad mode Date: Sun, 22 Jul 2018 23:20:05 +0200 Message-Id: <20180722212010.3979-11-afaerber@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180722212010.3979-1-afaerber@suse.de> References: <20180722212010.3979-1-afaerber@suse.de> MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ionela Voinescu For dual and quad modes to work, the SPFI controller needs to have information about command/address/dummy bytes in the transaction register. This information is not relevant for single mode, and therefore it can have any value in the allowed range. Therefore, for any read or write transfers of less than 8 bytes (cmd = 1 byte, addr up to 7 bytes), SPFI will be configured, but not enabled (unless it is the last transfer in the queue). The transfer will be enabled by the subsequent transfer. A pending transfer is determined by the content of the transaction register: if command part is set and tsize is not. This way we ensure that for dual and quad transactions the command request size will appear in the command/address part of the transaction register, while the data size will be in tsize, all data being sent/received in the same transaction (as set up in the transaction register). Signed-off-by: Ionela Voinescu Signed-off-by: Ezequiel Garcia Signed-off-by: Andreas Färber --- drivers/spi/spi-img-spfi.c | 96 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 7a37090dabbe..c845a505bae6 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -40,7 +40,8 @@ #define SPFI_CONTROL_SOFT_RESET BIT(11) #define SPFI_CONTROL_SEND_DMA BIT(10) #define SPFI_CONTROL_GET_DMA BIT(9) -#define SPFI_CONTROL_SE BIT(8) +#define SPFI_CONTROL_SE BIT(8) +#define SPFI_CONTROL_TX_RX BIT(1) #define SPFI_CONTROL_TMODE_SHIFT 5 #define SPFI_CONTROL_TMODE_MASK 0x7 #define SPFI_CONTROL_TMODE_SINGLE 0 @@ -51,6 +52,10 @@ #define SPFI_TRANSACTION 0x18 #define SPFI_TRANSACTION_TSIZE_SHIFT 16 #define SPFI_TRANSACTION_TSIZE_MASK 0xffff +#define SPFI_TRANSACTION_CMD_SHIFT 13 +#define SPFI_TRANSACTION_CMD_MASK 0x7 +#define SPFI_TRANSACTION_ADDR_SHIFT 10 +#define SPFI_TRANSACTION_ADDR_MASK 0x7 #define SPFI_PORT_STATE 0x1c #define SPFI_PORT_STATE_DEV_SEL_SHIFT 20 @@ -87,6 +92,7 @@ */ #define SPFI_32BIT_FIFO_SIZE 64 #define SPFI_8BIT_FIFO_SIZE 16 +#define SPFI_DATA_REQUEST_MAX_SIZE 8 struct img_spfi { struct device *dev; @@ -103,6 +109,8 @@ struct img_spfi { struct dma_chan *tx_ch; bool tx_dma_busy; bool rx_dma_busy; + + bool complete; }; struct img_spfi_device_data { @@ -123,9 +131,11 @@ static inline void spfi_start(struct img_spfi *spfi) { u32 val; - val = spfi_readl(spfi, SPFI_CONTROL); - val |= SPFI_CONTROL_SPFI_EN; - spfi_writel(spfi, val, SPFI_CONTROL); + if (spfi->complete) { + val = spfi_readl(spfi, SPFI_CONTROL); + val |= SPFI_CONTROL_SPFI_EN; + spfi_writel(spfi, val, SPFI_CONTROL); + } } static inline void spfi_reset(struct img_spfi *spfi) @@ -138,12 +148,21 @@ static int spfi_wait_all_done(struct img_spfi *spfi) { unsigned long timeout = jiffies + msecs_to_jiffies(50); + if (!(spfi->complete)) + return 0; + while (time_before(jiffies, timeout)) { u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); if (status & SPFI_INTERRUPT_ALLDONETRIG) { spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG, SPFI_INTERRUPT_CLEAR); + /* + * Disable SPFI for it not to interfere with + * pending transactions + */ + spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL) + & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL); return 0; } cpu_relax(); @@ -494,9 +513,32 @@ static void img_spfi_config(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) { struct img_spfi *spfi = spi_master_get_devdata(spi->master); - u32 val, div; + u32 val, div, transact; + bool is_pending; /* + * For read or write transfers of less than 8 bytes (cmd = 1 byte, + * addr up to 7 bytes), SPFI will be configured, but not enabled + * (unless it is the last transfer in the queue).The transfer will + * be enabled by the subsequent transfer. + * A pending transfer is determined by the content of the + * transaction register: if command part is set and tsize + * is not + */ + transact = spfi_readl(spfi, SPFI_TRANSACTION); + is_pending = ((transact >> SPFI_TRANSACTION_CMD_SHIFT) & + SPFI_TRANSACTION_CMD_MASK) && + (!((transact >> SPFI_TRANSACTION_TSIZE_SHIFT) & + SPFI_TRANSACTION_TSIZE_MASK)); + + /* If there are no pending transactions it's OK to soft reset */ + if (!is_pending) { + /* Start the transaction from a known (reset) state */ + spfi_reset(spfi); + } + + /* + * Before anything else, set up parameters. * output = spfi_clk * (BITCLK / 512), where BITCLK must be a * power of 2 up to 128 */ @@ -509,20 +551,52 @@ static void img_spfi_config(struct spi_master *master, struct spi_device *spi, val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT; spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select)); - spfi_writel(spfi, xfer->len << SPFI_TRANSACTION_TSIZE_SHIFT, - SPFI_TRANSACTION); + if (!list_is_last(&xfer->transfer_list, &master->cur_msg->transfers) && + /* + * For duplex mode (both the tx and rx buffers are !NULL) the + * CMD, ADDR, and DUMMY byte parts of the transaction register + * should always be 0 and therefore the pending transfer + * technique cannot be used. + */ + (xfer->tx_buf) && (!xfer->rx_buf) && + (xfer->len <= SPFI_DATA_REQUEST_MAX_SIZE) && !is_pending) { + transact = (1 & SPFI_TRANSACTION_CMD_MASK) << + SPFI_TRANSACTION_CMD_SHIFT; + transact |= ((xfer->len - 1) & SPFI_TRANSACTION_ADDR_MASK) << + SPFI_TRANSACTION_ADDR_SHIFT; + spfi->complete = false; + } else { + spfi->complete = true; + if (is_pending) { + /* Keep setup from pending transfer */ + transact |= ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) << + SPFI_TRANSACTION_TSIZE_SHIFT); + } else { + transact = ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) << + SPFI_TRANSACTION_TSIZE_SHIFT); + } + } + spfi_writel(spfi, transact, SPFI_TRANSACTION); val = spfi_readl(spfi, SPFI_CONTROL); val &= ~(SPFI_CONTROL_SEND_DMA | SPFI_CONTROL_GET_DMA); - if (xfer->tx_buf) + /* + * We set up send DMA for pending transfers also, as + * those are always send transfers + */ + if ((xfer->tx_buf) || is_pending) val |= SPFI_CONTROL_SEND_DMA; - if (xfer->rx_buf) + if (xfer->tx_buf) + val |= SPFI_CONTROL_TX_RX; + if (xfer->rx_buf) { val |= SPFI_CONTROL_GET_DMA; + val &= ~SPFI_CONTROL_TX_RX; + } val &= ~(SPFI_CONTROL_TMODE_MASK << SPFI_CONTROL_TMODE_SHIFT); - if (xfer->tx_nbits == SPI_NBITS_DUAL && + if (xfer->tx_nbits == SPI_NBITS_DUAL || xfer->rx_nbits == SPI_NBITS_DUAL) val |= SPFI_CONTROL_TMODE_DUAL << SPFI_CONTROL_TMODE_SHIFT; - else if (xfer->tx_nbits == SPI_NBITS_QUAD && + else if (xfer->tx_nbits == SPI_NBITS_QUAD || xfer->rx_nbits == SPI_NBITS_QUAD) val |= SPFI_CONTROL_TMODE_QUAD << SPFI_CONTROL_TMODE_SHIFT; val |= SPFI_CONTROL_SE; From patchwork Sun Jul 22 21:20:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 10539427 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D7D8B1823 for ; Sun, 22 Jul 2018 21:21:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5CA72843B for ; Sun, 22 Jul 2018 21:21:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B9C8228449; Sun, 22 Jul 2018 21:21:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 631C12843B for ; Sun, 22 Jul 2018 21:21:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387932AbeGVWS6 (ORCPT ); Sun, 22 Jul 2018 18:18:58 -0400 Received: from mx2.suse.de ([195.135.220.15]:38772 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2387759AbeGVWSY (ORCPT ); Sun, 22 Jul 2018 18:18:24 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id C5254AFD4; Sun, 22 Jul 2018 21:20:22 +0000 (UTC) From: =?utf-8?q?Andreas_F=C3=A4rber?= To: linux-mips@linux-mips.org Cc: Ralf Baechle , Paul Burton , James Hogan , linux-kernel@vger.kernel.org, Ionela Voinescu , =?utf-8?q?Andreas_F=C3=A4rber?= , Mark Brown , linux-spi@vger.kernel.org Subject: [PATCH 11/15] spi: img-spfi: Set device select bits for SPFI port state Date: Sun, 22 Jul 2018 23:20:06 +0200 Message-Id: <20180722212010.3979-12-afaerber@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180722212010.3979-1-afaerber@suse.de> References: <20180722212010.3979-1-afaerber@suse.de> MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ionela Voinescu Even if the chip select line is not controlled by the SPFI hardware, the device select bits need to be set to specify the chip select line in use for the hardware to know what parameters to use for the current transfer. Signed-off-by: Ionela Voinescu Signed-off-by: Andreas Färber --- drivers/spi/spi-img-spfi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index c845a505bae6..0d73d31a6a2b 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -438,6 +438,9 @@ static int img_spfi_prepare(struct spi_master *master, struct spi_message *msg) u32 val; val = spfi_readl(spfi, SPFI_PORT_STATE); + val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK << + SPFI_PORT_STATE_DEV_SEL_SHIFT); + val |= msg->spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT; if (msg->spi->mode & SPI_CPHA) val |= SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select); else From patchwork Sun Jul 22 21:20:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 10539423 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 82F1014BC for ; Sun, 22 Jul 2018 21:20:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 718592843B for ; Sun, 22 Jul 2018 21:20:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 655EF28449; Sun, 22 Jul 2018 21:20:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0AFEF2843B for ; Sun, 22 Jul 2018 21:20:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387830AbeGVWSZ (ORCPT ); Sun, 22 Jul 2018 18:18:25 -0400 Received: from mx2.suse.de ([195.135.220.15]:38792 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2387772AbeGVWSZ (ORCPT ); Sun, 22 Jul 2018 18:18:25 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 301FBAFD5; Sun, 22 Jul 2018 21:20:23 +0000 (UTC) From: =?utf-8?q?Andreas_F=C3=A4rber?= To: linux-mips@linux-mips.org Cc: Ralf Baechle , Paul Burton , James Hogan , linux-kernel@vger.kernel.org, Ionela Voinescu , =?utf-8?q?Andreas_F=C3=A4rber?= , Mark Brown , linux-spi@vger.kernel.org Subject: [PATCH 12/15] spi: img-spfi: Use device 0 configuration for all devices Date: Sun, 22 Jul 2018 23:20:07 +0200 Message-Id: <20180722212010.3979-13-afaerber@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180722212010.3979-1-afaerber@suse.de> References: <20180722212010.3979-1-afaerber@suse.de> MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ionela Voinescu Given that we control the chip select line externally, we can use only one parameter register (device 0 parameter register) and one set of configuration bits (port configuration bits for device 0) for all devices (all chip select lines). Signed-off-by: Ionela Voinescu Signed-off-by: Andreas Färber --- drivers/spi/spi-img-spfi.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 0d73d31a6a2b..231b59c1ab60 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -437,18 +437,23 @@ static int img_spfi_prepare(struct spi_master *master, struct spi_message *msg) struct img_spfi *spfi = spi_master_get_devdata(master); u32 val; + /* + * The chip select line is controlled externally so + * we can use the CS0 configuration for all devices + */ val = spfi_readl(spfi, SPFI_PORT_STATE); + + /* 0 for device selection */ val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK << SPFI_PORT_STATE_DEV_SEL_SHIFT); - val |= msg->spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT; if (msg->spi->mode & SPI_CPHA) - val |= SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select); + val |= SPFI_PORT_STATE_CK_PHASE(0); else - val &= ~SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select); + val &= ~SPFI_PORT_STATE_CK_PHASE(0); if (msg->spi->mode & SPI_CPOL) - val |= SPFI_PORT_STATE_CK_POL(msg->spi->chip_select); + val |= SPFI_PORT_STATE_CK_POL(0); else - val &= ~SPFI_PORT_STATE_CK_POL(msg->spi->chip_select); + val &= ~SPFI_PORT_STATE_CK_POL(0); spfi_writel(spfi, val, SPFI_PORT_STATE); return 0; @@ -548,11 +553,15 @@ static void img_spfi_config(struct spi_master *master, struct spi_device *spi, div = DIV_ROUND_UP(clk_get_rate(spfi->spfi_clk), xfer->speed_hz); div = clamp(512 / (1 << get_count_order(div)), 1, 128); - val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(spi->chip_select)); + /* + * The chip select line is controlled externally so + * we can use the CS0 parameters for all devices + */ + val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(0)); val &= ~(SPFI_DEVICE_PARAMETER_BITCLK_MASK << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT); val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT; - spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select)); + spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(0)); if (!list_is_last(&xfer->transfer_list, &master->cur_msg->transfers) && /* From patchwork Sun Jul 22 21:20:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 10539421 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A778B1823 for ; Sun, 22 Jul 2018 21:20:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 943C12843B for ; Sun, 22 Jul 2018 21:20:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 87C2E28449; Sun, 22 Jul 2018 21:20:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2ACB72843B for ; Sun, 22 Jul 2018 21:20:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387772AbeGVWS0 (ORCPT ); Sun, 22 Jul 2018 18:18:26 -0400 Received: from mx2.suse.de ([195.135.220.15]:38804 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2387794AbeGVWSZ (ORCPT ); Sun, 22 Jul 2018 18:18:25 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 91399AFD6; Sun, 22 Jul 2018 21:20:23 +0000 (UTC) From: =?utf-8?q?Andreas_F=C3=A4rber?= To: linux-mips@linux-mips.org Cc: Ralf Baechle , Paul Burton , James Hogan , linux-kernel@vger.kernel.org, Ionela Voinescu , =?utf-8?q?Andreas_F=C3=A4rber?= , Mark Brown , linux-spi@vger.kernel.org Subject: [PATCH 13/15] spi: img-spfi: RX maximum burst size for DMA is 8 Date: Sun, 22 Jul 2018 23:20:08 +0200 Message-Id: <20180722212010.3979-14-afaerber@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180722212010.3979-1-afaerber@suse.de> References: <20180722212010.3979-1-afaerber@suse.de> MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ionela Voinescu The depth of the FIFOs is 16 bytes. The DMA request line is tied to the half full/empty (depending on the use of the TX or RX FIFO) threshold. For the TX FIFO, if you set a burst size of 8 (equal to half the depth) the first burst goes into FIFO without any issues, but due the latency involved (the time the data leaves the DMA engine to the time it arrives at the FIFO), the DMA might trigger another burst of 8. But given that there is no space for 2 additonal bursts of 8, this would result in a failure. Therefore, we have to keep the burst size for TX to 4 to accomodate for an extra burst. For the read (RX) scenario, the DMA request line goes high when there is at least 8 entries in the FIFO (half full), and we can program the burst size to be 8 because the risk of accidental burst does not exist. The DMA engine will not trigger another read until the read data for all the burst it has sent out has been received. While here, move the burst size setting outside of the if/else branches as they have the same value for both 8 and 32 bit data widths. Signed-off-by: Ionela Voinescu Signed-off-by: Andreas Färber --- drivers/spi/spi-img-spfi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 231b59c1ab60..8ad6c75d0af5 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -346,12 +346,11 @@ static int img_spfi_start_dma(struct spi_master *master, if (xfer->len % 4 == 0) { rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA; rxconf.src_addr_width = 4; - rxconf.src_maxburst = 4; } else { rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; rxconf.src_addr_width = 1; - rxconf.src_maxburst = 4; } + rxconf.src_maxburst = 8; dmaengine_slave_config(spfi->rx_ch, &rxconf); rxdesc = dmaengine_prep_slave_sg(spfi->rx_ch, xfer->rx_sg.sgl, @@ -370,12 +369,11 @@ static int img_spfi_start_dma(struct spi_master *master, if (xfer->len % 4 == 0) { txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA; txconf.dst_addr_width = 4; - txconf.dst_maxburst = 4; } else { txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; txconf.dst_addr_width = 1; - txconf.dst_maxburst = 4; } + txconf.dst_maxburst = 4; dmaengine_slave_config(spfi->tx_ch, &txconf); txdesc = dmaengine_prep_slave_sg(spfi->tx_ch, xfer->tx_sg.sgl, From patchwork Sun Jul 22 21:20:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 10539417 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A5E7E14BC for ; Sun, 22 Jul 2018 21:20:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 938CB2843B for ; Sun, 22 Jul 2018 21:20:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 874F92844C; Sun, 22 Jul 2018 21:20:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0DAD92843B for ; Sun, 22 Jul 2018 21:20:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387887AbeGVWSd (ORCPT ); Sun, 22 Jul 2018 18:18:33 -0400 Received: from mx2.suse.de ([195.135.220.15]:38830 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2387797AbeGVWS0 (ORCPT ); Sun, 22 Jul 2018 18:18:26 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 02F20AFE1; Sun, 22 Jul 2018 21:20:24 +0000 (UTC) From: =?utf-8?q?Andreas_F=C3=A4rber?= To: linux-mips@linux-mips.org Cc: Ralf Baechle , Paul Burton , James Hogan , linux-kernel@vger.kernel.org, Ionela Voinescu , =?utf-8?q?Andreas_F=C3=A4rber?= , Mark Brown , linux-spi@vger.kernel.org Subject: [PATCH 14/15] spi: img-spfi: Finish every transfer cleanly Date: Sun, 22 Jul 2018 23:20:09 +0200 Message-Id: <20180722212010.3979-15-afaerber@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180722212010.3979-1-afaerber@suse.de> References: <20180722212010.3979-1-afaerber@suse.de> MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ionela Voinescu Before this change, the interrupt status bit that signaled the end of a transfer was cleared in the wait_all_done function. That functionality triggered issues for DMA duplex transactions where the wait function was called twice, in both the TX and RX callbacks. In order to fix the issue, clear all interrupt data bits at the end of a PIO transfer or at the end of both TX and RX duplex transfers, if the transfer is not a pending transfer (command waiting for data). After that, the status register is checked for new incoming data or new data requests to be signaled. If SPFI finished cleanly, no new interrupt data bits should be set. Signed-off-by: Ionela Voinescu Signed-off-by: Andreas Färber --- drivers/spi/spi-img-spfi.c | 49 +++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 8ad6c75d0af5..a1244234daa5 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -83,6 +83,14 @@ #define SPFI_INTERRUPT_SDE BIT(1) #define SPFI_INTERRUPT_SDTRIG BIT(0) +#define SPFI_INTERRUPT_DATA_BITS (SPFI_INTERRUPT_SDHF |\ + SPFI_INTERRUPT_SDFUL |\ + SPFI_INTERRUPT_GDEX32BIT |\ + SPFI_INTERRUPT_GDHF |\ + SPFI_INTERRUPT_GDFUL |\ + SPFI_INTERRUPT_ALLDONETRIG |\ + SPFI_INTERRUPT_GDEX8BIT) + /* * There are four parallel FIFOs of 16 bytes each. The word buffer * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an @@ -144,6 +152,23 @@ static inline void spfi_reset(struct img_spfi *spfi) spfi_writel(spfi, 0, SPFI_CONTROL); } +static inline void spfi_finish(struct img_spfi *spfi) +{ + if (!(spfi->complete)) + return; + + /* Clear data bits as all transfers(TX and RX) have finished */ + spfi_writel(spfi, SPFI_INTERRUPT_DATA_BITS, SPFI_INTERRUPT_CLEAR); + if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & SPFI_INTERRUPT_DATA_BITS) { + dev_err(spfi->dev, "SPFI did not finish transfer cleanly.\n"); + spfi_reset(spfi); + } + /* Disable SPFI for it not to interfere with pending transactions */ + spfi_writel(spfi, + spfi_readl(spfi, SPFI_CONTROL) & ~SPFI_CONTROL_SPFI_EN, + SPFI_CONTROL); +} + static int spfi_wait_all_done(struct img_spfi *spfi) { unsigned long timeout = jiffies + msecs_to_jiffies(50); @@ -152,19 +177,9 @@ static int spfi_wait_all_done(struct img_spfi *spfi) return 0; while (time_before(jiffies, timeout)) { - u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); - - if (status & SPFI_INTERRUPT_ALLDONETRIG) { - spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG, - SPFI_INTERRUPT_CLEAR); - /* - * Disable SPFI for it not to interfere with - * pending transactions - */ - spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL) - & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL); + if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & + SPFI_INTERRUPT_ALLDONETRIG) return 0; - } cpu_relax(); } @@ -296,6 +311,8 @@ static int img_spfi_start_pio(struct spi_master *master, } ret = spfi_wait_all_done(spfi); + spfi_finish(spfi); + if (ret < 0) return ret; @@ -311,8 +328,10 @@ static void img_spfi_dma_rx_cb(void *data) spin_lock_irqsave(&spfi->lock, flags); spfi->rx_dma_busy = false; - if (!spfi->tx_dma_busy) + if (!spfi->tx_dma_busy) { + spfi_finish(spfi); spi_finalize_current_transfer(spfi->master); + } spin_unlock_irqrestore(&spfi->lock, flags); } @@ -325,8 +344,10 @@ static void img_spfi_dma_tx_cb(void *data) spin_lock_irqsave(&spfi->lock, flags); spfi->tx_dma_busy = false; - if (!spfi->rx_dma_busy) + if (!spfi->rx_dma_busy) { + spfi_finish(spfi); spi_finalize_current_transfer(spfi->master); + } spin_unlock_irqrestore(&spfi->lock, flags); }