summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chipdrivers.h3
-rw-r--r--flashchips.c21
-rw-r--r--sharplhf00l04.c101
3 files changed, 32 insertions, 93 deletions
diff --git a/chipdrivers.h b/chipdrivers.h
index 4456204..af22abf 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -53,6 +53,7 @@ int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len,
int spi_aai_write(struct flashchip *flash, uint8_t *buf);
/* 82802ab.c */
+uint8_t wait_82802ab(chipaddr bios);
int probe_82802ab(struct flashchip *flash);
int erase_82802ab(struct flashchip *flash);
int write_82802ab(struct flashchip *flash, uint8_t *buf);
@@ -117,7 +118,7 @@ int write_49fl00x(struct flashchip *flash, uint8_t *buf);
/* sharplhf00l04.c */
int probe_lhf00l04(struct flashchip *flash);
-int erase_lhf00l04(struct flashchip *flash);
+int erase_lhf00l04_block(struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen);
int write_lhf00l04(struct flashchip *flash, uint8_t *buf);
void protect_lhf00l04(chipaddr bios);
diff --git a/flashchips.c b/flashchips.c
index 50a1226..e6c4b86 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -2522,9 +2522,24 @@ struct flashchip flashchips[] = {
.total_size = 1024,
.page_size = 64 * 1024,
.tested = TEST_UNTESTED,
- .probe = probe_lhf00l04,
- .probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sharplhf00l04.c) */
- .erase = erase_lhf00l04,
+ .probe = probe_49lfxxxc,
+ .probe_timing = TIMING_ZERO,
+ .erase = NULL,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {8 * 1024, 8}
+ },
+ .block_erase = erase_lhf00l04_block,
+ }, {
+ .eraseblocks = {
+ {1024 * 1024, 1}
+ },
+ .block_erase = NULL, /* 30 D0, only in PP mode */
+ },
+ },
.write = write_lhf00l04,
.read = read_memmapped,
},
diff --git a/sharplhf00l04.c b/sharplhf00l04.c
index 1234ae4..9669e20 100644
--- a/sharplhf00l04.c
+++ b/sharplhf00l04.c
@@ -33,80 +33,20 @@ void print_lhf00l04_status(uint8_t status)
printf("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:");
}
-int probe_lhf00l04(struct flashchip *flash)
-{
- chipaddr bios = flash->virtual_memory;
- uint8_t id1, id2;
-
-#if 0
- /* Enter ID mode */
- chip_writeb(0xAA, bios + 0x5555);
- chip_writeb(0x55, bios + 0x2AAA);
- chip_writeb(0x90, bios + 0x5555);
-#endif
-
- chip_writeb(0xff, bios);
- programmer_delay(10);
- chip_writeb(0x90, bios);
- programmer_delay(10);
-
- id1 = chip_readb(bios);
- id2 = chip_readb(bios + 0x01);
-
- /* Leave ID mode */
- chip_writeb(0xAA, bios + 0x5555);
- chip_writeb(0x55, bios + 0x2AAA);
- chip_writeb(0xF0, bios + 0x5555);
-
- programmer_delay(10);
-
- printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
-
- if (id1 != flash->manufacture_id || id2 != flash->model_id)
- return 0;
-
- map_flash_registers(flash);
-
- return 1;
-}
-
-uint8_t wait_lhf00l04(chipaddr bios)
-{
- uint8_t status;
-
- chip_writeb(0x70, bios);
- if ((chip_readb(bios) & 0x80) == 0) { // it's busy
- while ((chip_readb(bios) & 0x80) == 0) ;
- }
-
- status = chip_readb(bios);
-
- // put another command to get out of status register mode.
-
- chip_writeb(0x90, bios);
- programmer_delay(10);
-
- chip_readb(bios); // vendor ID
- chip_readb(bios + 0x01); // device ID
-
- // this is needed to jam it out of "read id" mode
- chip_writeb(0xAA, bios + 0x5555);
- chip_writeb(0x55, bios + 0x2AAA);
- chip_writeb(0xF0, bios + 0x5555);
-
- return status;
-}
+/* FIXME: The datasheet is unclear whether we should use toggle_ready_jedec
+ * or wait_82802ab.
+ */
-int erase_lhf00l04_block(struct flashchip *flash, int offset)
+int erase_lhf00l04_block(struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen)
{
- chipaddr bios = flash->virtual_memory + offset;
- chipaddr wrprotect = flash->virtual_registers + offset + 2;
+ chipaddr bios = flash->virtual_memory + blockaddr;
+ chipaddr wrprotect = flash->virtual_registers + blockaddr + 2;
uint8_t status;
// clear status register
chip_writeb(0x50, bios);
printf("Erase at 0x%lx\n", bios);
- status = wait_lhf00l04(flash->virtual_memory);
+ status = wait_82802ab(flash->virtual_memory);
print_lhf00l04_status(status);
// clear write protect
printf("write protect is at 0x%lx\n", (wrprotect));
@@ -119,34 +59,17 @@ int erase_lhf00l04_block(struct flashchip *flash, int offset)
chip_writeb(0xd0, bios);
programmer_delay(10);
// now let's see what the register is
- status = wait_lhf00l04(flash->virtual_memory);
+ status = wait_82802ab(flash->virtual_memory);
print_lhf00l04_status(status);
- printf("DONE BLOCK 0x%x\n", offset);
+ printf("DONE BLOCK 0x%x\n", blockaddr);
- if (check_erased_range(flash, offset, flash->page_size)) {
+ if (check_erased_range(flash, blockaddr, blocklen)) {
fprintf(stderr, "ERASE FAILED!\n");
return -1;
}
return 0;
}
-int erase_lhf00l04(struct flashchip *flash)
-{
- int i;
- unsigned int total_size = flash->total_size * 1024;
-
- printf("total_size is %d; flash->page_size is %d\n",
- total_size, flash->page_size);
- for (i = 0; i < total_size; i += flash->page_size)
- if (erase_lhf00l04_block(flash, i)) {
- fprintf(stderr, "ERASE FAILED!\n");
- return -1;
- }
- printf("DONE ERASE\n");
-
- return 0;
-}
-
void write_page_lhf00l04(chipaddr bios, uint8_t *src,
chipaddr dst, int page_size)
{
@@ -156,7 +79,7 @@ void write_page_lhf00l04(chipaddr bios, uint8_t *src,
/* transfer data from source to destination */
chip_writeb(0x40, dst);
chip_writeb(*src++, dst++);
- wait_lhf00l04(bios);
+ wait_82802ab(bios);
}
}
@@ -167,7 +90,7 @@ int write_lhf00l04(struct flashchip *flash, uint8_t *buf)
int page_size = flash->page_size;
chipaddr bios = flash->virtual_memory;
- if (erase_lhf00l04(flash)) {
+ if (erase_flash(flash)) {
fprintf(stderr, "ERASE FAILED!\n");
return -1;
}
OpenPOWER on IntegriCloud