Skip to contentSkip to conversation

mtd: m25p80: utilize dedicated 4-byte addressing commands

PATCH Superseded Brian Norris 5 participants 14 messages Mar 10, 2013 – Mar 18, 2013

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/3 mtd: m25p80: utilize dedicated 4-byte addressing commands

Traditionally, the command set used by SPI flash only supported a 3-byte address. However, large SPI flash (>= 32MB, or 256Mbit) require 4 bytes to address the entire flash. Most manufacturers have supplied a mode switch (via a "bank register writer", or a "enable 4-byte mode" command), which tells the flash to expect 4 address cycles from now on, instead of 3. This mode remains until power is cut, the reset line is triggered (on packages where present), or a command is sent to reset the flash or to reset the 3-byte addressing mode.

As an alternative, some flash manufacturers have developed a new command set that accept a full 4-byte address. They can be used orthogonally to any of the modes; that is, they can be used when the flash is in either 3-byte or 4-byte address mode.

Now, there are a number of reasons why the "stateful" 4-byte address mode switch may not be acceptable. For instance, some SoC's perform a dumb boot sequence in which they only send 3-byte read commands to the flash. However, if an unexpected reset occurs, the flash chip cannot be guaranteed to return to its 3-byte mode. Thus, the SoC controller and flash will not understand each other. (One might consider hooking up the aforementioned reset pin to the system reset line so that any system reset will reset the flash to 3-byte mode, but some packages do not provide this pin. And in some other packages, one must choose between having a reset pin and having enough pins for 4-output QSPI support. It is an error prone process choosing a flash that will support a hardware reset pin!)

This patch provides support for the new stateless command set, so that we can avoid the problems that come with a stateful addressing mode change. The flash can be left in "3-byte mode" while still accessing the entire flash.

Note that Spansion supports this command set on all its large flash (e.g, S25FL512S), and Macronix has begun supporting this command set on some new flash (e.g., MX25L25635F). For the moment, I don't know how to differentiate the Macronix that don't support this command set (e.g., MX25L25635E) from those that do, so this patch only supports Spansion.

---
 drivers/mtd/devices/m25p80.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)
drivers/mtd/devices/m25p80.c +29 -7
index e80db9e..5ff14ee 100644
@@ -48,6 +48,12 @@
 #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
 #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
 
+/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
+#define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
+#define	OPCODE_FAST_READ_4B	0x0c	/* Read data bytes (high frequency) */
+#define	OPCODE_PP_4B		0x12	/* Page program (up to 256 bytes) */
+#define	OPCODE_SE_4B		0xdc	/* Sector erase (usually 64KiB) */
+
 /* Used for SST flashes only. */
 #define	OPCODE_BP		0x02	/* Byte program */
 #define	OPCODE_WRDI		0x04	/* Write disable */
@@ -84,6 +90,8 @@ struct m25p {
 	u16			page_size;
 	u16			addr_width;
 	u8			erase_opcode;
+	u8			read_opcode;
+	u8			program_opcode;
 	u8			*command;
 	bool			fast_read;
 };
@@ -371,7 +379,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	 */
 
 	/* Set up the write data buffer. */
-	opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ;
+	opcode = flash->read_opcode;
 	flash->command[0] = opcode;
 	m25p_addr2cmd(flash, from, flash->command);
 
@@ -422,7 +430,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
 	write_enable(flash);
 
 	/* Set up the opcode in the write buffer. */
-	flash->command[0] = OPCODE_PP;
+	flash->command[0] = flash->program_opcode;
 	m25p_addr2cmd(flash, to, flash->command);
 
 	page_offset = to & (flash->page_size - 1);
@@ -1017,6 +1025,11 @@ static int m25p_probe(struct spi_device *spi)
 		flash->erase_opcode = OPCODE_SE;
 		flash->mtd.erasesize = info->sector_size;
 	}
+	/* Default commands */
+	flash->read_opcode = flash->fast_read ?
+		OPCODE_FAST_READ :
+		OPCODE_NORM_READ;
+	flash->program_opcode = OPCODE_PP;
 
 	if (info->flags & M25P_NO_ERASE)
 		flash->mtd.flags |= MTD_NO_ERASE;
@@ -1038,13 +1051,22 @@ static int m25p_probe(struct spi_device *spi)
 
 	if (info->addr_width)
 		flash->addr_width = info->addr_width;
-	else {
+	else if (flash->mtd.size > 0x1000000) {
 		/* enable 4-byte addressing if the device exceeds 16MiB */
-		if (flash->mtd.size > 0x1000000) {
-			flash->addr_width = 4;
+		flash->addr_width = 4;
+		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
+			/* Dedicated 4-byte command set */
+			flash->read_opcode = flash->fast_read ?
+				OPCODE_FAST_READ_4B :
+				OPCODE_NORM_READ_4B;
+			flash->program_opcode = OPCODE_PP_4B;
+			/* No small sector erase for 4-byte command set */
+			flash->erase_opcode = OPCODE_SE_4B;
+			flash->mtd.erasesize = info->sector_size;
+		} else {
 			set_4byte(flash, info->jedec_id, 1);
-		} else
-			flash->addr_width = 3;
+	} else
+		flash->addr_width = 3;
 	}
 
 	dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name,
Signature · 1 line
1.8.1.5
#1 lore raw

PATCH 2/3 mtd: m25p80: correct EN4B/EX4B comment

---
 drivers/mtd/devices/m25p80.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/devices/m25p80.c +1 -1
index 5ff14ee..6aafdc1 100644
@@ -59,7 +59,7 @@
 #define	OPCODE_WRDI		0x04	/* Write disable */
 #define	OPCODE_AAI_WP		0xad	/* Auto address increment word program */
 
-/* Used for Macronix flashes only. */
+/* Used for Macronix and Winbond flashes. */
 #define	OPCODE_EN4B		0xb7	/* Enter 4-byte mode */
 #define	OPCODE_EX4B		0xe9	/* Exit 4-byte mode */
 
Signature · 1 line
1.8.1.5
#2 lore raw

PATCH 3/3 mtd: nand: reword nand_chip bad block interface comments

In reply to Brian Norris

This remedies a few problems:

(1) The use of "the" vs. "a" is a little confusing, IMO.

(2) nand_chip.block_bad is used exclusively for checking the OOB bad block markers of a NAND. Any BBT functionality is handled in nand_bbt.c, so this description should differentiate itself from nand_bbt.c.

---
 include/linux/mtd/nand.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/mtd/nand.h +2 -2
index 591eeeb..234fbff 100644
@@ -379,8 +379,8 @@ struct nand_buffers {
  * @write_buf:		[REPLACEABLE] write data from the buffer to the chip
  * @read_buf:		[REPLACEABLE] read data from the chip into the buffer
  * @select_chip:	[REPLACEABLE] select chip nr
- * @block_bad:		[REPLACEABLE] check, if the block is bad
- * @block_markbad:	[REPLACEABLE] mark the block bad
+ * @block_bad:		[REPLACEABLE] check if a block is bad, using OOB markers
+ * @block_markbad:	[REPLACEABLE] mark a block bad
  * @cmd_ctrl:		[BOARDSPECIFIC] hardwarespecific function for controlling
  *			ALE/CLE/nCE. Also used to write command and address
  * @init_size:		[BOARDSPECIFIC] hardwarespecific function for setting
Signature · 1 line
1.8.1.5
Acked-by on v1 1/3
#3 lore raw
In reply to Brian Norris

Dear Brian Norris,

Quoted 32 lines

Traditionally, the command set used by SPI flash only supported a 3-byte address. However, large SPI flash (>= 32MB, or 256Mbit) require 4 bytes to address the entire flash. Most manufacturers have supplied a mode switch (via a "bank register writer", or a "enable 4-byte mode" command), which tells the flash to expect 4 address cycles from now on, instead of 3. This mode remains until power is cut, the reset line is triggered (on packages where present), or a command is sent to reset the flash or to reset the 3-byte addressing mode.

As an alternative, some flash manufacturers have developed a new command set that accept a full 4-byte address. They can be used orthogonally to any of the modes; that is, they can be used when the flash is in either 3-byte or 4-byte address mode.

Now, there are a number of reasons why the "stateful" 4-byte address mode switch may not be acceptable. For instance, some SoC's perform a dumb boot sequence in which they only send 3-byte read commands to the flash. However, if an unexpected reset occurs, the flash chip cannot be guaranteed to return to its 3-byte mode. Thus, the SoC controller and flash will not understand each other. (One might consider hooking up the aforementioned reset pin to the system reset line so that any system reset will reset the flash to 3-byte mode, but some packages do not provide this pin. And in some other packages, one must choose between having a reset pin and having enough pins for 4-output QSPI support. It is an error prone process choosing a flash that will support a hardware reset pin!)

This patch provides support for the new stateless command set, so that we can avoid the problems that come with a stateful addressing mode change. The flash can be left in "3-byte mode" while still accessing the entire flash.

Quoted 7 lines

Note that Spansion supports this command set on all its large flash (e.g, S25FL512S), and Macronix has begun supporting this command set on some new flash (e.g., MX25L25635F). For the moment, I don't know how to differentiate the Macronix that don't support this command set (e.g., MX25L25635E) from those that do, so this patch only supports Spansion.

Looks reasonable

What system/CPU do you observe these issue on just out of curiosity?

drivers/mtd/devices/m25p80.c line 48

Quoted 10 lines
---
 drivers/mtd/devices/m25p80.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)
drivers/mtd/devices/m25p80.c +0 -0
index e80db9e..5ff14ee 100644
@@ -48,6 +48,12 @@
 #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) 

*/

drivers/mtd/devices/m25p80.c

Quoted 4 lines
drivers/mtd/devices/m25p80.c +2 -0
 #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
 
+/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
+#define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low 

frequency) */

drivers/mtd/devices/m25p80.c line 53

Quoted 1 line
drivers/mtd/devices/m25p80.c +1 -0
+#define	OPCODE_FAST_READ_4B	0x0c	/* Read data bytes (high 

frequency) */

drivers/mtd/devices/m25p80.c line 54

Quoted 1 line
drivers/mtd/devices/m25p80.c +1 -0
+#define	OPCODE_PP_4B		0x12	/* Page program (up to 256 

bytes) */

drivers/mtd/devices/m25p80.c line 55

Quoted 1 line
drivers/mtd/devices/m25p80.c +1 -0
+#define	OPCODE_SE_4B		0xdc	/* Sector erase (usually 64KiB) 

*/

Quoted 71 lines
drivers/mtd/devices/m25p80.c +3 -0
+
 /* Used for SST flashes only. */
 #define	OPCODE_BP		0x02	/* Byte program */
 #define	OPCODE_WRDI		0x04	/* Write disable */
@@ -84,6 +90,8 @@ struct m25p {
 	u16			page_size;
 	u16			addr_width;
 	u8			erase_opcode;
+	u8			read_opcode;
+	u8			program_opcode;
 	u8			*command;
 	bool			fast_read;
 };
@@ -371,7 +379,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t

from, size_t len, */

drivers/mtd/devices/m25p80.c +21 -7
 	/* Set up the write data buffer. */
-	opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ;
+	opcode = flash->read_opcode;
 	flash->command[0] = opcode;
 	m25p_addr2cmd(flash, from, flash->command);
@@ -422,7 +430,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t
 to, size_t len, write_enable(flash);
 
 	/* Set up the opcode in the write buffer. */
-	flash->command[0] = OPCODE_PP;
+	flash->command[0] = flash->program_opcode;
 	m25p_addr2cmd(flash, to, flash->command);
 
 	page_offset = to & (flash->page_size - 1);
@@ -1017,6 +1025,11 @@ static int m25p_probe(struct spi_device *spi)
 		flash->erase_opcode = OPCODE_SE;
 		flash->mtd.erasesize = info->sector_size;
 	}
+	/* Default commands */
+	flash->read_opcode = flash->fast_read ?
+		OPCODE_FAST_READ :
+		OPCODE_NORM_READ;
+	flash->program_opcode = OPCODE_PP;
 
 	if (info->flags & M25P_NO_ERASE)
 		flash->mtd.flags |= MTD_NO_ERASE;
@@ -1038,13 +1051,22 @@ static int m25p_probe(struct spi_device *spi)
 
 	if (info->addr_width)
 		flash->addr_width = info->addr_width;
-	else {
+	else if (flash->mtd.size > 0x1000000) {
 		/* enable 4-byte addressing if the device exceeds 16MiB */
-		if (flash->mtd.size > 0x1000000) {
-			flash->addr_width = 4;
+		flash->addr_width = 4;
+		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
+			/* Dedicated 4-byte command set */
+			flash->read_opcode = flash->fast_read ?
+				OPCODE_FAST_READ_4B :
+				OPCODE_NORM_READ_4B;
+			flash->program_opcode = OPCODE_PP_4B;
+			/* No small sector erase for 4-byte command set */
+			flash->erase_opcode = OPCODE_SE_4B;
+			flash->mtd.erasesize = info->sector_size;
+		} else {
 			set_4byte(flash, info->jedec_id, 1);
-		} else
-			flash->addr_width = 3;
+	} else
+		flash->addr_width = 3;
 	}
 
 	dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name,
#4 lore raw
Quoted 38 lines · Marek Vasut
Quoted 38 lines

Traditionally, the command set used by SPI flash only supported a 3-byte address. However, large SPI flash (>= 32MB, or 256Mbit) require 4 bytes to address the entire flash. Most manufacturers have supplied a mode switch (via a "bank register writer", or a "enable 4-byte mode" command), which tells the flash to expect 4 address cycles from now on, instead of 3. This mode remains until power is cut, the reset line is triggered (on packages where present), or a command is sent to reset the flash or to reset the 3-byte addressing mode.

As an alternative, some flash manufacturers have developed a new command set that accept a full 4-byte address. They can be used orthogonally to any of the modes; that is, they can be used when the flash is in either 3-byte or 4-byte address mode.

Now, there are a number of reasons why the "stateful" 4-byte address mode switch may not be acceptable. For instance, some SoC's perform a dumb boot sequence in which they only send 3-byte read commands to the flash. However, if an unexpected reset occurs, the flash chip cannot be guaranteed to return to its 3-byte mode. Thus, the SoC controller and flash will not understand each other. (One might consider hooking up the aforementioned reset pin to the system reset line so that any system reset will reset the flash to 3-byte mode, but some packages do not provide this pin. And in some other packages, one must choose between having a reset pin and having enough pins for 4-output QSPI support. It is an error prone process choosing a flash that will support a hardware reset pin!)

This patch provides support for the new stateless command set, so that we can avoid the problems that come with a stateful addressing mode change. The flash can be left in "3-byte mode" while still accessing the entire flash.

Note that Spansion supports this command set on all its large flash (e.g, S25FL512S), and Macronix has begun supporting this command set on some new flash (e.g., MX25L25635F). For the moment, I don't know how to differentiate the Macronix that don't support this command set (e.g., MX25L25635E) from those that do, so this patch only supports Spansion.

Quoted 7 lines
Quoted 1 line

Looks reasonable

What system/CPU do you observe these issue on just out of curiosity?

A Broadcom 74xx series SoC.

Brian

#5 lore raw

Dear Brian Norris,

Quoted 41 lines · Marek Vasut
Quoted 40 lines
Quoted 39 lines

Traditionally, the command set used by SPI flash only supported a 3-byte address. However, large SPI flash (>= 32MB, or 256Mbit) require 4 bytes to address the entire flash. Most manufacturers have supplied a mode switch (via a "bank register writer", or a "enable 4-byte mode" command), which tells the flash to expect 4 address cycles from now on, instead of 3. This mode remains until power is cut, the reset line is triggered (on packages where present), or a command is sent to reset the flash or to reset the 3-byte addressing mode.

As an alternative, some flash manufacturers have developed a new command set that accept a full 4-byte address. They can be used orthogonally to any of the modes; that is, they can be used when the flash is in either 3-byte or 4-byte address mode.

Now, there are a number of reasons why the "stateful" 4-byte address mode switch may not be acceptable. For instance, some SoC's perform a dumb boot sequence in which they only send 3-byte read commands to the flash. However, if an unexpected reset occurs, the flash chip cannot be guaranteed to return to its 3-byte mode. Thus, the SoC controller and flash will not understand each other. (One might consider hooking up the aforementioned reset pin to the system reset line so that any system reset will reset the flash to 3-byte mode, but some packages do not provide this pin. And in some other packages, one must choose between having a reset pin and having enough pins for 4-output QSPI support. It is an error prone process choosing a flash that will support a hardware reset pin!)

This patch provides support for the new stateless command set, so that we can avoid the problems that come with a stateful addressing mode change. The flash can be left in "3-byte mode" while still accessing the entire flash.

Note that Spansion supports this command set on all its large flash (e.g, S25FL512S), and Macronix has begun supporting this command set on some new flash (e.g., MX25L25635F). For the moment, I don't know how to differentiate the Macronix that don't support this command set (e.g., MX25L25635E) from those that do, so this patch only supports Spansion.

Quoted 7 lines
Quoted 5 lines

Looks reasonable

What system/CPU do you observe these issue on just out of curiosity?

A Broadcom 74xx series SoC.

Oh ok. The bootrom programmers really do a poor job :(

Best regards,
Marek Vasut

#6 lore raw
In reply to Brian Norris
Quoted 8 lines · Brian Norris

Traditionally, the command set used by SPI flash only supported a 3-byte address. However, large SPI flash (>= 32MB, or 256Mbit) require 4 bytes to address the entire flash. Most manufacturers have supplied a mode switch (via a "bank register writer", or a "enable 4-byte mode" command), which tells the flash to expect 4 address cycles from now on, instead of 3. This mode remains until power is cut, the reset line is triggered (on packages where present), or a command is sent to reset the flash or to reset the 3-byte addressing mode.

Aiaiai!

Build fails on all my general testing defconfigs.

--------------------------------------------------------------------------------
Failed to build the following commit for configuration "arm-omap2plus_defconfig" (architecture arm)":

d4222c5 mtd: nand: reword nand_chip bad block interface comments

drivers/mtd/devices/m25p80.c:1073: warning: type defaults to 'int' in declaration of '_dev_info' drivers/mtd/devices/m25p80.c:1073: warning: function declaration isn't a prototype drivers/mtd/devices/m25p80.c:1073: error: conflicting types for '_dev_info' drivers/mtd/devices/m25p80.c:1073: note: a parameter list with an ellipsis can't match an empty parameter name list declaration include/linux/device.h:960: note: previous declaration of '_dev_info' was here drivers/mtd/devices/m25p80.c:1076: error: expected declaration specifiers or '...' before string constant drivers/mtd/devices/m25p80.c:1076: error: expected declaration specifiers or '...' before 'flash' drivers/mtd/devices/m25p80.c:1076: error: expected declaration specifiers or '...' before '(' token drivers/mtd/devices/m25p80.c:1076: error: expected declaration specifiers or '...' before '(' token drivers/mtd/devices/m25p80.c:1076: error: expected declaration specifiers or '...' before 'flash' drivers/mtd/devices/m25p80.c:1076: error: expected declaration specifiers or '...' before 'flash' drivers/mtd/devices/m25p80.c:1076: error: expected declaration specifiers or '...' before 'flash' drivers/mtd/devices/m25p80.c:1076: warning: data definition has no type or storage class drivers/mtd/devices/m25p80.c:1076: warning: type defaults to 'int' in declaration of 'no_printk' drivers/mtd/devices/m25p80.c:1076: warning: function declaration isn't a prototype drivers/mtd/devices/m25p80.c:1076: error: conflicting types for 'no_printk' drivers/mtd/devices/m25p80.c:1076: note: a parameter list with an ellipsis can't match an empty parameter name list declaration include/linux/printk.h:93: note: previous definition of 'no_printk' was here drivers/mtd/devices/m25p80.c:1083: error: expected identifier or '(' before 'if' drivers/mtd/devices/m25p80.c:1084: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token drivers/mtd/devices/m25p80.c:1084: error: expected '=', ',', ';', 'asm' or '__attribute__' before '++' token drivers/mtd/devices/m25p80.c:1097: error: expected identifier or '(' before 'return' drivers/mtd/devices/m25p80.c:1100: error: expected identifier or '(' before '}' token
make[4]: *** [drivers/mtd/devices/m25p80.o] Error 1

... ans so on for other configurations.

Signature · 2 lines
Best Regards,
Artem Bityutskiy
#7 lore raw
Quoted 10 lines · Artem Bityutskiy
Quoted 8 lines · Brian Norris

Traditionally, the command set used by SPI flash only supported a 3-byte address. However, large SPI flash (>= 32MB, or 256Mbit) require 4 bytes to address the entire flash. Most manufacturers have supplied a mode switch (via a "bank register writer", or a "enable 4-byte mode" command), which tells the flash to expect 4 address cycles from now on, instead of 3. This mode remains until power is cut, the reset line is triggered (on packages where present), or a command is sent to reset the flash or to reset the 3-byte addressing mode.

Quoted 8 lines

Aiaiai!

Build fails on all my general testing defconfigs.

--------------------------------------------------------------------------------
Failed to build the following commit for configuration "arm-omap2plus_defconfig" (architecture arm)":

d4222c5 mtd: nand: reword nand_chip bad block interface comments

<snip>

Wow, my bad. I actually wrote and tested this against an older kernel, then ported it. In fixing some conflicts, I misplaced my braces...

Anyway, this error (plus a logical mistake that I noticed, regarding the placement of the "fast_read" check) tells me I should take a closer look at this one. I'll get back with v2 eventually.

Brian

#8 lore raw
In reply to Brian Norris
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"B" == Brian Norris <[email protected]> writes:

Hi,

B> This patch provides support for the new stateless command set, so that B> we can avoid the problems that come with a stateful addressing mode B> change. The flash can be left in "3-byte mode" while still accessing the B> entire flash.

Patch looks good (besides the build issue ;)

B> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c B> index e80db9e..5ff14ee 100644
B> --- a/drivers/mtd/devices/m25p80.c
B> +++ b/drivers/mtd/devices/m25p80.c
B> @@ -48,6 +48,12 @@
B> #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
B> #define OPCODE_RDID 0x9f /* Read JEDEC ID */

B> +/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
B> +#define OPCODE_NORM_READ_4B 0x13 /* Read data bytes (low frequency) */
B> +#define OPCODE_FAST_READ_4B 0x0c /* Read data bytes (high frequency) */
B> +#define OPCODE_PP_4B 0x12 /* Page program (up to 256 bytes) */
B> +#define OPCODE_SE_4B 0xdc /* Sector erase (usually 64KiB) */

FYI, looking at a Micron N25Q datasheet, they support the same 4B read/fast read commands, but NOT the 4B PP/SE ones - So for those you need the enter-4B / exit-4B dance :/

Signature · 1 line
Bye, Peter Korsgaard
#9 lore raw
Quoted 25 lines · Peter Korsgaard
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"B" == Brian Norris <[email protected]> writes:

Hi,

B> This patch provides support for the new stateless command set, so that B> we can avoid the problems that come with a stateful addressing mode B> change. The flash can be left in "3-byte mode" while still accessing the B> entire flash.

Patch looks good (besides the build issue ;)

B> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c B> index e80db9e..5ff14ee 100644
B> --- a/drivers/mtd/devices/m25p80.c
B> +++ b/drivers/mtd/devices/m25p80.c
B> @@ -48,6 +48,12 @@
B> #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
B> #define OPCODE_RDID 0x9f /* Read JEDEC ID */

B> +/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
B> +#define OPCODE_NORM_READ_4B 0x13 /* Read data bytes (low frequency) */
B> +#define OPCODE_FAST_READ_4B 0x0c /* Read data bytes (high frequency) */
B> +#define OPCODE_PP_4B 0x12 /* Page program (up to 256 bytes) */
B> +#define OPCODE_SE_4B 0xdc /* Sector erase (usually 64KiB) */

Quoted 4 lines

FYI, looking at a Micron N25Q datasheet, they support the same 4B read/fast read commands, but NOT the 4B PP/SE ones - So for those you need the enter-4B / exit-4B dance :/

Same for windbond chip.

#10 lore raw
In reply to Brian Norris
Quoted 14 lines · Brian Norris

Traditionally, the command set used by SPI flash only supported a 3-byte address. However, large SPI flash (>= 32MB, or 256Mbit) require 4 bytes to address the entire flash. Most manufacturers have supplied a mode switch (via a "bank register writer", or a "enable 4-byte mode" command), which tells the flash to expect 4 address cycles from now on, instead of 3. This mode remains until power is cut, the reset line is triggered (on packages where present), or a command is sent to reset the flash or to reset the 3-byte addressing mode.

As an alternative, some flash manufacturers have developed a new command set that accept a full 4-byte address. They can be used orthogonally to any of the modes; that is, they can be used when the flash is in either 3-byte or 4-byte address mode.

Quoted 6 lines

Now, there are a number of reasons why the "stateful" 4-byte address mode switch may not be acceptable. For instance, some SoC's perform a dumb boot sequence in which they only send 3-byte read commands to the flash. However, if an unexpected reset occurs, the flash chip cannot be guaranteed to return to its 3-byte mode. Thus, the SoC controller and flash will not understand each other.

What's funny is the other side work :

you can have a ROM that use 4-byte mode with 3-byte or 2-byte device as soon as the read command is the same. [1]

What's happen is that the first 1/2 bytes will be skipped and you need to take care of that when flasing the device.

Matthieu

[1]
- send Read Data (03h)command
- send 32 bits address
- read data

#11 lore raw

Dear Matthieu CASTET,

Quoted 22 lines
Quoted 14 lines · Brian Norris

Traditionally, the command set used by SPI flash only supported a 3-byte address. However, large SPI flash (>= 32MB, or 256Mbit) require 4 bytes to address the entire flash. Most manufacturers have supplied a mode switch (via a "bank register writer", or a "enable 4-byte mode" command), which tells the flash to expect 4 address cycles from now on, instead of 3. This mode remains until power is cut, the reset line is triggered (on packages where present), or a command is sent to reset the flash or to reset the 3-byte addressing mode.

As an alternative, some flash manufacturers have developed a new command set that accept a full 4-byte address. They can be used orthogonally to any of the modes; that is, they can be used when the flash is in either 3-byte or 4-byte address mode.

Quoted 6 lines

Now, there are a number of reasons why the "stateful" 4-byte address mode switch may not be acceptable. For instance, some SoC's perform a dumb boot sequence in which they only send 3-byte read commands to the flash. However, if an unexpected reset occurs, the flash chip cannot be guaranteed to return to its 3-byte mode. Thus, the SoC controller and flash will not understand each other.

Quoted 4 lines

What's funny is the other side work :

you can have a ROM that use 4-byte mode with 3-byte or 2-byte device as soon as the read command is the same. [1]

Well, all of these are crap design. The SPI flash shall be power-cycled if the platform reboots no matter what exactly to prevent having it in undefined state.

Best regards,
Marek Vasut

#12 lore raw
Quoted 10 lines · Marek Vasut

Dear Matthieu CASTET,

Quoted 4 lines

What's funny is the other side work :

you can have a ROM that use 4-byte mode with 3-byte or 2-byte device as soon as the read command is the same. [1]

Well, all of these are crap design. The SPI flash shall be power-cycled if the platform reboots no matter what exactly to prevent having it in undefined state.

This side (ROM that use 4-byte mode with 3-byte or 2-byte device) is used to avoid detection of the flash by the rom (no need to know if spi eeprom or spi nor).

#13 lore raw
In reply to Marek Vasut
Quoted 24 lines · Marek Vasut

Dear Matthieu CASTET,

Quoted 22 lines
Quoted 20 lines · Brian Norris

Traditionally, the command set used by SPI flash only supported a 3-byte address. However, large SPI flash (>= 32MB, or 256Mbit) require 4 bytes to address the entire flash. Most manufacturers have supplied a mode switch (via a "bank register writer", or a "enable 4-byte mode" command), which tells the flash to expect 4 address cycles from now on, instead of 3. This mode remains until power is cut, the reset line is triggered (on packages where present), or a command is sent to reset the flash or to reset the 3-byte addressing mode.

As an alternative, some flash manufacturers have developed a new command set that accept a full 4-byte address. They can be used orthogonally to any of the modes; that is, they can be used when the flash is in either 3-byte or 4-byte address mode.

Now, there are a number of reasons why the "stateful" 4-byte address mode switch may not be acceptable. For instance, some SoC's perform a dumb boot sequence in which they only send 3-byte read commands to the flash. However, if an unexpected reset occurs, the flash chip cannot be guaranteed to return to its 3-byte mode. Thus, the SoC controller and flash will not understand each other.

Quoted 7 lines
Quoted 4 lines

What's funny is the other side work :

you can have a ROM that use 4-byte mode with 3-byte or 2-byte device as soon as the read command is the same. [1]

Well, all of these are crap design. The SPI flash shall be power-cycled if the platform reboots no matter what exactly to prevent having it in undefined state.

While I agree that ideally, the flash should always be reset/power-cycled on reboot, these type of flash have traditionally been stateless (and have no RESET command) and flash manufacturers have done nothing to help this as they added state (e.g., non-standard command sets; partially-supported command sets). Plus, as I mentioned, not all flash have reset pins, as they try to skimp on pins or take them over for other uses.

What exactly is your recommended non-crap design on these stateful flash that have no reset pin? Just a smarter boot ROM which can handle different states/flash types?

Brian