mtd: spi-nor: sfdp: get the 1-1-8 and 1-8-8 protocol from SFDP
authorJaimeLiao <jaimeliao@mxic.com.tw>
Tue, 19 Dec 2023 10:21:03 +0000 (18:21 +0800)
committerTudor Ambarus <tudor.ambarus@linaro.org>
Wed, 20 Dec 2023 08:44:00 +0000 (10:44 +0200)
BFPT 17th DWORD contains the information about 1-1-8 and 1-8-8.
Parse BFPT DWORD[17] instruction to determine whether flash
supports 1-1-8 and 1-8-8, and set its dummy cycles accordingly.

Validated only the 1-1-8 read using a macronix flash with
Xilinx board zynq-picozed.

Signed-off-by: JaimeLiao <jaimeliao@mxic.com.tw>
Reviewed-by: Michael Walle <mwalle@kernel.org>
Link: https://lore.kernel.org/r/20231219102103.92738-2-jaimeliao.tw@gmail.com
[ta: update commit message, get rid of extra dereference]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
drivers/mtd/spi-nor/sfdp.c
drivers/mtd/spi-nor/sfdp.h

index b3b11dfed7893d84991a5da71b5702ee4d7a47c5..57713de3283278970c5d125bde422c36dfd71b5e 100644 (file)
@@ -446,6 +446,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
        u32 dword;
        u16 half;
        u8 erase_mask;
+       u8 wait_states, mode_clocks, opcode;
 
        /* JESD216 Basic Flash Parameter Table length is at least 9 DWORDs. */
        if (bfpt_header->length < BFPT_DWORD_MAX_JESD216)
@@ -631,6 +632,32 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
        if (bfpt_header->length == BFPT_DWORD_MAX_JESD216B)
                return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt);
 
+       /* Parse 1-1-8 read instruction */
+       opcode = FIELD_GET(BFPT_DWORD17_RD_1_1_8_CMD, bfpt.dwords[SFDP_DWORD(17)]);
+       if (opcode) {
+               mode_clocks = FIELD_GET(BFPT_DWORD17_RD_1_1_8_MODE_CLOCKS,
+                                       bfpt.dwords[SFDP_DWORD(17)]);
+               wait_states = FIELD_GET(BFPT_DWORD17_RD_1_1_8_WAIT_STATES,
+                                       bfpt.dwords[SFDP_DWORD(17)]);
+               params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8;
+               spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_1_1_8],
+                                         mode_clocks, wait_states, opcode,
+                                         SNOR_PROTO_1_1_8);
+       }
+
+       /* Parse 1-8-8 read instruction */
+       opcode = FIELD_GET(BFPT_DWORD17_RD_1_8_8_CMD, bfpt.dwords[SFDP_DWORD(17)]);
+       if (opcode) {
+               mode_clocks = FIELD_GET(BFPT_DWORD17_RD_1_8_8_MODE_CLOCKS,
+                                       bfpt.dwords[SFDP_DWORD(17)]);
+               wait_states = FIELD_GET(BFPT_DWORD17_RD_1_8_8_WAIT_STATES,
+                                       bfpt.dwords[SFDP_DWORD(17)]);
+               params->hwcaps.mask |= SNOR_HWCAPS_READ_1_8_8;
+               spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_1_8_8],
+                                         mode_clocks, wait_states, opcode,
+                                         SNOR_PROTO_1_8_8);
+       }
+
        /* 8D-8D-8D command extension. */
        switch (bfpt.dwords[SFDP_DWORD(18)] & BFPT_DWORD18_CMD_EXT_MASK) {
        case BFPT_DWORD18_CMD_EXT_REP:
@@ -968,6 +995,8 @@ static int spi_nor_parse_4bait(struct spi_nor *nor,
                { SNOR_HWCAPS_READ_1_1_1_DTR,   BIT(13) },
                { SNOR_HWCAPS_READ_1_2_2_DTR,   BIT(14) },
                { SNOR_HWCAPS_READ_1_4_4_DTR,   BIT(15) },
+               { SNOR_HWCAPS_READ_1_1_8,       BIT(20) },
+               { SNOR_HWCAPS_READ_1_8_8,       BIT(21) },
        };
        static const struct sfdp_4bait programs[] = {
                { SNOR_HWCAPS_PP,               BIT(6) },
index 6eb99e1cdd619d2c0bdb468d6febe5a943d00b58..da0fe5aa9bb0a13b46a69c95cbd3ba960332bbb5 100644 (file)
@@ -118,6 +118,13 @@ struct sfdp_bfpt {
        (BFPT_DWORD16_EN4B_EN4B | BFPT_DWORD16_EX4B_EX4B)
 #define BFPT_DWORD16_SWRST_EN_RST              BIT(12)
 
+#define BFPT_DWORD17_RD_1_1_8_CMD              GENMASK(31, 24)
+#define BFPT_DWORD17_RD_1_1_8_MODE_CLOCKS      GENMASK(23, 21)
+#define BFPT_DWORD17_RD_1_1_8_WAIT_STATES      GENMASK(20, 16)
+#define BFPT_DWORD17_RD_1_8_8_CMD              GENMASK(15, 8)
+#define BFPT_DWORD17_RD_1_8_8_MODE_CLOCKS      GENMASK(7, 5)
+#define BFPT_DWORD17_RD_1_8_8_WAIT_STATES      GENMASK(4, 0)
+
 #define BFPT_DWORD18_CMD_EXT_MASK              GENMASK(30, 29)
 #define BFPT_DWORD18_CMD_EXT_REP               (0x0UL << 29) /* Repeat */
 #define BFPT_DWORD18_CMD_EXT_INV               (0x1UL << 29) /* Invert */