[RFC 09/10] mtd: spi-nor: Disable hybrid mode for SPANSION S25FS-S family

Cyrille Pitchen cyrille.pitchen at wedev4u.fr
Wed Dec 6 02:58:18 PST 2017


Hi Prabhakar,

Le 06/12/2017 à 09:15, Prabhakar Kushwaha a écrit :
> The S25FS-S family physical sectors may be configured as a hybrid
> combination of eight 4-kB parameter sectors at the top or bottom
> of the address space with all but one of the remaining sectors
> being uniform size.
> The default status of the flash is the hybrid architecture.
> The parameter sectors and the uniform sectors have different erase
> commands.
> 
> This patch disables the hybrid sector architecture which makes the
> flash have uniform sector size and uniform erase command.
>

This issue should be addressed in a generic way, not Spansion specific,
by adding support of the optional Sector Map Parameter Table (SFDP).
In case of non uniform memories, like this Spansion S25FS-S family or
SST26, the Sector Map Parameter Table becomes mandatory as a SFDP table.

>From the JESD216B specification, about the JEDEC Sector Map Parameter Table:
"""
This table is required when a memory device:
* Has sectors of more than one size
* Or, does not allow all Erase Type commands to be applied to all sectors.
"""

Best regards,

Cyrille
 
> Signed-off-by: Rajat Srivastava <rajat.srivastava at nxp.com>
> Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 49 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mtd/spi-nor.h   |  1 +
>  2 files changed, 50 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 58c37f6f..ca2ae44 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1692,6 +1692,33 @@ static int spansion_dummy_config(struct spi_nor *nor, u8 num_wait_states,
>  	return 0;
>  }
>  
> +static int spansion_s25fs_disable_hybrid_mode(struct spi_nor *nor)
> +{
> +	u8 cr3v = 0x0;
> +	int ret = 0x0;
> +
> +	ret = nor->read_anyreg(nor, SPINOR_OP_RDAR, SPANSION_CR3V_OFF,
> +			       &cr3v, 1);
> +	if (ret < 0) {
> +		dev_err(nor->dev, "error %d reading CR3V\n", ret);
> +		return ret;
> +	}
> +
> +	/* CR3V bit3: 4-KB Erase */
> +	if (cr3v & SPANSION_CR3V_4KB_ERASE_DISABLE)
> +		return 0;
> +
> +	cr3v |= SPANSION_CR3V_4KB_ERASE_DISABLE;
> +	ret = nor->write_anyreg(nor, SPINOR_OP_RDAR, SPANSION_CR3V_OFF,
> +				&cr3v, 1);
> +	if (ret < 0) {
> +		dev_err(nor->dev, "error %d writing CR3V\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
>  static int spi_nor_check(struct spi_nor *nor)
>  {
>  	if (!nor->dev || !nor->read || !nor->write ||
> @@ -2939,6 +2966,28 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  			return ret;
>  	}
>  
> +	/*
> +	 * The S25FS-S family physical sectors may be configured as a
> +	 * hybrid combination of eight 4-kB parameter sectors
> +	 * at the top or bottom of the address space with all
> +	 * but one of the remaining sectors being uniform size.
> +	 * The Parameter Sector Erase commands (20h or 21h) must
> +	 * be used to erase the 4-kB parameter sectors individually.
> +	 * The Sector (uniform sector) Erase commands (D8h or DCh)
> +	 * must be used to erase any of the remaining
> +	 * sectors, including the portion of highest or lowest address
> +	 * sector that is not overlaid by the parameter sectors.
> +	 * The uniform sector erase command has no effect on parameter sectors.
> +	 * The following code removes the 4-kB parameter sectors from the
> +	 * address map i.e. it disables the hybrid mode so that all sectors are
> +	 * uniform size.
> +	 */
> +	if (JEDEC_EXT_ID(info) == SPINOR_S25FS_FAMILY_ID) {
> +		ret = spansion_s25fs_disable_hybrid_mode(nor);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	dev_info(dev, "%s (%lld Kbytes)\n", info->name,
>  			(long long)mtd->size >> 10);
>  
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index 9ff96cb..6c34e00 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -115,6 +115,7 @@
>  #define SPANSION_CR1V_OFF	0x00800002 /* CR1V offset */
>  #define SPANSION_CR2V_OFF	0x00800003 /* CR2V offset */
>  #define SPANSION_CR3V_OFF	0x00800004 /* CR3V offset */
> +#define SPANSION_CR3V_4KB_ERASE_DISABLE	0x8
>  
>  
>  /* Used for Micron flashes only. */
> 




More information about the linux-mtd mailing list