1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-26 22:52:34 +02:00

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.

Corresponding to flashrom svn r1725.

Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
This commit is contained in:
Stefan Tauner 2013-08-27 18:02:19 +00:00
parent fdc4f7ebb9
commit 1dd5d3aa66
3 changed files with 60 additions and 3 deletions

View File

@ -419,6 +419,47 @@ int spi_erase_at45db_chip(struct flashctx *flash, unsigned int addr, unsigned in
return at45db_erase(flash, AT45DB_CHIP_ERASE, AT45DB_CHIP_ERASE_ADDR, 500000, 200); 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) 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; const unsigned int page_size = flash->chip->page_size;

View File

@ -121,6 +121,7 @@ int spi_erase_at45db_page(struct flashctx *flash, unsigned int addr, unsigned in
int spi_erase_at45db_block(struct flashctx *flash, unsigned int addr, unsigned int blocklen); 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_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_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 */ /* 82802ab.c */
uint8_t wait_82802ab(struct flashctx *flash); uint8_t wait_82802ab(struct flashctx *flash);

View File

@ -2323,11 +2323,26 @@ const struct flashchip flashchips[] = {
.total_size = 16896 /* No power of two sizes */, .total_size = 16896 /* No power of two sizes */,
.page_size = 1056 /* 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 */ /* 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 = probe_spi_rdid,
.probe_timing = TIMING_ZERO, .probe_timing = TIMING_ZERO,
.write = NULL /* Incompatible Page write */, .block_erasers =
.read = NULL /* Incompatible read */, {
{
.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}, .voltage = {2700, 3600},
}, },