x1000: add support for simple on-die ECC with NAND flash
Many SPI NAND flash chips have on-die ECC engines that report ECC status via the status feature register. This code handles the common case where ECC status is reported with 2 bits: one bit to indicate if flips were detected & corrected, and another bit to indicate an uncorrectable error. Change-Id: I5d587cd960ca9d090d2629e890724a6bc411e70c
This commit is contained in:
parent
df29c7991a
commit
47cbeb2e67
2 changed files with 23 additions and 0 deletions
|
@ -22,6 +22,7 @@
|
|||
#include "nand-x1000.h"
|
||||
#include "sfc-x1000.h"
|
||||
#include "system.h"
|
||||
#include "logf.h"
|
||||
#include <string.h>
|
||||
|
||||
const struct nand_chip supported_nand_chips[] = {
|
||||
|
@ -151,6 +152,11 @@ static void setup_chip_registers(struct nand_drv* drv)
|
|||
en ? FREG_CFG_QUAD_ENABLE : 0);
|
||||
}
|
||||
|
||||
if(drv->chip->flags & NAND_CHIPFLAG_ON_DIE_ECC) {
|
||||
/* Enable on-die ECC */
|
||||
nand_upd_reg(drv, FREG_CFG, FREG_CFG_ECC_ENABLE, FREG_CFG_ECC_ENABLE);
|
||||
}
|
||||
|
||||
/* Clear OTP bit to access the main data array */
|
||||
nand_upd_reg(drv, FREG_CFG, FREG_CFG_OTP_ENABLE, 0);
|
||||
|
||||
|
@ -249,6 +255,20 @@ int nand_page_read(struct nand_drv* drv, nand_page_t page, void* buffer)
|
|||
sfc_exec(drv->cmd_page_read, page, NULL, 0);
|
||||
nand_wait_busy(drv);
|
||||
sfc_exec(drv->cmd_read_cache, 0, buffer, drv->fpage_size|SFC_READ);
|
||||
|
||||
if(drv->chip->flags & NAND_CHIPFLAG_ON_DIE_ECC) {
|
||||
uint8_t status = nand_get_reg(drv, FREG_STATUS);
|
||||
|
||||
if(status & FREG_STATUS_ECC_UNCOR_ERR) {
|
||||
logf("ecc uncorrectable error on page %08lx", (unsigned long)page);
|
||||
return NAND_ERR_ECC_FAIL;
|
||||
}
|
||||
|
||||
if(status & FREG_STATUS_ECC_HAS_FLIPS) {
|
||||
logf("ecc corrected bitflips on page %08lx", (unsigned long)page);
|
||||
}
|
||||
}
|
||||
|
||||
return NAND_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define NAND_ERR_PROGRAM_FAIL (-2)
|
||||
#define NAND_ERR_ERASE_FAIL (-3)
|
||||
#define NAND_ERR_UNALIGNED (-4)
|
||||
#define NAND_ERR_ECC_FAIL (-5)
|
||||
|
||||
/* keep max page size in sync with the NAND chip table in the .c file */
|
||||
#define NAND_DRV_SCRATCHSIZE 32
|
||||
|
@ -43,6 +44,8 @@
|
|||
#define NAND_CHIPFLAG_HAS_QE_BIT 0x0002
|
||||
/* Chip has 2nd device ID byte */
|
||||
#define NAND_CHIPFLAG_HAS_DEVID2 0x0004
|
||||
/* True if the chip has on-die ECC */
|
||||
#define NAND_CHIPFLAG_ON_DIE_ECC 0x0008
|
||||
|
||||
/* cmd mode a d phase format has data */
|
||||
#define NANDCMD_RESET SFC_CMD(0xff, SFC_TMODE_1_1_1, 0, 0, SFC_PFMT_ADDR_FIRST, 0)
|
||||
|
|
Loading…
Reference in a new issue