9
0
Fork 0

[CFI driver] For some Spansion flashes we have to write the

AMD_CMD_WRITE_TO_BUFFER command to the destination
	     address of the buffer write and not to the sector
	     beginning. Linux mtd does this as default, so I
	     assume this should work for other flashes aswell.
	     Reorder functions so that this change fits in nicely.
This commit is contained in:
Sascha Hauer 2008-02-26 10:32:25 +01:00
parent d99f33eb25
commit 51c840cd18
3 changed files with 31 additions and 49 deletions

View File

@ -110,13 +110,15 @@ static int amd_flash_write_cfibuffer (flash_info_t * info, ulong dest, const uch
int retcode;
volatile cfiptr_t src;
volatile cfiptr_t dst;
cfiword_t cword;
src.cp = (uchar *)cp;
dst.cp = (uchar *) dest;
sector = find_sector (info, dest);
flash_unlock_seq(info,0);
flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_TO_BUFFER);
flash_make_cmd (info, AMD_CMD_WRITE_TO_BUFFER, &cword);
flash_write_word(info, cword, (void *)dest);
switch (info->portwidth) {
case FLASH_CFI_8BIT:

View File

@ -41,6 +41,7 @@
#include <init.h>
#include <malloc.h>
#include <cfi_flash_new.h>
#include <asm/io.h>
/*
* This file implements a Common Flash Interface (CFI) driver for U-Boot.
@ -877,6 +878,7 @@ int flash_status_check (flash_info_t * info, flash_sect_t sector,
void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
{
int i;
cfiword_t val;
uchar *cp = (uchar *) cmdbuf;
#if defined(__LITTLE_ENDIAN)
@ -886,63 +888,19 @@ void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
#endif
*cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd;
}
/*
* Write a proper sized command to the correct address
*/
void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
{
volatile cfiptr_t addr;
uchar *addr;
cfiword_t cword;
addr.cp = flash_make_addr (info, sect, offset);
addr = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd,
cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
*addr.cp = cword.c;
#ifdef CONFIG_BLACKFIN
asm("ssync;");
#endif
break;
case FLASH_CFI_16BIT:
debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp,
cmd, cword.w,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
*addr.wp = cword.w;
#ifdef CONFIG_BLACKFIN
asm("ssync;");
#endif
break;
case FLASH_CFI_32BIT:
debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp,
cmd, cword.l,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
*addr.lp = cword.l;
#ifdef CONFIG_BLACKFIN
asm("ssync;");
#endif
break;
case FLASH_CFI_64BIT:
#ifdef DEBUG
{
char str[20];
print_longlong (str, cword.ll);
debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
addr.llp, cmd, str,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
}
#endif
*addr.llp = cword.ll;
#ifdef CONFIG_BLACKFIN
asm("ssync;");
#endif
break;
}
flash_write_word(info, cword, addr);
}
int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)

View File

@ -25,6 +25,7 @@
*/
#include <driver.h>
#include <asm/io.h>
typedef unsigned long flash_sect_t;
struct cfi_cmd_set;
@ -222,6 +223,27 @@ typedef union {
volatile unsigned long long *llp;
} cfiptr_t;
static inline void flash_write_word(flash_info_t *info, cfiword_t datum, void *addr)
{
switch (info->portwidth) {
case FLASH_CFI_8BIT:
debug("fw addr %p val %02x\n", addr, datum.c);
writeb(datum.c, addr);
break;
case FLASH_CFI_16BIT:
debug("fw addr %p val %04x\n", addr, datum.w);
writew(datum.w, addr);
break;
case FLASH_CFI_32BIT:
debug("fw addr %p val %08x\n", addr, datum.l);
writel(datum.l, addr);
break;
case FLASH_CFI_64BIT:
memcpy((void *)addr, &datum.ll, 8);
break;
}
}
extern void flash_print_info (flash_info_t *);
extern int flash_sect_erase (ulong addr_first, ulong addr_last);
extern int flash_sect_protect (int flag, ulong addr_first, ulong addr_last);