]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/onenand/onenand_base.c
Merge remote-tracking branch 'mpc83xx/next'
[u-boot] / drivers / mtd / onenand / onenand_base.c
index 24e02c2840b6c30f84b80d03be01e5af778e7a80..1a7b40eaa37fdc5909fee41e1699a077d9319a22 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #include <common.h>
-#include <linux/mtd/compat.h>
+#include <linux/compat.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 
@@ -367,7 +367,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
                this->write_word(value,
                                 this->base + ONENAND_REG_START_ADDRESS2);
 
-               if (ONENAND_IS_MLC(this))
+               if (ONENAND_IS_4KB_PAGE(this))
                        ONENAND_SET_BUFFERRAM0(this);
                else
                        /* Switch to the next data buffer */
@@ -395,7 +395,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
                case FLEXONENAND_CMD_RECOVER_LSB:
                case ONENAND_CMD_READ:
                case ONENAND_CMD_READOOB:
-                       if (ONENAND_IS_MLC(this))
+                       if (ONENAND_IS_4KB_PAGE(this))
                                dataram = ONENAND_SET_BUFFERRAM0(this);
                        else
                                dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
@@ -893,7 +893,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
        while (!ret) {
                /* If there is more to load then start next load */
                from += thislen;
-               if (!ONENAND_IS_MLC(this) && read + thislen < len) {
+               if (!ONENAND_IS_4KB_PAGE(this) && read + thislen < len) {
                        this->main_buf = buf + thislen;
                        this->command(mtd, ONENAND_CMD_READ, from, writesize);
                        /*
@@ -927,7 +927,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                        oobcolumn = 0;
                }
 
-               if (ONENAND_IS_MLC(this) && (read + thislen < len)) {
+               if (ONENAND_IS_4KB_PAGE(this) && (read + thislen < len)) {
                        this->command(mtd, ONENAND_CMD_READ, from, writesize);
                        ret = this->wait(mtd, FL_READING);
                        if (unlikely(ret))
@@ -944,13 +944,13 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                /* Set up for next read from bufferRAM */
                if (unlikely(boundary))
                        this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
-               if (!ONENAND_IS_MLC(this))
+               if (!ONENAND_IS_4KB_PAGE(this))
                        ONENAND_SET_NEXT_BUFFERRAM(this);
                buf += thislen;
                thislen = min_t(int, writesize, len - read);
                column = 0;
 
-               if (!ONENAND_IS_MLC(this)) {
+               if (!ONENAND_IS_4KB_PAGE(this)) {
                        /* Now wait for load */
                        ret = this->wait(mtd, FL_READING);
                        onenand_update_bufferram(mtd, from, !ret);
@@ -1024,7 +1024,8 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
 
        stats = mtd->ecc_stats;
 
-       readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
+       readcmd = ONENAND_IS_4KB_PAGE(this) ?
+               ONENAND_CMD_READ : ONENAND_CMD_READOOB;
 
        while (read < len) {
                thislen = oobsize - column;
@@ -1202,7 +1203,8 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
 
        MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n", (unsigned int) from, len);
 
-       readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
+       readcmd = ONENAND_IS_4KB_PAGE(this) ?
+               ONENAND_CMD_READ : ONENAND_CMD_READOOB;
 
        /* Initialize return value */
        ops->oobretlen = 0;
@@ -1271,7 +1273,8 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
        u_char *oob_buf = this->oob_buf;
        int status, i, readcmd;
 
-       readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
+       readcmd = ONENAND_IS_4KB_PAGE(this) ?
+               ONENAND_CMD_READ : ONENAND_CMD_READOOB;
 
        this->command(mtd, readcmd, to, mtd->oobsize);
        onenand_update_bufferram(mtd, to, 0);
@@ -1560,7 +1563,8 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
 
        oobbuf = this->oob_buf;
 
-       oobcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
+       oobcmd = ONENAND_IS_4KB_PAGE(this) ?
+               ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
 
        /* Loop until all data write */
        while (written < len) {
@@ -1577,7 +1581,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
                        memcpy(oobbuf + column, buf, thislen);
                this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
 
-               if (ONENAND_IS_MLC(this)) {
+               if (ONENAND_IS_4KB_PAGE(this)) {
                        /* Set main area of DataRAM to 0xff*/
                        memset(this->page_buf, 0xff, mtd->writesize);
                        this->write_bufferram(mtd, 0, ONENAND_DATARAM,
@@ -1943,16 +1947,10 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int
 {
        struct onenand_chip *this = mtd->priv;
        int start, end, block, value, status;
-       int wp_status_mask;
 
        start = onenand_block(this, ofs);
        end = onenand_block(this, ofs + len);
 
-       if (cmd == ONENAND_CMD_LOCK)
-               wp_status_mask = ONENAND_WP_LS;
-       else
-               wp_status_mask = ONENAND_WP_US;
-
        /* Continuous lock scheme */
        if (this->options & ONENAND_HAS_CONT_LOCK) {
                /* Set start block address */
@@ -2146,7 +2144,10 @@ static void onenand_check_features(struct mtd_info *mtd)
        /* Lock scheme */
        switch (density) {
        case ONENAND_DEVICE_DENSITY_4Gb:
-               this->options |= ONENAND_HAS_2PLANE;
+               if (ONENAND_IS_DDP(this))
+                       this->options |= ONENAND_HAS_2PLANE;
+               else
+                       this->options |= ONENAND_HAS_4KB_PAGE;
 
        case ONENAND_DEVICE_DENSITY_2Gb:
                /* 2Gb DDP don't have 2 plane */
@@ -2168,6 +2169,9 @@ static void onenand_check_features(struct mtd_info *mtd)
        }
 
        if (ONENAND_IS_MLC(this))
+               this->options |= ONENAND_HAS_4KB_PAGE;
+
+       if (ONENAND_IS_4KB_PAGE(this))
                this->options &= ~ONENAND_HAS_2PLANE;
 
        if (FLEXONENAND(this)) {
@@ -2181,6 +2185,9 @@ static void onenand_check_features(struct mtd_info *mtd)
                printk(KERN_DEBUG "Chip support all block unlock\n");
        if (this->options & ONENAND_HAS_2PLANE)
                printk(KERN_DEBUG "Chip has 2 plane\n");
+       if (this->options & ONENAND_HAS_4KB_PAGE)
+               printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
+
 }
 
 /**
@@ -2226,19 +2233,21 @@ static const struct onenand_manufacturers onenand_manuf_ids[] = {
 static int onenand_check_maf(int manuf)
 {
        int size = ARRAY_SIZE(onenand_manuf_ids);
-       char *name;
        int i;
+#ifdef ONENAND_DEBUG
+       char *name;
+#endif
 
        for (i = 0; i < size; i++)
                if (manuf == onenand_manuf_ids[i].id)
                        break;
 
+#ifdef ONENAND_DEBUG
        if (i < size)
                name = onenand_manuf_ids[i].name;
        else
                name = "Unknown";
 
-#ifdef ONENAND_DEBUG
        printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
 #endif
 
@@ -2255,7 +2264,7 @@ static int flexonenand_get_boundary(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
        unsigned int die, bdry;
-       int ret, syscfg, locked;
+       int syscfg, locked;
 
        /* Disable ECC */
        syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
@@ -2266,7 +2275,7 @@ static int flexonenand_get_boundary(struct mtd_info *mtd)
                this->wait(mtd, FL_SYNCING);
 
                this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
-               ret = this->wait(mtd, FL_READING);
+               this->wait(mtd, FL_READING);
 
                bdry = this->read_word(this->base + ONENAND_DATARAM);
                if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
@@ -2276,7 +2285,7 @@ static int flexonenand_get_boundary(struct mtd_info *mtd)
                this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
 
                this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-               ret = this->wait(mtd, FL_RESETING);
+               this->wait(mtd, FL_RESETING);
 
                printk(KERN_INFO "Die %d boundary: %d%s\n", die,
                       this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
@@ -2505,23 +2514,24 @@ out:
 }
 
 /**
- * onenand_probe - [OneNAND Interface] Probe the OneNAND device
+ * onenand_chip_probe - [OneNAND Interface] Probe the OneNAND chip
  * @param mtd          MTD device structure
  *
  * OneNAND detection method:
  *   Compare the the values from command with ones from register
  */
-static int onenand_probe(struct mtd_info *mtd)
+static int onenand_chip_probe(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
-       int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
-       int density;
+       int bram_maf_id, bram_dev_id, maf_id, dev_id;
        int syscfg;
 
        /* Save system configuration 1 */
        syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
+
        /* Clear Sync. Burst Read mode to read BootRAM */
-       this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1);
+       this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ),
+                        this->base + ONENAND_REG_SYS_CFG1);
 
        /* Send the command for reading device ID from BootRAM */
        this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
@@ -2546,18 +2556,45 @@ static int onenand_probe(struct mtd_info *mtd)
        /* Read manufacturer and device IDs from Register */
        maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
        dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
-       ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
-       this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
 
        /* Check OneNAND device */
        if (maf_id != bram_maf_id || dev_id != bram_dev_id)
                return -ENXIO;
 
+       return 0;
+}
+
+/**
+ * onenand_probe - [OneNAND Interface] Probe the OneNAND device
+ * @param mtd          MTD device structure
+ *
+ * OneNAND detection method:
+ *   Compare the the values from command with ones from register
+ */
+int onenand_probe(struct mtd_info *mtd)
+{
+       struct onenand_chip *this = mtd->priv;
+       int dev_id, ver_id;
+       int density;
+       int ret;
+
+       ret = this->chip_probe(mtd);
+       if (ret)
+               return ret;
+
+       /* Read device IDs from Register */
+       dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
+       ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
+       this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
+
        /* Flash device information */
        mtd->name = onenand_print_device_info(dev_id, ver_id);
        this->device_id = dev_id;
        this->version_id = ver_id;
 
+       /* Check OneNAND features */
+       onenand_check_features(mtd);
+
        density = onenand_get_density(dev_id);
        if (FLEXONENAND(this)) {
                this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
@@ -2580,7 +2617,7 @@ static int onenand_probe(struct mtd_info *mtd)
        mtd->writesize =
            this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
        /* We use the full BufferRAM */
-       if (ONENAND_IS_MLC(this))
+       if (ONENAND_IS_4KB_PAGE(this))
                mtd->writesize <<= 1;
 
        mtd->oobsize = mtd->writesize >> 5;
@@ -2611,9 +2648,6 @@ static int onenand_probe(struct mtd_info *mtd)
        else
                mtd->size = this->chipsize;
 
-       /* Check OneNAND features */
-       onenand_check_features(mtd);
-
        mtd->flags = MTD_CAP_NANDFLASH;
        mtd->erase = onenand_erase;
        mtd->read = onenand_read;
@@ -2659,6 +2693,9 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
        if (!this->write_bufferram)
                this->write_bufferram = onenand_write_bufferram;
 
+       if (!this->chip_probe)
+               this->chip_probe = onenand_chip_probe;
+
        if (!this->block_markbad)
                this->block_markbad = onenand_default_block_markbad;
        if (!this->scan_bbt)