diff options
author | Wolfgang Denk <wd@xpert.denx.de> | 2008-10-31 01:12:28 +0100 |
---|---|---|
committer | Stefan Roese <sr@denx.de> | 2008-10-31 11:32:53 +0100 |
commit | 9abda6ba735efb059f63dcb25d78b174bfcad1ad (patch) | |
tree | 969ba69d50877f7b019ca74af62489a0cd021a74 /drivers/mtd/cfi_flash.c | |
parent | d685b74c64a38849f1a129b3ab846fbf67dd937e (diff) | |
download | u-boot-imx-9abda6ba735efb059f63dcb25d78b174bfcad1ad.zip u-boot-imx-9abda6ba735efb059f63dcb25d78b174bfcad1ad.tar.gz u-boot-imx-9abda6ba735efb059f63dcb25d78b174bfcad1ad.tar.bz2 |
CFI Driver: Fix "flash not ready" problem
This patch fixes a problem on systems where the NOR flash is attached
to a 64 bit bus. The toggle bit detection in flash_toggle() is based
on the assumption that the same flash address is read twice without
any other interjacent flash accesses. However, on 32 bit systems the
function flash_read64() [as currently implemented] does not perform
an atomic 64 bit read - instead, this is broken down into two 32 bit
read accesses on addresses "addr" and "addr + 4". So instead of
reading a 64 bit value twice from "addr", we see a sequence of 4 32
bit reads from "addr", "addr + 4", "addr", and "addr + 4". The
consequence is that flash_toggle() fails to work.
This patch implements a simple, but somewhat ugly solution, as it
avoids the use of flash_read64() in this critical place (by breaking
it down manually into 32 bit read operations) instead of rewriting
flash_read64() such to perform atomic 64 bit reads as one could
expect. However, such a rewrite would require the use of floating
point load operations, which becomes 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 value from temporary variable;
restore saved MSR;
return u64 value;
The benefit-cost ratio of such an implementation was considered too
bad to actually attempt this, especially as we can expect that such
an implementation would not only have a bigger memory footprint but
also cause a performance degradation.
Signed-off-by: Wolfgang Denk <wd@denx.de>
Signed-off-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'drivers/mtd/cfi_flash.c')
-rw-r--r-- | drivers/mtd/cfi_flash.c | 3 |
1 files changed, 2 insertions, 1 deletions
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; |