of: Always use 'struct device.of_node' to get device node pointer.
[safe/jmp/linux-2.6] / drivers / mtd / nand / fsl_elbc_nand.c
index 4b69aac..4a60795 100644 (file)
@@ -89,7 +89,6 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = {
        .eccbytes = 3,
        .eccpos = {6, 7, 8},
        .oobfree = { {0, 5}, {9, 7} },
-       .oobavail = 12,
 };
 
 /* Small Page FLASH with FMR[ECCM] = 1 */
@@ -97,7 +96,6 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = {
        .eccbytes = 3,
        .eccpos = {8, 9, 10},
        .oobfree = { {0, 5}, {6, 2}, {11, 5} },
-       .oobavail = 12,
 };
 
 /* Large Page FLASH with FMR[ECCM] = 0 */
@@ -105,7 +103,6 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = {
        .eccbytes = 12,
        .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56},
        .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} },
-       .oobavail = 48,
 };
 
 /* Large Page FLASH with FMR[ECCM] = 1 */
@@ -113,7 +110,48 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = {
        .eccbytes = 12,
        .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58},
        .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} },
-       .oobavail = 48,
+};
+
+/*
+ * fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset
+ * 1, so we have to adjust bad block pattern. This pattern should be used for
+ * x8 chips only. So far hardware does not support x16 chips anyway.
+ */
+static u8 scan_ff_pattern[] = { 0xff, };
+
+static struct nand_bbt_descr largepage_memorybased = {
+       .options = 0,
+       .offs = 0,
+       .len = 1,
+       .pattern = scan_ff_pattern,
+};
+
+/*
+ * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt,
+ * interfere with ECC positions, that's why we implement our own descriptors.
+ * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0.
+ */
+static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
+static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+                  NAND_BBT_2BIT | NAND_BBT_VERSION,
+       .offs = 11,
+       .len = 4,
+       .veroffs = 15,
+       .maxblocks = 4,
+       .pattern = bbt_pattern,
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+                  NAND_BBT_2BIT | NAND_BBT_VERSION,
+       .offs = 11,
+       .len = 4,
+       .veroffs = 15,
+       .maxblocks = 4,
+       .pattern = mirror_pattern,
 };
 
 /*=================================*/
@@ -199,12 +237,15 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
 
        ctrl->use_mdr = 0;
 
-       dev_vdbg(ctrl->dev,
-                "fsl_elbc_run_command: stat=%08x mdr=%08x fmr=%08x\n",
-                ctrl->status, ctrl->mdr, in_be32(&lbc->fmr));
+       if (ctrl->status != LTESR_CC) {
+               dev_info(ctrl->dev,
+                        "command failed: fir %x fcr %x status %x mdr %x\n",
+                        in_be32(&lbc->fir), in_be32(&lbc->fcr),
+                        ctrl->status, ctrl->mdr);
+               return -EIO;
+       }
 
-       /* returns 0 on success otherwise non-zero) */
-       return ctrl->status == LTESR_CC ? 0 : -EIO;
+       return 0;
 }
 
 static void fsl_elbc_do_read(struct nand_chip *chip, int oob)
@@ -215,17 +256,17 @@ static void fsl_elbc_do_read(struct nand_chip *chip, int oob)
 
        if (priv->page_size) {
                out_be32(&lbc->fir,
-                        (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+                        (FIR_OP_CM0 << FIR_OP0_SHIFT) |
                         (FIR_OP_CA  << FIR_OP1_SHIFT) |
                         (FIR_OP_PA  << FIR_OP2_SHIFT) |
-                        (FIR_OP_CW1 << FIR_OP3_SHIFT) |
+                        (FIR_OP_CM1 << FIR_OP3_SHIFT) |
                         (FIR_OP_RBW << FIR_OP4_SHIFT));
 
                out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) |
                                    (NAND_CMD_READSTART << FCR_CMD1_SHIFT));
        } else {
                out_be32(&lbc->fir,
-                        (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+                        (FIR_OP_CM0 << FIR_OP0_SHIFT) |
                         (FIR_OP_CA  << FIR_OP1_SHIFT) |
                         (FIR_OP_PA  << FIR_OP2_SHIFT) |
                         (FIR_OP_RBW << FIR_OP3_SHIFT));
@@ -294,7 +335,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
        case NAND_CMD_READID:
                dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n");
 
-               out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+               out_be32(&lbc->fir, (FIR_OP_CM0 << FIR_OP0_SHIFT) |
                                    (FIR_OP_UA  << FIR_OP1_SHIFT) |
                                    (FIR_OP_RBW << FIR_OP2_SHIFT));
                out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT);
@@ -321,16 +362,20 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n");
 
                out_be32(&lbc->fir,
-                        (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+                        (FIR_OP_CM0 << FIR_OP0_SHIFT) |
                         (FIR_OP_PA  << FIR_OP1_SHIFT) |
-                        (FIR_OP_CM1 << FIR_OP2_SHIFT));
+                        (FIR_OP_CM2 << FIR_OP2_SHIFT) |
+                        (FIR_OP_CW1 << FIR_OP3_SHIFT) |
+                        (FIR_OP_RS  << FIR_OP4_SHIFT));
 
                out_be32(&lbc->fcr,
                         (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) |
-                        (NAND_CMD_ERASE2 << FCR_CMD1_SHIFT));
+                        (NAND_CMD_STATUS << FCR_CMD1_SHIFT) |
+                        (NAND_CMD_ERASE2 << FCR_CMD2_SHIFT));
 
                out_be32(&lbc->fbcr, 0);
                ctrl->read_bytes = 0;
+               ctrl->use_mdr = 1;
 
                fsl_elbc_run_command(mtd);
                return;
@@ -345,40 +390,41 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
                ctrl->column = column;
                ctrl->oob = 0;
+               ctrl->use_mdr = 1;
 
-               if (priv->page_size) {
-                       fcr = (NAND_CMD_SEQIN << FCR_CMD0_SHIFT) |
-                             (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT);
+               fcr = (NAND_CMD_STATUS   << FCR_CMD1_SHIFT) |
+                     (NAND_CMD_SEQIN    << FCR_CMD2_SHIFT) |
+                     (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT);
 
+               if (priv->page_size) {
                        out_be32(&lbc->fir,
-                                (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+                                (FIR_OP_CM2 << FIR_OP0_SHIFT) |
                                 (FIR_OP_CA  << FIR_OP1_SHIFT) |
                                 (FIR_OP_PA  << FIR_OP2_SHIFT) |
                                 (FIR_OP_WB  << FIR_OP3_SHIFT) |
-                                (FIR_OP_CW1 << FIR_OP4_SHIFT));
+                                (FIR_OP_CM3 << FIR_OP4_SHIFT) |
+                                (FIR_OP_CW1 << FIR_OP5_SHIFT) |
+                                (FIR_OP_RS  << FIR_OP6_SHIFT));
                } else {
-                       fcr = (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT) |
-                             (NAND_CMD_SEQIN << FCR_CMD2_SHIFT);
-
                        out_be32(&lbc->fir,
-                                (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+                                (FIR_OP_CM0 << FIR_OP0_SHIFT) |
                                 (FIR_OP_CM2 << FIR_OP1_SHIFT) |
                                 (FIR_OP_CA  << FIR_OP2_SHIFT) |
                                 (FIR_OP_PA  << FIR_OP3_SHIFT) |
                                 (FIR_OP_WB  << FIR_OP4_SHIFT) |
-                                (FIR_OP_CW1 << FIR_OP5_SHIFT));
+                                (FIR_OP_CM3 << FIR_OP5_SHIFT) |
+                                (FIR_OP_CW1 << FIR_OP6_SHIFT) |
+                                (FIR_OP_RS  << FIR_OP7_SHIFT));
 
                        if (column >= mtd->writesize) {
                                /* OOB area --> READOOB */
                                column -= mtd->writesize;
                                fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT;
                                ctrl->oob = 1;
-                       } else if (column < 256) {
+                       } else {
+                               WARN_ON(column != 0);
                                /* First 256 bytes --> READ0 */
                                fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT;
-                       } else {
-                               /* Second 256 bytes --> READ1 */
-                               fcr |= NAND_CMD_READ1 << FCR_CMD0_SHIFT;
                        }
                }
 
@@ -590,22 +636,6 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip)
 {
        struct fsl_elbc_mtd *priv = chip->priv;
        struct fsl_elbc_ctrl *ctrl = priv->ctrl;
-       struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
-
-       if (ctrl->status != LTESR_CC)
-               return NAND_STATUS_FAIL;
-
-       /* Use READ_STATUS command, but wait for the device to be ready */
-       ctrl->use_mdr = 0;
-       out_be32(&lbc->fir,
-                (FIR_OP_CW0 << FIR_OP0_SHIFT) |
-                (FIR_OP_RBW << FIR_OP1_SHIFT));
-       out_be32(&lbc->fcr, NAND_CMD_STATUS << FCR_CMD0_SHIFT);
-       out_be32(&lbc->fbcr, 1);
-       set_addr(mtd, 0, 0, 0);
-       ctrl->read_bytes = 1;
-
-       fsl_elbc_run_command(mtd);
 
        if (ctrl->status != LTESR_CC)
                return NAND_STATUS_FAIL;
@@ -613,8 +643,7 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip)
        /* The chip always seems to report that it is
         * write-protected, even when it is not.
         */
-       setbits8(ctrl->addr, NAND_STATUS_WP);
-       return fsl_elbc_read_byte(mtd);
+       return (ctrl->mdr & 0xff) | NAND_STATUS_WP;
 }
 
 static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
@@ -638,7 +667,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
 
        dev_dbg(ctrl->dev, "fsl_elbc_init: nand->numchips = %d\n",
                chip->numchips);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chipsize = %ld\n",
+       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
                chip->chipsize);
        dev_dbg(ctrl->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
                chip->pagemask);
@@ -665,7 +694,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
        dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.layout = %p\n",
                chip->ecc.layout);
        dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->size = %d\n", mtd->size);
+       dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size);
        dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->erasesize = %d\n",
                mtd->erasesize);
        dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->writesize = %d\n",
@@ -687,8 +716,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
                        chip->ecc.layout = (priv->fmr & FMR_ECCM) ?
                                           &fsl_elbc_oob_lp_eccm1 :
                                           &fsl_elbc_oob_lp_eccm0;
-                       mtd->ecclayout = chip->ecc.layout;
-                       mtd->oobavail = chip->ecc.layout->oobavail;
+                       chip->badblock_pattern = &largepage_memorybased;
                }
        } else {
                dev_err(ctrl->dev,
@@ -702,7 +730,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
 
 static int fsl_elbc_read_page(struct mtd_info *mtd,
                               struct nand_chip *chip,
-                              uint8_t *buf)
+                             uint8_t *buf,
+                             int page)
 {
        fsl_elbc_read_buf(mtd, buf, mtd->writesize);
        fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -740,7 +769,9 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
        /* Fill in fsl_elbc_mtd structure */
        priv->mtd.priv = chip;
        priv->mtd.owner = THIS_MODULE;
-       priv->fmr = 0; /* rest filled in later */
+
+       /* Set the ECCM according to the settings in bootloader.*/
+       priv->fmr = in_be32(&lbc->fmr) & FMR_ECCM;
 
        /* fill in nand_chip structure */
        /* set up function call table */
@@ -752,8 +783,12 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
        chip->cmdfunc = fsl_elbc_cmdfunc;
        chip->waitfunc = fsl_elbc_wait;
 
+       chip->bbt_td = &bbt_main_descr;
+       chip->bbt_md = &bbt_mirror_descr;
+
        /* set up nand options */
-       chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR;
+       chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR |
+                       NAND_USE_FLASH_BBT;
 
        chip->controller = &ctrl->controller;
        chip->priv = priv;
@@ -795,8 +830,8 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv)
        return 0;
 }
 
-static int fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
-                               struct device_node *node)
+static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
+                                        struct device_node *node)
 {
        struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
        struct fsl_elbc_mtd *priv;
@@ -846,7 +881,7 @@ static int fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
                goto err;
        }
 
-       priv->mtd.name = kasprintf(GFP_KERNEL, "%x.flash", res.start);
+       priv->mtd.name = kasprintf(GFP_KERNEL, "%x.flash", (unsigned)res.start);
        if (!priv->mtd.name) {
                ret = -ENOMEM;
                goto err;
@@ -877,8 +912,7 @@ static int fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
 
 #ifdef CONFIG_MTD_OF_PARTS
        if (ret == 0) {
-               ret = of_mtd_parse_partitions(priv->dev, &priv->mtd,
-                                             node, &parts);
+               ret = of_mtd_parse_partitions(priv->dev, node, &parts);
                if (ret < 0)
                        goto err;
        }
@@ -890,8 +924,8 @@ static int fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
 #endif
                add_mtd_device(&priv->mtd);
 
-       printk(KERN_INFO "eLBC NAND device at 0x%zx, bank %d\n",
-              res.start, priv->bank);
+       printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n",
+              (unsigned long long)res.start, priv->bank);
        return 0;
 
 err:
@@ -903,6 +937,13 @@ static int __devinit fsl_elbc_ctrl_init(struct fsl_elbc_ctrl *ctrl)
 {
        struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
 
+       /*
+        * NAND transactions can tie up the bus for a long time, so set the
+        * bus timeout to max by clearing LBCR[BMT] (highest base counter
+        * value) and setting LBCR[BMTPS] to the highest prescaler value.
+        */
+       clrsetbits_be32(&lbc->lbcr, LBCR_BMT, 15);
+
        /* clear event registers */
        setbits32(&lbc->ltesr, LTESR_NAND_MASK);
        out_be32(&lbc->lteatr, 0);
@@ -917,7 +958,7 @@ static int __devinit fsl_elbc_ctrl_init(struct fsl_elbc_ctrl *ctrl)
        return 0;
 }
 
-static int __devexit fsl_elbc_ctrl_remove(struct of_device *ofdev)
+static int fsl_elbc_ctrl_remove(struct of_device *ofdev)
 {
        struct fsl_elbc_ctrl *ctrl = dev_get_drvdata(&ofdev->dev);
        int i;
@@ -989,14 +1030,14 @@ static int __devinit fsl_elbc_ctrl_probe(struct of_device *ofdev,
        init_waitqueue_head(&ctrl->controller.wq);
        init_waitqueue_head(&ctrl->irq_wait);
 
-       ctrl->regs = of_iomap(ofdev->node, 0);
+       ctrl->regs = of_iomap(ofdev->dev.of_node, 0);
        if (!ctrl->regs) {
                dev_err(&ofdev->dev, "failed to get memory region\n");
                ret = -ENODEV;
                goto err;
        }
 
-       ctrl->irq = of_irq_to_resource(ofdev->node, 0, NULL);
+       ctrl->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL);
        if (ctrl->irq == NO_IRQ) {
                dev_err(&ofdev->dev, "failed to get irq resource\n");
                ret = -ENODEV;
@@ -1017,7 +1058,7 @@ static int __devinit fsl_elbc_ctrl_probe(struct of_device *ofdev,
                goto err;
        }
 
-       for_each_child_of_node(ofdev->node, child)
+       for_each_child_of_node(ofdev->dev.of_node, child)
                if (of_device_is_compatible(child, "fsl,elbc-fcm-nand"))
                        fsl_elbc_chip_probe(ctrl, child);
 
@@ -1041,7 +1082,7 @@ static struct of_platform_driver fsl_elbc_ctrl_driver = {
        },
        .match_table = fsl_elbc_match,
        .probe = fsl_elbc_ctrl_probe,
-       .remove = __devexit_p(fsl_elbc_ctrl_remove),
+       .remove = fsl_elbc_ctrl_remove,
 };
 
 static int __init fsl_elbc_init(void)