
Dear Scott,
In message 48FBADA6.3090505@psyent.com you wrote:
Why the heck does flash_is_busy() return 0 when the flashobviously is still busy?
Does this use the toggle bit detection? I saw the same symptoms with Nios II. Basically, the memory controller was reading the 16-bit flash twice to obtain a full 32-bit word, then returning just the first 16-bits. So, I would never see the toggle bit changing.
Not sure if this is similar to your situation ... but it was a real pain-in-the-butt to finally understand what was happening in my situation.
My situation is indeed similar. The 64 bit read (which is supposed to be implemented by flash_read64()) is in fact broken downinto two 32 bit reads, with the consequence that flash_toggle() does not work any more, because of reading the *same* addresses twice we are reading alternate addresses (addr, addr+4, addr, addr+4).
This patch fixes the problem for me:
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index c40bf66..24e9b9f 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -596,7 +596,8 @@ static int flash_toggle (flash_info_t * info, flash_sect_t sect, retval = flash_read32(addr) != flash_read32(addr); break; case FLASH_CFI_64BIT: - retval = flash_read64(addr) != flash_read64(addr); + retval = ( (flash_read32( addr ) != flash_read32( addr )) || + (flash_read32(addr+4) != flash_read32(addr+4)) ); break; default: retval = 0;
However, I'm not really happy about this. Maybe we should really implement an atomic 64 bit read operation for flash_read64()? But the only solution I could come up for this would be pretty complex:
save MSR; set Floating Point enable bit in MSR; use "lfd" instruction to perform atomic 64 bit read; use "stfd" to store value to temporary variable on stack; load u64 from temporary variable; restore saved MSR; return u64 value;
Is this worth the trouble?
Is it valid to assume that a processor which has the flashon a 64 bit bus will also have a FPU?
Would ne need to save/restore the FP register used here?
Best regards,
Wolfgang Denk