From: Hou Zhiqiang <b48...@freescale.com>

The clear flag status register operation is required by Micron
SPI-NOR chips, which support FSR. And if an error bit of FSR
have been set like protection, voltage, erase, and program,
it must be cleared by the clear FSR operation.

Signed-off-by: Hou Zhiqiang <b48...@freescale.com>
Signed-off-by: Mingkai.Hu <mingkai...@freescale.com>
Signed-off-by: Jagan Teki <jt...@openedev.com>
Reviewed-by: Jagan Teki <jt...@openedev.com>
---
Changes for v3:
        - none
Changes for v2:
        - none

 drivers/mtd/spi/sf_internal.h |  7 +++++++
 drivers/mtd/spi/sf_ops.c      | 18 ++++++++++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 3304217..e4cb198 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -81,6 +81,7 @@ enum spi_nor_option_flags {
 #define CMD_READ_STATUS1               0x35
 #define CMD_WRITE_ENABLE               0x06
 #define CMD_READ_CONFIG                        0x35
+#define CMD_CLEAR_FLAG_STATUS          0x50
 #define CMD_FLAG_STATUS                        0x70
 
 /* Read commands */
@@ -104,7 +105,13 @@ enum spi_nor_option_flags {
 #define STATUS_WIP                     (1 << 0)
 #define STATUS_QEB_WINSPAN             (1 << 1)
 #define STATUS_QEB_MXIC                (1 << 6)
+#define STATUS_ERR_PROT                        (1 << 1)
+#define STATUS_ERR_VOLT                        (1 << 3)
+#define STATUS_ERR_PROG                        (1 << 4)
+#define STATUS_ERR_ERASE               (1 << 5)
 #define STATUS_PEC                     (1 << 7)
+#define FSR_ERR_MSK                    (STATUS_ERR_PROT | STATUS_ERR_VOLT | \
+                                       STATUS_ERR_PROG | STATUS_ERR_ERASE)
 
 /* Flash timeout values */
 #define SPI_FLASH_PROG_TIMEOUT         (2 * CONFIG_SYS_HZ)
diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
index ae4a937..77b053a 100644
--- a/drivers/mtd/spi/sf_ops.c
+++ b/drivers/mtd/spi/sf_ops.c
@@ -153,6 +153,11 @@ static void spi_flash_dual_flash(struct spi_flash *flash, 
u32 *addr)
 }
 #endif
 
+static inline int write_cfsr(struct spi_flash *flash)
+{
+       return spi_flash_cmd(flash->spi, CMD_CLEAR_FLAG_STATUS, NULL, 0);
+}
+
 static inline int spi_flash_sr_ready(struct spi_flash *flash)
 {
        int sr = spi_flash_cmd_read_status(flash);
@@ -165,10 +170,15 @@ static inline int spi_flash_sr_ready(struct spi_flash 
*flash)
 static inline int spi_flash_fsr_ready(struct spi_flash *flash)
 {
        int fsr = read_fsr(flash);
-       if (fsr < 0)
-               return fsr;
-       else
-               return fsr & STATUS_PEC;
+       if (fsr & FSR_ERR_MSK) {
+               printf("SF: flag status(0x%x) error occured\n", fsr);
+               int cfsr = write_cfsr(flash);
+               if (cfsr < 0)
+                       printf("SF: clear flag status failed\n");
+               return -EINVAL;
+       }
+
+       return fsr & STATUS_PEC;
 }
 
 static int spi_flash_ready(struct spi_flash *flash)
-- 
1.9.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to