]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
mtd: spi-nor: Add support for Infineon s25fs256t
authorTakahiro Kuwano <Takahiro.Kuwano@infineon.com>
Mon, 19 Dec 2022 01:28:21 +0000 (10:28 +0900)
committerJagan Teki <jagan@amarulasolutions.com>
Thu, 26 Jan 2023 15:37:45 +0000 (21:07 +0530)
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
  - Supports mixture of 128KB and 64KB sectors by OTP configuration
    (this patch supports uniform 128KB only)

Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
drivers/mtd/spi/spi-nor-core.c
drivers/mtd/spi/spi-nor-ids.c
include/linux/mtd/spi-nor.h

index 7d42ba9ff8f7be266f90adfe5571605712fad26f..2c3116ee5300ff1bc9c09c8d5c605105350e618c 100644 (file)
@@ -3195,6 +3195,10 @@ static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info,
 }
 
 #ifdef CONFIG_SPI_FLASH_SPANSION
+
+/* Use ID byte 4 to distinguish S25FS256T and S25Hx-T */
+#define S25FS256T_ID4  (0x08)
+
 static int s25_mdp_ready(struct spi_nor *nor)
 {
        u32 addr;
@@ -3234,19 +3238,35 @@ static int s25_setup(struct spi_nor *nor, const struct flash_info *info,
                     const struct spi_nor_flash_parameter *params)
 {
        int ret;
-       u8 cfr3v;
+       u8 cr;
 
 #ifdef CONFIG_SPI_FLASH_BAR
        return -ENOTSUPP; /* Bank Address Register is not supported */
 #endif
+       /*
+        * S25FS256T has multiple sector architecture options, with selection of
+        * count and location of 128KB and 64KB sectors. This driver supports
+        * uniform 128KB only due to complexity of non-uniform layout.
+        */
+       if (nor->info->id[4] == S25FS256T_ID4) {
+               ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_ARCFN, 8, &cr);
+               if (ret)
+                       return ret;
+
+               if (cr) /* Option 0 (ARCFN[7:0] == 0x00) is uniform */
+                       return -EOPNOTSUPP;
+
+               return spi_nor_default_setup(nor, info, params);
+       }
+
        /*
         * Read CFR3V to check if uniform sector is selected. If not, assign an
         * erase hook that supports non-uniform erase.
         */
-       ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_CFR3V, 0, &cfr3v);
+       ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_CFR3V, 0, &cr);
        if (ret)
                return ret;
-       if (!(cfr3v & CFR3V_UNHYSA))
+       if (!(cr & CFR3V_UNHYSA))
                nor->erase = s25_erase_non_uniform;
 
        /*
@@ -3296,6 +3316,10 @@ static int s25_post_bfpt_fixup(struct spi_nor *nor,
                nor->addr_mode_nbytes = 4;
        }
 
+       /* The default address mode in S25FS256T is 4. */
+       if (nor->info->id[4] == S25FS256T_ID4)
+               nor->addr_mode_nbytes = 4;
+
        /*
         * The page_size is set to 512B from BFPT, but it actually depends on
         * the configuration register. Look up the CFR3V and determine the
@@ -3321,12 +3345,17 @@ static int s25_post_bfpt_fixup(struct spi_nor *nor,
 static void s25_post_sfdp_fixup(struct spi_nor *nor,
                                struct spi_nor_flash_parameter *params)
 {
-       /* READ_FAST_4B (0Ch) requires mode cycles*/
-       params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
-       /* PP_1_1_4 is not supported */
-       params->hwcaps.mask &= ~SNOR_HWCAPS_PP_1_1_4;
-       /* Use volatile register to enable quad */
-       params->quad_enable = s25_quad_enable;
+       if (nor->info->id[4] == S25FS256T_ID4) {
+               /* PP_1_1_4 is supported */
+               params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4;
+       } else {
+               /* READ_FAST_4B (0Ch) requires mode cycles*/
+               params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
+               /* PP_1_1_4 is not supported */
+               params->hwcaps.mask &= ~SNOR_HWCAPS_PP_1_1_4;
+               /* Use volatile register to enable quad */
+               params->quad_enable = s25_quad_enable;
+       }
 }
 
 static struct spi_nor_fixups s25_fixups = {
index 5f8f3ec955d9149dc5ac900c8c2a35248a6bd6cc..a862fbd707b335f567ff485ad3ca873d3b4b2013 100644 (file)
@@ -294,6 +294,8 @@ const struct flash_info spi_nor_ids[] = {
                USE_CLSR) },
        { INFO6("s25hs02gt",  0x342b1c, 0x0f0090, 256 * 1024, 1024,
                SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+       { INFO6("s25fs256t",  0x342b19, 0x0f0890, 128 * 1024, 256,
+               SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
 #ifdef CONFIG_SPI_FLASH_S28HX_T
        { INFO("s28hl512t",  0x345a1a,      0, 256 * 1024, 256, SPI_NOR_OCTAL_DTR_READ) },
        { INFO("s28hl01gt",  0x345a1b,      0, 256 * 1024, 512, SPI_NOR_OCTAL_DTR_READ) },
index 605cddef4d06bbe3f2d802208d7d0618278b9d3d..2861b73edbce3e774dd5480f9cfcc1fa754bea56 100644 (file)
 #define SPINOR_REG_ADDR_STR1V  0x00800000
 #define SPINOR_REG_ADDR_CFR1V  0x00800002
 #define SPINOR_REG_ADDR_CFR3V  0x00800004
+#define SPINOR_REG_ADDR_ARCFN  0x00000006
 #define CFR3V_UNHYSA           BIT(3)  /* Uniform sectors or not */
 #define CFR3V_PGMBUF           BIT(4)  /* Program buffer size */