mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 24/26] mtd: nand: atmel: Fix pmecc ecc settings
Date: Fri,  6 Nov 2020 14:38:58 +0100	[thread overview]
Message-ID: <20201106133900.2656-25-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20201106133900.2656-1-s.hauer@pengutronix.de>

pmecc has hardcoded steps of 1 and ecc size of the nand chips page size.
This is wrong, the ECC engine does 512 or 1024 bytes per step. Adjust
ecc size and step size accordingly. Also, fix ecc strength which was
hardcoded to 1.
With this the correct number of bitflips is reported, which should be
the number of bitflips per ecc step, not the one for the whole page.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/atmel_nand.c | 58 ++++++++++-------------------------
 1 file changed, 16 insertions(+), 42 deletions(-)

diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 438a967bd6..db13f5b7e4 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -107,8 +107,6 @@ struct atmel_nand_host {
 	void			*ecc_code;
 };
 
-static struct nand_ecclayout atmel_pmecc_oobinfo;
-
 /*
  * Enable NAND.
  */
@@ -201,22 +199,6 @@ static int pmecc_get_ecc_bytes(int cap, int sector_size)
 	return (m * cap + 7) / 8;
 }
 
-static void pmecc_config_ecc_layout(struct nand_ecclayout *layout,
-	int oobsize, int ecc_len)
-{
-	int i;
-
-	layout->eccbytes = ecc_len;
-
-	/* ECC will occupy the last ecc_len bytes continuously */
-	for (i = 0; i < ecc_len; i++)
-		layout->eccpos[i] = oobsize - ecc_len + i;
-
-	layout->oobfree[0].offset = 2;
-	layout->oobfree[0].length =
-		oobsize - ecc_len - layout->oobfree[0].offset;
-}
-
 static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
 {
 	int table_size;
@@ -574,7 +556,7 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf)
 {
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
 	struct atmel_nand_host *host = nand_chip->priv;
-	int i, err_nbr, ret, bitflips = 0;
+	int i, err_nbr, ret, max_bitflips = 0;
 	uint8_t *buf_pos;
 	uint8_t *ecc_code = host->ecc_code;
 
@@ -583,7 +565,7 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < nand_chip->ecc.bytes; i++)
+	for (i = 0; i < nand_chip->ecc.bytes * nand_chip->ecc.steps; i++)
 		if (ecc_code[i] != 0xff)
 			goto normal_check;
 	/* Erased page, return OK */
@@ -608,13 +590,13 @@ normal_check:
 				pmecc_correct_data(mtd, buf_pos, ecc_code, i,
 					host->pmecc_bytes_per_sector, err_nbr);
 				mtd->ecc_stats.corrected += err_nbr;
-				bitflips += err_nbr;
+				max_bitflips = max(max_bitflips, err_nbr);
 			}
 		}
 		pmecc_stat >>= 1;
 	}
 
-	return bitflips;
+	return max_bitflips;
 }
 
 static int atmel_nand_pmecc_read_page(struct nand_chip *chip, uint8_t *buf,
@@ -622,7 +604,6 @@ static int atmel_nand_pmecc_read_page(struct nand_chip *chip, uint8_t *buf,
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct atmel_nand_host *host = chip->priv;
-	int eccsize = chip->ecc.size;
 	uint32_t stat;
 	int ret;
 
@@ -636,7 +617,7 @@ static int atmel_nand_pmecc_read_page(struct nand_chip *chip, uint8_t *buf,
 
 	nand_read_page_op(chip, page, 0, NULL, 0);
 
-	chip->legacy.read_buf(chip, buf, eccsize);
+	chip->legacy.read_buf(chip, buf, mtd->writesize);
 	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);
 
 	ret = wait_on_timeout(PMECC_MAX_TIMEOUT_MS,
@@ -711,7 +692,7 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
 	struct nand_chip *nand_chip = mtd_to_nand(mtd);
 	struct atmel_nand_host *host = nand_chip->priv;
 	uint32_t val = 0;
-	struct nand_ecclayout *ecc_layout;
+	int eccbytes;
 
 	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
 	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
@@ -758,11 +739,10 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
 		| PMECC_CFG_AUTO_DISABLE);
 	pmecc_writel(host->ecc, CFG, val);
 
-	ecc_layout = host->ecclayout;
+	eccbytes = host->pmecc_sector_number * host->pmecc_bytes_per_sector;
 	pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
-	pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
-	pmecc_writel(host->ecc, EADDR,
-			ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
+	pmecc_writel(host->ecc, SADDR, mtd->oobsize - eccbytes);
+	pmecc_writel(host->ecc, EADDR, mtd->oobsize - 1);
 	/* See datasheet about PMECC Clock Control Register */
 	pmecc_writel(host->ecc, CLK, 2);
 	pmecc_writel(host->ecc, IDR, 0xff);
@@ -914,9 +894,6 @@ static int __init atmel_pmecc_nand_init_params(struct device_d *dev,
 		host->board->pmecc_lookup_table_offset = 0;
 	}
 
-	/* ECC is calculated for the whole page (1 step) */
-	nand_chip->ecc.size = mtd->writesize;
-
 	/* set ECC page size and oob layout */
 	switch (mtd->writesize) {
 	case 2048:
@@ -932,18 +909,16 @@ static int __init atmel_pmecc_nand_init_params(struct device_d *dev,
 		host->pmecc_index_of = host->pmecc_rom_base +
 			host->board->pmecc_lookup_table_offset;
 
-		nand_chip->ecc.steps = 1;
-		nand_chip->ecc.bytes = host->pmecc_bytes_per_sector *
-				       host->pmecc_sector_number;
+		nand_chip->ecc.steps = host->pmecc_sector_number;
+		nand_chip->ecc.bytes = host->pmecc_bytes_per_sector;
+		nand_chip->ecc.size = sector_size;
+		nand_chip->ecc.strength = cap;
+
 		if (nand_chip->ecc.bytes > mtd->oobsize - 2) {
 			dev_err(host->dev, "No room for ECC bytes\n");
 			return -EINVAL;
 		}
-		pmecc_config_ecc_layout(&atmel_pmecc_oobinfo,
-					mtd->oobsize,
-					nand_chip->ecc.bytes);
-		host->ecclayout = &atmel_pmecc_oobinfo;
-		mtd_set_ecclayout(mtd, host->ecclayout);
+		mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
 		break;
 	case 512:
 	case 1024:
@@ -1016,7 +991,6 @@ static int atmel_nand_read_page(struct nand_chip *chip, uint8_t *buf,
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct atmel_nand_host *host = chip->priv;
-	int eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
 	uint32_t *eccpos = host->ecclayout->eccpos;
 	uint8_t *p = buf;
@@ -1027,7 +1001,7 @@ static int atmel_nand_read_page(struct nand_chip *chip, uint8_t *buf,
 	nand_read_page_op(chip, page, 0, NULL, 0);
 
 	/* read the page */
-	chip->legacy.read_buf(chip, p, eccsize);
+	chip->legacy.read_buf(chip, p, mtd->writesize);
 
 	/* move to ECC position if needed */
 	if (eccpos[0] != 0) {
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2020-11-06 13:39 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-06 13:38 [PATCH 00/26] Update nand layer to Linux-5.9 Sascha Hauer
2020-11-06 13:38 ` [PATCH 01/26] mtd: Drop asynchronous erase support Sascha Hauer
2020-11-06 13:38 ` [PATCH 02/26] mtd: nand: remove unused header file Sascha Hauer
2020-11-06 13:38 ` [PATCH 03/26] mtd: nand: drop unused erase_cmd hook Sascha Hauer
2020-11-06 13:38 ` [PATCH 04/26] mtd: nand: drop unused errstat hook Sascha Hauer
2020-11-06 13:38 ` [PATCH 05/26] mtd: nand: Pass struct nand_chip around Sascha Hauer
2020-11-06 13:38 ` [PATCH 06/26] mtd: Add underscore prefix to mtd hooks Sascha Hauer
2020-11-06 13:38 ` [PATCH 07/26] mtd: Use classdev->parent Sascha Hauer
2020-11-06 13:38 ` [PATCH 08/26] mtd: rename class_dev to dev Sascha Hauer
2020-11-06 13:38 ` [PATCH 09/26] mtd: rename master to parent Sascha Hauer
2020-11-06 13:38 ` [PATCH 10/26] lib: Add match_string() Sascha Hauer
2020-11-06 13:38 ` [PATCH 11/26] mtd: nand: move function hooks to struct nand_legacy Sascha Hauer
2020-11-06 13:38 ` [PATCH 12/26] mtd: Add ecc_step_size Sascha Hauer
2020-11-06 13:38 ` [PATCH 13/26] mtd: nand: omap_gpmc: Drop unused variable Sascha Hauer
2020-11-06 13:38 ` [PATCH 14/26] mtd: nand: omap_gpmc: Fix wrong length check Sascha Hauer
2020-11-06 13:38 ` [PATCH 15/26] mtd: nand: omap_gpmc: Add missing bch16 string Sascha Hauer
2020-11-06 13:38 ` [PATCH 16/26] mtd: nand: denali: Drop multichip support Sascha Hauer
2020-11-06 13:38 ` [PATCH 17/26] mtd: nand: marvell: Use nand_to_mtd() Sascha Hauer
2020-11-06 13:38 ` [PATCH 18/26] mtd: nand: gpmi: " Sascha Hauer
2020-11-06 13:38 ` [PATCH 19/26] mtd: nand: orion: " Sascha Hauer
2020-11-06 13:38 ` [PATCH 20/26] mtd: nand: Update to Linux-5.9 Sascha Hauer
2020-11-06 13:38 ` [PATCH 21/26] mtd: nand: denali: " Sascha Hauer
2020-11-06 13:38 ` [PATCH 22/26] mtd: nand: atmel: Return number of bitflips Sascha Hauer
2020-11-06 13:38 ` [PATCH 23/26] mtd: nand: atmel: drop dead code Sascha Hauer
2020-11-06 13:38 ` Sascha Hauer [this message]
2020-11-06 13:38 ` [PATCH 25/26] nand command: Print OOB information Sascha Hauer
2020-11-06 13:39 ` [PATCH 26/26] nand command: Allow offsets with [kM] suffixes Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201106133900.2656-25-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox