Add support for Octal flash devices. Octal flash devices use 8 IO lines
for data transfer. Currently only 1-1-8 Octal Read mode is supported.

Signed-off-by: Vignesh Raghavendra <vigne...@ti.com>
---
 drivers/mtd/spi/sf_internal.h  |  3 ++-
 drivers/mtd/spi/spi-nor-core.c | 20 +++++++++++++++++++-
 drivers/spi/spi-mem.c          |  6 ++++++
 drivers/spi/spi-uclass.c       |  6 ++++++
 include/linux/mtd/spi-nor.h    |  8 ++++++++
 include/spi.h                  |  2 ++
 6 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 5c643034c691..940b2e4c9e00 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -37,7 +37,7 @@ struct flash_info {
        u16             page_size;
        u16             addr_width;
 
-       u16             flags;
+       u32             flags;
 #define SECT_4K                        BIT(0)  /* SPINOR_OP_BE_4K works 
uniformly */
 #define SPI_NOR_NO_ERASE       BIT(1)  /* No erase command needed */
 #define SST_WRITE              BIT(2)  /* use SST byte programming */
@@ -66,6 +66,7 @@ struct flash_info {
 #define SPI_NOR_SKIP_SFDP      BIT(13) /* Skip parsing of SFDP tables */
 #define USE_CLSR               BIT(14) /* use CLSR command */
 #define SPI_NOR_HAS_SST26LOCK  BIT(15) /* Flash supports lock/unlock via BPR */
+#define SPI_NOR_OCTAL_READ      BIT(16) /* Flash supports Octal Read */
 };
 
 extern const struct flash_info spi_nor_ids[];
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 5a8c08425566..9b726be5d22d 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -251,6 +251,8 @@ static u8 spi_nor_convert_3to4_read(u8 opcode)
                { SPINOR_OP_READ_1_2_2, SPINOR_OP_READ_1_2_2_4B },
                { SPINOR_OP_READ_1_1_4, SPINOR_OP_READ_1_1_4_4B },
                { SPINOR_OP_READ_1_4_4, SPINOR_OP_READ_1_4_4_4B },
+               { SPINOR_OP_READ_1_1_8, SPINOR_OP_READ_1_1_8_4B },
+               { SPINOR_OP_READ_1_8_8, SPINOR_OP_READ_1_8_8_4B },
 
                { SPINOR_OP_READ_1_1_1_DTR,     SPINOR_OP_READ_1_1_1_DTR_4B },
                { SPINOR_OP_READ_1_2_2_DTR,     SPINOR_OP_READ_1_2_2_DTR_4B },
@@ -267,6 +269,8 @@ static u8 spi_nor_convert_3to4_program(u8 opcode)
                { SPINOR_OP_PP,         SPINOR_OP_PP_4B },
                { SPINOR_OP_PP_1_1_4,   SPINOR_OP_PP_1_1_4_4B },
                { SPINOR_OP_PP_1_4_4,   SPINOR_OP_PP_1_4_4_4B },
+               { SPINOR_OP_PP_1_1_8,   SPINOR_OP_PP_1_1_8_4B },
+               { SPINOR_OP_PP_1_8_8,   SPINOR_OP_PP_1_8_8_4B },
        };
 
        return spi_nor_convert_opcode(opcode, spi_nor_3to4_program,
@@ -2121,6 +2125,13 @@ static int spi_nor_init_params(struct spi_nor *nor,
                                          SNOR_PROTO_1_1_4);
        }
 
+       if (info->flags & SPI_NOR_OCTAL_READ) {
+               params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8;
+               spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_1_1_8],
+                                         0, 8, SPINOR_OP_READ_1_1_8,
+                                         SNOR_PROTO_1_1_8);
+       }
+
        /* Page Program settings. */
        params->hwcaps.mask |= SNOR_HWCAPS_PP;
        spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
@@ -2428,7 +2439,14 @@ int spi_nor_scan(struct spi_nor *nor)
        nor->read_reg = spi_nor_read_reg;
        nor->write_reg = spi_nor_write_reg;
 
-       if (spi->mode & SPI_RX_QUAD) {
+       if (spi->mode & SPI_RX_OCTAL) {
+               hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8;
+
+               if (spi->mode & SPI_TX_OCTAL)
+                       hwcaps.mask |= (SNOR_HWCAPS_READ_1_8_8 |
+                                       SNOR_HWCAPS_PP_1_1_8 |
+                                       SNOR_HWCAPS_PP_1_8_8);
+       } else if (spi->mode & SPI_RX_QUAD) {
                hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
 
                if (spi->mode & SPI_TX_QUAD)
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 7788ab995344..cc358bd4f7ce 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -123,6 +123,12 @@ static int spi_check_buswidth_req(struct spi_slave *slave, 
u8 buswidth, bool tx)
                        return 0;
 
                break;
+       case 8:
+               if ((tx && (mode & SPI_TX_OCTAL)) ||
+                   (!tx && (mode & SPI_RX_OCTAL)))
+                       return 0;
+
+               break;
 
        default:
                break;
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 665611f7e23a..e16e9b4a4e98 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -445,6 +445,9 @@ int spi_slave_ofdata_to_platdata(struct udevice *dev,
        case 4:
                mode |= SPI_TX_QUAD;
                break;
+       case 8:
+               mode |= SPI_TX_OCTAL;
+               break;
        default:
                warn_non_spl("spi-tx-bus-width %d not supported\n", value);
                break;
@@ -460,6 +463,9 @@ int spi_slave_ofdata_to_platdata(struct udevice *dev,
        case 4:
                mode |= SPI_RX_QUAD;
                break;
+       case 8:
+               mode |= SPI_RX_OCTAL;
+               break;
        default:
                warn_non_spl("spi-rx-bus-width %d not supported\n", value);
                break;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index f9964a766456..e75e0485bd4f 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -47,9 +47,13 @@
 #define SPINOR_OP_READ_1_2_2   0xbb    /* Read data bytes (Dual I/O SPI) */
 #define SPINOR_OP_READ_1_1_4   0x6b    /* Read data bytes (Quad Output SPI) */
 #define SPINOR_OP_READ_1_4_4   0xeb    /* Read data bytes (Quad I/O SPI) */
+#define SPINOR_OP_READ_1_1_8   0x8b    /* Read data bytes (Octal Output SPI) */
+#define SPINOR_OP_READ_1_8_8   0xcb    /* Read data bytes (Octal I/O SPI) */
 #define SPINOR_OP_PP           0x02    /* Page program (up to 256 bytes) */
 #define SPINOR_OP_PP_1_1_4     0x32    /* Quad page program */
 #define SPINOR_OP_PP_1_4_4     0x38    /* Quad page program */
+#define SPINOR_OP_PP_1_1_8     0x82    /* Octal page program */
+#define SPINOR_OP_PP_1_8_8     0xc2    /* Octal page program */
 #define SPINOR_OP_BE_4K                0x20    /* Erase 4KiB block */
 #define SPINOR_OP_BE_4K_PMC    0xd7    /* Erase 4KiB block on PMC chips */
 #define SPINOR_OP_BE_32K       0x52    /* Erase 32KiB block */
@@ -70,9 +74,13 @@
 #define SPINOR_OP_READ_1_2_2_4B        0xbc    /* Read data bytes (Dual I/O 
SPI) */
 #define SPINOR_OP_READ_1_1_4_4B        0x6c    /* Read data bytes (Quad Output 
SPI) */
 #define SPINOR_OP_READ_1_4_4_4B        0xec    /* Read data bytes (Quad I/O 
SPI) */
+#define SPINOR_OP_READ_1_1_8_4B        0x7c    /* Read data bytes (Octal 
Output SPI) */
+#define SPINOR_OP_READ_1_8_8_4B        0xcc    /* Read data bytes (Octal I/O 
SPI) */
 #define SPINOR_OP_PP_4B                0x12    /* Page program (up to 256 
bytes) */
 #define SPINOR_OP_PP_1_1_4_4B  0x34    /* Quad page program */
 #define SPINOR_OP_PP_1_4_4_4B  0x3e    /* Quad page program */
+#define SPINOR_OP_PP_1_1_8_4B  0x84    /* Octal page program */
+#define SPINOR_OP_PP_1_8_8_4B  0x8e    /* Octal page program */
 #define SPINOR_OP_BE_4K_4B     0x21    /* Erase 4KiB block */
 #define SPINOR_OP_BE_32K_4B    0x5c    /* Erase 32KiB block */
 #define SPINOR_OP_SE_4B                0xdc    /* Sector erase (usually 64KiB) 
*/
diff --git a/include/spi.h b/include/spi.h
index 6fbb4336ce38..66959a8fe0a8 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -30,6 +30,8 @@
 #define SPI_RX_SLOW    BIT(11)                 /* receive with 1 wire slow */
 #define SPI_RX_DUAL    BIT(12)                 /* receive with 2 wires */
 #define SPI_RX_QUAD    BIT(13)                 /* receive with 4 wires */
+#define SPI_TX_OCTAL   BIT(14)                 /* transmit with 8 wires */
+#define SPI_RX_OCTAL   BIT(15)                 /* receive with 8 wires */
 
 /* Header byte that marks the start of the message */
 #define SPI_PREAMBLE_END_BYTE  0xec
-- 
2.24.0

Reply via email to