Patchwork Add support for the Macronix MX28F2000P chip (256KB parallel)

login
register
about
Submitter Uwe Hermann
Date 2011-09-02 20:51:43
Message ID <20110902205142.GH16138@greenwood>
Download mbox | patch
Permalink /patch/3399/
State Superseded
Headers show

Comments

Uwe Hermann - 2011-09-02 20:51:43
See patch for a first attempt to support the Macronix MX28F2000P.

Some TODOs remain in the code, and it will be tested soon by Mete0 (IRC).
However, the chip requires 12V for programming/erasing, we'll see if
that'll work out of the box or maybe requires some board-enable.

Also, there's a "DMI chassis-type is not specific enough.", thus the
laptop=force_I_want_a_brick options is currently needed.

http://paste.flashrom.org/view.php?id=789
http://paste.flashrom.org/view.php?id=787


Uwe.

Patch

Add support for the Macronix MX28F2000P chip (256KB parallel).

This 256KB chip has a similar, but not identical, command set to the
SST SST28SF040A chip. It features a chip erase, block erase, byte write,
chip ID, and reset command.

In contrast to the SST28SF040A, the reset command is 0xff, 0xff (instead of
only one 0xff), and the write command is 0x40 (instead of 0x10).
No locking/unlocking (protect/unprotect) commands are documented, it seems.

Finally, unlike the SST28SF040A, the MX28F2000P requires 12V for write and
erase operations. Only read/ID is supported with the usual 5V.
It's likely that a board-enable will be required to enable the 12V on the
respective pin (untested though).

Note: As reported by Mete0 <admin@phpcode.us> on IRC, his chip
(MX28F2000PPC-12C4) seems to have an ID of 0x2d instead of 0x2a as per
datasheet. We'll have to find out if that's a datasheet typo, or if it's
a different chip revision which is not mentioned in the datasheet or...

http://paste.flashrom.org/view.php?id=787
http://paste.flashrom.org/view.php?id=789

Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de>

Index: flashchips.c
===================================================================
--- flashchips.c	(Revision 1424)
+++ flashchips.c	(Arbeitskopie)
@@ -4422,6 +4422,38 @@ 
 
 	{
 		.vendor		= "Macronix",
+		.name		= "MX28F2000P",
+		.bustype	= BUS_PARALLEL,
+		.manufacture_id	= MACRONIX_ID,
+		.model_id	= MACRONIX_MX28F2000P,
+		.total_size	= 256,
+		.page_size	= 0, /* unused */
+		.feature_bits	= 0,
+		.tested		= TEST_UNTESTED,
+		.probe		= probe_mx28f2000p,
+		.probe_timing	= TIMING_ZERO, // TODO
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = {
+					{4 * 1024, 4},
+					{16 * 1024, 14},
+					{4 * 1024, 4},
+				},
+				.block_erase = erase_sector_28sf040,
+			}, {
+				.eraseblocks = { {256 * 1024, 1} },
+				.block_erase = erase_chip_28sf040,
+			}
+		},
+		.unlock		= NULL, /* No locking mechanism available. */
+		.write		= write_28sf040,
+		.read		= read_memmapped,
+		.voltage	= {4500, 5500}, /* Needs 12V for write/erase! */
+	},
+
+	{
+		.vendor		= "Macronix",
 		.name		= "MX29F001B",
 		.bustype	= BUS_PARALLEL,
 		.manufacture_id	= MACRONIX_ID,
Index: flashchips.h
===================================================================
--- flashchips.h	(Revision 1424)
+++ flashchips.h	(Arbeitskopie)
@@ -367,6 +367,7 @@ 
 #define MACRONIX_MX25L1635D	0x2415
 #define MACRONIX_MX25L1635E	0x2515	/* MX25L1635{E} */
 #define MACRONIX_MX25L3235D	0x5E16	/* MX25L3225D/MX25L3235D/MX25L3237D */
+#define MACRONIX_MX28F2000P	0x2a
 #define MACRONIX_MX29F001B	0x19
 #define MACRONIX_MX29F001T	0x18
 #define MACRONIX_MX29F002B	0x34	/* Same as MX29F002NB */
Index: sst28sf040.c
===================================================================
--- sst28sf040.c	(Revision 1424)
+++ sst28sf040.c	(Arbeitskopie)
@@ -25,7 +25,7 @@ 
 
 #define AUTO_PG_ERASE1		0x20
 #define AUTO_PG_ERASE2		0xD0
-#define AUTO_PGRM		0x10
+#define AUTO_PGRM		0x40 /* Quick hack */
 #define CHIP_ERASE		0x30
 #define RESET			0xFF
 #define READ_ID			0x90
@@ -68,6 +68,8 @@ 
 	chip_writeb(AUTO_PG_ERASE1, bios);
 	chip_writeb(AUTO_PG_ERASE2, bios + address);
 
+	programmer_delay(200); /* TODO: Needed? */
+
 	/* wait for Toggle bit ready */
 	toggle_ready_jedec(bios);
 
@@ -123,3 +125,33 @@ 
 	}
 	return erase_28sf040(flash);
 }
+
+int probe_mx28f2000p(struct flashchip *flash)
+{
+	chipaddr bios = flash->virtual_memory;
+	uint8_t id1, id2;
+
+	/* Reset to get a clean state. */
+	chip_writeb(0xFF, bios);
+	chip_writeb(0xFF, bios);
+	programmer_delay(10); /* TODO: Needed? */
+
+	chip_writeb(0x90, bios);
+	programmer_delay(10); /* TODO: Needed? */
+
+	id1 = chip_readb(bios);
+	id2 = chip_readb(bios + 0x01);
+
+	programmer_delay(10); /* TODO: Needed? */
+
+	msg_cdbg("%s: id1 0x%02x, id2 0x%02x", __func__, id1, id2);
+
+	if (!oddparity(id1))
+		msg_cdbg(", id1 parity violation");
+
+	msg_cdbg("\n");
+	if (id1 != flash->manufacture_id || id2 != flash->model_id)
+		return 0;
+
+	return 1;
+}
Index: chipdrivers.h
===================================================================
--- chipdrivers.h	(Revision 1424)
+++ chipdrivers.h	(Arbeitskopie)
@@ -117,6 +117,7 @@ 
 int write_28sf040(struct flashchip *flash, uint8_t *buf, int start, int len);
 int unprotect_28sf040(struct flashchip *flash);
 int protect_28sf040(struct flashchip *flash);
+int probe_mx28f2000p(struct flashchip *flash);
 
 /* sst49lfxxxc.c */
 int erase_sector_49lfxxxc(struct flashchip *flash, unsigned int address, unsigned int sector_size);