
Dear Stefan Roese,
2009/7/3 Stefan Roese sr@denx.de:
Yes, I understand your problem and it needs to get fixed. But your original patch changed the unlock address not only for this "legacy" FLASH type but for all AMD type FLASH chips. And I'm not sure if this is correct. Meaning if the AMD/Spansion chips will accept these unlock addresses.
Perhaps you could check some data-sheets (some older and more recent Spansion CFI chips) which unlock addresses should be used here.
After checked the data sheets of jedec flash currently supported in u-boot -
SST 39LF020 AMD AM29LV040B SST 39LF040 ST Micro M29W040B AMD AM29LV400BB AMD AM29LV800BB
I found that the addresses to program a word of these chips are related to 0 (not sector base).
And in flash_erase() in drivers/mtd/cfi_flash.c
case CFI_CMDSET_AMD_STANDARD: case CFI_CMDSET_AMD_EXTENDED: flash_unlock_seq (info, sect); flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_ERASE_START); flash_unlock_seq (info, sect); flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR); break; #ifdef CONFIG_FLASH_CFI_LEGACY case CFI_CMDSET_AMD_LEGACY: flash_unlock_seq (info, 0); flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_ERASE_START); flash_unlock_seq (info, 0); flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR); break; #endif
It look like CFI_CMDSET_AMD_LEGACY use base 0 CFI_CMDSET_AMD_STANDARD and CFI_CMDSET_AMD_EXTENDED use sector base for erase.
It probably is the same case while programing a word.
The following patch might be feasible. However, I don't have those chips for testing.
regards, Po-Yu Chuang
--- drivers/mtd/cfi_flash.c | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index d0732f5..81ac5d3 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -835,14 +835,19 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest, break; case CFI_CMDSET_AMD_EXTENDED: case CFI_CMDSET_AMD_STANDARD: -#ifdef CONFIG_FLASH_CFI_LEGACY - case CFI_CMDSET_AMD_LEGACY: -#endif sect = find_sector(info, dest); flash_unlock_seq (info, sect); flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_WRITE); sect_found = 1; break; +#ifdef CONFIG_FLASH_CFI_LEGACY + case CFI_CMDSET_AMD_LEGACY: + sect = find_sector(info, dest); + flash_unlock_seq (info, 0); + flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_WRITE); + sect_found = 1; + break; +#endif }
switch (info->portwidth) {