aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2014-01-03 18:13:33 -0500
committerBrian Norris <computersforpeace@gmail.com>2014-01-14 02:12:58 -0500
commitba84fb5952af114e28ac82adcdef75297701ccc1 (patch)
treef800bac36e01b161b46f30bc308c963a81658d86 /drivers/mtd/nand
parent6f0065b0124bef5e66869ec0b813d251797be439 (diff)
mtd: nand: add generic READ RETRY support
Modern MLC (and even SLC?) NAND can experience a large number of bitflips (beyond the recommended correctability capacity) due to drifts in the voltage threshold (Vt). These bitflips can cause ECC errors to occur well within the expected lifetime of the flash. To account for this, some manufacturers provide a mechanism for shifting the Vt threshold after a corrupted read. The generic pattern seems to be that a particular flash has N read retry modes (where N = 0, traditionally), and after an ECC failure, the host should reconfigure the flash to use the next available mode, then retry the read operation. This process repeats until all bitfips can be corrected or until the host has tried all available retry modes. This patch adds the infrastructure support for a vendor-specific/flash-specific callback, used for setting the read-retry mode (i.e., voltage threshold). For now, this patch always returns the flash to mode 0 (the default mode) after a successful read-retry, according to the flowchart found in Micron's datasheets. This may need to change in the future if it is determined that eventually, mode 0 is insufficient for the majority of the flash cells (and so for performance reasons, we should leave the flash in mode 1, 2, etc.). Signed-off-by: Brian Norris <computersforpeace@gmail.com> Acked-by: Huang Shijie <b32955@freescale.com>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/nand_base.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index b5c3768b32ae..4c2f39f351da 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1410,6 +1410,30 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
1410} 1410}
1411 1411
1412/** 1412/**
1413 * nand_setup_read_retry - [INTERN] Set the READ RETRY mode
1414 * @mtd: MTD device structure
1415 * @retry_mode: the retry mode to use
1416 *
1417 * Some vendors supply a special command to shift the Vt threshold, to be used
1418 * when there are too many bitflips in a page (i.e., ECC error). After setting
1419 * a new threshold, the host should retry reading the page.
1420 */
1421static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
1422{
1423 struct nand_chip *chip = mtd->priv;
1424
1425 pr_debug("setting READ RETRY mode %d\n", retry_mode);
1426
1427 if (retry_mode >= chip->read_retries)
1428 return -EINVAL;
1429
1430 if (!chip->setup_read_retry)
1431 return -EOPNOTSUPP;
1432
1433 return chip->setup_read_retry(mtd, retry_mode);
1434}
1435
1436/**
1413 * nand_do_read_ops - [INTERN] Read data with ECC 1437 * nand_do_read_ops - [INTERN] Read data with ECC
1414 * @mtd: MTD device structure 1438 * @mtd: MTD device structure
1415 * @from: offset to read from 1439 * @from: offset to read from
@@ -1430,6 +1454,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1430 1454
1431 uint8_t *bufpoi, *oob, *buf; 1455 uint8_t *bufpoi, *oob, *buf;
1432 unsigned int max_bitflips = 0; 1456 unsigned int max_bitflips = 0;
1457 int retry_mode = 0;
1433 bool ecc_fail = false; 1458 bool ecc_fail = false;
1434 1459
1435 chipnr = (int)(from >> chip->chip_shift); 1460 chipnr = (int)(from >> chip->chip_shift);
@@ -1454,6 +1479,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1454 if (realpage != chip->pagebuf || oob) { 1479 if (realpage != chip->pagebuf || oob) {
1455 bufpoi = aligned ? buf : chip->buffers->databuf; 1480 bufpoi = aligned ? buf : chip->buffers->databuf;
1456 1481
1482read_retry:
1457 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); 1483 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
1458 1484
1459 /* 1485 /*
@@ -1494,8 +1520,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1494 memcpy(buf, chip->buffers->databuf + col, bytes); 1520 memcpy(buf, chip->buffers->databuf + col, bytes);
1495 } 1521 }
1496 1522
1497 buf += bytes;
1498
1499 if (unlikely(oob)) { 1523 if (unlikely(oob)) {
1500 int toread = min(oobreadlen, max_oobsize); 1524 int toread = min(oobreadlen, max_oobsize);
1501 1525
@@ -1514,8 +1538,24 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1514 nand_wait_ready(mtd); 1538 nand_wait_ready(mtd);
1515 } 1539 }
1516 1540
1517 if (mtd->ecc_stats.failed - ecc_failures) 1541 if (mtd->ecc_stats.failed - ecc_failures) {
1518 ecc_fail = true; 1542 if (retry_mode + 1 <= chip->read_retries) {
1543 retry_mode++;
1544 ret = nand_setup_read_retry(mtd,
1545 retry_mode);
1546 if (ret < 0)
1547 break;
1548
1549 /* Reset failures; retry */
1550 mtd->ecc_stats.failed = ecc_failures;
1551 goto read_retry;
1552 } else {
1553 /* No more retry modes; real failure */
1554 ecc_fail = true;
1555 }
1556 }
1557
1558 buf += bytes;
1519 } else { 1559 } else {
1520 memcpy(buf, chip->buffers->databuf + col, bytes); 1560 memcpy(buf, chip->buffers->databuf + col, bytes);
1521 buf += bytes; 1561 buf += bytes;
@@ -1525,6 +1565,14 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1525 1565
1526 readlen -= bytes; 1566 readlen -= bytes;
1527 1567
1568 /* Reset to retry mode 0 */
1569 if (retry_mode) {
1570 ret = nand_setup_read_retry(mtd, 0);
1571 if (ret < 0)
1572 break;
1573 retry_mode = 0;
1574 }
1575
1528 if (!readlen) 1576 if (!readlen)
1529 break; 1577 break;
1530 1578