mtd: spi-nor: spansion: Add support for Infineon S25FS256T
authorTakahiro Kuwano <Takahiro.Kuwano@infineon.com>
Thu, 2 Mar 2023 07:35:07 +0000 (16:35 +0900)
committerTudor Ambarus <tudor.ambarus@linaro.org>
Fri, 17 Mar 2023 09:11:03 +0000 (11:11 +0200)
Infineon S25FS256T is 256Mbit Quad SPI NOR flash. The key features and
differences comparing to other Spansion/Cypress flash familes are:
  - 4-byte address mode by factory default
  - Quad mode is enabled by factory default
  - OP_READ_FAST_4B(0Ch) is not supported
  - Supports mixture of 128KB and 64KB sectors by OTP configuration
    (this patch supports uniform 128KB only due to complexity of
     non-uniform layout)

Tested on Xilinx Zynq-7000 FPGA board.

Link: https://www.infineon.com/dgdlac/Infineon-S25FS256T_256Mb_SEMPER_Nano_Flash_Quad_SPI_1.8V-DataSheet-v12_00-EN.pdf?fileId=8ac78c8c80027ecd0180740c5a46707a
Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
Link: https://lore.kernel.org/r/097ef04484966593ba1326d0a99462753d7d1073.1677557525.git.Takahiro.Kuwano@infineon.com
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
drivers/mtd/spi-nor/spansion.c

index 9faab29..1678b7b 100644 (file)
@@ -29,6 +29,7 @@
         SPINOR_REG_CYPRESS_CFR5_OPI)
 #define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS     SPINOR_REG_CYPRESS_CFR5_BIT6
 #define SPINOR_OP_CYPRESS_RD_FAST              0xee
+#define SPINOR_REG_CYPRESS_ARCFN               0x00000006
 
 /* Cypress SPI NOR flash operations. */
 #define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf)             \
@@ -219,6 +220,62 @@ static int cypress_nor_set_page_size(struct spi_nor *nor)
 }
 
 static int
+s25fs256t_post_bfpt_fixup(struct spi_nor *nor,
+                         const struct sfdp_parameter_header *bfpt_header,
+                         const struct sfdp_bfpt *bfpt)
+{
+       struct spi_mem_op op;
+       int ret;
+
+       /* 4-byte address mode is enabled by default */
+       nor->params->addr_nbytes = 4;
+       nor->params->addr_mode_nbytes = 4;
+
+       /* Read Architecture Configuration Register (ARCFN) */
+       op = (struct spi_mem_op)
+               CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
+                                         SPINOR_REG_CYPRESS_ARCFN, 1,
+                                         nor->bouncebuf);
+       ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
+       if (ret)
+               return ret;
+
+       /* ARCFN value must be 0 if uniform sector is selected  */
+       if (nor->bouncebuf[0])
+               return -ENODEV;
+
+       return cypress_nor_set_page_size(nor);
+}
+
+static void s25fs256t_post_sfdp_fixup(struct spi_nor *nor)
+{
+       struct spi_nor_flash_parameter *params = nor->params;
+
+       /* PP_1_1_4_4B is supported but missing in 4BAIT. */
+       params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4;
+       spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_1_1_4],
+                               SPINOR_OP_PP_1_1_4_4B,
+                               SNOR_PROTO_1_1_4);
+}
+
+static void s25fs256t_late_init(struct spi_nor *nor)
+{
+       /*
+        * Programming is supported only in 16-byte ECC data unit granularity.
+        * Byte-programming, bit-walking, or multiple program operations to the
+        * same ECC data unit without an erase are not allowed. See chapter
+        * 5.3.1 and 5.6 in the datasheet.
+        */
+       nor->params->writesize = 16;
+}
+
+static struct spi_nor_fixups s25fs256t_fixups = {
+       .post_bfpt = s25fs256t_post_bfpt_fixup,
+       .post_sfdp = s25fs256t_post_sfdp_fixup,
+       .late_init = s25fs256t_late_init,
+};
+
+static int
 s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
                        const struct sfdp_parameter_header *bfpt_header,
                        const struct sfdp_bfpt *bfpt)
@@ -446,6 +503,9 @@ static const struct flash_info spansion_nor_parts[] = {
        { "s25fl256l",  INFO(0x016019,      0,  64 * 1024, 512)
                NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
                FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
+       { "s25fs256t",  INFO6(0x342b19, 0x0f0890, 0, 0)
+               PARSE_SFDP
+               .fixups = &s25fs256t_fixups },
        { "s25hl512t",  INFO6(0x342a1a, 0x0f0390, 256 * 1024, 256)
                PARSE_SFDP
                MFR_FLAGS(USE_CLSR)