Wicked chip:
No WRSR, no write enable command, auto-erasing page write (but even
without that page writes are recommended to write the whole page
i.e. operate on a completely erased page), mad requirements on block
refreshments if only partly written.

Found on my Intel D946GZIS and tested with my serprog in situ.

Signed-off-by: Stefan Tauner <[email protected]>
---
 chipdrivers.h |    2 ++
 flashchips.c  |   14 +++++++---
 spi.h         |   10 ++++++++
 spi25.c       |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/chipdrivers.h b/chipdrivers.h
index 1ef4959..f110807 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -41,7 +41,9 @@ int probe_spi_res2(struct flashctx *flash);
 int spi_write_enable(struct flashctx *flash);
 int spi_write_disable(struct flashctx *flash);
 int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen);
+int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen);
 int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen);
+int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen);
 int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen);
 int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen);
 int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen);
diff --git a/flashchips.c b/flashchips.c
index 4e09ab1..103aa7b 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -1795,18 +1795,24 @@ const struct flashchip flashchips[] = {
                .total_size     = 512,
                .page_size      = 256,
                /* does not support EWSR nor WREN and has no writable status 
register bits whatsoever */
-               .tested         = TEST_UNTESTED,
+               .tested         = TEST_OK_PREW,
                .probe          = probe_spi_rdid,
                .probe_timing   = TIMING_ZERO,
                .block_erasers  =
                {
                        {
+                               .eraseblocks = { {256, 2048} },
+                               .block_erase = spi_block_erase_81,
+                       }, {
+                               .eraseblocks = { {2 * 1024, 256} },
+                               .block_erase = spi_block_erase_50,
+                       }, {
                                .eraseblocks = { {4 * 1024, 128} },
                                .block_erase = spi_block_erase_20,
                        }
-               },
-               .write          = NULL /* Incompatible Page write */,
-               .read           = spi_chip_read,
+               }, /* Supports also an incompatible page write (of exactly 256 
B) and an auto-erasing write. */
+               .write          = spi_chip_write_1,
+               .read           = spi_chip_read, /* Fast read (0x0B) supported 
*/
                .voltage        = {2700, 3600}, /* 3.0-3.6V for higher speed, 
2.7-3.6V normal */
        },
 
diff --git a/spi.h b/spi.h
index ce2ede8..1733fd3 100644
--- a/spi.h
+++ b/spi.h
@@ -76,11 +76,21 @@
 #define JEDEC_CE_C7_OUTSIZE    0x01
 #define JEDEC_CE_C7_INSIZE     0x00
 
+/* Block Erase 0x50 is supported by Atmel AT26DF chips. */
+#define JEDEC_BE_50            0x50
+#define JEDEC_BE_50_OUTSIZE    0x04
+#define JEDEC_BE_50_INSIZE     0x00
+
 /* Block Erase 0x52 is supported by SST and old Atmel chips. */
 #define JEDEC_BE_52            0x52
 #define JEDEC_BE_52_OUTSIZE    0x04
 #define JEDEC_BE_52_INSIZE     0x00
 
+/* Block Erase 0x81 is supported by Atmel AT26DF chips. */
+#define JEDEC_BE_81            0x81
+#define JEDEC_BE_81_OUTSIZE    0x04
+#define JEDEC_BE_81_INSIZE     0x00
+
 /* Block Erase 0xd8 is supported by EON/Macronix chips. */
 #define JEDEC_BE_D8            0xd8
 #define JEDEC_BE_D8_OUTSIZE    0x04
diff --git a/spi25.c b/spi25.c
index a65f548..10c5a4a 100644
--- a/spi25.c
+++ b/spi25.c
@@ -741,6 +741,86 @@ int spi_block_erase_20(struct flashctx *flash, unsigned 
int addr,
        return 0;
 }
 
+int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen)
+{
+       int result;
+       struct spi_command cmds[] = {
+       {
+/*             .writecnt       = JEDEC_WREN_OUTSIZE,
+               .writearr       = (const unsigned char[]){ JEDEC_WREN },
+               .readcnt        = 0,
+               .readarr        = NULL,
+       }, { */
+               .writecnt       = JEDEC_BE_50_OUTSIZE,
+               .writearr       = (const unsigned char[]){
+                                       JEDEC_BE_50,
+                                       (addr >> 16) & 0xff,
+                                       (addr >> 8) & 0xff,
+                                       (addr & 0xff)
+                               },
+               .readcnt        = 0,
+               .readarr        = NULL,
+       }, {
+               .writecnt       = 0,
+               .writearr       = NULL,
+               .readcnt        = 0,
+               .readarr        = NULL,
+       }};
+
+       result = spi_send_multicommand(flash, cmds);
+       if (result) {
+               msg_cerr("%s failed during command execution at address 
0x%x\n", __func__, addr);
+               return result;
+       }
+       /* Wait until the Write-In-Progress bit is cleared.
+        * This usually takes 10 ms, so wait in 1 ms steps.
+        */
+       while (spi_read_status_register(flash) & SPI_SR_WIP)
+               programmer_delay(1 * 1000);
+       /* FIXME: Check the status register for errors. */
+       return 0;
+}
+
+int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen)
+{
+       int result;
+       struct spi_command cmds[] = {
+       {
+/*             .writecnt       = JEDEC_WREN_OUTSIZE,
+               .writearr       = (const unsigned char[]){ JEDEC_WREN },
+               .readcnt        = 0,
+               .readarr        = NULL,
+       }, { */
+               .writecnt       = JEDEC_BE_81_OUTSIZE,
+               .writearr       = (const unsigned char[]){
+                                       JEDEC_BE_81,
+                                       (addr >> 16) & 0xff,
+                                       (addr >> 8) & 0xff,
+                                       (addr & 0xff)
+                               },
+               .readcnt        = 0,
+               .readarr        = NULL,
+       }, {
+               .writecnt       = 0,
+               .writearr       = NULL,
+               .readcnt        = 0,
+               .readarr        = NULL,
+       }};
+
+       result = spi_send_multicommand(flash, cmds);
+       if (result) {
+               msg_cerr("%s failed during command execution at address 
0x%x\n", __func__, addr);
+               return result;
+       }
+       /* Wait until the Write-In-Progress bit is cleared.
+        * This usually takes 8 ms, so wait in 1 ms steps.
+        */
+       while (spi_read_status_register(flash) & SPI_SR_WIP)
+               programmer_delay(1 * 1000);
+       /* FIXME: Check the status register for errors. */
+       return 0;
+}
+
 int spi_block_erase_60(struct flashctx *flash, unsigned int addr,
                       unsigned int blocklen)
 {
-- 
Kind regards, Stefan Tauner


_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to