summaryrefslogtreecommitdiffstats
path: root/jedec.c
diff options
context:
space:
mode:
Diffstat (limited to 'jedec.c')
-rw-r--r--jedec.c136
1 files changed, 72 insertions, 64 deletions
diff --git a/jedec.c b/jedec.c
index 97621d9..69c0c0c 100644
--- a/jedec.c
+++ b/jedec.c
@@ -37,17 +37,18 @@ uint8_t oddparity(uint8_t val)
return (val ^ (val >> 1)) & 0x1;
}
-static void toggle_ready_jedec_common(chipaddr dst, int delay)
+static void toggle_ready_jedec_common(const struct flashctx *flash,
+ chipaddr dst, int delay)
{
unsigned int i = 0;
uint8_t tmp1, tmp2;
- tmp1 = chip_readb(dst) & 0x40;
+ tmp1 = chip_readb(flash, dst) & 0x40;
while (i++ < 0xFFFFFFF) {
if (delay)
programmer_delay(delay);
- tmp2 = chip_readb(dst) & 0x40;
+ tmp2 = chip_readb(flash, dst) & 0x40;
if (tmp1 == tmp2) {
break;
}
@@ -57,9 +58,9 @@ static void toggle_ready_jedec_common(chipaddr dst, int delay)
msg_cdbg("%s: excessive loops, i=0x%x\n", __func__, i);
}
-void toggle_ready_jedec(chipaddr dst)
+void toggle_ready_jedec(const struct flashctx *flash, chipaddr dst)
{
- toggle_ready_jedec_common(dst, 0);
+ toggle_ready_jedec_common(flash, dst, 0);
}
/* Some chips require a minimum delay between toggle bit reads.
@@ -69,12 +70,13 @@ void toggle_ready_jedec(chipaddr dst)
* Given that erase is slow on all chips, it is recommended to use
* toggle_ready_jedec_slow in erase functions.
*/
-static void toggle_ready_jedec_slow(chipaddr dst)
+static void toggle_ready_jedec_slow(const struct flashctx *flash, chipaddr dst)
{
- toggle_ready_jedec_common(dst, 8 * 1000);
+ toggle_ready_jedec_common(flash, dst, 8 * 1000);
}
-void data_polling_jedec(chipaddr dst, uint8_t data)
+void data_polling_jedec(const struct flashctx *flash, chipaddr dst,
+ uint8_t data)
{
unsigned int i = 0;
uint8_t tmp;
@@ -82,7 +84,7 @@ void data_polling_jedec(chipaddr dst, uint8_t data)
data &= 0x80;
while (i++ < 0xFFFFFFF) {
- tmp = chip_readb(dst) & 0x80;
+ tmp = chip_readb(flash, dst) & 0x80;
if (tmp == data) {
break;
}
@@ -110,12 +112,13 @@ static unsigned int getaddrmask(struct flashctx *flash)
}
}
-static void start_program_jedec_common(struct flashctx *flash, unsigned int mask)
+static void start_program_jedec_common(struct flashctx *flash,
+ unsigned int mask)
{
chipaddr bios = flash->virtual_memory;
- chip_writeb(0xAA, bios + (0x5555 & mask));
- chip_writeb(0x55, bios + (0x2AAA & mask));
- chip_writeb(0xA0, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0xA0, bios + (0x5555 & mask));
}
static int probe_jedec_common(struct flashctx *flash, unsigned int mask)
@@ -150,57 +153,57 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask)
/* Reset chip to a clean slate */
if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
{
- chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
if (probe_timing_exit)
programmer_delay(10);
- chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
if (probe_timing_exit)
programmer_delay(10);
}
- chip_writeb(0xF0, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xF0, bios + (0x5555 & mask));
if (probe_timing_exit)
programmer_delay(probe_timing_exit);
/* Issue JEDEC Product ID Entry command */
- chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
if (probe_timing_enter)
programmer_delay(10);
- chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
if (probe_timing_enter)
programmer_delay(10);
- chip_writeb(0x90, bios + (0x5555 & mask));
+ chip_writeb(flash, 0x90, bios + (0x5555 & mask));
if (probe_timing_enter)
programmer_delay(probe_timing_enter);
/* Read product ID */
- id1 = chip_readb(bios);
- id2 = chip_readb(bios + 0x01);
+ id1 = chip_readb(flash, bios);
+ id2 = chip_readb(flash, bios + 0x01);
largeid1 = id1;
largeid2 = id2;
/* Check if it is a continuation ID, this should be a while loop. */
if (id1 == 0x7F) {
largeid1 <<= 8;
- id1 = chip_readb(bios + 0x100);
+ id1 = chip_readb(flash, bios + 0x100);
largeid1 |= id1;
}
if (id2 == 0x7F) {
largeid2 <<= 8;
- id2 = chip_readb(bios + 0x101);
+ id2 = chip_readb(flash, bios + 0x101);
largeid2 |= id2;
}
/* Issue JEDEC Product ID Exit command */
if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
{
- chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
if (probe_timing_exit)
programmer_delay(10);
- chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
if (probe_timing_exit)
programmer_delay(10);
}
- chip_writeb(0xF0, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xF0, bios + (0x5555 & mask));
if (probe_timing_exit)
programmer_delay(probe_timing_exit);
@@ -209,17 +212,17 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask)
msg_cdbg(", id1 parity violation");
/* Read the product ID location again. We should now see normal flash contents. */
- flashcontent1 = chip_readb(bios);
- flashcontent2 = chip_readb(bios + 0x01);
+ flashcontent1 = chip_readb(flash, bios);
+ flashcontent2 = chip_readb(flash, bios + 0x01);
/* Check if it is a continuation ID, this should be a while loop. */
if (flashcontent1 == 0x7F) {
flashcontent1 <<= 8;
- flashcontent1 |= chip_readb(bios + 0x100);
+ flashcontent1 |= chip_readb(flash, bios + 0x100);
}
if (flashcontent2 == 0x7F) {
flashcontent2 <<= 8;
- flashcontent2 |= chip_readb(bios + 0x101);
+ flashcontent2 |= chip_readb(flash, bios + 0x101);
}
if (largeid1 == flashcontent1)
@@ -238,7 +241,7 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask)
}
static int erase_sector_jedec_common(struct flashctx *flash, unsigned int page,
- unsigned int pagesize, unsigned int mask)
+ unsigned int pagesize, unsigned int mask)
{
chipaddr bios = flash->virtual_memory;
int delay_us = 0;
@@ -246,29 +249,29 @@ static int erase_sector_jedec_common(struct flashctx *flash, unsigned int page,
delay_us = 10;
/* Issue the Sector Erase command */
- chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
programmer_delay(delay_us);
- chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
programmer_delay(delay_us);
- chip_writeb(0x80, bios + (0x5555 & mask));
+ chip_writeb(flash, 0x80, bios + (0x5555 & mask));
programmer_delay(delay_us);
- chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
programmer_delay(delay_us);
- chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
programmer_delay(delay_us);
- chip_writeb(0x30, bios + page);
+ chip_writeb(flash, 0x30, bios + page);
programmer_delay(delay_us);
/* wait for Toggle bit ready */
- toggle_ready_jedec_slow(bios);
+ toggle_ready_jedec_slow(flash, bios);
/* FIXME: Check the status register for errors. */
return 0;
}
static int erase_block_jedec_common(struct flashctx *flash, unsigned int block,
- unsigned int blocksize, unsigned int mask)
+ unsigned int blocksize, unsigned int mask)
{
chipaddr bios = flash->virtual_memory;
int delay_us = 0;
@@ -276,22 +279,22 @@ static int erase_block_jedec_common(struct flashctx *flash, unsigned int block,
delay_us = 10;
/* Issue the Sector Erase command */
- chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
programmer_delay(delay_us);
- chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
programmer_delay(delay_us);
- chip_writeb(0x80, bios + (0x5555 & mask));
+ chip_writeb(flash, 0x80, bios + (0x5555 & mask));
programmer_delay(delay_us);
- chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
programmer_delay(delay_us);
- chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
programmer_delay(delay_us);
- chip_writeb(0x50, bios + block);
+ chip_writeb(flash, 0x50, bios + block);
programmer_delay(delay_us);
/* wait for Toggle bit ready */
- toggle_ready_jedec_slow(bios);
+ toggle_ready_jedec_slow(flash, bios);
/* FIXME: Check the status register for errors. */
return 0;
@@ -305,28 +308,28 @@ static int erase_chip_jedec_common(struct flashctx *flash, unsigned int mask)
delay_us = 10;
/* Issue the JEDEC Chip Erase command */
- chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
programmer_delay(delay_us);
- chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
programmer_delay(delay_us);
- chip_writeb(0x80, bios + (0x5555 & mask));
+ chip_writeb(flash, 0x80, bios + (0x5555 & mask));
programmer_delay(delay_us);
- chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
programmer_delay(delay_us);
- chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
programmer_delay(delay_us);
- chip_writeb(0x10, bios + (0x5555 & mask));
+ chip_writeb(flash, 0x10, bios + (0x5555 & mask));
programmer_delay(delay_us);
- toggle_ready_jedec_slow(bios);
+ toggle_ready_jedec_slow(flash, bios);
/* FIXME: Check the status register for errors. */
return 0;
}
static int write_byte_program_jedec_common(struct flashctx *flash, uint8_t *src,
- chipaddr dst, unsigned int mask)
+ chipaddr dst, unsigned int mask)
{
int tried = 0, failed = 0;
chipaddr bios = flash->virtual_memory;
@@ -341,10 +344,10 @@ retry:
start_program_jedec_common(flash, mask);
/* transfer data from source to destination */
- chip_writeb(*src, dst);
- toggle_ready_jedec(bios);
+ chip_writeb(flash, *src, dst);
+ toggle_ready_jedec(flash, bios);
- if (chip_readb(dst) != *src && tried++ < MAX_REFLASH_TRIES) {
+ if (chip_readb(flash, dst) != *src && tried++ < MAX_REFLASH_TRIES) {
goto retry;
}
@@ -355,7 +358,8 @@ retry:
}
/* chunksize is 1 */
-int write_jedec_1(struct flashctx *flash, uint8_t *src, unsigned int start, unsigned int len)
+int write_jedec_1(struct flashctx *flash, uint8_t *src, unsigned int start,
+ unsigned int len)
{
int i, failed = 0;
chipaddr dst = flash->virtual_memory + start;
@@ -376,7 +380,8 @@ int write_jedec_1(struct flashctx *flash, uint8_t *src, unsigned int start, unsi
return failed;
}
-int write_page_write_jedec_common(struct flashctx *flash, uint8_t *src, unsigned int start, unsigned int page_size)
+int write_page_write_jedec_common(struct flashctx *flash, uint8_t *src,
+ unsigned int start, unsigned int page_size)
{
int i, tried = 0, failed;
uint8_t *s = src;
@@ -395,12 +400,12 @@ retry:
for (i = 0; i < page_size; i++) {
/* If the data is 0xFF, don't program it */
if (*src != 0xFF)
- chip_writeb(*src, dst);
+ chip_writeb(flash, *src, dst);
dst++;
src++;
}
- toggle_ready_jedec(dst - 1);
+ toggle_ready_jedec(flash, dst - 1);
dst = d;
src = s;
@@ -424,7 +429,8 @@ retry:
* This function is a slightly modified copy of spi_write_chunked.
* Each page is written separately in chunks with a maximum size of chunksize.
*/
-int write_jedec(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len)
+int write_jedec(struct flashctx *flash, uint8_t *buf, unsigned int start,
+ int unsigned len)
{
unsigned int i, starthere, lenhere;
/* FIXME: page_size is the wrong variable. We need max_writechunk_size
@@ -480,7 +486,8 @@ int probe_jedec(struct flashctx *flash)
return probe_jedec_common(flash, mask);
}
-int erase_sector_jedec(struct flashctx *flash, unsigned int page, unsigned int size)
+int erase_sector_jedec(struct flashctx *flash, unsigned int page,
+ unsigned int size)
{
unsigned int mask;
@@ -488,7 +495,8 @@ int erase_sector_jedec(struct flashctx *flash, unsigned int page, unsigned int s
return erase_sector_jedec_common(flash, page, size, mask);
}
-int erase_block_jedec(struct flashctx *flash, unsigned int page, unsigned int size)
+int erase_block_jedec(struct flashctx *flash, unsigned int page,
+ unsigned int size)
{
unsigned int mask;
OpenPOWER on IntegriCloud