Re: [PATCH 04/30] mtd: spi-nor: winbond: Make the RDCR fixup Winbond wide

"Michael Walle" <[email protected]>
Newsgroups org.infradead.lists.linux-mtd,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Fri May 29, 2026 at 5:22 PM CEST, Miquel Raynal wrote:
> The top level paragraph of the QER field in the JESD216B mentions:
>
> "In this standard, [...]  Status register 2 refers to the byte read
> using instruction 35h. Status register 2 is the second byte transferred
> in a Write Status (01h) command. [...]"
>
> Value 100b, named in Linux BFPT_DWORD15_QER_SR2_BIT1_NO_RD, does not
> mention anything about reads and only brings details about writes.
>
> This has been interpreted in the spi-nor core by the absence of read
> capability, but there is no explicit reason for that, except that there
> were probably some very old chips which didn't support command 35h.

I agree. But making it a vendor default we always have to have an
entry. So if this is really for all winbond chips, we shall do a
catch all entry (like in macronix.c).

> All quad capable Winbond chips carry a CMP SWP bit in SR2. SR2 is
> readable with command 35h. In practice, all Winbond families but the
> W25X family have support for this feature, so re-enable it Winbond-wide
> in a late vendor fixup, except for the {EF, 30, xx} family.
>
> Signed-off-by: Miquel Raynal <[email protected]>

> ---
>  drivers/mtd/spi-nor/winbond.c | 37 ++++++++++++++-----------------------
>  1 file changed, 14 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
> index b4088fc5fde9..4300f0419f13 100644
> --- a/drivers/mtd/spi-nor/winbond.c
> +++ b/drivers/mtd/spi-nor/winbond.c
> @@ -73,26 +73,6 @@ static const struct spi_nor_fixups w25q256_fixups = {
>  	.post_bfpt = w25q256_post_bfpt_fixups,
>  };
>  
> -static int
> -winbond_rdcr_post_bfpt_fixup(struct spi_nor *nor,
> -			     const struct sfdp_parameter_header *bfpt_header,
> -			     const struct sfdp_bfpt *bfpt)
> -{
> -	/*
> -	 * W25H02NW, unlike its W25H512NW nor W25H01NW cousins, improperly sets
> -	 * the QE BFPT configuration bits, indicating a non readable CR. This is
> -	 * both incorrect and impractical, as the chip features a CMP bit for its
> -	 * locking scheme that lays in the Control Register, and needs to be read.
> -	 */
> -	nor->flags &= ~SNOR_F_NO_READ_CR;
> -
> -	return 0;
> -}
> -
> -static const struct spi_nor_fixups winbond_rdcr_fixup = {
> -	.post_bfpt = winbond_rdcr_post_bfpt_fixup,
> -};
> -
>  /**
>   * winbond_nor_select_die() - Set active die.
>   * @nor:	pointer to 'struct spi_nor'.
> @@ -305,7 +285,6 @@ static const struct flash_info winbond_nor_parts[] = {
>  		.id = SNOR_ID(0xef, 0x60, 0x21),
>  		.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
>  			 SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP,
> -		.fixups = &winbond_rdcr_fixup,
>  	}, {
>  		/* W25Q16JV-M */
>  		.id = SNOR_ID(0xef, 0x70, 0x15),
> @@ -381,7 +360,6 @@ static const struct flash_info winbond_nor_parts[] = {
>  		.id = SNOR_ID(0xef, 0x80, 0x22),
>  		.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
>  			 SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP,
> -		.fixups = &winbond_rdcr_fixup,
>  	}, {
>  		/* W25H512NW-M */
>  		.id = SNOR_ID(0xef, 0xa0, 0x20),
> @@ -397,7 +375,6 @@ static const struct flash_info winbond_nor_parts[] = {
>  		.id = SNOR_ID(0xef, 0xa0, 0x22),
>  		.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
>  			 SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP,
> -		.fixups = &winbond_rdcr_fixup,
>  	},
>  };
>  
> @@ -490,6 +467,20 @@ static int winbond_nor_late_init(struct spi_nor *nor)
>  	 */
>  	params->set_4byte_addr_mode = winbond_nor_set_4byte_addr_mode;
>  
> +	/*
> +	 * All W25Q/W25H chips do set the BFPT_DWORD15_QER_SR2_BIT1_NO_RD bit in
> +	 * their SFDP tables. The historical spi-nor assumption in this case has
> +	 * been to declare CR reads as unsupported, whereas the Jedec
> +	 * specification doesn't clearly state that. In practice, all these
> +	 * chips do support reading back the CR, which is needed for SWP support,
> +	 * so make sure that capability remains enabled (needed for SWP).
> +	 * In practice, only exclude the old W25X family (JEDEC ID: EF 30 xx)
> +	 * which actually does not support this feature.
> +	 */
> +	if (nor->info->id->bytes[0] == 0xef &&
> +	    nor->info->id->bytes[1] > 0x30)
> +		nor->flags &= ~SNOR_F_NO_READ_CR;

This is somewhat hard to read and the byte[0] is redundant here.
Maybe you can come up with some macro magic sugar :)

-michael

> +
>  	return 0;
>  }
>

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
signature.asc (application/pgp-signature, 297 B)
-----BEGIN PGP SIGNATURE-----

iKgEABMJADAWIQTIVZIcOo5wfU/AngkSJzzuPgIf+AUCaku3lBIcbXdhbGxlQGtl
cm5lbC5vcmcACgkQEic87j4CH/hCXAGAoZmvhEM6qMZ5vdRHgIVkynetqQv0q6Qq
3aItZxX50e7fDCEFfzr4nbzxI3I26f69AYDW3bCClH49wrHqxF9kZ2f0F2OxH/Ez
b1PnDcEE7Y7PUCjZyTBOKiZD/PQlRYLjf0I=
=fZHX
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.