All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] mtd: st_spi_fsm: Align with ST's internal development
@ 2014-05-22 11:23 ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:23 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: computersforpeace, linux-mtd

Hi Brian, all,

v2:
  These are the last remaining patches in the set, all rebased and
  with the DT documentation requested after the last submission.

v1:
  This patch-set updates ST's FSM SPI-NOR driver with all the internal
  goodness which has happened since the initial (now upstreamed) snapshot
  was taken. It covers just over 6 months worth of internal development
  and bug-fixes. A final whitespace clean-up is also appended to the set
  - to make it look pretty and stuff. :)

 Documentation/devicetree/bindings/mtd/st-fsm.txt |   2 +
 drivers/mtd/devices/st_spi_fsm.c                 | 687 +++++++++++++++--------
 2 files changed, 469 insertions(+), 220 deletions(-)



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH v2 00/10] mtd: st_spi_fsm: Align with ST's internal development
@ 2014-05-22 11:23 ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Brian, all,

v2:
  These are the last remaining patches in the set, all rebased and
  with the DT documentation requested after the last submission.

v1:
  This patch-set updates ST's FSM SPI-NOR driver with all the internal
  goodness which has happened since the initial (now upstreamed) snapshot
  was taken. It covers just over 6 months worth of internal development
  and bug-fixes. A final whitespace clean-up is also appended to the set
  - to make it look pretty and stuff. :)

 Documentation/devicetree/bindings/mtd/st-fsm.txt |   2 +
 drivers/mtd/devices/st_spi_fsm.c                 | 687 +++++++++++++++--------
 2 files changed, 469 insertions(+), 220 deletions(-)

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 01/10] mtd: st_spi_fsm: Extend fsm_clear_fifo to handle unwanted bytes
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:23   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:23 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Lee Jones, Angus Clark

Under certain conditions, the SPI-FSM Controller can be left in a state where
the data FIFO is not entirely empty.  This can lead to problems where subsequent
data transfers appear to have been shifted by a number of unidentified bytes.

One simple example would be an errant FSM sequence which loaded more data to the
FIFO than was read by the host.  Another more interesting case results from an
obscure artefact in the FSM Controller.  When switching from data transfers in
x4 or x2 mode to data transfers in x1 mode, extraneous bytes will appear in the
FIFO, unless the previous data transfer was a multiple of 32 cycles (i.e. 8
bytes for x2, and 16 bytes for x4).  This applies equally whether FSM is being
operated directly by a S/W driver, or by the SPI boot-controller in FSM-Boot
mode.  Furthermore, data in the FIFO not only survive a transition between
FSM-Boot and FSM, but also a S/W reset of IP block [1].

By taking certain precautions, it is possible to prevent the driver from causing
this type of problem (e.g. ensuring that the host and programmed sequence
agree on the transfer size, and restricting transfer sizes to multiples of
32-cycles [2]).  However, at the point the driver is loaded, no assumptions can be
made regarding the state of the FIFO.  Even if previous S/W drivers have behaved
correctly, it is impossible to control the number of transactions serviced by
the controller operating in FSM-Boot.

To address this problem, we ensure the FIFO is cleared during initialisation,
before performing any FSM operations.  Previously, the fsm_clear_fifo() code was
capable of detecting and clearing any unwanted 32-bit words from the FIFO.  This
patch extends the capability to handle an arbitrary number of bytes present in
the FIFO [3].  Now that the issue is better understood, we also remove the calls
to fsm_clear_fifo() following the fsm_read() and fsm_write() operations.

The process of actually clearing the FIFO deserves a mention.  While the FIFO
may contain any number of bytes, the SPI_FAST_SEQ_STA register only reports the
number of complete 32-bit words present.  Furthermore, data can only be drained
from the FIFO by reading complete 32-bit words.  With this in mind, a two stage
process is used to the clear the FIFO:

    1. Read any complete 32-bit words from the FIFO, as reported by the
           SPI_FAST_SEQ_STA register.

    2. Mop up any remaining bytes.  At this point, it is not known if there
           are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy
           FSM sequence is used to load one byte at a time, until a complete
           32-bit word is formed; at most, 4 bytes will need to be loaded.

[1] Although this issue has existed since early versions of the SPI-FSM
    controller, its full extent only emerged recently as a consequence of the
    targetpacks starting to use FSM-Boot(x4) as the default configuration.

[2] The requirement to restrict transfers to multiples of 32 cycles was found
    empirically back when DUAL and QUAD mode support was added.  The current
    analysis now gives a satisfactory explanation for this requirement.

[3] Theoretically, it is possible for the FIFO to contain an arbitrary number of
    bits.  However, since there are no known use-cases that leave incomplete
    bytes in the FIFO, only words and bytes are considered here.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 96 +++++++++++++++++++++++++++++++++-------
 1 file changed, 80 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index f97fe14..aca4d72 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -663,6 +663,23 @@ static struct stfsm_seq stfsm_seq_write_status = {
 		    SEQ_CFG_STARTSEQ),
 };
 
+/* Dummy sequence to read one byte of data from flash into the FIFO */
+static const struct stfsm_seq stfsm_seq_load_fifo_byte = {
+	.data_size = TRANSFER_SIZE(1),
+	.seq_opc[0] = (SEQ_OPC_PADS_1 |
+		       SEQ_OPC_CYCLES(8) |
+		       SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
+	.seq = {
+		STFSM_INST_CMD1,
+		STFSM_INST_DATA_READ,
+		STFSM_INST_STOP,
+	},
+	.seq_cfg = (SEQ_CFG_PADS_1 |
+		    SEQ_CFG_READNOTWRITE |
+		    SEQ_CFG_CSDEASSERT |
+		    SEQ_CFG_STARTSEQ),
+};
+
 static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq)
 {
 	seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
@@ -695,22 +712,6 @@ static inline uint32_t stfsm_fifo_available(struct stfsm *fsm)
 	return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f;
 }
 
-static void stfsm_clear_fifo(struct stfsm *fsm)
-{
-	uint32_t avail;
-
-	for (;;) {
-		avail = stfsm_fifo_available(fsm);
-		if (!avail)
-			break;
-
-		while (avail) {
-			readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
-			avail--;
-		}
-	}
-}
-
 static inline void stfsm_load_seq(struct stfsm *fsm,
 				  const struct stfsm_seq *seq)
 {
@@ -772,6 +773,69 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, uint32_t size)
 	}
 }
 
+/*
+ * Clear the data FIFO
+ *
+ * Typically, this is only required during driver initialisation, where no
+ * assumptions can be made regarding the state of the FIFO.
+ *
+ * The process of clearing the FIFO is complicated by fact that while it is
+ * possible for the FIFO to contain an arbitrary number of bytes [1], the
+ * SPI_FAST_SEQ_STA register only reports the number of complete 32-bit words
+ * present.  Furthermore, data can only be drained from the FIFO by reading
+ * complete 32-bit words.
+ *
+ * With this in mind, a two stage process is used to the clear the FIFO:
+ *
+ *     1. Read any complete 32-bit words from the FIFO, as reported by the
+ *        SPI_FAST_SEQ_STA register.
+ *
+ *     2. Mop up any remaining bytes.  At this point, it is not known if there
+ *        are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy FSM
+ *        sequence is used to load one byte at a time, until a complete 32-bit
+ *        word is formed; at most, 4 bytes will need to be loaded.
+ *
+ * [1] It is theoretically possible for the FIFO to contain an arbitrary number
+ *     of bits.  However, since there are no known use-cases that leave
+ *     incomplete bytes in the FIFO, only words and bytes are considered here.
+ */
+static void stfsm_clear_fifo(struct stfsm *fsm)
+{
+	const struct stfsm_seq *seq = &stfsm_seq_load_fifo_byte;
+	uint32_t words;
+	int i;
+
+	/* 1. Clear any 32-bit words */
+	words = stfsm_fifo_available(fsm);
+	if (words) {
+		for (i = 0; i < words; i++)
+			readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+		dev_dbg(fsm->dev, "cleared %d words from FIFO\n", words);
+	}
+
+	/*
+	 * 2. Clear any remaining bytes
+	 *    - Load the FIFO, one byte at a time, until a complete 32-bit word
+	 *      is available.
+	 */
+	for (i = 0, words = 0; i < 4 && !words; i++) {
+		stfsm_load_seq(fsm, seq);
+		stfsm_wait_seq(fsm);
+		words = stfsm_fifo_available(fsm);
+	}
+
+	/*    - A single word must be available now */
+	if (words != 1) {
+		dev_err(fsm->dev, "failed to clear bytes from the data FIFO\n");
+		return;
+	}
+
+	/*    - Read the 32-bit word */
+	readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+
+	dev_dbg(fsm->dev, "cleared %d byte(s) from the data FIFO\n", 4 - i);
+}
+
 static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf,
 			    uint32_t size)
 {
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 01/10] mtd: st_spi_fsm: Extend fsm_clear_fifo to handle unwanted bytes
@ 2014-05-22 11:23   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:23 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Lee Jones, computersforpeace, linux-mtd, Angus Clark

Under certain conditions, the SPI-FSM Controller can be left in a state where
the data FIFO is not entirely empty.  This can lead to problems where subsequent
data transfers appear to have been shifted by a number of unidentified bytes.

One simple example would be an errant FSM sequence which loaded more data to the
FIFO than was read by the host.  Another more interesting case results from an
obscure artefact in the FSM Controller.  When switching from data transfers in
x4 or x2 mode to data transfers in x1 mode, extraneous bytes will appear in the
FIFO, unless the previous data transfer was a multiple of 32 cycles (i.e. 8
bytes for x2, and 16 bytes for x4).  This applies equally whether FSM is being
operated directly by a S/W driver, or by the SPI boot-controller in FSM-Boot
mode.  Furthermore, data in the FIFO not only survive a transition between
FSM-Boot and FSM, but also a S/W reset of IP block [1].

By taking certain precautions, it is possible to prevent the driver from causing
this type of problem (e.g. ensuring that the host and programmed sequence
agree on the transfer size, and restricting transfer sizes to multiples of
32-cycles [2]).  However, at the point the driver is loaded, no assumptions can be
made regarding the state of the FIFO.  Even if previous S/W drivers have behaved
correctly, it is impossible to control the number of transactions serviced by
the controller operating in FSM-Boot.

To address this problem, we ensure the FIFO is cleared during initialisation,
before performing any FSM operations.  Previously, the fsm_clear_fifo() code was
capable of detecting and clearing any unwanted 32-bit words from the FIFO.  This
patch extends the capability to handle an arbitrary number of bytes present in
the FIFO [3].  Now that the issue is better understood, we also remove the calls
to fsm_clear_fifo() following the fsm_read() and fsm_write() operations.

The process of actually clearing the FIFO deserves a mention.  While the FIFO
may contain any number of bytes, the SPI_FAST_SEQ_STA register only reports the
number of complete 32-bit words present.  Furthermore, data can only be drained
from the FIFO by reading complete 32-bit words.  With this in mind, a two stage
process is used to the clear the FIFO:

    1. Read any complete 32-bit words from the FIFO, as reported by the
           SPI_FAST_SEQ_STA register.

    2. Mop up any remaining bytes.  At this point, it is not known if there
           are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy
           FSM sequence is used to load one byte at a time, until a complete
           32-bit word is formed; at most, 4 bytes will need to be loaded.

[1] Although this issue has existed since early versions of the SPI-FSM
    controller, its full extent only emerged recently as a consequence of the
    targetpacks starting to use FSM-Boot(x4) as the default configuration.

[2] The requirement to restrict transfers to multiples of 32 cycles was found
    empirically back when DUAL and QUAD mode support was added.  The current
    analysis now gives a satisfactory explanation for this requirement.

[3] Theoretically, it is possible for the FIFO to contain an arbitrary number of
    bits.  However, since there are no known use-cases that leave incomplete
    bytes in the FIFO, only words and bytes are considered here.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 96 +++++++++++++++++++++++++++++++++-------
 1 file changed, 80 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index f97fe14..aca4d72 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -663,6 +663,23 @@ static struct stfsm_seq stfsm_seq_write_status = {
 		    SEQ_CFG_STARTSEQ),
 };
 
+/* Dummy sequence to read one byte of data from flash into the FIFO */
+static const struct stfsm_seq stfsm_seq_load_fifo_byte = {
+	.data_size = TRANSFER_SIZE(1),
+	.seq_opc[0] = (SEQ_OPC_PADS_1 |
+		       SEQ_OPC_CYCLES(8) |
+		       SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
+	.seq = {
+		STFSM_INST_CMD1,
+		STFSM_INST_DATA_READ,
+		STFSM_INST_STOP,
+	},
+	.seq_cfg = (SEQ_CFG_PADS_1 |
+		    SEQ_CFG_READNOTWRITE |
+		    SEQ_CFG_CSDEASSERT |
+		    SEQ_CFG_STARTSEQ),
+};
+
 static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq)
 {
 	seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
@@ -695,22 +712,6 @@ static inline uint32_t stfsm_fifo_available(struct stfsm *fsm)
 	return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f;
 }
 
-static void stfsm_clear_fifo(struct stfsm *fsm)
-{
-	uint32_t avail;
-
-	for (;;) {
-		avail = stfsm_fifo_available(fsm);
-		if (!avail)
-			break;
-
-		while (avail) {
-			readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
-			avail--;
-		}
-	}
-}
-
 static inline void stfsm_load_seq(struct stfsm *fsm,
 				  const struct stfsm_seq *seq)
 {
@@ -772,6 +773,69 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, uint32_t size)
 	}
 }
 
+/*
+ * Clear the data FIFO
+ *
+ * Typically, this is only required during driver initialisation, where no
+ * assumptions can be made regarding the state of the FIFO.
+ *
+ * The process of clearing the FIFO is complicated by fact that while it is
+ * possible for the FIFO to contain an arbitrary number of bytes [1], the
+ * SPI_FAST_SEQ_STA register only reports the number of complete 32-bit words
+ * present.  Furthermore, data can only be drained from the FIFO by reading
+ * complete 32-bit words.
+ *
+ * With this in mind, a two stage process is used to the clear the FIFO:
+ *
+ *     1. Read any complete 32-bit words from the FIFO, as reported by the
+ *        SPI_FAST_SEQ_STA register.
+ *
+ *     2. Mop up any remaining bytes.  At this point, it is not known if there
+ *        are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy FSM
+ *        sequence is used to load one byte at a time, until a complete 32-bit
+ *        word is formed; at most, 4 bytes will need to be loaded.
+ *
+ * [1] It is theoretically possible for the FIFO to contain an arbitrary number
+ *     of bits.  However, since there are no known use-cases that leave
+ *     incomplete bytes in the FIFO, only words and bytes are considered here.
+ */
+static void stfsm_clear_fifo(struct stfsm *fsm)
+{
+	const struct stfsm_seq *seq = &stfsm_seq_load_fifo_byte;
+	uint32_t words;
+	int i;
+
+	/* 1. Clear any 32-bit words */
+	words = stfsm_fifo_available(fsm);
+	if (words) {
+		for (i = 0; i < words; i++)
+			readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+		dev_dbg(fsm->dev, "cleared %d words from FIFO\n", words);
+	}
+
+	/*
+	 * 2. Clear any remaining bytes
+	 *    - Load the FIFO, one byte at a time, until a complete 32-bit word
+	 *      is available.
+	 */
+	for (i = 0, words = 0; i < 4 && !words; i++) {
+		stfsm_load_seq(fsm, seq);
+		stfsm_wait_seq(fsm);
+		words = stfsm_fifo_available(fsm);
+	}
+
+	/*    - A single word must be available now */
+	if (words != 1) {
+		dev_err(fsm->dev, "failed to clear bytes from the data FIFO\n");
+		return;
+	}
+
+	/*    - Read the 32-bit word */
+	readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+
+	dev_dbg(fsm->dev, "cleared %d byte(s) from the data FIFO\n", 4 - i);
+}
+
 static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf,
 			    uint32_t size)
 {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 01/10] mtd: st_spi_fsm: Extend fsm_clear_fifo to handle unwanted bytes
@ 2014-05-22 11:23   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

Under certain conditions, the SPI-FSM Controller can be left in a state where
the data FIFO is not entirely empty.  This can lead to problems where subsequent
data transfers appear to have been shifted by a number of unidentified bytes.

One simple example would be an errant FSM sequence which loaded more data to the
FIFO than was read by the host.  Another more interesting case results from an
obscure artefact in the FSM Controller.  When switching from data transfers in
x4 or x2 mode to data transfers in x1 mode, extraneous bytes will appear in the
FIFO, unless the previous data transfer was a multiple of 32 cycles (i.e. 8
bytes for x2, and 16 bytes for x4).  This applies equally whether FSM is being
operated directly by a S/W driver, or by the SPI boot-controller in FSM-Boot
mode.  Furthermore, data in the FIFO not only survive a transition between
FSM-Boot and FSM, but also a S/W reset of IP block [1].

By taking certain precautions, it is possible to prevent the driver from causing
this type of problem (e.g. ensuring that the host and programmed sequence
agree on the transfer size, and restricting transfer sizes to multiples of
32-cycles [2]).  However, at the point the driver is loaded, no assumptions can be
made regarding the state of the FIFO.  Even if previous S/W drivers have behaved
correctly, it is impossible to control the number of transactions serviced by
the controller operating in FSM-Boot.

To address this problem, we ensure the FIFO is cleared during initialisation,
before performing any FSM operations.  Previously, the fsm_clear_fifo() code was
capable of detecting and clearing any unwanted 32-bit words from the FIFO.  This
patch extends the capability to handle an arbitrary number of bytes present in
the FIFO [3].  Now that the issue is better understood, we also remove the calls
to fsm_clear_fifo() following the fsm_read() and fsm_write() operations.

The process of actually clearing the FIFO deserves a mention.  While the FIFO
may contain any number of bytes, the SPI_FAST_SEQ_STA register only reports the
number of complete 32-bit words present.  Furthermore, data can only be drained
from the FIFO by reading complete 32-bit words.  With this in mind, a two stage
process is used to the clear the FIFO:

    1. Read any complete 32-bit words from the FIFO, as reported by the
           SPI_FAST_SEQ_STA register.

    2. Mop up any remaining bytes.  At this point, it is not known if there
           are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy
           FSM sequence is used to load one byte at a time, until a complete
           32-bit word is formed; at most, 4 bytes will need to be loaded.

[1] Although this issue has existed since early versions of the SPI-FSM
    controller, its full extent only emerged recently as a consequence of the
    targetpacks starting to use FSM-Boot(x4) as the default configuration.

[2] The requirement to restrict transfers to multiples of 32 cycles was found
    empirically back when DUAL and QUAD mode support was added.  The current
    analysis now gives a satisfactory explanation for this requirement.

[3] Theoretically, it is possible for the FIFO to contain an arbitrary number of
    bits.  However, since there are no known use-cases that leave incomplete
    bytes in the FIFO, only words and bytes are considered here.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 96 +++++++++++++++++++++++++++++++++-------
 1 file changed, 80 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index f97fe14..aca4d72 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -663,6 +663,23 @@ static struct stfsm_seq stfsm_seq_write_status = {
 		    SEQ_CFG_STARTSEQ),
 };
 
+/* Dummy sequence to read one byte of data from flash into the FIFO */
+static const struct stfsm_seq stfsm_seq_load_fifo_byte = {
+	.data_size = TRANSFER_SIZE(1),
+	.seq_opc[0] = (SEQ_OPC_PADS_1 |
+		       SEQ_OPC_CYCLES(8) |
+		       SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
+	.seq = {
+		STFSM_INST_CMD1,
+		STFSM_INST_DATA_READ,
+		STFSM_INST_STOP,
+	},
+	.seq_cfg = (SEQ_CFG_PADS_1 |
+		    SEQ_CFG_READNOTWRITE |
+		    SEQ_CFG_CSDEASSERT |
+		    SEQ_CFG_STARTSEQ),
+};
+
 static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq)
 {
 	seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
@@ -695,22 +712,6 @@ static inline uint32_t stfsm_fifo_available(struct stfsm *fsm)
 	return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f;
 }
 
-static void stfsm_clear_fifo(struct stfsm *fsm)
-{
-	uint32_t avail;
-
-	for (;;) {
-		avail = stfsm_fifo_available(fsm);
-		if (!avail)
-			break;
-
-		while (avail) {
-			readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
-			avail--;
-		}
-	}
-}
-
 static inline void stfsm_load_seq(struct stfsm *fsm,
 				  const struct stfsm_seq *seq)
 {
@@ -772,6 +773,69 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, uint32_t size)
 	}
 }
 
+/*
+ * Clear the data FIFO
+ *
+ * Typically, this is only required during driver initialisation, where no
+ * assumptions can be made regarding the state of the FIFO.
+ *
+ * The process of clearing the FIFO is complicated by fact that while it is
+ * possible for the FIFO to contain an arbitrary number of bytes [1], the
+ * SPI_FAST_SEQ_STA register only reports the number of complete 32-bit words
+ * present.  Furthermore, data can only be drained from the FIFO by reading
+ * complete 32-bit words.
+ *
+ * With this in mind, a two stage process is used to the clear the FIFO:
+ *
+ *     1. Read any complete 32-bit words from the FIFO, as reported by the
+ *        SPI_FAST_SEQ_STA register.
+ *
+ *     2. Mop up any remaining bytes.  At this point, it is not known if there
+ *        are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy FSM
+ *        sequence is used to load one byte at a time, until a complete 32-bit
+ *        word is formed; at most, 4 bytes will need to be loaded.
+ *
+ * [1] It is theoretically possible for the FIFO to contain an arbitrary number
+ *     of bits.  However, since there are no known use-cases that leave
+ *     incomplete bytes in the FIFO, only words and bytes are considered here.
+ */
+static void stfsm_clear_fifo(struct stfsm *fsm)
+{
+	const struct stfsm_seq *seq = &stfsm_seq_load_fifo_byte;
+	uint32_t words;
+	int i;
+
+	/* 1. Clear any 32-bit words */
+	words = stfsm_fifo_available(fsm);
+	if (words) {
+		for (i = 0; i < words; i++)
+			readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+		dev_dbg(fsm->dev, "cleared %d words from FIFO\n", words);
+	}
+
+	/*
+	 * 2. Clear any remaining bytes
+	 *    - Load the FIFO, one byte at a time, until a complete 32-bit word
+	 *      is available.
+	 */
+	for (i = 0, words = 0; i < 4 && !words; i++) {
+		stfsm_load_seq(fsm, seq);
+		stfsm_wait_seq(fsm);
+		words = stfsm_fifo_available(fsm);
+	}
+
+	/*    - A single word must be available now */
+	if (words != 1) {
+		dev_err(fsm->dev, "failed to clear bytes from the data FIFO\n");
+		return;
+	}
+
+	/*    - Read the 32-bit word */
+	readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+
+	dev_dbg(fsm->dev, "cleared %d byte(s) from the data FIFO\n", 4 - i);
+}
+
 static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf,
 			    uint32_t size)
 {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Obtain and use EMI clock if provided
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:24   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: computersforpeace, linux-mtd, Lee Jones

ST's Common Clk Framework is now available. This patch ensures the FSM
makes use of it by obtaining and enabling the EMI clock if provided. If
system fails to provide the EMI clock FSM uses its original default
rate.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 45 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index aca4d72..fe54533 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/clk.h>
 
 #include "serial_flash_cmds.h"
 
@@ -262,6 +263,7 @@ struct stfsm {
 	struct mtd_info		mtd;
 	struct mutex		lock;
 	struct flash_info       *info;
+	struct clk              *clk;
 
 	uint32_t                configuration;
 	uint32_t                fifo_dir_delay;
@@ -1907,8 +1909,13 @@ static void stfsm_set_freq(struct stfsm *fsm, uint32_t spi_freq)
 	uint32_t emi_freq;
 	uint32_t clk_div;
 
-	/* TODO: Make this dynamic */
-	emi_freq = STFSM_DEFAULT_EMI_FREQ;
+	if (!fsm->clk) {
+		dev_warn(fsm->dev,
+			 "No EMI clock available. Using default 100MHz.\n");
+
+		emi_freq = STFSM_DEFAULT_EMI_FREQ;
+	} else
+		emi_freq = clk_get_rate(fsm->clk);
 
 	/*
 	 * Calculate clk_div - values between 2 and 128
@@ -2058,6 +2065,15 @@ static int stfsm_probe(struct platform_device *pdev)
 		return PTR_ERR(fsm->base);
 	}
 
+	fsm->clk = devm_clk_get(&pdev->dev, "emi_clk");
+	if (IS_ERR(fsm->clk)) {
+		dev_warn(fsm->dev, "Couldn't find EMI clock.\n");
+		fsm->clk = NULL;
+	} else if (clk_prepare_enable(fsm->clk)) {
+		dev_warn(fsm->dev, "Failed to enable EMI clock.\n");
+		fsm->clk = NULL;
+	}
+
 	mutex_init(&fsm->lock);
 
 	ret = stfsm_init(fsm);
@@ -2122,6 +2138,30 @@ static int stfsm_remove(struct platform_device *pdev)
 	return mtd_device_unregister(&fsm->mtd);
 }
 
+#ifdef CONFIG_PM
+static int stfsmfsm_suspend(struct device *dev)
+{
+	struct stfsm *fsm = dev_get_drvdata(dev);
+
+	if (fsm->clk)
+		clk_disable_unprepare(fsm->clk);
+
+	return 0;
+}
+
+static int stfsmfsm_resume(struct device *dev)
+{
+	struct stfsm *fsm = dev_get_drvdata(dev);
+
+	if (fsm->clk)
+		clk_prepare_enable(fsm->clk);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(stfsm_pm_ops, stfsmfsm_suspend, stfsmfsm_resume);
+
 static struct of_device_id stfsm_match[] = {
 	{ .compatible = "st,spi-fsm", },
 	{},
@@ -2135,6 +2175,7 @@ static struct platform_driver stfsm_driver = {
 		.name	= "st-spi-fsm",
 		.owner	= THIS_MODULE,
 		.of_match_table = stfsm_match,
+		.pm     = &stfsm_pm_ops,
 	},
 };
 module_platform_driver(stfsm_driver);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Obtain and use EMI clock if provided
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: Lee Jones, computersforpeace, linux-mtd

ST's Common Clk Framework is now available. This patch ensures the FSM
makes use of it by obtaining and enabling the EMI clock if provided. If
system fails to provide the EMI clock FSM uses its original default
rate.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 45 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index aca4d72..fe54533 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/clk.h>
 
 #include "serial_flash_cmds.h"
 
@@ -262,6 +263,7 @@ struct stfsm {
 	struct mtd_info		mtd;
 	struct mutex		lock;
 	struct flash_info       *info;
+	struct clk              *clk;
 
 	uint32_t                configuration;
 	uint32_t                fifo_dir_delay;
@@ -1907,8 +1909,13 @@ static void stfsm_set_freq(struct stfsm *fsm, uint32_t spi_freq)
 	uint32_t emi_freq;
 	uint32_t clk_div;
 
-	/* TODO: Make this dynamic */
-	emi_freq = STFSM_DEFAULT_EMI_FREQ;
+	if (!fsm->clk) {
+		dev_warn(fsm->dev,
+			 "No EMI clock available. Using default 100MHz.\n");
+
+		emi_freq = STFSM_DEFAULT_EMI_FREQ;
+	} else
+		emi_freq = clk_get_rate(fsm->clk);
 
 	/*
 	 * Calculate clk_div - values between 2 and 128
@@ -2058,6 +2065,15 @@ static int stfsm_probe(struct platform_device *pdev)
 		return PTR_ERR(fsm->base);
 	}
 
+	fsm->clk = devm_clk_get(&pdev->dev, "emi_clk");
+	if (IS_ERR(fsm->clk)) {
+		dev_warn(fsm->dev, "Couldn't find EMI clock.\n");
+		fsm->clk = NULL;
+	} else if (clk_prepare_enable(fsm->clk)) {
+		dev_warn(fsm->dev, "Failed to enable EMI clock.\n");
+		fsm->clk = NULL;
+	}
+
 	mutex_init(&fsm->lock);
 
 	ret = stfsm_init(fsm);
@@ -2122,6 +2138,30 @@ static int stfsm_remove(struct platform_device *pdev)
 	return mtd_device_unregister(&fsm->mtd);
 }
 
+#ifdef CONFIG_PM
+static int stfsmfsm_suspend(struct device *dev)
+{
+	struct stfsm *fsm = dev_get_drvdata(dev);
+
+	if (fsm->clk)
+		clk_disable_unprepare(fsm->clk);
+
+	return 0;
+}
+
+static int stfsmfsm_resume(struct device *dev)
+{
+	struct stfsm *fsm = dev_get_drvdata(dev);
+
+	if (fsm->clk)
+		clk_prepare_enable(fsm->clk);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(stfsm_pm_ops, stfsmfsm_suspend, stfsmfsm_resume);
+
 static struct of_device_id stfsm_match[] = {
 	{ .compatible = "st,spi-fsm", },
 	{},
@@ -2135,6 +2175,7 @@ static struct platform_driver stfsm_driver = {
 		.name	= "st-spi-fsm",
 		.owner	= THIS_MODULE,
 		.of_match_table = stfsm_match,
+		.pm     = &stfsm_pm_ops,
 	},
 };
 module_platform_driver(stfsm_driver);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 02/10] mtd: st_spi_fsm: Obtain and use EMI clock if provided
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

ST's Common Clk Framework is now available. This patch ensures the FSM
makes use of it by obtaining and enabling the EMI clock if provided. If
system fails to provide the EMI clock FSM uses its original default
rate.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 45 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index aca4d72..fe54533 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/clk.h>
 
 #include "serial_flash_cmds.h"
 
@@ -262,6 +263,7 @@ struct stfsm {
 	struct mtd_info		mtd;
 	struct mutex		lock;
 	struct flash_info       *info;
+	struct clk              *clk;
 
 	uint32_t                configuration;
 	uint32_t                fifo_dir_delay;
@@ -1907,8 +1909,13 @@ static void stfsm_set_freq(struct stfsm *fsm, uint32_t spi_freq)
 	uint32_t emi_freq;
 	uint32_t clk_div;
 
-	/* TODO: Make this dynamic */
-	emi_freq = STFSM_DEFAULT_EMI_FREQ;
+	if (!fsm->clk) {
+		dev_warn(fsm->dev,
+			 "No EMI clock available. Using default 100MHz.\n");
+
+		emi_freq = STFSM_DEFAULT_EMI_FREQ;
+	} else
+		emi_freq = clk_get_rate(fsm->clk);
 
 	/*
 	 * Calculate clk_div - values between 2 and 128
@@ -2058,6 +2065,15 @@ static int stfsm_probe(struct platform_device *pdev)
 		return PTR_ERR(fsm->base);
 	}
 
+	fsm->clk = devm_clk_get(&pdev->dev, "emi_clk");
+	if (IS_ERR(fsm->clk)) {
+		dev_warn(fsm->dev, "Couldn't find EMI clock.\n");
+		fsm->clk = NULL;
+	} else if (clk_prepare_enable(fsm->clk)) {
+		dev_warn(fsm->dev, "Failed to enable EMI clock.\n");
+		fsm->clk = NULL;
+	}
+
 	mutex_init(&fsm->lock);
 
 	ret = stfsm_init(fsm);
@@ -2122,6 +2138,30 @@ static int stfsm_remove(struct platform_device *pdev)
 	return mtd_device_unregister(&fsm->mtd);
 }
 
+#ifdef CONFIG_PM
+static int stfsmfsm_suspend(struct device *dev)
+{
+	struct stfsm *fsm = dev_get_drvdata(dev);
+
+	if (fsm->clk)
+		clk_disable_unprepare(fsm->clk);
+
+	return 0;
+}
+
+static int stfsmfsm_resume(struct device *dev)
+{
+	struct stfsm *fsm = dev_get_drvdata(dev);
+
+	if (fsm->clk)
+		clk_prepare_enable(fsm->clk);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(stfsm_pm_ops, stfsmfsm_suspend, stfsmfsm_resume);
+
 static struct of_device_id stfsm_match[] = {
 	{ .compatible = "st,spi-fsm", },
 	{},
@@ -2135,6 +2175,7 @@ static struct platform_driver stfsm_driver = {
 		.name	= "st-spi-fsm",
 		.owner	= THIS_MODULE,
 		.of_match_table = stfsm_match,
+		.pm     = &stfsm_pm_ops,
 	},
 };
 module_platform_driver(stfsm_driver);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 03/10] mtd: st_spi_fsm: Add support for Micron N25Q512A
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:24   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Nunzio Raciti, Lee Jones

From: Nunzio Raciti <nunzio.raciti@st.com>

This patch adds support for the Micron N25Q512A device as required
by the B2147 (STiD127) board.

Signed-off-by: Nunzio Raciti <nunzio.raciti@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index fe54533..67ea35e 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -374,6 +374,8 @@ static struct flash_info flash_types[] = {
 	  stfsm_n25q_config },
 	{ "n25q256", 0x20ba19, 0, 64 * 1024,  512,
 	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config },
+	{ "n25q512", 0x20ba20, 0, 64 * 1024,  1024,
+	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config},
 
 	/*
 	 * Spansion S25FLxxxP
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 03/10] mtd: st_spi_fsm: Add support for Micron N25Q512A
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Lee Jones, computersforpeace, linux-mtd, Nunzio Raciti

From: Nunzio Raciti <nunzio.raciti@st.com>

This patch adds support for the Micron N25Q512A device as required
by the B2147 (STiD127) board.

Signed-off-by: Nunzio Raciti <nunzio.raciti@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index fe54533..67ea35e 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -374,6 +374,8 @@ static struct flash_info flash_types[] = {
 	  stfsm_n25q_config },
 	{ "n25q256", 0x20ba19, 0, 64 * 1024,  512,
 	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config },
+	{ "n25q512", 0x20ba20, 0, 64 * 1024,  1024,
+	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config},
 
 	/*
 	 * Spansion S25FLxxxP
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 03/10] mtd: st_spi_fsm: Add support for Micron N25Q512A
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nunzio Raciti <nunzio.raciti@st.com>

This patch adds support for the Micron N25Q512A device as required
by the B2147 (STiD127) board.

Signed-off-by: Nunzio Raciti <nunzio.raciti@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index fe54533..67ea35e 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -374,6 +374,8 @@ static struct flash_info flash_types[] = {
 	  stfsm_n25q_config },
 	{ "n25q256", 0x20ba19, 0, 64 * 1024,  512,
 	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config },
+	{ "n25q512", 0x20ba20, 0, 64 * 1024,  1024,
+	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config},
 
 	/*
 	 * Spansion S25FLxxxP
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 04/10] mtd: st_spi_fsm: Add support for N25Q512 and N25Q00A devices
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:24   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Angus Clark, Carmelo Amoroso, Lee Jones

From: Angus Clark <angus.clark@st.com>

This patch adds support for the Micron N25Q512 and N25Q00A Serial Flash devices.
Unlike previous Micron devices, it is now mandatory to check the Flags Status
Register following a Write or Erase operation.  The N25Q512A device presents a
further complication in that different variants of the device use different
opcodes for the WRITE_1_4_4 operation.  Since there is no easy way to determine
at runtime which variant is being used, FLASH_CAPS_WRITE_1_4_4 support is
removed for N25Q512 devices, resulting in WRITE_1_1_4 being used instead.

The following devices have been tested:

    b2000C + N25Q512A13GSF40G
    b2000C + N25Q00AA13GSF40G
    b2147A + N25Q512A83GSF40X

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 96 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 91 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 67ea35e..d48004d 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -225,12 +225,25 @@
 #define S25FL_STATUS_E_ERR     0x20
 #define S25FL_STATUS_P_ERR     0x40
 
+/* N25Q - READ/WRITE/CLEAR NON/VOLATILE STATUS/CONFIG Registers */
+#define N25Q_CMD_RFSR          0x70
+#define N25Q_CMD_CLFSR         0x50
 #define N25Q_CMD_WRVCR         0x81
 #define N25Q_CMD_RDVCR         0x85
 #define N25Q_CMD_RDVECR        0x65
 #define N25Q_CMD_RDNVCR        0xb5
 #define N25Q_CMD_WRNVCR        0xb1
 
+/* N25Q Flags Status Register: Error Flags */
+#define N25Q_FLAGS_ERR_ERASE   BIT(5)
+#define N25Q_FLAGS_ERR_PROG    BIT(4)
+#define N25Q_FLAGS_ERR_VPP     BIT(3)
+#define N25Q_FLAGS_ERR_PROT    BIT(1)
+#define N25Q_FLAGS_ERROR       (N25Q_FLAGS_ERR_ERASE   | \
+                                N25Q_FLAGS_ERR_PROG    | \
+                                N25Q_FLAGS_ERR_VPP     | \
+                                N25Q_FLAGS_ERR_PROT)
+
 #define FLASH_PAGESIZE         256			/* In Bytes    */
 #define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
 #define FLASH_MAX_BUSY_WAIT    (300 * HZ)	/* Maximum 'CHIPERASE' time */
@@ -242,6 +255,7 @@
 #define CFG_WRITE_TOGGLE_32BIT_ADDR    0x00000002
 #define CFG_ERASESEC_TOGGLE_32BIT_ADDR 0x00000008
 #define CFG_S25FL_CHECK_ERROR_FLAGS    0x00000010
+#define CFG_N25Q_CHECK_ERROR_FLAGS     0x00000020
 
 struct stfsm_seq {
 	uint32_t data_size;
@@ -360,6 +374,7 @@ static struct flash_info flash_types[] = {
 	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
 	  stfsm_mx25_config},
 
+	/* Micron N25Qxxx */
 #define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
 		   FLASH_FLAG_READ_FAST         |	\
 		   FLASH_FLAG_READ_1_1_2        |	\
@@ -372,10 +387,29 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_WRITE_1_4_4)
 	{ "n25q128", 0x20ba18, 0, 64 * 1024,  256, N25Q_FLAG, 108,
 	  stfsm_n25q_config },
-	{ "n25q256", 0x20ba19, 0, 64 * 1024,  512,
-	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config },
-	{ "n25q512", 0x20ba20, 0, 64 * 1024,  1024,
-	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config},
+
+       /* Micron N25Q256/N25Q512/N25Q00A (32-bit ADDR devices)
+        *
+        * Versions are available with or without a dedicated RESET# pin
+        * (e.g. N25Q512A83GSF40G vs. N25Q512A13GSF40G).  To complicate matters,
+        * the versions that include a RESET# pin (Feature Set = 8) require a
+        * different opcode for the FLASH_CMD_WRITE_1_4_4 command.
+        * Unfortunately it is not possible to determine easily at run-time
+        * which version is being used.  We therefore remove support for
+        * FLASH_FLAG_WRITE_1_4_4 (falling back to FLASH_FLAG_WRITE_1_1_4), and
+        * defer overall support for RESET# to the board-level platform/Device
+        * Tree property "reset-signal".
+        */
+#define N25Q_32BIT_ADDR_FLAG  ((N25Q_FLAG              |	\
+				FLASH_FLAG_32BIT_ADDR  |	\
+				FLASH_FLAG_RESET)      &	\
+			       ~FLASH_FLAG_WRITE_1_4_4)
+	{ "n25q256", 0x20ba19,      0, 64 * 1024,   512,
+	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
+	{ "n25q512", 0x20ba20, 0x1000, 64 * 1024,  1024,
+	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
+	{ "n25q00a", 0x20ba21, 0x1000, 64 * 1024,  2048,
+	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
 
 	/*
 	 * Spansion S25FLxxxP
@@ -854,6 +888,30 @@ static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf,
 	return size;
 }
 
+static int n25q_clear_flags(struct stfsm *fsm)
+{
+	struct stfsm_seq seq = {
+		.seq_opc[0] = (SEQ_OPC_PADS_1 |
+			       SEQ_OPC_CYCLES(8) |
+			       SEQ_OPC_OPCODE(N25Q_CMD_CLFSR) |
+			       SEQ_OPC_CSDEASSERT),
+		.seq = {
+			STFSM_INST_CMD1,
+			STFSM_INST_STOP,
+		},
+		.seq_cfg = (SEQ_CFG_PADS_1 |
+			    SEQ_CFG_READNOTWRITE |
+			    SEQ_CFG_CSDEASSERT |
+			    SEQ_CFG_STARTSEQ),
+	};
+
+	stfsm_load_seq(fsm, &seq);
+
+	stfsm_wait_seq(fsm);
+
+	return 0;
+}
+
 static int stfsm_enter_32bit_addr(struct stfsm *fsm, int enter)
 {
 	struct stfsm_seq *seq = &fsm->stfsm_seq_en_32bit_addr;
@@ -1214,10 +1272,18 @@ static int stfsm_mx25_config(struct stfsm *fsm)
 static int stfsm_n25q_config(struct stfsm *fsm)
 {
 	uint32_t flags = fsm->info->flags;
-	uint8_t vcr;
+	uint8_t vcr, sta;
 	int ret = 0;
 	bool soc_reset;
 
+	/*
+	 * Check/Clear Error Flags
+	 */
+	fsm->configuration |= CFG_N25Q_CHECK_ERROR_FLAGS;
+	stfsm_read_status(fsm, N25Q_CMD_RFSR, &sta, 1);
+	if (sta & N25Q_FLAGS_ERROR)
+		n25q_clear_flags(fsm);
+
 	/* Configure 'READ' sequence */
 	if (flags & FLASH_FLAG_32BIT_ADDR)
 		ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
@@ -1592,6 +1658,7 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 	uint32_t page_buf[FLASH_PAGESIZE_32];
 	uint8_t *t = (uint8_t *)&tmp;
 	const uint8_t *p;
+	uint8_t sta;
 	int ret;
 	int i;
 
@@ -1663,6 +1730,15 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
+	/* N25Q: Check/Clear Error Flags */
+	if (fsm->configuration & CFG_N25Q_CHECK_ERROR_FLAGS) {
+		stfsm_read_status(fsm, N25Q_CMD_RFSR, &sta, 1);
+		if (sta & N25Q_FLAGS_ERROR) {
+			n25q_clear_flags(fsm);
+			ret = -EPROTO;
+		}
+	}
+
 	/* Exit 32-bit address mode, if required */
 	if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR)
 		stfsm_enter_32bit_addr(fsm, 0);
@@ -1705,6 +1781,7 @@ static int stfsm_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
 static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
 {
 	struct stfsm_seq *seq = &stfsm_seq_erase_sector;
+	uint8_t sta;
 	int ret;
 
 	dev_dbg(fsm->dev, "erasing sector at 0x%08x\n", offset);
@@ -1725,6 +1802,15 @@ static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
+	/* N25Q: Check/Clear Error Flags */
+	if (fsm->configuration & CFG_N25Q_CHECK_ERROR_FLAGS) {
+		stfsm_read_status(fsm, N25Q_CMD_RFSR, &sta, 1);
+		if (sta & N25Q_FLAGS_ERROR) {
+			n25q_clear_flags(fsm);
+			ret = -EPROTO;
+		}
+	}
+
 	/* Exit 32-bit address mode, if required */
 	if (fsm->configuration & CFG_ERASESEC_TOGGLE_32BIT_ADDR)
 		stfsm_enter_32bit_addr(fsm, 0);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 04/10] mtd: st_spi_fsm: Add support for N25Q512 and N25Q00A devices
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Angus Clark, Lee Jones, computersforpeace, linux-mtd, Carmelo Amoroso

From: Angus Clark <angus.clark@st.com>

This patch adds support for the Micron N25Q512 and N25Q00A Serial Flash devices.
Unlike previous Micron devices, it is now mandatory to check the Flags Status
Register following a Write or Erase operation.  The N25Q512A device presents a
further complication in that different variants of the device use different
opcodes for the WRITE_1_4_4 operation.  Since there is no easy way to determine
at runtime which variant is being used, FLASH_CAPS_WRITE_1_4_4 support is
removed for N25Q512 devices, resulting in WRITE_1_1_4 being used instead.

The following devices have been tested:

    b2000C + N25Q512A13GSF40G
    b2000C + N25Q00AA13GSF40G
    b2147A + N25Q512A83GSF40X

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 96 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 91 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 67ea35e..d48004d 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -225,12 +225,25 @@
 #define S25FL_STATUS_E_ERR     0x20
 #define S25FL_STATUS_P_ERR     0x40
 
+/* N25Q - READ/WRITE/CLEAR NON/VOLATILE STATUS/CONFIG Registers */
+#define N25Q_CMD_RFSR          0x70
+#define N25Q_CMD_CLFSR         0x50
 #define N25Q_CMD_WRVCR         0x81
 #define N25Q_CMD_RDVCR         0x85
 #define N25Q_CMD_RDVECR        0x65
 #define N25Q_CMD_RDNVCR        0xb5
 #define N25Q_CMD_WRNVCR        0xb1
 
+/* N25Q Flags Status Register: Error Flags */
+#define N25Q_FLAGS_ERR_ERASE   BIT(5)
+#define N25Q_FLAGS_ERR_PROG    BIT(4)
+#define N25Q_FLAGS_ERR_VPP     BIT(3)
+#define N25Q_FLAGS_ERR_PROT    BIT(1)
+#define N25Q_FLAGS_ERROR       (N25Q_FLAGS_ERR_ERASE   | \
+                                N25Q_FLAGS_ERR_PROG    | \
+                                N25Q_FLAGS_ERR_VPP     | \
+                                N25Q_FLAGS_ERR_PROT)
+
 #define FLASH_PAGESIZE         256			/* In Bytes    */
 #define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
 #define FLASH_MAX_BUSY_WAIT    (300 * HZ)	/* Maximum 'CHIPERASE' time */
@@ -242,6 +255,7 @@
 #define CFG_WRITE_TOGGLE_32BIT_ADDR    0x00000002
 #define CFG_ERASESEC_TOGGLE_32BIT_ADDR 0x00000008
 #define CFG_S25FL_CHECK_ERROR_FLAGS    0x00000010
+#define CFG_N25Q_CHECK_ERROR_FLAGS     0x00000020
 
 struct stfsm_seq {
 	uint32_t data_size;
@@ -360,6 +374,7 @@ static struct flash_info flash_types[] = {
 	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
 	  stfsm_mx25_config},
 
+	/* Micron N25Qxxx */
 #define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
 		   FLASH_FLAG_READ_FAST         |	\
 		   FLASH_FLAG_READ_1_1_2        |	\
@@ -372,10 +387,29 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_WRITE_1_4_4)
 	{ "n25q128", 0x20ba18, 0, 64 * 1024,  256, N25Q_FLAG, 108,
 	  stfsm_n25q_config },
-	{ "n25q256", 0x20ba19, 0, 64 * 1024,  512,
-	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config },
-	{ "n25q512", 0x20ba20, 0, 64 * 1024,  1024,
-	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config},
+
+       /* Micron N25Q256/N25Q512/N25Q00A (32-bit ADDR devices)
+        *
+        * Versions are available with or without a dedicated RESET# pin
+        * (e.g. N25Q512A83GSF40G vs. N25Q512A13GSF40G).  To complicate matters,
+        * the versions that include a RESET# pin (Feature Set = 8) require a
+        * different opcode for the FLASH_CMD_WRITE_1_4_4 command.
+        * Unfortunately it is not possible to determine easily at run-time
+        * which version is being used.  We therefore remove support for
+        * FLASH_FLAG_WRITE_1_4_4 (falling back to FLASH_FLAG_WRITE_1_1_4), and
+        * defer overall support for RESET# to the board-level platform/Device
+        * Tree property "reset-signal".
+        */
+#define N25Q_32BIT_ADDR_FLAG  ((N25Q_FLAG              |	\
+				FLASH_FLAG_32BIT_ADDR  |	\
+				FLASH_FLAG_RESET)      &	\
+			       ~FLASH_FLAG_WRITE_1_4_4)
+	{ "n25q256", 0x20ba19,      0, 64 * 1024,   512,
+	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
+	{ "n25q512", 0x20ba20, 0x1000, 64 * 1024,  1024,
+	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
+	{ "n25q00a", 0x20ba21, 0x1000, 64 * 1024,  2048,
+	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
 
 	/*
 	 * Spansion S25FLxxxP
@@ -854,6 +888,30 @@ static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf,
 	return size;
 }
 
+static int n25q_clear_flags(struct stfsm *fsm)
+{
+	struct stfsm_seq seq = {
+		.seq_opc[0] = (SEQ_OPC_PADS_1 |
+			       SEQ_OPC_CYCLES(8) |
+			       SEQ_OPC_OPCODE(N25Q_CMD_CLFSR) |
+			       SEQ_OPC_CSDEASSERT),
+		.seq = {
+			STFSM_INST_CMD1,
+			STFSM_INST_STOP,
+		},
+		.seq_cfg = (SEQ_CFG_PADS_1 |
+			    SEQ_CFG_READNOTWRITE |
+			    SEQ_CFG_CSDEASSERT |
+			    SEQ_CFG_STARTSEQ),
+	};
+
+	stfsm_load_seq(fsm, &seq);
+
+	stfsm_wait_seq(fsm);
+
+	return 0;
+}
+
 static int stfsm_enter_32bit_addr(struct stfsm *fsm, int enter)
 {
 	struct stfsm_seq *seq = &fsm->stfsm_seq_en_32bit_addr;
@@ -1214,10 +1272,18 @@ static int stfsm_mx25_config(struct stfsm *fsm)
 static int stfsm_n25q_config(struct stfsm *fsm)
 {
 	uint32_t flags = fsm->info->flags;
-	uint8_t vcr;
+	uint8_t vcr, sta;
 	int ret = 0;
 	bool soc_reset;
 
+	/*
+	 * Check/Clear Error Flags
+	 */
+	fsm->configuration |= CFG_N25Q_CHECK_ERROR_FLAGS;
+	stfsm_read_status(fsm, N25Q_CMD_RFSR, &sta, 1);
+	if (sta & N25Q_FLAGS_ERROR)
+		n25q_clear_flags(fsm);
+
 	/* Configure 'READ' sequence */
 	if (flags & FLASH_FLAG_32BIT_ADDR)
 		ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
@@ -1592,6 +1658,7 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 	uint32_t page_buf[FLASH_PAGESIZE_32];
 	uint8_t *t = (uint8_t *)&tmp;
 	const uint8_t *p;
+	uint8_t sta;
 	int ret;
 	int i;
 
@@ -1663,6 +1730,15 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
+	/* N25Q: Check/Clear Error Flags */
+	if (fsm->configuration & CFG_N25Q_CHECK_ERROR_FLAGS) {
+		stfsm_read_status(fsm, N25Q_CMD_RFSR, &sta, 1);
+		if (sta & N25Q_FLAGS_ERROR) {
+			n25q_clear_flags(fsm);
+			ret = -EPROTO;
+		}
+	}
+
 	/* Exit 32-bit address mode, if required */
 	if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR)
 		stfsm_enter_32bit_addr(fsm, 0);
@@ -1705,6 +1781,7 @@ static int stfsm_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
 static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
 {
 	struct stfsm_seq *seq = &stfsm_seq_erase_sector;
+	uint8_t sta;
 	int ret;
 
 	dev_dbg(fsm->dev, "erasing sector at 0x%08x\n", offset);
@@ -1725,6 +1802,15 @@ static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
+	/* N25Q: Check/Clear Error Flags */
+	if (fsm->configuration & CFG_N25Q_CHECK_ERROR_FLAGS) {
+		stfsm_read_status(fsm, N25Q_CMD_RFSR, &sta, 1);
+		if (sta & N25Q_FLAGS_ERROR) {
+			n25q_clear_flags(fsm);
+			ret = -EPROTO;
+		}
+	}
+
 	/* Exit 32-bit address mode, if required */
 	if (fsm->configuration & CFG_ERASESEC_TOGGLE_32BIT_ADDR)
 		stfsm_enter_32bit_addr(fsm, 0);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 04/10] mtd: st_spi_fsm: Add support for N25Q512 and N25Q00A devices
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Angus Clark <angus.clark@st.com>

This patch adds support for the Micron N25Q512 and N25Q00A Serial Flash devices.
Unlike previous Micron devices, it is now mandatory to check the Flags Status
Register following a Write or Erase operation.  The N25Q512A device presents a
further complication in that different variants of the device use different
opcodes for the WRITE_1_4_4 operation.  Since there is no easy way to determine
at runtime which variant is being used, FLASH_CAPS_WRITE_1_4_4 support is
removed for N25Q512 devices, resulting in WRITE_1_1_4 being used instead.

The following devices have been tested:

    b2000C + N25Q512A13GSF40G
    b2000C + N25Q00AA13GSF40G
    b2147A + N25Q512A83GSF40X

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 96 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 91 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 67ea35e..d48004d 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -225,12 +225,25 @@
 #define S25FL_STATUS_E_ERR     0x20
 #define S25FL_STATUS_P_ERR     0x40
 
+/* N25Q - READ/WRITE/CLEAR NON/VOLATILE STATUS/CONFIG Registers */
+#define N25Q_CMD_RFSR          0x70
+#define N25Q_CMD_CLFSR         0x50
 #define N25Q_CMD_WRVCR         0x81
 #define N25Q_CMD_RDVCR         0x85
 #define N25Q_CMD_RDVECR        0x65
 #define N25Q_CMD_RDNVCR        0xb5
 #define N25Q_CMD_WRNVCR        0xb1
 
+/* N25Q Flags Status Register: Error Flags */
+#define N25Q_FLAGS_ERR_ERASE   BIT(5)
+#define N25Q_FLAGS_ERR_PROG    BIT(4)
+#define N25Q_FLAGS_ERR_VPP     BIT(3)
+#define N25Q_FLAGS_ERR_PROT    BIT(1)
+#define N25Q_FLAGS_ERROR       (N25Q_FLAGS_ERR_ERASE   | \
+                                N25Q_FLAGS_ERR_PROG    | \
+                                N25Q_FLAGS_ERR_VPP     | \
+                                N25Q_FLAGS_ERR_PROT)
+
 #define FLASH_PAGESIZE         256			/* In Bytes    */
 #define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
 #define FLASH_MAX_BUSY_WAIT    (300 * HZ)	/* Maximum 'CHIPERASE' time */
@@ -242,6 +255,7 @@
 #define CFG_WRITE_TOGGLE_32BIT_ADDR    0x00000002
 #define CFG_ERASESEC_TOGGLE_32BIT_ADDR 0x00000008
 #define CFG_S25FL_CHECK_ERROR_FLAGS    0x00000010
+#define CFG_N25Q_CHECK_ERROR_FLAGS     0x00000020
 
 struct stfsm_seq {
 	uint32_t data_size;
@@ -360,6 +374,7 @@ static struct flash_info flash_types[] = {
 	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
 	  stfsm_mx25_config},
 
+	/* Micron N25Qxxx */
 #define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
 		   FLASH_FLAG_READ_FAST         |	\
 		   FLASH_FLAG_READ_1_1_2        |	\
@@ -372,10 +387,29 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_WRITE_1_4_4)
 	{ "n25q128", 0x20ba18, 0, 64 * 1024,  256, N25Q_FLAG, 108,
 	  stfsm_n25q_config },
-	{ "n25q256", 0x20ba19, 0, 64 * 1024,  512,
-	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config },
-	{ "n25q512", 0x20ba20, 0, 64 * 1024,  1024,
-	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config},
+
+       /* Micron N25Q256/N25Q512/N25Q00A (32-bit ADDR devices)
+        *
+        * Versions are available with or without a dedicated RESET# pin
+        * (e.g. N25Q512A83GSF40G vs. N25Q512A13GSF40G).  To complicate matters,
+        * the versions that include a RESET# pin (Feature Set = 8) require a
+        * different opcode for the FLASH_CMD_WRITE_1_4_4 command.
+        * Unfortunately it is not possible to determine easily at run-time
+        * which version is being used.  We therefore remove support for
+        * FLASH_FLAG_WRITE_1_4_4 (falling back to FLASH_FLAG_WRITE_1_1_4), and
+        * defer overall support for RESET# to the board-level platform/Device
+        * Tree property "reset-signal".
+        */
+#define N25Q_32BIT_ADDR_FLAG  ((N25Q_FLAG              |	\
+				FLASH_FLAG_32BIT_ADDR  |	\
+				FLASH_FLAG_RESET)      &	\
+			       ~FLASH_FLAG_WRITE_1_4_4)
+	{ "n25q256", 0x20ba19,      0, 64 * 1024,   512,
+	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
+	{ "n25q512", 0x20ba20, 0x1000, 64 * 1024,  1024,
+	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
+	{ "n25q00a", 0x20ba21, 0x1000, 64 * 1024,  2048,
+	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
 
 	/*
 	 * Spansion S25FLxxxP
@@ -854,6 +888,30 @@ static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf,
 	return size;
 }
 
+static int n25q_clear_flags(struct stfsm *fsm)
+{
+	struct stfsm_seq seq = {
+		.seq_opc[0] = (SEQ_OPC_PADS_1 |
+			       SEQ_OPC_CYCLES(8) |
+			       SEQ_OPC_OPCODE(N25Q_CMD_CLFSR) |
+			       SEQ_OPC_CSDEASSERT),
+		.seq = {
+			STFSM_INST_CMD1,
+			STFSM_INST_STOP,
+		},
+		.seq_cfg = (SEQ_CFG_PADS_1 |
+			    SEQ_CFG_READNOTWRITE |
+			    SEQ_CFG_CSDEASSERT |
+			    SEQ_CFG_STARTSEQ),
+	};
+
+	stfsm_load_seq(fsm, &seq);
+
+	stfsm_wait_seq(fsm);
+
+	return 0;
+}
+
 static int stfsm_enter_32bit_addr(struct stfsm *fsm, int enter)
 {
 	struct stfsm_seq *seq = &fsm->stfsm_seq_en_32bit_addr;
@@ -1214,10 +1272,18 @@ static int stfsm_mx25_config(struct stfsm *fsm)
 static int stfsm_n25q_config(struct stfsm *fsm)
 {
 	uint32_t flags = fsm->info->flags;
-	uint8_t vcr;
+	uint8_t vcr, sta;
 	int ret = 0;
 	bool soc_reset;
 
+	/*
+	 * Check/Clear Error Flags
+	 */
+	fsm->configuration |= CFG_N25Q_CHECK_ERROR_FLAGS;
+	stfsm_read_status(fsm, N25Q_CMD_RFSR, &sta, 1);
+	if (sta & N25Q_FLAGS_ERROR)
+		n25q_clear_flags(fsm);
+
 	/* Configure 'READ' sequence */
 	if (flags & FLASH_FLAG_32BIT_ADDR)
 		ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
@@ -1592,6 +1658,7 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 	uint32_t page_buf[FLASH_PAGESIZE_32];
 	uint8_t *t = (uint8_t *)&tmp;
 	const uint8_t *p;
+	uint8_t sta;
 	int ret;
 	int i;
 
@@ -1663,6 +1730,15 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
+	/* N25Q: Check/Clear Error Flags */
+	if (fsm->configuration & CFG_N25Q_CHECK_ERROR_FLAGS) {
+		stfsm_read_status(fsm, N25Q_CMD_RFSR, &sta, 1);
+		if (sta & N25Q_FLAGS_ERROR) {
+			n25q_clear_flags(fsm);
+			ret = -EPROTO;
+		}
+	}
+
 	/* Exit 32-bit address mode, if required */
 	if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR)
 		stfsm_enter_32bit_addr(fsm, 0);
@@ -1705,6 +1781,7 @@ static int stfsm_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
 static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
 {
 	struct stfsm_seq *seq = &stfsm_seq_erase_sector;
+	uint8_t sta;
 	int ret;
 
 	dev_dbg(fsm->dev, "erasing sector at 0x%08x\n", offset);
@@ -1725,6 +1802,15 @@ static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
+	/* N25Q: Check/Clear Error Flags */
+	if (fsm->configuration & CFG_N25Q_CHECK_ERROR_FLAGS) {
+		stfsm_read_status(fsm, N25Q_CMD_RFSR, &sta, 1);
+		if (sta & N25Q_FLAGS_ERROR) {
+			n25q_clear_flags(fsm);
+			ret = -EPROTO;
+		}
+	}
+
 	/* Exit 32-bit address mode, if required */
 	if (fsm->configuration & CFG_ERASESEC_TOGGLE_32BIT_ADDR)
 		stfsm_enter_32bit_addr(fsm, 0);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 05/10] mtd: st_spi_fsm: Update the JEDEC probe to handle extended READIDs
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:24   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Angus Clark, Carmelo Amoroso, Lee Jones

From: Angus Clark <angus.clark@st.com>

The previous code was based on 3-byte JEDEC IDs, with a possible 2-byte
extension.  However, devices are now emerging that return 6 or more bytes of
READID data and the additional bytes are required to differentiate between
variants or generations of similar devices.

This patch refactors the device table and JEDEC probe code to handle arbitrary
length READIDs, with the standard JEDEC definition now becoming a special case.
Functionally, there should be no change in behaviour.  A subsequent patch will
update the table with extended READIDs where applicable.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 209 ++++++++++++++++++++++-----------------
 1 file changed, 121 insertions(+), 88 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index d48004d..3409651 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -21,6 +21,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/spi-nor.h>
 #include <linux/sched.h>
+#include <linux/sort.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
@@ -221,6 +222,11 @@
 #define FLASH_STATUS_BP2       0x10
 #define FLASH_STATUS_SRWP0     0x80
 #define FLASH_STATUS_TIMEOUT   0xff
+
+/* Maximum READID length */
+#define MAX_READID_LEN         6
+#define MAX_READID_LEN_ALIGNED ALIGN(MAX_READID_LEN, 4)
+
 /* S25FL Error Flags */
 #define S25FL_STATUS_E_ERR     0x20
 #define S25FL_STATUS_P_ERR     0x40
@@ -305,13 +311,9 @@ struct seq_rw_config {
 /* SPI Flash Device Table */
 struct flash_info {
 	char            *name;
-	/*
-	 * JEDEC id zero means "no ID" (most older chips); otherwise it has
-	 * a high byte of zero plus three data bytes: the manufacturer id,
-	 * then a two byte device id.
-	 */
-	u32             jedec_id;
-	u16             ext_id;
+	/* READID data, as returned by 'FLASH_CMD_RDID' (0x9f). */
+	u8              readid[MAX_READID_LEN];
+	int             readid_len;
 	/*
 	 * The size listed here is what works with SPINOR_OP_SE, which isn't
 	 * necessarily called a "sector" by the vendor.
@@ -327,6 +329,38 @@ struct flash_info {
 	int             (*config)(struct stfsm *);
 };
 
+/* Device with standard 3-byte JEDEC ID */
+#define JEDEC_INFO(_name, _jedec_id, _sector_size, _n_sectors,	\
+		   _flags, _max_freq, _config)			\
+	{							\
+		.name = (_name),				\
+		.readid[0] = ((_jedec_id) >> 16 & 0xff),	\
+		.readid[1] = ((_jedec_id) >>  8 & 0xff),	\
+		.readid[2] = ((_jedec_id) >>  0 & 0xff),	\
+		.readid_len = 3,				\
+		.sector_size = (_sector_size),			\
+		.n_sectors = (_n_sectors),			\
+		.flags = (_flags),				\
+		.max_freq = (_max_freq),			\
+		.config = (_config)				\
+	}
+
+/* Device with arbitrary-length READID */
+#define RDID(...) __VA_ARGS__  /* Dummy macro to protect array argument. */
+#define RDID_INFO(_name, _readid, _readid_len, _sector_size,	\
+		  _n_sectors, _flags, _max_freq, _config)	\
+	{							\
+		.name = (_name),				\
+		.readid = _readid,				\
+		.readid_len = _readid_len,			\
+		.flags = (_flags),				\
+		.sector_size = (_sector_size),			\
+		.n_sectors = (_n_sectors),			\
+		.flags = (_flags),				\
+		.max_freq = (_max_freq),			\
+		.config = (_config)				\
+	}
+
 static int stfsm_n25q_config(struct stfsm *fsm);
 static int stfsm_mx25_config(struct stfsm *fsm);
 static int stfsm_s25fl_config(struct stfsm *fsm);
@@ -339,19 +373,19 @@ static struct flash_info flash_types[] = {
 	 * (eg faster operating frequency)
 	 */
 #define M25P_FLAG (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST)
-	{ "m25p40",  0x202013, 0,  64 * 1024,   8, M25P_FLAG, 25, NULL },
-	{ "m25p80",  0x202014, 0,  64 * 1024,  16, M25P_FLAG, 25, NULL },
-	{ "m25p16",  0x202015, 0,  64 * 1024,  32, M25P_FLAG, 25, NULL },
-	{ "m25p32",  0x202016, 0,  64 * 1024,  64, M25P_FLAG, 50, NULL },
-	{ "m25p64",  0x202017, 0,  64 * 1024, 128, M25P_FLAG, 50, NULL },
-	{ "m25p128", 0x202018, 0, 256 * 1024,  64, M25P_FLAG, 50, NULL },
+	JEDEC_INFO("m25p40",  0x202013,  64 * 1024,   8, M25P_FLAG, 25, NULL),
+	JEDEC_INFO("m25p80",  0x202014,  64 * 1024,  16, M25P_FLAG, 25, NULL),
+	JEDEC_INFO("m25p16",  0x202015,  64 * 1024,  32, M25P_FLAG, 25, NULL),
+	JEDEC_INFO("m25p32",  0x202016,  64 * 1024,  64, M25P_FLAG, 50, NULL),
+	JEDEC_INFO("m25p64",  0x202017,  64 * 1024, 128, M25P_FLAG, 50, NULL),
+	JEDEC_INFO("m25p128", 0x202018, 256 * 1024,  64, M25P_FLAG, 50, NULL),
 
 #define M25PX_FLAG (FLASH_FLAG_READ_WRITE      |	\
 		    FLASH_FLAG_READ_FAST        |	\
 		    FLASH_FLAG_READ_1_1_2       |	\
 		    FLASH_FLAG_WRITE_1_1_2)
-	{ "m25px32", 0x207116, 0,  64 * 1024,  64, M25PX_FLAG, 75, NULL },
-	{ "m25px64", 0x207117, 0,  64 * 1024, 128, M25PX_FLAG, 75, NULL },
+	JEDEC_INFO("m25px32", 0x207116,  64 * 1024,  64, M25PX_FLAG, 75, NULL),
+	JEDEC_INFO("m25px64", 0x207117,  64 * 1024, 128, M25PX_FLAG, 75, NULL),
 
 	/* Macronix MX25xxx
 	 *     - Support for 'FLASH_FLAG_WRITE_1_4_4' is omitted for devices
@@ -364,15 +398,12 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_READ_1_1_4        |	\
 		   FLASH_FLAG_SE_4K             |	\
 		   FLASH_FLAG_SE_32K)
-	{ "mx25l3255e",  0xc29e16, 0, 64 * 1024, 64,
-	  (MX25_FLAG | FLASH_FLAG_WRITE_1_4_4), 86,
-	  stfsm_mx25_config},
-	{ "mx25l25635e", 0xc22019, 0, 64*1024, 512,
-	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
-	  stfsm_mx25_config },
-	{ "mx25l25655e", 0xc22619, 0, 64*1024, 512,
-	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
-	  stfsm_mx25_config},
+	JEDEC_INFO("mx25l3255e",  0xc29e16, 64 * 1024, 64,
+		   (MX25_FLAG | FLASH_FLAG_WRITE_1_4_4), 86, stfsm_mx25_config),
+	JEDEC_INFO("mx25l25635e", 0xc22019, 64 * 1024, 512,
+		   (MX25_FLAG | FLASH_FLAG_RESET), 70, stfsm_mx25_config),
+	JEDEC_INFO("mx25l25655e", 0xc22619, 64 * 1024, 512,
+		   (MX25_FLAG | FLASH_FLAG_RESET), 70, stfsm_mx25_config),
 
 	/* Micron N25Qxxx */
 #define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
@@ -385,8 +416,8 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_WRITE_1_2_2       |	\
 		   FLASH_FLAG_WRITE_1_1_4       |	\
 		   FLASH_FLAG_WRITE_1_4_4)
-	{ "n25q128", 0x20ba18, 0, 64 * 1024,  256, N25Q_FLAG, 108,
-	  stfsm_n25q_config },
+	JEDEC_INFO("n25q128", 0x20ba18, 64 * 1024,  256,
+		   N25Q_FLAG, 108, stfsm_n25q_config),
 
        /* Micron N25Q256/N25Q512/N25Q00A (32-bit ADDR devices)
         *
@@ -404,12 +435,12 @@ static struct flash_info flash_types[] = {
 				FLASH_FLAG_32BIT_ADDR  |	\
 				FLASH_FLAG_RESET)      &	\
 			       ~FLASH_FLAG_WRITE_1_4_4)
-	{ "n25q256", 0x20ba19,      0, 64 * 1024,   512,
-	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
-	{ "n25q512", 0x20ba20, 0x1000, 64 * 1024,  1024,
-	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
-	{ "n25q00a", 0x20ba21, 0x1000, 64 * 1024,  2048,
-	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
+	JEDEC_INFO("n25q256", 0x20ba19, 64 * 1024,   512,
+		   N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
+	RDID_INFO("n25q512", RDID({0x20, 0xba, 0x20, 0x10, 0x00}), 5, 64 * 1024,
+		  1024, N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
+	RDID_INFO("n25q00a", RDID({0x20, 0xba, 0x21, 0x10, 0x00}), 5, 64 * 1024,
+		  2048, N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
 
 	/*
 	 * Spansion S25FLxxxP
@@ -422,12 +453,12 @@ static struct flash_info flash_types[] = {
 			FLASH_FLAG_READ_1_4_4   |	\
 			FLASH_FLAG_WRITE_1_1_4  |	\
 			FLASH_FLAG_READ_FAST)
-	{ "s25fl032p",  0x010215, 0x4d00,  64 * 1024,  64, S25FLXXXP_FLAG, 80,
-	  stfsm_s25fl_config},
-	{ "s25fl129p0", 0x012018, 0x4d00, 256 * 1024,  64, S25FLXXXP_FLAG, 80,
-	  stfsm_s25fl_config },
-	{ "s25fl129p1", 0x012018, 0x4d01,  64 * 1024, 256, S25FLXXXP_FLAG, 80,
-	  stfsm_s25fl_config },
+	RDID_INFO("s25fl032p", RDID({0x01, 0x02, 0x15, 0x4d, 0x00}), 5,
+		  64 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl129p0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00}), 5,
+		  256 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl129p1", RDID({0x01, 0x20, 0x18, 0x4d, 0x01}), 5,
+		  64 * 1024, 256, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
 
 	/*
 	 * Spansion S25FLxxxS
@@ -441,25 +472,24 @@ static struct flash_info flash_types[] = {
 #define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
 			FLASH_FLAG_RESET        |	\
 			FLASH_FLAG_DYB_LOCKING)
-	{ "s25fl128s0", 0x012018, 0x0300,  256 * 1024, 64, S25FLXXXS_FLAG, 80,
-	  stfsm_s25fl_config },
-	{ "s25fl128s1", 0x012018, 0x0301,  64 * 1024, 256, S25FLXXXS_FLAG, 80,
-	  stfsm_s25fl_config },
-	{ "s25fl256s0", 0x010219, 0x4d00, 256 * 1024, 128,
-	  S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
-	{ "s25fl256s1", 0x010219, 0x4d01,  64 * 1024, 512,
-	  S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
-
-	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x03, 0x00}), 5,
+		  256 * 1024, 64, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl128s1", RDID({0x01, 0x20, 0x18, 0x03, 0x01}), 5,
+		  64 * 1024, 256, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl256s0", RDID({0x01, 0x02, 0x19, 0x4d, 0x00}), 5,
+		  256 * 1024, 128, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01}), 5,
+		  64 * 1024, 512, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+
 #define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
 		   FLASH_FLAG_READ_FAST         |	\
 		   FLASH_FLAG_READ_1_1_2        |	\
 		   FLASH_FLAG_WRITE_1_1_2)
-	{ "w25x40",  0xef3013, 0,  64 * 1024,   8, W25X_FLAG, 75, NULL },
-	{ "w25x80",  0xef3014, 0,  64 * 1024,  16, W25X_FLAG, 75, NULL },
-	{ "w25x16",  0xef3015, 0,  64 * 1024,  32, W25X_FLAG, 75, NULL },
-	{ "w25x32",  0xef3016, 0,  64 * 1024,  64, W25X_FLAG, 75, NULL },
-	{ "w25x64",  0xef3017, 0,  64 * 1024, 128, W25X_FLAG, 75, NULL },
+	JEDEC_INFO("w25x40", 0xef3013, 64 * 1024,   8, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x80", 0xef3014, 64 * 1024,  16, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x16", 0xef3015, 64 * 1024,  32, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x32", 0xef3016, 64 * 1024,  64, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x64", 0xef3017, 64 * 1024, 128, W25X_FLAG, 75, NULL),
 
 	/* Winbond -- w25q "blocks" are 64K, "sectors" are 4KiB */
 #define W25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
@@ -469,17 +499,16 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_READ_1_1_4        |	\
 		   FLASH_FLAG_READ_1_4_4        |	\
 		   FLASH_FLAG_WRITE_1_1_4)
-	{ "w25q80",  0xef4014, 0,  64 * 1024,  16, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-	{ "w25q16",  0xef4015, 0,  64 * 1024,  32, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-	{ "w25q32",  0xef4016, 0,  64 * 1024,  64, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-	{ "w25q64",  0xef4017, 0,  64 * 1024, 128, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-
-	/* Sentinel */
-	{ NULL, 0x000000, 0, 0, 0, 0, 0, NULL },
+	JEDEC_INFO("w25q80", 0xef4014, 64 * 1024,  16,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+	JEDEC_INFO("w25q16", 0xef4015, 64 * 1024,  32,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+	JEDEC_INFO("w25q32", 0xef4016, 64 * 1024,  64,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+	JEDEC_INFO("w25q64", 0xef4017, 64 * 1024, 128,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+
+	{ },
 };
 
 /*
@@ -610,7 +639,7 @@ static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
 #define W25Q_STATUS_QE			(0x1 << 1)
 
 static struct stfsm_seq stfsm_seq_read_jedec = {
-	.data_size = TRANSFER_SIZE(8),
+	.data_size = TRANSFER_SIZE(MAX_READID_LEN_ALIGNED),
 	.seq_opc[0] = (SEQ_OPC_PADS_1 |
 		       SEQ_OPC_CYCLES(8) |
 		       SEQ_OPC_OPCODE(SPINOR_OP_RDID)),
@@ -706,7 +735,7 @@ static const struct stfsm_seq stfsm_seq_load_fifo_byte = {
 	.data_size = TRANSFER_SIZE(1),
 	.seq_opc[0] = (SEQ_OPC_PADS_1 |
 		       SEQ_OPC_CYCLES(8) |
-		       SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
+		       SEQ_OPC_OPCODE(SPINOR_OP_RDID)),
 	.seq = {
 		STFSM_INST_CMD1,
 		STFSM_INST_DATA_READ,
@@ -1929,45 +1958,49 @@ out1:
 static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *jedec)
 {
 	const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
-	uint32_t tmp[2];
+	uint32_t tmp[MAX_READID_LEN_ALIGNED / 4];
 
 	stfsm_load_seq(fsm, seq);
 
-	stfsm_read_fifo(fsm, tmp, 8);
+	stfsm_read_fifo(fsm, tmp, MAX_READID_LEN_ALIGNED);
 
-	memcpy(jedec, tmp, 5);
+	memcpy(jedec, tmp, MAX_READID_LEN);
 
 	stfsm_wait_seq(fsm);
 }
 
+static int stfsm_cmp_flash_info_readid_len(const void *a, const void *b)
+{
+	return ((struct flash_info *)b)->readid_len -
+		((struct flash_info *)a)->readid_len;
+}
+
 static struct flash_info *stfsm_jedec_probe(struct stfsm *fsm)
 {
-	struct flash_info	*info;
-	u16                     ext_jedec;
-	u32			jedec;
-	u8			id[5];
+	uint8_t readid[MAX_READID_LEN];
+	char readid_str[MAX_READID_LEN * 3 + 1];
+	struct flash_info *info;
 
-	stfsm_read_jedec(fsm, id);
+	stfsm_read_jedec(fsm, readid);
 
-	jedec     = id[0] << 16 | id[1] << 8 | id[2];
-	/*
-	 * JEDEC also defines an optional "extended device information"
-	 * string for after vendor-specific data, after the three bytes
-	 * we use here. Supporting some chips might require using it.
-	 */
-	ext_jedec = id[3] << 8  | id[4];
+	hex_dump_to_buffer(readid, MAX_READID_LEN, 16, 1,
+			   readid_str, sizeof(readid_str), 0);
+
+	dev_dbg(fsm->dev, "READID = %s\n", readid_str);
 
-	dev_dbg(fsm->dev, "JEDEC =  0x%08x [%02x %02x %02x %02x %02x]\n",
-		jedec, id[0], id[1], id[2], id[3], id[4]);
+	/* The 'readid' may match multiple entries in the table.  To ensure we
+	 * retrieve the most specific match, the table is sorted in order of
+	 * 'readid_len'.
+	 */
+	sort(flash_types, ARRAY_SIZE(flash_types) - 1,
+	     sizeof(struct flash_info), stfsm_cmp_flash_info_readid_len, NULL);
 
 	for (info = flash_types; info->name; info++) {
-		if (info->jedec_id == jedec) {
-			if (info->ext_id && info->ext_id != ext_jedec)
-				continue;
+		if (memcmp(info->readid, readid, info->readid_len) == 0)
 			return info;
-		}
 	}
-	dev_err(fsm->dev, "Unrecognized JEDEC id %06x\n", jedec);
+
+	dev_err(fsm->dev, "Unrecognized READID [%s]\n", readid_str);
 
 	return NULL;
 }
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 05/10] mtd: st_spi_fsm: Update the JEDEC probe to handle extended READIDs
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Angus Clark, Lee Jones, computersforpeace, linux-mtd, Carmelo Amoroso

From: Angus Clark <angus.clark@st.com>

The previous code was based on 3-byte JEDEC IDs, with a possible 2-byte
extension.  However, devices are now emerging that return 6 or more bytes of
READID data and the additional bytes are required to differentiate between
variants or generations of similar devices.

This patch refactors the device table and JEDEC probe code to handle arbitrary
length READIDs, with the standard JEDEC definition now becoming a special case.
Functionally, there should be no change in behaviour.  A subsequent patch will
update the table with extended READIDs where applicable.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 209 ++++++++++++++++++++++-----------------
 1 file changed, 121 insertions(+), 88 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index d48004d..3409651 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -21,6 +21,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/spi-nor.h>
 #include <linux/sched.h>
+#include <linux/sort.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
@@ -221,6 +222,11 @@
 #define FLASH_STATUS_BP2       0x10
 #define FLASH_STATUS_SRWP0     0x80
 #define FLASH_STATUS_TIMEOUT   0xff
+
+/* Maximum READID length */
+#define MAX_READID_LEN         6
+#define MAX_READID_LEN_ALIGNED ALIGN(MAX_READID_LEN, 4)
+
 /* S25FL Error Flags */
 #define S25FL_STATUS_E_ERR     0x20
 #define S25FL_STATUS_P_ERR     0x40
@@ -305,13 +311,9 @@ struct seq_rw_config {
 /* SPI Flash Device Table */
 struct flash_info {
 	char            *name;
-	/*
-	 * JEDEC id zero means "no ID" (most older chips); otherwise it has
-	 * a high byte of zero plus three data bytes: the manufacturer id,
-	 * then a two byte device id.
-	 */
-	u32             jedec_id;
-	u16             ext_id;
+	/* READID data, as returned by 'FLASH_CMD_RDID' (0x9f). */
+	u8              readid[MAX_READID_LEN];
+	int             readid_len;
 	/*
 	 * The size listed here is what works with SPINOR_OP_SE, which isn't
 	 * necessarily called a "sector" by the vendor.
@@ -327,6 +329,38 @@ struct flash_info {
 	int             (*config)(struct stfsm *);
 };
 
+/* Device with standard 3-byte JEDEC ID */
+#define JEDEC_INFO(_name, _jedec_id, _sector_size, _n_sectors,	\
+		   _flags, _max_freq, _config)			\
+	{							\
+		.name = (_name),				\
+		.readid[0] = ((_jedec_id) >> 16 & 0xff),	\
+		.readid[1] = ((_jedec_id) >>  8 & 0xff),	\
+		.readid[2] = ((_jedec_id) >>  0 & 0xff),	\
+		.readid_len = 3,				\
+		.sector_size = (_sector_size),			\
+		.n_sectors = (_n_sectors),			\
+		.flags = (_flags),				\
+		.max_freq = (_max_freq),			\
+		.config = (_config)				\
+	}
+
+/* Device with arbitrary-length READID */
+#define RDID(...) __VA_ARGS__  /* Dummy macro to protect array argument. */
+#define RDID_INFO(_name, _readid, _readid_len, _sector_size,	\
+		  _n_sectors, _flags, _max_freq, _config)	\
+	{							\
+		.name = (_name),				\
+		.readid = _readid,				\
+		.readid_len = _readid_len,			\
+		.flags = (_flags),				\
+		.sector_size = (_sector_size),			\
+		.n_sectors = (_n_sectors),			\
+		.flags = (_flags),				\
+		.max_freq = (_max_freq),			\
+		.config = (_config)				\
+	}
+
 static int stfsm_n25q_config(struct stfsm *fsm);
 static int stfsm_mx25_config(struct stfsm *fsm);
 static int stfsm_s25fl_config(struct stfsm *fsm);
@@ -339,19 +373,19 @@ static struct flash_info flash_types[] = {
 	 * (eg faster operating frequency)
 	 */
 #define M25P_FLAG (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST)
-	{ "m25p40",  0x202013, 0,  64 * 1024,   8, M25P_FLAG, 25, NULL },
-	{ "m25p80",  0x202014, 0,  64 * 1024,  16, M25P_FLAG, 25, NULL },
-	{ "m25p16",  0x202015, 0,  64 * 1024,  32, M25P_FLAG, 25, NULL },
-	{ "m25p32",  0x202016, 0,  64 * 1024,  64, M25P_FLAG, 50, NULL },
-	{ "m25p64",  0x202017, 0,  64 * 1024, 128, M25P_FLAG, 50, NULL },
-	{ "m25p128", 0x202018, 0, 256 * 1024,  64, M25P_FLAG, 50, NULL },
+	JEDEC_INFO("m25p40",  0x202013,  64 * 1024,   8, M25P_FLAG, 25, NULL),
+	JEDEC_INFO("m25p80",  0x202014,  64 * 1024,  16, M25P_FLAG, 25, NULL),
+	JEDEC_INFO("m25p16",  0x202015,  64 * 1024,  32, M25P_FLAG, 25, NULL),
+	JEDEC_INFO("m25p32",  0x202016,  64 * 1024,  64, M25P_FLAG, 50, NULL),
+	JEDEC_INFO("m25p64",  0x202017,  64 * 1024, 128, M25P_FLAG, 50, NULL),
+	JEDEC_INFO("m25p128", 0x202018, 256 * 1024,  64, M25P_FLAG, 50, NULL),
 
 #define M25PX_FLAG (FLASH_FLAG_READ_WRITE      |	\
 		    FLASH_FLAG_READ_FAST        |	\
 		    FLASH_FLAG_READ_1_1_2       |	\
 		    FLASH_FLAG_WRITE_1_1_2)
-	{ "m25px32", 0x207116, 0,  64 * 1024,  64, M25PX_FLAG, 75, NULL },
-	{ "m25px64", 0x207117, 0,  64 * 1024, 128, M25PX_FLAG, 75, NULL },
+	JEDEC_INFO("m25px32", 0x207116,  64 * 1024,  64, M25PX_FLAG, 75, NULL),
+	JEDEC_INFO("m25px64", 0x207117,  64 * 1024, 128, M25PX_FLAG, 75, NULL),
 
 	/* Macronix MX25xxx
 	 *     - Support for 'FLASH_FLAG_WRITE_1_4_4' is omitted for devices
@@ -364,15 +398,12 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_READ_1_1_4        |	\
 		   FLASH_FLAG_SE_4K             |	\
 		   FLASH_FLAG_SE_32K)
-	{ "mx25l3255e",  0xc29e16, 0, 64 * 1024, 64,
-	  (MX25_FLAG | FLASH_FLAG_WRITE_1_4_4), 86,
-	  stfsm_mx25_config},
-	{ "mx25l25635e", 0xc22019, 0, 64*1024, 512,
-	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
-	  stfsm_mx25_config },
-	{ "mx25l25655e", 0xc22619, 0, 64*1024, 512,
-	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
-	  stfsm_mx25_config},
+	JEDEC_INFO("mx25l3255e",  0xc29e16, 64 * 1024, 64,
+		   (MX25_FLAG | FLASH_FLAG_WRITE_1_4_4), 86, stfsm_mx25_config),
+	JEDEC_INFO("mx25l25635e", 0xc22019, 64 * 1024, 512,
+		   (MX25_FLAG | FLASH_FLAG_RESET), 70, stfsm_mx25_config),
+	JEDEC_INFO("mx25l25655e", 0xc22619, 64 * 1024, 512,
+		   (MX25_FLAG | FLASH_FLAG_RESET), 70, stfsm_mx25_config),
 
 	/* Micron N25Qxxx */
 #define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
@@ -385,8 +416,8 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_WRITE_1_2_2       |	\
 		   FLASH_FLAG_WRITE_1_1_4       |	\
 		   FLASH_FLAG_WRITE_1_4_4)
-	{ "n25q128", 0x20ba18, 0, 64 * 1024,  256, N25Q_FLAG, 108,
-	  stfsm_n25q_config },
+	JEDEC_INFO("n25q128", 0x20ba18, 64 * 1024,  256,
+		   N25Q_FLAG, 108, stfsm_n25q_config),
 
        /* Micron N25Q256/N25Q512/N25Q00A (32-bit ADDR devices)
         *
@@ -404,12 +435,12 @@ static struct flash_info flash_types[] = {
 				FLASH_FLAG_32BIT_ADDR  |	\
 				FLASH_FLAG_RESET)      &	\
 			       ~FLASH_FLAG_WRITE_1_4_4)
-	{ "n25q256", 0x20ba19,      0, 64 * 1024,   512,
-	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
-	{ "n25q512", 0x20ba20, 0x1000, 64 * 1024,  1024,
-	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
-	{ "n25q00a", 0x20ba21, 0x1000, 64 * 1024,  2048,
-	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
+	JEDEC_INFO("n25q256", 0x20ba19, 64 * 1024,   512,
+		   N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
+	RDID_INFO("n25q512", RDID({0x20, 0xba, 0x20, 0x10, 0x00}), 5, 64 * 1024,
+		  1024, N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
+	RDID_INFO("n25q00a", RDID({0x20, 0xba, 0x21, 0x10, 0x00}), 5, 64 * 1024,
+		  2048, N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
 
 	/*
 	 * Spansion S25FLxxxP
@@ -422,12 +453,12 @@ static struct flash_info flash_types[] = {
 			FLASH_FLAG_READ_1_4_4   |	\
 			FLASH_FLAG_WRITE_1_1_4  |	\
 			FLASH_FLAG_READ_FAST)
-	{ "s25fl032p",  0x010215, 0x4d00,  64 * 1024,  64, S25FLXXXP_FLAG, 80,
-	  stfsm_s25fl_config},
-	{ "s25fl129p0", 0x012018, 0x4d00, 256 * 1024,  64, S25FLXXXP_FLAG, 80,
-	  stfsm_s25fl_config },
-	{ "s25fl129p1", 0x012018, 0x4d01,  64 * 1024, 256, S25FLXXXP_FLAG, 80,
-	  stfsm_s25fl_config },
+	RDID_INFO("s25fl032p", RDID({0x01, 0x02, 0x15, 0x4d, 0x00}), 5,
+		  64 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl129p0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00}), 5,
+		  256 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl129p1", RDID({0x01, 0x20, 0x18, 0x4d, 0x01}), 5,
+		  64 * 1024, 256, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
 
 	/*
 	 * Spansion S25FLxxxS
@@ -441,25 +472,24 @@ static struct flash_info flash_types[] = {
 #define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
 			FLASH_FLAG_RESET        |	\
 			FLASH_FLAG_DYB_LOCKING)
-	{ "s25fl128s0", 0x012018, 0x0300,  256 * 1024, 64, S25FLXXXS_FLAG, 80,
-	  stfsm_s25fl_config },
-	{ "s25fl128s1", 0x012018, 0x0301,  64 * 1024, 256, S25FLXXXS_FLAG, 80,
-	  stfsm_s25fl_config },
-	{ "s25fl256s0", 0x010219, 0x4d00, 256 * 1024, 128,
-	  S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
-	{ "s25fl256s1", 0x010219, 0x4d01,  64 * 1024, 512,
-	  S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
-
-	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x03, 0x00}), 5,
+		  256 * 1024, 64, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl128s1", RDID({0x01, 0x20, 0x18, 0x03, 0x01}), 5,
+		  64 * 1024, 256, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl256s0", RDID({0x01, 0x02, 0x19, 0x4d, 0x00}), 5,
+		  256 * 1024, 128, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01}), 5,
+		  64 * 1024, 512, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+
 #define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
 		   FLASH_FLAG_READ_FAST         |	\
 		   FLASH_FLAG_READ_1_1_2        |	\
 		   FLASH_FLAG_WRITE_1_1_2)
-	{ "w25x40",  0xef3013, 0,  64 * 1024,   8, W25X_FLAG, 75, NULL },
-	{ "w25x80",  0xef3014, 0,  64 * 1024,  16, W25X_FLAG, 75, NULL },
-	{ "w25x16",  0xef3015, 0,  64 * 1024,  32, W25X_FLAG, 75, NULL },
-	{ "w25x32",  0xef3016, 0,  64 * 1024,  64, W25X_FLAG, 75, NULL },
-	{ "w25x64",  0xef3017, 0,  64 * 1024, 128, W25X_FLAG, 75, NULL },
+	JEDEC_INFO("w25x40", 0xef3013, 64 * 1024,   8, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x80", 0xef3014, 64 * 1024,  16, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x16", 0xef3015, 64 * 1024,  32, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x32", 0xef3016, 64 * 1024,  64, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x64", 0xef3017, 64 * 1024, 128, W25X_FLAG, 75, NULL),
 
 	/* Winbond -- w25q "blocks" are 64K, "sectors" are 4KiB */
 #define W25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
@@ -469,17 +499,16 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_READ_1_1_4        |	\
 		   FLASH_FLAG_READ_1_4_4        |	\
 		   FLASH_FLAG_WRITE_1_1_4)
-	{ "w25q80",  0xef4014, 0,  64 * 1024,  16, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-	{ "w25q16",  0xef4015, 0,  64 * 1024,  32, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-	{ "w25q32",  0xef4016, 0,  64 * 1024,  64, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-	{ "w25q64",  0xef4017, 0,  64 * 1024, 128, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-
-	/* Sentinel */
-	{ NULL, 0x000000, 0, 0, 0, 0, 0, NULL },
+	JEDEC_INFO("w25q80", 0xef4014, 64 * 1024,  16,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+	JEDEC_INFO("w25q16", 0xef4015, 64 * 1024,  32,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+	JEDEC_INFO("w25q32", 0xef4016, 64 * 1024,  64,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+	JEDEC_INFO("w25q64", 0xef4017, 64 * 1024, 128,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+
+	{ },
 };
 
 /*
@@ -610,7 +639,7 @@ static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
 #define W25Q_STATUS_QE			(0x1 << 1)
 
 static struct stfsm_seq stfsm_seq_read_jedec = {
-	.data_size = TRANSFER_SIZE(8),
+	.data_size = TRANSFER_SIZE(MAX_READID_LEN_ALIGNED),
 	.seq_opc[0] = (SEQ_OPC_PADS_1 |
 		       SEQ_OPC_CYCLES(8) |
 		       SEQ_OPC_OPCODE(SPINOR_OP_RDID)),
@@ -706,7 +735,7 @@ static const struct stfsm_seq stfsm_seq_load_fifo_byte = {
 	.data_size = TRANSFER_SIZE(1),
 	.seq_opc[0] = (SEQ_OPC_PADS_1 |
 		       SEQ_OPC_CYCLES(8) |
-		       SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
+		       SEQ_OPC_OPCODE(SPINOR_OP_RDID)),
 	.seq = {
 		STFSM_INST_CMD1,
 		STFSM_INST_DATA_READ,
@@ -1929,45 +1958,49 @@ out1:
 static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *jedec)
 {
 	const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
-	uint32_t tmp[2];
+	uint32_t tmp[MAX_READID_LEN_ALIGNED / 4];
 
 	stfsm_load_seq(fsm, seq);
 
-	stfsm_read_fifo(fsm, tmp, 8);
+	stfsm_read_fifo(fsm, tmp, MAX_READID_LEN_ALIGNED);
 
-	memcpy(jedec, tmp, 5);
+	memcpy(jedec, tmp, MAX_READID_LEN);
 
 	stfsm_wait_seq(fsm);
 }
 
+static int stfsm_cmp_flash_info_readid_len(const void *a, const void *b)
+{
+	return ((struct flash_info *)b)->readid_len -
+		((struct flash_info *)a)->readid_len;
+}
+
 static struct flash_info *stfsm_jedec_probe(struct stfsm *fsm)
 {
-	struct flash_info	*info;
-	u16                     ext_jedec;
-	u32			jedec;
-	u8			id[5];
+	uint8_t readid[MAX_READID_LEN];
+	char readid_str[MAX_READID_LEN * 3 + 1];
+	struct flash_info *info;
 
-	stfsm_read_jedec(fsm, id);
+	stfsm_read_jedec(fsm, readid);
 
-	jedec     = id[0] << 16 | id[1] << 8 | id[2];
-	/*
-	 * JEDEC also defines an optional "extended device information"
-	 * string for after vendor-specific data, after the three bytes
-	 * we use here. Supporting some chips might require using it.
-	 */
-	ext_jedec = id[3] << 8  | id[4];
+	hex_dump_to_buffer(readid, MAX_READID_LEN, 16, 1,
+			   readid_str, sizeof(readid_str), 0);
+
+	dev_dbg(fsm->dev, "READID = %s\n", readid_str);
 
-	dev_dbg(fsm->dev, "JEDEC =  0x%08x [%02x %02x %02x %02x %02x]\n",
-		jedec, id[0], id[1], id[2], id[3], id[4]);
+	/* The 'readid' may match multiple entries in the table.  To ensure we
+	 * retrieve the most specific match, the table is sorted in order of
+	 * 'readid_len'.
+	 */
+	sort(flash_types, ARRAY_SIZE(flash_types) - 1,
+	     sizeof(struct flash_info), stfsm_cmp_flash_info_readid_len, NULL);
 
 	for (info = flash_types; info->name; info++) {
-		if (info->jedec_id == jedec) {
-			if (info->ext_id && info->ext_id != ext_jedec)
-				continue;
+		if (memcmp(info->readid, readid, info->readid_len) == 0)
 			return info;
-		}
 	}
-	dev_err(fsm->dev, "Unrecognized JEDEC id %06x\n", jedec);
+
+	dev_err(fsm->dev, "Unrecognized READID [%s]\n", readid_str);
 
 	return NULL;
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 05/10] mtd: st_spi_fsm: Update the JEDEC probe to handle extended READIDs
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Angus Clark <angus.clark@st.com>

The previous code was based on 3-byte JEDEC IDs, with a possible 2-byte
extension.  However, devices are now emerging that return 6 or more bytes of
READID data and the additional bytes are required to differentiate between
variants or generations of similar devices.

This patch refactors the device table and JEDEC probe code to handle arbitrary
length READIDs, with the standard JEDEC definition now becoming a special case.
Functionally, there should be no change in behaviour.  A subsequent patch will
update the table with extended READIDs where applicable.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 209 ++++++++++++++++++++++-----------------
 1 file changed, 121 insertions(+), 88 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index d48004d..3409651 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -21,6 +21,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/spi-nor.h>
 #include <linux/sched.h>
+#include <linux/sort.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
@@ -221,6 +222,11 @@
 #define FLASH_STATUS_BP2       0x10
 #define FLASH_STATUS_SRWP0     0x80
 #define FLASH_STATUS_TIMEOUT   0xff
+
+/* Maximum READID length */
+#define MAX_READID_LEN         6
+#define MAX_READID_LEN_ALIGNED ALIGN(MAX_READID_LEN, 4)
+
 /* S25FL Error Flags */
 #define S25FL_STATUS_E_ERR     0x20
 #define S25FL_STATUS_P_ERR     0x40
@@ -305,13 +311,9 @@ struct seq_rw_config {
 /* SPI Flash Device Table */
 struct flash_info {
 	char            *name;
-	/*
-	 * JEDEC id zero means "no ID" (most older chips); otherwise it has
-	 * a high byte of zero plus three data bytes: the manufacturer id,
-	 * then a two byte device id.
-	 */
-	u32             jedec_id;
-	u16             ext_id;
+	/* READID data, as returned by 'FLASH_CMD_RDID' (0x9f). */
+	u8              readid[MAX_READID_LEN];
+	int             readid_len;
 	/*
 	 * The size listed here is what works with SPINOR_OP_SE, which isn't
 	 * necessarily called a "sector" by the vendor.
@@ -327,6 +329,38 @@ struct flash_info {
 	int             (*config)(struct stfsm *);
 };
 
+/* Device with standard 3-byte JEDEC ID */
+#define JEDEC_INFO(_name, _jedec_id, _sector_size, _n_sectors,	\
+		   _flags, _max_freq, _config)			\
+	{							\
+		.name = (_name),				\
+		.readid[0] = ((_jedec_id) >> 16 & 0xff),	\
+		.readid[1] = ((_jedec_id) >>  8 & 0xff),	\
+		.readid[2] = ((_jedec_id) >>  0 & 0xff),	\
+		.readid_len = 3,				\
+		.sector_size = (_sector_size),			\
+		.n_sectors = (_n_sectors),			\
+		.flags = (_flags),				\
+		.max_freq = (_max_freq),			\
+		.config = (_config)				\
+	}
+
+/* Device with arbitrary-length READID */
+#define RDID(...) __VA_ARGS__  /* Dummy macro to protect array argument. */
+#define RDID_INFO(_name, _readid, _readid_len, _sector_size,	\
+		  _n_sectors, _flags, _max_freq, _config)	\
+	{							\
+		.name = (_name),				\
+		.readid = _readid,				\
+		.readid_len = _readid_len,			\
+		.flags = (_flags),				\
+		.sector_size = (_sector_size),			\
+		.n_sectors = (_n_sectors),			\
+		.flags = (_flags),				\
+		.max_freq = (_max_freq),			\
+		.config = (_config)				\
+	}
+
 static int stfsm_n25q_config(struct stfsm *fsm);
 static int stfsm_mx25_config(struct stfsm *fsm);
 static int stfsm_s25fl_config(struct stfsm *fsm);
@@ -339,19 +373,19 @@ static struct flash_info flash_types[] = {
 	 * (eg faster operating frequency)
 	 */
 #define M25P_FLAG (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST)
-	{ "m25p40",  0x202013, 0,  64 * 1024,   8, M25P_FLAG, 25, NULL },
-	{ "m25p80",  0x202014, 0,  64 * 1024,  16, M25P_FLAG, 25, NULL },
-	{ "m25p16",  0x202015, 0,  64 * 1024,  32, M25P_FLAG, 25, NULL },
-	{ "m25p32",  0x202016, 0,  64 * 1024,  64, M25P_FLAG, 50, NULL },
-	{ "m25p64",  0x202017, 0,  64 * 1024, 128, M25P_FLAG, 50, NULL },
-	{ "m25p128", 0x202018, 0, 256 * 1024,  64, M25P_FLAG, 50, NULL },
+	JEDEC_INFO("m25p40",  0x202013,  64 * 1024,   8, M25P_FLAG, 25, NULL),
+	JEDEC_INFO("m25p80",  0x202014,  64 * 1024,  16, M25P_FLAG, 25, NULL),
+	JEDEC_INFO("m25p16",  0x202015,  64 * 1024,  32, M25P_FLAG, 25, NULL),
+	JEDEC_INFO("m25p32",  0x202016,  64 * 1024,  64, M25P_FLAG, 50, NULL),
+	JEDEC_INFO("m25p64",  0x202017,  64 * 1024, 128, M25P_FLAG, 50, NULL),
+	JEDEC_INFO("m25p128", 0x202018, 256 * 1024,  64, M25P_FLAG, 50, NULL),
 
 #define M25PX_FLAG (FLASH_FLAG_READ_WRITE      |	\
 		    FLASH_FLAG_READ_FAST        |	\
 		    FLASH_FLAG_READ_1_1_2       |	\
 		    FLASH_FLAG_WRITE_1_1_2)
-	{ "m25px32", 0x207116, 0,  64 * 1024,  64, M25PX_FLAG, 75, NULL },
-	{ "m25px64", 0x207117, 0,  64 * 1024, 128, M25PX_FLAG, 75, NULL },
+	JEDEC_INFO("m25px32", 0x207116,  64 * 1024,  64, M25PX_FLAG, 75, NULL),
+	JEDEC_INFO("m25px64", 0x207117,  64 * 1024, 128, M25PX_FLAG, 75, NULL),
 
 	/* Macronix MX25xxx
 	 *     - Support for 'FLASH_FLAG_WRITE_1_4_4' is omitted for devices
@@ -364,15 +398,12 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_READ_1_1_4        |	\
 		   FLASH_FLAG_SE_4K             |	\
 		   FLASH_FLAG_SE_32K)
-	{ "mx25l3255e",  0xc29e16, 0, 64 * 1024, 64,
-	  (MX25_FLAG | FLASH_FLAG_WRITE_1_4_4), 86,
-	  stfsm_mx25_config},
-	{ "mx25l25635e", 0xc22019, 0, 64*1024, 512,
-	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
-	  stfsm_mx25_config },
-	{ "mx25l25655e", 0xc22619, 0, 64*1024, 512,
-	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
-	  stfsm_mx25_config},
+	JEDEC_INFO("mx25l3255e",  0xc29e16, 64 * 1024, 64,
+		   (MX25_FLAG | FLASH_FLAG_WRITE_1_4_4), 86, stfsm_mx25_config),
+	JEDEC_INFO("mx25l25635e", 0xc22019, 64 * 1024, 512,
+		   (MX25_FLAG | FLASH_FLAG_RESET), 70, stfsm_mx25_config),
+	JEDEC_INFO("mx25l25655e", 0xc22619, 64 * 1024, 512,
+		   (MX25_FLAG | FLASH_FLAG_RESET), 70, stfsm_mx25_config),
 
 	/* Micron N25Qxxx */
 #define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
@@ -385,8 +416,8 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_WRITE_1_2_2       |	\
 		   FLASH_FLAG_WRITE_1_1_4       |	\
 		   FLASH_FLAG_WRITE_1_4_4)
-	{ "n25q128", 0x20ba18, 0, 64 * 1024,  256, N25Q_FLAG, 108,
-	  stfsm_n25q_config },
+	JEDEC_INFO("n25q128", 0x20ba18, 64 * 1024,  256,
+		   N25Q_FLAG, 108, stfsm_n25q_config),
 
        /* Micron N25Q256/N25Q512/N25Q00A (32-bit ADDR devices)
         *
@@ -404,12 +435,12 @@ static struct flash_info flash_types[] = {
 				FLASH_FLAG_32BIT_ADDR  |	\
 				FLASH_FLAG_RESET)      &	\
 			       ~FLASH_FLAG_WRITE_1_4_4)
-	{ "n25q256", 0x20ba19,      0, 64 * 1024,   512,
-	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
-	{ "n25q512", 0x20ba20, 0x1000, 64 * 1024,  1024,
-	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
-	{ "n25q00a", 0x20ba21, 0x1000, 64 * 1024,  2048,
-	  N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config},
+	JEDEC_INFO("n25q256", 0x20ba19, 64 * 1024,   512,
+		   N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
+	RDID_INFO("n25q512", RDID({0x20, 0xba, 0x20, 0x10, 0x00}), 5, 64 * 1024,
+		  1024, N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
+	RDID_INFO("n25q00a", RDID({0x20, 0xba, 0x21, 0x10, 0x00}), 5, 64 * 1024,
+		  2048, N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
 
 	/*
 	 * Spansion S25FLxxxP
@@ -422,12 +453,12 @@ static struct flash_info flash_types[] = {
 			FLASH_FLAG_READ_1_4_4   |	\
 			FLASH_FLAG_WRITE_1_1_4  |	\
 			FLASH_FLAG_READ_FAST)
-	{ "s25fl032p",  0x010215, 0x4d00,  64 * 1024,  64, S25FLXXXP_FLAG, 80,
-	  stfsm_s25fl_config},
-	{ "s25fl129p0", 0x012018, 0x4d00, 256 * 1024,  64, S25FLXXXP_FLAG, 80,
-	  stfsm_s25fl_config },
-	{ "s25fl129p1", 0x012018, 0x4d01,  64 * 1024, 256, S25FLXXXP_FLAG, 80,
-	  stfsm_s25fl_config },
+	RDID_INFO("s25fl032p", RDID({0x01, 0x02, 0x15, 0x4d, 0x00}), 5,
+		  64 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl129p0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00}), 5,
+		  256 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl129p1", RDID({0x01, 0x20, 0x18, 0x4d, 0x01}), 5,
+		  64 * 1024, 256, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
 
 	/*
 	 * Spansion S25FLxxxS
@@ -441,25 +472,24 @@ static struct flash_info flash_types[] = {
 #define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
 			FLASH_FLAG_RESET        |	\
 			FLASH_FLAG_DYB_LOCKING)
-	{ "s25fl128s0", 0x012018, 0x0300,  256 * 1024, 64, S25FLXXXS_FLAG, 80,
-	  stfsm_s25fl_config },
-	{ "s25fl128s1", 0x012018, 0x0301,  64 * 1024, 256, S25FLXXXS_FLAG, 80,
-	  stfsm_s25fl_config },
-	{ "s25fl256s0", 0x010219, 0x4d00, 256 * 1024, 128,
-	  S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
-	{ "s25fl256s1", 0x010219, 0x4d01,  64 * 1024, 512,
-	  S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
-
-	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x03, 0x00}), 5,
+		  256 * 1024, 64, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl128s1", RDID({0x01, 0x20, 0x18, 0x03, 0x01}), 5,
+		  64 * 1024, 256, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl256s0", RDID({0x01, 0x02, 0x19, 0x4d, 0x00}), 5,
+		  256 * 1024, 128, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01}), 5,
+		  64 * 1024, 512, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
+
 #define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
 		   FLASH_FLAG_READ_FAST         |	\
 		   FLASH_FLAG_READ_1_1_2        |	\
 		   FLASH_FLAG_WRITE_1_1_2)
-	{ "w25x40",  0xef3013, 0,  64 * 1024,   8, W25X_FLAG, 75, NULL },
-	{ "w25x80",  0xef3014, 0,  64 * 1024,  16, W25X_FLAG, 75, NULL },
-	{ "w25x16",  0xef3015, 0,  64 * 1024,  32, W25X_FLAG, 75, NULL },
-	{ "w25x32",  0xef3016, 0,  64 * 1024,  64, W25X_FLAG, 75, NULL },
-	{ "w25x64",  0xef3017, 0,  64 * 1024, 128, W25X_FLAG, 75, NULL },
+	JEDEC_INFO("w25x40", 0xef3013, 64 * 1024,   8, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x80", 0xef3014, 64 * 1024,  16, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x16", 0xef3015, 64 * 1024,  32, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x32", 0xef3016, 64 * 1024,  64, W25X_FLAG, 75, NULL),
+	JEDEC_INFO("w25x64", 0xef3017, 64 * 1024, 128, W25X_FLAG, 75, NULL),
 
 	/* Winbond -- w25q "blocks" are 64K, "sectors" are 4KiB */
 #define W25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
@@ -469,17 +499,16 @@ static struct flash_info flash_types[] = {
 		   FLASH_FLAG_READ_1_1_4        |	\
 		   FLASH_FLAG_READ_1_4_4        |	\
 		   FLASH_FLAG_WRITE_1_1_4)
-	{ "w25q80",  0xef4014, 0,  64 * 1024,  16, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-	{ "w25q16",  0xef4015, 0,  64 * 1024,  32, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-	{ "w25q32",  0xef4016, 0,  64 * 1024,  64, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-	{ "w25q64",  0xef4017, 0,  64 * 1024, 128, W25Q_FLAG, 80,
-	  stfsm_w25q_config },
-
-	/* Sentinel */
-	{ NULL, 0x000000, 0, 0, 0, 0, 0, NULL },
+	JEDEC_INFO("w25q80", 0xef4014, 64 * 1024,  16,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+	JEDEC_INFO("w25q16", 0xef4015, 64 * 1024,  32,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+	JEDEC_INFO("w25q32", 0xef4016, 64 * 1024,  64,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+	JEDEC_INFO("w25q64", 0xef4017, 64 * 1024, 128,
+		   W25Q_FLAG, 80, stfsm_w25q_config),
+
+	{ },
 };
 
 /*
@@ -610,7 +639,7 @@ static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
 #define W25Q_STATUS_QE			(0x1 << 1)
 
 static struct stfsm_seq stfsm_seq_read_jedec = {
-	.data_size = TRANSFER_SIZE(8),
+	.data_size = TRANSFER_SIZE(MAX_READID_LEN_ALIGNED),
 	.seq_opc[0] = (SEQ_OPC_PADS_1 |
 		       SEQ_OPC_CYCLES(8) |
 		       SEQ_OPC_OPCODE(SPINOR_OP_RDID)),
@@ -706,7 +735,7 @@ static const struct stfsm_seq stfsm_seq_load_fifo_byte = {
 	.data_size = TRANSFER_SIZE(1),
 	.seq_opc[0] = (SEQ_OPC_PADS_1 |
 		       SEQ_OPC_CYCLES(8) |
-		       SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
+		       SEQ_OPC_OPCODE(SPINOR_OP_RDID)),
 	.seq = {
 		STFSM_INST_CMD1,
 		STFSM_INST_DATA_READ,
@@ -1929,45 +1958,49 @@ out1:
 static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *jedec)
 {
 	const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
-	uint32_t tmp[2];
+	uint32_t tmp[MAX_READID_LEN_ALIGNED / 4];
 
 	stfsm_load_seq(fsm, seq);
 
-	stfsm_read_fifo(fsm, tmp, 8);
+	stfsm_read_fifo(fsm, tmp, MAX_READID_LEN_ALIGNED);
 
-	memcpy(jedec, tmp, 5);
+	memcpy(jedec, tmp, MAX_READID_LEN);
 
 	stfsm_wait_seq(fsm);
 }
 
+static int stfsm_cmp_flash_info_readid_len(const void *a, const void *b)
+{
+	return ((struct flash_info *)b)->readid_len -
+		((struct flash_info *)a)->readid_len;
+}
+
 static struct flash_info *stfsm_jedec_probe(struct stfsm *fsm)
 {
-	struct flash_info	*info;
-	u16                     ext_jedec;
-	u32			jedec;
-	u8			id[5];
+	uint8_t readid[MAX_READID_LEN];
+	char readid_str[MAX_READID_LEN * 3 + 1];
+	struct flash_info *info;
 
-	stfsm_read_jedec(fsm, id);
+	stfsm_read_jedec(fsm, readid);
 
-	jedec     = id[0] << 16 | id[1] << 8 | id[2];
-	/*
-	 * JEDEC also defines an optional "extended device information"
-	 * string for after vendor-specific data, after the three bytes
-	 * we use here. Supporting some chips might require using it.
-	 */
-	ext_jedec = id[3] << 8  | id[4];
+	hex_dump_to_buffer(readid, MAX_READID_LEN, 16, 1,
+			   readid_str, sizeof(readid_str), 0);
+
+	dev_dbg(fsm->dev, "READID = %s\n", readid_str);
 
-	dev_dbg(fsm->dev, "JEDEC =  0x%08x [%02x %02x %02x %02x %02x]\n",
-		jedec, id[0], id[1], id[2], id[3], id[4]);
+	/* The 'readid' may match multiple entries in the table.  To ensure we
+	 * retrieve the most specific match, the table is sorted in order of
+	 * 'readid_len'.
+	 */
+	sort(flash_types, ARRAY_SIZE(flash_types) - 1,
+	     sizeof(struct flash_info), stfsm_cmp_flash_info_readid_len, NULL);
 
 	for (info = flash_types; info->name; info++) {
-		if (info->jedec_id == jedec) {
-			if (info->ext_id && info->ext_id != ext_jedec)
-				continue;
+		if (memcmp(info->readid, readid, info->readid_len) == 0)
 			return info;
-		}
 	}
-	dev_err(fsm->dev, "Unrecognized JEDEC id %06x\n", jedec);
+
+	dev_err(fsm->dev, "Unrecognized READID [%s]\n", readid_str);
 
 	return NULL;
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 06/10] mtd: st_spi_fsm: Update Spansion device entries
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:24   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Angus Clark, Carmelo Amoroso, Lee Jones

From: Angus Clark <angus.clark@st.com>

This patch updates various Spansion device entries in the flash_types[] table:
  - Define full 6-byte READIDs for S25FL128Sx devices (and fix the 4th
    byte). This allows us to differentiate between S25FL129P and S25FL128S
    devices.
  - Add S25FL128Px device entries.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 3409651..7514a07 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -445,6 +445,7 @@ static struct flash_info flash_types[] = {
 	/*
 	 * Spansion S25FLxxxP
 	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
+	 *     - S25FL128Px devices do not support DUAL or QUAD I/O
 	 */
 #define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE  |	\
 			FLASH_FLAG_READ_1_1_2   |	\
@@ -455,6 +456,12 @@ static struct flash_info flash_types[] = {
 			FLASH_FLAG_READ_FAST)
 	RDID_INFO("s25fl032p", RDID({0x01, 0x02, 0x15, 0x4d, 0x00}), 5,
 		  64 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl128p1", RDID({0x01, 0x20, 0x18, 0x03, 0x00}), 5,
+		  256 * 1024, 64,
+		  (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST), 104, NULL),
+	RDID_INFO("s25fl128p0", RDID({0x01, 0x20, 0x18, 0x03, 0x01}), 5,
+		  64 * 1024, 256,
+		  (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST), 104, NULL),
 	RDID_INFO("s25fl129p0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00}), 5,
 		  256 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
 	RDID_INFO("s25fl129p1", RDID({0x01, 0x20, 0x18, 0x4d, 0x01}), 5,
@@ -468,17 +475,18 @@ static struct flash_info flash_types[] = {
 	 *       so this information is captured in the board's flags.
 	 *     - Supports 'DYB' sector protection. Depending on variant, sectors
 	 *       may default to locked state on power-on.
+	 *     - S25FL127Sx handled as S25FL128Sx
 	 */
 #define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
 			FLASH_FLAG_RESET        |	\
 			FLASH_FLAG_DYB_LOCKING)
-	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x03, 0x00}), 5,
+	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00, 0x80}), 6,
 		  256 * 1024, 64, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
-	RDID_INFO("s25fl128s1", RDID({0x01, 0x20, 0x18, 0x03, 0x01}), 5,
+	RDID_INFO("s25fl128s1", RDID({0x01, 0x20, 0x18, 0x4d, 0x01, 0x80}), 6,
 		  64 * 1024, 256, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
-	RDID_INFO("s25fl256s0", RDID({0x01, 0x02, 0x19, 0x4d, 0x00}), 5,
+	RDID_INFO("s25fl256s0", RDID({0x01, 0x02, 0x19, 0x4d, 0x00, 0x80}), 6,
 		  256 * 1024, 128, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
-	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01}), 5,
+	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01, 0x80}), 6,
 		  64 * 1024, 512, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
 
 #define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 06/10] mtd: st_spi_fsm: Update Spansion device entries
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Angus Clark, Lee Jones, computersforpeace, linux-mtd, Carmelo Amoroso

From: Angus Clark <angus.clark@st.com>

This patch updates various Spansion device entries in the flash_types[] table:
  - Define full 6-byte READIDs for S25FL128Sx devices (and fix the 4th
    byte). This allows us to differentiate between S25FL129P and S25FL128S
    devices.
  - Add S25FL128Px device entries.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 3409651..7514a07 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -445,6 +445,7 @@ static struct flash_info flash_types[] = {
 	/*
 	 * Spansion S25FLxxxP
 	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
+	 *     - S25FL128Px devices do not support DUAL or QUAD I/O
 	 */
 #define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE  |	\
 			FLASH_FLAG_READ_1_1_2   |	\
@@ -455,6 +456,12 @@ static struct flash_info flash_types[] = {
 			FLASH_FLAG_READ_FAST)
 	RDID_INFO("s25fl032p", RDID({0x01, 0x02, 0x15, 0x4d, 0x00}), 5,
 		  64 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl128p1", RDID({0x01, 0x20, 0x18, 0x03, 0x00}), 5,
+		  256 * 1024, 64,
+		  (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST), 104, NULL),
+	RDID_INFO("s25fl128p0", RDID({0x01, 0x20, 0x18, 0x03, 0x01}), 5,
+		  64 * 1024, 256,
+		  (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST), 104, NULL),
 	RDID_INFO("s25fl129p0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00}), 5,
 		  256 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
 	RDID_INFO("s25fl129p1", RDID({0x01, 0x20, 0x18, 0x4d, 0x01}), 5,
@@ -468,17 +475,18 @@ static struct flash_info flash_types[] = {
 	 *       so this information is captured in the board's flags.
 	 *     - Supports 'DYB' sector protection. Depending on variant, sectors
 	 *       may default to locked state on power-on.
+	 *     - S25FL127Sx handled as S25FL128Sx
 	 */
 #define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
 			FLASH_FLAG_RESET        |	\
 			FLASH_FLAG_DYB_LOCKING)
-	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x03, 0x00}), 5,
+	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00, 0x80}), 6,
 		  256 * 1024, 64, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
-	RDID_INFO("s25fl128s1", RDID({0x01, 0x20, 0x18, 0x03, 0x01}), 5,
+	RDID_INFO("s25fl128s1", RDID({0x01, 0x20, 0x18, 0x4d, 0x01, 0x80}), 6,
 		  64 * 1024, 256, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
-	RDID_INFO("s25fl256s0", RDID({0x01, 0x02, 0x19, 0x4d, 0x00}), 5,
+	RDID_INFO("s25fl256s0", RDID({0x01, 0x02, 0x19, 0x4d, 0x00, 0x80}), 6,
 		  256 * 1024, 128, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
-	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01}), 5,
+	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01, 0x80}), 6,
 		  64 * 1024, 512, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
 
 #define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 06/10] mtd: st_spi_fsm: Update Spansion device entries
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Angus Clark <angus.clark@st.com>

This patch updates various Spansion device entries in the flash_types[] table:
  - Define full 6-byte READIDs for S25FL128Sx devices (and fix the 4th
    byte). This allows us to differentiate between S25FL129P and S25FL128S
    devices.
  - Add S25FL128Px device entries.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 3409651..7514a07 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -445,6 +445,7 @@ static struct flash_info flash_types[] = {
 	/*
 	 * Spansion S25FLxxxP
 	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
+	 *     - S25FL128Px devices do not support DUAL or QUAD I/O
 	 */
 #define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE  |	\
 			FLASH_FLAG_READ_1_1_2   |	\
@@ -455,6 +456,12 @@ static struct flash_info flash_types[] = {
 			FLASH_FLAG_READ_FAST)
 	RDID_INFO("s25fl032p", RDID({0x01, 0x02, 0x15, 0x4d, 0x00}), 5,
 		  64 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
+	RDID_INFO("s25fl128p1", RDID({0x01, 0x20, 0x18, 0x03, 0x00}), 5,
+		  256 * 1024, 64,
+		  (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST), 104, NULL),
+	RDID_INFO("s25fl128p0", RDID({0x01, 0x20, 0x18, 0x03, 0x01}), 5,
+		  64 * 1024, 256,
+		  (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST), 104, NULL),
 	RDID_INFO("s25fl129p0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00}), 5,
 		  256 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
 	RDID_INFO("s25fl129p1", RDID({0x01, 0x20, 0x18, 0x4d, 0x01}), 5,
@@ -468,17 +475,18 @@ static struct flash_info flash_types[] = {
 	 *       so this information is captured in the board's flags.
 	 *     - Supports 'DYB' sector protection. Depending on variant, sectors
 	 *       may default to locked state on power-on.
+	 *     - S25FL127Sx handled as S25FL128Sx
 	 */
 #define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
 			FLASH_FLAG_RESET        |	\
 			FLASH_FLAG_DYB_LOCKING)
-	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x03, 0x00}), 5,
+	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00, 0x80}), 6,
 		  256 * 1024, 64, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
-	RDID_INFO("s25fl128s1", RDID({0x01, 0x20, 0x18, 0x03, 0x01}), 5,
+	RDID_INFO("s25fl128s1", RDID({0x01, 0x20, 0x18, 0x4d, 0x01, 0x80}), 6,
 		  64 * 1024, 256, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
-	RDID_INFO("s25fl256s0", RDID({0x01, 0x02, 0x19, 0x4d, 0x00}), 5,
+	RDID_INFO("s25fl256s0", RDID({0x01, 0x02, 0x19, 0x4d, 0x00, 0x80}), 6,
 		  256 * 1024, 128, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
-	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01}), 5,
+	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01, 0x80}), 6,
 		  64 * 1024, 512, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
 
 #define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 07/10] mtd: st_spi_fsm: Improve busy wait handling
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:24   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Angus Clark, Lee Jones

From: Angus Clark <angus.clark@st.com>

In this patch, the fsm_wait_busy() function is updated to a take a timeout
parameter.  This allows us to specify different timeout delays depending on
the operation being performed.  Previously, a fixed, worst-case delay
(corresponding to the Chip Erase operation, ~300s!) was used. For the moment,
we have defined conservative delays for each relevant operation, which should
accommodate all existing devices.  In principle, one could set the delays
according the device probed, but there is probably little to be gained.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 7514a07..3f74e125 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -252,7 +252,12 @@
 
 #define FLASH_PAGESIZE         256			/* In Bytes    */
 #define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
-#define FLASH_MAX_BUSY_WAIT    (300 * HZ)	/* Maximum 'CHIPERASE' time */
+/* Maximum operation times (in ms) */
+#define FLASH_MAX_CHIP_ERASE_MS 500000          /* Chip Erase time */
+#define FLASH_MAX_SEC_ERASE_MS  30000           /* Sector Erase time */
+#define FLASH_MAX_PAGE_WRITE_MS 100             /* Write Page time */
+#define FLASH_MAX_STA_WRITE_MS  4000            /* Write status reg time */
+#define FSM_MAX_WAIT_SEQ_MS     1000            /* FSM execution time */
 
 /*
  * Flags to tweak operation of default read/write/erase routines
@@ -966,7 +971,7 @@ static int stfsm_enter_32bit_addr(struct stfsm *fsm, int enter)
 	return 0;
 }
 
-static uint8_t stfsm_wait_busy(struct stfsm *fsm)
+static uint8_t stfsm_wait_busy(struct stfsm *fsm, unsigned int max_time_ms)
 {
 	struct stfsm_seq *seq = &stfsm_seq_read_status_fifo;
 	unsigned long deadline;
@@ -984,7 +989,7 @@ static uint8_t stfsm_wait_busy(struct stfsm *fsm)
 	/*
 	 * Repeat until busy bit is deasserted, or timeout, or error (S25FLxxxS)
 	 */
-	deadline = jiffies + FLASH_MAX_BUSY_WAIT;
+	deadline = jiffies + msecs_to_jiffies(max_time_ms);
 	while (!timeout) {
 		if (time_after_eq(jiffies, deadline))
 			timeout = 1;
@@ -1063,7 +1068,7 @@ static int stfsm_write_status(struct stfsm *fsm, uint8_t cmd,
 	stfsm_wait_seq(fsm);
 
 	if (wait_busy)
-		stfsm_wait_busy(fsm);
+		stfsm_wait_busy(fsm, FLASH_MAX_STA_WRITE_MS);
 
 	return 0;
 }
@@ -1460,7 +1465,7 @@ static void stfsm_s25fl_write_dyb(struct stfsm *fsm, uint32_t offs, uint8_t dby)
 	stfsm_load_seq(fsm, &seq);
 	stfsm_wait_seq(fsm);
 
-	stfsm_wait_busy(fsm);
+	stfsm_wait_busy(fsm, FLASH_MAX_STA_WRITE_MS);
 }
 
 static int stfsm_s25fl_clear_status_reg(struct stfsm *fsm)
@@ -1763,7 +1768,7 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 	stfsm_wait_seq(fsm);
 
 	/* Wait for completion */
-	ret = stfsm_wait_busy(fsm);
+	ret = stfsm_wait_busy(fsm, FLASH_MAX_PAGE_WRITE_MS);
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
@@ -1835,7 +1840,7 @@ static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
 	stfsm_wait_seq(fsm);
 
 	/* Wait for completion */
-	ret = stfsm_wait_busy(fsm);
+	ret = stfsm_wait_busy(fsm, FLASH_MAX_SEC_ERASE_MS);
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
@@ -1865,7 +1870,7 @@ static int stfsm_erase_chip(struct stfsm *fsm)
 
 	stfsm_wait_seq(fsm);
 
-	return stfsm_wait_busy(fsm);
+	return stfsm_wait_busy(fsm, FLASH_MAX_CHIP_ERASE_MS);
 }
 
 /*
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 07/10] mtd: st_spi_fsm: Improve busy wait handling
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Angus Clark, Lee Jones, computersforpeace, linux-mtd

From: Angus Clark <angus.clark@st.com>

In this patch, the fsm_wait_busy() function is updated to a take a timeout
parameter.  This allows us to specify different timeout delays depending on
the operation being performed.  Previously, a fixed, worst-case delay
(corresponding to the Chip Erase operation, ~300s!) was used. For the moment,
we have defined conservative delays for each relevant operation, which should
accommodate all existing devices.  In principle, one could set the delays
according the device probed, but there is probably little to be gained.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 7514a07..3f74e125 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -252,7 +252,12 @@
 
 #define FLASH_PAGESIZE         256			/* In Bytes    */
 #define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
-#define FLASH_MAX_BUSY_WAIT    (300 * HZ)	/* Maximum 'CHIPERASE' time */
+/* Maximum operation times (in ms) */
+#define FLASH_MAX_CHIP_ERASE_MS 500000          /* Chip Erase time */
+#define FLASH_MAX_SEC_ERASE_MS  30000           /* Sector Erase time */
+#define FLASH_MAX_PAGE_WRITE_MS 100             /* Write Page time */
+#define FLASH_MAX_STA_WRITE_MS  4000            /* Write status reg time */
+#define FSM_MAX_WAIT_SEQ_MS     1000            /* FSM execution time */
 
 /*
  * Flags to tweak operation of default read/write/erase routines
@@ -966,7 +971,7 @@ static int stfsm_enter_32bit_addr(struct stfsm *fsm, int enter)
 	return 0;
 }
 
-static uint8_t stfsm_wait_busy(struct stfsm *fsm)
+static uint8_t stfsm_wait_busy(struct stfsm *fsm, unsigned int max_time_ms)
 {
 	struct stfsm_seq *seq = &stfsm_seq_read_status_fifo;
 	unsigned long deadline;
@@ -984,7 +989,7 @@ static uint8_t stfsm_wait_busy(struct stfsm *fsm)
 	/*
 	 * Repeat until busy bit is deasserted, or timeout, or error (S25FLxxxS)
 	 */
-	deadline = jiffies + FLASH_MAX_BUSY_WAIT;
+	deadline = jiffies + msecs_to_jiffies(max_time_ms);
 	while (!timeout) {
 		if (time_after_eq(jiffies, deadline))
 			timeout = 1;
@@ -1063,7 +1068,7 @@ static int stfsm_write_status(struct stfsm *fsm, uint8_t cmd,
 	stfsm_wait_seq(fsm);
 
 	if (wait_busy)
-		stfsm_wait_busy(fsm);
+		stfsm_wait_busy(fsm, FLASH_MAX_STA_WRITE_MS);
 
 	return 0;
 }
@@ -1460,7 +1465,7 @@ static void stfsm_s25fl_write_dyb(struct stfsm *fsm, uint32_t offs, uint8_t dby)
 	stfsm_load_seq(fsm, &seq);
 	stfsm_wait_seq(fsm);
 
-	stfsm_wait_busy(fsm);
+	stfsm_wait_busy(fsm, FLASH_MAX_STA_WRITE_MS);
 }
 
 static int stfsm_s25fl_clear_status_reg(struct stfsm *fsm)
@@ -1763,7 +1768,7 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 	stfsm_wait_seq(fsm);
 
 	/* Wait for completion */
-	ret = stfsm_wait_busy(fsm);
+	ret = stfsm_wait_busy(fsm, FLASH_MAX_PAGE_WRITE_MS);
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
@@ -1835,7 +1840,7 @@ static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
 	stfsm_wait_seq(fsm);
 
 	/* Wait for completion */
-	ret = stfsm_wait_busy(fsm);
+	ret = stfsm_wait_busy(fsm, FLASH_MAX_SEC_ERASE_MS);
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
@@ -1865,7 +1870,7 @@ static int stfsm_erase_chip(struct stfsm *fsm)
 
 	stfsm_wait_seq(fsm);
 
-	return stfsm_wait_busy(fsm);
+	return stfsm_wait_busy(fsm, FLASH_MAX_CHIP_ERASE_MS);
 }
 
 /*
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 07/10] mtd: st_spi_fsm: Improve busy wait handling
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Angus Clark <angus.clark@st.com>

In this patch, the fsm_wait_busy() function is updated to a take a timeout
parameter.  This allows us to specify different timeout delays depending on
the operation being performed.  Previously, a fixed, worst-case delay
(corresponding to the Chip Erase operation, ~300s!) was used. For the moment,
we have defined conservative delays for each relevant operation, which should
accommodate all existing devices.  In principle, one could set the delays
according the device probed, but there is probably little to be gained.

Signed-off-by: Angus Clark <angus.clark@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 7514a07..3f74e125 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -252,7 +252,12 @@
 
 #define FLASH_PAGESIZE         256			/* In Bytes    */
 #define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
-#define FLASH_MAX_BUSY_WAIT    (300 * HZ)	/* Maximum 'CHIPERASE' time */
+/* Maximum operation times (in ms) */
+#define FLASH_MAX_CHIP_ERASE_MS 500000          /* Chip Erase time */
+#define FLASH_MAX_SEC_ERASE_MS  30000           /* Sector Erase time */
+#define FLASH_MAX_PAGE_WRITE_MS 100             /* Write Page time */
+#define FLASH_MAX_STA_WRITE_MS  4000            /* Write status reg time */
+#define FSM_MAX_WAIT_SEQ_MS     1000            /* FSM execution time */
 
 /*
  * Flags to tweak operation of default read/write/erase routines
@@ -966,7 +971,7 @@ static int stfsm_enter_32bit_addr(struct stfsm *fsm, int enter)
 	return 0;
 }
 
-static uint8_t stfsm_wait_busy(struct stfsm *fsm)
+static uint8_t stfsm_wait_busy(struct stfsm *fsm, unsigned int max_time_ms)
 {
 	struct stfsm_seq *seq = &stfsm_seq_read_status_fifo;
 	unsigned long deadline;
@@ -984,7 +989,7 @@ static uint8_t stfsm_wait_busy(struct stfsm *fsm)
 	/*
 	 * Repeat until busy bit is deasserted, or timeout, or error (S25FLxxxS)
 	 */
-	deadline = jiffies + FLASH_MAX_BUSY_WAIT;
+	deadline = jiffies + msecs_to_jiffies(max_time_ms);
 	while (!timeout) {
 		if (time_after_eq(jiffies, deadline))
 			timeout = 1;
@@ -1063,7 +1068,7 @@ static int stfsm_write_status(struct stfsm *fsm, uint8_t cmd,
 	stfsm_wait_seq(fsm);
 
 	if (wait_busy)
-		stfsm_wait_busy(fsm);
+		stfsm_wait_busy(fsm, FLASH_MAX_STA_WRITE_MS);
 
 	return 0;
 }
@@ -1460,7 +1465,7 @@ static void stfsm_s25fl_write_dyb(struct stfsm *fsm, uint32_t offs, uint8_t dby)
 	stfsm_load_seq(fsm, &seq);
 	stfsm_wait_seq(fsm);
 
-	stfsm_wait_busy(fsm);
+	stfsm_wait_busy(fsm, FLASH_MAX_STA_WRITE_MS);
 }
 
 static int stfsm_s25fl_clear_status_reg(struct stfsm *fsm)
@@ -1763,7 +1768,7 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 	stfsm_wait_seq(fsm);
 
 	/* Wait for completion */
-	ret = stfsm_wait_busy(fsm);
+	ret = stfsm_wait_busy(fsm, FLASH_MAX_PAGE_WRITE_MS);
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
@@ -1835,7 +1840,7 @@ static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
 	stfsm_wait_seq(fsm);
 
 	/* Wait for completion */
-	ret = stfsm_wait_busy(fsm);
+	ret = stfsm_wait_busy(fsm, FLASH_MAX_SEC_ERASE_MS);
 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
 		stfsm_s25fl_clear_status_reg(fsm);
 
@@ -1865,7 +1870,7 @@ static int stfsm_erase_chip(struct stfsm *fsm)
 
 	stfsm_wait_seq(fsm);
 
-	return stfsm_wait_busy(fsm);
+	return stfsm_wait_busy(fsm, FLASH_MAX_CHIP_ERASE_MS);
 }
 
 /*
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 08/10] mtd: st_spi_fsm: Provide documentation for boot device mask property
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:24   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Lee Jones, devicetree

The system configuration registers which display which device the system
booted on are in the same place on all boards which support the FSM.
However, the bits do shift every so slightly.  To combat these we're
adding a new property which supplies the necessary mask used to abstract
the required information.

Cc: devicetree@vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 Documentation/devicetree/bindings/mtd/st-fsm.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
index c248939..0523fd4 100644
--- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
+++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
@@ -11,6 +11,8 @@ Optional properties:
   - st,syscfg          : Phandle to boot-device system configuration registers
   - st,boot-device-reg : Address of the aforementioned boot-device register(s)
   - st,boot-device-spi : Expected boot-device value if booted via this device
+  - st,boot-device-msk : Mask to use when extracting boot device from the
+			 above system config registers
 
 Example:
 	spifsm: spifsm@fe902000{
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 08/10] mtd: st_spi_fsm: Provide documentation for boot device mask property
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Lee Jones, computersforpeace, linux-mtd, devicetree

The system configuration registers which display which device the system
booted on are in the same place on all boards which support the FSM.
However, the bits do shift every so slightly.  To combat these we're
adding a new property which supplies the necessary mask used to abstract
the required information.

Cc: devicetree@vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 Documentation/devicetree/bindings/mtd/st-fsm.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
index c248939..0523fd4 100644
--- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
+++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
@@ -11,6 +11,8 @@ Optional properties:
   - st,syscfg          : Phandle to boot-device system configuration registers
   - st,boot-device-reg : Address of the aforementioned boot-device register(s)
   - st,boot-device-spi : Expected boot-device value if booted via this device
+  - st,boot-device-msk : Mask to use when extracting boot device from the
+			 above system config registers
 
 Example:
 	spifsm: spifsm@fe902000{
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 08/10] mtd: st_spi_fsm: Provide documentation for boot device mask property
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

The system configuration registers which display which device the system
booted on are in the same place on all boards which support the FSM.
However, the bits do shift every so slightly.  To combat these we're
adding a new property which supplies the necessary mask used to abstract
the required information.

Cc: devicetree at vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 Documentation/devicetree/bindings/mtd/st-fsm.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
index c248939..0523fd4 100644
--- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
+++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
@@ -11,6 +11,8 @@ Optional properties:
   - st,syscfg          : Phandle to boot-device system configuration registers
   - st,boot-device-reg : Address of the aforementioned boot-device register(s)
   - st,boot-device-spi : Expected boot-device value if booted via this device
+  - st,boot-device-msk : Mask to use when extracting boot device from the
+			 above system config registers
 
 Example:
 	spifsm: spifsm at fe902000{
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:24   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Christophe Kerello, Lee Jones

From: Christophe Kerello <christophe.kerello@st.com>

This patch adds a mask to be able to get the right boot device selection.

For example:
    for STiH415, value = SYSTEM_STATUS398[4:0]
    for STiH416, value = SYSTEM_STATUS2598[4:0]
    for STiH407, value = SYSTEM_STATUS5561[6:2]

Signed-off-by: Christophe Kerello <christophe.kerello@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 3f74e125..6d535d9 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -2125,6 +2125,7 @@ static void stfsm_fetch_platform_configs(struct platform_device *pdev)
 	struct regmap *regmap;
 	uint32_t boot_device_reg;
 	uint32_t boot_device_spi;
+	uint32_t boot_device_msk;
 	uint32_t boot_device;     /* Value we read from *boot_device_reg */
 	int ret;
 
@@ -2149,10 +2150,17 @@ static void stfsm_fetch_platform_configs(struct platform_device *pdev)
 	if (ret)
 		goto boot_device_fail;
 
+	/* Mask to apply on boot_device_reg */
+	ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
+	if (ret)
+		goto boot_device_fail;
+
 	ret = regmap_read(regmap, boot_device_reg, &boot_device);
 	if (ret)
 		goto boot_device_fail;
 
+	boot_device &= boot_device_msk;
+
 	if (boot_device != boot_device_spi)
 		fsm->booted_from_spi = false;
 
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Christophe Kerello, Lee Jones, computersforpeace, linux-mtd

From: Christophe Kerello <christophe.kerello@st.com>

This patch adds a mask to be able to get the right boot device selection.

For example:
    for STiH415, value = SYSTEM_STATUS398[4:0]
    for STiH416, value = SYSTEM_STATUS2598[4:0]
    for STiH407, value = SYSTEM_STATUS5561[6:2]

Signed-off-by: Christophe Kerello <christophe.kerello@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 3f74e125..6d535d9 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -2125,6 +2125,7 @@ static void stfsm_fetch_platform_configs(struct platform_device *pdev)
 	struct regmap *regmap;
 	uint32_t boot_device_reg;
 	uint32_t boot_device_spi;
+	uint32_t boot_device_msk;
 	uint32_t boot_device;     /* Value we read from *boot_device_reg */
 	int ret;
 
@@ -2149,10 +2150,17 @@ static void stfsm_fetch_platform_configs(struct platform_device *pdev)
 	if (ret)
 		goto boot_device_fail;
 
+	/* Mask to apply on boot_device_reg */
+	ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
+	if (ret)
+		goto boot_device_fail;
+
 	ret = regmap_read(regmap, boot_device_reg, &boot_device);
 	if (ret)
 		goto boot_device_fail;
 
+	boot_device &= boot_device_msk;
+
 	if (boot_device != boot_device_spi)
 		fsm->booted_from_spi = false;
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Christophe Kerello <christophe.kerello@st.com>

This patch adds a mask to be able to get the right boot device selection.

For example:
    for STiH415, value = SYSTEM_STATUS398[4:0]
    for STiH416, value = SYSTEM_STATUS2598[4:0]
    for STiH407, value = SYSTEM_STATUS5561[6:2]

Signed-off-by: Christophe Kerello <christophe.kerello@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 3f74e125..6d535d9 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -2125,6 +2125,7 @@ static void stfsm_fetch_platform_configs(struct platform_device *pdev)
 	struct regmap *regmap;
 	uint32_t boot_device_reg;
 	uint32_t boot_device_spi;
+	uint32_t boot_device_msk;
 	uint32_t boot_device;     /* Value we read from *boot_device_reg */
 	int ret;
 
@@ -2149,10 +2150,17 @@ static void stfsm_fetch_platform_configs(struct platform_device *pdev)
 	if (ret)
 		goto boot_device_fail;
 
+	/* Mask to apply on boot_device_reg */
+	ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
+	if (ret)
+		goto boot_device_fail;
+
 	ret = regmap_read(regmap, boot_device_reg, &boot_device);
 	if (ret)
 		goto boot_device_fail;
 
+	boot_device &= boot_device_msk;
+
 	if (boot_device != boot_device_spi)
 		fsm->booted_from_spi = false;
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 10/10] mtd: st_spi_fsm: General tidy-up
  2014-05-22 11:23 ` Lee Jones
  (?)
@ 2014-05-22 11:24   ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: computersforpeace, linux-mtd, Lee Jones

Due to the nature of the port (lots of copy/paste) much of the white-space
is taken up by spaces instead of tab separators. This patch aims to change
that.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 298 +++++++++++++++++++--------------------
 1 file changed, 149 insertions(+), 149 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 6d535d9..c4cccf9 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -82,9 +82,9 @@
 #define SPI_CFG_CS_SETUPHOLD(x)		(((x) & 0xff) << 16)
 #define SPI_CFG_DATA_HOLD(x)		(((x) & 0xff) << 24)
 
-#define SPI_CFG_DEFAULT_MIN_CS_HIGH    SPI_CFG_MIN_CS_HIGH(0x0AA)
-#define SPI_CFG_DEFAULT_CS_SETUPHOLD   SPI_CFG_CS_SETUPHOLD(0xA0)
-#define SPI_CFG_DEFAULT_DATA_HOLD      SPI_CFG_DATA_HOLD(0x00)
+#define SPI_CFG_DEFAULT_MIN_CS_HIGH	SPI_CFG_MIN_CS_HIGH(0x0AA)
+#define SPI_CFG_DEFAULT_CS_SETUPHOLD	SPI_CFG_CS_SETUPHOLD(0xA0)
+#define SPI_CFG_DEFAULT_DATA_HOLD	SPI_CFG_DATA_HOLD(0x00)
 
 /*
  * Register: SPI_FAST_SEQ_TRANSFER_SIZE
@@ -164,7 +164,7 @@
 #define STFSM_OPC_ADD			0x2
 #define STFSM_OPC_STA			0x3
 #define STFSM_OPC_MODE			0x4
-#define STFSM_OPC_DUMMY		0x5
+#define STFSM_OPC_DUMMY			0x5
 #define STFSM_OPC_DATA			0x6
 #define STFSM_OPC_WAIT			0x7
 #define STFSM_OPC_JUMP			0x8
@@ -197,88 +197,87 @@
 #define STFSM_INST_WAIT			STFSM_INSTR(STFSM_OPC_WAIT,	0)
 #define STFSM_INST_STOP			STFSM_INSTR(STFSM_OPC_STOP,	0)
 
-#define STFSM_DEFAULT_EMI_FREQ 100000000UL                        /* 100 MHz */
-#define STFSM_DEFAULT_WR_TIME  (STFSM_DEFAULT_EMI_FREQ * (15/1000)) /* 15ms */
+#define STFSM_DEFAULT_EMI_FREQ		100000000UL	/* 100 MHz */
+#define STFSM_DEFAULT_WR_TIME	(STFSM_DEFAULT_EMI_FREQ * (15/1000)) /* 15ms */
 
-#define STFSM_FLASH_SAFE_FREQ  10000000UL                         /* 10 MHz */
+#define STFSM_FLASH_SAFE_FREQ		10000000UL	/* 10 MHz */
 
-#define STFSM_MAX_WAIT_SEQ_MS  1000     /* FSM execution time */
+#define STFSM_MAX_WAIT_SEQ_MS		1000		/* FSM execution time */
 
 /* S25FLxxxS commands */
-#define S25FL_CMD_WRITE4_1_1_4 0x34
-#define S25FL_CMD_SE4          0xdc
-#define S25FL_CMD_CLSR         0x30
-#define S25FL_CMD_DYBWR                0xe1
-#define S25FL_CMD_DYBRD                0xe0
-#define S25FL_CMD_WRITE4       0x12    /* Note, opcode clashes with
+#define S25FL_CMD_WRITE4_1_1_4		0x34
+#define S25FL_CMD_SE4			0xdc
+#define S25FL_CMD_CLSR			0x30
+#define S25FL_CMD_DYBWR			0xe1
+#define S25FL_CMD_DYBRD			0xe0
+#define S25FL_CMD_WRITE4		0x12    /* Note, opcode clashes with
 					* 'SPINOR_OP_WRITE_1_4_4'
 					* as found on N25Qxxx devices! */
-
 /* Status register */
-#define FLASH_STATUS_BUSY      0x01
-#define FLASH_STATUS_WEL       0x02
-#define FLASH_STATUS_BP0       0x04
-#define FLASH_STATUS_BP1       0x08
-#define FLASH_STATUS_BP2       0x10
-#define FLASH_STATUS_SRWP0     0x80
-#define FLASH_STATUS_TIMEOUT   0xff
+#define FLASH_STATUS_BUSY		0x01
+#define FLASH_STATUS_WEL		0x02
+#define FLASH_STATUS_BP0		0x04
+#define FLASH_STATUS_BP1		0x08
+#define FLASH_STATUS_BP2		0x10
+#define FLASH_STATUS_SRWP0		0x80
+#define FLASH_STATUS_TIMEOUT		0xff
 
 /* Maximum READID length */
-#define MAX_READID_LEN         6
-#define MAX_READID_LEN_ALIGNED ALIGN(MAX_READID_LEN, 4)
+#define MAX_READID_LEN	 		6
+#define MAX_READID_LEN_ALIGNED 		ALIGN(MAX_READID_LEN, 4)
 
 /* S25FL Error Flags */
-#define S25FL_STATUS_E_ERR     0x20
-#define S25FL_STATUS_P_ERR     0x40
+#define S25FL_STATUS_E_ERR		0x20
+#define S25FL_STATUS_P_ERR		0x40
 
 /* N25Q - READ/WRITE/CLEAR NON/VOLATILE STATUS/CONFIG Registers */
-#define N25Q_CMD_RFSR          0x70
-#define N25Q_CMD_CLFSR         0x50
-#define N25Q_CMD_WRVCR         0x81
-#define N25Q_CMD_RDVCR         0x85
-#define N25Q_CMD_RDVECR        0x65
-#define N25Q_CMD_RDNVCR        0xb5
-#define N25Q_CMD_WRNVCR        0xb1
+#define N25Q_CMD_RFSR			0x70
+#define N25Q_CMD_CLFSR			0x50
+#define N25Q_CMD_WRVCR			0x81
+#define N25Q_CMD_RDVCR			0x85
+#define N25Q_CMD_RDVECR			0x65
+#define N25Q_CMD_RDNVCR			0xb5
+#define N25Q_CMD_WRNVCR			0xb1
 
 /* N25Q Flags Status Register: Error Flags */
-#define N25Q_FLAGS_ERR_ERASE   BIT(5)
-#define N25Q_FLAGS_ERR_PROG    BIT(4)
-#define N25Q_FLAGS_ERR_VPP     BIT(3)
-#define N25Q_FLAGS_ERR_PROT    BIT(1)
-#define N25Q_FLAGS_ERROR       (N25Q_FLAGS_ERR_ERASE   | \
-                                N25Q_FLAGS_ERR_PROG    | \
-                                N25Q_FLAGS_ERR_VPP     | \
-                                N25Q_FLAGS_ERR_PROT)
-
-#define FLASH_PAGESIZE         256			/* In Bytes    */
-#define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
+#define N25Q_FLAGS_ERR_ERASE		BIT(5)
+#define N25Q_FLAGS_ERR_PROG		BIT(4)
+#define N25Q_FLAGS_ERR_VPP		BIT(3)
+#define N25Q_FLAGS_ERR_PROT		BIT(1)
+#define N25Q_FLAGS_ERROR		(N25Q_FLAGS_ERR_ERASE	| \
+					 N25Q_FLAGS_ERR_PROG	| \
+					 N25Q_FLAGS_ERR_VPP	| \
+					 N25Q_FLAGS_ERR_PROT)
+
+#define FLASH_PAGESIZE			256		     /* In Bytes    */
+#define FLASH_PAGESIZE_32		(FLASH_PAGESIZE / 4) /* In uint32_t */
 /* Maximum operation times (in ms) */
-#define FLASH_MAX_CHIP_ERASE_MS 500000          /* Chip Erase time */
-#define FLASH_MAX_SEC_ERASE_MS  30000           /* Sector Erase time */
-#define FLASH_MAX_PAGE_WRITE_MS 100             /* Write Page time */
-#define FLASH_MAX_STA_WRITE_MS  4000            /* Write status reg time */
-#define FSM_MAX_WAIT_SEQ_MS     1000            /* FSM execution time */
+#define FLASH_MAX_CHIP_ERASE_MS		500000	/* Chip Erase time */
+#define FLASH_MAX_SEC_ERASE_MS		30000	/* Sector Erase time */
+#define FLASH_MAX_PAGE_WRITE_MS		100	/* Write Page time */
+#define FLASH_MAX_STA_WRITE_MS		4000	/* Write status reg time */
+#define FSM_MAX_WAIT_SEQ_MS		1000	/* FSM execution time */
 
 /*
  * Flags to tweak operation of default read/write/erase routines
  */
-#define CFG_READ_TOGGLE_32BIT_ADDR     0x00000001
-#define CFG_WRITE_TOGGLE_32BIT_ADDR    0x00000002
-#define CFG_ERASESEC_TOGGLE_32BIT_ADDR 0x00000008
-#define CFG_S25FL_CHECK_ERROR_FLAGS    0x00000010
-#define CFG_N25Q_CHECK_ERROR_FLAGS     0x00000020
+#define CFG_READ_TOGGLE_32BIT_ADDR		0x00000001
+#define CFG_WRITE_TOGGLE_32BIT_ADDR		0x00000002
+#define CFG_ERASESEC_TOGGLE_32BIT_ADDR		0x00000008
+#define CFG_S25FL_CHECK_ERROR_FLAGS		0x00000010
+#define CFG_N25Q_CHECK_ERROR_FLAGS		0x00000020
 
 struct stfsm_seq {
-	uint32_t data_size;
-	uint32_t addr1;
-	uint32_t addr2;
-	uint32_t addr_cfg;
-	uint32_t seq_opc[5];
-	uint32_t mode;
-	uint32_t dummy;
-	uint32_t status;
-	uint8_t  seq[16];
-	uint32_t seq_cfg;
+	uint32_t 		data_size;
+	uint32_t 		addr1;
+	uint32_t 		addr2;
+	uint32_t 		addr_cfg;
+	uint32_t 		seq_opc[5];
+	uint32_t 		mode;
+	uint32_t 		dummy;
+	uint32_t 		status;
+	uint8_t  		seq[16];
+	uint32_t 		seq_cfg;
 } __packed __aligned(4);
 
 struct stfsm {
@@ -287,51 +286,52 @@ struct stfsm {
 	struct resource		*region;
 	struct mtd_info		mtd;
 	struct mutex		lock;
-	struct flash_info       *info;
-	struct clk              *clk;
-
-	uint32_t                configuration;
-	uint32_t                fifo_dir_delay;
-	bool                    booted_from_spi;
-	bool                    reset_signal;
-	bool                    reset_por;
-
-	struct stfsm_seq stfsm_seq_read;
-	struct stfsm_seq stfsm_seq_write;
-	struct stfsm_seq stfsm_seq_en_32bit_addr;
+	struct flash_info	*info;
+	struct clk		*clk;
+
+	uint32_t		configuration;
+	uint32_t		fifo_dir_delay;
+	bool			booted_from_spi;
+	bool			reset_signal;
+	bool			reset_por;
+
+	struct stfsm_seq 	stfsm_seq_read;
+	struct stfsm_seq 	stfsm_seq_write;
+	struct stfsm_seq 	stfsm_seq_en_32bit_addr;
 };
 
 /* Parameters to configure a READ or WRITE FSM sequence */
 struct seq_rw_config {
-	uint32_t        flags;          /* flags to support config */
-	uint8_t         cmd;            /* FLASH command */
-	int             write;          /* Write Sequence */
-	uint8_t         addr_pads;      /* No. of addr pads (MODE & DUMMY) */
-	uint8_t         data_pads;      /* No. of data pads */
-	uint8_t         mode_data;      /* MODE data */
-	uint8_t         mode_cycles;    /* No. of MODE cycles */
-	uint8_t         dummy_cycles;   /* No. of DUMMY cycles */
+	uint32_t		flags;		/* flags to support config */
+	uint8_t	 		cmd;		/* FLASH command */
+	int			write;		/* Write Sequence */
+	uint8_t	 		addr_pads;	/* No. of addr pads */
+						/* (MODE & DUMMY) */
+	uint8_t	 		data_pads;	/* No. of data pads */
+	uint8_t	 		mode_data;	/* MODE data */
+	uint8_t	 		mode_cycles;	/* No. of MODE cycles */
+	uint8_t	 		dummy_cycles;	/* No. of DUMMY cycles */
 };
 
 /* SPI Flash Device Table */
 struct flash_info {
-	char            *name;
+	char			*name;
 	/* READID data, as returned by 'FLASH_CMD_RDID' (0x9f). */
-	u8              readid[MAX_READID_LEN];
-	int             readid_len;
+	u8			readid[MAX_READID_LEN];
+	int			readid_len;
 	/*
 	 * The size listed here is what works with SPINOR_OP_SE, which isn't
 	 * necessarily called a "sector" by the vendor.
 	 */
-	unsigned        sector_size;
-	u16             n_sectors;
-	u32             flags;
+	unsigned		sector_size;
+	u16			n_sectors;
+	u32			flags;
 	/*
 	 * Note, where FAST_READ is supported, freq_max specifies the
 	 * FAST_READ frequency, not the READ frequency.
 	 */
-	u32             max_freq;
-	int             (*config)(struct stfsm *);
+	u32			max_freq;
+	int			(*config)(struct stfsm *);
 };
 
 /* Device with standard 3-byte JEDEC ID */
@@ -385,9 +385,9 @@ static struct flash_info flash_types[] = {
 	JEDEC_INFO("m25p64",  0x202017,  64 * 1024, 128, M25P_FLAG, 50, NULL),
 	JEDEC_INFO("m25p128", 0x202018, 256 * 1024,  64, M25P_FLAG, 50, NULL),
 
-#define M25PX_FLAG (FLASH_FLAG_READ_WRITE      |	\
-		    FLASH_FLAG_READ_FAST        |	\
-		    FLASH_FLAG_READ_1_1_2       |	\
+#define M25PX_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		    FLASH_FLAG_READ_FAST	|	\
+		    FLASH_FLAG_READ_1_1_2	|	\
 		    FLASH_FLAG_WRITE_1_1_2)
 	JEDEC_INFO("m25px32", 0x207116,  64 * 1024,  64, M25PX_FLAG, 75, NULL),
 	JEDEC_INFO("m25px64", 0x207117,  64 * 1024, 128, M25PX_FLAG, 75, NULL),
@@ -396,12 +396,12 @@ static struct flash_info flash_types[] = {
 	 *     - Support for 'FLASH_FLAG_WRITE_1_4_4' is omitted for devices
 	 *       where operating frequency must be reduced.
 	 */
-#define MX25_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
-		   FLASH_FLAG_READ_1_2_2        |	\
-		   FLASH_FLAG_READ_1_1_4        |	\
-		   FLASH_FLAG_SE_4K             |	\
+#define MX25_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST		|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
+		   FLASH_FLAG_READ_1_2_2	|	\
+		   FLASH_FLAG_READ_1_1_4	|	\
+		   FLASH_FLAG_SE_4K		|	\
 		   FLASH_FLAG_SE_32K)
 	JEDEC_INFO("mx25l3255e",  0xc29e16, 64 * 1024, 64,
 		   (MX25_FLAG | FLASH_FLAG_WRITE_1_4_4), 86, stfsm_mx25_config),
@@ -411,34 +411,34 @@ static struct flash_info flash_types[] = {
 		   (MX25_FLAG | FLASH_FLAG_RESET), 70, stfsm_mx25_config),
 
 	/* Micron N25Qxxx */
-#define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
-		   FLASH_FLAG_READ_1_2_2        |	\
-		   FLASH_FLAG_READ_1_1_4        |	\
-		   FLASH_FLAG_READ_1_4_4        |	\
-		   FLASH_FLAG_WRITE_1_1_2       |	\
-		   FLASH_FLAG_WRITE_1_2_2       |	\
-		   FLASH_FLAG_WRITE_1_1_4       |	\
+#define N25Q_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST		|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
+		   FLASH_FLAG_READ_1_2_2	|	\
+		   FLASH_FLAG_READ_1_1_4	|	\
+		   FLASH_FLAG_READ_1_4_4	|	\
+		   FLASH_FLAG_WRITE_1_1_2	|	\
+		   FLASH_FLAG_WRITE_1_2_2	|	\
+		   FLASH_FLAG_WRITE_1_1_4	|	\
 		   FLASH_FLAG_WRITE_1_4_4)
 	JEDEC_INFO("n25q128", 0x20ba18, 64 * 1024,  256,
 		   N25Q_FLAG, 108, stfsm_n25q_config),
 
        /* Micron N25Q256/N25Q512/N25Q00A (32-bit ADDR devices)
-        *
-        * Versions are available with or without a dedicated RESET# pin
-        * (e.g. N25Q512A83GSF40G vs. N25Q512A13GSF40G).  To complicate matters,
-        * the versions that include a RESET# pin (Feature Set = 8) require a
-        * different opcode for the FLASH_CMD_WRITE_1_4_4 command.
-        * Unfortunately it is not possible to determine easily at run-time
-        * which version is being used.  We therefore remove support for
-        * FLASH_FLAG_WRITE_1_4_4 (falling back to FLASH_FLAG_WRITE_1_1_4), and
-        * defer overall support for RESET# to the board-level platform/Device
-        * Tree property "reset-signal".
-        */
-#define N25Q_32BIT_ADDR_FLAG  ((N25Q_FLAG              |	\
-				FLASH_FLAG_32BIT_ADDR  |	\
-				FLASH_FLAG_RESET)      &	\
+	*
+	* Versions are available with or without a dedicated RESET# pin
+	* (e.g. N25Q512A83GSF40G vs. N25Q512A13GSF40G).  To complicate matters,
+	* the versions that include a RESET# pin (Feature Set = 8) require a
+	* different opcode for the FLASH_CMD_WRITE_1_4_4 command.
+	* Unfortunately it is not possible to determine easily at run-time
+	* which version is being used.  We therefore remove support for
+	* FLASH_FLAG_WRITE_1_4_4 (falling back to FLASH_FLAG_WRITE_1_1_4), and
+	* defer overall support for RESET# to the board-level platform/Device
+	* Tree property "reset-signal".
+	*/
+#define N25Q_32BIT_ADDR_FLAG  ((N25Q_FLAG		|	\
+				FLASH_FLAG_32BIT_ADDR	|	\
+				FLASH_FLAG_RESET)	&	\
 			       ~FLASH_FLAG_WRITE_1_4_4)
 	JEDEC_INFO("n25q256", 0x20ba19, 64 * 1024,   512,
 		   N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
@@ -452,12 +452,12 @@ static struct flash_info flash_types[] = {
 	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
 	 *     - S25FL128Px devices do not support DUAL or QUAD I/O
 	 */
-#define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE  |	\
-			FLASH_FLAG_READ_1_1_2   |	\
-			FLASH_FLAG_READ_1_2_2   |	\
-			FLASH_FLAG_READ_1_1_4   |	\
-			FLASH_FLAG_READ_1_4_4   |	\
-			FLASH_FLAG_WRITE_1_1_4  |	\
+#define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE	|	\
+			FLASH_FLAG_READ_1_1_2	|	\
+			FLASH_FLAG_READ_1_2_2	|	\
+			FLASH_FLAG_READ_1_1_4	|	\
+			FLASH_FLAG_READ_1_4_4	|	\
+			FLASH_FLAG_WRITE_1_1_4	|	\
 			FLASH_FLAG_READ_FAST)
 	RDID_INFO("s25fl032p", RDID({0x01, 0x02, 0x15, 0x4d, 0x00}), 5,
 		  64 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
@@ -482,8 +482,8 @@ static struct flash_info flash_types[] = {
 	 *       may default to locked state on power-on.
 	 *     - S25FL127Sx handled as S25FL128Sx
 	 */
-#define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
-			FLASH_FLAG_RESET        |	\
+#define S25FLXXXS_FLAG (S25FLXXXP_FLAG	 	|	\
+			FLASH_FLAG_RESET	|	\
 			FLASH_FLAG_DYB_LOCKING)
 	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00, 0x80}), 6,
 		  256 * 1024, 64, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
@@ -494,9 +494,9 @@ static struct flash_info flash_types[] = {
 	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01, 0x80}), 6,
 		  64 * 1024, 512, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
 
-#define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
+#define W25X_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST	 	|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
 		   FLASH_FLAG_WRITE_1_1_2)
 	JEDEC_INFO("w25x40", 0xef3013, 64 * 1024,   8, W25X_FLAG, 75, NULL),
 	JEDEC_INFO("w25x80", 0xef3014, 64 * 1024,  16, W25X_FLAG, 75, NULL),
@@ -505,12 +505,12 @@ static struct flash_info flash_types[] = {
 	JEDEC_INFO("w25x64", 0xef3017, 64 * 1024, 128, W25X_FLAG, 75, NULL),
 
 	/* Winbond -- w25q "blocks" are 64K, "sectors" are 4KiB */
-#define W25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
-		   FLASH_FLAG_READ_1_2_2        |	\
-		   FLASH_FLAG_READ_1_1_4        |	\
-		   FLASH_FLAG_READ_1_4_4        |	\
+#define W25Q_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST		|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
+		   FLASH_FLAG_READ_1_2_2	|	\
+		   FLASH_FLAG_READ_1_1_4	|	\
+		   FLASH_FLAG_READ_1_4_4	|	\
 		   FLASH_FLAG_WRITE_1_1_4)
 	JEDEC_INFO("w25q80", 0xef4014, 64 * 1024,  16,
 		   W25Q_FLAG, 80, stfsm_w25q_config),
@@ -581,7 +581,7 @@ static struct seq_rw_config n25q_read3_configs[] = {
 
 /* N25Q 4-byte Address READ configurations
  *	- use special 4-byte address READ commands (reduces overheads, and
- *        reduces risk of hitting watchdog reset issues).
+ *	reduces risk of hitting watchdog reset issues).
  *	- 'FAST' variants configured for 8 dummy cycles (see note above.)
  */
 static struct seq_rw_config n25q_read4_configs[] = {
@@ -643,7 +643,7 @@ static struct seq_rw_config stfsm_s25fl_read4_configs[] = {
 static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
 	{FLASH_FLAG_WRITE_1_1_4, S25FL_CMD_WRITE4_1_1_4, 1, 1, 4, 0x00, 0, 0},
 	{FLASH_FLAG_READ_WRITE,  S25FL_CMD_WRITE4,       1, 1, 1, 0x00, 0, 0},
-	{0x00,                   0,                      0, 0, 0, 0x00, 0, 0},
+	{0x00,		   0,		      0, 0, 0, 0x00, 0, 0},
 };
 
 /*
@@ -868,12 +868,12 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, uint32_t size)
  * With this in mind, a two stage process is used to the clear the FIFO:
  *
  *     1. Read any complete 32-bit words from the FIFO, as reported by the
- *        SPI_FAST_SEQ_STA register.
+ *	SPI_FAST_SEQ_STA register.
  *
  *     2. Mop up any remaining bytes.  At this point, it is not known if there
- *        are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy FSM
- *        sequence is used to load one byte at a time, until a complete 32-bit
- *        word is formed; at most, 4 bytes will need to be loaded.
+ *	are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy FSM
+ *	sequence is used to load one byte at a time, until a complete 32-bit
+ *	word is formed; at most, 4 bytes will need to be loaded.
  *
  * [1] It is theoretically possible for the FIFO to contain an arbitrary number
  *     of bits.  However, since there are no known use-cases that leave
@@ -2098,7 +2098,7 @@ static int stfsm_init(struct stfsm *fsm)
 		return ret;
 
 	/* Set timing parameters */
-	writel(SPI_CFG_DEVICE_ST            |
+	writel(SPI_CFG_DEVICE_ST	    |
 	       SPI_CFG_DEFAULT_MIN_CS_HIGH  |
 	       SPI_CFG_DEFAULT_CS_SETUPHOLD |
 	       SPI_CFG_DEFAULT_DATA_HOLD,
@@ -2317,7 +2317,7 @@ static struct platform_driver stfsm_driver = {
 		.name	= "st-spi-fsm",
 		.owner	= THIS_MODULE,
 		.of_match_table = stfsm_match,
-		.pm     = &stfsm_pm_ops,
+		.pm	= &stfsm_pm_ops,
 	},
 };
 module_platform_driver(stfsm_driver);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 10/10] mtd: st_spi_fsm: General tidy-up
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: Lee Jones, computersforpeace, linux-mtd

Due to the nature of the port (lots of copy/paste) much of the white-space
is taken up by spaces instead of tab separators. This patch aims to change
that.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 298 +++++++++++++++++++--------------------
 1 file changed, 149 insertions(+), 149 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 6d535d9..c4cccf9 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -82,9 +82,9 @@
 #define SPI_CFG_CS_SETUPHOLD(x)		(((x) & 0xff) << 16)
 #define SPI_CFG_DATA_HOLD(x)		(((x) & 0xff) << 24)
 
-#define SPI_CFG_DEFAULT_MIN_CS_HIGH    SPI_CFG_MIN_CS_HIGH(0x0AA)
-#define SPI_CFG_DEFAULT_CS_SETUPHOLD   SPI_CFG_CS_SETUPHOLD(0xA0)
-#define SPI_CFG_DEFAULT_DATA_HOLD      SPI_CFG_DATA_HOLD(0x00)
+#define SPI_CFG_DEFAULT_MIN_CS_HIGH	SPI_CFG_MIN_CS_HIGH(0x0AA)
+#define SPI_CFG_DEFAULT_CS_SETUPHOLD	SPI_CFG_CS_SETUPHOLD(0xA0)
+#define SPI_CFG_DEFAULT_DATA_HOLD	SPI_CFG_DATA_HOLD(0x00)
 
 /*
  * Register: SPI_FAST_SEQ_TRANSFER_SIZE
@@ -164,7 +164,7 @@
 #define STFSM_OPC_ADD			0x2
 #define STFSM_OPC_STA			0x3
 #define STFSM_OPC_MODE			0x4
-#define STFSM_OPC_DUMMY		0x5
+#define STFSM_OPC_DUMMY			0x5
 #define STFSM_OPC_DATA			0x6
 #define STFSM_OPC_WAIT			0x7
 #define STFSM_OPC_JUMP			0x8
@@ -197,88 +197,87 @@
 #define STFSM_INST_WAIT			STFSM_INSTR(STFSM_OPC_WAIT,	0)
 #define STFSM_INST_STOP			STFSM_INSTR(STFSM_OPC_STOP,	0)
 
-#define STFSM_DEFAULT_EMI_FREQ 100000000UL                        /* 100 MHz */
-#define STFSM_DEFAULT_WR_TIME  (STFSM_DEFAULT_EMI_FREQ * (15/1000)) /* 15ms */
+#define STFSM_DEFAULT_EMI_FREQ		100000000UL	/* 100 MHz */
+#define STFSM_DEFAULT_WR_TIME	(STFSM_DEFAULT_EMI_FREQ * (15/1000)) /* 15ms */
 
-#define STFSM_FLASH_SAFE_FREQ  10000000UL                         /* 10 MHz */
+#define STFSM_FLASH_SAFE_FREQ		10000000UL	/* 10 MHz */
 
-#define STFSM_MAX_WAIT_SEQ_MS  1000     /* FSM execution time */
+#define STFSM_MAX_WAIT_SEQ_MS		1000		/* FSM execution time */
 
 /* S25FLxxxS commands */
-#define S25FL_CMD_WRITE4_1_1_4 0x34
-#define S25FL_CMD_SE4          0xdc
-#define S25FL_CMD_CLSR         0x30
-#define S25FL_CMD_DYBWR                0xe1
-#define S25FL_CMD_DYBRD                0xe0
-#define S25FL_CMD_WRITE4       0x12    /* Note, opcode clashes with
+#define S25FL_CMD_WRITE4_1_1_4		0x34
+#define S25FL_CMD_SE4			0xdc
+#define S25FL_CMD_CLSR			0x30
+#define S25FL_CMD_DYBWR			0xe1
+#define S25FL_CMD_DYBRD			0xe0
+#define S25FL_CMD_WRITE4		0x12    /* Note, opcode clashes with
 					* 'SPINOR_OP_WRITE_1_4_4'
 					* as found on N25Qxxx devices! */
-
 /* Status register */
-#define FLASH_STATUS_BUSY      0x01
-#define FLASH_STATUS_WEL       0x02
-#define FLASH_STATUS_BP0       0x04
-#define FLASH_STATUS_BP1       0x08
-#define FLASH_STATUS_BP2       0x10
-#define FLASH_STATUS_SRWP0     0x80
-#define FLASH_STATUS_TIMEOUT   0xff
+#define FLASH_STATUS_BUSY		0x01
+#define FLASH_STATUS_WEL		0x02
+#define FLASH_STATUS_BP0		0x04
+#define FLASH_STATUS_BP1		0x08
+#define FLASH_STATUS_BP2		0x10
+#define FLASH_STATUS_SRWP0		0x80
+#define FLASH_STATUS_TIMEOUT		0xff
 
 /* Maximum READID length */
-#define MAX_READID_LEN         6
-#define MAX_READID_LEN_ALIGNED ALIGN(MAX_READID_LEN, 4)
+#define MAX_READID_LEN	 		6
+#define MAX_READID_LEN_ALIGNED 		ALIGN(MAX_READID_LEN, 4)
 
 /* S25FL Error Flags */
-#define S25FL_STATUS_E_ERR     0x20
-#define S25FL_STATUS_P_ERR     0x40
+#define S25FL_STATUS_E_ERR		0x20
+#define S25FL_STATUS_P_ERR		0x40
 
 /* N25Q - READ/WRITE/CLEAR NON/VOLATILE STATUS/CONFIG Registers */
-#define N25Q_CMD_RFSR          0x70
-#define N25Q_CMD_CLFSR         0x50
-#define N25Q_CMD_WRVCR         0x81
-#define N25Q_CMD_RDVCR         0x85
-#define N25Q_CMD_RDVECR        0x65
-#define N25Q_CMD_RDNVCR        0xb5
-#define N25Q_CMD_WRNVCR        0xb1
+#define N25Q_CMD_RFSR			0x70
+#define N25Q_CMD_CLFSR			0x50
+#define N25Q_CMD_WRVCR			0x81
+#define N25Q_CMD_RDVCR			0x85
+#define N25Q_CMD_RDVECR			0x65
+#define N25Q_CMD_RDNVCR			0xb5
+#define N25Q_CMD_WRNVCR			0xb1
 
 /* N25Q Flags Status Register: Error Flags */
-#define N25Q_FLAGS_ERR_ERASE   BIT(5)
-#define N25Q_FLAGS_ERR_PROG    BIT(4)
-#define N25Q_FLAGS_ERR_VPP     BIT(3)
-#define N25Q_FLAGS_ERR_PROT    BIT(1)
-#define N25Q_FLAGS_ERROR       (N25Q_FLAGS_ERR_ERASE   | \
-                                N25Q_FLAGS_ERR_PROG    | \
-                                N25Q_FLAGS_ERR_VPP     | \
-                                N25Q_FLAGS_ERR_PROT)
-
-#define FLASH_PAGESIZE         256			/* In Bytes    */
-#define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
+#define N25Q_FLAGS_ERR_ERASE		BIT(5)
+#define N25Q_FLAGS_ERR_PROG		BIT(4)
+#define N25Q_FLAGS_ERR_VPP		BIT(3)
+#define N25Q_FLAGS_ERR_PROT		BIT(1)
+#define N25Q_FLAGS_ERROR		(N25Q_FLAGS_ERR_ERASE	| \
+					 N25Q_FLAGS_ERR_PROG	| \
+					 N25Q_FLAGS_ERR_VPP	| \
+					 N25Q_FLAGS_ERR_PROT)
+
+#define FLASH_PAGESIZE			256		     /* In Bytes    */
+#define FLASH_PAGESIZE_32		(FLASH_PAGESIZE / 4) /* In uint32_t */
 /* Maximum operation times (in ms) */
-#define FLASH_MAX_CHIP_ERASE_MS 500000          /* Chip Erase time */
-#define FLASH_MAX_SEC_ERASE_MS  30000           /* Sector Erase time */
-#define FLASH_MAX_PAGE_WRITE_MS 100             /* Write Page time */
-#define FLASH_MAX_STA_WRITE_MS  4000            /* Write status reg time */
-#define FSM_MAX_WAIT_SEQ_MS     1000            /* FSM execution time */
+#define FLASH_MAX_CHIP_ERASE_MS		500000	/* Chip Erase time */
+#define FLASH_MAX_SEC_ERASE_MS		30000	/* Sector Erase time */
+#define FLASH_MAX_PAGE_WRITE_MS		100	/* Write Page time */
+#define FLASH_MAX_STA_WRITE_MS		4000	/* Write status reg time */
+#define FSM_MAX_WAIT_SEQ_MS		1000	/* FSM execution time */
 
 /*
  * Flags to tweak operation of default read/write/erase routines
  */
-#define CFG_READ_TOGGLE_32BIT_ADDR     0x00000001
-#define CFG_WRITE_TOGGLE_32BIT_ADDR    0x00000002
-#define CFG_ERASESEC_TOGGLE_32BIT_ADDR 0x00000008
-#define CFG_S25FL_CHECK_ERROR_FLAGS    0x00000010
-#define CFG_N25Q_CHECK_ERROR_FLAGS     0x00000020
+#define CFG_READ_TOGGLE_32BIT_ADDR		0x00000001
+#define CFG_WRITE_TOGGLE_32BIT_ADDR		0x00000002
+#define CFG_ERASESEC_TOGGLE_32BIT_ADDR		0x00000008
+#define CFG_S25FL_CHECK_ERROR_FLAGS		0x00000010
+#define CFG_N25Q_CHECK_ERROR_FLAGS		0x00000020
 
 struct stfsm_seq {
-	uint32_t data_size;
-	uint32_t addr1;
-	uint32_t addr2;
-	uint32_t addr_cfg;
-	uint32_t seq_opc[5];
-	uint32_t mode;
-	uint32_t dummy;
-	uint32_t status;
-	uint8_t  seq[16];
-	uint32_t seq_cfg;
+	uint32_t 		data_size;
+	uint32_t 		addr1;
+	uint32_t 		addr2;
+	uint32_t 		addr_cfg;
+	uint32_t 		seq_opc[5];
+	uint32_t 		mode;
+	uint32_t 		dummy;
+	uint32_t 		status;
+	uint8_t  		seq[16];
+	uint32_t 		seq_cfg;
 } __packed __aligned(4);
 
 struct stfsm {
@@ -287,51 +286,52 @@ struct stfsm {
 	struct resource		*region;
 	struct mtd_info		mtd;
 	struct mutex		lock;
-	struct flash_info       *info;
-	struct clk              *clk;
-
-	uint32_t                configuration;
-	uint32_t                fifo_dir_delay;
-	bool                    booted_from_spi;
-	bool                    reset_signal;
-	bool                    reset_por;
-
-	struct stfsm_seq stfsm_seq_read;
-	struct stfsm_seq stfsm_seq_write;
-	struct stfsm_seq stfsm_seq_en_32bit_addr;
+	struct flash_info	*info;
+	struct clk		*clk;
+
+	uint32_t		configuration;
+	uint32_t		fifo_dir_delay;
+	bool			booted_from_spi;
+	bool			reset_signal;
+	bool			reset_por;
+
+	struct stfsm_seq 	stfsm_seq_read;
+	struct stfsm_seq 	stfsm_seq_write;
+	struct stfsm_seq 	stfsm_seq_en_32bit_addr;
 };
 
 /* Parameters to configure a READ or WRITE FSM sequence */
 struct seq_rw_config {
-	uint32_t        flags;          /* flags to support config */
-	uint8_t         cmd;            /* FLASH command */
-	int             write;          /* Write Sequence */
-	uint8_t         addr_pads;      /* No. of addr pads (MODE & DUMMY) */
-	uint8_t         data_pads;      /* No. of data pads */
-	uint8_t         mode_data;      /* MODE data */
-	uint8_t         mode_cycles;    /* No. of MODE cycles */
-	uint8_t         dummy_cycles;   /* No. of DUMMY cycles */
+	uint32_t		flags;		/* flags to support config */
+	uint8_t	 		cmd;		/* FLASH command */
+	int			write;		/* Write Sequence */
+	uint8_t	 		addr_pads;	/* No. of addr pads */
+						/* (MODE & DUMMY) */
+	uint8_t	 		data_pads;	/* No. of data pads */
+	uint8_t	 		mode_data;	/* MODE data */
+	uint8_t	 		mode_cycles;	/* No. of MODE cycles */
+	uint8_t	 		dummy_cycles;	/* No. of DUMMY cycles */
 };
 
 /* SPI Flash Device Table */
 struct flash_info {
-	char            *name;
+	char			*name;
 	/* READID data, as returned by 'FLASH_CMD_RDID' (0x9f). */
-	u8              readid[MAX_READID_LEN];
-	int             readid_len;
+	u8			readid[MAX_READID_LEN];
+	int			readid_len;
 	/*
 	 * The size listed here is what works with SPINOR_OP_SE, which isn't
 	 * necessarily called a "sector" by the vendor.
 	 */
-	unsigned        sector_size;
-	u16             n_sectors;
-	u32             flags;
+	unsigned		sector_size;
+	u16			n_sectors;
+	u32			flags;
 	/*
 	 * Note, where FAST_READ is supported, freq_max specifies the
 	 * FAST_READ frequency, not the READ frequency.
 	 */
-	u32             max_freq;
-	int             (*config)(struct stfsm *);
+	u32			max_freq;
+	int			(*config)(struct stfsm *);
 };
 
 /* Device with standard 3-byte JEDEC ID */
@@ -385,9 +385,9 @@ static struct flash_info flash_types[] = {
 	JEDEC_INFO("m25p64",  0x202017,  64 * 1024, 128, M25P_FLAG, 50, NULL),
 	JEDEC_INFO("m25p128", 0x202018, 256 * 1024,  64, M25P_FLAG, 50, NULL),
 
-#define M25PX_FLAG (FLASH_FLAG_READ_WRITE      |	\
-		    FLASH_FLAG_READ_FAST        |	\
-		    FLASH_FLAG_READ_1_1_2       |	\
+#define M25PX_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		    FLASH_FLAG_READ_FAST	|	\
+		    FLASH_FLAG_READ_1_1_2	|	\
 		    FLASH_FLAG_WRITE_1_1_2)
 	JEDEC_INFO("m25px32", 0x207116,  64 * 1024,  64, M25PX_FLAG, 75, NULL),
 	JEDEC_INFO("m25px64", 0x207117,  64 * 1024, 128, M25PX_FLAG, 75, NULL),
@@ -396,12 +396,12 @@ static struct flash_info flash_types[] = {
 	 *     - Support for 'FLASH_FLAG_WRITE_1_4_4' is omitted for devices
 	 *       where operating frequency must be reduced.
 	 */
-#define MX25_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
-		   FLASH_FLAG_READ_1_2_2        |	\
-		   FLASH_FLAG_READ_1_1_4        |	\
-		   FLASH_FLAG_SE_4K             |	\
+#define MX25_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST		|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
+		   FLASH_FLAG_READ_1_2_2	|	\
+		   FLASH_FLAG_READ_1_1_4	|	\
+		   FLASH_FLAG_SE_4K		|	\
 		   FLASH_FLAG_SE_32K)
 	JEDEC_INFO("mx25l3255e",  0xc29e16, 64 * 1024, 64,
 		   (MX25_FLAG | FLASH_FLAG_WRITE_1_4_4), 86, stfsm_mx25_config),
@@ -411,34 +411,34 @@ static struct flash_info flash_types[] = {
 		   (MX25_FLAG | FLASH_FLAG_RESET), 70, stfsm_mx25_config),
 
 	/* Micron N25Qxxx */
-#define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
-		   FLASH_FLAG_READ_1_2_2        |	\
-		   FLASH_FLAG_READ_1_1_4        |	\
-		   FLASH_FLAG_READ_1_4_4        |	\
-		   FLASH_FLAG_WRITE_1_1_2       |	\
-		   FLASH_FLAG_WRITE_1_2_2       |	\
-		   FLASH_FLAG_WRITE_1_1_4       |	\
+#define N25Q_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST		|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
+		   FLASH_FLAG_READ_1_2_2	|	\
+		   FLASH_FLAG_READ_1_1_4	|	\
+		   FLASH_FLAG_READ_1_4_4	|	\
+		   FLASH_FLAG_WRITE_1_1_2	|	\
+		   FLASH_FLAG_WRITE_1_2_2	|	\
+		   FLASH_FLAG_WRITE_1_1_4	|	\
 		   FLASH_FLAG_WRITE_1_4_4)
 	JEDEC_INFO("n25q128", 0x20ba18, 64 * 1024,  256,
 		   N25Q_FLAG, 108, stfsm_n25q_config),
 
        /* Micron N25Q256/N25Q512/N25Q00A (32-bit ADDR devices)
-        *
-        * Versions are available with or without a dedicated RESET# pin
-        * (e.g. N25Q512A83GSF40G vs. N25Q512A13GSF40G).  To complicate matters,
-        * the versions that include a RESET# pin (Feature Set = 8) require a
-        * different opcode for the FLASH_CMD_WRITE_1_4_4 command.
-        * Unfortunately it is not possible to determine easily at run-time
-        * which version is being used.  We therefore remove support for
-        * FLASH_FLAG_WRITE_1_4_4 (falling back to FLASH_FLAG_WRITE_1_1_4), and
-        * defer overall support for RESET# to the board-level platform/Device
-        * Tree property "reset-signal".
-        */
-#define N25Q_32BIT_ADDR_FLAG  ((N25Q_FLAG              |	\
-				FLASH_FLAG_32BIT_ADDR  |	\
-				FLASH_FLAG_RESET)      &	\
+	*
+	* Versions are available with or without a dedicated RESET# pin
+	* (e.g. N25Q512A83GSF40G vs. N25Q512A13GSF40G).  To complicate matters,
+	* the versions that include a RESET# pin (Feature Set = 8) require a
+	* different opcode for the FLASH_CMD_WRITE_1_4_4 command.
+	* Unfortunately it is not possible to determine easily at run-time
+	* which version is being used.  We therefore remove support for
+	* FLASH_FLAG_WRITE_1_4_4 (falling back to FLASH_FLAG_WRITE_1_1_4), and
+	* defer overall support for RESET# to the board-level platform/Device
+	* Tree property "reset-signal".
+	*/
+#define N25Q_32BIT_ADDR_FLAG  ((N25Q_FLAG		|	\
+				FLASH_FLAG_32BIT_ADDR	|	\
+				FLASH_FLAG_RESET)	&	\
 			       ~FLASH_FLAG_WRITE_1_4_4)
 	JEDEC_INFO("n25q256", 0x20ba19, 64 * 1024,   512,
 		   N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
@@ -452,12 +452,12 @@ static struct flash_info flash_types[] = {
 	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
 	 *     - S25FL128Px devices do not support DUAL or QUAD I/O
 	 */
-#define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE  |	\
-			FLASH_FLAG_READ_1_1_2   |	\
-			FLASH_FLAG_READ_1_2_2   |	\
-			FLASH_FLAG_READ_1_1_4   |	\
-			FLASH_FLAG_READ_1_4_4   |	\
-			FLASH_FLAG_WRITE_1_1_4  |	\
+#define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE	|	\
+			FLASH_FLAG_READ_1_1_2	|	\
+			FLASH_FLAG_READ_1_2_2	|	\
+			FLASH_FLAG_READ_1_1_4	|	\
+			FLASH_FLAG_READ_1_4_4	|	\
+			FLASH_FLAG_WRITE_1_1_4	|	\
 			FLASH_FLAG_READ_FAST)
 	RDID_INFO("s25fl032p", RDID({0x01, 0x02, 0x15, 0x4d, 0x00}), 5,
 		  64 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
@@ -482,8 +482,8 @@ static struct flash_info flash_types[] = {
 	 *       may default to locked state on power-on.
 	 *     - S25FL127Sx handled as S25FL128Sx
 	 */
-#define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
-			FLASH_FLAG_RESET        |	\
+#define S25FLXXXS_FLAG (S25FLXXXP_FLAG	 	|	\
+			FLASH_FLAG_RESET	|	\
 			FLASH_FLAG_DYB_LOCKING)
 	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00, 0x80}), 6,
 		  256 * 1024, 64, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
@@ -494,9 +494,9 @@ static struct flash_info flash_types[] = {
 	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01, 0x80}), 6,
 		  64 * 1024, 512, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
 
-#define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
+#define W25X_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST	 	|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
 		   FLASH_FLAG_WRITE_1_1_2)
 	JEDEC_INFO("w25x40", 0xef3013, 64 * 1024,   8, W25X_FLAG, 75, NULL),
 	JEDEC_INFO("w25x80", 0xef3014, 64 * 1024,  16, W25X_FLAG, 75, NULL),
@@ -505,12 +505,12 @@ static struct flash_info flash_types[] = {
 	JEDEC_INFO("w25x64", 0xef3017, 64 * 1024, 128, W25X_FLAG, 75, NULL),
 
 	/* Winbond -- w25q "blocks" are 64K, "sectors" are 4KiB */
-#define W25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
-		   FLASH_FLAG_READ_1_2_2        |	\
-		   FLASH_FLAG_READ_1_1_4        |	\
-		   FLASH_FLAG_READ_1_4_4        |	\
+#define W25Q_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST		|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
+		   FLASH_FLAG_READ_1_2_2	|	\
+		   FLASH_FLAG_READ_1_1_4	|	\
+		   FLASH_FLAG_READ_1_4_4	|	\
 		   FLASH_FLAG_WRITE_1_1_4)
 	JEDEC_INFO("w25q80", 0xef4014, 64 * 1024,  16,
 		   W25Q_FLAG, 80, stfsm_w25q_config),
@@ -581,7 +581,7 @@ static struct seq_rw_config n25q_read3_configs[] = {
 
 /* N25Q 4-byte Address READ configurations
  *	- use special 4-byte address READ commands (reduces overheads, and
- *        reduces risk of hitting watchdog reset issues).
+ *	reduces risk of hitting watchdog reset issues).
  *	- 'FAST' variants configured for 8 dummy cycles (see note above.)
  */
 static struct seq_rw_config n25q_read4_configs[] = {
@@ -643,7 +643,7 @@ static struct seq_rw_config stfsm_s25fl_read4_configs[] = {
 static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
 	{FLASH_FLAG_WRITE_1_1_4, S25FL_CMD_WRITE4_1_1_4, 1, 1, 4, 0x00, 0, 0},
 	{FLASH_FLAG_READ_WRITE,  S25FL_CMD_WRITE4,       1, 1, 1, 0x00, 0, 0},
-	{0x00,                   0,                      0, 0, 0, 0x00, 0, 0},
+	{0x00,		   0,		      0, 0, 0, 0x00, 0, 0},
 };
 
 /*
@@ -868,12 +868,12 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, uint32_t size)
  * With this in mind, a two stage process is used to the clear the FIFO:
  *
  *     1. Read any complete 32-bit words from the FIFO, as reported by the
- *        SPI_FAST_SEQ_STA register.
+ *	SPI_FAST_SEQ_STA register.
  *
  *     2. Mop up any remaining bytes.  At this point, it is not known if there
- *        are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy FSM
- *        sequence is used to load one byte at a time, until a complete 32-bit
- *        word is formed; at most, 4 bytes will need to be loaded.
+ *	are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy FSM
+ *	sequence is used to load one byte at a time, until a complete 32-bit
+ *	word is formed; at most, 4 bytes will need to be loaded.
  *
  * [1] It is theoretically possible for the FIFO to contain an arbitrary number
  *     of bits.  However, since there are no known use-cases that leave
@@ -2098,7 +2098,7 @@ static int stfsm_init(struct stfsm *fsm)
 		return ret;
 
 	/* Set timing parameters */
-	writel(SPI_CFG_DEVICE_ST            |
+	writel(SPI_CFG_DEVICE_ST	    |
 	       SPI_CFG_DEFAULT_MIN_CS_HIGH  |
 	       SPI_CFG_DEFAULT_CS_SETUPHOLD |
 	       SPI_CFG_DEFAULT_DATA_HOLD,
@@ -2317,7 +2317,7 @@ static struct platform_driver stfsm_driver = {
 		.name	= "st-spi-fsm",
 		.owner	= THIS_MODULE,
 		.of_match_table = stfsm_match,
-		.pm     = &stfsm_pm_ops,
+		.pm	= &stfsm_pm_ops,
 	},
 };
 module_platform_driver(stfsm_driver);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 10/10] mtd: st_spi_fsm: General tidy-up
@ 2014-05-22 11:24   ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

Due to the nature of the port (lots of copy/paste) much of the white-space
is taken up by spaces instead of tab separators. This patch aims to change
that.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mtd/devices/st_spi_fsm.c | 298 +++++++++++++++++++--------------------
 1 file changed, 149 insertions(+), 149 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 6d535d9..c4cccf9 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -82,9 +82,9 @@
 #define SPI_CFG_CS_SETUPHOLD(x)		(((x) & 0xff) << 16)
 #define SPI_CFG_DATA_HOLD(x)		(((x) & 0xff) << 24)
 
-#define SPI_CFG_DEFAULT_MIN_CS_HIGH    SPI_CFG_MIN_CS_HIGH(0x0AA)
-#define SPI_CFG_DEFAULT_CS_SETUPHOLD   SPI_CFG_CS_SETUPHOLD(0xA0)
-#define SPI_CFG_DEFAULT_DATA_HOLD      SPI_CFG_DATA_HOLD(0x00)
+#define SPI_CFG_DEFAULT_MIN_CS_HIGH	SPI_CFG_MIN_CS_HIGH(0x0AA)
+#define SPI_CFG_DEFAULT_CS_SETUPHOLD	SPI_CFG_CS_SETUPHOLD(0xA0)
+#define SPI_CFG_DEFAULT_DATA_HOLD	SPI_CFG_DATA_HOLD(0x00)
 
 /*
  * Register: SPI_FAST_SEQ_TRANSFER_SIZE
@@ -164,7 +164,7 @@
 #define STFSM_OPC_ADD			0x2
 #define STFSM_OPC_STA			0x3
 #define STFSM_OPC_MODE			0x4
-#define STFSM_OPC_DUMMY		0x5
+#define STFSM_OPC_DUMMY			0x5
 #define STFSM_OPC_DATA			0x6
 #define STFSM_OPC_WAIT			0x7
 #define STFSM_OPC_JUMP			0x8
@@ -197,88 +197,87 @@
 #define STFSM_INST_WAIT			STFSM_INSTR(STFSM_OPC_WAIT,	0)
 #define STFSM_INST_STOP			STFSM_INSTR(STFSM_OPC_STOP,	0)
 
-#define STFSM_DEFAULT_EMI_FREQ 100000000UL                        /* 100 MHz */
-#define STFSM_DEFAULT_WR_TIME  (STFSM_DEFAULT_EMI_FREQ * (15/1000)) /* 15ms */
+#define STFSM_DEFAULT_EMI_FREQ		100000000UL	/* 100 MHz */
+#define STFSM_DEFAULT_WR_TIME	(STFSM_DEFAULT_EMI_FREQ * (15/1000)) /* 15ms */
 
-#define STFSM_FLASH_SAFE_FREQ  10000000UL                         /* 10 MHz */
+#define STFSM_FLASH_SAFE_FREQ		10000000UL	/* 10 MHz */
 
-#define STFSM_MAX_WAIT_SEQ_MS  1000     /* FSM execution time */
+#define STFSM_MAX_WAIT_SEQ_MS		1000		/* FSM execution time */
 
 /* S25FLxxxS commands */
-#define S25FL_CMD_WRITE4_1_1_4 0x34
-#define S25FL_CMD_SE4          0xdc
-#define S25FL_CMD_CLSR         0x30
-#define S25FL_CMD_DYBWR                0xe1
-#define S25FL_CMD_DYBRD                0xe0
-#define S25FL_CMD_WRITE4       0x12    /* Note, opcode clashes with
+#define S25FL_CMD_WRITE4_1_1_4		0x34
+#define S25FL_CMD_SE4			0xdc
+#define S25FL_CMD_CLSR			0x30
+#define S25FL_CMD_DYBWR			0xe1
+#define S25FL_CMD_DYBRD			0xe0
+#define S25FL_CMD_WRITE4		0x12    /* Note, opcode clashes with
 					* 'SPINOR_OP_WRITE_1_4_4'
 					* as found on N25Qxxx devices! */
-
 /* Status register */
-#define FLASH_STATUS_BUSY      0x01
-#define FLASH_STATUS_WEL       0x02
-#define FLASH_STATUS_BP0       0x04
-#define FLASH_STATUS_BP1       0x08
-#define FLASH_STATUS_BP2       0x10
-#define FLASH_STATUS_SRWP0     0x80
-#define FLASH_STATUS_TIMEOUT   0xff
+#define FLASH_STATUS_BUSY		0x01
+#define FLASH_STATUS_WEL		0x02
+#define FLASH_STATUS_BP0		0x04
+#define FLASH_STATUS_BP1		0x08
+#define FLASH_STATUS_BP2		0x10
+#define FLASH_STATUS_SRWP0		0x80
+#define FLASH_STATUS_TIMEOUT		0xff
 
 /* Maximum READID length */
-#define MAX_READID_LEN         6
-#define MAX_READID_LEN_ALIGNED ALIGN(MAX_READID_LEN, 4)
+#define MAX_READID_LEN	 		6
+#define MAX_READID_LEN_ALIGNED 		ALIGN(MAX_READID_LEN, 4)
 
 /* S25FL Error Flags */
-#define S25FL_STATUS_E_ERR     0x20
-#define S25FL_STATUS_P_ERR     0x40
+#define S25FL_STATUS_E_ERR		0x20
+#define S25FL_STATUS_P_ERR		0x40
 
 /* N25Q - READ/WRITE/CLEAR NON/VOLATILE STATUS/CONFIG Registers */
-#define N25Q_CMD_RFSR          0x70
-#define N25Q_CMD_CLFSR         0x50
-#define N25Q_CMD_WRVCR         0x81
-#define N25Q_CMD_RDVCR         0x85
-#define N25Q_CMD_RDVECR        0x65
-#define N25Q_CMD_RDNVCR        0xb5
-#define N25Q_CMD_WRNVCR        0xb1
+#define N25Q_CMD_RFSR			0x70
+#define N25Q_CMD_CLFSR			0x50
+#define N25Q_CMD_WRVCR			0x81
+#define N25Q_CMD_RDVCR			0x85
+#define N25Q_CMD_RDVECR			0x65
+#define N25Q_CMD_RDNVCR			0xb5
+#define N25Q_CMD_WRNVCR			0xb1
 
 /* N25Q Flags Status Register: Error Flags */
-#define N25Q_FLAGS_ERR_ERASE   BIT(5)
-#define N25Q_FLAGS_ERR_PROG    BIT(4)
-#define N25Q_FLAGS_ERR_VPP     BIT(3)
-#define N25Q_FLAGS_ERR_PROT    BIT(1)
-#define N25Q_FLAGS_ERROR       (N25Q_FLAGS_ERR_ERASE   | \
-                                N25Q_FLAGS_ERR_PROG    | \
-                                N25Q_FLAGS_ERR_VPP     | \
-                                N25Q_FLAGS_ERR_PROT)
-
-#define FLASH_PAGESIZE         256			/* In Bytes    */
-#define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
+#define N25Q_FLAGS_ERR_ERASE		BIT(5)
+#define N25Q_FLAGS_ERR_PROG		BIT(4)
+#define N25Q_FLAGS_ERR_VPP		BIT(3)
+#define N25Q_FLAGS_ERR_PROT		BIT(1)
+#define N25Q_FLAGS_ERROR		(N25Q_FLAGS_ERR_ERASE	| \
+					 N25Q_FLAGS_ERR_PROG	| \
+					 N25Q_FLAGS_ERR_VPP	| \
+					 N25Q_FLAGS_ERR_PROT)
+
+#define FLASH_PAGESIZE			256		     /* In Bytes    */
+#define FLASH_PAGESIZE_32		(FLASH_PAGESIZE / 4) /* In uint32_t */
 /* Maximum operation times (in ms) */
-#define FLASH_MAX_CHIP_ERASE_MS 500000          /* Chip Erase time */
-#define FLASH_MAX_SEC_ERASE_MS  30000           /* Sector Erase time */
-#define FLASH_MAX_PAGE_WRITE_MS 100             /* Write Page time */
-#define FLASH_MAX_STA_WRITE_MS  4000            /* Write status reg time */
-#define FSM_MAX_WAIT_SEQ_MS     1000            /* FSM execution time */
+#define FLASH_MAX_CHIP_ERASE_MS		500000	/* Chip Erase time */
+#define FLASH_MAX_SEC_ERASE_MS		30000	/* Sector Erase time */
+#define FLASH_MAX_PAGE_WRITE_MS		100	/* Write Page time */
+#define FLASH_MAX_STA_WRITE_MS		4000	/* Write status reg time */
+#define FSM_MAX_WAIT_SEQ_MS		1000	/* FSM execution time */
 
 /*
  * Flags to tweak operation of default read/write/erase routines
  */
-#define CFG_READ_TOGGLE_32BIT_ADDR     0x00000001
-#define CFG_WRITE_TOGGLE_32BIT_ADDR    0x00000002
-#define CFG_ERASESEC_TOGGLE_32BIT_ADDR 0x00000008
-#define CFG_S25FL_CHECK_ERROR_FLAGS    0x00000010
-#define CFG_N25Q_CHECK_ERROR_FLAGS     0x00000020
+#define CFG_READ_TOGGLE_32BIT_ADDR		0x00000001
+#define CFG_WRITE_TOGGLE_32BIT_ADDR		0x00000002
+#define CFG_ERASESEC_TOGGLE_32BIT_ADDR		0x00000008
+#define CFG_S25FL_CHECK_ERROR_FLAGS		0x00000010
+#define CFG_N25Q_CHECK_ERROR_FLAGS		0x00000020
 
 struct stfsm_seq {
-	uint32_t data_size;
-	uint32_t addr1;
-	uint32_t addr2;
-	uint32_t addr_cfg;
-	uint32_t seq_opc[5];
-	uint32_t mode;
-	uint32_t dummy;
-	uint32_t status;
-	uint8_t  seq[16];
-	uint32_t seq_cfg;
+	uint32_t 		data_size;
+	uint32_t 		addr1;
+	uint32_t 		addr2;
+	uint32_t 		addr_cfg;
+	uint32_t 		seq_opc[5];
+	uint32_t 		mode;
+	uint32_t 		dummy;
+	uint32_t 		status;
+	uint8_t  		seq[16];
+	uint32_t 		seq_cfg;
 } __packed __aligned(4);
 
 struct stfsm {
@@ -287,51 +286,52 @@ struct stfsm {
 	struct resource		*region;
 	struct mtd_info		mtd;
 	struct mutex		lock;
-	struct flash_info       *info;
-	struct clk              *clk;
-
-	uint32_t                configuration;
-	uint32_t                fifo_dir_delay;
-	bool                    booted_from_spi;
-	bool                    reset_signal;
-	bool                    reset_por;
-
-	struct stfsm_seq stfsm_seq_read;
-	struct stfsm_seq stfsm_seq_write;
-	struct stfsm_seq stfsm_seq_en_32bit_addr;
+	struct flash_info	*info;
+	struct clk		*clk;
+
+	uint32_t		configuration;
+	uint32_t		fifo_dir_delay;
+	bool			booted_from_spi;
+	bool			reset_signal;
+	bool			reset_por;
+
+	struct stfsm_seq 	stfsm_seq_read;
+	struct stfsm_seq 	stfsm_seq_write;
+	struct stfsm_seq 	stfsm_seq_en_32bit_addr;
 };
 
 /* Parameters to configure a READ or WRITE FSM sequence */
 struct seq_rw_config {
-	uint32_t        flags;          /* flags to support config */
-	uint8_t         cmd;            /* FLASH command */
-	int             write;          /* Write Sequence */
-	uint8_t         addr_pads;      /* No. of addr pads (MODE & DUMMY) */
-	uint8_t         data_pads;      /* No. of data pads */
-	uint8_t         mode_data;      /* MODE data */
-	uint8_t         mode_cycles;    /* No. of MODE cycles */
-	uint8_t         dummy_cycles;   /* No. of DUMMY cycles */
+	uint32_t		flags;		/* flags to support config */
+	uint8_t	 		cmd;		/* FLASH command */
+	int			write;		/* Write Sequence */
+	uint8_t	 		addr_pads;	/* No. of addr pads */
+						/* (MODE & DUMMY) */
+	uint8_t	 		data_pads;	/* No. of data pads */
+	uint8_t	 		mode_data;	/* MODE data */
+	uint8_t	 		mode_cycles;	/* No. of MODE cycles */
+	uint8_t	 		dummy_cycles;	/* No. of DUMMY cycles */
 };
 
 /* SPI Flash Device Table */
 struct flash_info {
-	char            *name;
+	char			*name;
 	/* READID data, as returned by 'FLASH_CMD_RDID' (0x9f). */
-	u8              readid[MAX_READID_LEN];
-	int             readid_len;
+	u8			readid[MAX_READID_LEN];
+	int			readid_len;
 	/*
 	 * The size listed here is what works with SPINOR_OP_SE, which isn't
 	 * necessarily called a "sector" by the vendor.
 	 */
-	unsigned        sector_size;
-	u16             n_sectors;
-	u32             flags;
+	unsigned		sector_size;
+	u16			n_sectors;
+	u32			flags;
 	/*
 	 * Note, where FAST_READ is supported, freq_max specifies the
 	 * FAST_READ frequency, not the READ frequency.
 	 */
-	u32             max_freq;
-	int             (*config)(struct stfsm *);
+	u32			max_freq;
+	int			(*config)(struct stfsm *);
 };
 
 /* Device with standard 3-byte JEDEC ID */
@@ -385,9 +385,9 @@ static struct flash_info flash_types[] = {
 	JEDEC_INFO("m25p64",  0x202017,  64 * 1024, 128, M25P_FLAG, 50, NULL),
 	JEDEC_INFO("m25p128", 0x202018, 256 * 1024,  64, M25P_FLAG, 50, NULL),
 
-#define M25PX_FLAG (FLASH_FLAG_READ_WRITE      |	\
-		    FLASH_FLAG_READ_FAST        |	\
-		    FLASH_FLAG_READ_1_1_2       |	\
+#define M25PX_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		    FLASH_FLAG_READ_FAST	|	\
+		    FLASH_FLAG_READ_1_1_2	|	\
 		    FLASH_FLAG_WRITE_1_1_2)
 	JEDEC_INFO("m25px32", 0x207116,  64 * 1024,  64, M25PX_FLAG, 75, NULL),
 	JEDEC_INFO("m25px64", 0x207117,  64 * 1024, 128, M25PX_FLAG, 75, NULL),
@@ -396,12 +396,12 @@ static struct flash_info flash_types[] = {
 	 *     - Support for 'FLASH_FLAG_WRITE_1_4_4' is omitted for devices
 	 *       where operating frequency must be reduced.
 	 */
-#define MX25_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
-		   FLASH_FLAG_READ_1_2_2        |	\
-		   FLASH_FLAG_READ_1_1_4        |	\
-		   FLASH_FLAG_SE_4K             |	\
+#define MX25_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST		|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
+		   FLASH_FLAG_READ_1_2_2	|	\
+		   FLASH_FLAG_READ_1_1_4	|	\
+		   FLASH_FLAG_SE_4K		|	\
 		   FLASH_FLAG_SE_32K)
 	JEDEC_INFO("mx25l3255e",  0xc29e16, 64 * 1024, 64,
 		   (MX25_FLAG | FLASH_FLAG_WRITE_1_4_4), 86, stfsm_mx25_config),
@@ -411,34 +411,34 @@ static struct flash_info flash_types[] = {
 		   (MX25_FLAG | FLASH_FLAG_RESET), 70, stfsm_mx25_config),
 
 	/* Micron N25Qxxx */
-#define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
-		   FLASH_FLAG_READ_1_2_2        |	\
-		   FLASH_FLAG_READ_1_1_4        |	\
-		   FLASH_FLAG_READ_1_4_4        |	\
-		   FLASH_FLAG_WRITE_1_1_2       |	\
-		   FLASH_FLAG_WRITE_1_2_2       |	\
-		   FLASH_FLAG_WRITE_1_1_4       |	\
+#define N25Q_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST		|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
+		   FLASH_FLAG_READ_1_2_2	|	\
+		   FLASH_FLAG_READ_1_1_4	|	\
+		   FLASH_FLAG_READ_1_4_4	|	\
+		   FLASH_FLAG_WRITE_1_1_2	|	\
+		   FLASH_FLAG_WRITE_1_2_2	|	\
+		   FLASH_FLAG_WRITE_1_1_4	|	\
 		   FLASH_FLAG_WRITE_1_4_4)
 	JEDEC_INFO("n25q128", 0x20ba18, 64 * 1024,  256,
 		   N25Q_FLAG, 108, stfsm_n25q_config),
 
        /* Micron N25Q256/N25Q512/N25Q00A (32-bit ADDR devices)
-        *
-        * Versions are available with or without a dedicated RESET# pin
-        * (e.g. N25Q512A83GSF40G vs. N25Q512A13GSF40G).  To complicate matters,
-        * the versions that include a RESET# pin (Feature Set = 8) require a
-        * different opcode for the FLASH_CMD_WRITE_1_4_4 command.
-        * Unfortunately it is not possible to determine easily at run-time
-        * which version is being used.  We therefore remove support for
-        * FLASH_FLAG_WRITE_1_4_4 (falling back to FLASH_FLAG_WRITE_1_1_4), and
-        * defer overall support for RESET# to the board-level platform/Device
-        * Tree property "reset-signal".
-        */
-#define N25Q_32BIT_ADDR_FLAG  ((N25Q_FLAG              |	\
-				FLASH_FLAG_32BIT_ADDR  |	\
-				FLASH_FLAG_RESET)      &	\
+	*
+	* Versions are available with or without a dedicated RESET# pin
+	* (e.g. N25Q512A83GSF40G vs. N25Q512A13GSF40G).  To complicate matters,
+	* the versions that include a RESET# pin (Feature Set = 8) require a
+	* different opcode for the FLASH_CMD_WRITE_1_4_4 command.
+	* Unfortunately it is not possible to determine easily at run-time
+	* which version is being used.  We therefore remove support for
+	* FLASH_FLAG_WRITE_1_4_4 (falling back to FLASH_FLAG_WRITE_1_1_4), and
+	* defer overall support for RESET# to the board-level platform/Device
+	* Tree property "reset-signal".
+	*/
+#define N25Q_32BIT_ADDR_FLAG  ((N25Q_FLAG		|	\
+				FLASH_FLAG_32BIT_ADDR	|	\
+				FLASH_FLAG_RESET)	&	\
 			       ~FLASH_FLAG_WRITE_1_4_4)
 	JEDEC_INFO("n25q256", 0x20ba19, 64 * 1024,   512,
 		   N25Q_32BIT_ADDR_FLAG, 108, stfsm_n25q_config),
@@ -452,12 +452,12 @@ static struct flash_info flash_types[] = {
 	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
 	 *     - S25FL128Px devices do not support DUAL or QUAD I/O
 	 */
-#define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE  |	\
-			FLASH_FLAG_READ_1_1_2   |	\
-			FLASH_FLAG_READ_1_2_2   |	\
-			FLASH_FLAG_READ_1_1_4   |	\
-			FLASH_FLAG_READ_1_4_4   |	\
-			FLASH_FLAG_WRITE_1_1_4  |	\
+#define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE	|	\
+			FLASH_FLAG_READ_1_1_2	|	\
+			FLASH_FLAG_READ_1_2_2	|	\
+			FLASH_FLAG_READ_1_1_4	|	\
+			FLASH_FLAG_READ_1_4_4	|	\
+			FLASH_FLAG_WRITE_1_1_4	|	\
 			FLASH_FLAG_READ_FAST)
 	RDID_INFO("s25fl032p", RDID({0x01, 0x02, 0x15, 0x4d, 0x00}), 5,
 		  64 * 1024,  64, S25FLXXXP_FLAG, 80, stfsm_s25fl_config),
@@ -482,8 +482,8 @@ static struct flash_info flash_types[] = {
 	 *       may default to locked state on power-on.
 	 *     - S25FL127Sx handled as S25FL128Sx
 	 */
-#define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
-			FLASH_FLAG_RESET        |	\
+#define S25FLXXXS_FLAG (S25FLXXXP_FLAG	 	|	\
+			FLASH_FLAG_RESET	|	\
 			FLASH_FLAG_DYB_LOCKING)
 	RDID_INFO("s25fl128s0", RDID({0x01, 0x20, 0x18, 0x4d, 0x00, 0x80}), 6,
 		  256 * 1024, 64, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
@@ -494,9 +494,9 @@ static struct flash_info flash_types[] = {
 	RDID_INFO("s25fl256s1", RDID({0x01, 0x02, 0x19, 0x4d, 0x01, 0x80}), 6,
 		  64 * 1024, 512, S25FLXXXS_FLAG, 80, stfsm_s25fl_config),
 
-#define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
+#define W25X_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST	 	|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
 		   FLASH_FLAG_WRITE_1_1_2)
 	JEDEC_INFO("w25x40", 0xef3013, 64 * 1024,   8, W25X_FLAG, 75, NULL),
 	JEDEC_INFO("w25x80", 0xef3014, 64 * 1024,  16, W25X_FLAG, 75, NULL),
@@ -505,12 +505,12 @@ static struct flash_info flash_types[] = {
 	JEDEC_INFO("w25x64", 0xef3017, 64 * 1024, 128, W25X_FLAG, 75, NULL),
 
 	/* Winbond -- w25q "blocks" are 64K, "sectors" are 4KiB */
-#define W25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
-		   FLASH_FLAG_READ_FAST         |	\
-		   FLASH_FLAG_READ_1_1_2        |	\
-		   FLASH_FLAG_READ_1_2_2        |	\
-		   FLASH_FLAG_READ_1_1_4        |	\
-		   FLASH_FLAG_READ_1_4_4        |	\
+#define W25Q_FLAG (FLASH_FLAG_READ_WRITE	|	\
+		   FLASH_FLAG_READ_FAST		|	\
+		   FLASH_FLAG_READ_1_1_2	|	\
+		   FLASH_FLAG_READ_1_2_2	|	\
+		   FLASH_FLAG_READ_1_1_4	|	\
+		   FLASH_FLAG_READ_1_4_4	|	\
 		   FLASH_FLAG_WRITE_1_1_4)
 	JEDEC_INFO("w25q80", 0xef4014, 64 * 1024,  16,
 		   W25Q_FLAG, 80, stfsm_w25q_config),
@@ -581,7 +581,7 @@ static struct seq_rw_config n25q_read3_configs[] = {
 
 /* N25Q 4-byte Address READ configurations
  *	- use special 4-byte address READ commands (reduces overheads, and
- *        reduces risk of hitting watchdog reset issues).
+ *	reduces risk of hitting watchdog reset issues).
  *	- 'FAST' variants configured for 8 dummy cycles (see note above.)
  */
 static struct seq_rw_config n25q_read4_configs[] = {
@@ -643,7 +643,7 @@ static struct seq_rw_config stfsm_s25fl_read4_configs[] = {
 static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
 	{FLASH_FLAG_WRITE_1_1_4, S25FL_CMD_WRITE4_1_1_4, 1, 1, 4, 0x00, 0, 0},
 	{FLASH_FLAG_READ_WRITE,  S25FL_CMD_WRITE4,       1, 1, 1, 0x00, 0, 0},
-	{0x00,                   0,                      0, 0, 0, 0x00, 0, 0},
+	{0x00,		   0,		      0, 0, 0, 0x00, 0, 0},
 };
 
 /*
@@ -868,12 +868,12 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, uint32_t size)
  * With this in mind, a two stage process is used to the clear the FIFO:
  *
  *     1. Read any complete 32-bit words from the FIFO, as reported by the
- *        SPI_FAST_SEQ_STA register.
+ *	SPI_FAST_SEQ_STA register.
  *
  *     2. Mop up any remaining bytes.  At this point, it is not known if there
- *        are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy FSM
- *        sequence is used to load one byte at a time, until a complete 32-bit
- *        word is formed; at most, 4 bytes will need to be loaded.
+ *	are 0, 1, 2, or 3 bytes in the FIFO.  To handle all cases, a dummy FSM
+ *	sequence is used to load one byte at a time, until a complete 32-bit
+ *	word is formed;@most, 4 bytes will need to be loaded.
  *
  * [1] It is theoretically possible for the FIFO to contain an arbitrary number
  *     of bits.  However, since there are no known use-cases that leave
@@ -2098,7 +2098,7 @@ static int stfsm_init(struct stfsm *fsm)
 		return ret;
 
 	/* Set timing parameters */
-	writel(SPI_CFG_DEVICE_ST            |
+	writel(SPI_CFG_DEVICE_ST	    |
 	       SPI_CFG_DEFAULT_MIN_CS_HIGH  |
 	       SPI_CFG_DEFAULT_CS_SETUPHOLD |
 	       SPI_CFG_DEFAULT_DATA_HOLD,
@@ -2317,7 +2317,7 @@ static struct platform_driver stfsm_driver = {
 		.name	= "st-spi-fsm",
 		.owner	= THIS_MODULE,
 		.of_match_table = stfsm_match,
-		.pm     = &stfsm_pm_ops,
+		.pm	= &stfsm_pm_ops,
 	},
 };
 module_platform_driver(stfsm_driver);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
  2014-05-22 11:24   ` Lee Jones
  (?)
@ 2014-05-22 11:47     ` Arnd Bergmann
  -1 siblings, 0 replies; 50+ messages in thread
From: Arnd Bergmann @ 2014-05-22 11:47 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lee Jones, linux-kernel, Christophe Kerello, computersforpeace,
	linux-mtd

On Thursday 22 May 2014 12:24:07 Lee Jones wrote:
> +       /* Mask to apply on boot_device_reg */
> +       ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
> +       if (ret)
> +               goto boot_device_fail;
> +
> 

The binding defines this property as "optional", but the driver fails
here if it's not provided. I suggest you add a default value here so you
can deal with existing dts. The default should be documented in
the binding as well.

	Arnd

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:47     ` Arnd Bergmann
  0 siblings, 0 replies; 50+ messages in thread
From: Arnd Bergmann @ 2014-05-22 11:47 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Christophe Kerello, computersforpeace, Lee Jones, linux-kernel,
	linux-mtd

On Thursday 22 May 2014 12:24:07 Lee Jones wrote:
> +       /* Mask to apply on boot_device_reg */
> +       ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
> +       if (ret)
> +               goto boot_device_fail;
> +
> 

The binding defines this property as "optional", but the driver fails
here if it's not provided. I suggest you add a default value here so you
can deal with existing dts. The default should be documented in
the binding as well.

	Arnd

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:47     ` Arnd Bergmann
  0 siblings, 0 replies; 50+ messages in thread
From: Arnd Bergmann @ 2014-05-22 11:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 22 May 2014 12:24:07 Lee Jones wrote:
> +       /* Mask to apply on boot_device_reg */
> +       ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
> +       if (ret)
> +               goto boot_device_fail;
> +
> 

The binding defines this property as "optional", but the driver fails
here if it's not provided. I suggest you add a default value here so you
can deal with existing dts. The default should be documented in
the binding as well.

	Arnd

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
  2014-05-22 11:47     ` Arnd Bergmann
  (?)
@ 2014-05-22 11:52       ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:52 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-kernel, Christophe Kerello,
	computersforpeace, linux-mtd

> On Thursday 22 May 2014 12:24:07 Lee Jones wrote:
> > +       /* Mask to apply on boot_device_reg */
> > +       ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
> > +       if (ret)
> > +               goto boot_device_fail;
> > +
> > 
> 
> The binding defines this property as "optional", but the driver fails
> here if it's not provided. I suggest you add a default value here so you
> can deal with existing dts. The default should be documented in
> the binding as well.

The property is optional. It doesn't fail completely, merely skips the
boot device check and falls back to using SPI.  I can update the
documentation to this effect though, no problem.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:52       ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:52 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-mtd, computersforpeace, Christophe Kerello, linux-kernel,
	linux-arm-kernel

> On Thursday 22 May 2014 12:24:07 Lee Jones wrote:
> > +       /* Mask to apply on boot_device_reg */
> > +       ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
> > +       if (ret)
> > +               goto boot_device_fail;
> > +
> > 
> 
> The binding defines this property as "optional", but the driver fails
> here if it's not provided. I suggest you add a default value here so you
> can deal with existing dts. The default should be documented in
> the binding as well.

The property is optional. It doesn't fail completely, merely skips the
boot device check and falls back to using SPI.  I can update the
documentation to this effect though, no problem.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:52       ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:52 UTC (permalink / raw)
  To: linux-arm-kernel

> On Thursday 22 May 2014 12:24:07 Lee Jones wrote:
> > +       /* Mask to apply on boot_device_reg */
> > +       ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
> > +       if (ret)
> > +               goto boot_device_fail;
> > +
> > 
> 
> The binding defines this property as "optional", but the driver fails
> here if it's not provided. I suggest you add a default value here so you
> can deal with existing dts. The default should be documented in
> the binding as well.

The property is optional. It doesn't fail completely, merely skips the
boot device check and falls back to using SPI.  I can update the
documentation to this effect though, no problem.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
  2014-05-22 11:52       ` Lee Jones
  (?)
@ 2014-05-22 11:53         ` Arnd Bergmann
  -1 siblings, 0 replies; 50+ messages in thread
From: Arnd Bergmann @ 2014-05-22 11:53 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-arm-kernel, linux-kernel, Christophe Kerello,
	computersforpeace, linux-mtd

On Thursday 22 May 2014 12:52:16 Lee Jones wrote:
> > On Thursday 22 May 2014 12:24:07 Lee Jones wrote:
> > > +       /* Mask to apply on boot_device_reg */
> > > +       ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
> > > +       if (ret)
> > > +               goto boot_device_fail;
> > > +
> > > 
> > 
> > The binding defines this property as "optional", but the driver fails
> > here if it's not provided. I suggest you add a default value here so you
> > can deal with existing dts. The default should be documented in
> > the binding as well.
> 
> The property is optional. It doesn't fail completely, merely skips the
> boot device check and falls back to using SPI.  I can update the
> documentation to this effect though, no problem.

Ah, I see, thanks for the explanation!

	Arnd

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:53         ` Arnd Bergmann
  0 siblings, 0 replies; 50+ messages in thread
From: Arnd Bergmann @ 2014-05-22 11:53 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-mtd, computersforpeace, Christophe Kerello, linux-kernel,
	linux-arm-kernel

On Thursday 22 May 2014 12:52:16 Lee Jones wrote:
> > On Thursday 22 May 2014 12:24:07 Lee Jones wrote:
> > > +       /* Mask to apply on boot_device_reg */
> > > +       ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
> > > +       if (ret)
> > > +               goto boot_device_fail;
> > > +
> > > 
> > 
> > The binding defines this property as "optional", but the driver fails
> > here if it's not provided. I suggest you add a default value here so you
> > can deal with existing dts. The default should be documented in
> > the binding as well.
> 
> The property is optional. It doesn't fail completely, merely skips the
> boot device check and falls back to using SPI.  I can update the
> documentation to this effect though, no problem.

Ah, I see, thanks for the explanation!

	Arnd

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:53         ` Arnd Bergmann
  0 siblings, 0 replies; 50+ messages in thread
From: Arnd Bergmann @ 2014-05-22 11:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 22 May 2014 12:52:16 Lee Jones wrote:
> > On Thursday 22 May 2014 12:24:07 Lee Jones wrote:
> > > +       /* Mask to apply on boot_device_reg */
> > > +       ret = of_property_read_u32(np, "st,boot-device-msk", &boot_device_msk);
> > > +       if (ret)
> > > +               goto boot_device_fail;
> > > +
> > > 
> > 
> > The binding defines this property as "optional", but the driver fails
> > here if it's not provided. I suggest you add a default value here so you
> > can deal with existing dts. The default should be documented in
> > the binding as well.
> 
> The property is optional. It doesn't fail completely, merely skips the
> boot device check and falls back to using SPI.  I can update the
> documentation to this effect though, no problem.

Ah, I see, thanks for the explanation!

	Arnd

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH v2 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
  2014-05-22 11:24   ` Lee Jones
  (?)
@ 2014-05-22 11:56     ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:56 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Christophe Kerello

mtd: st_spi_fsm: Provide documentation for boot device mask property

The system configuration registers which display which device the system
booted on are in the same place on all boards which support the FSM.
However, the bits do shift every so slightly.  To combat these we're
adding a new property which supplies the necessary mask used to abstract
the required information.

Cc: devicetree@vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>

diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
index c248939..2ef9710 100644
--- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
+++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
@@ -11,6 +11,10 @@ Optional properties:
   - st,syscfg          : Phandle to boot-device system configuration registers
   - st,boot-device-reg : Address of the aforementioned boot-device register(s)
   - st,boot-device-spi : Expected boot-device value if booted via this device
+  - st,boot-device-msk : Mask to use when extracting boot device from the
+                        above system config registers
+  NB: If any of the st,boot-device-* properties are missing, the driver falls
+  back to the default assumption of 'booted from SPI'.
 
 Example:
        spifsm: spifsm@fe902000{

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:56     ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:56 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Christophe Kerello, computersforpeace, linux-mtd

mtd: st_spi_fsm: Provide documentation for boot device mask property

The system configuration registers which display which device the system
booted on are in the same place on all boards which support the FSM.
However, the bits do shift every so slightly.  To combat these we're
adding a new property which supplies the necessary mask used to abstract
the required information.

Cc: devicetree@vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>

diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
index c248939..2ef9710 100644
--- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
+++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
@@ -11,6 +11,10 @@ Optional properties:
   - st,syscfg          : Phandle to boot-device system configuration registers
   - st,boot-device-reg : Address of the aforementioned boot-device register(s)
   - st,boot-device-spi : Expected boot-device value if booted via this device
+  - st,boot-device-msk : Mask to use when extracting boot device from the
+                        above system config registers
+  NB: If any of the st,boot-device-* properties are missing, the driver falls
+  back to the default assumption of 'booted from SPI'.
 
 Example:
        spifsm: spifsm@fe902000{

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:56     ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:56 UTC (permalink / raw)
  To: linux-arm-kernel

mtd: st_spi_fsm: Provide documentation for boot device mask property

The system configuration registers which display which device the system
booted on are in the same place on all boards which support the FSM.
However, the bits do shift every so slightly.  To combat these we're
adding a new property which supplies the necessary mask used to abstract
the required information.

Cc: devicetree at vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>

diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
index c248939..2ef9710 100644
--- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
+++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
@@ -11,6 +11,10 @@ Optional properties:
   - st,syscfg          : Phandle to boot-device system configuration registers
   - st,boot-device-reg : Address of the aforementioned boot-device register(s)
   - st,boot-device-spi : Expected boot-device value if booted via this device
+  - st,boot-device-msk : Mask to use when extracting boot device from the
+                        above system config registers
+  NB: If any of the st,boot-device-* properties are missing, the driver falls
+  back to the default assumption of 'booted from SPI'.
 
 Example:
        spifsm: spifsm at fe902000{

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
  2014-05-22 11:56     ` Lee Jones
  (?)
@ 2014-05-22 11:58       ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:58 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, Christophe Kerello

Whoops, wrong patch, please ignore this v2.

> mtd: st_spi_fsm: Provide documentation for boot device mask property
> 
> The system configuration registers which display which device the system
> booted on are in the same place on all boards which support the FSM.
> However, the bits do shift every so slightly.  To combat these we're
> adding a new property which supplies the necessary mask used to abstract
> the required information.
> 
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> 
> diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
> index c248939..2ef9710 100644
> --- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
> +++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
> @@ -11,6 +11,10 @@ Optional properties:
>    - st,syscfg          : Phandle to boot-device system configuration registers
>    - st,boot-device-reg : Address of the aforementioned boot-device register(s)
>    - st,boot-device-spi : Expected boot-device value if booted via this device
> +  - st,boot-device-msk : Mask to use when extracting boot device from the
> +                        above system config registers
> +  NB: If any of the st,boot-device-* properties are missing, the driver falls
> +  back to the default assumption of 'booted from SPI'.
>  
>  Example:
>         spifsm: spifsm@fe902000{

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:58       ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:58 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Christophe Kerello, computersforpeace, linux-mtd

Whoops, wrong patch, please ignore this v2.

> mtd: st_spi_fsm: Provide documentation for boot device mask property
> 
> The system configuration registers which display which device the system
> booted on are in the same place on all boards which support the FSM.
> However, the bits do shift every so slightly.  To combat these we're
> adding a new property which supplies the necessary mask used to abstract
> the required information.
> 
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> 
> diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
> index c248939..2ef9710 100644
> --- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
> +++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
> @@ -11,6 +11,10 @@ Optional properties:
>    - st,syscfg          : Phandle to boot-device system configuration registers
>    - st,boot-device-reg : Address of the aforementioned boot-device register(s)
>    - st,boot-device-spi : Expected boot-device value if booted via this device
> +  - st,boot-device-msk : Mask to use when extracting boot device from the
> +                        above system config registers
> +  NB: If any of the st,boot-device-* properties are missing, the driver falls
> +  back to the default assumption of 'booted from SPI'.
>  
>  Example:
>         spifsm: spifsm@fe902000{

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH v2 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins
@ 2014-05-22 11:58       ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:58 UTC (permalink / raw)
  To: linux-arm-kernel

Whoops, wrong patch, please ignore this v2.

> mtd: st_spi_fsm: Provide documentation for boot device mask property
> 
> The system configuration registers which display which device the system
> booted on are in the same place on all boards which support the FSM.
> However, the bits do shift every so slightly.  To combat these we're
> adding a new property which supplies the necessary mask used to abstract
> the required information.
> 
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> 
> diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
> index c248939..2ef9710 100644
> --- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
> +++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
> @@ -11,6 +11,10 @@ Optional properties:
>    - st,syscfg          : Phandle to boot-device system configuration registers
>    - st,boot-device-reg : Address of the aforementioned boot-device register(s)
>    - st,boot-device-spi : Expected boot-device value if booted via this device
> +  - st,boot-device-msk : Mask to use when extracting boot device from the
> +                        above system config registers
> +  NB: If any of the st,boot-device-* properties are missing, the driver falls
> +  back to the default assumption of 'booted from SPI'.
>  
>  Example:
>         spifsm: spifsm at fe902000{

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH v2 08/10] mtd: st_spi_fsm: Provide documentation for boot device mask property
  2014-05-22 11:24   ` Lee Jones
  (?)
@ 2014-05-22 11:59     ` Lee Jones
  -1 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:59 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: computersforpeace, linux-mtd, devicetree, arnd

mtd: st_spi_fsm: Provide documentation for boot device mask property

The system configuration registers which display which device the system
booted on are in the same place on all boards which support the FSM.
However, the bits do shift every so slightly.  To combat these we're
adding a new property which supplies the necessary mask used to abstract
the required information.

Cc: devicetree@vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>

diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
index c248939..2ef9710 100644
--- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
+++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
@@ -11,6 +11,10 @@ Optional properties:
   - st,syscfg          : Phandle to boot-device system configuration registers
   - st,boot-device-reg : Address of the aforementioned boot-device register(s)
   - st,boot-device-spi : Expected boot-device value if booted via this device
+  - st,boot-device-msk : Mask to use when extracting boot device from the
+                        above system config registers
+  NB: If any of the st,boot-device-* properties are missing, the driver falls
+  back to the default assumption of 'booted from SPI'.
 
 Example:
        spifsm: spifsm@fe902000{

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 08/10] mtd: st_spi_fsm: Provide documentation for boot device mask property
@ 2014-05-22 11:59     ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:59 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: devicetree, computersforpeace, linux-mtd, arnd

mtd: st_spi_fsm: Provide documentation for boot device mask property

The system configuration registers which display which device the system
booted on are in the same place on all boards which support the FSM.
However, the bits do shift every so slightly.  To combat these we're
adding a new property which supplies the necessary mask used to abstract
the required information.

Cc: devicetree@vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>

diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
index c248939..2ef9710 100644
--- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
+++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
@@ -11,6 +11,10 @@ Optional properties:
   - st,syscfg          : Phandle to boot-device system configuration registers
   - st,boot-device-reg : Address of the aforementioned boot-device register(s)
   - st,boot-device-spi : Expected boot-device value if booted via this device
+  - st,boot-device-msk : Mask to use when extracting boot device from the
+                        above system config registers
+  NB: If any of the st,boot-device-* properties are missing, the driver falls
+  back to the default assumption of 'booted from SPI'.
 
 Example:
        spifsm: spifsm@fe902000{

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 08/10] mtd: st_spi_fsm: Provide documentation for boot device mask property
@ 2014-05-22 11:59     ` Lee Jones
  0 siblings, 0 replies; 50+ messages in thread
From: Lee Jones @ 2014-05-22 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

mtd: st_spi_fsm: Provide documentation for boot device mask property

The system configuration registers which display which device the system
booted on are in the same place on all boards which support the FSM.
However, the bits do shift every so slightly.  To combat these we're
adding a new property which supplies the necessary mask used to abstract
the required information.

Cc: devicetree at vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>

diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
index c248939..2ef9710 100644
--- a/Documentation/devicetree/bindings/mtd/st-fsm.txt
+++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt
@@ -11,6 +11,10 @@ Optional properties:
   - st,syscfg          : Phandle to boot-device system configuration registers
   - st,boot-device-reg : Address of the aforementioned boot-device register(s)
   - st,boot-device-spi : Expected boot-device value if booted via this device
+  - st,boot-device-msk : Mask to use when extracting boot device from the
+                        above system config registers
+  NB: If any of the st,boot-device-* properties are missing, the driver falls
+  back to the default assumption of 'booted from SPI'.
 
 Example:
        spifsm: spifsm at fe902000{

^ permalink raw reply related	[flat|nested] 50+ messages in thread

end of thread, other threads:[~2014-05-22 11:59 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-22 11:23 [PATCH v2 00/10] mtd: st_spi_fsm: Align with ST's internal development Lee Jones
2014-05-22 11:23 ` Lee Jones
2014-05-22 11:23 ` [PATCH 01/10] mtd: st_spi_fsm: Extend fsm_clear_fifo to handle unwanted bytes Lee Jones
2014-05-22 11:23   ` Lee Jones
2014-05-22 11:23   ` Lee Jones
2014-05-22 11:24 ` [PATCH 02/10] mtd: st_spi_fsm: Obtain and use EMI clock if provided Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24 ` [PATCH 03/10] mtd: st_spi_fsm: Add support for Micron N25Q512A Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24 ` [PATCH 04/10] mtd: st_spi_fsm: Add support for N25Q512 and N25Q00A devices Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24 ` [PATCH 05/10] mtd: st_spi_fsm: Update the JEDEC probe to handle extended READIDs Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24 ` [PATCH 06/10] mtd: st_spi_fsm: Update Spansion device entries Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24 ` [PATCH 07/10] mtd: st_spi_fsm: Improve busy wait handling Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24 ` [PATCH 08/10] mtd: st_spi_fsm: Provide documentation for boot device mask property Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:59   ` [PATCH v2 " Lee Jones
2014-05-22 11:59     ` Lee Jones
2014-05-22 11:59     ` Lee Jones
2014-05-22 11:24 ` [PATCH 09/10] mtd: st_spi_fsm: Provide mask to obtain correct boot device pins Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:47   ` Arnd Bergmann
2014-05-22 11:47     ` Arnd Bergmann
2014-05-22 11:47     ` Arnd Bergmann
2014-05-22 11:52     ` Lee Jones
2014-05-22 11:52       ` Lee Jones
2014-05-22 11:52       ` Lee Jones
2014-05-22 11:53       ` Arnd Bergmann
2014-05-22 11:53         ` Arnd Bergmann
2014-05-22 11:53         ` Arnd Bergmann
2014-05-22 11:56   ` [PATCH v2 " Lee Jones
2014-05-22 11:56     ` Lee Jones
2014-05-22 11:56     ` Lee Jones
2014-05-22 11:58     ` Lee Jones
2014-05-22 11:58       ` Lee Jones
2014-05-22 11:58       ` Lee Jones
2014-05-22 11:24 ` [PATCH 10/10] mtd: st_spi_fsm: General tidy-up Lee Jones
2014-05-22 11:24   ` Lee Jones
2014-05-22 11:24   ` Lee Jones

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.