Skip to content

Commit 53919a9

Browse files
committed
mtd: spi-nor: micron-st: enable die erase for multi die flashes
Enable die erase for multi die flashes, it will speed the erase time. Unfortunately, Micron does not provide a 4-byte opcode equivalent for the die erase. The SFDP 4BAIT table fails to consider the die erase too, the standard can be improved. Thus we're forced to enter in the 4 byte address mode in order to benefit of the die erase. Tested on n25q00. This flash defines the 4BAIT SFDP table, thus it will use the 4BAIT opcodes for reads, page programs or erases, with the exception that it will use the die erase command in the 4 byte address mode. Link: https://media-www.micron.com/-/media/client/global/documents/products/data-sheet/nor-flash/serial-nor/n25q/n25q_1gb_3v_65nm.pdf?rev=b6eba74759984f749f8c039bc5bc47b7 Link: https://media-www.micron.com/-/media/client/global/documents/products/data-sheet/nor-flash/serial-nor/mt25q/die-rev-b/mt25q_qlkt_l_02g_cbb_0.pdf?rev=43f7f66fc8da4d7d901b35fa51284c8f Link: https://lore.kernel.org/r/20231125123529.55686-4-tudor.ambarus@linaro.org Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
1 parent 461d0ba commit 53919a9

File tree

2 files changed

+47
-19
lines changed

2 files changed

+47
-19
lines changed

drivers/mtd/spi-nor/core.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2935,6 +2935,9 @@ static int spi_nor_late_init_params(struct spi_nor *nor)
29352935
return ret;
29362936
}
29372937

2938+
/* Needed by some flashes late_init hooks. */
2939+
spi_nor_init_flags(nor);
2940+
29382941
if (nor->info->fixups && nor->info->fixups->late_init) {
29392942
ret = nor->info->fixups->late_init(nor);
29402943
if (ret)
@@ -2948,7 +2951,6 @@ static int spi_nor_late_init_params(struct spi_nor *nor)
29482951
if (!params->set_4byte_addr_mode)
29492952
params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_brwr;
29502953

2951-
spi_nor_init_flags(nor);
29522954
spi_nor_init_fixup_flags(nor);
29532955

29542956
/*
@@ -3186,6 +3188,18 @@ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
31863188
struct spi_nor_flash_parameter *params = nor->params;
31873189
int ret;
31883190

3191+
if (enable) {
3192+
/*
3193+
* If the RESET# pin isn't hooked up properly, or the system
3194+
* otherwise doesn't perform a reset command in the boot
3195+
* sequence, it's impossible to 100% protect against unexpected
3196+
* reboots (e.g., crashes). Warn the user (or hopefully, system
3197+
* designer) that this is bad.
3198+
*/
3199+
WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
3200+
"enabling reset hack; may not recover from unexpected reboots\n");
3201+
}
3202+
31893203
ret = params->set_4byte_addr_mode(nor, enable);
31903204
if (ret && ret != -ENOTSUPP)
31913205
return ret;
@@ -3234,20 +3248,8 @@ static int spi_nor_init(struct spi_nor *nor)
32343248

32353249
if (nor->addr_nbytes == 4 &&
32363250
nor->read_proto != SNOR_PROTO_8_8_8_DTR &&
3237-
!(nor->flags & SNOR_F_4B_OPCODES)) {
3238-
/*
3239-
* If the RESET# pin isn't hooked up properly, or the system
3240-
* otherwise doesn't perform a reset command in the boot
3241-
* sequence, it's impossible to 100% protect against unexpected
3242-
* reboots (e.g., crashes). Warn the user (or hopefully, system
3243-
* designer) that this is bad.
3244-
*/
3245-
WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
3246-
"enabling reset hack; may not recover from unexpected reboots\n");
3247-
err = spi_nor_set_4byte_addr_mode(nor, true);
3248-
if (err)
3249-
return err;
3250-
}
3251+
!(nor->flags & SNOR_F_4B_OPCODES))
3252+
return spi_nor_set_4byte_addr_mode(nor, true);
32513253

32523254
return 0;
32533255
}

drivers/mtd/spi-nor/micron-st.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
/* flash_info mfr_flag. Used to read proprietary FSR register. */
1212
#define USE_FSR BIT(0)
1313

14+
#define SPINOR_OP_MT_DIE_ERASE 0xc4 /* Chip (die) erase opcode */
1415
#define SPINOR_OP_RDFSR 0x70 /* Read flag status register */
1516
#define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */
1617
#define SPINOR_OP_MT_DTR_RD 0xfd /* Fast Read opcode in DTR mode */
@@ -192,6 +193,30 @@ static struct spi_nor_fixups mt25qu512a_fixups = {
192193
.post_bfpt = mt25qu512a_post_bfpt_fixup,
193194
};
194195

196+
static int st_nor_four_die_late_init(struct spi_nor *nor)
197+
{
198+
struct spi_nor_flash_parameter *params = nor->params;
199+
200+
params->die_erase_opcode = SPINOR_OP_MT_DIE_ERASE;
201+
params->n_dice = 4;
202+
203+
/*
204+
* Unfortunately the die erase opcode does not have a 4-byte opcode
205+
* correspondent for these flashes. The SFDP 4BAIT table fails to
206+
* consider the die erase too. We're forced to enter in the 4 byte
207+
* address mode in order to benefit of the die erase.
208+
*/
209+
return spi_nor_set_4byte_addr_mode(nor, true);
210+
}
211+
212+
static struct spi_nor_fixups n25q00_fixups = {
213+
.late_init = st_nor_four_die_late_init,
214+
};
215+
216+
static struct spi_nor_fixups mt25q02_fixups = {
217+
.late_init = st_nor_four_die_late_init,
218+
};
219+
195220
static const struct flash_info st_nor_parts[] = {
196221
{
197222
.name = "m25p05-nonjedec",
@@ -366,16 +391,17 @@ static const struct flash_info st_nor_parts[] = {
366391
.name = "n25q00",
367392
.size = SZ_128M,
368393
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
369-
SPI_NOR_BP3_SR_BIT6 | NO_CHIP_ERASE,
394+
SPI_NOR_BP3_SR_BIT6,
370395
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
371396
.mfr_flags = USE_FSR,
397+
.fixups = &n25q00_fixups,
372398
}, {
373399
.id = SNOR_ID(0x20, 0xba, 0x22),
374400
.name = "mt25ql02g",
375401
.size = SZ_256M,
376-
.flags = NO_CHIP_ERASE,
377402
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
378403
.mfr_flags = USE_FSR,
404+
.fixups = &mt25q02_fixups,
379405
}, {
380406
.id = SNOR_ID(0x20, 0xbb, 0x15),
381407
.name = "n25q016a",
@@ -433,16 +459,16 @@ static const struct flash_info st_nor_parts[] = {
433459
.id = SNOR_ID(0x20, 0xbb, 0x21),
434460
.name = "n25q00a",
435461
.size = SZ_128M,
436-
.flags = NO_CHIP_ERASE,
437462
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
438463
.mfr_flags = USE_FSR,
464+
.fixups = &n25q00_fixups,
439465
}, {
440466
.id = SNOR_ID(0x20, 0xbb, 0x22),
441467
.name = "mt25qu02g",
442468
.size = SZ_256M,
443-
.flags = NO_CHIP_ERASE,
444469
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
445470
.mfr_flags = USE_FSR,
471+
.fixups = &mt25q02_fixups,
446472
}
447473
};
448474

0 commit comments

Comments
 (0)