Commit 653f6def authored by Takahiro Kuwano's avatar Takahiro Kuwano Committed by Pratyush Yadav
Browse files

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: default avatarTudor Ambarus <tudor.ambarus@linaro.org>
Tested-by: Marek Vasut <marek.vasut+renesas@mailbox.org> # S25FS512S
Signed-off-by: default avatarTakahiro Kuwano <Takahiro.Kuwano@infineon.com>
Signed-off-by: default avatarPratyush Yadav <pratyush@kernel.org>
parent 604cf6a4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);
};
+16 −2
Original line number Diff line number Diff line
@@ -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;
}