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.c75
1 files changed, 28 insertions, 47 deletions
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 33d8aad8bba5..eedd8ee2c9ac 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -75,7 +75,6 @@ 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 char *oob_poi; /* Place to write ECC after read back */
79}; 78};
80 79
81/* These map to the positions used by the FCM hardware ECC generator */ 80/* These map to the positions used by the FCM hardware ECC generator */
@@ -244,6 +243,25 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
244 return -EIO; 243 return -EIO;
245 } 244 }
246 245
246 if (chip->ecc.mode != NAND_ECC_HW)
247 return 0;
248
249 if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) {
250 uint32_t lteccr = in_be32(&lbc->lteccr);
251 /*
252 * if command was a full page read and the ELBC
253 * has the LTECCR register, then bits 12-15 (ppc order) of
254 * LTECCR indicates which 512 byte sub-pages had fixed errors.
255 * bits 28-31 are uncorrectable errors, marked elsewhere.
256 * for small page nand only 1 bit is used.
257 * if the ELBC doesn't have the lteccr register it reads 0
258 */
259 if (lteccr & 0x000F000F)
260 out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */
261 if (lteccr & 0x000F0000)
262 mtd->ecc_stats.corrected++;
263 }
264
247 return 0; 265 return 0;
248} 266}
249 267
@@ -435,7 +453,6 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
435 453
436 /* PAGEPROG reuses all of the setup from SEQIN and adds the length */ 454 /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
437 case NAND_CMD_PAGEPROG: { 455 case NAND_CMD_PAGEPROG: {
438 int full_page;
439 dev_vdbg(priv->dev, 456 dev_vdbg(priv->dev,
440 "fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG " 457 "fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG "
441 "writing %d bytes.\n", elbc_fcm_ctrl->index); 458 "writing %d bytes.\n", elbc_fcm_ctrl->index);
@@ -445,34 +462,12 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
445 * write so the HW generates the ECC. 462 * write so the HW generates the ECC.
446 */ 463 */
447 if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 || 464 if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 ||
448 elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize) { 465 elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize)
449 out_be32(&lbc->fbcr, elbc_fcm_ctrl->index); 466 out_be32(&lbc->fbcr, elbc_fcm_ctrl->index);
450 full_page = 0; 467 else
451 } else {
452 out_be32(&lbc->fbcr, 0); 468 out_be32(&lbc->fbcr, 0);
453 full_page = 1;
454 }
455 469
456 fsl_elbc_run_command(mtd); 470 fsl_elbc_run_command(mtd);
457
458 /* Read back the page in order to fill in the ECC for the
459 * caller. Is this really needed?
460 */
461 if (full_page && elbc_fcm_ctrl->oob_poi) {
462 out_be32(&lbc->fbcr, 3);
463 set_addr(mtd, 6, page_addr, 1);
464
465 elbc_fcm_ctrl->read_bytes = mtd->writesize + 9;
466
467 fsl_elbc_do_read(chip, 1);
468 fsl_elbc_run_command(mtd);
469
470 memcpy_fromio(elbc_fcm_ctrl->oob_poi + 6,
471 &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], 3);
472 elbc_fcm_ctrl->index += 3;
473 }
474
475 elbc_fcm_ctrl->oob_poi = NULL;
476 return; 471 return;
477 } 472 }
478 473
@@ -752,13 +747,8 @@ static void fsl_elbc_write_page(struct mtd_info *mtd,
752 struct nand_chip *chip, 747 struct nand_chip *chip,
753 const uint8_t *buf) 748 const uint8_t *buf)
754{ 749{
755 struct fsl_elbc_mtd *priv = chip->priv;
756 struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
757
758 fsl_elbc_write_buf(mtd, buf, mtd->writesize); 750 fsl_elbc_write_buf(mtd, buf, mtd->writesize);
759 fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize); 751 fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
760
761 elbc_fcm_ctrl->oob_poi = chip->oob_poi;
762} 752}
763 753
764static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) 754static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
@@ -791,8 +781,8 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
791 chip->bbt_md = &bbt_mirror_descr; 781 chip->bbt_md = &bbt_mirror_descr;
792 782
793 /* set up nand options */ 783 /* set up nand options */
794 chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR | 784 chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR;
795 NAND_USE_FLASH_BBT; 785 chip->bbt_options = NAND_BBT_USE_FLASH;
796 786
797 chip->controller = &elbc_fcm_ctrl->controller; 787 chip->controller = &elbc_fcm_ctrl->controller;
798 chip->priv = priv; 788 chip->priv = priv;
@@ -829,7 +819,6 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv)
829 819
830 elbc_fcm_ctrl->chips[priv->bank] = NULL; 820 elbc_fcm_ctrl->chips[priv->bank] = NULL;
831 kfree(priv); 821 kfree(priv);
832 kfree(elbc_fcm_ctrl);
833 return 0; 822 return 0;
834} 823}
835 824
@@ -842,13 +831,14 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
842 struct resource res; 831 struct resource res;
843 struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl; 832 struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl;
844 static const char *part_probe_types[] 833 static const char *part_probe_types[]
845 = { "cmdlinepart", "RedBoot", NULL }; 834 = { "cmdlinepart", "RedBoot", "ofpart", NULL };
846 struct mtd_partition *parts;
847 int ret; 835 int ret;
848 int bank; 836 int bank;
849 struct device *dev; 837 struct device *dev;
850 struct device_node *node = pdev->dev.of_node; 838 struct device_node *node = pdev->dev.of_node;
839 struct mtd_part_parser_data ppdata;
851 840
841 ppdata.of_node = pdev->dev.of_node;
852 if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) 842 if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
853 return -ENODEV; 843 return -ENODEV;
854 lbc = fsl_lbc_ctrl_dev->regs; 844 lbc = fsl_lbc_ctrl_dev->regs;
@@ -934,17 +924,8 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
934 924
935 /* First look for RedBoot table or partitions on the command 925 /* First look for RedBoot table or partitions on the command
936 * line, these take precedence over device tree information */ 926 * line, these take precedence over device tree information */
937 ret = parse_mtd_partitions(&priv->mtd, part_probe_types, &parts, 0); 927 mtd_device_parse_register(&priv->mtd, part_probe_types, &ppdata,
938 if (ret < 0) 928 NULL, 0);
939 goto err;
940
941 if (ret == 0) {
942 ret = of_mtd_parse_partitions(priv->dev, node, &parts);
943 if (ret < 0)
944 goto err;
945 }
946
947 mtd_device_register(&priv->mtd, parts, ret);
948 929
949 printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n", 930 printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n",
950 (unsigned long long)res.start, priv->bank); 931 (unsigned long long)res.start, priv->bank);