]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - board/atmel/atstk1000/flash.c
imported Freescale specific U-Boot additions for i.MX28,... release L2.6.31_10.08.01
[karo-tx-uboot.git] / board / atmel / atstk1000 / flash.c
index 3aebf66ee24015a01d5f5f4c0ff68e2dc4bb86c0..0ba06ddc5d87f9f56ff451a06254d72462745fa1 100755 (executable)
@@ -22,7 +22,7 @@
 #include <common.h>
 
 #ifdef CONFIG_ATSTK1000_EXT_FLASH
-#include <asm/cacheflush.h>
+#include <asm/arch/cacheflush.h>
 #include <asm/io.h>
 #include <asm/sections.h>
 
@@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 flash_info_t flash_info[1];
 
-static void __flashprog flash_identify(uint16_t *flash, flash_info_t *info)
+static void flash_identify(uint16_t *flash, flash_info_t *info)
 {
        unsigned long flags;
 
@@ -55,32 +55,28 @@ unsigned long flash_init(void)
        unsigned long addr;
        unsigned int i;
 
-       gd->bd->bi_flashstart = CFG_FLASH_BASE;
-       gd->bd->bi_flashsize = CFG_FLASH_SIZE;
-       gd->bd->bi_flashoffset = __edata_lma - _text;
-
-       flash_info[0].size = CFG_FLASH_SIZE;
+       flash_info[0].size = CONFIG_SYS_FLASH_SIZE;
        flash_info[0].sector_count = 135;
 
-       flash_identify(uncached((void *)CFG_FLASH_BASE), &flash_info[0]);
+       flash_identify(uncached((void *)CONFIG_SYS_FLASH_BASE), &flash_info[0]);
 
        for (i = 0, addr = 0; i < 8; i++, addr += 0x2000)
                flash_info[0].start[i] = addr;
        for (; i < flash_info[0].sector_count; i++, addr += 0x10000)
                flash_info[0].start[i] = addr;
 
-       return CFG_FLASH_SIZE;
+       return CONFIG_SYS_FLASH_SIZE;
 }
 
 void flash_print_info(flash_info_t *info)
 {
-       printf("Flash: Vendor ID: 0x%02x, Product ID: 0x%02x\n",
+       printf("Flash: Vendor ID: 0x%02lx, Product ID: 0x%02lx\n",
               info->flash_id >> 16, info->flash_id & 0xffff);
        printf("Size: %ld MB in %d sectors\n",
               info->size >> 10, info->sector_count);
 }
 
-int __flashprog flash_erase(flash_info_t *info, int s_first, int s_last)
+int flash_erase(flash_info_t *info, int s_first, int s_last)
 {
        unsigned long flags;
        unsigned long start_time;
@@ -158,12 +154,12 @@ int __flashprog flash_erase(flash_info_t *info, int s_first, int s_last)
        return ERR_OK;
 }
 
-int __flashprog write_buff(flash_info_t *info, uchar *src,
+int write_buff(flash_info_t *info, uchar *src,
                           ulong addr, ulong count)
 {
        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]
@@ -198,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)