summaryrefslogtreecommitdiff
path: root/drivers/mtd/cfi_flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/cfi_flash.c')
-rw-r--r--drivers/mtd/cfi_flash.c156
1 files changed, 92 insertions, 64 deletions
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 68ab55f8a5..aaca81b01d 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -32,7 +32,7 @@
*/
/* The DEBUG define must be before common to enable debugging */
-/* #define DEBUG */
+/* #define DEBUG */
#include <common.h>
#include <asm/processor.h>
@@ -162,6 +162,10 @@ static ulong bank_base[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS_LIST;
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* FLASH chips info */
#endif
+#ifdef CFG_FLASH_SPL_ACCESS
+void board_flash_set_access(ulong bank_base, int banknum, flash_info_t* flash_info);
+#endif
+
/*
* Check if chip width is defined. If not, start detecting with 8bit.
*/
@@ -358,9 +362,9 @@ static inline uchar flash_read_uchar (flash_info_t * info, uint offset)
cp = flash_map (info, 0, offset);
#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
- retval = flash_read8(cp);
+ retval = info->read8(cp);
#else
- retval = flash_read8(cp + info->portwidth - 1);
+ retval = info->read8(cp + info->portwidth - 1);
#endif
flash_unmap (info, 0, offset, cp);
return retval;
@@ -374,7 +378,7 @@ static inline ushort flash_read_word (flash_info_t * info, uint offset)
ushort *addr, retval;
addr = flash_map (info, 0, offset);
- retval = flash_read16 (addr);
+ retval = info->read16 (addr);
flash_unmap (info, 0, offset, addr);
return retval;
}
@@ -399,19 +403,19 @@ static ulong flash_read_long (flash_info_t * info, flash_sect_t sect,
debug ("long addr is at %p info->portwidth = %d\n", addr,
info->portwidth);
for (x = 0; x < 4 * info->portwidth; x++) {
- debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
+ debug ("addr[%x] = 0x%x\n", x, info->read8(addr + x));
}
#endif
#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
- retval = ((flash_read8(addr) << 16) |
- (flash_read8(addr + info->portwidth) << 24) |
- (flash_read8(addr + 2 * info->portwidth)) |
- (flash_read8(addr + 3 * info->portwidth) << 8));
+ retval = ((info->read8(addr) << 16) |
+ (info->read8(addr + info->portwidth) << 24) |
+ (info->read8(addr + 2 * info->portwidth)) |
+ (info->read8(addr + 3 * info->portwidth) << 8));
#else
- retval = ((flash_read8(addr + 2 * info->portwidth - 1) << 24) |
- (flash_read8(addr + info->portwidth - 1) << 16) |
- (flash_read8(addr + 4 * info->portwidth - 1) << 8) |
- (flash_read8(addr + 3 * info->portwidth - 1)));
+ retval = ((info->read8(addr + 2 * info->portwidth - 1) << 24) |
+ (info->read8(addr + info->portwidth - 1) << 16) |
+ (info->read8(addr + 4 * info->portwidth - 1) << 8) |
+ (info->read8(addr + 3 * info->portwidth - 1)));
#endif
flash_unmap(info, sect, offset, addr);
@@ -434,19 +438,19 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
case FLASH_CFI_8BIT:
debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr, cmd,
cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
- flash_write8(cword.c, addr);
+ info->write8(cword.c, addr);
break;
case FLASH_CFI_16BIT:
debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr,
cmd, cword.w,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
- flash_write16(cword.w, addr);
+ info->write16(cword.w, addr);
break;
case FLASH_CFI_32BIT:
debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr,
cmd, cword.l,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
- flash_write32(cword.l, addr);
+ info->write32(cword.l, addr);
break;
case FLASH_CFI_64BIT:
#ifdef DEBUG
@@ -460,7 +464,7 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
}
#endif
- flash_write64(cword.ll, addr);
+ info->write64(cword.ll, addr);
break;
}
@@ -491,16 +495,16 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect,
debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- debug ("is= %x %x\n", flash_read8(addr), cword.c);
- retval = (flash_read8(addr) == cword.c);
+ debug ("is= %x %x\n", info->read8(addr), cword.c);
+ retval = (info->read8(addr) == cword.c);
break;
case FLASH_CFI_16BIT:
- debug ("is= %4.4x %4.4x\n", flash_read16(addr), cword.w);
- retval = (flash_read16(addr) == cword.w);
+ debug ("is= %4.4x %4.4x\n", info->read16(addr), cword.w);
+ retval = (info->read16(addr) == cword.w);
break;
case FLASH_CFI_32BIT:
- debug ("is= %8.8lx %8.8lx\n", flash_read32(addr), cword.l);
- retval = (flash_read32(addr) == cword.l);
+ debug ("is= %8.8lx %8.8lx\n", info->read32(addr), cword.l);
+ retval = (info->read32(addr) == cword.l);
break;
case FLASH_CFI_64BIT:
#ifdef DEBUG
@@ -508,12 +512,12 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect,
char str1[20];
char str2[20];
- print_longlong (str1, flash_read64(addr));
+ print_longlong (str1, info->read64(addr));
print_longlong (str2, cword.ll);
debug ("is= %s %s\n", str1, str2);
}
#endif
- retval = (flash_read64(addr) == cword.ll);
+ retval = (info->read64(addr) == cword.ll);
break;
default:
retval = 0;
@@ -537,16 +541,16 @@ static int flash_isset (flash_info_t * info, flash_sect_t sect,
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- retval = ((flash_read8(addr) & cword.c) == cword.c);
+ retval = ((info->read8(addr) & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
- retval = ((flash_read16(addr) & cword.w) == cword.w);
+ retval = ((info->read16(addr) & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
- retval = ((flash_read32(addr) & cword.l) == cword.l);
+ retval = ((info->read32(addr) & cword.l) == cword.l);
break;
case FLASH_CFI_64BIT:
- retval = ((flash_read64(addr) & cword.ll) == cword.ll);
+ retval = ((info->read64(addr) & cword.ll) == cword.ll);
break;
default:
retval = 0;
@@ -570,20 +574,20 @@ static int flash_toggle (flash_info_t * info, flash_sect_t sect,
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- retval = ((flash_read8(addr) & cword.c) !=
- (flash_read8(addr) & cword.c));
+ retval = ((info->read8(addr) & cword.c) !=
+ (info->read8(addr) & cword.c));
break;
case FLASH_CFI_16BIT:
- retval = ((flash_read16(addr) & cword.w) !=
- (flash_read16(addr) & cword.w));
+ retval = ((info->read16(addr) & cword.w) !=
+ (info->read16(addr) & cword.w));
break;
case FLASH_CFI_32BIT:
- retval = ((flash_read32(addr) & cword.l) !=
- (flash_read32(addr) & cword.l));
+ retval = ((info->read32(addr) & cword.l) !=
+ (info->read32(addr) & cword.l));
break;
case FLASH_CFI_64BIT:
- retval = ((flash_read64(addr) & cword.ll) !=
- (flash_read64(addr) & cword.ll));
+ retval = ((info->read64(addr) & cword.ll) !=
+ (info->read64(addr) & cword.ll));
break;
default:
retval = 0;
@@ -768,16 +772,16 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
/* Check if Flash is (sufficiently) erased */
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- flag = ((flash_read8(dstaddr) & cword.c) == cword.c);
+ flag = ((info->read8(dstaddr) & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
- flag = ((flash_read16(dstaddr) & cword.w) == cword.w);
+ flag = ((info->read16(dstaddr) & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
- flag = ((flash_read32(dstaddr) & cword.l) == cword.l);
+ flag = ((info->read32(dstaddr) & cword.l) == cword.l);
break;
case FLASH_CFI_64BIT:
- flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);
+ flag = ((info->read64(dstaddr) & cword.ll) == cword.ll);
break;
default:
flag = 0;
@@ -809,16 +813,16 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- flash_write8(cword.c, dstaddr);
+ info->write8(cword.c, dstaddr);
break;
case FLASH_CFI_16BIT:
- flash_write16(cword.w, dstaddr);
+ info->write16(cword.w, dstaddr);
break;
case FLASH_CFI_32BIT:
- flash_write32(cword.l, dstaddr);
+ info->write32(cword.l, dstaddr);
break;
case FLASH_CFI_64BIT:
- flash_write64(cword.ll, dstaddr);
+ info->write64(cword.ll, dstaddr);
break;
}
@@ -870,23 +874,23 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
while ((cnt-- > 0) && (flag == 0)) {
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- flag = ((flash_read8(dst2) & flash_read8(src)) ==
- flash_read8(src));
+ flag = ((info->read8(dst2) & info->read8(src)) ==
+ info->read8(src));
src += 1, dst2 += 1;
break;
case FLASH_CFI_16BIT:
- flag = ((flash_read16(dst2) & flash_read16(src)) ==
- flash_read16(src));
+ flag = ((info->read16(dst2) & info->read16(src)) ==
+ info->read16(src));
src += 2, dst2 += 2;
break;
case FLASH_CFI_32BIT:
- flag = ((flash_read32(dst2) & flash_read32(src)) ==
- flash_read32(src));
+ flag = ((info->read32(dst2) & info->read32(src)) ==
+ info->read32(src));
src += 4, dst2 += 4;
break;
case FLASH_CFI_64BIT:
- flag = ((flash_read64(dst2) & flash_read64(src)) ==
- flash_read64(src));
+ flag = ((info->read64(dst2) & info->read64(src)) ==
+ info->read64(src));
src += 8, dst2 += 8;
break;
}
@@ -915,19 +919,19 @@ 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);
+ info->write8(info->read8(src), dst);
src += 1, dst += 1;
break;
case FLASH_CFI_16BIT:
- flash_write16(flash_read16(src), dst);
+ info->write16(info->read16(src), dst);
src += 2, dst += 2;
break;
case FLASH_CFI_32BIT:
- flash_write32(flash_read32(src), dst);
+ info->write32(info->read32(src), dst);
src += 4, dst += 4;
break;
case FLASH_CFI_64BIT:
- flash_write64(flash_read64(src), dst);
+ info->write64(info->read64(src), dst);
src += 8, dst += 8;
break;
default:
@@ -958,25 +962,25 @@ 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);
+ info->write8(info->read8(src), dst);
src += 1, dst += 1;
}
break;
case FLASH_CFI_16BIT:
while (cnt-- > 0) {
- flash_write16(flash_read16(src), dst);
+ info->write16(info->read16(src), dst);
src += 2, dst += 2;
}
break;
case FLASH_CFI_32BIT:
while (cnt-- > 0) {
- flash_write32(flash_read32(src), dst);
+ info->write32(info->read32(src), dst);
src += 4, dst += 4;
}
break;
case FLASH_CFI_64BIT:
while (cnt-- > 0) {
- flash_write64(flash_read64(src), dst);
+ info->write64(info->read64(src), dst);
src += 8, dst += 8;
}
break;
@@ -1240,14 +1244,14 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
cword.l = 0;
p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
for (i = 0; i < aln; ++i)
- flash_add_byte (info, &cword, flash_read8(p + i));
+ flash_add_byte (info, &cword, info->read8(p + i));
for (; (i < info->portwidth) && (cnt > 0); i++) {
flash_add_byte (info, &cword, *src++);
cnt--;
}
for (; (cnt == 0) && (i < info->portwidth); ++i)
- flash_add_byte (info, &cword, flash_read8(p + i));
+ flash_add_byte (info, &cword, info->read8(p + i));
rc = flash_write_cfiword (info, wp, cword);
unmap_physmem(p, info->portwidth);
@@ -1315,7 +1319,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
--cnt;
}
for (; i < info->portwidth; ++i)
- flash_add_byte (info, &cword, flash_read8(p + i));
+ flash_add_byte (info, &cword, info->read8(p + i));
unmap_physmem(p, info->portwidth);
return flash_write_cfiword (info, wp, cword);
@@ -1888,6 +1892,29 @@ unsigned long flash_init (void)
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
+ /* flash read and write routines board specific attention */
+#ifdef CFG_FLASH_SPL_ACCESS
+ board_flash_set_access(bank_base[i], i, &flash_info[i]);
+#endif
+
+ if(!flash_info[i].write8)
+ flash_info[i].write8 = flash_write8;
+ if(!flash_info[i].write16)
+ flash_info[i].write16 = flash_write16;
+ if(!flash_info[i].write32)
+ flash_info[i].write32 = flash_write32;
+ if(!flash_info[i].write64)
+ flash_info[i].write64 = flash_write64;
+
+ if(!flash_info[i].read8)
+ flash_info[i].read8 = flash_read8;
+ if(!flash_info[i].read16)
+ flash_info[i].read16 = flash_read16;
+ if(!flash_info[i].read32)
+ flash_info[i].read32 = flash_read32;
+ if(!flash_info[i].read64)
+ flash_info[i].read64 = flash_read64;
+
if (!flash_detect_legacy (bank_base[i], i))
flash_get_size (bank_base[i], i);
size += flash_info[i].size;
@@ -1947,6 +1974,7 @@ unsigned long flash_init (void)
}
}
#endif /* CFG_FLASH_PROTECTION */
+
}
/* Monitor protection ON by default */