mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Marek Vasut <marek.vasut@gmail.com>
To: Cyrille Pitchen <cyrille.pitchen@atmel.com>,
	linux-mtd@lists.infradead.org, jartur@cadence.com,
	kdasu.kdev@gmail.com, mar.krzeminski@gmail.com
Cc: computersforpeace@gmail.com, dwmw2@infradead.org,
	boris.brezillon@free-electrons.com, richard@nod.at,
	linux-kernel@vger.kernel.org, nicolas.ferre@microchip.com
Subject: Re: [RFC PATCH v5 4/6] mtd: spi-nor: add support to non-uniform SPI NOR flash memories
Date: Sat, 15 Apr 2017 17:24:45 +0200	[thread overview]
Message-ID: <5cb3f0f1-b932-7d79-7aaf-2e08952b3a2c@gmail.com> (raw)
In-Reply-To: <fa832746dedee8d1b6ea97b0418f22da81031606.1490220411.git.cyrille.pitchen@atmel.com>

On 03/23/2017 12:33 AM, Cyrille Pitchen wrote:

Hrmmmm, sigh, took me almost month to review this one, sorry :(

> This patch is a first step in introducing  the support of SPI memories
> with non-uniform erase sizes like Spansion s25fs512s.
> 
> It introduces the memory erase map which splits the memory array into one
> or many erase regions. Each erase region supports up to 4 erase commands,
> as defined by the JEDEC JESD216B (SFDP) specification.
> In turn, an erase command is defined by an op code and a sector size.
> 
> To be backward compatible, the erase map of uniform SPI NOR flash memories
> is initialized so it contains only one erase region and this erase region
> supports only one erase command. Hence a single size is used to erase any
> sector/block of the memory.
> 
> Besides, since the algorithm used to erase sectors on non-uniform SPI NOR
> flash memories is quite expensive, when possible, the erase map is tuned
> to come back to the uniform case.
> 
> This is a transitional patch: non-uniform erase maps will be used later
> when initialized based on the SFDP data.
> 
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>

[...]

Before I dive into the code, I have two questions:

1) On ie. 128 MiB part, how many struct spi_nor_erase_region {}
   instances would be allocated in total (consider you support
   4k, 64k and 32M erase opcodes) ? Three ?

2) Would it make sense to represent the erase regions as a tree instead?
   For example

      [ region with 32MiB die erase opcode , start=0 , count=4 ]
            |
            V
[ region with 64k erase opcode ][ region with 64k erase opcode ]
[       start=0, count=1       ][      start=0, count=511      ]
            |
            V
[ region with 4k erase opcode ]
[      start=0, count=16      ]

I think it'd make the lookup for the best-fitting opcode combination
faster if the user decides to erase some arbitrarily-aligned block of
the flash.

What do you think ?

Note this tree-based approach does not handle the cases where erase
regions would overlap, although I doubt that could be a problem .

> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index d270788f5ab6..c12cafe99bee 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -216,6 +216,55 @@ enum spi_nor_option_flags {
>  };
>  
>  /**
> + * struct spi_nor_erase_command - Structure to describe a SPI NOR erase command
> + * @size:		the size of the sector/block erased by the command.
> + * @size_shift:		the size shift: if @size is a power of 2 then the shift
> + *			is stored in @size_shift, otherwise @size_shift is zero.
> + * @size_mask:		the size mask based on @size_shift.
> + * @opcode:		the SPI command op code to erase the sector/block.
> + */
> +struct spi_nor_erase_command {
> +	u32	size;
> +	u32	size_shift;
> +	u32	size_mask;
> +	u8	opcode;
> +};
> +
> +/**
> + * struct spi_nor_erase_region - Structure to describe a SPI NOR erase region
> + * @offset:		the offset in the data array of erase region start.
> + *			LSB bits are used as a bitmask encoding the erase
> + *			commands supported inside this erase region.
> + * @size:		the size of the region in bytes.
> + */
> +struct spi_nor_erase_region {
> +	u64		offset;
> +	u64		size;
> +};
> +
> +#define SNOR_CMD_ERASE_MAX	4
> +#define SNOR_CMD_ERASE_MASK	GENMASK_ULL(SNOR_CMD_ERASE_MAX - 1, 0)
> +#define SNOR_CMD_ERASE_OFFSET(_cmd_mask, _offset)	\
> +	((((u64)(_offset)) & ~SNOR_CMD_ERASE_MASK) |	\
> +	 (((u64)(_cmd_mask)) & SNOR_CMD_ERASE_MASK))
> +
> +/**
> + * struct spi_nor_erase_map - Structure to describe the SPI NOR erase map
> + * @commands:		an array of erase commands shared by all the regions.
> + * @uniform_region:	a pre-allocated erase region for SPI NOR with a uniform
> + *			sector size (legacy implementation).
> + * @regions:		point to an array describing the boundaries of the erase
> + *			regions.
> + * @num_regions:	the number of elements in the @regions array.
> + */
> +struct spi_nor_erase_map {
> +	struct spi_nor_erase_command	commands[SNOR_CMD_ERASE_MAX];
> +	struct spi_nor_erase_region	uniform_region;
> +	struct spi_nor_erase_region	*regions;
> +	u32				num_regions;
> +};
> +
> +/**
>   * struct flash_info -	Forward declaration of a structure used internally by
>   *			spi_nor_scan() and spi_nor_init().
>   */
> @@ -238,6 +287,7 @@ struct flash_info;
>   * @write_proto:	the SPI protocol for write operations
>   * @reg_proto		the SPI protocol for read_reg/write_reg/erase operations
>   * @cmd_buf:		used by the write_reg
> + * @erase_map:		the erase map of the SPI NOR
>   * @prepare:		[OPTIONAL] do some preparations for the
>   *			read/write/erase/lock/unlock operations
>   * @unprepare:		[OPTIONAL] do some post work after the
> @@ -273,6 +323,7 @@ struct spi_nor {
>  	bool			sst_write_second;
>  	u32			flags;
>  	u8			cmd_buf[SPI_NOR_MAX_CMD_SIZE];
> +	struct spi_nor_erase_map	erase_map;
>  
>  	int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
>  	void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
> @@ -293,6 +344,11 @@ struct spi_nor {
>  	void *priv;
>  };
>  
> +static inline bool spi_nor_has_uniform_erase(const struct spi_nor *nor)
> +{
> +	return (nor->erase_map.regions == &nor->erase_map.uniform_region);
> +}
> +
>  static inline void spi_nor_set_flash_node(struct spi_nor *nor,
>  					  struct device_node *np)
>  {
> 


-- 
Best regards,
Marek Vasut

  reply	other threads:[~2017-04-15 15:34 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-22 23:33 [PATCH v5 0/6] mtd: spi-nor: parse SFDP tables to setup (Q)SPI memories Cyrille Pitchen
2017-03-22 23:33 ` [PATCH v5 1/6] mtd: spi-nor: introduce more SPI protocols and the Dual Transfer Mode Cyrille Pitchen
2017-03-23 15:13   ` Cédric Le Goater
2017-03-23 19:10     ` Cyrille Pitchen
2017-03-24 10:03       ` Cédric Le Goater
2017-03-24 11:39         ` Cyrille Pitchen
2017-04-02 17:05   ` Cyrille Pitchen
2017-04-06 23:30   ` Marek Vasut
2017-04-09 21:16     ` Cyrille Pitchen
2017-04-09 21:40       ` Marek Vasut
2017-03-22 23:33 ` [PATCH v5 2/6] mtd: m25p80: add support of SPI 1-2-2 and 1-4-4 protocols Cyrille Pitchen
2017-04-02 17:05   ` Cyrille Pitchen
2017-04-06 23:37   ` Marek Vasut
2017-04-09 19:37     ` Cyrille Pitchen
2017-04-09 20:46       ` Marek Vasut
2017-04-09 21:30         ` Cyrille Pitchen
2017-04-09 21:46           ` Marek Vasut
2017-03-22 23:33 ` [PATCH v5 3/6] mtd: spi-nor: add spi_nor_init() function Cyrille Pitchen
2017-04-02 17:06   ` Cyrille Pitchen
2017-03-22 23:33 ` [RFC PATCH v5 4/6] mtd: spi-nor: add support to non-uniform SPI NOR flash memories Cyrille Pitchen
2017-04-15 15:24   ` Marek Vasut [this message]
2017-03-22 23:33 ` [RFC PATCH v5 5/6] mtd: spi-nor: parse Serial Flash Discoverable Parameters (SFDP) tables Cyrille Pitchen
2017-04-15 15:34   ` Marek Vasut
2017-03-22 23:39 ` [RFC PATCH v5 6/6] mtd: spi-nor: parse SFDP 4-byte Address Instruction Table Cyrille Pitchen
2017-04-15 15:36   ` Marek Vasut
2017-03-29 16:45 ` [PATCH v5 0/6] mtd: spi-nor: parse SFDP tables to setup (Q)SPI memories Cyrille Pitchen
2017-04-02 18:32   ` Marek Vasut

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5cb3f0f1-b932-7d79-7aaf-2e08952b3a2c@gmail.com \
    --to=marek.vasut@gmail.com \
    --cc=boris.brezillon@free-electrons.com \
    --cc=computersforpeace@gmail.com \
    --cc=cyrille.pitchen@atmel.com \
    --cc=dwmw2@infradead.org \
    --cc=jartur@cadence.com \
    --cc=kdasu.kdev@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=mar.krzeminski@gmail.com \
    --cc=nicolas.ferre@microchip.com \
    --cc=richard@nod.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®