diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index f04c72d05a33bc6a2c0e2f6cefb660e001994416..40fddcddad5aa0b9edd3b270da059b87e9eba085 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -239,12 +239,14 @@ static u32 flash_read32(void *addr)
 	return __raw_readl(addr);
 }
 
-static u64 flash_read64(void *addr)
+static u64 __flash_read64(void *addr)
 {
 	/* No architectures currently implement __raw_readq() */
 	return *(volatile u64 *)addr;
 }
 
+u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64")));
+
 /*-----------------------------------------------------------------------
  */
 #if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
@@ -364,6 +366,20 @@ static inline uchar flash_read_uchar (flash_info_t * info, uint offset)
 	return retval;
 }
 
+/*-----------------------------------------------------------------------
+ * read a word at a port width address, assume 16bit bus
+ */
+static inline ushort flash_read_word (flash_info_t * info, uint offset)
+{
+	ushort *addr, retval;
+
+	addr = flash_map (info, 0, offset);
+	retval = flash_read16 (addr);
+	flash_unmap (info, 0, offset, addr);
+	return retval;
+}
+
+
 /*-----------------------------------------------------------------------
  * read a long word by picking the least significant byte of each maximum
  * port size word. Swap for ppc format.
@@ -1449,17 +1465,29 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
 	flash_unlock_seq(info, 0);
 	flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
 	udelay(1000); /* some flash are slow to respond */
+
 	info->manufacturer_id = flash_read_uchar (info,
 					FLASH_OFFSET_MANUFACTURER_ID);
-	info->device_id = flash_read_uchar (info,
-					FLASH_OFFSET_DEVICE_ID);
-	if (info->device_id == 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);
+
+	switch (info->chipwidth){
+	case FLASH_CFI_8BIT:
+		info->device_id = flash_read_uchar (info,
+						FLASH_OFFSET_DEVICE_ID);
+		if (info->device_id == 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;
+	case FLASH_CFI_16BIT:
+		info->device_id = flash_read_word (info,
+						FLASH_OFFSET_DEVICE_ID);
+		break;
+	default:
+		break;
 	}
 	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
 }
diff --git a/drivers/mtd/jedec_flash.c b/drivers/mtd/jedec_flash.c
index 41aad3bd6a5f28e230aa3e8b695f4dc2319c3eea..b958d1723a2a5acc690d12627670bdffd8a21daa 100644
--- a/drivers/mtd/jedec_flash.c
+++ b/drivers/mtd/jedec_flash.c
@@ -216,6 +216,25 @@ static const struct amd_flash_info jedec_table[] = {
 		}
 	},
 #endif
+#ifdef CFG_FLASH_LEGACY_512Kx16
+	{
+		.mfr_id		= MANUFACTURER_AMD,
+		.dev_id		= AM29LV400BB,
+		.name		= "AMD AM29LV400BB",
+		.uaddr		= {
+			[1] = MTD_UADDR_0x0555_0x02AA /* x16 */
+		},
+		.DevSize	= SIZE_512KiB,
+		.CmdSet		= CFI_CMDSET_AMD_LEGACY,
+		.NumEraseRegions= 4,
+		.regions	= {
+			ERASEINFO(0x04000,1),
+			ERASEINFO(0x02000,2),
+			ERASEINFO(0x08000,1),
+			ERASEINFO(0x10000,7),
+		}
+	},
+#endif
 };
 
 static inline void fill_info(flash_info_t *info, const struct amd_flash_info *jedec_entry, ulong base)