
Dear Scott,
could you please test the following patch on top of this big patch to see if ecc.strength problem goes away? I can integrate it into big one then.
From dffea1f073c546ab88f37f219f66d9d1478d4cf1 Mon Sep 17 00:00:00 2001
From: Sergey Lapin slapin@ossfans.org Date: Thu, 17 Jan 2013 18:29:21 +0400 Subject: [PATCH] SQUASHME: mtd: nand: Add ecc.strength support to drivers
Updated the patch according to Josh's request:
From 4d857af69f4383bef246ad0231fc82ce30a1276c Mon Sep 17 00:00:00 2001
From: Sergey Lapin slapin@ossfans.org Date: Thu, 17 Jan 2013 18:29:21 +0400 Subject: [PATCH] SQUASHME: mtd: nand: Add ecc.strength support to drivers
Signed-off-by: Sergey Lapin slapin@ossfans.org --- drivers/mtd/nand/atmel_nand.c | 1 + drivers/mtd/nand/bfin_nand.c | 2 ++ drivers/mtd/nand/davinci_nand.c | 1 + drivers/mtd/nand/diskonchip.c | 1 + drivers/mtd/nand/fsl_elbc_nand.c | 6 ++++++ drivers/mtd/nand/fsl_ifc_nand.c | 1 + drivers/mtd/nand/fsmc_nand.c | 2 ++ drivers/mtd/nand/jz4740_nand.c | 5 +++++ drivers/mtd/nand/mxc_nand.c | 7 +++++++ drivers/mtd/nand/mxs_nand.c | 1 + drivers/mtd/nand/nand_base.c | 1 + drivers/mtd/nand/ndfc.c | 1 + drivers/mtd/nand/nomadik.c | 1 + drivers/mtd/nand/omap_gpmc.c | 1 + drivers/mtd/nand/s3c2410_nand.c | 1 + drivers/mtd/nand/s3c64xx.c | 1 + drivers/mtd/nand/tegra_nand.c | 1 + 17 files changed, 34 insertions(+)
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index b09e7b7..3bfbaf8 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -709,6 +709,7 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
nand->ecc.read_page = atmel_nand_pmecc_read_page; nand->ecc.write_page = atmel_nand_pmecc_write_page; + nand->ecc.strength = cap;
atmel_pmecc_core_init(mtd);
diff --git a/drivers/mtd/nand/bfin_nand.c b/drivers/mtd/nand/bfin_nand.c index c7ddbb2..7e755e8 100644 --- a/drivers/mtd/nand/bfin_nand.c +++ b/drivers/mtd/nand/bfin_nand.c @@ -374,9 +374,11 @@ int board_nand_init(struct nand_chip *chip) if (!NAND_IS_512()) { chip->ecc.bytes = 3; chip->ecc.size = 256; + chip->ecc.strength = 1; } else { chip->ecc.bytes = 6; chip->ecc.size = 512; + chip->ecc.strength = 2; } chip->ecc.mode = NAND_ECC_HW; chip->ecc.calculate = bfin_nfc_calculate_ecc; diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 04b24f3..9777878 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -613,6 +613,7 @@ void davinci_nand_init(struct nand_chip *nand) nand->ecc.mode = NAND_ECC_HW; nand->ecc.size = 512; nand->ecc.bytes = 3; + nand->ecc.strength = 4; nand->ecc.calculate = nand_davinci_calculate_ecc; nand->ecc.correct = nand_davinci_correct_data; nand->ecc.hwctl = nand_davinci_enable_hwecc; diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 104d97f..4cd741e 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -1658,6 +1658,7 @@ static int __init doc_probe(unsigned long physadr) nand->ecc.mode = NAND_ECC_HW_SYNDROME; nand->ecc.size = 512; nand->ecc.bytes = 6; + nand->ecc.strength = 2; nand->bbt_options = NAND_BBT_USE_FLASH;
doc->physadr = physadr; diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 65edbf5..c3f350d 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -781,6 +781,12 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr) nand->ecc.size = 512; nand->ecc.bytes = 3; nand->ecc.steps = 1; + chip->ecc.strength = 1; + /* + * FIXME: can hardware ecc correct 4 bitflips if page size is + * 2k? Then does hardware report number of corrections for this + * case? If so, ecc_stats reporting needs to be fixed as well. + */ } else { /* otherwise fall back to default software ECC */ nand->ecc.mode = NAND_ECC_SOFT; diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 5d47b40..823a2eb 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -871,6 +871,7 @@ int board_nand_init(struct nand_chip *nand) /* Hardware generates ECC per 512 Bytes */ nand->ecc.size = 512; nand->ecc.bytes = 8; + nand->ecc.strength = 1;
switch (csor & CSOR_NAND_PGS_MASK) { case CSOR_NAND_PGS_512: diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 48ca543..fab2aeb 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -453,6 +453,7 @@ int fsmc_nand_init(struct nand_chip *nand) switch (fsmc_version) { case FSMC_VER8: nand->ecc.bytes = 13; + nand->ecc.strength = 8; nand->ecc.correct = fsmc_bch8_correct_data; nand->ecc.read_page = fsmc_read_page_hwecc; if (mtd->writesize == 512) @@ -467,6 +468,7 @@ int fsmc_nand_init(struct nand_chip *nand) break; default: nand->ecc.bytes = 3; + nand->ecc.strength = 1; nand->ecc.layout = &fsmc_ecc1_layout; nand->ecc.correct = nand_correct_data; break; diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index 3ec34f3..3f64dc3 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -253,6 +253,11 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.mode = NAND_ECC_HW_OOB_FIRST; nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; + nand->ecc.strength = 2; + /* + * FIXME: ecc_strength value of 2 bits per 512 bytes of data is a + * conservative guess, given 9 ecc bytes and reed-solomon alg. + */ nand->ecc.layout = &qi_lb60_ecclayout_2gb; nand->chip_delay = 50; nand->options = NAND_USE_FLASH_BBT; diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index c51a012..df2f489 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1222,6 +1222,13 @@ int board_nand_init(struct nand_chip *this) this->ecc.mode = NAND_ECC_HW; }
+ if (this->ecc.mode == NAND_ECC_HW) { + if (is_mxc_nfc_1()) + this->ecc.strength = 1; + else + this->ecc.strength = 4; + } + host->pagesize_2k = 0;
this->ecc.size = 512; diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 422519a..d1f4986 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -1166,6 +1166,7 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.mode = NAND_ECC_HW; nand->ecc.bytes = 9; nand->ecc.size = 512; + nand->ecc.strength = 8;
return 0;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 3ad7783..a2df8ee 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3233,6 +3233,7 @@ int nand_scan_tail(struct mtd_info *mtd) if (!chip->ecc.size) chip->ecc.size = 256; chip->ecc.bytes = 3; + chip->ecc.strength = 1; break;
case NAND_ECC_SOFT_BCH: diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 6ebbb5e..b7a837b 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -216,6 +216,7 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.mode = NAND_ECC_HW; nand->ecc.size = 256; nand->ecc.bytes = 3; + nand->ecc.strength = 1; nand->select_chip = ndfc_select_chip;
#ifdef CONFIG_SYS_NDFC_16BIT diff --git a/drivers/mtd/nand/nomadik.c b/drivers/mtd/nand/nomadik.c index b76f4cb..dc8e513 100644 --- a/drivers/mtd/nand/nomadik.c +++ b/drivers/mtd/nand/nomadik.c @@ -212,6 +212,7 @@ int board_nand_init(struct nand_chip *chip) chip->ecc.mode = NAND_ECC_HW; chip->ecc.bytes = 3; chip->ecc.size = 512; + chip->ecc.strength = 1; chip->ecc.layout = &nomadik_ecc_layout; chip->ecc.calculate = nomadik_ecc_calculate; chip->ecc.hwctl = nomadik_ecc_hwctl; diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index ccf9750..728dfdc 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -274,6 +274,7 @@ void omap_nand_switch_ecc(int32_t hardware) nand->ecc.layout = &hw_nand_oob; nand->ecc.size = 512; nand->ecc.bytes = 3; + nand->ecc.strength = 1; nand->ecc.hwctl = omap_enable_hwecc; nand->ecc.correct = omap_correct_data; nand->ecc.calculate = omap_calculate_ecc; diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index e1a459b..43d8213 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -173,6 +173,7 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.mode = NAND_ECC_HW; nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; + nand->ecc.strength = 1; #else nand->ecc.mode = NAND_ECC_SOFT; #endif diff --git a/drivers/mtd/nand/s3c64xx.c b/drivers/mtd/nand/s3c64xx.c index 87f0341..8c4a737 100644 --- a/drivers/mtd/nand/s3c64xx.c +++ b/drivers/mtd/nand/s3c64xx.c @@ -285,6 +285,7 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.mode = NAND_ECC_HW; nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; + nand->ecc.strength = 1; #else nand->ecc.mode = NAND_ECC_SOFT; #endif /* ! CONFIG_SYS_S3C_NAND_HWECC */ diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c index 854fd21..6afbec6 100644 --- a/drivers/mtd/nand/tegra_nand.c +++ b/drivers/mtd/nand/tegra_nand.c @@ -1014,6 +1014,7 @@ int tegra_nand_init(struct nand_chip *nand, int devnum) nand->ecc.write_page_raw = nand_write_page_raw; nand->ecc.read_oob = nand_read_oob; nand->ecc.write_oob = nand_write_oob; + nand->ecc.strength = 1; nand->select_chip = nand_select_chip; nand->dev_ready = nand_dev_ready; nand->priv = &nand_ctrl;