]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/mtd/nand/fsl_elbc_nand.c
mtd: fsl_elbc_nand: set Nand flash page address to FBAR and FPAR correctly
[mv-sheeva.git] / drivers / mtd / nand / fsl_elbc_nand.c
index eedd8ee2c9ac8b83059edf9cf5856a12e4a53e48..d29479abe50441b009d83c0e5ce15a8f1e0bb668 100644 (file)
@@ -166,15 +166,22 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
 
        elbc_fcm_ctrl->page = page_addr;
 
-       out_be32(&lbc->fbar,
-                page_addr >> (chip->phys_erase_shift - chip->page_shift));
-
        if (priv->page_size) {
+               /*
+                * large page size chip : FPAR[PI] save the lowest 6 bits,
+                *                        FBAR[BLK] save the other bits.
+                */
+               out_be32(&lbc->fbar, page_addr >> 6);
                out_be32(&lbc->fpar,
                         ((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) |
                         (oob ? FPAR_LP_MS : 0) | column);
                buf_num = (page_addr & 1) << 2;
        } else {
+               /*
+                * small page size chip : FPAR[PI] save the lowest 5 bits,
+                *                        FBAR[BLK] save the other bits.
+                */
+               out_be32(&lbc->fbar, page_addr >> 5);
                out_be32(&lbc->fpar,
                         ((page_addr << FPAR_SP_PI_SHIFT) & FPAR_SP_PI) |
                         (oob ? FPAR_SP_MS : 0) | column);
@@ -407,9 +414,17 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                         page_addr, column);
 
                elbc_fcm_ctrl->column = column;
-               elbc_fcm_ctrl->oob = 0;
                elbc_fcm_ctrl->use_mdr = 1;
 
+               if (column >= mtd->writesize) {
+                       /* OOB area */
+                       column -= mtd->writesize;
+                       elbc_fcm_ctrl->oob = 1;
+               } else {
+                       WARN_ON(column != 0);
+                       elbc_fcm_ctrl->oob = 0;
+               }
+
                fcr = (NAND_CMD_STATUS   << FCR_CMD1_SHIFT) |
                      (NAND_CMD_SEQIN    << FCR_CMD2_SHIFT) |
                      (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT);
@@ -434,16 +449,12 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                                 (FIR_OP_CW1 << FIR_OP6_SHIFT) |
                                 (FIR_OP_RS  << FIR_OP7_SHIFT));
 
-                       if (column >= mtd->writesize) {
+                       if (elbc_fcm_ctrl->oob)
                                /* OOB area --> READOOB */
-                               column -= mtd->writesize;
                                fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT;
-                               elbc_fcm_ctrl->oob = 1;
-                       } else {
-                               WARN_ON(column != 0);
+                       else
                                /* First 256 bytes --> READ0 */
                                fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT;
-                       }
                }
 
                out_be32(&lbc->fcr, fcr);
@@ -463,7 +474,8 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                 */
                if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 ||
                    elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize)
-                       out_be32(&lbc->fbcr, elbc_fcm_ctrl->index);
+                       out_be32(&lbc->fbcr,
+                               elbc_fcm_ctrl->index - elbc_fcm_ctrl->column);
                else
                        out_be32(&lbc->fbcr, 0);
 
@@ -971,18 +983,7 @@ static struct platform_driver fsl_elbc_nand_driver = {
        .remove = fsl_elbc_nand_remove,
 };
 
-static int __init fsl_elbc_nand_init(void)
-{
-       return platform_driver_register(&fsl_elbc_nand_driver);
-}
-
-static void __exit fsl_elbc_nand_exit(void)
-{
-       platform_driver_unregister(&fsl_elbc_nand_driver);
-}
-
-module_init(fsl_elbc_nand_init);
-module_exit(fsl_elbc_nand_exit);
+module_platform_driver(fsl_elbc_nand_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Freescale");