[U-Boot-Users] RE: CFI conformant flash driver available

Rune Raknerud rune.raknerud at cargoscan.com
Fri Jan 23 10:12:51 CET 2004


Brad.Kemp at Seranoa.com wrote:
> To enable the driver CFG_CFI_FLASH_DRIVER must be defined. =20
> Attached is a patch for the cfi flash driver.=20
> The driver includes support for both the Intel and the AMD=20 command
> sets. =20
> The tar file contains 2 files, a patch for the existing=20
> sources and the cfi_flash.c which must be placed in the=20 drivers
> directory. Thanks to all who are helping out. Please let me know if=20
> there are any problems or if things went well.
> If possible plese let me know what are the port width, chip=20
> width, flash chip and number of banks on successful uses of=20 this
> driver. Wolfgang - please do not apply this until I get some
> feedback=20 from those who are testing it.
> Thanks
> Brad Kemp
> 
I have tested the patch with my Intel 28F640J3A in 8 bit mode. It does not work properly. This device can be configured to work in 8 bit or 16 bit mode, using the BYTE# pin. The device does not use A0 for the "Read Identifier Codes" and "Read Query" commands. When used in 8 bit mode, the addresses has to be multiplied by 2 (see table 5 and 6 in data sheet). flash_detect_cfi() is fooled by this, and returns with portwidth set to 2 and chipwidth set to 1. This will work for the "Read Identifier Codes" and "Read Query" commands, but not for the "Write to Buffer" and "Word/Byte Program" commands. My quick hack is to check the flash device interface (table 11 in data sheet). If it is a x8/x16 device and portwidth = 2, I check if it is in 8 bit or 16 bit mode. If it is in 8 bit mode, I change the portwidth to 1 in write_buff().
My patch to flash.h:
--- flash.h	Fri Jan 23 09:57:16 2004
+++ include/flash.h	Fri Jan 23 09:58:23 2004
@@ -38,10 +38,13 @@
 #ifdef CFG_FLASH_CFI
 	uchar	portwidth;		/* the width of the port		*/
 	uchar	chipwidth;		/* the width of the chip		*/
+	ushort	mode;			/* 8 bit or 16 bit mode 		*/
 	ushort	buffer_size;		/* # of bytes in write buffer		*/
 	ulong	erase_blk_tout;		/* maximum block erase timeout		*/
 	ulong	write_tout;		/* maximum write timeout		*/
 	ulong	buffer_write_tout;	/* maximum buffer write timeout		*/
+	ushort  vendor;                 /* the primary vendor id                */
+	ushort  cmd_reset;              /* Vendor specific reset command        */
 
 #endif
 } flash_info_t;
@@ -60,6 +63,14 @@
 #define FLASH_CFI_BY16		0x02
 #define FLASH_CFI_BY32		0x04
 #define FLASH_CFI_BY64		0x08
+/* convert between bit value and numeric value */
+#define CFI_FLASH_SHIFT_WIDTH      3
+/*
+ * Values for the flash device interface
+ */
+#define FLASH_CFI_X8		0x00
+#define FLASH_CFI_X16		0x01
+#define FLASH_CFI_X8X16		0x02
 
 /* Prototypes */
 
@@ -78,6 +89,8 @@
 /* board/?/flash.c */
 #if defined(CFG_FLASH_PROTECTION)
 extern int flash_real_protect(flash_info_t *info, long sector, int prot);
+extern void flash_read_user_serial(flash_info_t * info, void * buffer, int offset, int len);
+extern void flash_read_factory_serial(flash_info_t * info, void * buffer, int offset, int len);
 #endif	/* CFG_FLASH_PROTECTION */
 
My patch to cfi_flash.c:
--- cfi_flash.c	Wed Jan 21 16:05:56 2004
+++ drivers/cfi_flash.c	Fri Jan 23 09:51:31 2004
@@ -240,7 +240,7 @@
 #if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
 	flash_protect(FLAG_PROTECT_SET,
 		      CFG_MONITOR_BASE,
-		      CFG_MONITOR_BASE + monitor_flash_len - 1,
+		      CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
 		      &flash_info[0]);
 #endif
 
@@ -386,7 +386,13 @@
 	int aln;
 	cfiword_t cword;
 	int i, rc;
+	int x8mode = 0;
 
+	/* special handling of 16 bit devices in 8 bit mode */
+	if (info->mode == FLASH_CFI_8BIT) {
+		info->portwidth = FLASH_CFI_8BIT;
+		x8mode = 1;
+	}
 	/* get lower aligned address */
 	wp = (addr & ~(info->portwidth - 1));
 
@@ -447,6 +453,10 @@
 		flash_add_byte(info, & cword, (*(uchar *)cp));
 	}
 
+	/* special handling of 16 bit devices in 8 bit mode */
+	if (x8mode) {
+		info->portwidth = FLASH_CFI_16BIT;
+	}
 	return flash_write_cfiword(info, wp, cword);
 }
 
@@ -766,8 +776,9 @@
 */
 static int flash_detect_cfi(flash_info_t * info)
 {
+	int interface;
 
-    puts("flash detect cfi\n");
+	debug("flash detect cfi\n");
 
 	for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_64BIT;
 	    info->portwidth <<= 1) {
@@ -782,6 +793,24 @@
 			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')) {
+				interface = flash_read_ushort(info, 0, FLASH_OFFSET_INTERFACE);
+				debug("device interface is %d\n", interface);
+				if ((interface == FLASH_CFI_X8X16) && (info->portwidth == FLASH_CFI_16BIT)) {
+					debug("x8/x16 portwidth 16\n");
+					info->portwidth =FLASH_CFI_8BIT;
+					if(flash_isequal(info, 0, 2*FLASH_OFFSET_CFI_RESP, 'Q') &&
+					flash_isequal(info, 0, 2*FLASH_OFFSET_CFI_RESP+1, 'Q') &&
+					flash_isequal(info, 0, 2*FLASH_OFFSET_CFI_RESP+2, 'R')) {
+						info->mode = FLASH_CFI_8BIT;
+					}
+					else {
+						info->mode = FLASH_CFI_16BIT;
+					}
+					info->portwidth =FLASH_CFI_16BIT;
+				}
+				else {
+					info->mode = info->portwidth;
+				}
 				debug("found port %d chip %d ", info->portwidth, info->chipwidth);
 				debug("port %d bits chip %d bits\n", info->portwidth << CFI_FLASH_SHIFT_WIDTH, 

Best regards
Rune Raknerud




More information about the U-Boot mailing list