linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] Bringing generic ECC engine support to SPI-NAND
@ 2020-10-01 10:20 Miquel Raynal
  2020-10-01 10:20 ` [PATCH 1/6] mtd: nand: Add helpers to manage ECC engines and configurations Miquel Raynal
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Miquel Raynal @ 2020-10-01 10:20 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni, Miquel Raynal

Hello,

This is the penultimate series regarding ECC engine support for
SPI-NAND devices.

Previous work prepared the subsystem for the addition, cleaned and
created real software engines, created a real on-die ECC engine. This
series gathers all the existing bits into a final solution where
SPI-NAND devices may be linked to either their own on-die ECC engine,
or an external software engine.

Last step will be to bring external and pipelined (ie. not on-die)
hardware ECC engines.

Thanks,
Miquèl

Miquel Raynal (6):
  mtd: nand: Add helpers to manage ECC engines and configurations
  dt-bindings: mtd: Deprecate nand-ecc-mode
  mtd: spinand: Use the external ECC engine logic
  mtd: spinand: Allow the case where there is no ECC engine
  mtd: spinand: Fix OOB read
  mtd: spinand: Remove outdated comment

 .../bindings/mtd/nand-controller.yaml         |  11 +-
 drivers/mtd/nand/core.c                       | 124 ++++++++++++++++++
 drivers/mtd/nand/ecc.c                        |   8 +-
 drivers/mtd/nand/spi/Kconfig                  |   1 +
 drivers/mtd/nand/spi/core.c                   | 109 ++++++++-------
 include/linux/mtd/nand.h                      |   4 +
 6 files changed, 194 insertions(+), 63 deletions(-)

-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/6] mtd: nand: Add helpers to manage ECC engines and configurations
  2020-10-01 10:20 [PATCH 0/6] Bringing generic ECC engine support to SPI-NAND Miquel Raynal
@ 2020-10-01 10:20 ` Miquel Raynal
  2020-10-30 17:28   ` Miquel Raynal
  2020-10-01 10:20 ` [PATCH 2/6] dt-bindings: mtd: Deprecate nand-ecc-mode Miquel Raynal
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Miquel Raynal @ 2020-10-01 10:20 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni, Miquel Raynal

Add the logic in the NAND core to find the right ECC engine depending
on the NAND chip requirements and the user desires. Right now, the
choice may be made between (more will come):
* software Hamming
* software BCH
* on-die (SPI-NAND devices only)

Once the ECC engine has been found, the ECC engine must be
configured.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/core.c  | 124 +++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h |   4 ++
 2 files changed, 128 insertions(+)

diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
index b6de955ac8bf..5e13a03d2b32 100644
--- a/drivers/mtd/nand/core.c
+++ b/drivers/mtd/nand/core.c
@@ -207,6 +207,130 @@ int nanddev_mtd_max_bad_blocks(struct mtd_info *mtd, loff_t offs, size_t len)
 }
 EXPORT_SYMBOL_GPL(nanddev_mtd_max_bad_blocks);
 
+/**
+ * nanddev_get_ecc_engine() - Find and get a suitable ECC engine
+ * @nand: NAND device
+ */
+static int nanddev_get_ecc_engine(struct nand_device *nand)
+{
+	int engine_type;
+
+	/* Read the user desires in terms of ECC engine/configuration */
+	of_get_nand_ecc_user_config(nand);
+
+	engine_type = nand->ecc.user_conf.engine_type;
+	if (engine_type == NAND_ECC_ENGINE_TYPE_INVALID)
+		engine_type = nand->ecc.defaults.engine_type;
+
+	switch (engine_type) {
+	case NAND_ECC_ENGINE_TYPE_NONE:
+		return 0;
+	case NAND_ECC_ENGINE_TYPE_SOFT:
+		nand->ecc.engine = nand_ecc_get_sw_engine(nand);
+		break;
+	case NAND_ECC_ENGINE_TYPE_ON_DIE:
+		nand->ecc.engine = nand_ecc_get_on_die_hw_engine(nand);
+		break;
+	case NAND_ECC_ENGINE_TYPE_ON_HOST:
+		pr_err("On-host hardware ECC engines not supported yet\n");
+		break;
+	default:
+		pr_err("Missing ECC engine type\n");
+	}
+
+	if (!nand->ecc.engine)
+		return  -EINVAL;
+
+	return 0;
+}
+
+/**
+ * nanddev_put_ecc_engine() - Dettach and put the in-use ECC engine
+ * @nand: NAND device
+ */
+static int nanddev_put_ecc_engine(struct nand_device *nand)
+{
+	switch (nand->ecc.ctx.conf.engine_type) {
+	case NAND_ECC_ENGINE_TYPE_ON_HOST:
+		pr_err("On-host hardware ECC engines not supported yet\n");
+		break;
+	case NAND_ECC_ENGINE_TYPE_NONE:
+	case NAND_ECC_ENGINE_TYPE_SOFT:
+	case NAND_ECC_ENGINE_TYPE_ON_DIE:
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ * nanddev_find_ecc_configuration() - Find a suitable ECC configuration
+ * @nand: NAND device
+ */
+static int nanddev_find_ecc_configuration(struct nand_device *nand)
+{
+	int ret;
+
+	if (!nand->ecc.engine)
+		return -ENOTSUPP;
+
+	ret = nand_ecc_init_ctx(nand);
+	if (ret)
+		return ret;
+
+	if (!nand_ecc_is_strong_enough(nand))
+		pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n",
+			nand->mtd.name);
+
+	return 0;
+}
+
+/**
+ * nanddev_ecc_engine_init() - Initialize an ECC engine for the chip
+ * @nand: NAND device
+ */
+int nanddev_ecc_engine_init(struct nand_device *nand)
+{
+	int ret;
+
+	/* Look for the ECC engine to use */
+	ret = nanddev_get_ecc_engine(nand);
+	if (ret) {
+		pr_err("No ECC engine found\n");
+		return ret;
+	}
+
+	/* No ECC engine requested */
+	if (!nand->ecc.engine)
+		return 0;
+
+	/* Configure the engine: balance user input and chip requirements */
+	ret = nanddev_find_ecc_configuration(nand);
+	if (ret) {
+		pr_err("No suitable ECC configuration\n");
+		nanddev_put_ecc_engine(nand);
+
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nanddev_ecc_engine_init);
+
+/**
+ * nanddev_ecc_engine_cleanup() - Cleanup ECC engine initializations
+ * @nand: NAND device
+ */
+void nanddev_ecc_engine_cleanup(struct nand_device *nand)
+{
+	if (nand->ecc.engine)
+		nand_ecc_cleanup_ctx(nand);
+
+	nanddev_put_ecc_engine(nand);
+}
+EXPORT_SYMBOL_GPL(nanddev_ecc_engine_cleanup);
+
 /**
  * nanddev_init() - Initialize a NAND device
  * @nand: NAND device
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 6c6f91c03c42..414f8a4d2853 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -936,6 +936,10 @@ bool nanddev_isreserved(struct nand_device *nand, const struct nand_pos *pos);
 int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos);
 int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos);
 
+/* ECC related functions */
+int nanddev_ecc_engine_init(struct nand_device *nand);
+void nanddev_ecc_engine_cleanup(struct nand_device *nand);
+
 /* BBT related functions */
 enum nand_bbt_block_status {
 	NAND_BBT_BLOCK_STATUS_UNKNOWN,
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/6] dt-bindings: mtd: Deprecate nand-ecc-mode
  2020-10-01 10:20 [PATCH 0/6] Bringing generic ECC engine support to SPI-NAND Miquel Raynal
  2020-10-01 10:20 ` [PATCH 1/6] mtd: nand: Add helpers to manage ECC engines and configurations Miquel Raynal
@ 2020-10-01 10:20 ` Miquel Raynal
  2020-10-30 17:28   ` Miquel Raynal
  2020-10-01 10:20 ` [PATCH 3/6] mtd: spinand: Use the external ECC engine logic Miquel Raynal
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Miquel Raynal @ 2020-10-01 10:20 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni, Miquel Raynal

This property does not describe very well its purpose: it describes
the ECC engine type. Deprecate it in favor of nand-ecc-engine which
points to either the NAND part itself in case of on-die ECC, or to the
parent node in case of an integrated ECC engine in the NAND controller
(previously referred as "hardware") or to another node in case of an
external controller. Other "modes" (none/software) are achieved with
the new nand-use-soft-ecc-engine and nand-no-ecc-engine properties.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../devicetree/bindings/mtd/nand-controller.yaml      | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml
index e79bb6d2c108..6f32c540fcc0 100644
--- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml
+++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml
@@ -46,15 +46,6 @@ patternProperties:
         description:
           Contains the native Ready/Busy IDs.
 
-      nand-ecc-mode:
-        description:
-          Desired ECC engine, either hardware (most of the time
-          embedded in the NAND controller) or software correction
-          (Linux will handle the calculations). soft_bch is deprecated
-          and should be replaced by soft and nand-ecc-algo.
-        $ref: /schemas/types.yaml#/definitions/string
-        enum: [none, soft, hw, hw_syndrome, hw_oob_first, on-die]
-
       nand-ecc-engine:
         allOf:
           - $ref: /schemas/types.yaml#/definitions/phandle
@@ -169,7 +160,7 @@ examples:
 
       nand@0 {
         reg = <0>;
-        nand-ecc-mode = "soft";
+        nand-use-soft-ecc-engine;
         nand-ecc-algo = "bch";
 
         /* controller specific properties */
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/6] mtd: spinand: Use the external ECC engine logic
  2020-10-01 10:20 [PATCH 0/6] Bringing generic ECC engine support to SPI-NAND Miquel Raynal
  2020-10-01 10:20 ` [PATCH 1/6] mtd: nand: Add helpers to manage ECC engines and configurations Miquel Raynal
  2020-10-01 10:20 ` [PATCH 2/6] dt-bindings: mtd: Deprecate nand-ecc-mode Miquel Raynal
@ 2020-10-01 10:20 ` Miquel Raynal
  2020-10-30 17:28   ` Miquel Raynal
  2020-10-01 10:20 ` [PATCH 4/6] mtd: spinand: Allow the case where there is no ECC engine Miquel Raynal
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Miquel Raynal @ 2020-10-01 10:20 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni, Miquel Raynal

Now that all the logic is available in the NAND core, let's use it
from the SPI-NAND core. Right now there is no functional change as the
default ECC engine for SPI-NANDs is set to 'on-die', but user can now
use software correction if they want to by just setting the right
properties in the DT.

Also note that the OOB layout handling is removed from the SPI-NAND
core as each ECC engine is supposed to handle it by it's own; users
should not be aware of that.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/spi/Kconfig |  1 +
 drivers/mtd/nand/spi/core.c  | 97 ++++++++++++++++++++----------------
 2 files changed, 54 insertions(+), 44 deletions(-)

diff --git a/drivers/mtd/nand/spi/Kconfig b/drivers/mtd/nand/spi/Kconfig
index da89b250df7c..3d7649a2dd72 100644
--- a/drivers/mtd/nand/spi/Kconfig
+++ b/drivers/mtd/nand/spi/Kconfig
@@ -2,6 +2,7 @@
 menuconfig MTD_SPI_NAND
 	tristate "SPI NAND device Support"
 	select MTD_NAND_CORE
+	select MTD_NAND_ECC
 	depends on SPI_MASTER
 	select SPI_MEM
 	help
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index f58cea52c781..8a4d20e30edb 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -313,6 +313,15 @@ static struct nand_ecc_engine spinand_ondie_ecc_engine = {
 	.ops = &spinand_ondie_ecc_engine_ops,
 };
 
+static void spinand_ondie_ecc_save_status(struct nand_device *nand, u8 status)
+{
+	struct spinand_ondie_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+
+	if (nand->ecc.ctx.conf.engine_type == NAND_ECC_ENGINE_TYPE_ON_DIE &&
+	    engine_conf)
+		engine_conf->status = status;
+}
+
 static int spinand_write_enable_op(struct spinand_device *spinand)
 {
 	struct spi_mem_op op = SPINAND_WR_EN_DIS_OP(true);
@@ -334,7 +343,6 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
 				      const struct nand_page_io_req *req)
 {
 	struct nand_device *nand = spinand_to_nand(spinand);
-	struct mtd_info *mtd = nanddev_to_mtd(nand);
 	struct spi_mem_dirmap_desc *rdesc;
 	unsigned int nbytes = 0;
 	void *buf = NULL;
@@ -374,17 +382,6 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
 		memcpy(req->databuf.in, spinand->databuf + req->dataoffs,
 		       req->datalen);
 
-	if (req->ooblen) {
-		if (req->mode == MTD_OPS_AUTO_OOB)
-			mtd_ooblayout_get_databytes(mtd, req->oobbuf.in,
-						    spinand->oobbuf,
-						    req->ooboffs,
-						    req->ooblen);
-		else
-			memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs,
-			       req->ooblen);
-	}
-
 	return 0;
 }
 
@@ -392,7 +389,7 @@ static int spinand_write_to_cache_op(struct spinand_device *spinand,
 				     const struct nand_page_io_req *req)
 {
 	struct nand_device *nand = spinand_to_nand(spinand);
-	struct mtd_info *mtd = nanddev_to_mtd(nand);
+	struct mtd_info *mtd = spinand_to_mtd(spinand);
 	struct spi_mem_dirmap_desc *wdesc;
 	unsigned int nbytes, column = 0;
 	void *buf = spinand->databuf;
@@ -404,9 +401,12 @@ static int spinand_write_to_cache_op(struct spinand_device *spinand,
 	 * must fill the page cache entirely even if we only want to program
 	 * the data portion of the page, otherwise we might corrupt the BBM or
 	 * user data previously programmed in OOB area.
+	 *
+	 * Only reset the data buffer manually, the OOB buffer is prepared by
+	 * ECC engines ->prepare_io_req() callback.
 	 */
 	nbytes = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);
-	memset(spinand->databuf, 0xff, nbytes);
+	memset(spinand->databuf, 0xff, nanddev_page_size(nand));
 
 	if (req->datalen)
 		memcpy(spinand->databuf + req->dataoffs, req->databuf.out,
@@ -523,12 +523,16 @@ static int spinand_lock_block(struct spinand_device *spinand, u8 lock)
 }
 
 static int spinand_read_page(struct spinand_device *spinand,
-			     const struct nand_page_io_req *req,
-			     bool ecc_enabled)
+			     const struct nand_page_io_req *req)
 {
+	struct nand_device *nand = spinand_to_nand(spinand);
 	u8 status;
 	int ret;
 
+	ret = nand_ecc_prepare_io_req(nand, (struct nand_page_io_req *)req);
+	if (ret)
+		return ret;
+
 	ret = spinand_load_page_op(spinand, req);
 	if (ret)
 		return ret;
@@ -537,22 +541,26 @@ static int spinand_read_page(struct spinand_device *spinand,
 	if (ret < 0)
 		return ret;
 
+	spinand_ondie_ecc_save_status(nand, status);
+
 	ret = spinand_read_from_cache_op(spinand, req);
 	if (ret)
 		return ret;
 
-	if (!ecc_enabled)
-		return 0;
-
-	return spinand_check_ecc_status(spinand, status);
+	return nand_ecc_finish_io_req(nand, (struct nand_page_io_req *)req);
 }
 
 static int spinand_write_page(struct spinand_device *spinand,
 			      const struct nand_page_io_req *req)
 {
+	struct nand_device *nand = spinand_to_nand(spinand);
 	u8 status;
 	int ret;
 
+	ret = nand_ecc_prepare_io_req(nand, (struct nand_page_io_req *)req);
+	if (ret)
+		return ret;
+
 	ret = spinand_write_enable_op(spinand);
 	if (ret)
 		return ret;
@@ -567,9 +575,9 @@ static int spinand_write_page(struct spinand_device *spinand,
 
 	ret = spinand_wait(spinand, &status);
 	if (!ret && (status & STATUS_PROG_FAILED))
-		ret = -EIO;
+		return -EIO;
 
-	return ret;
+	return nand_ecc_finish_io_req(nand, (struct nand_page_io_req *)req);
 }
 
 static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
@@ -579,25 +587,24 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
 	struct nand_device *nand = mtd_to_nanddev(mtd);
 	unsigned int max_bitflips = 0;
 	struct nand_io_iter iter;
-	bool enable_ecc = false;
+	bool disable_ecc = false;
 	bool ecc_failed = false;
 	int ret = 0;
 
-	if (ops->mode != MTD_OPS_RAW && spinand->eccinfo.ooblayout)
-		enable_ecc = true;
+	if (ops->mode == MTD_OPS_RAW || !spinand->eccinfo.ooblayout)
+		disable_ecc = true;
 
 	mutex_lock(&spinand->lock);
 
 	nanddev_io_for_each_page(nand, NAND_PAGE_READ, from, ops, &iter) {
+		if (disable_ecc)
+			iter.req.mode = MTD_OPS_RAW;
+
 		ret = spinand_select_target(spinand, iter.req.pos.target);
 		if (ret)
 			break;
 
-		ret = spinand_ecc_enable(spinand, enable_ecc);
-		if (ret)
-			break;
-
-		ret = spinand_read_page(spinand, &iter.req, enable_ecc);
+		ret = spinand_read_page(spinand, &iter.req);
 		if (ret < 0 && ret != -EBADMSG)
 			break;
 
@@ -628,20 +635,19 @@ static int spinand_mtd_write(struct mtd_info *mtd, loff_t to,
 	struct spinand_device *spinand = mtd_to_spinand(mtd);
 	struct nand_device *nand = mtd_to_nanddev(mtd);
 	struct nand_io_iter iter;
-	bool enable_ecc = false;
+	bool disable_ecc = false;
 	int ret = 0;
 
-	if (ops->mode != MTD_OPS_RAW && mtd->ooblayout)
-		enable_ecc = true;
+	if (ops->mode == MTD_OPS_RAW || !mtd->ooblayout)
+		disable_ecc = true;
 
 	mutex_lock(&spinand->lock);
 
 	nanddev_io_for_each_page(nand, NAND_PAGE_WRITE, to, ops, &iter) {
-		ret = spinand_select_target(spinand, iter.req.pos.target);
-		if (ret)
-			break;
+		if (disable_ecc)
+			iter.req.mode = MTD_OPS_RAW;
 
-		ret = spinand_ecc_enable(spinand, enable_ecc);
+		ret = spinand_select_target(spinand, iter.req.pos.target);
 		if (ret)
 			break;
 
@@ -671,7 +677,7 @@ static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
 	};
 
 	spinand_select_target(spinand, pos->target);
-	spinand_read_page(spinand, &req, false);
+	spinand_read_page(spinand, &req);
 	if (marker[0] != 0xff || marker[1] != 0xff)
 		return true;
 
@@ -1137,6 +1143,11 @@ static int spinand_init(struct spinand_device *spinand)
 	nand->ecc.defaults.engine_type = NAND_ECC_ENGINE_TYPE_ON_DIE;
 	nand->ecc.ondie_engine = &spinand_ondie_ecc_engine;
 
+	spinand_ecc_enable(spinand, false);
+	ret = nanddev_ecc_engine_init(nand);
+	if (ret)
+		goto err_cleanup_nanddev;
+
 	/*
 	 * Right now, we don't support ECC, so let the whole oob
 	 * area available for the user.
@@ -1149,14 +1160,9 @@ static int spinand_init(struct spinand_device *spinand)
 	mtd->_erase = spinand_mtd_erase;
 	mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks;
 
-	if (spinand->eccinfo.ooblayout)
-		mtd_set_ooblayout(mtd, spinand->eccinfo.ooblayout);
-	else
-		mtd_set_ooblayout(mtd, &spinand_noecc_ooblayout);
-
 	ret = mtd_ooblayout_count_freebytes(mtd);
 	if (ret < 0)
-		goto err_cleanup_nanddev;
+		goto err_cleanup_ecc_engine;
 
 	mtd->oobavail = ret;
 
@@ -1166,6 +1172,9 @@ static int spinand_init(struct spinand_device *spinand)
 
 	return 0;
 
+err_cleanup_ecc_engine:
+	nanddev_ecc_engine_cleanup(nand);
+
 err_cleanup_nanddev:
 	nanddev_cleanup(nand);
 
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/6] mtd: spinand: Allow the case where there is no ECC engine
  2020-10-01 10:20 [PATCH 0/6] Bringing generic ECC engine support to SPI-NAND Miquel Raynal
                   ` (2 preceding siblings ...)
  2020-10-01 10:20 ` [PATCH 3/6] mtd: spinand: Use the external ECC engine logic Miquel Raynal
@ 2020-10-01 10:20 ` Miquel Raynal
  2020-10-30 17:28   ` Miquel Raynal
  2020-10-01 10:20 ` [PATCH 5/6] mtd: spinand: Fix OOB read Miquel Raynal
  2020-10-01 10:20 ` [PATCH 6/6] mtd: spinand: Remove outdated comment Miquel Raynal
  5 siblings, 1 reply; 13+ messages in thread
From: Miquel Raynal @ 2020-10-01 10:20 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni, Miquel Raynal

Even if this is not supposed to happen, there is no reason to fail the
probe if it was explicitly requested to use no ECC engine at all (for
instance, during development). This condition is met by just
commenting out the error on the OOB free bytes count after the
assignation of an ECC engine if none was provided (any other situation
would error out much earlier anyway).

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/ecc.c      | 8 ++++----
 drivers/mtd/nand/spi/core.c | 8 +++++---
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/ecc.c b/drivers/mtd/nand/ecc.c
index 9afdde70824a..6c43dfda01d4 100644
--- a/drivers/mtd/nand/ecc.c
+++ b/drivers/mtd/nand/ecc.c
@@ -105,7 +105,7 @@
  */
 int nand_ecc_init_ctx(struct nand_device *nand)
 {
-	if (!nand->ecc.engine->ops->init_ctx)
+	if (!nand->ecc.engine || !nand->ecc.engine->ops->init_ctx)
 		return 0;
 
 	return nand->ecc.engine->ops->init_ctx(nand);
@@ -118,7 +118,7 @@ EXPORT_SYMBOL(nand_ecc_init_ctx);
  */
 void nand_ecc_cleanup_ctx(struct nand_device *nand)
 {
-	if (nand->ecc.engine->ops->cleanup_ctx)
+	if (nand->ecc.engine && nand->ecc.engine->ops->cleanup_ctx)
 		nand->ecc.engine->ops->cleanup_ctx(nand);
 }
 EXPORT_SYMBOL(nand_ecc_cleanup_ctx);
@@ -131,7 +131,7 @@ EXPORT_SYMBOL(nand_ecc_cleanup_ctx);
 int nand_ecc_prepare_io_req(struct nand_device *nand,
 			    struct nand_page_io_req *req)
 {
-	if (!nand->ecc.engine->ops->prepare_io_req)
+	if (!nand->ecc.engine || !nand->ecc.engine->ops->prepare_io_req)
 		return 0;
 
 	return nand->ecc.engine->ops->prepare_io_req(nand, req);
@@ -146,7 +146,7 @@ EXPORT_SYMBOL(nand_ecc_prepare_io_req);
 int nand_ecc_finish_io_req(struct nand_device *nand,
 			   struct nand_page_io_req *req)
 {
-	if (!nand->ecc.engine->ops->finish_io_req)
+	if (!nand->ecc.engine || !nand->ecc.engine->ops->finish_io_req)
 		return 0;
 
 	return nand->ecc.engine->ops->finish_io_req(nand, req);
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 8a4d20e30edb..4a4c86d8eeb6 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1160,9 +1160,11 @@ static int spinand_init(struct spinand_device *spinand)
 	mtd->_erase = spinand_mtd_erase;
 	mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks;
 
-	ret = mtd_ooblayout_count_freebytes(mtd);
-	if (ret < 0)
-		goto err_cleanup_ecc_engine;
+	if (nand->ecc.engine) {
+		ret = mtd_ooblayout_count_freebytes(mtd);
+		if (ret < 0)
+			goto err_cleanup_ecc_engine;
+	}
 
 	mtd->oobavail = ret;
 
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/6] mtd: spinand: Fix OOB read
  2020-10-01 10:20 [PATCH 0/6] Bringing generic ECC engine support to SPI-NAND Miquel Raynal
                   ` (3 preceding siblings ...)
  2020-10-01 10:20 ` [PATCH 4/6] mtd: spinand: Allow the case where there is no ECC engine Miquel Raynal
@ 2020-10-01 10:20 ` Miquel Raynal
  2020-10-30 17:27   ` Miquel Raynal
  2020-10-01 10:20 ` [PATCH 6/6] mtd: spinand: Remove outdated comment Miquel Raynal
  5 siblings, 1 reply; 13+ messages in thread
From: Miquel Raynal @ 2020-10-01 10:20 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, stable, Thomas Petazzoni, Miquel Raynal

So far OOB have never been used in SPI-NAND, add the missing memcpy to
make it work properly.

Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs")
Cc: stable@vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/spi/core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 4a4c86d8eeb6..bec8c2a57f24 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -382,6 +382,10 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
 		memcpy(req->databuf.in, spinand->databuf + req->dataoffs,
 		       req->datalen);
 
+	if (req->ooblen)
+		memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs,
+		       req->ooblen);
+
 	return 0;
 }
 
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/6] mtd: spinand: Remove outdated comment
  2020-10-01 10:20 [PATCH 0/6] Bringing generic ECC engine support to SPI-NAND Miquel Raynal
                   ` (4 preceding siblings ...)
  2020-10-01 10:20 ` [PATCH 5/6] mtd: spinand: Fix OOB read Miquel Raynal
@ 2020-10-01 10:20 ` Miquel Raynal
  2020-10-30 17:27   ` Miquel Raynal
  5 siblings, 1 reply; 13+ messages in thread
From: Miquel Raynal @ 2020-10-01 10:20 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni, Miquel Raynal

This comment is no longer true so drop it.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/spi/core.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index bec8c2a57f24..8ea545bb924d 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1152,10 +1152,6 @@ static int spinand_init(struct spinand_device *spinand)
 	if (ret)
 		goto err_cleanup_nanddev;
 
-	/*
-	 * Right now, we don't support ECC, so let the whole oob
-	 * area available for the user.
-	 */
 	mtd->_read_oob = spinand_mtd_read;
 	mtd->_write_oob = spinand_mtd_write;
 	mtd->_block_isbad = spinand_mtd_block_isbad;
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/6] mtd: spinand: Remove outdated comment
  2020-10-01 10:20 ` [PATCH 6/6] mtd: spinand: Remove outdated comment Miquel Raynal
@ 2020-10-30 17:27   ` Miquel Raynal
  0 siblings, 0 replies; 13+ messages in thread
From: Miquel Raynal @ 2020-10-30 17:27 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni

On Thu, 2020-10-01 at 10:20:14 UTC, Miquel Raynal wrote:
> This comment is no longer true so drop it.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next.

Miquel

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 5/6] mtd: spinand: Fix OOB read
  2020-10-01 10:20 ` [PATCH 5/6] mtd: spinand: Fix OOB read Miquel Raynal
@ 2020-10-30 17:27   ` Miquel Raynal
  0 siblings, 0 replies; 13+ messages in thread
From: Miquel Raynal @ 2020-10-30 17:27 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni, stable

On Thu, 2020-10-01 at 10:20:13 UTC, Miquel Raynal wrote:
> So far OOB have never been used in SPI-NAND, add the missing memcpy to
> make it work properly.
> 
> Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs")
> Cc: stable@vger.kernel.org
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next.

Miquel

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/6] mtd: spinand: Allow the case where there is no ECC engine
  2020-10-01 10:20 ` [PATCH 4/6] mtd: spinand: Allow the case where there is no ECC engine Miquel Raynal
@ 2020-10-30 17:28   ` Miquel Raynal
  0 siblings, 0 replies; 13+ messages in thread
From: Miquel Raynal @ 2020-10-30 17:28 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni

On Thu, 2020-10-01 at 10:20:12 UTC, Miquel Raynal wrote:
> Even if this is not supposed to happen, there is no reason to fail the
> probe if it was explicitly requested to use no ECC engine at all (for
> instance, during development). This condition is met by just
> commenting out the error on the OOB free bytes count after the
> assignation of an ECC engine if none was provided (any other situation
> would error out much earlier anyway).
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next.

Miquel

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/6] mtd: spinand: Use the external ECC engine logic
  2020-10-01 10:20 ` [PATCH 3/6] mtd: spinand: Use the external ECC engine logic Miquel Raynal
@ 2020-10-30 17:28   ` Miquel Raynal
  0 siblings, 0 replies; 13+ messages in thread
From: Miquel Raynal @ 2020-10-30 17:28 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni

On Thu, 2020-10-01 at 10:20:11 UTC, Miquel Raynal wrote:
> Now that all the logic is available in the NAND core, let's use it
> from the SPI-NAND core. Right now there is no functional change as the
> default ECC engine for SPI-NANDs is set to 'on-die', but user can now
> use software correction if they want to by just setting the right
> properties in the DT.
> 
> Also note that the OOB layout handling is removed from the SPI-NAND
> core as each ECC engine is supposed to handle it by it's own; users
> should not be aware of that.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next.

Miquel

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/6] dt-bindings: mtd: Deprecate nand-ecc-mode
  2020-10-01 10:20 ` [PATCH 2/6] dt-bindings: mtd: Deprecate nand-ecc-mode Miquel Raynal
@ 2020-10-30 17:28   ` Miquel Raynal
  0 siblings, 0 replies; 13+ messages in thread
From: Miquel Raynal @ 2020-10-30 17:28 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni

On Thu, 2020-10-01 at 10:20:10 UTC, Miquel Raynal wrote:
> This property does not describe very well its purpose: it describes
> the ECC engine type. Deprecate it in favor of nand-ecc-engine which
> points to either the NAND part itself in case of on-die ECC, or to the
> parent node in case of an integrated ECC engine in the NAND controller
> (previously referred as "hardware") or to another node in case of an
> external controller. Other "modes" (none/software) are achieved with
> the new nand-use-soft-ecc-engine and nand-no-ecc-engine properties.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next.

Miquel

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/6] mtd: nand: Add helpers to manage ECC engines and configurations
  2020-10-01 10:20 ` [PATCH 1/6] mtd: nand: Add helpers to manage ECC engines and configurations Miquel Raynal
@ 2020-10-30 17:28   ` Miquel Raynal
  0 siblings, 0 replies; 13+ messages in thread
From: Miquel Raynal @ 2020-10-30 17:28 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Julien Su, ycllin, Thomas Petazzoni

On Thu, 2020-10-01 at 10:20:09 UTC, Miquel Raynal wrote:
> Add the logic in the NAND core to find the right ECC engine depending
> on the NAND chip requirements and the user desires. Right now, the
> choice may be made between (more will come):
> * software Hamming
> * software BCH
> * on-die (SPI-NAND devices only)
> 
> Once the ECC engine has been found, the ECC engine must be
> configured.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next.

Miquel

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-10-30 17:30 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-01 10:20 [PATCH 0/6] Bringing generic ECC engine support to SPI-NAND Miquel Raynal
2020-10-01 10:20 ` [PATCH 1/6] mtd: nand: Add helpers to manage ECC engines and configurations Miquel Raynal
2020-10-30 17:28   ` Miquel Raynal
2020-10-01 10:20 ` [PATCH 2/6] dt-bindings: mtd: Deprecate nand-ecc-mode Miquel Raynal
2020-10-30 17:28   ` Miquel Raynal
2020-10-01 10:20 ` [PATCH 3/6] mtd: spinand: Use the external ECC engine logic Miquel Raynal
2020-10-30 17:28   ` Miquel Raynal
2020-10-01 10:20 ` [PATCH 4/6] mtd: spinand: Allow the case where there is no ECC engine Miquel Raynal
2020-10-30 17:28   ` Miquel Raynal
2020-10-01 10:20 ` [PATCH 5/6] mtd: spinand: Fix OOB read Miquel Raynal
2020-10-30 17:27   ` Miquel Raynal
2020-10-01 10:20 ` [PATCH 6/6] mtd: spinand: Remove outdated comment Miquel Raynal
2020-10-30 17:27   ` Miquel Raynal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).