From 6a011ce851a0ba23ad50f9bac06dc323a863d0c5 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Sun, 10 Apr 2011 16:06:29 -0400
Subject: [PATCH 1/3] cfi_flash: reverse geometry for M29W800DT parts

The M29W800DT parts also report their geometry with the sector layout
reversed.  So add that ID to the flash_fixup_stm function.

Otherwise, we get:
bfin> flinfo

Bank # 1: CFI conformant FLASH (16 x 16)  Size: 1 MB in 19 Sectors
  AMD Standard command set, Manufacturer ID: 0x20, Device ID: 0x22D7
  Erase timeout: 8192 ms, write timeout: 1 ms

  Sector Start Addresses:
  20000000        20004000        20006000        20008000        20010000
  20020000        20030000        20040000        20050000        20060000
  20070000        20080000        20090000        200A0000        200B0000
  200C0000        200D0000        200E0000        200F0000

Reported-by: Jianxi Fu <fujianxi@gmail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 drivers/mtd/cfi_flash.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 91ddcb4676..b1110a138e 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -1852,9 +1852,10 @@ static void flash_fixup_stm(flash_info_t *info, struct cfi_qry *qry)
 	if (qry->num_erase_regions > 1) {
 		/* reverse geometry if top boot part */
 		if (info->cfi_version < 0x3131) {
-			/* CFI < 1.1, guess by device id (M29W320{DT,ET} only) */
-			if (info->device_id == 0x22CA ||
-			    info->device_id == 0x2256) {
+			/* CFI < 1.1, guess by device id */
+			if (info->device_id == 0x22CA || /* M29W320DT */
+			    info->device_id == 0x2256 || /* M29W320ET */
+			    info->device_id == 0x22D7) { /* M29W800DT */
 				cfi_reverse_geometry(qry);
 			}
 		}

From 5b448adb4b2f3244419de6409949a730771f8b21 Mon Sep 17 00:00:00 2001
From: Heiko Schocher <hs@denx.de>
Date: Mon, 11 Apr 2011 14:16:19 +0200
Subject: [PATCH 2/3] mtd, cfi: read AMD 3-byte (expanded) device ids on 16bit
 devices

tested on the a4m072 board with a S29GL512P flash.

flinfo without this patch
Bank # 1: CFI conformant flash (16 x 16)  Size: 32 MB in 256 Sectors
  AMD Standard command set, Manufacturer ID: 0x01, Device ID: 0x227E
  Erase timeout: 16384 ms, write timeout: 2 ms
  Buffer write timeout: 5 ms, buffer size: 32 bytes
[...]

flinfo with this patch
Bank # 1: CFI conformant flash (16 x 16)  Size: 32 MB in 256 Sectors
  AMD Standard command set, Manufacturer ID: 0x01, Device ID: 0x227E2301
  Erase timeout: 16384 ms, write timeout: 2 ms
  Buffer write timeout: 5 ms, buffer size: 32 bytes
[...]

Signed-off-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 drivers/mtd/cfi_flash.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index b1110a138e..aa76f6ce48 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -1202,8 +1202,9 @@ void flash_print_info (flash_info_t * info)
 		info->manufacturer_id);
 	printf (info->chipwidth == FLASH_CFI_16BIT ? "%04X" : "%02X",
 		info->device_id);
-	if (info->device_id == 0x7E) {
-		printf("%04X", info->device_id2);
+	if ((info->device_id & 0xff) == 0x7E) {
+		printf(info->chipwidth == FLASH_CFI_16BIT ? "%04X" : "%02X",
+		info->device_id2);
 	}
 	printf ("\n  Erase timeout: %ld ms, write timeout: %ld ms\n",
 		info->erase_blk_tout,
@@ -1599,6 +1600,14 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
 	case FLASH_CFI_16BIT:
 		info->device_id = flash_read_word (info,
 						FLASH_OFFSET_DEVICE_ID);
+		if ((info->device_id & 0xff) == 0x7E) {
+			/* AMD 3-byte (expanded) device ids */
+			info->device_id2 = flash_read_uchar (info,
+						FLASH_OFFSET_DEVICE_ID2);
+			info->device_id2 <<= 8;
+			info->device_id2 |= flash_read_uchar (info,
+						FLASH_OFFSET_DEVICE_ID3);
+		}
 		break;
 	default:
 		break;

From a90b9575f3ff71de58672295504e9ebaa8f051b4 Mon Sep 17 00:00:00 2001
From: Aaron Williams <aaron.williams@caviumnetworks.com>
Date: Tue, 12 Apr 2011 00:59:04 -0700
Subject: [PATCH 3/3] cfi_flash driver - Add delay after reset command

I ran into a problem where the reset was failing except when I enabled
debugging support.  After talking with Garret Swalling at Spansion I
was told that the GL-N series of devices require a 500ns wait for the
reset to complete.  The below patch adds a 1us delay after all reset
commands.

-Aaron Williams

Signed-off-by: Aaron Williams <aaron.williams@caviumnetworks.com>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 drivers/mtd/cfi_flash.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index aa76f6ce48..6039e1fadc 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -581,6 +581,7 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector,
 				prompt, info->start[sector],
 				flash_read_long (info, sector, 0));
 			flash_write_cmd (info, sector, 0, info->cmd_reset);
+			udelay(1);
 			return ERR_TIMOUT;
 		}
 		udelay (1);		/* also triggers watchdog */
@@ -628,6 +629,7 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
 				puts ("Vpp Low Error.\n");
 		}
 		flash_write_cmd (info, sector, 0, info->cmd_reset);
+		udelay(1);
 		break;
 	default:
 		break;
@@ -1491,6 +1493,7 @@ void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
 	flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
 	memcpy (dst, src + offset, len);
 	flash_write_cmd (info, 0, 0, info->cmd_reset);
+	udelay(1);
 	flash_unmap(info, 0, FLASH_OFFSET_USER_PROTECTION, src);
 }
 
@@ -1506,6 +1509,7 @@ void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
 	flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
 	memcpy (buffer, src + offset, len);
 	flash_write_cmd (info, 0, 0, info->cmd_reset);
+	udelay(1);
 	flash_unmap(info, 0, FLASH_OFFSET_INTEL_PROTECTION, src);
 }
 
@@ -1537,6 +1541,7 @@ static void cfi_reverse_geometry(struct cfi_qry *qry)
 static void cmdset_intel_read_jedec_ids(flash_info_t *info)
 {
 	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+	udelay(1);
 	flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
 	udelay(1000); /* some flash are slow to respond */
 	info->manufacturer_id = flash_read_uchar (info,
@@ -1613,6 +1618,7 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
 		break;
 	}
 	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
+	udelay(1);
 }
 
 static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
@@ -1739,6 +1745,7 @@ void __flash_cmd_reset(flash_info_t *info)
 	 * that AMD flash roms ignore the Intel command.
 	 */
 	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
+	udelay(1);
 	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
 }
 void flash_cmd_reset(flash_info_t *info)