@@ -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)
@@ -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)