summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2007-04-19 10:10:11 +0200
committerHaavard Skinnemoen <hskinnemoen@atmel.com>2008-02-05 12:14:27 +0100
commit61151cccb660cdb06a07fb283de6089913d7bde0 (patch)
tree3b40500415bbb4203dc9316f01aef1a000e58c08
parentb2e1d5b64469f10dfcce27f7b0afd935684a8e11 (diff)
downloadu-boot-imx-61151cccb660cdb06a07fb283de6089913d7bde0.zip
u-boot-imx-61151cccb660cdb06a07fb283de6089913d7bde0.tar.gz
u-boot-imx-61151cccb660cdb06a07fb283de6089913d7bde0.tar.bz2
ATSTK1000: Fix potential flash programming bug
The (now obsolete) atngw100 flash programming code was having problems programming the onboard at49bv642 chip. The atstk1000 flash programming code may have the same bug, so import fix for this problem from the AVR32 Linux BSP. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
-rw-r--r--board/atmel/atstk1000/flash.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/board/atmel/atstk1000/flash.c b/board/atmel/atstk1000/flash.c
index 93d790f..4047825 100644
--- a/board/atmel/atstk1000/flash.c
+++ b/board/atmel/atstk1000/flash.c
@@ -159,7 +159,7 @@ int __flashprog write_buff(flash_info_t *info, uchar *src,
{
unsigned long flags;
uint16_t *base, *p, *s, *end;
- uint16_t word, status;
+ uint16_t word, status, status1;
int ret = ERR_OK;
if (addr < info->start[0]
@@ -194,20 +194,33 @@ int __flashprog write_buff(flash_info_t *info, uchar *src,
sync_write_buffer();
/* Wait for completion */
+ status1 = readw(p);
do {
/* TODO: Timeout */
- status = readw(p);
- } while ((status != word) && !(status & 0x28));
+ status = status1;
+ status1 = readw(p);
+ } while (((status ^ status1) & 0x40) /* toggled */
+ && !(status1 & 0x28)); /* error bits */
- writew(0xf0, base);
- readw(base);
-
- if (status != word) {
- printf("Flash write error at address 0x%p: 0x%02x\n",
- p, status);
+ /*
+ * We'll need to check once again for toggle bit
+ * because the toggle bit may stop toggling as I/O5
+ * changes to "1" (ref at49bv642.pdf p9)
+ */
+ status1 = readw(p);
+ status = readw(p);
+ if ((status ^ status1) & 0x40) {
+ printf("Flash write error at address 0x%p: "
+ "0x%02x != 0x%02x\n",
+ p, status,word);
ret = ERR_PROG_ERROR;
+ writew(0xf0, base);
+ readw(base);
break;
}
+
+ writew(0xf0, base);
+ readw(base);
}
if (flags)