From: David Brownell <[email protected]>

More cleanup of the NAND driver; mostly just comments but including
one small bugfix to the 1-bit ECC computation for nonzero chipselects.

This should get the driver most of the way to seeming reasonable for
an upstream merge ... but, no 4-bit ECC support yet.

Signed-off-by: David Brownell <[email protected]>
---
 drivers/mtd/nand/davinci_nand.c |   92 ++++++++++++++------------------------
 1 file changed, 36 insertions(+), 56 deletions(-)

--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -3,12 +3,10 @@
  *
  * Copyright (C) 2006 Texas Instruments.
  *
- * ported to 2.6.23 (C) 2008 by
- * Sander Huijsen <[email protected]>
- * Troy Kisky <[email protected]>
- * Dirk Behme <[email protected]>
- *
- * --------------------------------------------------------------------------
+ * Port to 2.6.23 Copyright (C) 2008 by:
+ *   Sander Huijsen <[email protected]>
+ *   Troy Kisky <[email protected]>
+ *   Dirk Behme <[email protected]>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,19 +18,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- * --------------------------------------------------------------------------
- *
- *  Overview:
- *   This is a device driver for the NAND flash device found on the
- *   DaVinci DM6446 EVM board which utilizes the Samsung k9k2g08 part.
- *   (small page NAND).  It should work for some other DaVinci NAND
- *   configurations, but it ignores the dm355 4-bit ECC hardware.
- *
- *   Currently assumes EM_WAIT connects all of the NAND devices in
- *   a "wire-OR" configuration.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
@@ -42,18 +30,13 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/spinlock.h>
-#include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 
 #include <mach/cpu.h>
-#include <mach/hardware.h>
 #include <mach/nand.h>
-#include <mach/mux.h>
 
 #include <asm/mach-types.h>
-#include <asm/mach/flash.h>
 
 
 #ifdef CONFIG_MTD_PARTITIONS
@@ -69,6 +52,19 @@ static inline int mtd_has_cmdlinepart(vo
 #endif
 
 
+/*
+ * This is a device driver for the NAND flash controller found on the
+ * various DaVinci family chips.  It handles up to four SoC chipselects,
+ * and some flavors of secondary chipselect (e.g. based on A12) as used
+ * with multichip packages.
+ *
+ * The 1-bit ECC hardware is supported, but not yet the newer 4-bit ECC
+ * available on chips like the DM355 and OMAP-L137 and needed with the
+ * more error-prone MLC NAND chips.
+ *
+ * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
+ * outputs in a "wire-AND" configuration, with no per-chip signals.
+ */
 struct davinci_nand_info {
        struct mtd_info         mtd;
        struct nand_chip        chip;
@@ -107,11 +103,12 @@ static inline void davinci_nand_writel(s
        __raw_writel(value, info->base + offset);
 }
 
+/*----------------------------------------------------------------------*/
+
 /*
- * Hardware specific access to control-lines
- *
- * REVISIT avoid casting addresses
+ * Access to hardware control lines:  ALE, CLE, secondary chipselect.
  */
+
 static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
                                   unsigned int ctrl)
 {
@@ -153,6 +150,14 @@ static void nand_davinci_select_chip(str
  * 1-bit hardware ECC ... context maintained for each core chipselect
  */
 
+static inline u32 nand_davinci_readecc_1bit(struct mtd_info *mtd)
+{
+       struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+       return davinci_nand_readl(info, NANDF1ECC_OFFSET
+                       + 4 * info->core_chipsel);
+}
+
 static void nand_davinci_hwctl_1bit(struct mtd_info *mtd, int mode)
 {
        struct davinci_nand_info *info;
@@ -162,8 +167,7 @@ static void nand_davinci_hwctl_1bit(stru
        info = to_davinci_nand(mtd);
 
        /* Reset ECC hardware */
-       retval = davinci_nand_readl(info, NANDF1ECC_OFFSET
-                       + 4 * info->core_chipsel);
+       nand_davinci_readecc_1bit(mtd);
 
        spin_lock_irqsave(&davinci_nand_lock, flags);
 
@@ -176,25 +180,14 @@ static void nand_davinci_hwctl_1bit(stru
 }
 
 /*
- * Read DaVinci ECC register
- */
-static inline u32 nand_davinci_readecc_1bit(struct mtd_info *mtd)
-{
-       struct davinci_nand_info *info = to_davinci_nand(mtd);
-
-       /* Read register ECC and clear it */
-       return davinci_nand_readl(info, NANDF1ECC_OFFSET);
-}
-
-/*
- * Read DaVinci ECC registers and rework into MTD format
+ * Read hardware ECC value and pack into three bytes
  */
 static int nand_davinci_calculate_1bit(struct mtd_info *mtd,
                                      const u_char *dat, u_char *ecc_code)
 {
        unsigned int ecc_val = nand_davinci_readecc_1bit(mtd);
-       /* squeeze 0 middle bits out so that it fits in 3 bytes */
        unsigned int tmp = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4);
+
        /* invert so that erased block ecc is correct */
        tmp = ~tmp;
        ecc_code[0] = (u_char)(tmp);
@@ -225,7 +218,7 @@ static int nand_davinci_correct_1bit(str
                        }
                } else if (!(diff & (diff - 1))) {
                        /* Single bit ECC error in the ECC itself,
-                          nothing to fix */
+                        * nothing to fix */
                        return 1;
                } else {
                        /* Uncorrectable error */
@@ -405,15 +398,6 @@ static int __init nand_davinci_probe(str
        else
                ecc_mode = NAND_ECC_HW;
 
-       /*
-        * REVISIT dm355 adds an ECC mode that corrects up to 4 error
-        * bits, using 10 ECC bytes every 512 bytes of data.  And that
-        * is what TI's original LSP uses... along with quite a hacked
-        * up "inline OOB" scheme storing those ECC bytes, which happens
-        * to use (in good blocks) bytes used by factory bad-block marks
-        * (in bad blocks).  There was evidently a technical issue (now
-        * fixed?):  Linux seemed to limit ECC data to 32 bytes.
-        */
        switch (ecc_mode) {
        case NAND_ECC_NONE:
        case NAND_ECC_SOFT:
@@ -520,10 +504,6 @@ static int __init nand_davinci_probe(str
 
        /* If there's no partition info, just package the whole chip
         * as a single MTD device.
-        *
-        * NOTE:  When using the DM355 with large block NAND chips, don't
-        * use this driver to change data the ROM Boot Loader (RBL) reads
-        * from one of the first 24 blocks.  See DM355 errata for details.
         */
        if (!info->partitioned)
                ret = add_mtd_device(&info->mtd) ? -ENODEV : 0;

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to