sf: Set quad enable bit support
authorJagannadha Sutradharudu Teki <jaganna@xilinx.com>
Thu, 26 Dec 2013 08:24:57 +0000 (13:54 +0530)
committerJagannadha Sutradharudu Teki <jaganna@xilinx.com>
Sat, 11 Jan 2014 09:43:26 +0000 (15:13 +0530)
This patch provides support to set the quad enable bit on flash.

quad enable bit needs to set before performing any quad IO
operations on respective SPI flashes.

Currently added set  quad enable bit for winbond and spansion flash
devices. stmicro flash doesn't require to set as qeb is volatile.
remaining flash devices support will add in future patches.

Signed-off-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
drivers/mtd/spi/sf_internal.h
drivers/mtd/spi/sf_ops.c
drivers/mtd/spi/sf_probe.c

index dcc9014e5f7589757f3aec64a473b582ae713b42..dca34f7a71585475f4280a609777c5ff07dc114f 100644 (file)
 
 #define SPI_FLASH_16MB_BOUN            0x1000000
 
+/* CFI Manufacture ID's */
+#define SPI_FLASH_CFI_MFR_SPANSION     0x01
+#define SPI_FLASH_CFI_MFR_STMICRO      0x20
+#define SPI_FLASH_CFI_MFR_WINBOND      0xef
+
 /* SECT flags */
 #define SECT_4K                                (1 << 1)
 #define SECT_32K                       (1 << 2)
@@ -52,6 +57,7 @@
 
 /* Common status */
 #define STATUS_WIP                     0x01
+#define STATUS_QEB_WINSPAN             (1 << 1)
 #define STATUS_PEC                     0x80
 
 /* Flash timeout values */
@@ -93,8 +99,8 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len);
 /* Program the status register */
 int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr);
 
-/* Set quad enbale bit */
-int spi_flash_set_qeb(struct spi_flash *flash);
+/* Set quad enbale bit for winbond and spansion flashes */
+int spi_flash_set_qeb_winspan(struct spi_flash *flash);
 
 /* Enable writing on the SPI flash */
 static inline int spi_flash_cmd_write_enable(struct spi_flash *flash)
index 39e06ecae0dcf341464a11f8eebea3afe4ab2c92..827f71912d26cf105ff339fd08dd4b6c9faa670d 100644 (file)
@@ -38,6 +38,7 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr)
        return 0;
 }
 
+#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
 static int spi_flash_cmd_write_config(struct spi_flash *flash, u8 cr)
 {
        u8 data[2];
@@ -62,6 +63,31 @@ static int spi_flash_cmd_write_config(struct spi_flash *flash, u8 cr)
        return 0;
 }
 
+int spi_flash_set_qeb_winspan(struct spi_flash *flash)
+{
+       u8 qeb_status;
+       u8 cmd;
+       int ret;
+
+       cmd = CMD_READ_CONFIG;
+       ret = spi_flash_read_common(flash, &cmd, 1, &qeb_status, 1);
+       if (ret < 0) {
+               debug("SF: fail to read config register\n");
+               return ret;
+       }
+
+       if (qeb_status & STATUS_QEB_WINSPAN) {
+               debug("SF: Quad enable bit is already set\n");
+       } else {
+               ret = spi_flash_cmd_write_config(flash, STATUS_QEB_WINSPAN);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return ret;
+}
+#endif
+
 #ifdef CONFIG_SPI_FLASH_BAR
 static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel)
 {
index 3fa7363da390d073a40c8b57e3829acb3fd8d178..8b2972c7aaa914bcf7280b6176f0981d01cdb029 100644 (file)
@@ -165,6 +165,25 @@ static u8 spi_read_cmds_array[] = {
        CMD_READ_QUAD_OUTPUT_FAST,
 };
 
+static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0)
+{
+       switch (idcode0) {
+#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
+       case SPI_FLASH_CFI_MFR_SPANSION:
+       case SPI_FLASH_CFI_MFR_WINBOND:
+               return spi_flash_set_qeb_winspan(flash);
+#endif
+#ifdef CONFIG_SPI_FLASH_STMICRO
+       case SPI_FLASH_CFI_MFR_STMICRO:
+               debug("SF: QEB is volatile for %02x flash\n", idcode0);
+               return 0;
+#endif
+       default:
+               printf("SF: Need set QEB func for %02x flash\n", idcode0);
+               return -1;
+       }
+}
+
 static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
                u8 *idcode)
 {
@@ -250,6 +269,15 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
                /* Go for default supported write cmd */
                flash->write_cmd = CMD_PAGE_PROGRAM;
 
+       /* Set the quad enable bit - only for quad commands */
+       if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) ||
+           (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) {
+               if (spi_flash_set_qeb(flash, idcode[0])) {
+                       debug("SF: Fail to set QEB for %02x\n", idcode[0]);
+                       return NULL;
+               }
+       }
+
        /* Poll cmd seclection */
        flash->poll_cmd = CMD_READ_STATUS;
 #ifdef CONFIG_SPI_FLASH_STMICRO