Micron Nor flash don't support read operation after send write command. As 
below,

        flash_write_cmd(info, sector, offset, AMD_CMD_WRITE_TO_BUFFER);
        cnt = len >> shift;
        flash_write_cmd(info, sector, offset, cnt - 1);

        switch (info->portwidth) {
        case FLASH_CFI_8BIT:
                while (cnt-- > 0) {
                        flash_write8(flash_read8(src), dst);
                        src += 1, dst += 1;
                }
        break;

If the src address locate in NOR flash, flash_read operation will be failed.
So, read out the data to DRAM before send write command operation.

Signed-off-by: Qi Wang<qiw...@micron.com>
---
drivers/mtd/cfi_flash.c |   70 +++++++++++++++++++++++++++++++----------------
 1 file changed, 46 insertions(+), 24 deletions(-)

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 
a389cd1..0f532c0 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -25,6 +25,8 @@
 #include <environment.h>
 #include <mtd/cfi_flash.h>
 #include <watchdog.h>
+#include <malloc.h>
+#include <asm-generic/errno.h>
 
 /*
  * This file implements a Common Flash Interface (CFI) driver for @@ -855,6 
+857,8 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, 
uchar * cp,
        int cnt;
        int retcode;
        void *src = cp;
+       void *src2;
+       void *src2_bak;
        void *dst = (void *)dest;
        void *dst2 = dst;
        int flag = 1;
@@ -880,29 +884,45 @@ static int flash_write_cfibuffer (flash_info_t * info, 
ulong dest, uchar * cp,
                goto out_unmap;
        }
 
+       src2 = malloc(len);
+       if(!src2)
+       {
+               free(src2);
+               return -ENOMEM;
+       }
+
+       src2_bak = src2;
        cnt = len >> shift;
 
        while ((cnt-- > 0) && (flag == 1)) {
                switch (info->portwidth) {
                case FLASH_CFI_8BIT:
-                       flag = ((flash_read8(dst2) & flash_read8(src)) ==
-                               flash_read8(src));
+                       *(u8 *)src2 = flash_read8(src);
+                       flag = ((flash_read8(dst2) & *(u8 *)src2) ==
+                               *(u8 *)src2);
                        src += 1, dst2 += 1;
+                       src2 +=1;
                        break;
                case FLASH_CFI_16BIT:
-                       flag = ((flash_read16(dst2) & flash_read16(src)) ==
-                               flash_read16(src));
+                       *(u16 *)src2 = flash_read16(src);
+                       flag = ((flash_read16(dst2) & *(u16 *)src2) ==
+                               *(u16 *)src2);
                        src += 2, dst2 += 2;
+                       src2 += 2;
                        break;
                case FLASH_CFI_32BIT:
-                       flag = ((flash_read32(dst2) & flash_read32(src)) ==
-                               flash_read32(src));
+                       *(u32 *)src2 = flash_read32(src);
+                       flag = ((flash_read32(dst2) & *(u32 *)src2) ==
+                               *(u32 *)src2);
                        src += 4, dst2 += 4;
+                       src2 += 4;
                        break;
                case FLASH_CFI_64BIT:
-                       flag = ((flash_read64(dst2) & flash_read64(src)) ==
-                               flash_read64(src));
+                       *(u64 *)src2 = flash_read64(src);
+                       flag = ((flash_read64(dst2) & *(u64 *)src2) ==
+                               *(u64 *)src2);
                        src += 8, dst2 += 8;
+                       src2 += 8;
                        break;
                }
        }
@@ -912,6 +932,7 @@ static int flash_write_cfibuffer (flash_info_t * info, 
ulong dest, uchar * cp,
        }
 
        src = cp;
+       src2 = src2_bak;
        sector = find_sector (info, dest);
 
        switch (info->vendor) {
@@ -934,20 +955,20 @@ static int flash_write_cfibuffer (flash_info_t * info, 
ulong dest, uchar * cp,
                        while (cnt-- > 0) {
                                switch (info->portwidth) {
                                case FLASH_CFI_8BIT:
-                                       flash_write8(flash_read8(src), dst);
-                                       src += 1, dst += 1;
+                                       flash_write8(*(u8 *)src2, dst);
+                                       src2 += 1, dst += 1;
                                        break;
                                case FLASH_CFI_16BIT:
-                                       flash_write16(flash_read16(src), dst);
-                                       src += 2, dst += 2;
+                                       flash_write16(*(u16 *)src2, dst);
+                                       src2 += 2, dst += 2;
                                        break;
                                case FLASH_CFI_32BIT:
-                                       flash_write32(flash_read32(src), dst);
-                                       src += 4, dst += 4;
+                                       flash_write32(*(u32 *)src2, dst);
+                                       src2 += 4, dst += 4;
                                        break;
                                case FLASH_CFI_64BIT:
-                                       flash_write64(flash_read64(src), dst);
-                                       src += 8, dst += 8;
+                                       flash_write64(*(u64 *)src2, dst);
+                                       src2 += 8, dst += 8;
                                        break;
                                default:
                                        retcode = ERR_INVAL;
@@ -977,26 +998,26 @@ static int flash_write_cfibuffer (flash_info_t * info, 
ulong dest, uchar * cp,
                switch (info->portwidth) {
                case FLASH_CFI_8BIT:
                        while (cnt-- > 0) {
-                               flash_write8(flash_read8(src), dst);
-                               src += 1, dst += 1;
+                               flash_write8(*(u8 *)src2, dst);
+                               src2 += 1, dst += 1;
                        }
                        break;
                case FLASH_CFI_16BIT:
                        while (cnt-- > 0) {
-                               flash_write16(flash_read16(src), dst);
-                               src += 2, dst += 2;
+                               flash_write16(*(u16 *)src2, dst);
+                               src2 += 2, dst += 2;
                        }
                        break;
                case FLASH_CFI_32BIT:
                        while (cnt-- > 0) {
-                               flash_write32(flash_read32(src), dst);
-                               src += 4, dst += 4;
+                               flash_write32(*(u32 *)src2, dst);
+                               src2 += 4, dst += 4;
                        }
                        break;
                case FLASH_CFI_64BIT:
                        while (cnt-- > 0) {
-                               flash_write64(flash_read64(src), dst);
-                               src += 8, dst += 8;
+                               flash_write64(*(u64 *)src2, dst);
+                               src2 += 8, dst += 8;
                        }
                        break;
                default:
@@ -1023,6 +1044,7 @@ static int flash_write_cfibuffer (flash_info_t * info, 
ulong dest, uchar * cp,
        }
 
 out_unmap:
+       free(src2_bak);
        return retcode;
 }
 #endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
--
1.7.9.5

Qi Wang
Best wishes
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to