All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] AM335x large page support
@ 2021-06-10 13:49 Miquel Raynal
  2021-06-10 13:49 ` [PATCH 1/5] mtd: rawnand: omap: Aggregate the HW configuration of the ELM Miquel Raynal
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Miquel Raynal @ 2021-06-10 13:49 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett, Miquel Raynal

The OMAP ELM is limited by the number of ECC chunks that it can process
in one go. Until now, we assumed that this was the maximum flash page
size supported by this engine, but with a small code addition we can
make it generic to fit any page size.

Miquel Raynal (5):
  mtd: rawnand: omap: Aggregate the HW configuration of the ELM
  mtd: rawnand: omap: Rename a macro
  mtd: rawnand: omap: Check return values
  mtd: rawnand: omap: Various style fixes
  mtd: rawnand: omap: Add larger page NAND chips support

 drivers/mtd/nand/raw/omap2.c    | 233 ++++++++++++++++++++------------
 drivers/mtd/nand/raw/omap_elm.c |   2 +-
 2 files changed, 144 insertions(+), 91 deletions(-)

-- 
2.27.0


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

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

* [PATCH 1/5] mtd: rawnand: omap: Aggregate the HW configuration of the ELM
  2021-06-10 13:49 [PATCH 0/5] AM335x large page support Miquel Raynal
@ 2021-06-10 13:49 ` Miquel Raynal
  2021-06-11 19:01   ` Miquel Raynal
  2021-06-10 13:49 ` [PATCH 2/5] mtd: rawnand: omap: Rename a macro Miquel Raynal
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Miquel Raynal @ 2021-06-10 13:49 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett, Miquel Raynal

Instead of calling elm_config() for each possible BCH configuration,
just save the BCH configuration that must be applied and use it in a
single call at the bottom.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/raw/omap2.c | 32 ++++++++++++--------------------
 1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c
index 512f60780a50..eb8b5e10ab6e 100644
--- a/drivers/mtd/nand/raw/omap2.c
+++ b/drivers/mtd/nand/raw/omap2.c
@@ -1915,6 +1915,7 @@ static int omap_nand_attach_chip(struct nand_chip *chip)
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 	struct device *dev = &info->pdev->dev;
 	int min_oobbytes = BADBLOCK_MARKER_LENGTH;
+	int elm_bch_strength = -1;
 	int oobbytes_per_step;
 	dma_cap_mask_t mask;
 	int err;
@@ -2068,12 +2069,7 @@ static int omap_nand_attach_chip(struct nand_chip *chip)
 		chip->ecc.write_subpage	= omap_write_subpage_bch;
 		mtd_set_ooblayout(mtd, &omap_ooblayout_ops);
 		oobbytes_per_step	= chip->ecc.bytes;
-
-		err = elm_config(info->elm_dev, BCH4_ECC,
-				 mtd->writesize / chip->ecc.size,
-				 chip->ecc.size, chip->ecc.bytes);
-		if (err < 0)
-			return err;
+		elm_bch_strength = BCH4_ECC;
 		break;
 
 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
@@ -2110,13 +2106,7 @@ static int omap_nand_attach_chip(struct nand_chip *chip)
 		chip->ecc.write_subpage	= omap_write_subpage_bch;
 		mtd_set_ooblayout(mtd, &omap_ooblayout_ops);
 		oobbytes_per_step	= chip->ecc.bytes;
-
-		err = elm_config(info->elm_dev, BCH8_ECC,
-				 mtd->writesize / chip->ecc.size,
-				 chip->ecc.size, chip->ecc.bytes);
-		if (err < 0)
-			return err;
-
+		elm_bch_strength = BCH8_ECC;
 		break;
 
 	case OMAP_ECC_BCH16_CODE_HW:
@@ -2132,19 +2122,21 @@ static int omap_nand_attach_chip(struct nand_chip *chip)
 		chip->ecc.write_subpage	= omap_write_subpage_bch;
 		mtd_set_ooblayout(mtd, &omap_ooblayout_ops);
 		oobbytes_per_step	= chip->ecc.bytes;
-
-		err = elm_config(info->elm_dev, BCH16_ECC,
-				 mtd->writesize / chip->ecc.size,
-				 chip->ecc.size, chip->ecc.bytes);
-		if (err < 0)
-			return err;
-
+		elm_bch_strength = BCH16_ECC;
 		break;
 	default:
 		dev_err(dev, "Invalid or unsupported ECC scheme\n");
 		return -EINVAL;
 	}
 
+	if (elm_bch_strength >= 0) {
+		err = elm_config(info->elm_dev, elm_bch_strength,
+				 mtd->writesize / chip->ecc.size,
+				 chip->ecc.size, chip->ecc.bytes);
+		if (err < 0)
+			return err;
+	}
+
 	/* Check if NAND device's OOB is enough to store ECC signatures */
 	min_oobbytes += (oobbytes_per_step *
 			 (mtd->writesize / chip->ecc.size));
-- 
2.27.0


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

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

* [PATCH 2/5] mtd: rawnand: omap: Rename a macro
  2021-06-10 13:49 [PATCH 0/5] AM335x large page support Miquel Raynal
  2021-06-10 13:49 ` [PATCH 1/5] mtd: rawnand: omap: Aggregate the HW configuration of the ELM Miquel Raynal
@ 2021-06-10 13:49 ` Miquel Raynal
  2021-06-10 13:49 ` [PATCH 3/5] mtd: rawnand: omap: Check return values Miquel Raynal
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Miquel Raynal @ 2021-06-10 13:49 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett, Miquel Raynal

The macro BADBLOCK_MARKER_LENGTH is pretty long and could be reduced to
BBM_LEN which is more handy to use in the code.

This is a purely cosmetic change and is only done to avoid further
change to contain 100+ char lines just because of this definition.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/raw/omap2.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c
index eb8b5e10ab6e..cbe2c6ba510f 100644
--- a/drivers/mtd/nand/raw/omap2.c
+++ b/drivers/mtd/nand/raw/omap2.c
@@ -131,7 +131,7 @@
 #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
-#define BADBLOCK_MARKER_LENGTH		2
+#define BBM_LEN			2
 
 static u_char bch16_vector[] = {0xf5, 0x24, 0x1c, 0xd0, 0x61, 0xb3, 0xf1, 0x55,
 				0x2e, 0x2c, 0x86, 0xa3, 0xed, 0x36, 0x1b, 0x78,
@@ -1648,8 +1648,8 @@ static int omap_read_page_bch(struct nand_chip *chip, uint8_t *buf,
 
 	/* Read oob bytes */
 	nand_change_read_column_op(chip,
-				   mtd->writesize + BADBLOCK_MARKER_LENGTH,
-				   chip->oob_poi + BADBLOCK_MARKER_LENGTH,
+				   mtd->writesize + BBM_LEN,
+				   chip->oob_poi + BBM_LEN,
 				   chip->ecc.total, false);
 
 	/* Calculate ecc bytes */
@@ -1818,7 +1818,7 @@ static int omap_ooblayout_ecc(struct mtd_info *mtd, int section,
 {
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 	struct nand_chip *chip = &info->nand;
-	int off = BADBLOCK_MARKER_LENGTH;
+	int off = BBM_LEN;
 
 	if (info->ecc_opt == OMAP_ECC_HAM1_CODE_HW &&
 	    !(chip->options & NAND_BUSWIDTH_16))
@@ -1838,7 +1838,7 @@ static int omap_ooblayout_free(struct mtd_info *mtd, int section,
 {
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 	struct nand_chip *chip = &info->nand;
-	int off = BADBLOCK_MARKER_LENGTH;
+	int off = BBM_LEN;
 
 	if (info->ecc_opt == OMAP_ECC_HAM1_CODE_HW &&
 	    !(chip->options & NAND_BUSWIDTH_16))
@@ -1866,7 +1866,7 @@ static int omap_sw_ooblayout_ecc(struct mtd_info *mtd, int section,
 				 struct mtd_oob_region *oobregion)
 {
 	struct nand_chip *chip = mtd_to_nand(mtd);
-	int off = BADBLOCK_MARKER_LENGTH;
+	int off = BBM_LEN;
 
 	if (section >= chip->ecc.steps)
 		return -ERANGE;
@@ -1885,7 +1885,7 @@ static int omap_sw_ooblayout_free(struct mtd_info *mtd, int section,
 				  struct mtd_oob_region *oobregion)
 {
 	struct nand_chip *chip = mtd_to_nand(mtd);
-	int off = BADBLOCK_MARKER_LENGTH;
+	int off = BBM_LEN;
 
 	if (section)
 		return -ERANGE;
@@ -1914,7 +1914,7 @@ static int omap_nand_attach_chip(struct nand_chip *chip)
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 	struct device *dev = &info->pdev->dev;
-	int min_oobbytes = BADBLOCK_MARKER_LENGTH;
+	int min_oobbytes = BBM_LEN;
 	int elm_bch_strength = -1;
 	int oobbytes_per_step;
 	dma_cap_mask_t mask;
-- 
2.27.0


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

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

* [PATCH 3/5] mtd: rawnand: omap: Check return values
  2021-06-10 13:49 [PATCH 0/5] AM335x large page support Miquel Raynal
  2021-06-10 13:49 ` [PATCH 1/5] mtd: rawnand: omap: Aggregate the HW configuration of the ELM Miquel Raynal
  2021-06-10 13:49 ` [PATCH 2/5] mtd: rawnand: omap: Rename a macro Miquel Raynal
@ 2021-06-10 13:49 ` Miquel Raynal
  2021-06-11 19:01   ` Miquel Raynal
  2021-06-10 13:49 ` [PATCH 4/5] mtd: rawnand: omap: Various style fixes Miquel Raynal
  2021-06-10 13:49 ` [PATCH 5/5] mtd: rawnand: omap: Add larger page NAND chips support Miquel Raynal
  4 siblings, 1 reply; 11+ messages in thread
From: Miquel Raynal @ 2021-06-10 13:49 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett, Miquel Raynal

Check the return value of many helpers which might return error codes.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/raw/omap2.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c
index cbe2c6ba510f..4b2ad77db71d 100644
--- a/drivers/mtd/nand/raw/omap2.c
+++ b/drivers/mtd/nand/raw/omap2.c
@@ -1527,7 +1527,9 @@ static int omap_write_page_bch(struct nand_chip *chip, const uint8_t *buf,
 	int ret;
 	uint8_t *ecc_calc = chip->ecc.calc_buf;
 
-	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+	ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+	if (ret)
+		return ret;
 
 	/* Enable GPMC ecc engine */
 	chip->ecc.hwctl(chip, NAND_ECC_WRITE);
@@ -1536,7 +1538,9 @@ static int omap_write_page_bch(struct nand_chip *chip, const uint8_t *buf,
 	chip->legacy.write_buf(chip, buf, mtd->writesize);
 
 	/* Update ecc vector from GPMC result registers */
-	omap_calculate_ecc_bch_multi(mtd, buf, &ecc_calc[0]);
+	ret = omap_calculate_ecc_bch_multi(mtd, buf, &ecc_calc[0]);
+	if (ret)
+		return ret;
 
 	ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
 					 chip->ecc.total);
@@ -1579,7 +1583,9 @@ static int omap_write_subpage_bch(struct nand_chip *chip, u32 offset,
 	 * ECC is calculated for all subpages but we choose
 	 * only what we want.
 	 */
-	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+	ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+	if (ret)
+		return ret;
 
 	/* Enable GPMC ECC engine */
 	chip->ecc.hwctl(chip, NAND_ECC_WRITE);
@@ -1638,7 +1644,9 @@ static int omap_read_page_bch(struct nand_chip *chip, uint8_t *buf,
 	int stat, ret;
 	unsigned int max_bitflips = 0;
 
-	nand_read_page_op(chip, page, 0, NULL, 0);
+	ret = nand_read_page_op(chip, page, 0, NULL, 0);
+	if (ret)
+		return ret;
 
 	/* Enable GPMC ecc engine */
 	chip->ecc.hwctl(chip, NAND_ECC_READ);
@@ -1647,13 +1655,17 @@ static int omap_read_page_bch(struct nand_chip *chip, uint8_t *buf,
 	chip->legacy.read_buf(chip, buf, mtd->writesize);
 
 	/* Read oob bytes */
-	nand_change_read_column_op(chip,
-				   mtd->writesize + BBM_LEN,
-				   chip->oob_poi + BBM_LEN,
-				   chip->ecc.total, false);
+	ret = nand_change_read_column_op(chip,
+					 mtd->writesize + BBM_LEN,
+					 chip->oob_poi + BBM_LEN,
+					 chip->ecc.total, false);
+	if (ret)
+		return ret;
 
 	/* Calculate ecc bytes */
-	omap_calculate_ecc_bch_multi(mtd, buf, ecc_calc);
+	ret = omap_calculate_ecc_bch_multi(mtd, buf, ecc_calc);
+	if (ret)
+		return ret;
 
 	ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
 					 chip->ecc.total);
-- 
2.27.0


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

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

* [PATCH 4/5] mtd: rawnand: omap: Various style fixes
  2021-06-10 13:49 [PATCH 0/5] AM335x large page support Miquel Raynal
                   ` (2 preceding siblings ...)
  2021-06-10 13:49 ` [PATCH 3/5] mtd: rawnand: omap: Check return values Miquel Raynal
@ 2021-06-10 13:49 ` Miquel Raynal
  2021-06-11 19:01   ` Miquel Raynal
  2021-06-10 13:49 ` [PATCH 5/5] mtd: rawnand: omap: Add larger page NAND chips support Miquel Raynal
  4 siblings, 1 reply; 11+ messages in thread
From: Miquel Raynal @ 2021-06-10 13:49 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett, Miquel Raynal

Fix the comments style, declare the variables in a reverse Christmas
tree order, add an upper case character at the beginning of a sentence.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/raw/omap2.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c
index 4b2ad77db71d..71cd659cd876 100644
--- a/drivers/mtd/nand/raw/omap2.c
+++ b/drivers/mtd/nand/raw/omap2.c
@@ -1524,8 +1524,8 @@ static int omap_write_page_bch(struct nand_chip *chip, const uint8_t *buf,
 			       int oob_required, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
-	int ret;
 	uint8_t *ecc_calc = chip->ecc.calc_buf;
+	int ret;
 
 	ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
 	if (ret)
@@ -1594,7 +1594,7 @@ static int omap_write_subpage_bch(struct nand_chip *chip, u32 offset,
 	chip->legacy.write_buf(chip, buf, mtd->writesize);
 
 	for (step = 0; step < ecc_steps; step++) {
-		/* mask ECC of un-touched subpages by padding 0xFF */
+		/* Mask ECC of un-touched subpages with 0xFFs */
 		if (step < start_step || step > end_step)
 			memset(ecc_calc, 0xff, ecc_bytes);
 		else
@@ -1607,8 +1607,10 @@ static int omap_write_subpage_bch(struct nand_chip *chip, u32 offset,
 		ecc_calc += ecc_bytes;
 	}
 
-	/* copy calculated ECC for whole page to chip->buffer->oob */
-	/* this include masked-value(0xFF) for unwritten subpages */
+	/*
+	 * Copy the calculated ECC for the whole page including the
+	 * masked values (0xFF) corresponding to unwritten subpages.
+	 */
 	ecc_calc = chip->ecc.calc_buf;
 	ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
 					 chip->ecc.total);
@@ -1641,8 +1643,8 @@ static int omap_read_page_bch(struct nand_chip *chip, uint8_t *buf,
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	uint8_t *ecc_calc = chip->ecc.calc_buf;
 	uint8_t *ecc_code = chip->ecc.code_buf;
-	int stat, ret;
 	unsigned int max_bitflips = 0;
+	int stat, ret;
 
 	ret = nand_read_page_op(chip, page, 0, NULL, 0);
 	if (ret)
-- 
2.27.0


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

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

* [PATCH 5/5] mtd: rawnand: omap: Add larger page NAND chips support
  2021-06-10 13:49 [PATCH 0/5] AM335x large page support Miquel Raynal
                   ` (3 preceding siblings ...)
  2021-06-10 13:49 ` [PATCH 4/5] mtd: rawnand: omap: Various style fixes Miquel Raynal
@ 2021-06-10 13:49 ` Miquel Raynal
  2021-06-10 14:49   ` [External] " Barnett, Ryan J                            Collins
  2021-06-11 19:01   ` Miquel Raynal
  4 siblings, 2 replies; 11+ messages in thread
From: Miquel Raynal @ 2021-06-10 13:49 UTC (permalink / raw)
  To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett, Miquel Raynal

There is no reason to be limited to 4kiB page NAND chips just because
this is the maximum length the ELM is able to handle in one go. Just
call the ELM several times and it will process as many data as needed.

Here we introduce the concept of ECC page (which is at most 4kiB). The
ELM will be sought as many times as there are ECC pages.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/raw/omap2.c    | 179 ++++++++++++++++++++------------
 drivers/mtd/nand/raw/omap_elm.c |   2 +-
 2 files changed, 114 insertions(+), 67 deletions(-)

diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c
index 71cd659cd876..7497bc1d30eb 100644
--- a/drivers/mtd/nand/raw/omap2.c
+++ b/drivers/mtd/nand/raw/omap2.c
@@ -171,6 +171,10 @@ struct omap_nand_info {
 	struct device			*elm_dev;
 	/* NAND ready gpio */
 	struct gpio_desc		*ready_gpiod;
+	unsigned int			neccpg;
+	unsigned int			nsteps_per_eccpg;
+	unsigned int			eccpg_size;
+	unsigned int			eccpg_bytes;
 };
 
 static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd)
@@ -1354,7 +1358,7 @@ static int omap_elm_correct_data(struct nand_chip *chip, u_char *data,
 {
 	struct omap_nand_info *info = mtd_to_omap(nand_to_mtd(chip));
 	struct nand_ecc_ctrl *ecc = &info->nand.ecc;
-	int eccsteps = info->nand.ecc.steps;
+	int eccsteps = info->nsteps_per_eccpg;
 	int i , j, stat = 0;
 	int eccflag, actual_eccbytes;
 	struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
@@ -1524,28 +1528,37 @@ static int omap_write_page_bch(struct nand_chip *chip, const uint8_t *buf,
 			       int oob_required, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct omap_nand_info *info = mtd_to_omap(mtd);
 	uint8_t *ecc_calc = chip->ecc.calc_buf;
+	unsigned int eccpg;
 	int ret;
 
 	ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
 	if (ret)
 		return ret;
 
-	/* Enable GPMC ecc engine */
-	chip->ecc.hwctl(chip, NAND_ECC_WRITE);
+	for (eccpg = 0; eccpg < info->neccpg; eccpg++) {
+		/* Enable GPMC ecc engine */
+		chip->ecc.hwctl(chip, NAND_ECC_WRITE);
 
-	/* Write data */
-	chip->legacy.write_buf(chip, buf, mtd->writesize);
+		/* Write data */
+		chip->legacy.write_buf(chip, buf + (eccpg * info->eccpg_size),
+				       info->eccpg_size);
 
-	/* Update ecc vector from GPMC result registers */
-	ret = omap_calculate_ecc_bch_multi(mtd, buf, &ecc_calc[0]);
-	if (ret)
-		return ret;
+		/* Update ecc vector from GPMC result registers */
+		ret = omap_calculate_ecc_bch_multi(mtd,
+						   buf + (eccpg * info->eccpg_size),
+						   ecc_calc);
+		if (ret)
+			return ret;
 
-	ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
-					 chip->ecc.total);
-	if (ret)
-		return ret;
+		ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc,
+						 chip->oob_poi,
+						 eccpg * info->eccpg_bytes,
+						 info->eccpg_bytes);
+		if (ret)
+			return ret;
+	}
 
 	/* Write ecc vector to OOB area */
 	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
@@ -1569,12 +1582,13 @@ static int omap_write_subpage_bch(struct nand_chip *chip, u32 offset,
 				  int oob_required, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct omap_nand_info *info = mtd_to_omap(mtd);
 	u8 *ecc_calc = chip->ecc.calc_buf;
 	int ecc_size      = chip->ecc.size;
 	int ecc_bytes     = chip->ecc.bytes;
-	int ecc_steps     = chip->ecc.steps;
 	u32 start_step = offset / ecc_size;
 	u32 end_step   = (offset + data_len - 1) / ecc_size;
+	unsigned int eccpg;
 	int step, ret = 0;
 
 	/*
@@ -1587,36 +1601,44 @@ static int omap_write_subpage_bch(struct nand_chip *chip, u32 offset,
 	if (ret)
 		return ret;
 
-	/* Enable GPMC ECC engine */
-	chip->ecc.hwctl(chip, NAND_ECC_WRITE);
+	for (eccpg = 0; eccpg < info->neccpg; eccpg++) {
+		/* Enable GPMC ECC engine */
+		chip->ecc.hwctl(chip, NAND_ECC_WRITE);
 
-	/* Write data */
-	chip->legacy.write_buf(chip, buf, mtd->writesize);
+		/* Write data */
+		chip->legacy.write_buf(chip, buf + (eccpg * info->eccpg_size),
+				       info->eccpg_size);
 
-	for (step = 0; step < ecc_steps; step++) {
-		/* Mask ECC of un-touched subpages with 0xFFs */
-		if (step < start_step || step > end_step)
-			memset(ecc_calc, 0xff, ecc_bytes);
-		else
-			ret = _omap_calculate_ecc_bch(mtd, buf, ecc_calc, step);
+		for (step = 0; step < info->nsteps_per_eccpg; step++) {
+			unsigned int base_step = eccpg * info->nsteps_per_eccpg;
+			const u8 *bufoffs = buf + (eccpg * info->eccpg_size);
 
+			/* Mask ECC of un-touched subpages with 0xFFs */
+			if ((step + base_step) < start_step ||
+			    (step + base_step) > end_step)
+				memset(ecc_calc + (step * ecc_bytes), 0xff,
+				       ecc_bytes);
+			else
+				ret = _omap_calculate_ecc_bch(mtd,
+							      bufoffs + (step * ecc_size),
+							      ecc_calc + (step * ecc_bytes),
+							      step);
+
+			if (ret)
+				return ret;
+		}
+
+		/*
+		 * Copy the calculated ECC for the whole page including the
+		 * masked values (0xFF) corresponding to unwritten subpages.
+		 */
+		ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi,
+						 eccpg * info->eccpg_bytes,
+						 info->eccpg_bytes);
 		if (ret)
 			return ret;
-
-		buf += ecc_size;
-		ecc_calc += ecc_bytes;
 	}
 
-	/*
-	 * Copy the calculated ECC for the whole page including the
-	 * masked values (0xFF) corresponding to unwritten subpages.
-	 */
-	ecc_calc = chip->ecc.calc_buf;
-	ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
-					 chip->ecc.total);
-	if (ret)
-		return ret;
-
 	/* write OOB buffer to NAND device */
 	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
 
@@ -1641,46 +1663,60 @@ static int omap_read_page_bch(struct nand_chip *chip, uint8_t *buf,
 			      int oob_required, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct omap_nand_info *info = mtd_to_omap(mtd);
 	uint8_t *ecc_calc = chip->ecc.calc_buf;
 	uint8_t *ecc_code = chip->ecc.code_buf;
-	unsigned int max_bitflips = 0;
+	unsigned int max_bitflips = 0, eccpg;
 	int stat, ret;
 
 	ret = nand_read_page_op(chip, page, 0, NULL, 0);
 	if (ret)
 		return ret;
 
-	/* Enable GPMC ecc engine */
-	chip->ecc.hwctl(chip, NAND_ECC_READ);
+	for (eccpg = 0; eccpg < info->neccpg; eccpg++) {
+		/* Enable GPMC ecc engine */
+		chip->ecc.hwctl(chip, NAND_ECC_READ);
 
-	/* Read data */
-	chip->legacy.read_buf(chip, buf, mtd->writesize);
+		/* Read data */
+		ret = nand_change_read_column_op(chip, eccpg * info->eccpg_size,
+						 buf + (eccpg * info->eccpg_size),
+						 info->eccpg_size, false);
+		if (ret)
+			return ret;
 
-	/* Read oob bytes */
-	ret = nand_change_read_column_op(chip,
-					 mtd->writesize + BBM_LEN,
-					 chip->oob_poi + BBM_LEN,
-					 chip->ecc.total, false);
-	if (ret)
-		return ret;
+		/* Read oob bytes */
+		ret = nand_change_read_column_op(chip,
+						 mtd->writesize + BBM_LEN +
+						 (eccpg * info->eccpg_bytes),
+						 chip->oob_poi + BBM_LEN +
+						 (eccpg * info->eccpg_bytes),
+						 info->eccpg_bytes, false);
+		if (ret)
+			return ret;
 
-	/* Calculate ecc bytes */
-	ret = omap_calculate_ecc_bch_multi(mtd, buf, ecc_calc);
-	if (ret)
-		return ret;
+		/* Calculate ecc bytes */
+		ret = omap_calculate_ecc_bch_multi(mtd,
+						   buf + (eccpg * info->eccpg_size),
+						   ecc_calc);
+		if (ret)
+			return ret;
 
-	ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
-					 chip->ecc.total);
-	if (ret)
-		return ret;
+		ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code,
+						 chip->oob_poi,
+						 eccpg * info->eccpg_bytes,
+						 info->eccpg_bytes);
+		if (ret)
+			return ret;
 
-	stat = chip->ecc.correct(chip, buf, ecc_code, ecc_calc);
-
-	if (stat < 0) {
-		mtd->ecc_stats.failed++;
-	} else {
-		mtd->ecc_stats.corrected += stat;
-		max_bitflips = max_t(unsigned int, max_bitflips, stat);
+		stat = chip->ecc.correct(chip,
+					 buf + (eccpg * info->eccpg_size),
+					 ecc_code, ecc_calc);
+		if (stat < 0) {
+			mtd->ecc_stats.failed++;
+		} else {
+			mtd->ecc_stats.corrected += stat;
+			max_bitflips = max_t(unsigned int, max_bitflips, stat);
+		}
 	}
 
 	return max_bitflips;
@@ -2144,9 +2180,20 @@ static int omap_nand_attach_chip(struct nand_chip *chip)
 	}
 
 	if (elm_bch_strength >= 0) {
+		chip->ecc.steps = mtd->writesize / chip->ecc.size;
+		info->neccpg = chip->ecc.steps / ERROR_VECTOR_MAX;
+		if (info->neccpg) {
+			info->nsteps_per_eccpg = ERROR_VECTOR_MAX;
+		} else {
+			info->neccpg = 1;
+			info->nsteps_per_eccpg = chip->ecc.steps;
+		}
+		info->eccpg_size = info->nsteps_per_eccpg * chip->ecc.size;
+		info->eccpg_bytes = info->nsteps_per_eccpg * chip->ecc.bytes;
+
 		err = elm_config(info->elm_dev, elm_bch_strength,
-				 mtd->writesize / chip->ecc.size,
-				 chip->ecc.size, chip->ecc.bytes);
+				 info->nsteps_per_eccpg, chip->ecc.size,
+				 chip->ecc.bytes);
 		if (err < 0)
 			return err;
 	}
diff --git a/drivers/mtd/nand/raw/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c
index 4b799521a427..29a7d62c8367 100644
--- a/drivers/mtd/nand/raw/omap_elm.c
+++ b/drivers/mtd/nand/raw/omap_elm.c
@@ -113,7 +113,7 @@ int elm_config(struct device *dev, enum bch_ecc bch_type,
 		return -EINVAL;
 	}
 	/* ELM support 8 error syndrome process */
-	if (ecc_steps > ERROR_VECTOR_MAX) {
+	if (ecc_steps > ERROR_VECTOR_MAX && ecc_steps % ERROR_VECTOR_MAX) {
 		dev_err(dev, "unsupported config ecc-step=%d\n", ecc_steps);
 		return -EINVAL;
 	}
-- 
2.27.0


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

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

* RE: [External] [PATCH 5/5] mtd: rawnand: omap: Add larger page NAND chips support
  2021-06-10 13:49 ` [PATCH 5/5] mtd: rawnand: omap: Add larger page NAND chips support Miquel Raynal
@ 2021-06-10 14:49   ` Barnett, Ryan J                            Collins
  2021-06-11 19:01   ` Miquel Raynal
  1 sibling, 0 replies; 11+ messages in thread
From: Barnett, Ryan J                            Collins @ 2021-06-10 14:49 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni


> From: Miquel Raynal <miquel.raynal@bootlin.com>
> Sent: Thursday, June 10, 2021 08:49
> 
> There is no reason to be limited to 4kiB page NAND chips just because this is
> the maximum length the ELM is able to handle in one go. Just call the ELM
> several times and it will process as many data as needed.
> 
> Here we introduce the concept of ECC page (which is at most 4kiB). The ELM
> will be sought as many times as there are ECC pages.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  drivers/mtd/nand/raw/omap2.c    | 179 ++++++++++++++++++++------------
>  drivers/mtd/nand/raw/omap_elm.c |   2 +-
>  2 files changed, 114 insertions(+), 67 deletions(-)

Tested the series on a TI Sitara Processor with a NAND device which has 8KiB page size.

Tested-by: Ryan Barnett <ryan.barnett@collins.com>
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH 5/5] mtd: rawnand: omap: Add larger page NAND chips support
  2021-06-10 13:49 ` [PATCH 5/5] mtd: rawnand: omap: Add larger page NAND chips support Miquel Raynal
  2021-06-10 14:49   ` [External] " Barnett, Ryan J                            Collins
@ 2021-06-11 19:01   ` Miquel Raynal
  1 sibling, 0 replies; 11+ messages in thread
From: Miquel Raynal @ 2021-06-11 19:01 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett

On Thu, 2021-06-10 at 13:49:06 UTC, Miquel Raynal wrote:
> There is no reason to be limited to 4kiB page NAND chips just because
> this is the maximum length the ELM is able to handle in one go. Just
> call the ELM several times and it will process as many data as needed.
> 
> Here we introduce the concept of ECC page (which is at most 4kiB). The
> ELM will be sought as many times as there are ECC pages.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Tested-by: Ryan Barnett <ryan.barnett@collins.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] 11+ messages in thread

* Re: [PATCH 4/5] mtd: rawnand: omap: Various style fixes
  2021-06-10 13:49 ` [PATCH 4/5] mtd: rawnand: omap: Various style fixes Miquel Raynal
@ 2021-06-11 19:01   ` Miquel Raynal
  0 siblings, 0 replies; 11+ messages in thread
From: Miquel Raynal @ 2021-06-11 19:01 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett

On Thu, 2021-06-10 at 13:49:05 UTC, Miquel Raynal wrote:
> Fix the comments style, declare the variables in a reverse Christmas
> tree order, add an upper case character at the beginning of a sentence.
> 
> 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] 11+ messages in thread

* Re: [PATCH 3/5] mtd: rawnand: omap: Check return values
  2021-06-10 13:49 ` [PATCH 3/5] mtd: rawnand: omap: Check return values Miquel Raynal
@ 2021-06-11 19:01   ` Miquel Raynal
  0 siblings, 0 replies; 11+ messages in thread
From: Miquel Raynal @ 2021-06-11 19:01 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett

On Thu, 2021-06-10 at 13:49:04 UTC, Miquel Raynal wrote:
> Check the return value of many helpers which might return error codes.
> 
> 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] 11+ messages in thread

* Re: [PATCH 1/5] mtd: rawnand: omap: Aggregate the HW configuration of the ELM
  2021-06-10 13:49 ` [PATCH 1/5] mtd: rawnand: omap: Aggregate the HW configuration of the ELM Miquel Raynal
@ 2021-06-11 19:01   ` Miquel Raynal
  0 siblings, 0 replies; 11+ messages in thread
From: Miquel Raynal @ 2021-06-11 19:01 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Tudor Ambarus, linux-mtd
  Cc: Thomas Petazzoni, ryan.barnett

On Thu, 2021-06-10 at 13:49:02 UTC, Miquel Raynal wrote:
> Instead of calling elm_config() for each possible BCH configuration,
> just save the BCH configuration that must be applied and use it in a
> single call at the bottom.
> 
> 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] 11+ messages in thread

end of thread, other threads:[~2021-06-11 19:35 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-10 13:49 [PATCH 0/5] AM335x large page support Miquel Raynal
2021-06-10 13:49 ` [PATCH 1/5] mtd: rawnand: omap: Aggregate the HW configuration of the ELM Miquel Raynal
2021-06-11 19:01   ` Miquel Raynal
2021-06-10 13:49 ` [PATCH 2/5] mtd: rawnand: omap: Rename a macro Miquel Raynal
2021-06-10 13:49 ` [PATCH 3/5] mtd: rawnand: omap: Check return values Miquel Raynal
2021-06-11 19:01   ` Miquel Raynal
2021-06-10 13:49 ` [PATCH 4/5] mtd: rawnand: omap: Various style fixes Miquel Raynal
2021-06-11 19:01   ` Miquel Raynal
2021-06-10 13:49 ` [PATCH 5/5] mtd: rawnand: omap: Add larger page NAND chips support Miquel Raynal
2021-06-10 14:49   ` [External] " Barnett, Ryan J                            Collins
2021-06-11 19:01   ` Miquel Raynal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.