Patchwork Fix evil twins of Macronix MX25L1605, MX25L3205, MX25L6405.

login
register
about
Submitter Stefan Tauner
Date 2013-02-03 07:40:08
Message ID <1359877208-14013-1-git-send-email-stefan.tauner@student.tuwien.ac.at>
Download mbox | patch
Permalink /patch/3851/
State Accepted
Headers show

Comments

Stefan Tauner - 2013-02-03 07:40:08
Similarly to the previous patch this one updates the chips identified as above
with references to and data about their respective twins. Unlike previously this
one deals with the more evil details.

Helge Wagner from GE discovered some problems with chips sharing IDs
and proposed a patch to tackle (some of) them, see:
http://patchwork.coreboot.org/patch/3709/
That patch was bitrotting in our mailboxes for a long time and it is still not
ready for merge, but we increasingly get reports about problems (e.g.
http://paste.flashrom.org/view.php?id=1525) regarding these chips and
hence must act to ensure users' safety.

This patch splits the chip definitions of evil twins into separate ones which
correctly declare the respective attributes (the main problems are the erase
block sizes for the 0x20 opcode and hence my changes combine different
chips with partly different attributes apart from their names as long as the
erasers layout it the same). This forces the user to select the (right) chip
definition with the -c/--chip parameter and hence will break a number of
previously perfectly working environments.

0x2015 is used by and split to
 - MX25L1605 (64kB sectors in 0x20 erases)
 - MX25L1605A (4kB in 0x20 erases and an additional 0x52 opcode with 64kB blocks)
 - MX25L1605D/MX25L1608D (4k sectors in 0x20 erases)

0x2016 is used by and split to
 - MX25L3205, MX25L3205A (64kB 0x20)
 - MX25L3205D/MX25L3208D (4kB 0x20)
 - MX25L3206E (4k 0x20, 64k 0x52)

0x2017 is used by and split to
 - MX25L6405 MX25L6405D (64k 0x20)
 - MX25L6406E/MX25L6436E (4k 0x20)
 - MX25L6445E (4k 0x20, 64k 0x52)

Bonus: add some minor details to MX25L1635D, MX25L1635E, MX25L3235D,
MX25L12805D.

Signed-off-by: Stefan Tauner <stefan.tauner@student.tuwien.ac.at>

---
TODO after merging this:
 - implement probing methods that are able to distinguish at least
   some of the evil twins.
 - where this is not possible discuss alternatives like the somewhat
   fail-safe spi_block_erase_20_4or64k() by Helge
 - find and spank the ones reponsible for this whole mess.
---
 flashchips.c |  270 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 flashchips.h |    8 +-
 2 files changed, 252 insertions(+), 26 deletions(-)
Stefan Tauner - 2013-03-16 01:23:43
On Sun,  3 Feb 2013 08:40:08 +0100
Stefan Tauner <stefan.tauner@student.tuwien.ac.at> wrote:

> Similarly to the previous patch this one updates the chips identified as above
> with references to and data about their respective twins. Unlike previously this
> one deals with the more evil details.
> 
> Helge Wagner from GE discovered some problems with chips sharing IDs
> and proposed a patch to tackle (some of) them, see:
> http://patchwork.coreboot.org/patch/3709/
> That patch was bitrotting in our mailboxes for a long time and it is still not
> ready for merge, but we increasingly get reports about problems (e.g.
> http://paste.flashrom.org/view.php?id=1525) regarding these chips and
> hence must act to ensure users' safety.
> 
> This patch splits the chip definitions of evil twins into separate ones which
> correctly declare the respective attributes (the main problems are the erase
> block sizes for the 0x20 opcode and hence my changes combine different
> chips with partly different attributes apart from their names as long as the
> erasers layout it the same). This forces the user to select the (right) chip
> definition with the -c/--chip parameter and hence will break a number of
> previously perfectly working environments.
> 
> 0x2015 is used by and split to
>  - MX25L1605 (64kB sectors in 0x20 erases)
>  - MX25L1605A (4kB in 0x20 erases and an additional 0x52 opcode with 64kB blocks)
>  - MX25L1605D/MX25L1608D (4k sectors in 0x20 erases)
> 
> 0x2016 is used by and split to
>  - MX25L3205, MX25L3205A (64kB 0x20)
>  - MX25L3205D/MX25L3208D (4kB 0x20)
>  - MX25L3206E (4k 0x20, 64k 0x52)
> 
> 0x2017 is used by and split to
>  - MX25L6405 MX25L6405D (64k 0x20)
>  - MX25L6406E/MX25L6436E (4k 0x20)
>  - MX25L6445E (4k 0x20, 64k 0x52)
> 
> Bonus: add some minor details to MX25L1635D, MX25L1635E, MX25L3235D,
> MX25L12805D.
> 
> Signed-off-by: Stefan Tauner <stefan.tauner@student.tuwien.ac.at>

self-acked and committed in r1657.

Patch

diff --git a/flashchips.c b/flashchips.c
index b976ee6..1783fe7 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -5270,10 +5270,45 @@  const struct flashchip flashchips[] = {
 		.block_erasers	=
 		{
 			{
+				.eraseblocks = { {64 * 1024, 32} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 32} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {2 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_60,
+			}, {
+				.eraseblocks = { {2 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			},
+		},
+		.printlock	= spi_prettyprint_status_register_default_bp2, /* bit6: error flag */
+		.unlock		= spi_disable_blockprotect,
+		.write		= spi_chip_write_256,
+		.read		= spi_chip_read, /* Fast read (0x0B) supported */
+		.voltage	= {2700, 3600},
+	},
+
+	{
+		.vendor		= "Macronix",
+		.name		= "MX25L1605A",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= MACRONIX_ID,
+		.model_id	= MACRONIX_MX25L1605,
+		.total_size	= 2048,
+		.page_size	= 256,
+		.feature_bits	= FEATURE_WRSR_WREN,
+		.tested		= TEST_OK_PREW,
+		.probe		= probe_spi_rdid,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	=
+		{
+			{
 				.eraseblocks = { {4 * 1024, 512} },
-				.block_erase = spi_block_erase_20,	/* This erase function has 64k blocksize for eLiteFlash */
+				.block_erase = spi_block_erase_20,
 			}, {
-				.eraseblocks = { {64 * 1024, 32} },	/* Not supported in MX25L1605 (eLiteFlash) and MX25L1605D */
+				.eraseblocks = { {64 * 1024, 32} },
 				.block_erase = spi_block_erase_52,
 			}, {
 				.eraseblocks = { {64 * 1024, 32} },
@@ -5286,10 +5321,45 @@  const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
-		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
+		.printlock	= spi_prettyprint_status_register_default_bp2,
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
-		.read		= spi_chip_read,
+		.read		= spi_chip_read, /* Fast read (0x0B) supported */
+		.voltage	= {2700, 3600},
+	},
+
+	{
+		.vendor		= "Macronix",
+		.name		= "MX25L1605D/MX25L1608D",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= MACRONIX_ID,
+		.model_id	= MACRONIX_MX25L1605,
+		.total_size	= 2048,
+		.page_size	= 256,
+		.feature_bits	= FEATURE_WRSR_WREN,
+		.tested		= TEST_OK_PREW,
+		.probe		= probe_spi_rdid,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 512} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 32} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {2 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_60,
+			}, {
+				.eraseblocks = { {2 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			},
+		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* bit6: CP mode */
+		.unlock		= spi_disable_blockprotect,
+		.write		= spi_chip_write_256,
+		.read		= spi_chip_read, /* Fast read (0x0B), dual I/O supported */
 		.voltage	= {2700, 3600},
 	},
 
@@ -5301,7 +5371,8 @@  const struct flashchip flashchips[] = {
 		.model_id	= MACRONIX_MX25L1635D,
 		.total_size	= 2048,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 64B total; enter 0xB1, exit 0xC1 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -5321,10 +5392,10 @@  const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
-		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* bit6 is quad enable */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
-		.read		= spi_chip_read,
+		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
 	},
 
@@ -5336,7 +5407,8 @@  const struct flashchip flashchips[] = {
 		.model_id	= MACRONIX_MX25L1635E,
 		.total_size	= 2048,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 64B total; enter 0xB1, exit 0xC1 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -5356,16 +5428,16 @@  const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
-		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* bit6 is quad enable */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
-		.read		= spi_chip_read,
+		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
 	},
 
 	{
 		.vendor		= "Macronix",
-		.name		= "MX25L3205",
+		.name		= "MX25L3205(A)",
 		.bustype	= BUS_SPI,
 		.manufacture_id	= MACRONIX_ID,
 		.model_id	= MACRONIX_MX25L3205,
@@ -5378,12 +5450,87 @@  const struct flashchip flashchips[] = {
 		.block_erasers	=
 		{
 			{
+				.eraseblocks = { {64 * 1024, 64} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 64} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {4 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_60,
+			}, {
+				.eraseblocks = { {4 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			},
+		},
+		.printlock	= spi_prettyprint_status_register_default_bp2, /* bit6: error flag */
+		.unlock		= spi_disable_blockprotect,
+		.write		= spi_chip_write_256,
+		.read		= spi_chip_read, /* Fast read (0x0B) supported */
+		.voltage	= {2700, 3600},
+	},
+
+	{
+		.vendor		= "Macronix",
+		.name		= "MX25L3205D/MX25L3208D",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= MACRONIX_ID,
+		.model_id	= MACRONIX_MX25L3205,
+		.total_size	= 4096,
+		.page_size	= 256,
+		/* OTP: 64B total; enter 0xB1, exit 0xC1 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
+		.tested		= TEST_OK_PREW,
+		.probe		= probe_spi_rdid,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	=
+		{
+			{
 				.eraseblocks = { {4 * 1024, 1024} },
 				.block_erase = spi_block_erase_20,
 			}, {
+				.eraseblocks = { {64 * 1024, 64} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {4 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_60,
+			}, {
+				.eraseblocks = { {4 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			},
+		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* bit6: CP mode */
+		.unlock		= spi_disable_blockprotect,
+		.write		= spi_chip_write_256,
+		.read		= spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+		.voltage	= {2700, 3600},
+	},
+
+	{
+		.vendor		= "Macronix",
+		.name		= "MX25L3206E",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= MACRONIX_ID,
+		.model_id	= MACRONIX_MX25L3205,
+		.total_size	= 4096,
+		.page_size	= 256,
+		/* OTP: 64B total; enter 0xB1, exit 0xC1 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
+		.tested		= TEST_OK_PREW,
+		.probe		= probe_spi_rdid,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	=
+		{
+			{
 				.eraseblocks = { {4 * 1024, 1024} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 64} },
 				.block_erase = spi_block_erase_d8,
 			}, {
+				.eraseblocks = { {64 * 1024, 64} },
+				.block_erase = spi_block_erase_52,
+			}, {
 				.eraseblocks = { {4 * 1024 * 1024, 1} },
 				.block_erase = spi_block_erase_60,
 			}, {
@@ -5391,10 +5538,10 @@  const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
-		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
+		.printlock	= spi_prettyprint_status_register_default_bp3,
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
-		.read		= spi_chip_read,
+		.read		= spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
 		.voltage	= {2700, 3600},
 	},
 
@@ -5406,7 +5553,8 @@  const struct flashchip flashchips[] = {
 		.model_id	= MACRONIX_MX25L3235D,
 		.total_size	= 4096,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* OTP: 256B total; enter 0xB1, exit 0xC1 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -5426,7 +5574,7 @@  const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
-		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* bit6 is quad enable */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5435,13 +5583,14 @@  const struct flashchip flashchips[] = {
 
 	{
 		.vendor		= "Macronix",
-		.name		= "MX25L6405",
+		.name		= "MX25L6405(D)",
 		.bustype	= BUS_SPI,
 		.manufacture_id	= MACRONIX_ID,
 		.model_id	= MACRONIX_MX25L6405,
 		.total_size	= 8192,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* MX25L6405D has 64B of OTP; enter 0xB1, exit 0xC1 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -5461,7 +5610,7 @@  const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
-		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* bit6 has different meanings */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5470,13 +5619,90 @@  const struct flashchip flashchips[] = {
 
 	{
 		.vendor		= "Macronix",
-		.name		= "MX25L12805",
+		.name		= "MX25L6406E/MX25L6436E",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= MACRONIX_ID,
+		.model_id	= MACRONIX_MX25L6405,
+		.total_size	= 8192,
+		.page_size	= 256,
+		/* OTP: 06E 64B/36E 512B total; enter 0xB1, exit 0xC1 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
+		.tested		= TEST_OK_PREW,
+		.probe		= probe_spi_rdid,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 2048} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 128} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {8 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_60,
+			}, {
+				.eraseblocks = { {8 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* bit6 for 36E is quad enable */
+		.unlock		= spi_disable_blockprotect,
+		.write		= spi_chip_write_256,
+		.read		= spi_chip_read,
+		.voltage	= {2700, 3600},
+	},
+
+	{
+		.vendor		= "Macronix",
+		.name		= "MX25L6445E",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= MACRONIX_ID,
+		.model_id	= MACRONIX_MX25L6405,
+		.total_size	= 8192,
+		.page_size	= 256,
+		/* supports SFDP */
+		/* OTP: 512B total; enter 0xB1, exit 0xC1 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
+		.tested		= TEST_OK_PREW,
+		.probe		= probe_spi_rdid,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 2048} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {32 * 1024, 256} },
+				.block_erase = spi_block_erase_52,
+			}, {
+				.eraseblocks = { {64 * 1024, 128} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {8 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_60,
+			}, {
+				.eraseblocks = { {8 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* bit6 is quad enable */
+		.unlock		= spi_disable_blockprotect,
+		.write		= spi_chip_write_256,
+		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+		.voltage	= {2700, 3600},
+	},
+
+	{
+		.vendor		= "Macronix",
+		.name		= "MX25L12805(D)",
 		.bustype	= BUS_SPI,
 		.manufacture_id	= MACRONIX_ID,
 		.model_id	= MACRONIX_MX25L12805,
 		.total_size	= 16384,
 		.page_size	= 256,
-		.feature_bits	= FEATURE_WRSR_WREN,
+		/* MX25L12805D has 64B of OTP; enter 0xB1, exit 0xC1 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
 		.tested		= TEST_OK_PROBE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -5496,10 +5722,10 @@  const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
-		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
+		.printlock	= spi_prettyprint_status_register_default_bp3,
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
-		.read		= spi_chip_read,
+		.read		= spi_chip_read, /* MX25L12805D: Fast read (0x0B) supported */
 		.voltage	= {2700, 3600},
 	},
 
diff --git a/flashchips.h b/flashchips.h
index d123ab0..22af0e3 100644
--- a/flashchips.h
+++ b/flashchips.h
@@ -387,10 +387,10 @@ 
 #define MACRONIX_MX25L2005	0x2012	/* Same as MX25L2005C */
 #define MACRONIX_MX25L4005	0x2013	/* Same as MX25L4005A, MX25L4005C */
 #define MACRONIX_MX25L8005	0x2014	/* Same as MX25V8005 */
-#define MACRONIX_MX25L1605	0x2015	/* MX25L1605{,A,D} */
-#define MACRONIX_MX25L3205	0x2016	/* MX25L3205{,A} */
-#define MACRONIX_MX25L6405	0x2017	/* MX25L6405{,D}, MX25L6406E, MX25L6436E */
-#define MACRONIX_MX25L12805	0x2018	/* MX25L12805 */
+#define MACRONIX_MX25L1605	0x2015	/* MX25L1605 (64k 0x20); MX25L1605A (4k 0x20, 64k 0x52); MX25L1605D/MX25L1608D (4k 0x20) */
+#define MACRONIX_MX25L3205	0x2016	/* MX25L3205, MX25L3205A (64k 0x20); MX25L3205D/MX25L3208D (4k 0x20); MX25L3206E (4k 0x20, 64k 0x52) */
+#define MACRONIX_MX25L6405	0x2017	/* MX25L6405, MX25L6405D (64k 0x20); MX25L6406E/MX25L6436E (4k 0x20); MX25L6445E (4k 0x20, 64k 0x52) */
+#define MACRONIX_MX25L12805	0x2018	/* Same as MX25L12805D */
 #define MACRONIX_MX25L1635D	0x2415
 #define MACRONIX_MX25L1635E	0x2515	/* MX25L1635{E} */
 #define MACRONIX_MX25U1635E	0x2535