Some old dataflash chips don't have device ID,
we should identif them using bits in the flash status byte.
Add a variable status_byte in struct flash_info,
and assign correct value for above old chips.
Add those chips to the supported flash chip table
and identify them through the new variable status_byte.

Signed-off-by: Haikun Wang <haikun.w...@freescale.com>
---
 drivers/mtd/spi/sf_dataflash.c | 226 +++++++++++++++++++----------------------
 1 file changed, 107 insertions(+), 119 deletions(-)

diff --git a/drivers/mtd/spi/sf_dataflash.c b/drivers/mtd/spi/sf_dataflash.c
index 648f3ca..cd8d908 100644
--- a/drivers/mtd/spi/sf_dataflash.c
+++ b/drivers/mtd/spi/sf_dataflash.c
@@ -67,11 +67,87 @@
 #define OP_WRITE_SECURITY_REVC 0x9A
 #define OP_WRITE_SECURITY      0x9B    /* revision D */
 
+#define ATMEL_VENDOR_ID                0x1f
+
 struct dataflash {
        uint8_t                 command[16];
        unsigned short          page_offset;    /* offset in flash address */
 };
 
+struct flash_info {
+       char            *name;
+
+       /*
+        * JEDEC id has a high byte of zero plus three data bytes:
+        * the manufacturer id, then a two byte device id.
+        */
+       uint32_t        jedec_id;
+
+       /* The size listed here is what works with OP_ERASE_PAGE. */
+       unsigned        nr_pages;
+       uint16_t        pagesize;
+       uint16_t        pageoffset;
+       uint8_t         status_byte;
+
+       uint16_t        flags;
+#define SUP_POW2PS     0x0002          /* supports 2^N byte pages */
+#define IS_POW2PS      0x0001          /* uses 2^N byte pages */
+};
+
+static struct flash_info dataflash_data[] = {
+       /*
+        * NOTE:  chips with SUP_POW2PS (rev D and up) need two entries,
+        * one with IS_POW2PS and the other without.  The entry with the
+        * non-2^N byte page size can't name exact chip revisions without
+        * losing backwards compatibility for cmdlinepart.
+        *
+        * Those two entries have different name spelling format in order to
+        * show their difference obviously.
+        * The upper case refer to the chip isn't in normal 2^N bytes page-size
+        * mode.
+        * The lower case refer to the chip is in normal 2^N bytes page-size
+        * mode.
+        *
+        * These newer chips also support 128-byte security registers (with
+        * 64 bytes one-time-programmable) and software write-protection.
+        */
+       { "AT45DB011B",  0x1f2200, 512, 264, 9, 0, SUP_POW2PS},
+       { "at45db011d",  0x1f2200, 512, 256, 8, 0, SUP_POW2PS | IS_POW2PS},
+
+       { "AT45DB021B",  0x1f2300, 1024, 264, 9, 0, SUP_POW2PS},
+       { "at45db021d",  0x1f2300, 1024, 256, 8, 0, SUP_POW2PS | IS_POW2PS},
+
+       { "AT45DB041x",  0x1f2400, 2048, 264, 9, 0, SUP_POW2PS},
+       { "at45db041d",  0x1f2400, 2048, 256, 8, 0, SUP_POW2PS | IS_POW2PS},
+
+       { "AT45DB081B",  0x1f2500, 4096, 264, 9, 0, SUP_POW2PS},
+       { "at45db081d",  0x1f2500, 4096, 256, 8, 0, SUP_POW2PS | IS_POW2PS},
+
+       { "AT45DB161x",  0x1f2600, 4096, 528, 10, 0, SUP_POW2PS},
+       { "at45db161d",  0x1f2600, 4096, 512, 9, 0, SUP_POW2PS | IS_POW2PS},
+
+       /* rev C */
+       { "AT45DB321x",  0x1f2700, 8192, 528, 10, 0, 0},
+
+       { "AT45DB321x",  0x1f2701, 8192, 528, 10, 0, SUP_POW2PS},
+       { "at45db321d",  0x1f2701, 8192, 512, 9, 0, SUP_POW2PS | IS_POW2PS},
+
+       { "AT45DB642x",  0x1f2800, 8192, 1056, 11, 0, SUP_POW2PS},
+       { "at45db642d",  0x1f2800, 8192, 1024, 10, 0, SUP_POW2PS | IS_POW2PS},
+       /*
+       * Older chips support only legacy commands, identifing
+       * capacity using bits in the status byte.
+       */
+       { "AT45DB011B-NOID", 0, 512, 264, 9, 0x0c, 0},
+       { "AT45DB021B-NOID", 0, 1024, 264, 9, 0x14, 0},
+       { "AT45DB041x-NOID", 0, 2048, 264, 9, 0x1c, 0},
+       { "AT45DB081B-NOID", 0, 4096, 264, 9, 0x24, 0},
+       { "AT45DB161x-NOID", 0, 4096, 528, 10, 0x2c, 0},
+       { "AT45DB321x-NOID", 0, 8192, 528, 10, 0x34, 0},
+       { "AT45DB642x-NOID", 0, 8192, 1056, 11, 0x38, 0},
+       { "AT45DB642x-NOID", 0, 8192, 1056, 11, 0x3c, 0},
+};
+
 /*
  * Return the status of the DataFlash device.
  */
@@ -452,67 +528,7 @@ static int add_dataflash(struct udevice *dev, char *name, 
int nr_pages,
        return 0;
 }
 
-struct flash_info {
-       char            *name;
-
-       /*
-        * JEDEC id has a high byte of zero plus three data bytes:
-        * the manufacturer id, then a two byte device id.
-        */
-       uint32_t        jedec_id;
-
-       /* The size listed here is what works with OP_ERASE_PAGE. */
-       unsigned        nr_pages;
-       uint16_t        pagesize;
-       uint16_t        pageoffset;
-
-       uint16_t        flags;
-#define SUP_POW2PS     0x0002          /* supports 2^N byte pages */
-#define IS_POW2PS      0x0001          /* uses 2^N byte pages */
-};
-
-static struct flash_info dataflash_data[] = {
-       /*
-        * NOTE:  chips with SUP_POW2PS (rev D and up) need two entries,
-        * one with IS_POW2PS and the other without.  The entry with the
-        * non-2^N byte page size can't name exact chip revisions without
-        * losing backwards compatibility for cmdlinepart.
-        *
-        * Those two entries have different name spelling format in order to
-        * show their difference obviously.
-        * The upper case refer to the chip isn't in normal 2^N bytes page-size
-        * mode.
-        * The lower case refer to the chip is in normal 2^N bytes page-size
-        * mode.
-        *
-        * These newer chips also support 128-byte security registers (with
-        * 64 bytes one-time-programmable) and software write-protection.
-        */
-       { "AT45DB011B",  0x1f2200, 512, 264, 9, SUP_POW2PS},
-       { "at45db011d",  0x1f2200, 512, 256, 8, SUP_POW2PS | IS_POW2PS},
-
-       { "AT45DB021B",  0x1f2300, 1024, 264, 9, SUP_POW2PS},
-       { "at45db021d",  0x1f2300, 1024, 256, 8, SUP_POW2PS | IS_POW2PS},
-
-       { "AT45DB041x",  0x1f2400, 2048, 264, 9, SUP_POW2PS},
-       { "at45db041d",  0x1f2400, 2048, 256, 8, SUP_POW2PS | IS_POW2PS},
-
-       { "AT45DB081B",  0x1f2500, 4096, 264, 9, SUP_POW2PS},
-       { "at45db081d",  0x1f2500, 4096, 256, 8, SUP_POW2PS | IS_POW2PS},
-
-       { "AT45DB161x",  0x1f2600, 4096, 528, 10, SUP_POW2PS},
-       { "at45db161d",  0x1f2600, 4096, 512, 9, SUP_POW2PS | IS_POW2PS},
-
-       { "AT45DB321x",  0x1f2700, 8192, 528, 10, 0},           /* rev C */
-
-       { "AT45DB321x",  0x1f2701, 8192, 528, 10, SUP_POW2PS},
-       { "at45db321d",  0x1f2701, 8192, 512, 9, SUP_POW2PS | IS_POW2PS},
-
-       { "AT45DB642x",  0x1f2800, 8192, 1056, 11, SUP_POW2PS},
-       { "at45db642d",  0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS},
-};
-
-static int jedec_probe(struct spi_slave *spi, u8 *id,
+static int jedec_probe(struct spi_slave *spi, u8 *id, u8 status_byte,
                struct flash_info **pp_info)
 {
        int                     tmp;
@@ -529,7 +545,7 @@ static int jedec_probe(struct spi_slave *spi, u8 *id,
         * That's not an error; only rev C and newer chips handle it, and
         * only Atmel sells these chips.
         */
-       if (id[0] != 0x1f)
+       if (id[0] != ATMEL_VENDOR_ID && !status_byte)
                return -EINVAL;
 
        jedec = id[0];
@@ -541,7 +557,7 @@ static int jedec_probe(struct spi_slave *spi, u8 *id,
        for (tmp = 0, info = dataflash_data;
                        tmp < ARRAY_SIZE(dataflash_data);
                        tmp++, info++) {
-               if (info->jedec_id == jedec) {
+               if (info->jedec_id && info->jedec_id == jedec) {
                        if (info->flags & SUP_POW2PS) {
                                status = dataflash_status(spi);
                                if (status < 0) {
@@ -564,6 +580,16 @@ static int jedec_probe(struct spi_slave *spi, u8 *id,
                                *pp_info = info;
                                return 0;
                        }
+               } else if (!info->jedec_id && info->status_byte) {
+                       /*
+                       * if there's a device there, assume it's dataflash.
+                       * board setup should have set spi->max_speed_max to
+                       * match f(car) for continuous reads, mode 0 or 3.
+                       */
+                       if (status_byte == info->status_byte) {
+                               *pp_info = info;
+                               return 0;
+                       }
                }
        }
 
@@ -573,8 +599,8 @@ static int jedec_probe(struct spi_slave *spi, u8 *id,
         * class is involved (legacy chip id scheme).
         */
        printf("SPI DataFlash: Unsupported flash IDs: ");
-       printf("manuf %02x, jedec %04x, ext_jedec %04x\n",
-              id[0], jedec, id[3] << 8 | id[4]);
+       printf("manuf %02x, jedec %04x, ext_jedec %04x, status_byte %02x\n",
+              id[0], jedec, id[3] << 8 | id[4], status_byte);
        return -EPROTONOSUPPORT;
 }
 
@@ -614,71 +640,33 @@ static int spi_dataflash_probe(struct udevice *dev)
        }
 
        /*
+       * Older chips support only legacy commands, identifing
+       * capacity using bits in the status byte.
+       */
+       status = dataflash_status(spi);
+       if (status <= 0 || status == 0xff) {
+               printf("SPI DataFlash: read status error %d\n", status);
+               if (status == 0 || status == 0xff)
+                       status = -ENODEV;
+               goto err_read_cmd;
+       }
+
+       /*
         * Try to detect dataflash by JEDEC ID.
+        * Otherwise try to detect by status.
         * If it succeeds we know we have either a C or D part.
         * D will support power of 2 pagesize option.
         * Both support the security register, though with different
         * write procedures.
         */
-       ret = jedec_probe(spi, idcode, &info);
+       ret = jedec_probe(spi, idcode, (status & 0x3c), &info);
        if (!ret)
                add_dataflash(dev, info->name, info->nr_pages,
                              info->pagesize, info->pageoffset,
                              (info->flags & SUP_POW2PS) ? 'd' : 'c');
        else {
-               /*
-               * Older chips support only legacy commands, identifing
-               * capacity using bits in the status byte.
-               */
-               status = dataflash_status(spi);
-               if (status <= 0 || status == 0xff) {
-                       printf("SPI DataFlash: read status error %d\n", status);
-                       if (status == 0 || status == 0xff)
-                               status = -ENODEV;
-                       goto err_read_cmd;
-               }
-               /*
-               * if there's a device there, assume it's dataflash.
-               * board setup should have set spi->max_speed_max to
-               * match f(car) for continuous reads, mode 0 or 3.
-               */
-               switch (status & 0x3c) {
-               case 0x0c:      /* 0 0 1 1 x x */
-                       status = add_dataflash(dev, "AT45DB011B",
-                                              512, 264, 9, 0);
-                       break;
-               case 0x14:      /* 0 1 0 1 x x */
-                       status = add_dataflash(dev, "AT45DB021B",
-                                              1024, 264, 9, 0);
-                       break;
-               case 0x1c:      /* 0 1 1 1 x x */
-                       status = add_dataflash(dev, "AT45DB041x",
-                                              2048, 264, 9, 0);
-                       break;
-               case 0x24:      /* 1 0 0 1 x x */
-                       status = add_dataflash(dev, "AT45DB081B",
-                                              4096, 264, 9, 0);
-                       break;
-               case 0x2c:      /* 1 0 1 1 x x */
-                       status = add_dataflash(dev, "AT45DB161x",
-                                              4096, 528, 10, 0);
-                       break;
-               case 0x34:      /* 1 1 0 1 x x */
-                       status = add_dataflash(dev, "AT45DB321x",
-                                              8192, 528, 10, 0);
-                       break;
-               case 0x38:      /* 1 1 1 x x x */
-               case 0x3c:
-                       status = add_dataflash(dev, "AT45DB642x",
-                                              8192, 1056, 11, 0);
-                       break;
-               /* obsolete AT45DB1282 not (yet?) supported */
-               default:
-                       dev_info(&spi->dev, "unsupported device (%x)\n",
-                                status & 0x3c);
-                       status = -ENODEV;
-                       goto err_read_cmd;
-               }
+               status = -ENODEV;
+               goto err_read_cmd;
        }
 
        /* Assign spi data */
-- 
2.1.0.27.g96db324

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to