[PATCH v1 1/3] mtd: spi-nor: Modify rule for parse sfdp
Jaime Liao
jaimeliao.tw at gmail.com
Thu Jul 13 03:50:56 PDT 2023
From: JaimeLiao <jaimeliao.tw at gmail.com>
With various vendors adhering to the JEDEC Standard, the percentage
of SPI-NOR flash devices on the market that can read SFDP table is
increasing.
To enhance reliance on SFDP table, remove PARSE_SFDP flag,
allowing all SPI-NOR flash devices to read SFDP talbe. The exception
to this ule is for ICs that included SPI_NOR_SKIP_SFDP flag.
Furthermore, to establish a complementary relationship between ID
table information and SFDP talbe, organize no_sfdp_flags into
nor->info->flags.
The flash parameters are then organized by spi_nor_init_flags.
Signed-off-by: JaimeLiao <jaimeliao.tw at gmail.com>
---
drivers/mtd/spi-nor/core.c | 82 ++++++++++++++++++++------------------
drivers/mtd/spi-nor/core.h | 39 +++++++-----------
2 files changed, 59 insertions(+), 62 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 5f29fac8669a..bd2685a03c94 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2024,7 +2024,6 @@ static const struct flash_info spi_nor_generic_flash = {
* sane default.
*/
.page_size = 256,
- .parse_sfdp = true,
};
static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
@@ -2760,50 +2759,51 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
}
/**
- * spi_nor_no_sfdp_init_params() - Initialize the flash's parameters and
- * settings based on nor->info->sfdp_flags. This method should be called only by
- * flashes that do not define SFDP tables. If the flash supports SFDP but the
- * information is wrong and the settings from this function can not be retrieved
+ * spi_nor_flags_init_params() - Initialize the flash's parameters and
+ * settings based on nor->flags. This method should be called by flashes
+ * that define both on SFDP tables and id table informations.
+ * If the flash supports SFDP but the information is wrong
+ * and the settings from this function can not be retrieved
* by parsing SFDP, one should instead use the fixup hooks and update the wrong
* bits.
* @nor: pointer to a 'struct spi_nor'.
*/
-static void spi_nor_no_sfdp_init_params(struct spi_nor *nor)
+static void spi_nor_flags_init_params(struct spi_nor *nor)
{
struct spi_nor_flash_parameter *params = nor->params;
struct spi_nor_erase_map *map = ¶ms->erase_map;
- const u8 no_sfdp_flags = nor->info->no_sfdp_flags;
+ const u32 flags = nor->flags;
u8 i, erase_mask;
- if (no_sfdp_flags & SPI_NOR_DUAL_READ) {
+ if (flags & SPI_NOR_DUAL_READ) {
params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_2;
spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ_1_1_2],
0, 8, SPINOR_OP_READ_1_1_2,
SNOR_PROTO_1_1_2);
}
- if (no_sfdp_flags & SPI_NOR_QUAD_READ) {
+ if (flags & SPI_NOR_QUAD_READ) {
params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ_1_1_4],
0, 8, SPINOR_OP_READ_1_1_4,
SNOR_PROTO_1_1_4);
}
- if (no_sfdp_flags & SPI_NOR_OCTAL_READ) {
+ if (flags & SPI_NOR_OCTAL_READ) {
params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8;
spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ_1_1_8],
0, 8, SPINOR_OP_READ_1_1_8,
SNOR_PROTO_1_1_8);
}
- if (no_sfdp_flags & SPI_NOR_OCTAL_DTR_READ) {
+ if (flags & SPI_NOR_OCTAL_DTR_READ) {
params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR;
spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ_8_8_8_DTR],
0, 20, SPINOR_OP_READ_FAST,
SNOR_PROTO_8_8_8_DTR);
}
- if (no_sfdp_flags & SPI_NOR_OCTAL_DTR_PP) {
+ if (flags & SPI_NOR_OCTAL_DTR_PP) {
params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
/*
* Since xSPI Page Program opcode is backward compatible with
@@ -2819,7 +2819,7 @@ static void spi_nor_no_sfdp_init_params(struct spi_nor *nor)
*/
erase_mask = 0;
i = 0;
- if (no_sfdp_flags & SECT_4K) {
+ if (flags & SECT_4K) {
erase_mask |= BIT(i);
spi_nor_set_erase_type(&map->erase_type[i], 4096u,
SPINOR_OP_BE_4K);
@@ -2832,8 +2832,8 @@ static void spi_nor_no_sfdp_init_params(struct spi_nor *nor)
}
/**
- * spi_nor_init_flags() - Initialize NOR flags for settings that are not defined
- * in the JESD216 SFDP standard, thus can not be retrieved when parsing SFDP.
+ * spi_nor_init_flags() - Initialize NOR flags for settings that are defined
+ * in the id table information.
* @nor: pointer to a 'struct spi_nor'
*/
static void spi_nor_init_flags(struct spi_nor *nor)
@@ -2868,6 +2868,24 @@ static void spi_nor_init_flags(struct spi_nor *nor)
if (flags & SPI_NOR_RWW && nor->info->n_banks > 1 &&
!nor->controller_ops)
nor->flags |= SNOR_F_RWW;
+
+ if (nor->info->flags & SECT_4K)
+ nor->flags |= SNOR_F_SECT_4K;
+
+ if (nor->info->flags & SPI_NOR_DUAL_READ)
+ nor->flags |= SNOR_F_DUAL_READ;
+
+ if (nor->info->flags & SPI_NOR_QUAD_READ)
+ nor->flags |= SNOR_F_QUAD_READ;
+
+ if (nor->info->flags & SPI_NOR_OCTAL_READ)
+ nor->flags |= SNOR_F_OCTAL_READ;
+
+ if (nor->info->flags & SPI_NOR_OCTAL_DTR_READ)
+ nor->flags |= SNOR_F_OCTAL_DTR_READ;
+
+ if (nor->info->flags & SPI_NOR_OCTAL_DTR_PP)
+ nor->flags |= SNOR_F_OCTAL_DTR_PP;
}
/**
@@ -2901,6 +2919,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
{
struct spi_nor_flash_parameter *params = nor->params;
+ spi_nor_manufacturer_init_params(nor);
+
if (nor->manufacturer && nor->manufacturer->fixups &&
nor->manufacturer->fixups->late_init)
nor->manufacturer->fixups->late_init(nor);
@@ -2915,6 +2935,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
spi_nor_init_flags(nor);
spi_nor_init_fixup_flags(nor);
+ spi_nor_flags_init_params(nor);
+
/*
* NOR protection support. When locking_ops are not provided, we pick
* the default ones.
@@ -2952,19 +2974,17 @@ static void spi_nor_sfdp_init_params_deprecated(struct spi_nor *nor)
* @nor: pointer to a 'struct spi_nor'.
*
* The method assumes that flash doesn't support SFDP so it initializes flash
- * parameters in spi_nor_no_sfdp_init_params() which later on can be overwritten
+ * parameters in spi_nor_late_init_params() which later on can be overwritten
* when parsing SFDP, if supported.
*/
static void spi_nor_init_params_deprecated(struct spi_nor *nor)
{
- spi_nor_no_sfdp_init_params(nor);
-
spi_nor_manufacturer_init_params(nor);
- if (nor->info->no_sfdp_flags & (SPI_NOR_DUAL_READ |
- SPI_NOR_QUAD_READ |
- SPI_NOR_OCTAL_READ |
- SPI_NOR_OCTAL_DTR_READ))
+ if (nor->info->flags & (SPI_NOR_DUAL_READ |
+ SPI_NOR_QUAD_READ |
+ SPI_NOR_OCTAL_READ |
+ SPI_NOR_OCTAL_DTR_READ))
spi_nor_sfdp_init_params_deprecated(nor);
}
@@ -3041,19 +3061,7 @@ static void spi_nor_init_default_params(struct spi_nor *nor)
* spi_nor_manufacturer_init_params()
*
* which can be overwritten by:
- * 3/ SFDP flash parameters initialization. JESD216 SFDP is a standard and
- * should be more accurate that the above.
- * spi_nor_parse_sfdp() or spi_nor_no_sfdp_init_params()
- *
- * Please note that there is a ->post_bfpt() fixup hook that can overwrite
- * the flash parameters and settings immediately after parsing the Basic
- * Flash Parameter Table.
- * spi_nor_post_sfdp_fixups() is called after the SFDP tables are parsed.
- * It is used to tweak various flash parameters when information provided
- * by the SFDP tables are wrong.
- *
- * which can be overwritten by:
- * 4/ Late flash parameters initialization, used to initialize flash
+ * 3/ Late flash parameters initialization, used to initialize flash
* parameters that are not declared in the JESD216 SFDP standard, or where SFDP
* tables are not defined at all.
* spi_nor_late_init_params()
@@ -3070,14 +3078,12 @@ static int spi_nor_init_params(struct spi_nor *nor)
spi_nor_init_default_params(nor);
- if (nor->info->parse_sfdp) {
+ if (!(nor->info->flags & SPI_NOR_SKIP_SFDP)) {
ret = spi_nor_parse_sfdp(nor);
if (ret) {
dev_err(nor->dev, "BFPT parsing failed. Please consider using SPI_NOR_SKIP_SFDP when declaring the flash\n");
return ret;
}
- } else if (nor->info->no_sfdp_flags & SPI_NOR_SKIP_SFDP) {
- spi_nor_no_sfdp_init_params(nor);
} else {
spi_nor_init_params_deprecated(nor);
}
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 4fb5ff09c63a..f6de738a506c 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -132,6 +132,13 @@ enum spi_nor_option_flags {
SNOR_F_SWP_IS_VOLATILE = BIT(13),
SNOR_F_RWW = BIT(14),
SNOR_F_ECC = BIT(15),
+ SNOR_F_SECT_4K = BIT(16),
+ SNOR_F_DUAL_READ = BIT(17),
+ SNOR_F_QUAD_READ = BIT(18),
+ SNOR_F_OCTAL_READ = BIT(19),
+ SNOR_F_OCTAL_DTR_READ = BIT(20),
+ SNOR_F_OCTAL_DTR_PP = BIT(21),
+
};
struct spi_nor_read_command {
@@ -447,9 +454,6 @@ struct spi_nor_fixups {
* @page_size: the flash's page size.
* @addr_nbytes: number of address bytes to send.
*
- * @parse_sfdp: true when flash supports SFDP tables. The false value has no
- * meaning. If one wants to skip the SFDP tables, one should
- * instead use the SPI_NOR_SKIP_SFDP sfdp_flag.
* @flags: flags that indicate support that is not defined by the
* JESD216 standard in its SFDP tables. Flag meanings:
* SPI_NOR_HAS_LOCK: flash supports lock/unlock via SR
@@ -469,10 +473,6 @@ struct spi_nor_fixups {
* SPI_NOR_NO_FR: can't do fastread.
* SPI_NOR_QUAD_PP: flash supports Quad Input Page Program.
* SPI_NOR_RWW: flash supports reads while write.
- *
- * @no_sfdp_flags: flags that indicate support that can be discovered via SFDP.
- * Used when SFDP tables are not defined in the flash. These
- * flags are used together with the SPI_NOR_SKIP_SFDP flag.
* SPI_NOR_SKIP_SFDP: skip parsing of SFDP tables.
* SECT_4K: SPINOR_OP_BE_4K works uniformly.
* SPI_NOR_DUAL_READ: flash supports Dual Read.
@@ -508,8 +508,7 @@ struct flash_info {
u8 n_banks;
u8 addr_nbytes;
- bool parse_sfdp;
- u16 flags;
+ u32 flags;
#define SPI_NOR_HAS_LOCK BIT(0)
#define SPI_NOR_HAS_TB BIT(1)
#define SPI_NOR_TB_SR_BIT6 BIT(2)
@@ -521,15 +520,13 @@ struct flash_info {
#define SPI_NOR_NO_FR BIT(8)
#define SPI_NOR_QUAD_PP BIT(9)
#define SPI_NOR_RWW BIT(10)
-
- u8 no_sfdp_flags;
-#define SPI_NOR_SKIP_SFDP BIT(0)
-#define SECT_4K BIT(1)
-#define SPI_NOR_DUAL_READ BIT(3)
-#define SPI_NOR_QUAD_READ BIT(4)
-#define SPI_NOR_OCTAL_READ BIT(5)
-#define SPI_NOR_OCTAL_DTR_READ BIT(6)
-#define SPI_NOR_OCTAL_DTR_PP BIT(7)
+#define SPI_NOR_SKIP_SFDP BIT(11)
+#define SECT_4K BIT(12)
+#define SPI_NOR_DUAL_READ BIT(13)
+#define SPI_NOR_QUAD_READ BIT(14)
+#define SPI_NOR_OCTAL_READ BIT(15)
+#define SPI_NOR_OCTAL_DTR_READ BIT(16)
+#define SPI_NOR_OCTAL_DTR_PP BIT(17)
u8 fixup_flags;
#define SPI_NOR_4B_OPCODES BIT(0)
@@ -587,15 +584,9 @@ struct flash_info {
.n_regions = (_n_regions), \
},
-#define PARSE_SFDP \
- .parse_sfdp = true, \
-
#define FLAGS(_flags) \
.flags = (_flags), \
-#define NO_SFDP_FLAGS(_no_sfdp_flags) \
- .no_sfdp_flags = (_no_sfdp_flags), \
-
#define FIXUP_FLAGS(_fixup_flags) \
.fixup_flags = (_fixup_flags), \
--
2.25.1
More information about the linux-mtd
mailing list