Commit 1dd5d3aa authored by Stefan Tauner's avatar Stefan Tauner
Browse files

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: default avatarStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: default avatarStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
parent fdc4f7eb
......@@ -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);
}
/* 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;
......
......@@ -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_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);
......
......@@ -2323,11 +2323,26 @@ const struct flashchip flashchips[] = {
.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},
},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment