On some boards where the spi flash is not reset during warm reboot,
the chip has to be manually set into 3-byte address mode.

Signed-off-by: Simon Goldschmidt <sgoldschm...@de.pepperl-fuchs.com>
---
 drivers/mtd/spi/sf_internal.h |  2 ++
 drivers/mtd/spi/spi_flash.c   | 53 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 839cdbe1b0..06dee0a4ea 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -62,6 +62,8 @@ enum spi_nor_option_flags {
 #define CMD_READ_STATUS1               0x35
 #define CMD_READ_CONFIG                        0x35
 #define CMD_FLAG_STATUS                        0x70
+#define CMD_EN4B                               0xB7
+#define CMD_EX4B                               0xE9
 
 /* Bank addr access commands */
 #ifdef CONFIG_SPI_FLASH_BAR
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 34f68881ed..8db2882075 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -165,6 +165,55 @@ bar_end:
 }
 #endif
 
+static int set_4byte(struct spi_flash *flash, const struct spi_flash_info 
*info,
+               u8 enable)
+{
+       int ret;
+       bool need_wren = false;
+       u8 cmd;
+
+       if (flash->size <= SPI_FLASH_16MB_BOUN)
+               return 0;
+
+       switch (JEDEC_MFR(info)) {
+       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:
+               ret = spi_claim_bus(flash->spi);
+               if (ret) {
+                       debug("SF: Unable to claim SPI bus\n");
+                       return ret;
+               }
+
+               if (need_wren) {
+                       ret = spi_flash_cmd_write_enable(flash);
+                       if (ret < 0) {
+                               debug("SF: enabling write failed\n");
+                               spi_release_bus(flash->spi);
+                               return ret;
+                       }
+               }
+
+               cmd = enable ? CMD_EN4B : CMD_EX4B;
+               ret = spi_flash_cmd_write(flash->spi, &cmd, 1, NULL, 0);
+               if (ret) {
+                       debug("SF: fail to %s 4-byte address mode\n",
+                               enable ? "enter" : "exit");
+               }
+               if (need_wren)
+                       if (spi_flash_cmd_write_disable(flash) < 0)
+                               debug("SF: disabling write failed\n");
+               spi_release_bus(flash->spi);
+               return ret;
+       default:
+               /* Spansion style handled by bar_write  */
+               break;
+       }
+       return 0;
+}
+
 #ifdef CONFIG_SF_DUAL_FLASH
 static void spi_flash_dual(struct spi_flash *flash, u32 *addr)
 {
@@ -1086,6 +1135,10 @@ int spi_flash_scan(struct spi_flash *flash)
                flash->flags |= SNOR_F_USE_FSR;
 #endif
 
+       /* disable 4-byte addressing if the device exceeds 16MiB */
+       if (flash->size > SPI_FLASH_16MB_BOUN)
+               set_4byte(flash, info, 0);
+
        /* Configure the BAR - discover bank cmds and read current bank */
 #ifdef CONFIG_SPI_FLASH_BAR
        ret = read_bar(flash, info);
-- 
2.12.2.windows.2

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

Reply via email to