From patchwork Wed Oct 7 23:54:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 268408 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=-9.8 required=3.0 tests=BAYES_00, 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 A2BDCC4727F for ; Wed, 7 Oct 2020 23:56:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5BE94206E7 for ; Wed, 7 Oct 2020 23:56:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728620AbgJGX4r (ORCPT ); Wed, 7 Oct 2020 19:56:47 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45582 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728267AbgJGXz0 (ORCPT ); Wed, 7 Oct 2020 19:55:26 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 3D252803016F; Wed, 7 Oct 2020 23:55:18 +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 aU0WmY4WaH5S; Thu, 8 Oct 2020 02:55:17 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , Rob Herring , , , Subject: [PATCH v4 02/21] spi: dw: Add DWC SSI capability Date: Thu, 8 Oct 2020 02:54:51 +0300 Message-ID: <20201007235511.4935-3-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org Currently DWC SSI core is supported by means of setting up the core-specific update_cr0() callback. It isn't suitable for multiple reasons. First of all having exported several methods doing the same thing but for different chips makes the code harder to maintain. Secondly the spi-dw-core driver exports the methods, then the spi-dw-mmio driver sets the private data callback with one of them so to be called by the core driver again. That makes the code logic too complicated. Thirdly using callbacks for just updating the CR0 register is problematic, since in case if the register needed to be updated from different parts of the code, we'd have to create another callback (for instance the SPI device-specific parameters don't need to be calculated each time the SPI transfer is submitted, so it's better to pre-calculate the CR0 data at the SPI-device setup stage). So keeping all the above in mind let's discard the update_cr0() callbacks, define a generic and static dw_spi_update_cr0() method and create the DW_SPI_CAP_DWC_SSI capability, which when enabled would activate the alternative CR0 register layout. While at it add the comments to the code path of the normal DW APB SSI controller setup to make the dw_spi_update_cr0() method looking coherent. Signed-off-by: Serge Semin --- Changelog v2: - Get back the in-code comments to the dw_spi_update_cr0() method and it' further derivatives. Changelog v3: - Remove dw_spi_update_cr0() callback assignment from the DW APB SSI PCI glue-driver. --- drivers/spi/spi-dw-core.c | 80 ++++++++++++++++++--------------------- drivers/spi/spi-dw-mmio.c | 20 +--------- drivers/spi/spi-dw-pci.c | 6 --- drivers/spi/spi-dw.h | 9 +---- 4 files changed, 40 insertions(+), 75 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 3a7fdca8d335..be16fdaf7ce0 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -228,60 +228,56 @@ static irqreturn_t dw_spi_irq(int irq, void *dev_id) return dws->transfer_handler(dws); } -/* Configure CTRLR0 for DW_apb_ssi */ -u32 dw_spi_update_cr0(struct spi_controller *master, struct spi_device *spi, - struct spi_transfer *transfer) +static void dw_spi_update_cr0(struct dw_spi *dws, struct spi_device *spi, + struct spi_transfer *transfer) { struct chip_data *chip = spi_get_ctldata(spi); u32 cr0; - /* Default SPI mode is SCPOL = 0, SCPH = 0 */ - cr0 = (transfer->bits_per_word - 1) - | (SSI_MOTO_SPI << SPI_FRF_OFFSET) - | ((((spi->mode & SPI_CPOL) ? 1 : 0) << SPI_SCOL_OFFSET) | - (((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET) | - (((spi->mode & SPI_LOOP) ? 1 : 0) << SPI_SRL_OFFSET)) - | (chip->tmode << SPI_TMOD_OFFSET); + /* CTRLR0[ 4/3: 0] Data Frame Size */ + cr0 = (transfer->bits_per_word - 1); - return cr0; -} -EXPORT_SYMBOL_GPL(dw_spi_update_cr0); + if (!(dws->caps & DW_SPI_CAP_DWC_SSI)) { + /* CTRLR0[ 5: 4] Frame Format */ + cr0 |= SSI_MOTO_SPI << SPI_FRF_OFFSET; -/* Configure CTRLR0 for DWC_ssi */ -u32 dw_spi_update_cr0_v1_01a(struct spi_controller *master, - struct spi_device *spi, - struct spi_transfer *transfer) -{ - struct dw_spi *dws = spi_controller_get_devdata(master); - struct chip_data *chip = spi_get_ctldata(spi); - u32 cr0; + /* + * SPI mode (SCPOL|SCPH) + * CTRLR0[ 6] Serial Clock Phase + * CTRLR0[ 7] Serial Clock Polarity + */ + cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << SPI_SCOL_OFFSET; + cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET; - /* CTRLR0[ 4: 0] Data Frame Size */ - cr0 = (transfer->bits_per_word - 1); + /* CTRLR0[11] Shift Register Loop */ + cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << SPI_SRL_OFFSET; - /* CTRLR0[ 7: 6] Frame Format */ - cr0 |= SSI_MOTO_SPI << DWC_SSI_CTRLR0_FRF_OFFSET; + /* CTRLR0[ 9:8] Transfer Mode */ + cr0 |= chip->tmode << SPI_TMOD_OFFSET; + } else { + /* CTRLR0[ 7: 6] Frame Format */ + cr0 |= SSI_MOTO_SPI << DWC_SSI_CTRLR0_FRF_OFFSET; - /* - * SPI mode (SCPOL|SCPH) - * CTRLR0[ 8] Serial Clock Phase - * CTRLR0[ 9] Serial Clock Polarity - */ - cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << DWC_SSI_CTRLR0_SCPOL_OFFSET; - cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << DWC_SSI_CTRLR0_SCPH_OFFSET; + /* + * SPI mode (SCPOL|SCPH) + * CTRLR0[ 8] Serial Clock Phase + * CTRLR0[ 9] Serial Clock Polarity + */ + cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << DWC_SSI_CTRLR0_SCPOL_OFFSET; + cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << DWC_SSI_CTRLR0_SCPH_OFFSET; - /* CTRLR0[11:10] Transfer Mode */ - cr0 |= chip->tmode << DWC_SSI_CTRLR0_TMOD_OFFSET; + /* CTRLR0[13] Shift Register Loop */ + cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << DWC_SSI_CTRLR0_SRL_OFFSET; - /* CTRLR0[13] Shift Register Loop */ - cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << DWC_SSI_CTRLR0_SRL_OFFSET; + /* CTRLR0[11:10] Transfer Mode */ + cr0 |= chip->tmode << DWC_SSI_CTRLR0_TMOD_OFFSET; - if (dws->caps & DW_SPI_CAP_KEEMBAY_MST) - cr0 |= DWC_SSI_CTRLR0_KEEMBAY_MST; + if (dws->caps & DW_SPI_CAP_KEEMBAY_MST) + cr0 |= DWC_SSI_CTRLR0_KEEMBAY_MST; + } - return cr0; + dw_writel(dws, DW_SPI_CTRLR0, cr0); } -EXPORT_SYMBOL_GPL(dw_spi_update_cr0_v1_01a); static int dw_spi_transfer_one(struct spi_controller *master, struct spi_device *spi, struct spi_transfer *transfer) @@ -290,7 +286,6 @@ static int dw_spi_transfer_one(struct spi_controller *master, struct chip_data *chip = spi_get_ctldata(spi); u8 imask = 0; u16 txlevel = 0; - u32 cr0; int ret; dws->dma_mapped = 0; @@ -319,8 +314,7 @@ static int dw_spi_transfer_one(struct spi_controller *master, transfer->effective_speed_hz = dws->max_freq / chip->clk_div; - cr0 = dws->update_cr0(master, spi, transfer); - dw_writel(dws, DW_SPI_CTRLR0, cr0); + dw_spi_update_cr0(dws, spi, transfer); /* Check if current transfer is a DMA transaction */ if (master->can_dma && master->can_dma(master, spi, transfer)) diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index c0d351fde782..d0cc5bf4fa4e 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -110,9 +110,6 @@ static int dw_spi_mscc_init(struct platform_device *pdev, dwsmmio->dws.set_cs = dw_spi_mscc_set_cs; dwsmmio->priv = dwsmscc; - /* Register hook to configure CTRLR0 */ - dwsmmio->dws.update_cr0 = dw_spi_update_cr0; - return 0; } @@ -188,9 +185,6 @@ static int dw_spi_mscc_sparx5_init(struct platform_device *pdev, dwsmmio->dws.set_cs = dw_spi_sparx5_set_cs; dwsmmio->priv = dwsmscc; - /* Register hook to configure CTRLR0 */ - dwsmmio->dws.update_cr0 = dw_spi_update_cr0; - return 0; } @@ -199,18 +193,12 @@ static int dw_spi_alpine_init(struct platform_device *pdev, { dwsmmio->dws.caps = DW_SPI_CAP_CS_OVERRIDE; - /* Register hook to configure CTRLR0 */ - dwsmmio->dws.update_cr0 = dw_spi_update_cr0; - return 0; } static int dw_spi_dw_apb_init(struct platform_device *pdev, struct dw_spi_mmio *dwsmmio) { - /* Register hook to configure CTRLR0 */ - dwsmmio->dws.update_cr0 = dw_spi_update_cr0; - dw_spi_dma_setup_generic(&dwsmmio->dws); return 0; @@ -219,8 +207,7 @@ static int dw_spi_dw_apb_init(struct platform_device *pdev, static int dw_spi_dwc_ssi_init(struct platform_device *pdev, struct dw_spi_mmio *dwsmmio) { - /* Register hook to configure CTRLR0 */ - dwsmmio->dws.update_cr0 = dw_spi_update_cr0_v1_01a; + dwsmmio->dws.caps = DW_SPI_CAP_DWC_SSI; dw_spi_dma_setup_generic(&dwsmmio->dws); @@ -230,10 +217,7 @@ static int dw_spi_dwc_ssi_init(struct platform_device *pdev, static int dw_spi_keembay_init(struct platform_device *pdev, struct dw_spi_mmio *dwsmmio) { - dwsmmio->dws.caps = DW_SPI_CAP_KEEMBAY_MST; - - /* Register hook to configure CTRLR0 */ - dwsmmio->dws.update_cr0 = dw_spi_update_cr0_v1_01a; + dwsmmio->dws.caps = DW_SPI_CAP_KEEMBAY_MST | DW_SPI_CAP_DWC_SSI; return 0; } diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 271839a8add0..8a91cd58102f 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -48,9 +48,6 @@ static int spi_mid_init(struct dw_spi *dws) iounmap(clk_reg); - /* Register hook to configure CTRLR0 */ - dws->update_cr0 = dw_spi_update_cr0; - dw_spi_dma_setup_mfld(dws); return 0; @@ -58,9 +55,6 @@ static int spi_mid_init(struct dw_spi *dws) static int spi_generic_init(struct dw_spi *dws) { - /* Register hook to configure CTRLR0 */ - dws->update_cr0 = dw_spi_update_cr0; - dw_spi_dma_setup_generic(dws); return 0; diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index da9b543322c9..c02351cf2f99 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -109,6 +109,7 @@ enum dw_ssi_type { /* DW SPI capabilities */ #define DW_SPI_CAP_CS_OVERRIDE BIT(0) #define DW_SPI_CAP_KEEMBAY_MST BIT(1) +#define DW_SPI_CAP_DWC_SSI BIT(2) struct dw_spi; struct dw_spi_dma_ops { @@ -136,8 +137,6 @@ struct dw_spi { u16 bus_num; u16 num_cs; /* supported slave numbers */ void (*set_cs)(struct spi_device *spi, bool enable); - u32 (*update_cr0)(struct spi_controller *master, struct spi_device *spi, - struct spi_transfer *transfer); /* Current message transfer state info */ size_t len; @@ -254,12 +253,6 @@ extern int dw_spi_add_host(struct device *dev, struct dw_spi *dws); extern void dw_spi_remove_host(struct dw_spi *dws); extern int dw_spi_suspend_host(struct dw_spi *dws); extern int dw_spi_resume_host(struct dw_spi *dws); -extern u32 dw_spi_update_cr0(struct spi_controller *master, - struct spi_device *spi, - struct spi_transfer *transfer); -extern u32 dw_spi_update_cr0_v1_01a(struct spi_controller *master, - struct spi_device *spi, - struct spi_transfer *transfer); #ifdef CONFIG_SPI_DW_DMA From patchwork Wed Oct 7 23:54:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 268417 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=-9.8 required=3.0 tests=BAYES_00, 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 E1AC7C433E7 for ; Wed, 7 Oct 2020 23:55:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B441220714 for ; Wed, 7 Oct 2020 23:55:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728304AbgJGXz3 (ORCPT ); Wed, 7 Oct 2020 19:55:29 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45740 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728413AbgJGXz2 (ORCPT ); Wed, 7 Oct 2020 19:55:28 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 4D85E803202B; Wed, 7 Oct 2020 23:55:21 +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 CyI8ydeZGgvZ; Thu, 8 Oct 2020 02:55:20 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , Rob Herring , , , Subject: [PATCH v4 06/21] spi: dw: Update Rx sample delay in the config function Date: Thu, 8 Oct 2020 02:54:55 +0300 Message-ID: <20201007235511.4935-7-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org Rx sample delay can be SPI device specific, and should be synchronously initialized with the rest of the communication and peripheral device related controller setups. So let's move the Rx-sample delay setup into the DW APB SSI configuration update method. Signed-off-by: Serge Semin --- drivers/spi/spi-dw-core.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index cc341080d1a4..12080ea2ad84 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -294,13 +294,18 @@ static void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, spi_set_clk(dws, clk_div); dws->current_freq = speed_hz; } + + /* Update RX sample delay if required */ + if (dws->cur_rx_sample_dly != chip->rx_sample_dly) { + dw_writel(dws, DW_SPI_RX_SAMPLE_DLY, chip->rx_sample_dly); + dws->cur_rx_sample_dly = chip->rx_sample_dly; + } } static int dw_spi_transfer_one(struct spi_controller *master, struct spi_device *spi, struct spi_transfer *transfer) { struct dw_spi *dws = spi_controller_get_devdata(master); - struct chip_data *chip = spi_get_ctldata(spi); u8 imask = 0; u16 txlevel = 0; int ret; @@ -326,12 +331,6 @@ static int dw_spi_transfer_one(struct spi_controller *master, if (master->can_dma && master->can_dma(master, spi, transfer)) dws->dma_mapped = master->cur_msg_mapped; - /* Update RX sample delay if required */ - if (dws->cur_rx_sample_dly != chip->rx_sample_dly) { - dw_writel(dws, DW_SPI_RX_SAMPLE_DLY, chip->rx_sample_dly); - dws->cur_rx_sample_dly = chip->rx_sample_dly; - } - /* For poll mode just disable all interrupts */ spi_mask_intr(dws, 0xff); From patchwork Wed Oct 7 23:54:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 268410 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=-9.8 required=3.0 tests=BAYES_00, 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 27DCDC433E7 for ; Wed, 7 Oct 2020 23:56:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DB03A206E7 for ; Wed, 7 Oct 2020 23:56:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729003AbgJGX4d (ORCPT ); Wed, 7 Oct 2020 19:56:33 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45760 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728480AbgJGXza (ORCPT ); Wed, 7 Oct 2020 19:55:30 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 314F480305E2; Wed, 7 Oct 2020 23:55:22 +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 sEVfmK9HCbR4; Thu, 8 Oct 2020 02:55:21 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , Rob Herring , , , Subject: [PATCH v4 07/21] spi: dw: Add DW SPI controller config structure Date: Thu, 8 Oct 2020 02:54:56 +0300 Message-ID: <20201007235511.4935-8-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org DW APB SSI controller can be used by the two SPI core interfaces: traditional SPI transfers and SPI memory operations. The controller needs to be accordingly configured at runtime when the corresponding operations are executed. In order to do that for the both interfaces from a single function we introduce a new data wrapper for the transfer mode, data width, number of data frames (for the automatic data transfer) and the bus frequency. It will be used by the update_config() method to tune the DW APB SSI up. The update_config() method is made exported to be used not only by the DW SPI core driver, but by the glue layer drivers too. This will be required in a coming further commit. Signed-off-by: Serge Semin --- drivers/spi/spi-dw-core.c | 29 +++++++++++++++++------------ drivers/spi/spi-dw.h | 10 ++++++++++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 12080ea2ad84..01ab743bf177 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -20,10 +20,8 @@ #include #endif -/* Slave spi_dev related */ +/* Slave spi_device related */ struct chip_data { - u8 tmode; /* TR/TO/RO/EEPROM */ - u32 cr0; u32 rx_sample_dly; /* RX sample delay */ }; @@ -266,8 +264,8 @@ static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) return cr0; } -static void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, - struct spi_transfer *transfer) +void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, + struct dw_spi_cfg *cfg) { struct chip_data *chip = spi_get_ctldata(spi); u32 cr0 = chip->cr0; @@ -275,19 +273,22 @@ static void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, u16 clk_div; /* CTRLR0[ 4/3: 0] Data Frame Size */ - cr0 |= (transfer->bits_per_word - 1); + cr0 |= (cfg->dfs - 1); if (!(dws->caps & DW_SPI_CAP_DWC_SSI)) /* CTRLR0[ 9:8] Transfer Mode */ - cr0 |= chip->tmode << SPI_TMOD_OFFSET; + cr0 |= cfg->tmode << SPI_TMOD_OFFSET; else /* CTRLR0[11:10] Transfer Mode */ - cr0 |= chip->tmode << DWC_SSI_CTRLR0_TMOD_OFFSET; + cr0 |= cfg->tmode << DWC_SSI_CTRLR0_TMOD_OFFSET; dw_writel(dws, DW_SPI_CTRLR0, cr0); + if (cfg->tmode == SPI_TMOD_EPROMREAD || cfg->tmode == SPI_TMOD_RO) + dw_writel(dws, DW_SPI_CTRLR1, cfg->ndf ? cfg->ndf - 1 : 0); + /* Note DW APB SSI clock divider doesn't support odd numbers */ - clk_div = (DIV_ROUND_UP(dws->max_freq, transfer->speed_hz) + 1) & 0xfffe; + clk_div = (DIV_ROUND_UP(dws->max_freq, cfg->freq) + 1) & 0xfffe; speed_hz = dws->max_freq / clk_div; if (dws->current_freq != speed_hz) { @@ -301,11 +302,17 @@ static void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, dws->cur_rx_sample_dly = chip->rx_sample_dly; } } +EXPORT_SYMBOL_GPL(dw_spi_update_config); static int dw_spi_transfer_one(struct spi_controller *master, struct spi_device *spi, struct spi_transfer *transfer) { struct dw_spi *dws = spi_controller_get_devdata(master); + struct dw_spi_cfg cfg = { + .tmode = SPI_TMOD_TR, + .dfs = transfer->bits_per_word, + .freq = transfer->speed_hz, + }; u8 imask = 0; u16 txlevel = 0; int ret; @@ -323,7 +330,7 @@ static int dw_spi_transfer_one(struct spi_controller *master, spi_enable_chip(dws, 0); - dw_spi_update_config(dws, spi, transfer); + dw_spi_update_config(dws, spi, &cfg); transfer->effective_speed_hz = dws->current_freq; @@ -409,8 +416,6 @@ static int dw_spi_setup(struct spi_device *spi) */ chip->cr0 = dw_spi_prepare_cr0(dws, spi); - chip->tmode = SPI_TMOD_TR; - return 0; } diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index c02351cf2f99..2a2346438564 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -111,6 +111,14 @@ enum dw_ssi_type { #define DW_SPI_CAP_KEEMBAY_MST BIT(1) #define DW_SPI_CAP_DWC_SSI BIT(2) +/* Slave spi_transfer/spi_mem_op related */ +struct dw_spi_cfg { + u8 tmode; + u8 dfs; + u32 ndf; + u32 freq; +}; + struct dw_spi; struct dw_spi_dma_ops { int (*dma_init)(struct device *dev, struct dw_spi *dws); @@ -249,6 +257,8 @@ static inline void spi_shutdown_chip(struct dw_spi *dws) } extern void dw_spi_set_cs(struct spi_device *spi, bool enable); +extern void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, + struct dw_spi_cfg *cfg); extern int dw_spi_add_host(struct device *dev, struct dw_spi *dws); extern void dw_spi_remove_host(struct dw_spi *dws); extern int dw_spi_suspend_host(struct dw_spi *dws); From patchwork Wed Oct 7 23:54:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 268411 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=-9.8 required=3.0 tests=BAYES_00, 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 8EA81C4727F for ; Wed, 7 Oct 2020 23:56:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 614AF206E7 for ; Wed, 7 Oct 2020 23:56:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729004AbgJGX4R (ORCPT ); Wed, 7 Oct 2020 19:56:17 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45762 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728487AbgJGXzb (ORCPT ); Wed, 7 Oct 2020 19:55:31 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id D6FE0803202C; Wed, 7 Oct 2020 23:55:22 +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 foGjbNl7viMh; Thu, 8 Oct 2020 02:55:22 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , Rob Herring , , , Subject: [PATCH v4 08/21] spi: dw: Refactor data IO procedure Date: Thu, 8 Oct 2020 02:54:57 +0300 Message-ID: <20201007235511.4935-9-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org The Tx and Rx data write/read procedure can be significantly simplified by using Tx/Rx transfer lengths instead of the end pointers. By having the Tx/Rx data leftover lengths (in the number of transfer words) we can get rid of all subtraction and division operations utilized here and there in the tx_max(), rx_max(), dw_writer() and dw_reader() methods. Such modification will not only give us the more optimized IO procedures, but will make the data IO methods much more readable than before. Signed-off-by: Serge Semin --- drivers/spi/spi-dw-core.c | 37 +++++++++++++++++-------------------- drivers/spi/spi-dw.h | 5 ++--- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 01ab743bf177..3bb8aa3cba2b 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -108,9 +108,8 @@ EXPORT_SYMBOL_GPL(dw_spi_set_cs); /* Return the max entries we can fill into tx fifo */ static inline u32 tx_max(struct dw_spi *dws) { - u32 tx_left, tx_room, rxtx_gap; + u32 tx_room, rxtx_gap; - tx_left = (dws->tx_end - dws->tx) / dws->n_bytes; tx_room = dws->fifo_len - dw_readl(dws, DW_SPI_TXFLR); /* @@ -121,18 +120,15 @@ static inline u32 tx_max(struct dw_spi *dws) * shift registers. So a control from sw point of * view is taken. */ - rxtx_gap = ((dws->rx_end - dws->rx) - (dws->tx_end - dws->tx)) - / dws->n_bytes; + rxtx_gap = dws->fifo_len - (dws->rx_len - dws->tx_len); - return min3(tx_left, tx_room, (u32) (dws->fifo_len - rxtx_gap)); + return min3((u32)dws->tx_len, tx_room, rxtx_gap); } /* Return the max entries we should read out of rx fifo */ static inline u32 rx_max(struct dw_spi *dws) { - u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes; - - return min_t(u32, rx_left, dw_readl(dws, DW_SPI_RXFLR)); + return min_t(u32, dws->rx_len, dw_readl(dws, DW_SPI_RXFLR)); } static void dw_writer(struct dw_spi *dws) @@ -141,15 +137,16 @@ static void dw_writer(struct dw_spi *dws) u16 txw = 0; while (max--) { - /* Set the tx word if the transfer's original "tx" is not null */ - if (dws->tx_end - dws->len) { + if (dws->tx) { if (dws->n_bytes == 1) txw = *(u8 *)(dws->tx); else txw = *(u16 *)(dws->tx); + + dws->tx += dws->n_bytes; } dw_write_io_reg(dws, DW_SPI_DR, txw); - dws->tx += dws->n_bytes; + --dws->tx_len; } } @@ -160,14 +157,15 @@ static void dw_reader(struct dw_spi *dws) while (max--) { rxw = dw_read_io_reg(dws, DW_SPI_DR); - /* Care rx only if the transfer's original "rx" is not null */ - if (dws->rx_end - dws->len) { + if (dws->rx) { if (dws->n_bytes == 1) *(u8 *)(dws->rx) = rxw; else *(u16 *)(dws->rx) = rxw; + + dws->rx += dws->n_bytes; } - dws->rx += dws->n_bytes; + --dws->rx_len; } } @@ -192,7 +190,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) } dw_reader(dws); - if (dws->rx_end == dws->rx) { + if (!dws->rx_len) { spi_mask_intr(dws, 0xff); spi_finalize_current_transfer(dws->master); return IRQ_HANDLED; @@ -320,12 +318,11 @@ static int dw_spi_transfer_one(struct spi_controller *master, dws->dma_mapped = 0; dws->n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE); dws->tx = (void *)transfer->tx_buf; - dws->tx_end = dws->tx + transfer->len; + dws->tx_len = transfer->len / dws->n_bytes; dws->rx = transfer->rx_buf; - dws->rx_end = dws->rx + transfer->len; - dws->len = transfer->len; + dws->rx_len = dws->tx_len; - /* Ensure dw->rx and dw->rx_end are visible */ + /* Ensure the data above is visible for all CPUs */ smp_mb(); spi_enable_chip(dws, 0); @@ -352,7 +349,7 @@ static int dw_spi_transfer_one(struct spi_controller *master, return ret; } } else { - txlevel = min_t(u16, dws->fifo_len / 2, dws->len / dws->n_bytes); + txlevel = min_t(u16, dws->fifo_len / 2, dws->tx_len); dw_writel(dws, DW_SPI_TXFTLR, txlevel); /* Set the interrupt mask */ diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 2a2346438564..cfc9f63acde4 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -147,11 +147,10 @@ struct dw_spi { void (*set_cs)(struct spi_device *spi, bool enable); /* Current message transfer state info */ - size_t len; void *tx; - void *tx_end; + unsigned int tx_len; void *rx; - void *rx_end; + unsigned int rx_len; int dma_mapped; u8 n_bytes; /* current is a 1/2 bytes op */ irqreturn_t (*transfer_handler)(struct dw_spi *dws); From patchwork Wed Oct 7 23:55:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 268409 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=-9.8 required=3.0 tests=BAYES_00, 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 5CEBBC4363D for ; Wed, 7 Oct 2020 23:56:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 17EAC206FC for ; Wed, 7 Oct 2020 23:56:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728965AbgJGX4b (ORCPT ); Wed, 7 Oct 2020 19:56:31 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45790 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728557AbgJGXzb (ORCPT ); Wed, 7 Oct 2020 19:55:31 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 16A3B803202F; Wed, 7 Oct 2020 23:55:25 +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 AAQD5BvU9WRQ; Thu, 8 Oct 2020 02:55:24 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , Rob Herring , , , Subject: [PATCH v4 12/21] spi: dw: Discard chip enabling on DMA setup error Date: Thu, 8 Oct 2020 02:55:01 +0300 Message-ID: <20201007235511.4935-13-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org It's pointless to enable the chip back if the DMA setup procedure fails, since we'll disable it on the next transfer anyway. For the same reason We don't do that in case of a failure detected in any other methods called from the transfer_one() method. While at it consider any non-zero value returned from the dma_setup callback to be erroneous as it's supposed to be in the kernel. Signed-off-by: Serge Semin --- drivers/spi/spi-dw-core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 89e5428c8de6..ac87ff6d8be4 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -372,10 +372,8 @@ static int dw_spi_transfer_one(struct spi_controller *master, if (dws->dma_mapped) { ret = dws->dma_ops->dma_setup(dws, transfer); - if (ret < 0) { - spi_enable_chip(dws, 1); + if (ret) return ret; - } } spi_enable_chip(dws, 1); From patchwork Wed Oct 7 23:55: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: 268415 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=-9.8 required=3.0 tests=BAYES_00, 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 4A8C2C433E7 for ; Wed, 7 Oct 2020 23:55:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 13211206E7 for ; Wed, 7 Oct 2020 23:55:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728972AbgJGXzj (ORCPT ); Wed, 7 Oct 2020 19:55:39 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45794 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728561AbgJGXzc (ORCPT ); Wed, 7 Oct 2020 19:55:32 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id BBF698001383; Wed, 7 Oct 2020 23:55:25 +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 8nk12loQyQ0V; Thu, 8 Oct 2020 02:55:25 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , Rob Herring , , , Subject: [PATCH v4 13/21] spi: dw: De-assert chip-select on reset Date: Thu, 8 Oct 2020 02:55:02 +0300 Message-ID: <20201007235511.4935-14-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org SPI memory operations implementation will require to have the CS register cleared before executing the operation in order not to have the transmission automatically started prior the Tx FIFO is pre-initialized. Let's clear the register then on explicit controller reset to fulfil the requirements in case of an error or having the CS left set by a bootloader or another software. Signed-off-by: Serge Semin --- drivers/spi/spi-dw.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index cfc9f63acde4..eb1d46983319 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -237,15 +237,16 @@ static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) } /* - * This disables the SPI controller, interrupts, clears the interrupts status, - * and re-enable the controller back. Transmit and receive FIFO buffers are - * cleared when the device is disabled. + * This disables the SPI controller, interrupts, clears the interrupts status + * and CS, then re-enables the controller back. Transmit and receive FIFO + * buffers are cleared when the device is disabled. */ static inline void spi_reset_chip(struct dw_spi *dws) { spi_enable_chip(dws, 0); spi_mask_intr(dws, 0xff); dw_readl(dws, DW_SPI_ICR); + dw_writel(dws, DW_SPI_SER, 0); spi_enable_chip(dws, 1); } From patchwork Wed Oct 7 23:55: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: 268413 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=-9.8 required=3.0 tests=BAYES_00, 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 DF1B6C433E7 for ; Wed, 7 Oct 2020 23:56:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ADCDC206E7 for ; Wed, 7 Oct 2020 23:56:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729046AbgJGX4D (ORCPT ); Wed, 7 Oct 2020 19:56:03 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45796 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728560AbgJGXzb (ORCPT ); Wed, 7 Oct 2020 19:55:31 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 4D63B800163F; Wed, 7 Oct 2020 23:55:26 +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 BAhrQjsZVbhc; Thu, 8 Oct 2020 02:55:25 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , Rob Herring , , , Subject: [PATCH v4 14/21] spi: dw: Explicitly de-assert CS on SPI transfer completion Date: Thu, 8 Oct 2020 02:55:03 +0300 Message-ID: <20201007235511.4935-15-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org By design of the currently available native set_cs callback, the CS de-assertion will be done only if it's required by the corresponding controller capability. But in order to pre-fill the Tx FIFO buffer with data during the SPI memory ops execution the SER register needs to be left cleared before that. We'll also need a way to explicitly set and clear the corresponding CS bit at a certain moment of the operation. Let's alter the set_cs function then to also de-activate the CS, when it's required. Signed-off-by: Serge Semin --- drivers/spi/spi-dw-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index ac87ff6d8be4..76e323db170f 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -100,7 +100,7 @@ void dw_spi_set_cs(struct spi_device *spi, bool enable) */ if (cs_high == enable) dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select)); - else if (dws->caps & DW_SPI_CAP_CS_OVERRIDE) + else dw_writel(dws, DW_SPI_SER, 0); } EXPORT_SYMBOL_GPL(dw_spi_set_cs); From patchwork Wed Oct 7 23:55: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: 268414 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=-9.8 required=3.0 tests=BAYES_00, 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 4EAEEC4727E for ; Wed, 7 Oct 2020 23:55:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 076D5206E7 for ; Wed, 7 Oct 2020 23:55:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729021AbgJGXzx (ORCPT ); Wed, 7 Oct 2020 19:55:53 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45738 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728623AbgJGXzf (ORCPT ); Wed, 7 Oct 2020 19:55:35 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 0243B8001384; Wed, 7 Oct 2020 23:55:27 +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 3XdHdVVkwj3d; Thu, 8 Oct 2020 02:55:26 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , Rob Herring , , , Subject: [PATCH v4 15/21] spi: dw: Move num-of retries parameter to the header file Date: Thu, 8 Oct 2020 02:55:04 +0300 Message-ID: <20201007235511.4935-16-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org The parameter will be needed for another wait-done method being added in the framework of the SPI memory operation modification in a further commit. Signed-off-by: Serge Semin --- drivers/spi/spi-dw-dma.c | 5 ++--- drivers/spi/spi-dw.h | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c index bb390ff67d1d..9db119dc5554 100644 --- a/drivers/spi/spi-dw-dma.c +++ b/drivers/spi/spi-dw-dma.c @@ -17,7 +17,6 @@ #include "spi-dw.h" -#define WAIT_RETRIES 5 #define RX_BUSY 0 #define RX_BURST_LEVEL 16 #define TX_BUSY 1 @@ -208,7 +207,7 @@ static inline bool dw_spi_dma_tx_busy(struct dw_spi *dws) static int dw_spi_dma_wait_tx_done(struct dw_spi *dws, struct spi_transfer *xfer) { - int retry = WAIT_RETRIES; + int retry = SPI_WAIT_RETRIES; struct spi_delay delay; u32 nents; @@ -283,7 +282,7 @@ static inline bool dw_spi_dma_rx_busy(struct dw_spi *dws) static int dw_spi_dma_wait_rx_done(struct dw_spi *dws) { - int retry = WAIT_RETRIES; + int retry = SPI_WAIT_RETRIES; struct spi_delay delay; unsigned long ns, us; u32 nents; diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index eb1d46983319..946065201c9c 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -100,6 +100,8 @@ #define SPI_DMA_RDMAE (1 << 0) #define SPI_DMA_TDMAE (1 << 1) +#define SPI_WAIT_RETRIES 5 + enum dw_ssi_type { SSI_MOTO_SPI = 0, SSI_TI_SSP, From patchwork Wed Oct 7 23:55:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 268416 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=-9.8 required=3.0 tests=BAYES_00, 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 417EBC47423 for ; Wed, 7 Oct 2020 23:55:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E86C9206E7 for ; Wed, 7 Oct 2020 23:55:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728976AbgJGXzj (ORCPT ); Wed, 7 Oct 2020 19:55:39 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45878 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728951AbgJGXzg (ORCPT ); Wed, 7 Oct 2020 19:55:36 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 478AF803086A; Wed, 7 Oct 2020 23:55:29 +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 g6s_lKlK-klo; Thu, 8 Oct 2020 02:55:28 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , Rob Herring , , , Subject: [PATCH v4 18/21] spi: dw: Introduce max mem-ops SPI bus frequency setting Date: Thu, 8 Oct 2020 02:55:07 +0300 Message-ID: <20201007235511.4935-19-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org In some circumstances the current implementation of the SPI memory operations may occasionally fail even though they are executed in the atomic context. This may happen if the system bus is relatively slow in comparison to the SPI bus frequency, or there is a concurrent access to it, which makes the MMIO-operations occasionally stalling before push-pulling data from the DW APB SPI FIFOs. These two problems we've discovered on the Baikal-T1 SoC. In order to fix them we have no choice but to set an artificial limitation on the SPI bus speed. Note currently this limitation will be only applicable for the memory operations, since the standard SPI core interface is implemented with an assumption that there is no problem with the automatic CS toggling. Signed-off-by: Serge Semin --- drivers/spi/spi-dw-core.c | 4 +++- drivers/spi/spi-dw.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 8eb3b31b376d..bcfa224e0e43 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -629,7 +629,7 @@ static int dw_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) * operation. Transmit-only mode is suitable for the rest of them. */ cfg.dfs = 8; - cfg.freq = mem->spi->max_speed_hz; + cfg.freq = clamp(mem->spi->max_speed_hz, 0U, dws->max_mem_freq); if (op->data.dir == SPI_MEM_DATA_IN) { cfg.tmode = SPI_TMOD_EPROMREAD; cfg.ndf = op->data.nbytes; @@ -717,6 +717,8 @@ static void dw_spi_init_mem_ops(struct dw_spi *dws) dws->mem_ops.adjust_op_size = dw_spi_adjust_mem_op_size; dws->mem_ops.supports_op = dw_spi_supports_mem_op; dws->mem_ops.exec_op = dw_spi_exec_mem_op; + if (!dws->max_mem_freq) + dws->max_mem_freq = dws->max_freq; } } diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 4b08fe34a85d..dc5781236cc6 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -148,6 +148,7 @@ struct dw_spi { unsigned long paddr; int irq; u32 fifo_len; /* depth of the FIFO buffer */ + u32 max_mem_freq; /* max mem-ops bus freq */ u32 max_freq; /* max bus freq supported */ u32 caps; /* DW SPI capabilities */ From patchwork Wed Oct 7 23:55:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 268412 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=-9.8 required=3.0 tests=BAYES_00, 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 33992C433E7 for ; Wed, 7 Oct 2020 23:56:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EA96720714 for ; Wed, 7 Oct 2020 23:56:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727955AbgJGX4P (ORCPT ); Wed, 7 Oct 2020 19:56:15 -0400 Received: from mail.baikalelectronics.com ([87.245.175.226]:45780 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728971AbgJGXzm (ORCPT ); Wed, 7 Oct 2020 19:55:42 -0400 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 7C3A180023F6; Wed, 7 Oct 2020 23:55:30 +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 6299LsjrfWOj; Thu, 8 Oct 2020 02:55:29 +0300 (MSK) From: Serge Semin To: Mark Brown , Serge Semin , Rob Herring CC: Serge Semin , Alexey Malahov , Ramil Zaripov , Pavel Parkhomenko , Andy Shevchenko , Andy Shevchenko , Lars Povlsen , "wuxu . wu" , Feng Tang , , , , Rob Herring Subject: [PATCH v4 20/21] dt-bindings: spi: dw: Add Baikal-T1 SPI Controllers Date: Thu, 8 Oct 2020 02:55:09 +0300 Message-ID: <20201007235511.4935-21-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201007235511.4935-1-Sergey.Semin@baikalelectronics.ru> References: <20201007235511.4935-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: linux-spi@vger.kernel.org These controllers are based on the DW APB SSI IP-core and embedded into the SoC, so two of them are equipped with IRQ, DMA, 64 words FIFOs and 4 native CS, while another one as being utilized by the Baikal-T1 System Boot Controller has got a very limited resources: no IRQ, no DMA, only a single native chip-select and just 8 bytes Tx/Rx FIFOs available. That's why we have to mark the IRQ to be optional for the later interface. The SPI controller embedded into the Baikal-T1 System Boot Controller can be also used to directly access an external SPI flash by means of a dedicated FSM. The corresponding MMIO region availability is switchable by the embedded multiplexor, which phandle can be specified in the dts node. * We added a new example to test out the non-standard Baikal-T1 System Boot SPI Controller DT binding. Co-developed-by: Ramil Zaripov Signed-off-by: Ramil Zaripov Signed-off-by: Serge Semin Reviewed-by: Rob Herring --- .../bindings/spi/snps,dw-apb-ssi.yaml | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml index c62cbe79f00d..d6ae35777dac 100644 --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml @@ -22,6 +22,21 @@ allOf: properties: reg: minItems: 2 + - if: + properties: + compatible: + contains: + enum: + - baikal,bt1-sys-ssi + then: + properties: + mux-controls: + maxItems: 1 + required: + - mux-controls + else: + required: + - interrupts properties: compatible: @@ -44,12 +59,16 @@ properties: - const: snps,dw-apb-ssi - description: Intel Keem Bay SPI Controller const: intel,keembay-ssi + - description: Baikal-T1 SPI Controller + const: baikal,bt1-ssi + - description: Baikal-T1 System Boot SPI Controller + const: baikal,bt1-sys-ssi reg: minItems: 1 items: - description: DW APB SSI controller memory mapped registers - - description: SPI MST region map + - description: SPI MST region map or directly mapped SPI ROM interrupts: maxItems: 1 @@ -114,7 +133,6 @@ required: - reg - "#address-cells" - "#size-cells" - - interrupts - clocks examples: @@ -130,4 +148,15 @@ examples: cs-gpios = <&gpio0 13 0>, <&gpio0 14 0>; }; + - | + spi@1f040100 { + compatible = "baikal,bt1-sys-ssi"; + reg = <0x1f040100 0x900>, + <0x1c000000 0x1000000>; + #address-cells = <1>; + #size-cells = <0>; + mux-controls = <&boot_mux>; + clocks = <&ccu_sys>; + clock-names = "ssi_clk"; + }; ...