@@ -218,6 +218,28 @@ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1);
}
}
+
+static void spi_nor_die_cnt(struct spi_nor *nor,
+ const struct flash_info *info)
+{
+ switch (JEDEC_MFR(info)) {
+ case SNOR_MFR_MICRON:
+ /* 1GiB devices */
+ if (info->id[2] == 0x21) {
+ /* MT25Q00 has 2 dies N25Q00 has 4 */
+ if (info->id[4] & BIT(6))
+ nor->die_cnt = 2;
+ else
+ nor->die_cnt = 4;
+ } else
+ nor->die_cnt = 0;
+ break;
+ default:
+ nor->die_cnt = 0;
+ break;
+ }
+}
+
static inline int spi_nor_sr_ready(struct spi_nor *nor)
{
int sr = read_sr(nor);
@@ -979,8 +1001,14 @@ static const struct flash_info spi_nor_ids[] = {
{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
{ "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
- { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
- { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+ { "n25q00", INFO(0x20ba21, 0x1000, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | DIE_ERASE) },
+ { "n25q00a", INFO(0x20bb21, 0x1000, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | DIE_ERASE) },
+ { "n25q00", INFO(0x20ba21, 0x1004, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | DIE_ERASE) },
+ { "n25q00a", INFO(0x20bb21, 0x1004, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | DIE_ERASE) },
+ { "mt25ql01g", INFO(0x20ba21, 0x1044, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | DIE_ERASE) },
+ { "mt25qu01g", INFO(0x20bb21, 0x1044, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | DIE_ERASE) },
+ { "mt25ql01g", INFO(0x20ba21, 0x1040, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | DIE_ERASE) },
+ { "mt25qu01g", INFO(0x20bb21, 0x1040, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | DIE_ERASE) },
/* PMC */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
@@ -1488,6 +1516,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
nor->flags |= SNOR_F_USE_FSR;
if (info->flags & SPI_NOR_HAS_TB)
nor->flags |= SNOR_F_HAS_SR_TB;
+ if (info->flags & DIE_ERASE) {
+ nor->flags |= SNOR_F_DIE_ERASE;
+ spi_nor_die_cnt(nor, info);
+ }
#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
/* prefer "small sector" erase if possible */