[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