aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/fsl_elbc_nand.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/fsl_elbc_nand.c')
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 80b5264f0a3..78429380611 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -75,6 +75,7 @@ struct fsl_elbc_fcm_ctrl {
75 unsigned int use_mdr; /* Non zero if the MDR is to be set */ 75 unsigned int use_mdr; /* Non zero if the MDR is to be set */
76 unsigned int oob; /* Non zero if operating on OOB data */ 76 unsigned int oob; /* Non zero if operating on OOB data */
77 unsigned int counter; /* counter for the initializations */ 77 unsigned int counter; /* counter for the initializations */
78 unsigned int max_bitflips; /* Saved during READ0 cmd */
78}; 79};
79 80
80/* These map to the positions used by the FCM hardware ECC generator */ 81/* These map to the positions used by the FCM hardware ECC generator */
@@ -253,6 +254,8 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
253 if (chip->ecc.mode != NAND_ECC_HW) 254 if (chip->ecc.mode != NAND_ECC_HW)
254 return 0; 255 return 0;
255 256
257 elbc_fcm_ctrl->max_bitflips = 0;
258
256 if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) { 259 if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) {
257 uint32_t lteccr = in_be32(&lbc->lteccr); 260 uint32_t lteccr = in_be32(&lbc->lteccr);
258 /* 261 /*
@@ -262,11 +265,16 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
262 * bits 28-31 are uncorrectable errors, marked elsewhere. 265 * bits 28-31 are uncorrectable errors, marked elsewhere.
263 * for small page nand only 1 bit is used. 266 * for small page nand only 1 bit is used.
264 * if the ELBC doesn't have the lteccr register it reads 0 267 * if the ELBC doesn't have the lteccr register it reads 0
268 * FIXME: 4 bits can be corrected on NANDs with 2k pages, so
269 * count the number of sub-pages with bitflips and update
270 * ecc_stats.corrected accordingly.
265 */ 271 */
266 if (lteccr & 0x000F000F) 272 if (lteccr & 0x000F000F)
267 out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */ 273 out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */
268 if (lteccr & 0x000F0000) 274 if (lteccr & 0x000F0000) {
269 mtd->ecc_stats.corrected++; 275 mtd->ecc_stats.corrected++;
276 elbc_fcm_ctrl->max_bitflips = 1;
277 }
270 } 278 }
271 279
272 return 0; 280 return 0;
@@ -738,26 +746,28 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
738 return 0; 746 return 0;
739} 747}
740 748
741static int fsl_elbc_read_page(struct mtd_info *mtd, 749static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
742 struct nand_chip *chip, 750 uint8_t *buf, int oob_required, int page)
743 uint8_t *buf,
744 int page)
745{ 751{
752 struct fsl_elbc_mtd *priv = chip->priv;
753 struct fsl_lbc_ctrl *ctrl = priv->ctrl;
754 struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
755
746 fsl_elbc_read_buf(mtd, buf, mtd->writesize); 756 fsl_elbc_read_buf(mtd, buf, mtd->writesize);
747 fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize); 757 if (oob_required)
758 fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
748 759
749 if (fsl_elbc_wait(mtd, chip) & NAND_STATUS_FAIL) 760 if (fsl_elbc_wait(mtd, chip) & NAND_STATUS_FAIL)
750 mtd->ecc_stats.failed++; 761 mtd->ecc_stats.failed++;
751 762
752 return 0; 763 return elbc_fcm_ctrl->max_bitflips;
753} 764}
754 765
755/* ECC will be calculated automatically, and errors will be detected in 766/* ECC will be calculated automatically, and errors will be detected in
756 * waitfunc. 767 * waitfunc.
757 */ 768 */
758static void fsl_elbc_write_page(struct mtd_info *mtd, 769static void fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
759 struct nand_chip *chip, 770 const uint8_t *buf, int oob_required)
760 const uint8_t *buf)
761{ 771{
762 fsl_elbc_write_buf(mtd, buf, mtd->writesize); 772 fsl_elbc_write_buf(mtd, buf, mtd->writesize);
763 fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize); 773 fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -795,7 +805,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
795 chip->bbt_md = &bbt_mirror_descr; 805 chip->bbt_md = &bbt_mirror_descr;
796 806
797 /* set up nand options */ 807 /* set up nand options */
798 chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR; 808 chip->options = NAND_NO_READRDY;
799 chip->bbt_options = NAND_BBT_USE_FLASH; 809 chip->bbt_options = NAND_BBT_USE_FLASH;
800 810
801 chip->controller = &elbc_fcm_ctrl->controller; 811 chip->controller = &elbc_fcm_ctrl->controller;
@@ -814,11 +824,6 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
814 chip->ecc.size = 512; 824 chip->ecc.size = 512;
815 chip->ecc.bytes = 3; 825 chip->ecc.bytes = 3;
816 chip->ecc.strength = 1; 826 chip->ecc.strength = 1;
817 /*
818 * FIXME: can hardware ecc correct 4 bitflips if page size is
819 * 2k? Then does hardware report number of corrections for this
820 * case? If so, ecc_stats reporting needs to be fixed as well.
821 */
822 } else { 827 } else {
823 /* otherwise fall back to default software ECC */ 828 /* otherwise fall back to default software ECC */
824 chip->ecc.mode = NAND_ECC_SOFT; 829 chip->ecc.mode = NAND_ECC_SOFT;