Skip to contentSkip to conversation

cfi_flash: Micron Nor flash don't support read operation after send write command

PATCH New Qi Wang 王起 (qiwang) 2 participants 3 messages Mar 11, 2014 – Mar 12, 2014 Memory technology devices (MTD)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

---
drivers/mtd/cfi_flash.c | 70 +++++++++++++++++++++++++++++++----------------

 1 file changed, 46 insertions(+), 24 deletions(-)
drivers/mtd/cfi_flash.c +2 -0
@@ -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

#1 lore raw

PATCH 1/1 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.

Quoted 1 line · Qi Wang ?? (qiwang)

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.

Quoted 43 lines

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.

---
drivers/mtd/cfi_flash.c | 70 +++++++++++++++++++++++++++++++----------------

  1 file changed, 46 insertions(+), 24 deletions(-)
drivers/mtd/cfi_flash.c +2 -0
@@ -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;
drivers/mtd/cfi_flash.c +2 -0
+	void *src2;
+	void *src2_bak;
  	void *dst = (void *)dest;
  	void *dst2 = dst;
  	int flag = 1;

drivers/mtd/cfi_flash.c static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, · line 887

Quoted 4 lines
drivers/mtd/cfi_flash.c +1 -0
@@ -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"?

drivers/mtd/cfi_flash.c static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, · line 892

Quoted 5 lines
drivers/mtd/cfi_flash.c +5 -0
+	if(!src2)
+	{
+		free(src2);
+		return -ENOMEM;
+	}

Incorrect coding style. Please use something like this instead:

	if (!src2) {
		free(src2);
		return -ENOMEM;
	}

Thanks,
Stefan

#2 lore raw

PATCH 1/1 cfi_flash: Micron Nor flash don't support read operation after send write command

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 at denx.de]
Sent: Wednesday, March 12, 2014 1:14 PM
To: Qi Wang ?? (qiwang); u-boot at 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.

Quoted 1 line · Qi Wang ?? (qiwang)

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.

Quoted 43 lines

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.

---
drivers/mtd/cfi_flash.c | 70 +++++++++++++++++++++++++++++++----------------

  1 file changed, 46 insertions(+), 24 deletions(-)
drivers/mtd/cfi_flash.c +2 -0
@@ -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;
drivers/mtd/cfi_flash.c +2 -0
+	void *src2;
+	void *src2_bak;
  	void *dst = (void *)dest;
  	void *dst2 = dst;
  	int flag = 1;

drivers/mtd/cfi_flash.c static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, · line 887

Quoted 4 lines
drivers/mtd/cfi_flash.c +1 -0
@@ -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"?

drivers/mtd/cfi_flash.c static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, · line 892

Quoted 5 lines
drivers/mtd/cfi_flash.c +5 -0
+	if(!src2)
+	{
+		free(src2);
+		return -ENOMEM;
+	}

Incorrect coding style. Please use something like this instead:

	if (!src2) {
		free(src2);
		return -ENOMEM;
	}

Thanks,
Stefan