diff options
author | Kamal Dasu <kdasu.kdev@gmail.com> | 2016-06-09 17:17:55 -0400 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-07-11 08:39:43 +0200 |
commit | bc265323deace1f1472832a87458688796318c47 (patch) | |
tree | 52fabc1eb5cae99a52e6b72665f855c88a5aca52 /drivers/mtd | |
parent | 02b88eea9f9cab82f5f4be234c64466503021f82 (diff) | |
download | blackbird-op-linux-bc265323deace1f1472832a87458688796318c47.tar.gz blackbird-op-linux-bc265323deace1f1472832a87458688796318c47.zip |
mtd: brcmnand: Detect sticky ucorr ecc error on dma reads
This change provides a fix for controller bug where nand
controller could have a possible sticky error after a PIO
followed by a DMA read. The fix retries a read if we see
a uncorr_ecc after read to detect such sticky errors.
The fix applies to only controller version 7.0 and 7.1.
Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/brcmnand/brcmnand.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index f0b067229f7f..faca01d6e0f9 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1659,9 +1659,11 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, struct brcmnand_controller *ctrl = host->ctrl; u64 err_addr = 0; int err; + bool retry = true; dev_dbg(ctrl->dev, "read %llx -> %p\n", (unsigned long long)addr, buf); +try_dmaread: brcmnand_write_reg(ctrl, BRCMNAND_UNCORR_COUNT, 0); if (has_flash_dma(ctrl) && !oob && flash_dma_buf_ok(buf)) { @@ -1683,6 +1685,22 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, if (mtd_is_eccerr(err)) { /* + * On controller version and 7.0, 7.1 , DMA read after a + * prior PIO read that reported uncorrectable error, + * the DMA engine captures this error following DMA read + * cleared only on subsequent DMA read, so just retry once + * to clear a possible false error reported for current DMA + * read + */ + if ((ctrl->nand_version == 0x0700) || + (ctrl->nand_version == 0x0701)) { + if (retry) { + retry = false; + goto try_dmaread; + } + } + + /* * Controller version 7.2 has hw encoder to detect erased page * bitflips, apply sw verification for older controllers only */ |