diff mbox

[U-Boot,V6] sf: Add clear flag status register operation support

Message ID 1439888483-44476-1-git-send-email-B48286@freescale.com
State Superseded
Delegated to: Jagannadha Sutradharudu Teki
Headers show

Commit Message

Zhiqiang Hou Aug. 18, 2015, 9:01 a.m. UTC
From: Hou Zhiqiang <B48286@freescale.com>

The clear flag status register operation was required by Micron
SPI flash chips, which support FSR. And if an error bit of FSR
have been set, it must be cleared by the clear FSR operation.

Signed-off-by: Hou Zhiqiang <B48286@freescale.com>
Signed-off-by: Mingkai.Hu <Mingkai.Hu@freescale.com>
---
Tested on T1042RDB board.
V6:
    Generate the patch based on the latest wait ready logic.
    Depend on patch http://patchwork.ozlabs.org/patch/508166/
V5:
    1. Removed #ifdef for STMICRO.
    2. Add checking Protection and Voltage error bits.
    3. Only if there is any error bit set, issue the clear FSR command.
V4:
    Split the the patch to 2 patches for clear FSR and SPI flash address mode.
V3:
    Generate the patch based on the latest tree git://git.denx.de/u-boot.git.
V2:
    Add the operation of enter 3 Byte address mode in probe.
V1:
    Based on git://git.denx.de/u-boot.git.
 drivers/mtd/spi/sf_internal.h | 15 +++++++++++++++
 drivers/mtd/spi/sf_ops.c      |  7 +++++++
 2 files changed, 22 insertions(+)

Comments

Jagan Teki Aug. 18, 2015, 9:45 a.m. UTC | #1
On 18 August 2015 at 14:31, Zhiqiang Hou <B48286@freescale.com> wrote:
> From: Hou Zhiqiang <B48286@freescale.com>
>
> The clear flag status register operation was required by Micron
> SPI flash chips, which support FSR. And if an error bit of FSR
> have been set, it must be cleared by the clear FSR operation.
>
> Signed-off-by: Hou Zhiqiang <B48286@freescale.com>
> Signed-off-by: Mingkai.Hu <Mingkai.Hu@freescale.com>

Reviewed-by: Jagan Teki <jteki@openedev.com>

> ---
> Tested on T1042RDB board.
> V6:
>     Generate the patch based on the latest wait ready logic.
>     Depend on patch http://patchwork.ozlabs.org/patch/508166/
> V5:
>     1. Removed #ifdef for STMICRO.
>     2. Add checking Protection and Voltage error bits.
>     3. Only if there is any error bit set, issue the clear FSR command.
> V4:
>     Split the the patch to 2 patches for clear FSR and SPI flash address mode.
> V3:
>     Generate the patch based on the latest tree git://git.denx.de/u-boot.git.
> V2:
>     Add the operation of enter 3 Byte address mode in probe.
> V1:
>     Based on git://git.denx.de/u-boot.git.
>  drivers/mtd/spi/sf_internal.h | 15 +++++++++++++++
>  drivers/mtd/spi/sf_ops.c      |  7 +++++++
>  2 files changed, 22 insertions(+)
>
> diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
> index 8a3e5ec..fc6d751 100644
> --- a/drivers/mtd/spi/sf_internal.h
> +++ b/drivers/mtd/spi/sf_internal.h
> @@ -82,6 +82,7 @@ enum spi_nor_option_flags {
>  #define CMD_WRITE_ENABLE               0x06
>  #define CMD_READ_CONFIG                        0x35
>  #define CMD_FLAG_STATUS                        0x70
> +#define CMD_CLEAR_FLAG_STATUS          0x50
>
>  /* Read commands */
>  #define CMD_READ_ARRAY_SLOW            0x03
> @@ -104,7 +105,15 @@ enum spi_nor_option_flags {
>  #define STATUS_WIP                     (1 << 0)
>  #define STATUS_QEB_WINSPAN             (1 << 1)
>  #define STATUS_QEB_MXIC                (1 << 6)
> +
> +/* Flag status for STMICRO */
> +#define STATUS_PROT_ERR                        (1 << 1)
> +#define STATUS_VOLT_ERR                        (1 << 3)
> +#define STATUS_PROG_ERR                        (1 << 4)
> +#define STATUS_ERASE_ERR               (1 << 5)
>  #define STATUS_PEC                     (1 << 7)
> +#define FLAG_ERR_MASK                  (STATUS_PROT_ERR | STATUS_VOLT_ERR | \
> +                                        STATUS_PROG_ERR | STATUS_ERASE_ERR)
>
>  /* Flash timeout values */
>  #define SPI_FLASH_PROG_TIMEOUT         (2 * CONFIG_SYS_HZ)
> @@ -191,6 +200,12 @@ static inline int spi_flash_cmd_write_disable(struct spi_flash *flash)
>         return spi_flash_cmd(flash->spi, CMD_WRITE_DISABLE, NULL, 0);
>  }
>
> +/* Clear flag status register */
> +static inline int spi_flash_cmd_clear_flag_status(struct spi_flash *flash)
> +{
> +       return spi_flash_cmd(flash->spi, CMD_CLEAR_FLAG_STATUS, NULL, 0);
> +}
> +
>  /*
>   * Send the read status command to the device and wait for the wip
>   * (write-in-progress) bit to clear itself.
> diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
> index ba5ff0c..78ef08b 100644
> --- a/drivers/mtd/spi/sf_ops.c
> +++ b/drivers/mtd/spi/sf_ops.c
> @@ -174,6 +174,13 @@ static inline int spi_flash_fsr_ready(struct spi_flash *flash)
>         if (ret < 0)
>                 return ret;
>
> +       if (fsr & FLAG_ERR_MASK) {
> +               printf("SF: flag status(0x%x) error occured\n", fsr);
> +               ret = spi_flash_cmd_clear_flag_status(flash);
> +               if (ret < 0)
> +                       printf("SF: clear flag status failed\n");
> +               return -1;
> +       }
>         return fsr & STATUS_PEC;
>  }
>
> --
> 2.1.0.27.g96db324
>
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

thanks!
diff mbox

Patch

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 8a3e5ec..fc6d751 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -82,6 +82,7 @@  enum spi_nor_option_flags {
 #define CMD_WRITE_ENABLE		0x06
 #define CMD_READ_CONFIG			0x35
 #define CMD_FLAG_STATUS			0x70
+#define CMD_CLEAR_FLAG_STATUS		0x50
 
 /* Read commands */
 #define CMD_READ_ARRAY_SLOW		0x03
@@ -104,7 +105,15 @@  enum spi_nor_option_flags {
 #define STATUS_WIP			(1 << 0)
 #define STATUS_QEB_WINSPAN		(1 << 1)
 #define STATUS_QEB_MXIC		(1 << 6)
+
+/* Flag status for STMICRO */
+#define STATUS_PROT_ERR			(1 << 1)
+#define STATUS_VOLT_ERR			(1 << 3)
+#define STATUS_PROG_ERR			(1 << 4)
+#define STATUS_ERASE_ERR		(1 << 5)
 #define STATUS_PEC			(1 << 7)
+#define FLAG_ERR_MASK			(STATUS_PROT_ERR | STATUS_VOLT_ERR | \
+					 STATUS_PROG_ERR | STATUS_ERASE_ERR)
 
 /* Flash timeout values */
 #define SPI_FLASH_PROG_TIMEOUT		(2 * CONFIG_SYS_HZ)
@@ -191,6 +200,12 @@  static inline int spi_flash_cmd_write_disable(struct spi_flash *flash)
 	return spi_flash_cmd(flash->spi, CMD_WRITE_DISABLE, NULL, 0);
 }
 
+/* Clear flag status register */
+static inline int spi_flash_cmd_clear_flag_status(struct spi_flash *flash)
+{
+	return spi_flash_cmd(flash->spi, CMD_CLEAR_FLAG_STATUS, NULL, 0);
+}
+
 /*
  * Send the read status command to the device and wait for the wip
  * (write-in-progress) bit to clear itself.
diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
index ba5ff0c..78ef08b 100644
--- a/drivers/mtd/spi/sf_ops.c
+++ b/drivers/mtd/spi/sf_ops.c
@@ -174,6 +174,13 @@  static inline int spi_flash_fsr_ready(struct spi_flash *flash)
 	if (ret < 0)
 		return ret;
 
+	if (fsr & FLAG_ERR_MASK) {
+		printf("SF: flag status(0x%x) error occured\n", fsr);
+		ret = spi_flash_cmd_clear_flag_status(flash);
+		if (ret < 0)
+			printf("SF: clear flag status failed\n");
+		return -1;
+	}
 	return fsr & STATUS_PEC;
 }