Author: stefanct
Date: Tue Aug 27 20:02:19 2013
New Revision: 1725
URL: http://flashrom.org/trac/flashrom/changeset/1725

Log:
Add support for AT45CS1282.

This one is even more strange than the AT45DB chips. Like the AT45DB321C
it does not support any power-of-2 page sizes. There is only one asymmetrical
eraser and that uses two opcodes.

Signed-off-by: Stefan Tauner <[email protected]>
Acked-by: Stefan Tauner <[email protected]>

Modified:
   trunk/at45db.c
   trunk/chipdrivers.h
   trunk/flashchips.c

Modified: trunk/at45db.c
==============================================================================
--- trunk/at45db.c      Tue Aug 27 20:02:12 2013        (r1724)
+++ trunk/at45db.c      Tue Aug 27 20:02:19 2013        (r1725)
@@ -419,6 +419,47 @@
        return at45db_erase(flash, AT45DB_CHIP_ERASE, AT45DB_CHIP_ERASE_ADDR, 
500000, 200);
 }
 
+/* This one is really special and works only for AT45CS1282. It uses two 
different opcodes depending on the
+ * address and has an asymmetric layout. */
+int spi_erase_at45cs_sector(struct flashctx *flash, unsigned int addr, 
unsigned int blocklen)
+{
+       const unsigned int page_size = flash->chip->page_size;
+       const unsigned int total_size = flash->chip->total_size * 1024;
+       const struct block_eraser be = flash->chip->block_erasers[0];
+       const unsigned int sec_0a_top = be.eraseblocks[0].size;
+       const unsigned int sec_0b_top = be.eraseblocks[0].size + 
be.eraseblocks[1].size;
+
+       if ((addr + blocklen) > total_size) {
+               msg_cerr("%s: tried to erase a sector beyond flash boundary: 
addr=%u, blocklen=%u, size=%u\n",
+                        __func__, addr, blocklen, total_size);
+               return 1;
+       }
+
+       bool partial_range = false;
+       uint8_t opcode = 0x7C; /* Used for all but sector 0a. */
+       if (addr < sec_0a_top) {
+               opcode = 0x50;
+               /* One single sector of 8 pages at address 0. */
+               if (addr != 0 || blocklen != (8 * page_size))
+                       partial_range = true;
+       } else if (addr < sec_0b_top) {
+               /* One single sector of 248 pages adjacent to the first. */
+               if (addr != sec_0a_top || blocklen != (248 * page_size))
+                       partial_range = true;
+       } else {
+               /* The rest is filled by 63 aligned sectors of 256 pages. */
+               if ((addr % (256 * page_size)) != 0 || (blocklen % (256 * 
page_size)) != 0)
+                       partial_range = true;
+       }
+       if (partial_range) {
+               msg_cerr("%s: cannot erase partial sectors: addr=%u, 
blocklen=%u\n", __func__, addr, blocklen);
+               return 1;
+       }
+
+       /* Needs up to 4 s for completion, so let's wait 20 seconds in 200 ms 
steps. */
+       return at45db_erase(flash, opcode, at45db_convert_addr(addr, 
page_size), 200000, 100);
+}
+
 static int at45db_fill_buffer1(struct flashctx *flash, uint8_t *bytes, 
unsigned int off, unsigned int len)
 {
        const unsigned int page_size = flash->chip->page_size;

Modified: trunk/chipdrivers.h
==============================================================================
--- trunk/chipdrivers.h Tue Aug 27 20:02:12 2013        (r1724)
+++ trunk/chipdrivers.h Tue Aug 27 20:02:19 2013        (r1725)
@@ -121,6 +121,7 @@
 int spi_erase_at45db_block(struct flashctx *flash, unsigned int addr, unsigned 
int blocklen);
 int spi_erase_at45db_sector(struct flashctx *flash, unsigned int addr, 
unsigned int blocklen);
 int spi_erase_at45db_chip(struct flashctx *flash, unsigned int addr, unsigned 
int blocklen);
+int spi_erase_at45cs_sector(struct flashctx *flash, unsigned int addr, 
unsigned int blocklen);
 
 /* 82802ab.c */
 uint8_t wait_82802ab(struct flashctx *flash);

Modified: trunk/flashchips.c
==============================================================================
--- trunk/flashchips.c  Tue Aug 27 20:02:12 2013        (r1724)
+++ trunk/flashchips.c  Tue Aug 27 20:02:19 2013        (r1725)
@@ -2323,11 +2323,26 @@
                .total_size     = 16896 /* No power of two sizes */,
                .page_size      = 1056 /* No power of two sizes */,
                /* does not support EWSR nor WREN and has no writable status 
register bits whatsoever */
-               .tested         = TEST_BAD_REW,
+               /* OTP: 128B total, 64B pre-programmed; read 0x77 (4 dummy 
bytes); write 0x9A (via buffer) */
+               .feature_bits   = FEATURE_OTP,
+               .tested         = TEST_UNTESTED,
                .probe          = probe_spi_rdid,
                .probe_timing   = TIMING_ZERO,
-               .write          = NULL /* Incompatible Page write */,
-               .read           = NULL /* Incompatible read */,
+               .block_erasers  =
+               {
+                       {
+                               .eraseblocks = {
+                                       {8 * 1056, 1},    /* sector 0a:      
opcode 50h */
+                                       {248 * 1056, 1},  /* sector 0b:      
opcode 7Ch */
+                                       {256 * 1056, 63}, /* sectors 1 - 63: 
opcode 7Ch */
+                               },
+                               .block_erase = spi_erase_at45cs_sector,
+                       }
+               },
+               .printlock      = spi_prettyprint_status_register_plain,
+               .gran           = write_gran_1056bytes,
+               .write          = spi_write_at45db,
+               .read           = spi_read_at45db,
                .voltage        = {2700, 3600},
        },
 

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

Reply via email to