From 653f6def567c81f37302f9591ffd54df3e2a11eb Mon Sep 17 00:00:00 2001 From: Takahiro Kuwano Date: Wed, 5 Nov 2025 16:47:58 +0900 Subject: [PATCH] mtd: spi-nor: sfdp: introduce smpt_read_dummy fixup hook SMPT contains config detection info that describes opcode, address, and dummy cycles to read sector map config. The dummy cycles parameter can be SMPT_CMD_READ_DUMMY_IS_VARIABLE and in that case nor->read_dummy (initialized as 0) is used. In Infineon flash chips, Read Any Register command with variable dummy cycle is defined in SMPT. S25Hx/S28Hx flash has 0 dummy cycle by default to read volatile regiters and nor->read_dummy can work. S25FS-S flash has 8 dummy cycles so we need a hook that can fix dummy cycles with actually used value. Inroduce smpt_read_dummy() in struct spi_nor_fixups. It is called when the dummy cycle field in SMPT config detection is 'varialble'. Reviewed-by: Tudor Ambarus Tested-by: Marek Vasut # S25FS512S Signed-off-by: Takahiro Kuwano Signed-off-by: Pratyush Yadav --- drivers/mtd/spi-nor/core.h | 3 +++ drivers/mtd/spi-nor/sfdp.c | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index ceff412f7d65..5ad46d95d09c 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -409,6 +409,8 @@ struct spi_nor_flash_parameter { * flash parameters when information provided by the flash_info * table is incomplete or wrong. * @post_bfpt: called after the BFPT table has been parsed + * @smpt_read_dummy: called during SMPT table is being parsed. Used to fix the + * number of dummy cycles in read register ops. * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs * that do not support RDSFDP). Typically used to tweak various * parameters that could not be extracted by other means (i.e. @@ -426,6 +428,7 @@ struct spi_nor_fixups { int (*post_bfpt)(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt); + void (*smpt_read_dummy)(const struct spi_nor *nor, u8 *read_dummy); int (*post_sfdp)(struct spi_nor *nor); int (*late_init)(struct spi_nor *nor); }; diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index 21727f9a4ac6..9a47dcaca06a 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -699,6 +699,17 @@ static u8 spi_nor_smpt_addr_nbytes(const struct spi_nor *nor, const u32 settings } } +static void spi_nor_smpt_read_dummy_fixups(const struct spi_nor *nor, + u8 *read_dummy) +{ + if (nor->manufacturer && nor->manufacturer->fixups && + nor->manufacturer->fixups->smpt_read_dummy) + nor->manufacturer->fixups->smpt_read_dummy(nor, read_dummy); + + if (nor->info->fixups && nor->info->fixups->smpt_read_dummy) + nor->info->fixups->smpt_read_dummy(nor, read_dummy); +} + /** * spi_nor_smpt_read_dummy() - return the configuration detection command read * latency, in clock cycles. @@ -711,8 +722,11 @@ static u8 spi_nor_smpt_read_dummy(const struct spi_nor *nor, const u32 settings) { u8 read_dummy = SMPT_CMD_READ_DUMMY(settings); - if (read_dummy == SMPT_CMD_READ_DUMMY_IS_VARIABLE) - return nor->read_dummy; + if (read_dummy == SMPT_CMD_READ_DUMMY_IS_VARIABLE) { + read_dummy = nor->read_dummy; + spi_nor_smpt_read_dummy_fixups(nor, &read_dummy); + } + return read_dummy; } -- 2.47.3