[U-Boot] [PATCH V6] sf: Turn SPI flash chip into 3-Byte address mode

Siva Durga Prasad Paladugu siva.durga.paladugu at xilinx.com
Fri Aug 14 06:55:00 CEST 2015


Hi Zhiqiang,

> -----Original Message-----
> From: Zhiqiang Hou [mailto:B48286 at freescale.com]
> Sent: Wednesday, August 12, 2015 11:48 AM
> To: u-boot at lists.denx.de; jteki at openedev.com
> Cc: yorksun at freescale.com; Mingkai.Hu at freescale.com; Siva Durga Prasad
> Paladugu; Hou Zhiqiang
> Subject: [PATCH V6] sf: Turn SPI flash chip into 3-Byte address mode
>
> From: Hou Zhiqiang <B48286 at freescale.com>
>
> For more than 16MiB SPI flash chips, there are 3-Byte and 4-Byte address
> mode, and only the 3-Byte address mode is supported in U-Boot so far.
> So, reset the SPI flash to 3-Byte address mode in probe to ensure the SPI
> flash work correctly, because it may has been set to 4-Byte address mode
> after warm boot.
>
> Signed-off-by: Hou Zhiqiang <B48286 at freescale.com>
> ---
> Tested on T1042RDB board.
> V6:
>     Add the spi_release_bus.
> V5:
>     1. Removed #ifdef for STMICRO.
>     2. Add support for Spansion chips (>16MiB) switch to 3-Byte address mode.
> 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 |  7 +++++++
>  drivers/mtd/spi/sf_ops.c      | 40
> ++++++++++++++++++++++++++++++++++++++++
>  drivers/mtd/spi/sf_probe.c    | 10 ++++++++++
>  3 files changed, 57 insertions(+)
>
> diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
> index 1de1dac..9519bd8 100644
> --- a/drivers/mtd/spi/sf_internal.h
> +++ b/drivers/mtd/spi/sf_internal.h
> @@ -75,6 +75,10 @@ enum {
>  #define CMD_FLAG_STATUS                      0x70
>  #define CMD_CLEAR_FLAG_STATUS                0x50
>
> +/* Used for Micron, Macronix and Winbond flashes */
> +#define      CMD_ENTER_4B_ADDR               0xB7
> +#define      CMD_EXIT_4B_ADDR                0xE9
> +
>  /* Read commands */
>  #define CMD_READ_ARRAY_SLOW          0x03
>  #define CMD_READ_ARRAY_FAST          0x0b
> @@ -231,6 +235,9 @@ int spi_flash_read_common(struct spi_flash *flash,
> const u8 *cmd,  int spi_flash_cmd_read_ops(struct spi_flash *flash, u32
> offset,
>               size_t len, void *data);
>
> +int spi_flash_cmd_4B_addr_switch(struct spi_flash *flash,
> +             int enable, u8 idcode0);
> +
>  #ifdef CONFIG_SPI_FLASH_MTD
>  int spi_flash_mtd_register(struct spi_flash *flash);  void
> spi_flash_mtd_unregister(void); diff --git a/drivers/mtd/spi/sf_ops.c
> b/drivers/mtd/spi/sf_ops.c index deebcab..de30c55 100644
> --- a/drivers/mtd/spi/sf_ops.c
> +++ b/drivers/mtd/spi/sf_ops.c
> @@ -93,6 +93,46 @@ int spi_flash_cmd_write_config(struct spi_flash *flash,
> u8 wc)  }  #endif
>
> +int spi_flash_cmd_4B_addr_switch(struct spi_flash *flash,
> +                             int enable, u8 idcode0)
> +{
> +     int ret;
> +     u8 cmd, bar;
> +     bool need_wren = false;
> +
> +     ret = spi_claim_bus(flash->spi);
> +     if (ret) {
> +             debug("SF: unable to claim SPI bus\n");
> +             return ret;
> +     }
> +
> +     switch (idcode0) {
> +     case SPI_FLASH_CFI_MFR_STMICRO:
> +             /* Some Micron need WREN command; all will accept it */
> +             need_wren = true;
> +     case SPI_FLASH_CFI_MFR_MACRONIX:
> +     case SPI_FLASH_CFI_MFR_WINBOND:
> +             if (need_wren)
> +                     spi_flash_cmd_write_enable(flash);
> +
> +             cmd = enable ? CMD_ENTER_4B_ADDR :
> CMD_EXIT_4B_ADDR;
> +             ret = spi_flash_cmd(flash->spi, cmd, NULL, 0);
> +             if (need_wren)
> +                     spi_flash_cmd_write_disable(flash);
> +
> +             break;
> +     default:
> +             /* Spansion style */
> +             bar = enable << 7;
> +             cmd = CMD_BANKADDR_BRWR;
> +             ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &bar, 1);
> +     }
> +
> +     spi_release_bus(flash->spi);
> +
> +     return ret;
> +}
> +
>  #ifdef CONFIG_SPI_FLASH_BAR
>  static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8
> bank_sel)  { diff --git a/drivers/mtd/spi/sf_probe.c
> b/drivers/mtd/spi/sf_probe.c index e0283dc..3b204f8 100644
> --- a/drivers/mtd/spi/sf_probe.c
> +++ b/drivers/mtd/spi/sf_probe.c
> @@ -170,6 +170,16 @@ static int spi_flash_validate_params(struct spi_slave
> *spi, u8 *idcode,
>       flash->page_size <<= flash->shift;
>       flash->sector_size = params->sector_size << flash->shift;
>       flash->size = flash->sector_size * params->nr_sectors << flash->shift;
> +
> +     /*
> +      * So far, the 4-byte address mode haven't been supported in U-
> Boot,
> +      * and make sure the chip (> 16MiB) in default 3-byte address mode,
> +      * in case of warm bootup, the chip was set to 4-byte mode in kernel.
> +      */
> +     if (flash->size > SPI_FLASH_16MB_BOUN) {
I think that this check should be as below
if (flash->size > (SPI_FLASH_16MB_BOUN << flash->shift)

Regards,
Siva

> +             if (spi_flash_cmd_4B_addr_switch(flash, false, idcode[0]) <
> 0)
> +                     debug("SF: enter 3B address mode failed\n");
> +     }
>  #ifdef CONFIG_SF_DUAL_FLASH
>       if (flash->dual_flash & SF_DUAL_STACKED_FLASH)
>               flash->size <<= 1;
> --
> 2.1.0.27.g96db324



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.



More information about the U-Boot mailing list