[U-Boot-Users] CFI Driver Combined Patch
Jon Loeliger
jdl at freescale.com
Tue Feb 8 18:48:53 CET 2005
Wolfgang,
This patch combines two patches submitted by myself
and York Sun and obsoletes them.
Now obsolete patches:
CFI Driver by York Sun dated 2004-10-27
CRI Driver Fencepost Bugfix by Jon Loeliger dated 2004-12-06
Thanks,
jdl
New Patch changelog:
* Patch by Jon Loeliger, Kumar Gala, 2005-02-08
- Fix a fencepost error with York's previous patch to the
CFI driver for the case where the FLASH banks aren't
actually CFI devices. This prevents oversubscripting
the offset_multiply[] array.
diff -Nur --exclude=CVS u-boot/drivers/cfi_flash.c u-boot-pq3/drivers/cfi_flash.c
--- u-boot/drivers/cfi_flash.c 2005-01-09 11:12:33.000000000 -0600
+++ u-boot-pq3/drivers/cfi_flash.c 2005-02-08 10:43:02.977169000 -0600
@@ -10,6 +10,11 @@
* Ed Okerson
* Modified to work with little-endian systems.
*
+ * Copyright (C) 2004
+ * York Sun
+ * Modified to support 8-bit port and 32-bit chip, not verified
+ * Modified to support polling DQ7 and DQ6 for AMD flash
+ *
* See file CREDITS for list of people who contributed to this
* project.
*
@@ -33,17 +38,30 @@
* 01/22/2004 - Write performance enhancements for parallel chips (Tolunay)
* 01/23/2004 - Support for x8/x16 chips (Rune Raknerud)
* 01/27/2004 - Little endian support Ed Okerson
+ * 10/26/2004 - Revised to support polling DQ7 and DQ6 for AMD flash
+ * and to support 8-bit port width on 8-bit chip
+ * and 32/64-bit port width on 32-bit chip (not verified) by York Sun
+ * According to AMD technical support: It is a good practice
+ * to the use exact where data is being written to when using
+ * "DQ6" method, even though in theory you don't have to.
*
* Tested Architectures
* Port Width Chip Width # of banks Flash Chip Board
* 32 16 1 28F128J3 seranoa/eagle
* 64 16 1 28F128J3 seranoa/falcon
+ * 16 16 2 AM29LV641DH MPC8555CDS rev 1.0
+ * 16 16 2 AM29LV641MH MPC8555CDS rev 1.0
*
*/
/* The DEBUG define must be before common to enable debugging */
/* #define DEBUG */
+#define POLLING_AMD_DQ6
+#ifndef POLLING_AMD_DQ6
+#define POLLING_AMD_DQ7 /* To use polling DQ7 instead of DQ6 for AMD algorithm */
+#endif
+
#include <common.h>
#include <asm/processor.h>
#include <asm/byteorder.h>
@@ -105,6 +123,10 @@
#define AMD_CMD_UNLOCK_START 0xAA
#define AMD_CMD_UNLOCK_ACK 0x55
+#define AMD_DQ7 0x80
+#define AMD_DQ5 0x20
+#define AMD_STATUS_TIMEOUT 0x20
+
#define AMD_STATUS_TOGGLE 0x40
#define AMD_STATUS_ERROR 0x20
#define AMD_ADDR_ERASE_START 0x555
@@ -180,14 +202,14 @@
static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf);
static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect);
-static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
-static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
-static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static int flash_isequal (flash_info_t * info, cfiptr_t cptr, uchar cmd);
+static int flash_isset (flash_info_t * info, cfiptr_t cptr, uchar cmd);
+static int flash_toggle (flash_info_t * info, cfiptr_t cptr, uchar cmd);
static int flash_detect_cfi (flash_info_t * info);
static ulong flash_get_size (ulong base, int banknum);
static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword);
-static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
- ulong tout, char *prompt);
+static int Data_Polling_Check(flash_info_t * info, cfiptr_t cptr, cfiword_t cword);
+static int flash_full_status_check (flash_info_t * info, cfiptr_t cptr, cfiword_t cword, ulong tout, char *prompt);
#ifdef CFG_FLASH_USE_BUFFER_WRITE
static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int len);
#endif
@@ -195,9 +217,21 @@
/*-----------------------------------------------------------------------
* create an address based on the offset and the port width
*/
+static const uint offset_multiply[9][5]={ /* chip width = 0 (dummy), 1 (8-bit), 2 (16-bit), 3 (dummy), 4(32-bit) */
+ {0,0,0,0,0}, /* dummy */
+ {0,2,0,0,0}, /* port width = 1 (8-bit) */
+ {0,4,2,0,0}, /* port width = 2 (16-bit) */
+ {0,0,0,0,0}, /* dummy */
+ {0,8,4,0,4}, /* port width = 4 (32-bit) */
+ {0,0,0,0,0}, /* 5, dummy */
+ {0,0,0,0,0}, /* 6, dummy */
+ {0,0,0,0,0}, /* 7, dummy */
+ {0,16,8,0,8}, /* port width = 8 (64-bit) */
+ };
+
inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
{
- return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
+ return ((uchar *) (info->start[sect] + (offset * offset_multiply[info->portwidth][info->chipwidth])));
}
#ifdef DEBUG
@@ -368,8 +402,12 @@
{
int rcode = 0;
int prot;
+ cfiword_t cword;
+ cfiptr_t cptr;
flash_sect_t sect;
+ cword.c = 0xff;
+
if (info->flash_id != FLASH_MAN_CFI) {
puts ("Can't erase unknown flash type - aborted\n");
return 1;
@@ -414,11 +452,11 @@
info->vendor);
break;
}
-
- if (flash_full_status_check
- (info, sect, info->erase_blk_tout, "erase")) {
+ cptr.cp = flash_make_addr(info,sect,0);
+ if (flash_full_status_check(info,cptr,cword, info->erase_blk_tout,"erase") ) {
rcode = 1;
- } else
+ }
+ else
putc ('.');
}
}
@@ -437,8 +475,43 @@
return;
}
- printf ("CFI conformant FLASH (%d x %d)",
+ printf ("CFI compatible FLASH (%d port width with %d chip width)\n",
(info->portwidth << 3), (info->chipwidth << 3));
+ printf ("Command set is ");
+ switch (info->vendor) {
+ case CFI_CMDSET_INTEL_EXTENDED:
+ printf ("Intel/Sharp extended\n");
+ break;
+ case CFI_CMDSET_AMD_STANDARD:
+ printf ("AMD/Fujitsu standard. ");
+#ifdef POLLING_AMD_DQ7
+ printf ("Driver is polling DQ7 for status checking.\n");
+#else
+ printf ("Driver is polling DQ6 for status checking.\n");
+#endif
+ break;
+ case CFI_CMDSET_INTEL_STANDARD:
+ printf ("Intel/Sharp standard\n");
+ break;
+ case CFI_CMDSET_AMD_EXTENDED:
+ printf ("AMD/Fujitsu extended\n");
+#ifdef POLLING_AMD_DQ7
+ printf ("Driver is polling DQ7 for status checking.\n");
+#else
+ printf ("Driver is polling DQ6 for status checking.\n");
+#endif
+ break;
+ case CFI_CMDSET_MITSU_STANDARD:
+ printf ("Mitsubishi standard\n");
+ break;
+ case CFI_CMDSET_MITSU_EXTENDED:
+ printf ("Mitsubishi extendend\n");
+ break;
+ default:
+ printf ("Not defined\n");
+ break;
+ }
+
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
@@ -503,6 +576,9 @@
int aln;
cfiword_t cword;
int i, rc;
+ ulong temp,count;
+
+ count = cnt;
#ifdef CFG_FLASH_USE_BUFFER_WRITE
int buffered_size;
@@ -544,6 +620,8 @@
cnt -= i;
}
#else
+ temp = 0;
+ printf("\n");
while (cnt >= info->portwidth) {
cword.l = 0;
for (i = 0; i < info->portwidth; i++) {
@@ -553,6 +631,10 @@
return rc;
wp += info->portwidth;
cnt -= info->portwidth;
+ if (((count-cnt)>>10)>temp) {
+ temp=(count-cnt)>>10;
+ printf("\r%d KB",temp);
+ }
}
#endif /* CFG_FLASH_USE_BUFFER_WRITE */
if (cnt == 0) {
@@ -590,7 +672,7 @@
flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
if ((retcode =
- flash_full_status_check (info, sector, info->erase_blk_tout,
+ flash_full_status_check (info, sector, 0,0,info->erase_blk_tout,
prot ? "protect" : "unprotect")) == 0) {
info->protect[sector] = prot;
@@ -643,18 +725,22 @@
* flash_is_busy - check to see if the flash is busy
* This routine checks the status of the chip and returns true if the chip is busy
*/
-static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
+static int flash_is_busy (flash_info_t * info, cfiptr_t cptr, cfiword_t cword)
{
int retval;
switch (info->vendor) {
case CFI_CMDSET_INTEL_STANDARD:
case CFI_CMDSET_INTEL_EXTENDED:
- retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);
+ retval = !flash_isset (info, cptr, FLASH_STATUS_DONE);
break;
case CFI_CMDSET_AMD_STANDARD:
case CFI_CMDSET_AMD_EXTENDED:
- retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
+#ifdef POLLING_AMD_DQ7
+ retval = Data_Polling_Check (info, cptr, cword); /* data polling for D7 */
+#else
+ retval = flash_toggle (info, cptr, AMD_STATUS_TOGGLE);
+#endif
break;
default:
retval = 0;
@@ -663,24 +749,109 @@
return retval;
}
+
+/* ----------------------------------------------------------------------
+ * Polling DQ5 for AMD flash
+ * Edited by York Sun (yorksun at freescale.com)
+ */
+static int flash_time_out (flash_info_t * info, cfiptr_t cptr, cfiword_t cword)
+{
+ int retval;
+
+ switch (info->vendor) {
+ case CFI_CMDSET_AMD_STANDARD:
+ case CFI_CMDSET_AMD_EXTENDED:
+ retval = flash_isset (info, cptr, AMD_STATUS_TIMEOUT);
+ break;
+ default:
+ retval = 0;
+ }
+ debug ("flash_time_out: %d\n", retval);
+ return retval;
+}
+
+/* ----------------------------------------------------------------------
+ * Polling DQ7 for AMD flash
+ * Edited by York Sun (yorksun at freescale.com)
+ */
+static int Data_Polling_Check(flash_info_t * info, cfiptr_t cptr, cfiword_t cword)
+{
+ uchar read_data=0,polling_data=0;
+
+ switch (info->portwidth) {
+ case FLASH_CFI_8BIT:
+ polling_data= cword.c;
+ break;
+ case FLASH_CFI_16BIT:
+ polling_data=(uchar) (cword.w & 0xff);
+ break;
+ case FLASH_CFI_32BIT:
+ polling_data=(uchar) (cword.l & 0xff);
+ break;
+ case FLASH_CFI_64BIT:
+ polling_data=(uchar) (cword.ll & 0xff);
+ break;
+ default:
+ printf("Error in function %s\n",__FUNCTION__);
+ }
+ do {
+ switch (info->portwidth) {
+ case FLASH_CFI_8BIT:
+ read_data = cptr.cp[0];
+ break;
+ case FLASH_CFI_16BIT:
+ read_data = (uchar) (cptr.wp[0] & 0xff);
+ break;
+ case FLASH_CFI_32BIT:
+ read_data = (uchar) (cptr.lp[0] & 0xff);
+ break;
+ case FLASH_CFI_64BIT:
+ read_data = (uchar) (cptr.llp[0] & 0xff);
+ break;
+ }
+ if ((read_data & AMD_DQ7) == (polling_data & AMD_DQ7))
+ break;
+ } while ((read_data & AMD_DQ5) != (uchar) AMD_DQ5);
+ switch (info->portwidth) {
+ case FLASH_CFI_8BIT:
+ read_data = cptr.cp[0];
+ break;
+ case FLASH_CFI_16BIT:
+ read_data = (uchar) (cptr.wp[0] & 0xff);
+ break;
+ case FLASH_CFI_32BIT:
+ read_data = (uchar) (cptr.lp[0] & 0xff);
+ break;
+ case FLASH_CFI_64BIT:
+ read_data = (uchar) (cptr.llp[0] & 0xff);
+ break;
+ }
+ if ((read_data & AMD_DQ7) != (polling_data & AMD_DQ7))
+ return ERR_TIMOUT;
+ else
+ return ERR_OK;
+}
+
/*-----------------------------------------------------------------------
* wait for XSR.7 to be set. Time out with an error if it does not.
* This routine does not set the flash to read-array mode.
+ * get_timer does not always work. Polling DQ5 can get the time out info for AMD flash.
*/
-static int flash_status_check (flash_info_t * info, flash_sect_t sector,
- ulong tout, char *prompt)
+static int flash_status_check (flash_info_t * info, cfiptr_t cptr, cfiword_t cword, ulong tout, char *prompt)
{
- ulong start;
+ ulong start,now;
/* Wait for command completion */
- start = get_timer (0);
- while (flash_is_busy (info, sector)) {
- if (get_timer (start) > info->erase_blk_tout * CFG_HZ) {
- printf ("Flash %s timeout at address %lx data %lx\n",
- prompt, info->start[sector],
- flash_read_long (info, sector, 0));
- flash_write_cmd (info, sector, 0, info->cmd_reset);
- return ERR_TIMOUT;
+ start = get_timer (0);
+ while (flash_is_busy (info, cptr,cword)) {
+ if ((flash_time_out(info,cptr,cword)) || \
+ ((now=get_timer (start)) > info->erase_blk_tout * CFG_HZ)) {
+ if (flash_is_busy (info, cptr,cword)) {
+ printf ("Flash %s timeout at address %lx data %lx\n",\
+ prompt, (ulong)cptr.cp,cword.l);
+ flash_write_cmd (info, 0, 0, info->cmd_reset);
+ return ERR_TIMOUT;
+ }
}
}
return ERR_OK;
@@ -690,36 +861,34 @@
* Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
* This routine sets the flash to read-array mode.
*/
-static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
- ulong tout, char *prompt)
+static int flash_full_status_check (flash_info_t * info, cfiptr_t cptr, cfiword_t cword, ulong tout, char *prompt)
{
int retcode;
- retcode = flash_status_check (info, sector, tout, prompt);
+ retcode = flash_status_check (info, cptr, cword, tout, prompt);
switch (info->vendor) {
case CFI_CMDSET_INTEL_EXTENDED:
case CFI_CMDSET_INTEL_STANDARD:
if ((retcode != ERR_OK)
- && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
+ && !flash_isequal (info, cptr, FLASH_STATUS_DONE)) {
retcode = ERR_INVAL;
- printf ("Flash %s error at address %lx\n", prompt,
- info->start[sector]);
- if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
+ printf ("Flash %s error at address %lx\n", prompt,(ulong)cptr.cp);
+ if (flash_isset (info, cptr, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
puts ("Command Sequence Error.\n");
- } else if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS)) {
+ } else if (flash_isset (info, cptr, FLASH_STATUS_ECLBS)) {
puts ("Block Erase Error.\n");
retcode = ERR_NOT_ERASED;
- } else if (flash_isset (info, sector, 0, FLASH_STATUS_PSLBS)) {
+ } else if (flash_isset (info, cptr, FLASH_STATUS_PSLBS)) {
puts ("Locking Error\n");
}
- if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
+ if (flash_isset (info, cptr, FLASH_STATUS_DPS)) {
puts ("Block locked.\n");
retcode = ERR_PROTECTED;
}
- if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))
+ if (flash_isset (info, cptr, FLASH_STATUS_VPENS))
puts ("Vpp Low Error.\n");
}
- flash_write_cmd (info, sector, 0, FLASH_CMD_RESET);
+ flash_write_cmd (info, 0,0, FLASH_CMD_RESET);
break;
default:
break;
@@ -784,9 +953,16 @@
uint stmpi;
#endif
uchar *cp = (uchar *) cmdbuf;
-
- for (i = 0; i < info->portwidth; i++)
- *cp++ = ((i + 1) % info->chipwidth) ? '\0' : cmd;
+ if (info->chipwidth < FLASH_CFI_BY32) {
+ for (i = 0; i < info->portwidth; i++)
+ *cp++ = ((i + 1) % info->chipwidth) ? '\0' : cmd;
+ }
+ else {
+ ushort *ccp= (ushort *) cmdbuf;
+ ushort cmd_16= cmd + cmd * 256;
+ for (i = 0; i< info->portwidth; i=i+2)
+ *ccp++= ((i + 2) % info->chipwidth) ? '\0' :cmd_16;
+ }
#if defined(__LITTLE_ENDIAN)
switch (info->portwidth) {
case FLASH_CFI_8BIT:
@@ -819,20 +995,18 @@
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);
+ debug ("fwc issues cmd %x to addr %p with %x,\nassuming flash port width 8bit, chip width %d bit\n",\
+ cmd, addr.cp, cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
*addr.cp = cword.c;
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);
+ debug ("fwc issues cmd %x to addr %p with %4.4x,\nassuming flash port width 16bit, chip width %d bit\n",\
+ cmd, addr.wp, cword.w, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
*addr.wp = cword.w;
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);
+ debug ("fwc issues cmd %x to addr %p with %8.8lx,\nassuming flash port width 32bit, chip width %d bit\n",\
+ cmd, addr.lp, cword.l, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
*addr.lp = cword.l;
break;
case FLASH_CFI_64BIT:
@@ -842,9 +1016,8 @@
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);
+ debug ("fwrite issues cmd %x to addr %p with %s,\nassuming flash port width 64 bit, chip width %d bit\n",\
+ cmd, addr.llp, str, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
}
#endif
*addr.llp = cword.ll;
@@ -860,27 +1033,25 @@
/*-----------------------------------------------------------------------
*/
-static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+static int flash_isequal (flash_info_t * info, cfiptr_t cptr, uchar cmd)
{
- cfiptr_t cptr;
cfiword_t cword;
int retval;
- cptr.cp = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
- debug ("is= cmd %x(%c) addr %p ", cmd, cmd, cptr.cp);
+ debug ("expecting net value is %x(%c) at addr %p,\n", cmd, cmd, cptr.cp);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- debug ("is= %x %x\n", cptr.cp[0], cword.c);
+ debug ("expected read value %x, actual read %x\n", cword.c,cptr.cp[0]);
retval = (cptr.cp[0] == cword.c);
break;
case FLASH_CFI_16BIT:
- debug ("is= %4.4x %4.4x\n", cptr.wp[0], cword.w);
+ debug ("expected read value %4.4x, actual read %4.4x\n", cword.w,cptr.wp[0]);
retval = (cptr.wp[0] == cword.w);
break;
case FLASH_CFI_32BIT:
- debug ("is= %8.8lx %8.8lx\n", cptr.lp[0], cword.l);
+ debug ("expected read value %8.8lx, actual read %8.8lx\n", cword.l,cptr.lp[0]);
retval = (cptr.lp[0] == cword.l);
break;
case FLASH_CFI_64BIT:
@@ -891,7 +1062,7 @@
print_longlong (str1, cptr.llp[0]);
print_longlong (str2, cword.ll);
- debug ("is= %s %s\n", str1, str2);
+ debug ("expected read vaule is %s, actual read %s\n", str2, str1);
}
#endif
retval = (cptr.llp[0] == cword.ll);
@@ -905,13 +1076,11 @@
/*-----------------------------------------------------------------------
*/
-static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+static int flash_isset (flash_info_t * info, cfiptr_t cptr, uchar cmd)
{
- cfiptr_t cptr;
cfiword_t cword;
int retval;
- cptr.cp = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
@@ -935,13 +1104,11 @@
/*-----------------------------------------------------------------------
*/
-static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+static int flash_toggle (flash_info_t * info, cfiptr_t cptr, uchar cmd)
{
- cfiptr_t cptr;
cfiword_t cword;
int retval;
- cptr.cp = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
@@ -971,6 +1138,7 @@
*/
static int flash_detect_cfi (flash_info_t * info)
{
+ cfiptr_t cptr1,cptr2,cptr3;
debug ("flash detect cfi\n");
for (info->portwidth = FLASH_CFI_8BIT;
@@ -978,11 +1146,14 @@
for (info->chipwidth = FLASH_CFI_BY8;
info->chipwidth <= info->portwidth;
info->chipwidth <<= 1) {
+ cptr1.cp = flash_make_addr(info,0,FLASH_OFFSET_CFI_RESP);
+ cptr2.cp = flash_make_addr(info,0,FLASH_OFFSET_CFI_RESP + 1);
+ cptr3.cp = flash_make_addr(info,0,FLASH_OFFSET_CFI_RESP + 2);
flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
flash_write_cmd (info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
- if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
- && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
- && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
+ if (flash_isequal (info, cptr1,'Q')
+ && flash_isequal (info, cptr2, 'R')
+ && flash_isequal (info, cptr3, 'Y')) {
info->interface = flash_read_ushort (info, 0, FLASH_OFFSET_INTERFACE);
debug ("device interface is %d\n",
info->interface);
@@ -1014,6 +1185,7 @@
uchar num_erase_regions;
int erase_region_size;
int erase_region_count;
+ cfiptr_t cptr;
info->start[0] = base;
@@ -1073,9 +1245,12 @@
switch (info->vendor) {
case CFI_CMDSET_INTEL_EXTENDED:
case CFI_CMDSET_INTEL_STANDARD:
+ cptr.cp = flash_make_addr(info,
+ sect_cnt,
+ FLASH_OFFSET_PROTECT);
info->protect[sect_cnt] =
- flash_isset (info, sect_cnt,
- FLASH_OFFSET_PROTECT,
+ flash_isset (info,
+ cptr,
FLASH_STATUS_PROTECT);
break;
default:
@@ -1100,6 +1275,9 @@
if ((info->interface == FLASH_CFI_X8X16) && (info->chipwidth == FLASH_CFI_BY8)) {
info->portwidth >>= 1; /* XXX - Need to test on x8/x16 in parallel. */
}
+ } else {
+ info->portwidth = 1;
+ info->chipwidth = 1;
}
flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
@@ -1115,7 +1293,7 @@
cfiptr_t ctladdr;
cfiptr_t cptr;
- int flag;
+ int flag,retcode;
ctladdr.cp = flash_make_addr (info, 0, 0);
cptr.cp = (uchar *) dest;
@@ -1176,7 +1354,8 @@
if (flag)
enable_interrupts ();
- return flash_full_status_check (info, 0, info->write_tout, "write");
+ retcode = flash_full_status_check (info, cptr, cword, info->write_tout, "write");
+ return flag;
}
#ifdef CFG_FLASH_USE_BUFFER_WRITE
@@ -1215,7 +1394,7 @@
flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
if ((retcode =
- flash_status_check (info, sector, info->buffer_write_tout,
+ flash_status_check (info, sector, 0,0,info->buffer_write_tout,
"write to buffer")) == ERR_OK) {
/* reduce the number of loops by the width of the port */
switch (info->portwidth) {
@@ -1258,7 +1437,7 @@
flash_write_cmd (info, sector, 0,
FLASH_CMD_WRITE_BUFFER_CONFIRM);
retcode =
- flash_full_status_check (info, sector,
+ flash_full_status_check (info, sector,0,0,
info->buffer_write_tout,
"buffer write");
}
More information about the U-Boot
mailing list