mtd: st_spi_fsm: Update Macronix 32-bit addressing support

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Tue Jun 10 23:59:03 PDT 2014


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=009e7e61b1f15b16964f1b4b6bb1e30e6b03dc3b
Commit:     009e7e61b1f15b16964f1b4b6bb1e30e6b03dc3b
Parent:     5fa980691bb4f61e3c2ca9ca451111be4e06caa2
Author:     Angus Clark <angus.clark at st.com>
AuthorDate: Wed Mar 26 16:39:16 2014 +0000
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Apr 14 11:22:59 2014 -0700

    mtd: st_spi_fsm: Update Macronix 32-bit addressing support
    
    Support for the Macronix 32-bit addressing scheme was originally developed using
    the MX25L25635E device.  As is often the case, it was found that the presence of
    a "WAIT" instruction was required for the "EN4B/EX4B" FSM Sequence to complete.
    (It is known that the SPI FSM Controller makes certain undocumented assumptions
    regarding what constitutes a valid sequence.)  However, further testing
    suggested that a small delay was required after issuing the "EX4B" command;
    without this delay, data corruptions were observed, consistent with the device
    not being ready to retrieve data.  Although the issue was not fully understood,
    the workaround of adding a small delay was implemented, while awaiting
    clarification from Macronix.
    
    The same behaviour has now been found with a second Macronix device, the
    MX25L25655E.  However, with this device, it seems that the delay is also
    required after the 'EN4B' commands.  This discovery has prompted us to revisit
    the issue.
    
    Although still not conclusive, further tests have suggested that the issue is
    down to the SPI FSM Controller, rather than the Macronix devices.  Furthermore,
    an alternative workaround has emerged which is to set the WAIT time to
    0x00000001, rather then 0x00000000.  (Note, the WAIT instruction is used purely
    for the purpose of achieving "sequence validity", rather than actually
    implementing a delay!)
    
    The issue is now being investigated by the Design and Validation teams.  In the
    meantime, we implement the alternative workaround, which reduces the effective
    delay from 1us to 1ns.
    
    Signed-off-by: Angus Clark <angus.clark at st.com>
    Signed-off-by: Lee Jones <lee.jones at linaro.org>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/devices/st_spi_fsm.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index d7e38cc..40eb830 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -270,7 +270,6 @@
  */
 #define CFG_READ_TOGGLE_32BIT_ADDR     0x00000001
 #define CFG_WRITE_TOGGLE_32BIT_ADDR    0x00000002
-#define CFG_WRITE_EX_32BIT_ADDR_DELAY  0x00000004
 #define CFG_ERASESEC_TOGGLE_32BIT_ADDR 0x00000008
 #define CFG_S25FL_CHECK_ERROR_FLAGS    0x00000010
 
@@ -1152,23 +1151,17 @@ static int stfsm_mx25_config(struct stfsm *fsm)
 		stfsm_mx25_en_32bit_addr_seq(&fsm->stfsm_seq_en_32bit_addr);
 
 		soc_reset = stfsm_can_handle_soc_reset(fsm);
-		if (soc_reset || !fsm->booted_from_spi) {
+		if (soc_reset || !fsm->booted_from_spi)
 			/* If we can handle SoC resets, we enable 32-bit address
 			 * mode pervasively */
 			stfsm_enter_32bit_addr(fsm, 1);
 
-		} else {
+		else
 			/* Else, enable/disable 32-bit addressing before/after
 			 * each operation */
 			fsm->configuration = (CFG_READ_TOGGLE_32BIT_ADDR |
 					      CFG_WRITE_TOGGLE_32BIT_ADDR |
 					      CFG_ERASESEC_TOGGLE_32BIT_ADDR);
-			/* It seems a small delay is required after exiting
-			 * 32-bit mode following a write operation.  The issue
-			 * is under investigation.
-			 */
-			fsm->configuration |= CFG_WRITE_EX_32BIT_ADDR_DELAY;
-		}
 	}
 
 	/* For QUAD mode, set 'QE' STATUS bit */
@@ -1631,11 +1624,8 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
 		stfsm_s25fl_clear_status_reg(fsm);
 
 	/* Exit 32-bit address mode, if required */
-	if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR) {
+	if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR)
 		stfsm_enter_32bit_addr(fsm, 0);
-		if (fsm->configuration & CFG_WRITE_EX_32BIT_ADDR_DELAY)
-			udelay(1);
-	}
 
 	return 0;
 }
@@ -1938,6 +1928,13 @@ static int stfsm_init(struct stfsm *fsm)
 	       fsm->base + SPI_CONFIGDATA);
 	writel(STFSM_DEFAULT_WR_TIME, fsm->base + SPI_STATUS_WR_TIME_REG);
 
+	/*
+	 * Set the FSM 'WAIT' delay to the minimum workable value.  Note, for
+	 * our purposes, the WAIT instruction is used purely to achieve
+	 * "sequence validity" rather than actually implement a delay.
+	 */
+	writel(0x00000001, fsm->base + SPI_PROGRAM_ERASE_TIME);
+
 	/* Clear FIFO, just in case */
 	stfsm_clear_fifo(fsm);
 



More information about the linux-mtd-cvs mailing list