From patchwork Tue Dec 21 17:48:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 526780 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B1C5C4332F for ; Tue, 21 Dec 2021 17:48:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240570AbhLURsx (ORCPT ); Tue, 21 Dec 2021 12:48:53 -0500 Received: from relay12.mail.gandi.net ([217.70.178.232]:33383 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230248AbhLURsw (ORCPT ); Tue, 21 Dec 2021 12:48:52 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 8305C200006; Tue, 21 Dec 2021 17:48:50 +0000 (UTC) From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Mark Brown , , Julien Su , Jaime Liao , Boris Brezillon , Thomas Petazzoni , Xiangsheng Hou , Miquel Raynal Subject: [PATCH v8 02/14] spi: spi-mem: Introduce a capability structure Date: Tue, 21 Dec 2021 18:48:32 +0100 Message-Id: <20211221174844.56385-3-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211221174844.56385-1-miquel.raynal@bootlin.com> References: <20211221174844.56385-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Create a spi_controller_mem_caps structure and put it within the spi_controller_mem_ops structure as these are highly related. So far the only field in this structure is the support for dtr operations, but soon we will add another parameter. Also create a helper to parse the capabilities and check if the requested capability has been set or not. Signed-off-by: Miquel Raynal --- include/linux/spi/spi-mem.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 85e2ff7b840d..045ecb7c6f50 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -220,6 +220,17 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem) return mem->drvpriv; } +/** + * struct spi_controller_mem_caps - SPI memory controller capabilities + * @dtr: Supports DTR operations + */ +struct spi_controller_mem_caps { + bool dtr; +}; + +#define spi_mem_controller_is_capable(ctlr, cap) \ + ((ctlr)->mem_ops->caps && (ctlr)->mem_ops->caps->cap) \ + /** * struct spi_controller_mem_ops - SPI memory operations * @adjust_op_size: shrink the data xfer of an operation to match controller's @@ -253,6 +264,7 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem) * @poll_status: poll memory device status until (status & mask) == match or * when the timeout has expired. It fills the data buffer with * the last status value. + * @caps: controller capabilities for the handling of the above operations. * * This interface should be implemented by SPI controllers providing an * high-level interface to execute SPI memory operation, which is usually the @@ -283,6 +295,7 @@ struct spi_controller_mem_ops { unsigned long initial_delay_us, unsigned long polling_rate_us, unsigned long timeout_ms); + const struct spi_controller_mem_caps *caps; }; /** From patchwork Tue Dec 21 17:48:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 526779 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5F3FC433F5 for ; Tue, 21 Dec 2021 17:48:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240574AbhLURs4 (ORCPT ); Tue, 21 Dec 2021 12:48:56 -0500 Received: from relay12.mail.gandi.net ([217.70.178.232]:52427 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230248AbhLURsz (ORCPT ); Tue, 21 Dec 2021 12:48:55 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 78CD920000F; Tue, 21 Dec 2021 17:48:53 +0000 (UTC) From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Mark Brown , , Julien Su , Jaime Liao , Boris Brezillon , Thomas Petazzoni , Xiangsheng Hou , Miquel Raynal Subject: [PATCH v8 04/14] spi: cadence-quadspi: Provide a capability structure Date: Tue, 21 Dec 2021 18:48:34 +0100 Message-Id: <20211221174844.56385-5-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211221174844.56385-1-miquel.raynal@bootlin.com> References: <20211221174844.56385-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org This controller has DTR support, so advertize it with a capability now that the spi_controller_mem_ops structure contains this new field. This will later be used by the core to discriminate whether an operation is supported or not, in a more generic way than having different helpers. Signed-off-by: Miquel Raynal --- drivers/spi/spi-cadence-quadspi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 101cc71bffa7..98e0cc4236e3 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1388,10 +1388,15 @@ static const char *cqspi_get_name(struct spi_mem *mem) return devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), mem->spi->chip_select); } +static const struct spi_controller_mem_caps cqspi_mem_caps = { + .dtr = true, +}; + static const struct spi_controller_mem_ops cqspi_mem_ops = { .exec_op = cqspi_exec_mem_op, .get_name = cqspi_get_name, .supports_op = cqspi_supports_mem_op, + .caps = &cqspi_mem_caps, }; static int cqspi_setup_flash(struct cqspi_st *cqspi) From patchwork Tue Dec 21 17:48:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 526778 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A235C433F5 for ; Tue, 21 Dec 2021 17:48:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240577AbhLURs7 (ORCPT ); Tue, 21 Dec 2021 12:48:59 -0500 Received: from relay12.mail.gandi.net ([217.70.178.232]:49531 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230248AbhLURs6 (ORCPT ); Tue, 21 Dec 2021 12:48:58 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 8395E200012; Tue, 21 Dec 2021 17:48:56 +0000 (UTC) From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Mark Brown , , Julien Su , Jaime Liao , Boris Brezillon , Thomas Petazzoni , Xiangsheng Hou , Miquel Raynal Subject: [PATCH v8 06/14] spi: spi-mem: Kill the spi_mem_dtr_supports_op() helper Date: Tue, 21 Dec 2021 18:48:36 +0100 Message-Id: <20211221174844.56385-7-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211221174844.56385-1-miquel.raynal@bootlin.com> References: <20211221174844.56385-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Now that spi_mem_default_supports_op() has access to the static controller capabilities (related to memory operations), and now that these capabilities have been filled by the impacted controllers, there is no need for a specific helper checking only DTR operations, so let's just kill spi_mem_dtr_supports_op() and simply use spi_mem_default_supports_op() instead. Signed-off-by: Miquel Raynal Reviewed-by: Pratyush Yadav --- drivers/spi/spi-cadence-quadspi.c | 5 +---- drivers/spi/spi-mem.c | 20 -------------------- drivers/spi/spi-mxic.c | 10 +--------- include/linux/spi/spi-mem.h | 11 ----------- 4 files changed, 2 insertions(+), 44 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 98e0cc4236e3..bc6b33bce0bb 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1252,10 +1252,7 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem, if (!(all_true || all_false)) return false; - if (all_true) - return spi_mem_dtr_supports_op(mem, op); - else - return spi_mem_default_supports_op(mem, op); + return spi_mem_default_supports_op(mem, op); } static int cqspi_of_get_flash_pdata(struct platform_device *pdev, diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 83651cbc87f2..ccc606f741ae 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -160,26 +160,6 @@ static bool spi_mem_check_buswidth(struct spi_mem *mem, return true; } -bool spi_mem_dtr_supports_op(struct spi_mem *mem, - const struct spi_mem_op *op) -{ - if (op->cmd.buswidth == 8 && op->cmd.nbytes % 2) - return false; - - if (op->addr.nbytes && op->addr.buswidth == 8 && op->addr.nbytes % 2) - return false; - - if (op->dummy.nbytes && op->dummy.buswidth == 8 && op->dummy.nbytes % 2) - return false; - - if (op->data.dir != SPI_MEM_NO_DATA && - op->dummy.buswidth == 8 && op->data.nbytes % 2) - return false; - - return spi_mem_check_buswidth(mem, op); -} -EXPORT_SYMBOL_GPL(spi_mem_dtr_supports_op); - bool spi_mem_default_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index e137b1ec85d4..67d05ee8d6a0 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -335,8 +335,6 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, static bool mxic_spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { - bool all_false; - if (op->data.buswidth > 8 || op->addr.buswidth > 8 || op->dummy.buswidth > 8 || op->cmd.buswidth > 8) return false; @@ -348,13 +346,7 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem, if (op->addr.nbytes > 7) return false; - all_false = !op->cmd.dtr && !op->addr.dtr && !op->dummy.dtr && - !op->data.dtr; - - if (all_false) - return spi_mem_default_supports_op(mem, op); - else - return spi_mem_dtr_supports_op(mem, op); + return spi_mem_default_supports_op(mem, op); } static int mxic_spi_mem_exec_op(struct spi_mem *mem, diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 045ecb7c6f50..d7787c8f3746 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -332,10 +332,6 @@ void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, bool spi_mem_default_supports_op(struct spi_mem *mem, const struct spi_mem_op *op); - -bool spi_mem_dtr_supports_op(struct spi_mem *mem, - const struct spi_mem_op *op); - #else static inline int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr, @@ -358,13 +354,6 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, { return false; } - -static inline -bool spi_mem_dtr_supports_op(struct spi_mem *mem, - const struct spi_mem_op *op) -{ - return false; -} #endif /* CONFIG_SPI_MEM */ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op); From patchwork Tue Dec 21 17:48:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 526777 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CB7EC433EF for ; Tue, 21 Dec 2021 17:49:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240580AbhLURtC (ORCPT ); Tue, 21 Dec 2021 12:49:02 -0500 Received: from relay12.mail.gandi.net ([217.70.178.232]:46859 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230248AbhLURtB (ORCPT ); Tue, 21 Dec 2021 12:49:01 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 5DB6C20000D; Tue, 21 Dec 2021 17:48:59 +0000 (UTC) From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Mark Brown , , Julien Su , Jaime Liao , Boris Brezillon , Thomas Petazzoni , Xiangsheng Hou , Miquel Raynal Subject: [PATCH v8 08/14] mtd: spinand: Delay a little bit the dirmap creation Date: Tue, 21 Dec 2021 18:48:38 +0100 Message-Id: <20211221174844.56385-9-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211221174844.56385-1-miquel.raynal@bootlin.com> References: <20211221174844.56385-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org As we will soon tweak the dirmap creation to act a little bit differently depending on the picked ECC engine, we need to initialize dirmaps after ECC engines. This should not have any effect as dirmaps are not yet used at this point. Signed-off-by: Miquel Raynal --- drivers/mtd/nand/spi/core.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 7027c09925e2..715cad26fdef 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1209,14 +1209,6 @@ static int spinand_init(struct spinand_device *spinand) if (ret) goto err_free_bufs; - ret = spinand_create_dirmaps(spinand); - if (ret) { - dev_err(dev, - "Failed to create direct mappings for read/write operations (err = %d)\n", - ret); - goto err_manuf_cleanup; - } - ret = nanddev_init(nand, &spinand_ops, THIS_MODULE); if (ret) goto err_manuf_cleanup; @@ -1251,6 +1243,14 @@ static int spinand_init(struct spinand_device *spinand) mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength; mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size; + ret = spinand_create_dirmaps(spinand); + if (ret) { + dev_err(dev, + "Failed to create direct mappings for read/write operations (err = %d)\n", + ret); + goto err_cleanup_ecc_engine; + } + return 0; err_cleanup_ecc_engine: From patchwork Tue Dec 21 17:48:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 526776 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B97F0C433FE for ; Tue, 21 Dec 2021 17:49:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240581AbhLURtF (ORCPT ); Tue, 21 Dec 2021 12:49:05 -0500 Received: from relay12.mail.gandi.net ([217.70.178.232]:37459 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230248AbhLURtF (ORCPT ); Tue, 21 Dec 2021 12:49:05 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 898BB200003; Tue, 21 Dec 2021 17:49:02 +0000 (UTC) From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Mark Brown , , Julien Su , Jaime Liao , Boris Brezillon , Thomas Petazzoni , Xiangsheng Hou , Miquel Raynal , stable@vger.kernel.org, Mason Yang , Zhengxun Li Subject: [PATCH v8 10/14] spi: mxic: Fix the transmit path Date: Tue, 21 Dec 2021 18:48:40 +0100 Message-Id: <20211221174844.56385-11-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211221174844.56385-1-miquel.raynal@bootlin.com> References: <20211221174844.56385-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org By working with external hardware ECC engines, we figured out that Under certain circumstances, it is needed for the SPI controller to check INT_TX_EMPTY and INT_RX_NOT_EMPTY in both receive and transmit path (not only in the receive path). The delay penalty being negligible, move this code in the common path. Fixes: b942d80b0a39 ("spi: Add MXIC controller driver") Cc: stable@vger.kernel.org Suggested-by: Mason Yang Signed-off-by: Miquel Raynal Reviewed-by: Zhengxun Li Reviewed-by: Mark Brown --- drivers/spi/spi-mxic.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index 67d05ee8d6a0..aedc9a144b82 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -304,25 +304,21 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, writel(data, mxic->regs + TXD(nbytes % 4)); + ret = readl_poll_timeout(mxic->regs + INT_STS, sts, + sts & INT_TX_EMPTY, 0, USEC_PER_SEC); + if (ret) + return ret; + + ret = readl_poll_timeout(mxic->regs + INT_STS, sts, + sts & INT_RX_NOT_EMPTY, 0, + USEC_PER_SEC); + if (ret) + return ret; + + data = readl(mxic->regs + RXD); if (rxbuf) { - ret = readl_poll_timeout(mxic->regs + INT_STS, sts, - sts & INT_TX_EMPTY, 0, - USEC_PER_SEC); - if (ret) - return ret; - - ret = readl_poll_timeout(mxic->regs + INT_STS, sts, - sts & INT_RX_NOT_EMPTY, 0, - USEC_PER_SEC); - if (ret) - return ret; - - data = readl(mxic->regs + RXD); data >>= (8 * (4 - nbytes)); memcpy(rxbuf + pos, &data, nbytes); - WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY); - } else { - readl(mxic->regs + RXD); } WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY); From patchwork Tue Dec 21 17:48:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 526775 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D2527C433FE for ; Tue, 21 Dec 2021 17:49:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240583AbhLURtI (ORCPT ); Tue, 21 Dec 2021 12:49:08 -0500 Received: from relay12.mail.gandi.net ([217.70.178.232]:34869 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230248AbhLURtI (ORCPT ); Tue, 21 Dec 2021 12:49:08 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id E277620000D; Tue, 21 Dec 2021 17:49:05 +0000 (UTC) From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Mark Brown , , Julien Su , Jaime Liao , Boris Brezillon , Thomas Petazzoni , Xiangsheng Hou , Miquel Raynal Subject: [PATCH v8 12/14] spi: mxic: Create a helper to ease the start of an operation Date: Tue, 21 Dec 2021 18:48:42 +0100 Message-Id: <20211221174844.56385-13-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211221174844.56385-1-miquel.raynal@bootlin.com> References: <20211221174844.56385-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Create the mxic_spi_mem_prep_op_cfg() helper to provide the content to write to the register controlling the next IO command. This helper will soon be used by the dirmap implementation and having this code factorized out earlier will clarify this addition. Signed-off-by: Miquel Raynal Reviewed-by: Mark Brown --- drivers/spi/spi-mxic.c | 53 +++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index 7d0ec223622a..52fe1060d940 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -296,6 +296,33 @@ static u32 mxic_spi_prep_hc_cfg(struct spi_device *spi, u32 flags) HC_CFG_SLV_ACT(spi->chip_select) | HC_CFG_IDLE_SIO_LVL(1); } +static u32 mxic_spi_mem_prep_op_cfg(const struct spi_mem_op *op) +{ + u32 cfg = OP_CMD_BYTES(op->cmd.nbytes) | + OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) | + (op->cmd.dtr ? OP_CMD_DDR : 0); + + if (op->addr.nbytes) + cfg |= OP_ADDR_BYTES(op->addr.nbytes) | + OP_ADDR_BUSW(fls(op->addr.buswidth) - 1) | + (op->addr.dtr ? OP_ADDR_DDR : 0); + + if (op->dummy.nbytes) + cfg |= OP_DUMMY_CYC(op->dummy.nbytes); + + if (op->data.nbytes) { + cfg |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) | + (op->data.dtr ? OP_DATA_DDR : 0); + if (op->data.dir == SPI_MEM_DATA_IN) { + cfg |= OP_READ; + if (op->data.dtr) + cfg |= OP_DQS_EN; + } + } + + return cfg; +} + static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf, void *rxbuf, unsigned int len) { @@ -366,7 +393,6 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, { struct mxic_spi *mxic = spi_master_get_devdata(mem->spi->master); int i, ret; - u32 ss_ctrl; u8 addr[8], cmd[2]; ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz); @@ -378,29 +404,8 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, writel(HC_EN_BIT, mxic->regs + HC_EN); - ss_ctrl = OP_CMD_BYTES(op->cmd.nbytes) | - OP_CMD_BUSW(fls(op->cmd.buswidth) - 1) | - (op->cmd.dtr ? OP_CMD_DDR : 0); - - if (op->addr.nbytes) - ss_ctrl |= OP_ADDR_BYTES(op->addr.nbytes) | - OP_ADDR_BUSW(fls(op->addr.buswidth) - 1) | - (op->addr.dtr ? OP_ADDR_DDR : 0); - - if (op->dummy.nbytes) - ss_ctrl |= OP_DUMMY_CYC(op->dummy.nbytes); - - if (op->data.nbytes) { - ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1) | - (op->data.dtr ? OP_DATA_DDR : 0); - if (op->data.dir == SPI_MEM_DATA_IN) { - ss_ctrl |= OP_READ; - if (op->data.dtr) - ss_ctrl |= OP_DQS_EN; - } - } - - writel(ss_ctrl, mxic->regs + SS_CTRL(mem->spi->chip_select)); + writel(mxic_spi_mem_prep_op_cfg(op), + mxic->regs + SS_CTRL(mem->spi->chip_select)); writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT, mxic->regs + HC_CFG); From patchwork Tue Dec 21 17:48:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 526774 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06B8CC433FE for ; Tue, 21 Dec 2021 17:49:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240586AbhLURtL (ORCPT ); Tue, 21 Dec 2021 12:49:11 -0500 Received: from relay12.mail.gandi.net ([217.70.178.232]:37071 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230248AbhLURtL (ORCPT ); Tue, 21 Dec 2021 12:49:11 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 02322200003; Tue, 21 Dec 2021 17:49:08 +0000 (UTC) From: Miquel Raynal To: Richard Weinberger , Vignesh Raghavendra , Tudor Ambarus , Pratyush Yadav , Michael Walle , Cc: Mark Brown , , Julien Su , Jaime Liao , Boris Brezillon , Thomas Petazzoni , Xiangsheng Hou , Miquel Raynal Subject: [PATCH v8 14/14] spi: mxic: Add support for pipelined ECC operations Date: Tue, 21 Dec 2021 18:48:44 +0100 Message-Id: <20211221174844.56385-15-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211221174844.56385-1-miquel.raynal@bootlin.com> References: <20211221174844.56385-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Some SPI-NAND chips do not have a proper on-die ECC engine providing error correction/detection. This is particularly an issue on embedded devices with limited resources because all the computations must happen in software, unless an external hardware engine is provided. These external engines are new and can be of two categories: external or pipelined. Macronix is providing both, the former being already supported. The second, however, is very SoC implementation dependent and must be instantiated by the SPI host controller directly. An entire subsystem has been contributed to support these engines which makes the insertion into another subsystem such as SPI quite straightforward without the need for a lot of specific functions. Signed-off-by: Miquel Raynal Reviewed-by: Mark Brown --- drivers/spi/Kconfig | 2 +- drivers/spi/spi-mxic.c | 113 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 83e352b0c8f9..bff75629e872 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -856,7 +856,7 @@ config SPI_SYNQUACER config SPI_MXIC tristate "Macronix MX25F0A SPI controller" - depends on SPI_MASTER + depends on SPI_MASTER && MTD_NAND_ECC help This selects the Macronix MX25F0A SPI controller driver. diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index 97de058d2f80..40283126a941 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -167,6 +169,7 @@ #define HW_TEST(x) (0xe0 + ((x) * 4)) struct mxic_spi { + struct device *dev; struct clk *ps_clk; struct clk *send_clk; struct clk *send_dly_clk; @@ -177,6 +180,12 @@ struct mxic_spi { dma_addr_t dma; size_t size; } linear; + + struct { + bool use_pipelined_conf; + struct nand_ecc_engine *pipelined_engine; + void *ctx; + } ecc; }; static int mxic_spi_clk_enable(struct mxic_spi *mxic) @@ -400,7 +409,15 @@ static ssize_t mxic_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, LMODE_EN, mxic->regs + LRD_CTRL); - memcpy_fromio(buf, mxic->linear.map, len); + if (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl.data.ecc) { + ret = mxic_ecc_process_data_pipelined(mxic->ecc.pipelined_engine, + NAND_PAGE_READ, + mxic->linear.dma + offs); + if (ret) + return ret; + } else { + memcpy_fromio(buf, mxic->linear.map, len); + } writel(INT_LRD_DIS, mxic->regs + INT_STS); writel(0, mxic->regs + LRD_CTRL); @@ -436,7 +453,15 @@ static ssize_t mxic_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc, LMODE_EN, mxic->regs + LWR_CTRL); - memcpy_toio(mxic->linear.map, buf, len); + if (mxic->ecc.use_pipelined_conf && desc->info.op_tmpl.data.ecc) { + ret = mxic_ecc_process_data_pipelined(mxic->ecc.pipelined_engine, + NAND_PAGE_WRITE, + mxic->linear.dma + offs); + if (ret) + return ret; + } else { + memcpy_toio(mxic->linear.map, buf, len); + } writel(INT_LWR_DIS, mxic->regs + INT_STS); writel(0, mxic->regs + LWR_CTRL); @@ -539,6 +564,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem, static const struct spi_controller_mem_caps mxic_spi_mem_caps = { .dtr = true, + .ecc = true, }; static const struct spi_controller_mem_ops mxic_spi_mem_ops = { @@ -612,6 +638,80 @@ static int mxic_spi_transfer_one(struct spi_master *master, return 0; } +/* ECC wrapper */ +static int mxic_spi_mem_ecc_init_ctx(struct nand_device *nand) +{ + struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops(); + struct mxic_spi *mxic = nand->ecc.engine->priv; + + mxic->ecc.use_pipelined_conf = true; + + return ops->init_ctx(nand); +} + +static void mxic_spi_mem_ecc_cleanup_ctx(struct nand_device *nand) +{ + struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops(); + struct mxic_spi *mxic = nand->ecc.engine->priv; + + mxic->ecc.use_pipelined_conf = false; + + ops->cleanup_ctx(nand); +} + +static int mxic_spi_mem_ecc_prepare_io_req(struct nand_device *nand, + struct nand_page_io_req *req) +{ + struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops(); + + return ops->prepare_io_req(nand, req); +} + +static int mxic_spi_mem_ecc_finish_io_req(struct nand_device *nand, + struct nand_page_io_req *req) +{ + struct nand_ecc_engine_ops *ops = mxic_ecc_get_pipelined_ops(); + + return ops->finish_io_req(nand, req); +} + +static struct nand_ecc_engine_ops mxic_spi_mem_ecc_engine_pipelined_ops = { + .init_ctx = mxic_spi_mem_ecc_init_ctx, + .cleanup_ctx = mxic_spi_mem_ecc_cleanup_ctx, + .prepare_io_req = mxic_spi_mem_ecc_prepare_io_req, + .finish_io_req = mxic_spi_mem_ecc_finish_io_req, +}; + +static void mxic_spi_mem_ecc_remove(struct mxic_spi *mxic) +{ + if (mxic->ecc.pipelined_engine) { + mxic_ecc_put_pipelined_engine(mxic->ecc.pipelined_engine); + nand_ecc_unregister_on_host_hw_engine(mxic->ecc.pipelined_engine); + } +} + +static int mxic_spi_mem_ecc_probe(struct platform_device *pdev, + struct mxic_spi *mxic) +{ + struct nand_ecc_engine *eng; + + if (!mxic_ecc_get_pipelined_ops()) + return -EOPNOTSUPP; + + eng = mxic_ecc_get_pipelined_engine(pdev); + if (IS_ERR(eng)) + return PTR_ERR(eng); + + eng->dev = &pdev->dev; + eng->integration = NAND_ECC_ENGINE_INTEGRATION_PIPELINED; + eng->ops = &mxic_spi_mem_ecc_engine_pipelined_ops; + eng->priv = mxic; + mxic->ecc.pipelined_engine = eng; + nand_ecc_register_on_host_hw_engine(eng); + + return 0; +} + static int __maybe_unused mxic_spi_runtime_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); @@ -657,6 +757,7 @@ static int mxic_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, master); mxic = spi_master_get_devdata(master); + mxic->dev = &pdev->dev; master->dev.of_node = pdev->dev.of_node; @@ -702,6 +803,12 @@ static int mxic_spi_probe(struct platform_device *pdev) mxic_spi_hw_init(mxic); + ret = mxic_spi_mem_ecc_probe(pdev, mxic); + if (ret == -EPROBE_DEFER) { + pm_runtime_disable(&pdev->dev); + return ret; + } + ret = spi_register_master(master); if (ret) { dev_err(&pdev->dev, "spi_register_master failed\n"); @@ -714,8 +821,10 @@ static int mxic_spi_probe(struct platform_device *pdev) static int mxic_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); + struct mxic_spi *mxic = spi_master_get_devdata(master); pm_runtime_disable(&pdev->dev); + mxic_spi_mem_ecc_remove(mxic); spi_unregister_master(master); return 0;