[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:
parent
d99f33eb25
commit
51c840cd18
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue