diff options
-rw-r--r-- | drivers/mtd/spi-nor/spansion.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 9faab29aba57..1678b7b2e9f7 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -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(¶ms->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) |