diff options
author | Wolfgang Denk <wd@denx.de> | 2012-03-03 15:15:07 +0100 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2012-03-03 15:15:07 +0100 |
commit | e91004201c4265edf7897c4f8e0c21cd1dce0505 (patch) | |
tree | 97ca0cd21a4909774d9475f3198b610eeb7324c9 /drivers | |
parent | 8a1239e74cdf4d94738eb71928769d6e78bcc78c (diff) | |
parent | cfdae12f37ad126d1198f6c1ffa4ada9e69dd206 (diff) | |
download | u-boot-imx-e91004201c4265edf7897c4f8e0c21cd1dce0505.zip u-boot-imx-e91004201c4265edf7897c4f8e0c21cd1dce0505.tar.gz u-boot-imx-e91004201c4265edf7897c4f8e0c21cd1dce0505.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-nand-flash
* 'master' of git://git.denx.de/u-boot-nand-flash:
cmd_nand.c: Fix 'nand dump' after latest MTD resync
mtd/nand:Fix wrong usage of is_blank() in fsl_ifc_run_command
mtd/nand: Fix IFC driver to support 2K NAND page
nand: reinstate lazy bad block scanning
Revert "nand: make 1-bit software ECC configurable"
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/nand/Makefile | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 79 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 14 |
3 files changed, 49 insertions, 46 deletions
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 998fc73..1d1b628 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -39,7 +39,7 @@ COBJS-y += nand_bbt.o COBJS-y += nand_ids.o COBJS-y += nand_util.o endif -COBJS-$(CONFIG_MTD_ECC_SOFT) += nand_ecc.o +COBJS-y += nand_ecc.o COBJS-y += nand_base.o COBJS-$(CONFIG_NAND_ECC_BCH) += nand_bch.o diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index b3f3c3c..5cac78b 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -1,6 +1,6 @@ /* Integrated Flash Controller NAND Machine Driver * - * Copyright (c) 2011 Freescale Semiconductor, Inc + * Copyright (c) 2012 Freescale Semiconductor, Inc * * Authors: Dipen Dudhat <Dipen.Dudhat@freescale.com> * @@ -221,24 +221,11 @@ static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, u32 *eccstat, unsigned int bufnum) { u32 reg = eccstat[bufnum / 4]; - int errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; - - if (errors == 15) { /* uncorrectable */ - /* Blank pages fail hw ECC checks */ - if (is_blank(mtd, ctrl, bufnum)) - return 1; - - /* - * We disable ECCER reporting in hardware due to - * erratum IFC-A002770 -- so report it now if we - * see an uncorrectable error in ECCSTAT. - */ - ctrl->status |= IFC_NAND_EVTER_STAT_ECCER; - } else if (errors > 0) { - mtd->ecc_stats.corrected += errors; - } + int errors; - return 0; + errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; + + return errors; } /* @@ -279,16 +266,33 @@ static int fsl_ifc_run_command(struct mtd_info *mtd) printf("%s: Write Protect Error\n", __func__); if (ctrl->eccread) { - int bufperpage = mtd->writesize / 512; - int bufnum = (ctrl->page & priv->bufnum_mask) * bufperpage; - int bufnum_end = bufnum + bufperpage - 1; + int errors; + int bufnum = ctrl->page & priv->bufnum_mask; + int sector = bufnum * chip->ecc.steps; + int sector_end = sector + chip->ecc.steps - 1; - for (i = bufnum / 4; i <= bufnum_end / 4; i++) + for (i = sector / 4; i <= sector_end / 4; i++) eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]); - for (i = bufnum; i <= bufnum_end; i++) { - if (check_read_ecc(mtd, ctrl, eccstat, i)) + for (i = sector; i <= sector_end; i++) { + errors = check_read_ecc(mtd, ctrl, eccstat, i); + + if (errors == 15) { + /* + * Uncorrectable error. + * OK only if the whole page is blank. + * + * We disable ECCER reporting due to erratum + * IFC-A002770 -- so report it now if we + * see an uncorrectable error in ECCSTAT. + */ + if (!is_blank(mtd, ctrl, bufnum)) + ctrl->status |= + IFC_NAND_EVTER_STAT_ECCER; break; + } + + mtd->ecc_stats.corrected += errors; } ctrl->eccread = 0; @@ -448,21 +452,19 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, out_be32(&ifc->ifc_nand.nand_fir1, (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT)); - if (column >= mtd->writesize) { - /* OOB area --> READOOB */ - column -= mtd->writesize; - nand_fcr0 |= NAND_CMD_READOOB << - IFC_NAND_FCR0_CMD0_SHIFT; - ctrl->oob = 1; - } else if (column < 256) { - /* First 256 bytes --> READ0 */ - nand_fcr0 |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; - } else { - /* Second 256 bytes --> READ1 */ - nand_fcr0 |= NAND_CMD_READ1 << FCR_CMD0_SHIFT; - } + if (column >= mtd->writesize) + nand_fcr0 |= + NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT; + else + nand_fcr0 |= + NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT; } + if (column >= mtd->writesize) { + /* OOB area --> READOOB */ + column -= mtd->writesize; + ctrl->oob = 1; + } out_be32(&ifc->ifc_nand.nand_fcr0, nand_fcr0); set_addr(mtd, column, page_addr, ctrl->oob); return; @@ -471,7 +473,8 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, /* PAGEPROG reuses all of the setup from SEQIN and adds the length */ case NAND_CMD_PAGEPROG: if (ctrl->oob) - out_be32(&ifc->ifc_nand.nand_fbcr, ctrl->index); + out_be32(&ifc->ifc_nand.nand_fbcr, + ctrl->index - ctrl->column); else out_be32(&ifc->ifc_nand.nand_fbcr, 0); diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 12b960f..44f7b91 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -479,6 +479,11 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, { struct nand_chip *chip = mtd->priv; + if (!(chip->options & NAND_BBT_SCANNED)) { + chip->options |= NAND_BBT_SCANNED; + chip->scan_bbt(mtd); + } + if (!chip->bbt) return chip->block_bad(mtd, ofs, getchip); @@ -3028,10 +3033,6 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.mode = NAND_ECC_SOFT; case NAND_ECC_SOFT: - if (!mtd_nand_has_ecc_soft()) { - printk(KERN_WARNING "CONFIG_MTD_ECC_SOFT not enabled\n"); - return -EINVAL; - } chip->ecc.calculate = nand_calculate_ecc; chip->ecc.correct = nand_correct_data; chip->ecc.read_page = nand_read_page_swecc; @@ -3170,10 +3171,9 @@ int nand_scan_tail(struct mtd_info *mtd) /* Check, if we should skip the bad block table scan */ if (chip->options & NAND_SKIP_BBTSCAN) - return 0; + chip->options |= NAND_BBT_SCANNED; - /* Build bad block table */ - return chip->scan_bbt(mtd); + return 0; } /** |