[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