cfi_flash: Support buffered writes on non-standard Spansion NOR flash

Some NOR flash chip from Spansion, for example, the s29ws-n MirrorBit
series require different addresses for buffered write commands. Define a
configuration option to support buffered writes on those chips. A more
elegant solution would be to automatically detect those chips by parsing
their CFI records, but that would require introduction of a fixup table
into the cfi_flash driver.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
master
Guennadi Liakhovetski 16 years ago committed by Stefan Roese
parent 950a392464
commit 96ef831f71
  1. 7
      README
  2. 46
      drivers/mtd/cfi_flash.c

@ -2040,6 +2040,13 @@ Configuration Settings:
This option also enables the building of the cfi_flash driver This option also enables the building of the cfi_flash driver
in the drivers directory in the drivers directory
- CFG_FLASH_USE_BUFFER_WRITE
Use buffered writes to flash.
- CONFIG_FLASH_SPANSION_S29WS_N
s29ws-n MirrorBit flash has non-standard addresses for buffered
write commands.
- CFG_FLASH_QUIET_TEST - CFG_FLASH_QUIET_TEST
If this option is defined, the common CFI flash doesn't If this option is defined, the common CFI flash doesn't
print it's warning upon not recognized FLASH banks. This print it's warning upon not recognized FLASH banks. This

@ -844,25 +844,29 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
void *dst = map_physmem(dest, len, MAP_NOCACHE); void *dst = map_physmem(dest, len, MAP_NOCACHE);
void *dst2 = dst; void *dst2 = dst;
int flag = 0; int flag = 0;
uint offset = 0;
unsigned int shift;
switch (info->portwidth) { switch (info->portwidth) {
case FLASH_CFI_8BIT: case FLASH_CFI_8BIT:
cnt = len; shift = 0;
break; break;
case FLASH_CFI_16BIT: case FLASH_CFI_16BIT:
cnt = len >> 1; shift = 1;
break; break;
case FLASH_CFI_32BIT: case FLASH_CFI_32BIT:
cnt = len >> 2; shift = 2;
break; break;
case FLASH_CFI_64BIT: case FLASH_CFI_64BIT:
cnt = len >> 3; shift = 3;
break; break;
default: default:
retcode = ERR_INVAL; retcode = ERR_INVAL;
goto out_unmap; goto out_unmap;
} }
cnt = len >> shift;
while ((cnt-- > 0) && (flag == 0)) { while ((cnt-- > 0) && (flag == 0)) {
switch (info->portwidth) { switch (info->portwidth) {
case FLASH_CFI_8BIT: case FLASH_CFI_8BIT:
@ -906,23 +910,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
if (retcode == ERR_OK) { if (retcode == ERR_OK) {
/* reduce the number of loops by the width of /* reduce the number of loops by the width of
* the port */ * the port */
switch (info->portwidth) { cnt = len >> shift;
case FLASH_CFI_8BIT:
cnt = len;
break;
case FLASH_CFI_16BIT:
cnt = len >> 1;
break;
case FLASH_CFI_32BIT:
cnt = len >> 2;
break;
case FLASH_CFI_64BIT:
cnt = len >> 3;
break;
default:
retcode = ERR_INVAL;
goto out_unmap;
}
flash_write_cmd (info, sector, 0, (uchar) cnt - 1); flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
while (cnt-- > 0) { while (cnt-- > 0) {
switch (info->portwidth) { switch (info->portwidth) {
@ -959,36 +947,34 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
case CFI_CMDSET_AMD_STANDARD: case CFI_CMDSET_AMD_STANDARD:
case CFI_CMDSET_AMD_EXTENDED: case CFI_CMDSET_AMD_EXTENDED:
flash_unlock_seq(info,0); flash_unlock_seq(info,0);
flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_TO_BUFFER);
#ifdef CONFIG_FLASH_SPANSION_S29WS_N
offset = ((unsigned long)dst - info->start[sector]) >> shift;
#endif
flash_write_cmd(info, sector, offset, AMD_CMD_WRITE_TO_BUFFER);
cnt = len >> shift;
flash_write_cmd(info, sector, offset, (uchar)cnt - 1);
switch (info->portwidth) { switch (info->portwidth) {
case FLASH_CFI_8BIT: case FLASH_CFI_8BIT:
cnt = len;
flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
while (cnt-- > 0) { while (cnt-- > 0) {
flash_write8(flash_read8(src), dst); flash_write8(flash_read8(src), dst);
src += 1, dst += 1; src += 1, dst += 1;
} }
break; break;
case FLASH_CFI_16BIT: case FLASH_CFI_16BIT:
cnt = len >> 1;
flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
while (cnt-- > 0) { while (cnt-- > 0) {
flash_write16(flash_read16(src), dst); flash_write16(flash_read16(src), dst);
src += 2, dst += 2; src += 2, dst += 2;
} }
break; break;
case FLASH_CFI_32BIT: case FLASH_CFI_32BIT:
cnt = len >> 2;
flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
while (cnt-- > 0) { while (cnt-- > 0) {
flash_write32(flash_read32(src), dst); flash_write32(flash_read32(src), dst);
src += 4, dst += 4; src += 4, dst += 4;
} }
break; break;
case FLASH_CFI_64BIT: case FLASH_CFI_64BIT:
cnt = len >> 3;
flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
while (cnt-- > 0) { while (cnt-- > 0) {
flash_write64(flash_read64(src), dst); flash_write64(flash_read64(src), dst);
src += 8, dst += 8; src += 8, dst += 8;

Loading…
Cancel
Save