[PATCH v4 1/6] mtd: spi-nor: Add manufacturer read id function

Tudor Ambarus tudor.ambarus at linaro.org
Wed Sep 20 05:28:58 PDT 2023


Hi, Jaime,

Thanks for the patch! I think we are getting closer to have this
integrated, but I have some concerns that hopefully with your help we'll
address and move forward.

On 08.09.2023 09:42, Jaime Liao wrote:
> From: JaimeLiao <jaimeliao at mxic.com.tw>
> 
> Add manufacturer read id function because of some flash
> may change data format when read id in octal dtr mode.

I'm not convinced such a method is really needed, would you please
elaborate the explanation why it's needed?

I'm looking at the mx66lm1g45g datasheet. From what I see in "Figure 13.
Read Identification (RDID) Sequence (DTR-OPI Mode)" looks like even if
the flash is operated in 8d-8d-8d mode, what the flash actually uses is
a 8d-8d-8s mode for the read id. Each ID byte is sent twice on both
rising and falling edge of the clock, thus behaving like a 8d-8d-8s
protocol.

I see this flash supports 1-1-1, 8-8-8, and 8d-8d-8d, there are no mixed
modes supported, thus a 8d-8d-8s mode seems just like a hardware bug to
me. So my proposal is to leave the core away and to handle the read id
hack just in the macronix driver.

> 
> Signed-off-by: JaimeLiao <jaimeliao at mxic.com.tw>
> ---
>  drivers/mtd/spi-nor/core.c     | 30 ++++++++++++++++++++++++++++--
>  drivers/mtd/spi-nor/core.h     |  6 ++++++
>  drivers/mtd/spi-nor/macronix.c | 18 ++++++++++++++++++
>  3 files changed, 52 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 1b0c6770c14e..7ee624b16e17 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -408,7 +408,7 @@ int spi_nor_write_disable(struct spi_nor *nor)
>  }
>  
>  /**
> - * spi_nor_read_id() - Read the JEDEC ID.
> + * spi_nor_default_read_id() - Read the JEDEC ID.
>   * @nor:	pointer to 'struct spi_nor'.
>   * @naddr:	number of address bytes to send. Can be zero if the operation
>   *		does not need to send an address.
> @@ -420,7 +420,7 @@ int spi_nor_write_disable(struct spi_nor *nor)
>   *
>   * Return: 0 on success, -errno otherwise.
>   */
> -int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
> +int spi_nor_default_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
>  		    enum spi_nor_protocol proto)
>  {
>  	int ret;
> @@ -438,6 +438,32 @@ int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
>  	return ret;
>  }
>  
> +/**
> + * spi_nor_read_id() - Read ID by manufacturer read id function.
> + * @nor:	pointer to 'struct spi_nor'.
> + * @naddr:	number of address bytes to send. Can be zero if the operation
> + *		does not need to send an address.
> + * @ndummy:	number of dummy bytes to send after an opcode or address. Can
> + *		be zero if the operation does not require dummy bytes.
> + * @id:		pointer to a DMA-able buffer where the value of the JEDEC ID
> + *		will be written.
> + * @proto:	the SPI protocol for register operation.
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
> +		    enum spi_nor_protocol proto)
> +{
> +	int ret;
> +
> +	if (nor->manufacturer && nor->manufacturer->fixups && nor->manufacturer->fixups->read_id)
> +		ret = nor->manufacturer->fixups->read_id(nor, naddr, ndummy, id, proto);
> +	else
> +		ret = spi_nor_default_read_id(nor, naddr, ndummy, id, proto);
> +
> +	return ret;
> +}
> +
>  /**
>   * spi_nor_read_sr() - Read the Status Register.
>   * @nor:	pointer to 'struct spi_nor'.
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 9217379b9cfe..92cbc2d3f7fe 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -424,6 +424,8 @@ struct spi_nor_flash_parameter {
>   * @late_init: used to initialize flash parameters that are not declared in the
>   *             JESD216 SFDP standard, or where SFDP tables not defined at all.
>   *             Will replace the default_init() hook.
> + * @read_id:   used to read id which may change format after enter into
> +	       octal dtr mode.
>   *
>   * Those hooks can be used to tweak the SPI NOR configuration when the SFDP
>   * table is broken or not available.
> @@ -435,6 +437,8 @@ struct spi_nor_fixups {
>  			 const struct sfdp_bfpt *bfpt);
>  	int (*post_sfdp)(struct spi_nor *nor);
>  	int (*late_init)(struct spi_nor *nor);
> +	int (*read_id)(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
> +		       enum spi_nor_protocol reg_proto);
>  };
>  
>  /**
> @@ -667,6 +671,8 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor);
>  int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor);
>  int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor);
>  int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor);
> +int spi_nor_default_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
> +			    enum spi_nor_protocol reg_proto);
>  int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
>  		    enum spi_nor_protocol reg_proto);
>  int spi_nor_read_sr(struct spi_nor *nor, u8 *sr);
> diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
> index eb149e517c1f..8ab47691dfbb 100644
> --- a/drivers/mtd/spi-nor/macronix.c
> +++ b/drivers/mtd/spi-nor/macronix.c
> @@ -118,9 +118,27 @@ static int macronix_nor_late_init(struct spi_nor *nor)
>  	return 0;
>  }
>  
> +static int macronix_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
> +				enum spi_nor_protocol proto)
> +{
> +	int i, ret;
> +
> +	ret = spi_nor_default_read_id(nor, naddr, ndummy, id, proto);
> +	/* Retrieve odd array and re-sort id because of read id format will be A-A-B-B-C-C
> +	 * after enter into octal dtr mode for Macronix flashes.
> +	 */
> +	if (proto == SNOR_PROTO_8_8_8_DTR) {
> +		for (i = 0; i < nor->info->id_len; i++)
> +			id[i] = id[i*2];

why do you overwrite the id? How about just checking that
id[i] == id[i + 1]? why do you care if you print an a-a-b-b-c-c id?
> +	}
> +
> +	return ret;
> +}
> +
>  static const struct spi_nor_fixups macronix_nor_fixups = {
>  	.default_init = macronix_nor_default_init,
>  	.late_init = macronix_nor_late_init,
> +	.read_id = macronix_nor_read_id,
>  };
>  
>  const struct spi_nor_manufacturer spi_nor_macronix = {



More information about the linux-mtd mailing list