diff options
Diffstat (limited to 'drivers/mtd/nand/fsl_elbc_nand.c')
-rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 37 |
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 | ||
741 | static int fsl_elbc_read_page(struct mtd_info *mtd, | 749 | static 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 | */ |
758 | static void fsl_elbc_write_page(struct mtd_info *mtd, | 769 | static 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; |