Skip to contentSkip to conversation

mtd: rawnand: brcmnand: ECC error handling on EDU transfers

PATCH Applied Kamal Dasu 2 participants 5 messages Jun 12, 2020 – Jun 15, 2020

Subsystems (3)
lore
Share & tools
lore

Kamal Dasu

author
#0 lore raw

v2 cover mtd: rawnand: brcmnand: ECC error handling on EDU transfers

V2 changes:

"mtd: rawnand: brcmnand: Don't default to edu transfer"
- no change

"mtd: rawnand: brcmnand: ECC error handling on EDU transfers"
- Fix typos in commit message and clarify bitflips threhold use
- Fix typos in code comments
- change bool edu_read to bool edu_err in brcmnand_read()

Kamal Dasu (2):
mtd: rawnand: brcmnand: Don't default to edu transfer
mtd: rawnand: brcmnand: ECC error handling on EDU transfers

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 31 ++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)
Signature · 1 line
2.17.1
author
#1 lore raw

PATCH v2 1/2 mtd: rawnand: brcmnand: Don't default to edu transfer

When flash-dma is absent do not default to using flash-edu. Make sure flash-edu is enabled before setting EDU transfer function.

Fixes a5d53ad26a8b ("mtd: rawnand: brcmnand: Add support for flash-edu for dma transfers")
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/mtd/nand/raw/brcmnand/brcmnand.c +3 -2
index 8f9ffb46a09f..0c1d6e543586 100644
@@ -2953,8 +2953,9 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 		if (ret < 0)
 			goto err;
 
-		/* set edu transfer function to call */
-		ctrl->dma_trans = brcmnand_edu_trans;
+		if (has_edu(ctrl))
+			/* set edu transfer function to call */
+			ctrl->dma_trans = brcmnand_edu_trans;
 	}
 
 	/* Disable automatic device ID config, direct addressing */
Signature · 1 line
2.17.1
maintainer Applied
#2 lore raw

Re: [PATCH v2 1/2] mtd: rawnand: brcmnand: Don't default to edu transfer

Quoted 6 lines · Kamal Dasu

When flash-dma is absent do not default to using flash-edu. Make sure flash-edu is enabled before setting EDU transfer function.

Fixes a5d53ad26a8b ("mtd: rawnand: brcmnand: Add support for flash-edu for dma transfers")

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

Miquel

author
#3 lore raw

PATCH v2 2/2 mtd: rawnand: brcmnand: ECC error handling on EDU transfers

In reply to Kamal Dasu

Implement ECC correctable and uncorrectable error handling for EDU reads. If ECC correctable bitflips are encountered on EDU transfer, read page again using PIO. This is needed due to a NAND controller limitation where corrected data is not transferred to the DMA buffer on ECC error. This applies to ECC correctable errors that are reported by the controller hardware based on set number of bitflips threshold in the controller threshold register, bitflips below the threshold are corrected silently and are not reported by the controller hardware.

Fixes a5d53ad26a8b ("mtd: rawnand: brcmnand: Add support for flash-edu for dma transfers")
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 26 ++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
drivers/mtd/nand/raw/brcmnand/brcmnand.c +26 -0
index 0c1d6e543586..131d5d6e2626 100644
@@ -1855,6 +1855,22 @@ static int brcmnand_edu_trans(struct brcmnand_host *host, u64 addr, u32 *buf,
 	edu_writel(ctrl, EDU_STOP, 0); /* force stop */
 	edu_readl(ctrl, EDU_STOP);
 
+	if (!ret && edu_cmd == EDU_CMD_READ) {
+		u64 err_addr = 0;
+
+		/*
+		 * check for ECC errors here, subpage ECC errors are
+		 * retained in ECC error address register
+		 */
+		err_addr = brcmnand_get_uncorrecc_addr(ctrl);
+		if (!err_addr) {
+			err_addr = brcmnand_get_correcc_addr(ctrl);
+			if (err_addr)
+				ret = -EUCLEAN;
+		} else
+			ret = -EBADMSG;
+	}
+
 	return ret;
 }
 
@@ -2058,6 +2074,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
 	u64 err_addr = 0;
 	int err;
 	bool retry = true;
+	bool edu_err = false;
 
 	dev_dbg(ctrl->dev, "read %llx -> %p\n", (unsigned long long)addr, buf);
 
@@ -2075,6 +2092,10 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
 			else
 				return -EIO;
 		}
+
+		if (has_edu(ctrl) && err_addr)
+			edu_err = true;
+
 	} else {
 		if (oob)
 			memset(oob, 0x99, mtd->oobsize);
@@ -2122,6 +2143,11 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
 	if (mtd_is_bitflip(err)) {
 		unsigned int corrected = brcmnand_count_corrected(ctrl);
 
+		/* in case of EDU correctable error we read again using PIO */
+		if (edu_err)
+			err = brcmnand_read_by_pio(mtd, chip, addr, trans, buf,
+						   oob, &err_addr);
+
 		dev_dbg(ctrl->dev, "corrected error at 0x%llx\n",
 			(unsigned long long)err_addr);
 		mtd->ecc_stats.corrected += corrected;
Signature · 1 line
2.17.1
maintainer Applied
#4 lore raw
Quoted 11 lines · Kamal Dasu

Implement ECC correctable and uncorrectable error handling for EDU reads. If ECC correctable bitflips are encountered on EDU transfer, read page again using PIO. This is needed due to a NAND controller limitation where corrected data is not transferred to the DMA buffer on ECC error. This applies to ECC correctable errors that are reported by the controller hardware based on set number of bitflips threshold in the controller threshold register, bitflips below the threshold are corrected silently and are not reported by the controller hardware.

Fixes a5d53ad26a8b ("mtd: rawnand: brcmnand: Add support for flash-edu for dma transfers")

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

Miquel