Message ID | 1439888483-44476-1-git-send-email-B48286@freescale.com |
---|---|
State | Superseded |
Delegated to: | Jagannadha Sutradharudu Teki |
Headers | show |
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 --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; }