Add ability to take MAC address from the environment to DM9000 driver
[oweals/u-boot.git] / drivers / nand / nand_base.c
index a7ab8c27adcb93c9d40346d6c64fea0a7c04cd34..151f535c58bddbe2fac6873abd04cf7d84856011 100644 (file)
@@ -72,7 +72,7 @@
 
 #include <common.h>
 
-#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
 
 #include <malloc.h>
 #include <watchdog.h>
@@ -189,7 +189,11 @@ static void nand_release_device (struct mtd_info *mtd)
        spin_unlock (&this->chip_lock);
 }
 #else
-#define nand_release_device(mtd)       do {} while(0)
+static void nand_release_device (struct mtd_info *mtd)
+{
+       struct nand_chip *this = mtd->priv;
+       this->select_chip(mtd, -1);     /* De-select the NAND device */
+}
 #endif
 
 /**
@@ -423,8 +427,9 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
        struct nand_chip *this = mtd->priv;
        u16 bad;
 
+       page = (int)(ofs >> this->page_shift) & this->pagemask;
+
        if (getchip) {
-               page = (int)(ofs >> this->page_shift);
                chipnr = (int)(ofs >> this->chip_shift);
 
                /* Grab the lock and see if the device is available */
@@ -432,18 +437,17 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 
                /* Select the NAND device */
                this->select_chip(mtd, chipnr);
-       } else
-               page = (int) ofs;
+       }
 
        if (this->options & NAND_BUSWIDTH_16) {
-               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
+               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page);
                bad = cpu_to_le16(this->read_word(mtd));
                if (this->badblockpos & 0x1)
                        bad >>= 1;
                if ((bad & 0xFF) != 0xff)
                        res = 1;
        } else {
-               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask);
+               this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page);
                if (this->read_byte(mtd) != 0xff)
                        res = 1;
        }
@@ -831,8 +835,40 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
 #else
 static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
 {
-       /* TODO */
-       return 0;
+       unsigned long   timeo;
+
+       if (state == FL_ERASING)
+               timeo = (CFG_HZ * 400) / 1000;
+       else
+               timeo = (CFG_HZ * 20) / 1000;
+
+       if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
+               this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
+       else
+               this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+
+       reset_timer();
+
+       while (1) {
+               if (get_timer(0) > timeo) {
+                       printf("Timeout!");
+                       return 0x01;
+               }
+
+               if (this->dev_ready) {
+                       if (this->dev_ready(mtd))
+                               break;
+               } else {
+                       if (this->read_byte(mtd) & NAND_STATUS_READY)
+                               break;
+               }
+       }
+#ifdef PPCHAMELON_NAND_TIMER_HACK
+       reset_timer();
+       while (get_timer(0) < 10);
+#endif /*  PPCHAMELON_NAND_TIMER_HACK */
+
+       return this->read_byte(mtd);
 }
 #endif
 
@@ -857,7 +893,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
        int     i, status;
        u_char  ecc_code[32];
        int     eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
-       int     *oob_config = oobsel->eccpos;
+       uint    *oob_config = oobsel->eccpos;
        int     datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
        int     eccbytes = 0;
 
@@ -1079,7 +1115,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
        u_char ecc_calc[32];
        u_char ecc_code[32];
        int eccmode, eccsteps;
-       int     *oob_config, datidx;
+       unsigned *oob_config;
+       int     datidx;
        int     blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
        int     eccbytes;
        int     compareecc = 1;
@@ -1676,6 +1713,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
                                goto out;
                        }
                        *retlen = written;
+                       bufstart = (u_char*) &buf[written];
 
                        ofs = autoplace ? mtd->oobavail : mtd->oobsize;
                        if (eccbuf)
@@ -1684,6 +1722,8 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
                        numpages = min (totalpages, ppblock);
                        page &= this->pagemask;
                        startpage = page;
+                       oob = 0;
+                       this->oobdirty = 1;
                        oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
                                        autoplace, numpages);
                        /* Check, if we cross a chip boundary */
@@ -2108,13 +2148,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
        instr->state = MTD_ERASING;
 
        while (len) {
+#ifndef NAND_ALLOW_ERASE_ALL
                /* Check if we have a bad block, we do not erase bad blocks ! */
                if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
                        printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
                        instr->state = MTD_ERASE_FAILED;
                        goto erase_exit;
                }
-
+#endif
                /* Invalidate the page cache, if we erase the block which contains
                   the current cached page */
                if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
@@ -2297,7 +2338,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
                        mtd->oobblock = 1024 << (extid & 0x3);
                        extid >>= 2;
                        /* Calc oobsize */
-                       mtd->oobsize = (8 << (extid & 0x03)) * (mtd->oobblock / 512);
+                       mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock / 512);
                        extid >>= 2;
                        /* Calc blocksize. Blocksize is multiples of 64KiB */
                        mtd->erasesize = (64 * 1024)  << (extid & 0x03);
@@ -2363,14 +2404,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
                        if (nand_manuf_ids[j].id == nand_maf_id)
                                break;
                }
-               printk (KERN_INFO "NAND device: Manufacturer ID:"
-                       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
-                       nand_manuf_ids[j].name , nand_flash_ids[i].name);
                break;
        }
 
        if (!nand_flash_ids[i].name) {
+#ifndef CFG_NAND_QUIET_TEST
                printk (KERN_WARNING "No NAND device found!!!\n");
+#endif
                this->select_chip(mtd, -1);
                return 1;
        }