[U-Boot] [PATCH] cfi_flash: Micron Nor flash don't support read operation after send write command

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 Wangqiwang@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

Hi Qi Wang,
please don't send this patch so often.
On 11.03.2014 09:46, Qi Wang 王起 (qiwang) wrote:
Micron Nor flash don't support read operation after send write command.
Are all Micon NOR flash chips affected by this? Or only some chips? Please list the chips/families and best add a link to the description of this unsupported operation mode (chapter in data-sheet or errata).
Find a few more comments below.
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 Wangqiwang@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);
Naming is not optimal, at least for my taste. My not use "src_buf"?
- if(!src2)
- {
free(src2);
return -ENOMEM;
- }
Incorrect coding style. Please use something like this instead:
if (!src2) { free(src2); return -ENOMEM; }
Thanks, Stefan

Hi Stefan, ok, got it. Because I saw the patch format is malformed in the website http://patchwork.ozlabs.org/project/uboot/list/, so I send this patch three times. You can reference the last patch I submit. It's my first time to submit Patch to Uboot community. Sorry for bring inconvenient for you. Sorry for that. Anyway, can you help check if the patch I submit make sense? Thanks a lot
-----Original Message----- From: Stefan Roese [mailto:sr@denx.de] Sent: Wednesday, March 12, 2014 1:14 PM To: Qi Wang 王起 (qiwang); u-boot@lists.denx.de Subject: Re: [U-Boot] [PATCH] cfi_flash: Micron Nor flash don't support read operation after send write command
Hi Qi Wang,
please don't send this patch so often.
On 11.03.2014 09:46, Qi Wang 王起 (qiwang) wrote:
Micron Nor flash don't support read operation after send write command.
Are all Micon NOR flash chips affected by this? Or only some chips? Please list the chips/families and best add a link to the description of this unsupported operation mode (chapter in data-sheet or errata).
Find a few more comments below.
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 Wangqiwang@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);
Naming is not optimal, at least for my taste. My not use "src_buf"?
- if(!src2)
- {
free(src2);
return -ENOMEM;
- }
Incorrect coding style. Please use something like this instead:
if (!src2) { free(src2); return -ENOMEM; }
Thanks, Stefan
participants (2)
-
Qi Wang 王起 (qiwang)
-
Stefan Roese