diff options
Diffstat (limited to 'drivers/mtd/spi-nor')
-rw-r--r-- | drivers/mtd/spi-nor/core.c | 32 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/micron-st.c | 34 |
2 files changed, 47 insertions, 19 deletions
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 479494cf00c9..52e5b569ddfd 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2935,6 +2935,9 @@ static int spi_nor_late_init_params(struct spi_nor *nor) return ret; } + /* Needed by some flashes late_init hooks. */ + spi_nor_init_flags(nor); + if (nor->info->fixups && nor->info->fixups->late_init) { ret = nor->info->fixups->late_init(nor); if (ret) @@ -2948,7 +2951,6 @@ static int spi_nor_late_init_params(struct spi_nor *nor) if (!params->set_4byte_addr_mode) params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_brwr; - spi_nor_init_flags(nor); spi_nor_init_fixup_flags(nor); /* @@ -3186,6 +3188,18 @@ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) struct spi_nor_flash_parameter *params = nor->params; int ret; + if (enable) { + /* + * If the RESET# pin isn't hooked up properly, or the system + * otherwise doesn't perform a reset command in the boot + * sequence, it's impossible to 100% protect against unexpected + * reboots (e.g., crashes). Warn the user (or hopefully, system + * designer) that this is bad. + */ + WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET, + "enabling reset hack; may not recover from unexpected reboots\n"); + } + ret = params->set_4byte_addr_mode(nor, enable); if (ret && ret != -ENOTSUPP) return ret; @@ -3234,20 +3248,8 @@ static int spi_nor_init(struct spi_nor *nor) if (nor->addr_nbytes == 4 && nor->read_proto != SNOR_PROTO_8_8_8_DTR && - !(nor->flags & SNOR_F_4B_OPCODES)) { - /* - * If the RESET# pin isn't hooked up properly, or the system - * otherwise doesn't perform a reset command in the boot - * sequence, it's impossible to 100% protect against unexpected - * reboots (e.g., crashes). Warn the user (or hopefully, system - * designer) that this is bad. - */ - WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET, - "enabling reset hack; may not recover from unexpected reboots\n"); - err = spi_nor_set_4byte_addr_mode(nor, true); - if (err) - return err; - } + !(nor->flags & SNOR_F_4B_OPCODES)) + return spi_nor_set_4byte_addr_mode(nor, true); return 0; } diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index 8920547c12bf..b63f1e9b97d0 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -11,6 +11,7 @@ /* flash_info mfr_flag. Used to read proprietary FSR register. */ #define USE_FSR BIT(0) +#define SPINOR_OP_MT_DIE_ERASE 0xc4 /* Chip (die) erase opcode */ #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ #define SPINOR_OP_MT_DTR_RD 0xfd /* Fast Read opcode in DTR mode */ @@ -192,6 +193,30 @@ static struct spi_nor_fixups mt25qu512a_fixups = { .post_bfpt = mt25qu512a_post_bfpt_fixup, }; +static int st_nor_four_die_late_init(struct spi_nor *nor) +{ + struct spi_nor_flash_parameter *params = nor->params; + + params->die_erase_opcode = SPINOR_OP_MT_DIE_ERASE; + params->n_dice = 4; + + /* + * Unfortunately the die erase opcode does not have a 4-byte opcode + * correspondent for these flashes. The SFDP 4BAIT table fails to + * consider the die erase too. We're forced to enter in the 4 byte + * address mode in order to benefit of the die erase. + */ + return spi_nor_set_4byte_addr_mode(nor, true); +} + +static struct spi_nor_fixups n25q00_fixups = { + .late_init = st_nor_four_die_late_init, +}; + +static struct spi_nor_fixups mt25q02_fixups = { + .late_init = st_nor_four_die_late_init, +}; + static const struct flash_info st_nor_parts[] = { { .name = "m25p05-nonjedec", @@ -366,16 +391,17 @@ static const struct flash_info st_nor_parts[] = { .name = "n25q00", .size = SZ_128M, .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | - SPI_NOR_BP3_SR_BIT6 | NO_CHIP_ERASE, + SPI_NOR_BP3_SR_BIT6, .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, .mfr_flags = USE_FSR, + .fixups = &n25q00_fixups, }, { .id = SNOR_ID(0x20, 0xba, 0x22), .name = "mt25ql02g", .size = SZ_256M, - .flags = NO_CHIP_ERASE, .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, .mfr_flags = USE_FSR, + .fixups = &mt25q02_fixups, }, { .id = SNOR_ID(0x20, 0xbb, 0x15), .name = "n25q016a", @@ -433,16 +459,16 @@ static const struct flash_info st_nor_parts[] = { .id = SNOR_ID(0x20, 0xbb, 0x21), .name = "n25q00a", .size = SZ_128M, - .flags = NO_CHIP_ERASE, .no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ, .mfr_flags = USE_FSR, + .fixups = &n25q00_fixups, }, { .id = SNOR_ID(0x20, 0xbb, 0x22), .name = "mt25qu02g", .size = SZ_256M, - .flags = NO_CHIP_ERASE, .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, .mfr_flags = USE_FSR, + .fixups = &mt25q02_fixups, } }; |