diff mbox series

[v2,2/9] mtd: spi-nor: Introduce the concept of bank

Message ID 20221110155513.819798-3-miquel.raynal@bootlin.com
State Superseded
Delegated to: Ambarus Tudor
Headers show
Series mtd: spi-nor: read while write support | expand

Commit Message

Miquel Raynal Nov. 10, 2022, 3:55 p.m. UTC
SPI-NOR chips are made of pages, which gathered in small groups make
(erase) sectors. Sectors, gathered together, make banks inside the
chip. So far there was only one bank per device supported, but we are
about to introduce support for new chips featuring several banks (up to
4 so far) where different operations may happen in parallel.

Let's allow describing these additional bank parameters.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/spi-nor/core.c |  3 ++-
 drivers/mtd/spi-nor/core.h | 16 +++++++++++-----
 2 files changed, 13 insertions(+), 6 deletions(-)

Comments

Pratyush Yadav Nov. 20, 2022, 4:11 p.m. UTC | #1
On 10/11/22 04:55PM, Miquel Raynal wrote:
> SPI-NOR chips are made of pages, which gathered in small groups make
> (erase) sectors. Sectors, gathered together, make banks inside the
> chip. So far there was only one bank per device supported, but we are
> about to introduce support for new chips featuring several banks (up to
> 4 so far) where different operations may happen in parallel.
> 
> Let's allow describing these additional bank parameters.

Just to be sure, are the multiple banks still used via a single Chip 
Select, or do we need multi-CS support for this as well? I do remember 
seeing an RFC about multi-CS support from you some time back and I am 
not sure if that is related.

Reviewed-by: Pratyush Yadav <pratyush@kernel.org>

> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  drivers/mtd/spi-nor/core.c |  3 ++-
>  drivers/mtd/spi-nor/core.h | 16 +++++++++++-----
>  2 files changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index f2c64006f8d7..38a57aac6754 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -2539,7 +2539,8 @@ static void spi_nor_init_default_params(struct spi_nor *nor)
>  
>  	/* Set SPI NOR sizes. */
>  	params->writesize = 1;
> -	params->size = (u64)info->sector_size * info->n_sectors;
> +	params->bank_size = (u64)info->sector_size * info->n_sectors;
> +	params->size = params->bank_size * info->n_banks;
>  	params->page_size = info->page_size;
>  
>  	if (!(info->flags & SPI_NOR_NO_FR)) {
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index dc74c7be3e28..8a067d56c995 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -336,7 +336,8 @@ struct spi_nor_otp {
>   * by the spi_nor_fixups hooks, or dynamically when parsing the JESD216
>   * Serial Flash Discoverable Parameters (SFDP) tables.
>   *
> - * @size:		the flash memory density in bytes.
> + * @bank_size:		the flash memory bank density in bytes.
> + * @size:		the total flash memory density in bytes.
>   * @writesize		Minimal writable flash unit size. Defaults to 1. Set to
>   *			ECC unit size for ECC-ed flashes.
>   * @page_size:		the page size of the SPI NOR flash memory.
> @@ -374,6 +375,7 @@ struct spi_nor_otp {
>   * @locking_ops:	SPI NOR locking methods.
>   */
>  struct spi_nor_flash_parameter {
> +	u64				bank_size;
>  	u64				size;
>  	u32				writesize;
>  	u32				page_size;
> @@ -434,7 +436,8 @@ struct spi_nor_fixups {
>   * @id_len:         the number of bytes of ID.
>   * @sector_size:    the size listed here is what works with SPINOR_OP_SE, which
>   *                  isn't necessarily called a "sector" by the vendor.
> - * @n_sectors:      the number of sectors.
> + * @n_sectors:      the number of sectors per bank.
> + * @n_banks:        the number of banks.
>   * @page_size:      the flash's page size.
>   * @addr_nbytes:    number of address bytes to send.
>   *
> @@ -493,6 +496,7 @@ struct flash_info {
>  	u8 id_len;
>  	unsigned sector_size;
>  	u16 n_sectors;
> +	u16 n_banks;
>  	u16 page_size;
>  	u8 addr_nbytes;
>  
> @@ -538,23 +542,25 @@ struct flash_info {
>  	.id = { SPI_NOR_ID_3ITEMS(_jedec_id), SPI_NOR_ID_3ITEMS(_ext_id) }, \
>  	.id_len = 6
>  
> -#define SPI_NOR_GEOMETRY(_sector_size, _n_sectors)			\
> +#define SPI_NOR_GEOMETRY(_sector_size, _n_sectors, _n_banks)		\
>  	.sector_size = (_sector_size),					\
>  	.n_sectors = (_n_sectors),					\
> +	.n_banks = (_n_banks),						\
>  	.page_size = 256
>  
>  /* Used when the "_ext_id" is two bytes at most */
>  #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors)		\
>  	SPI_NOR_ID((_jedec_id), (_ext_id)),				\
> -	SPI_NOR_GEOMETRY((_sector_size), (_n_sectors)),
> +	SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1),
>  
>  #define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors)		\
>  	SPI_NOR_ID6((_jedec_id), (_ext_id)),				\
> -	SPI_NOR_GEOMETRY((_sector_size), (_n_sectors)),
> +	SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1),
>  
>  #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_nbytes)	\
>  		.sector_size = (_sector_size),				\
>  		.n_sectors = (_n_sectors),				\
> +		.n_banks = 1,						\
>  		.page_size = (_page_size),				\
>  		.addr_nbytes = (_addr_nbytes),				\
>  		.flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR,		\
Miquel Raynal Nov. 21, 2022, 8:26 a.m. UTC | #2
Hi Pratyush,

pratyush@kernel.org wrote on Sun, 20 Nov 2022 17:11:35 +0100:

> On 10/11/22 04:55PM, Miquel Raynal wrote:
> > SPI-NOR chips are made of pages, which gathered in small groups make
> > (erase) sectors. Sectors, gathered together, make banks inside the
> > chip. So far there was only one bank per device supported, but we are
> > about to introduce support for new chips featuring several banks (up to
> > 4 so far) where different operations may happen in parallel.
> > 
> > Let's allow describing these additional bank parameters.  
> 
> Just to be sure, are the multiple banks still used via a single Chip 
> Select, or do we need multi-CS support for this as well? I do remember 
> seeing an RFC about multi-CS support from you some time back and I am 
> not sure if that is related.

I confirm this is not related to the multi-CS binding I worked on
earlier. All the banks I am talking about are expected to be used via a
single CS.

> Reviewed-by: Pratyush Yadav <pratyush@kernel.org>

Thanks for the reviews!

Cheers,
Miquèl
diff mbox series

Patch

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index f2c64006f8d7..38a57aac6754 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2539,7 +2539,8 @@  static void spi_nor_init_default_params(struct spi_nor *nor)
 
 	/* Set SPI NOR sizes. */
 	params->writesize = 1;
-	params->size = (u64)info->sector_size * info->n_sectors;
+	params->bank_size = (u64)info->sector_size * info->n_sectors;
+	params->size = params->bank_size * info->n_banks;
 	params->page_size = info->page_size;
 
 	if (!(info->flags & SPI_NOR_NO_FR)) {
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index dc74c7be3e28..8a067d56c995 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -336,7 +336,8 @@  struct spi_nor_otp {
  * by the spi_nor_fixups hooks, or dynamically when parsing the JESD216
  * Serial Flash Discoverable Parameters (SFDP) tables.
  *
- * @size:		the flash memory density in bytes.
+ * @bank_size:		the flash memory bank density in bytes.
+ * @size:		the total flash memory density in bytes.
  * @writesize		Minimal writable flash unit size. Defaults to 1. Set to
  *			ECC unit size for ECC-ed flashes.
  * @page_size:		the page size of the SPI NOR flash memory.
@@ -374,6 +375,7 @@  struct spi_nor_otp {
  * @locking_ops:	SPI NOR locking methods.
  */
 struct spi_nor_flash_parameter {
+	u64				bank_size;
 	u64				size;
 	u32				writesize;
 	u32				page_size;
@@ -434,7 +436,8 @@  struct spi_nor_fixups {
  * @id_len:         the number of bytes of ID.
  * @sector_size:    the size listed here is what works with SPINOR_OP_SE, which
  *                  isn't necessarily called a "sector" by the vendor.
- * @n_sectors:      the number of sectors.
+ * @n_sectors:      the number of sectors per bank.
+ * @n_banks:        the number of banks.
  * @page_size:      the flash's page size.
  * @addr_nbytes:    number of address bytes to send.
  *
@@ -493,6 +496,7 @@  struct flash_info {
 	u8 id_len;
 	unsigned sector_size;
 	u16 n_sectors;
+	u16 n_banks;
 	u16 page_size;
 	u8 addr_nbytes;
 
@@ -538,23 +542,25 @@  struct flash_info {
 	.id = { SPI_NOR_ID_3ITEMS(_jedec_id), SPI_NOR_ID_3ITEMS(_ext_id) }, \
 	.id_len = 6
 
-#define SPI_NOR_GEOMETRY(_sector_size, _n_sectors)			\
+#define SPI_NOR_GEOMETRY(_sector_size, _n_sectors, _n_banks)		\
 	.sector_size = (_sector_size),					\
 	.n_sectors = (_n_sectors),					\
+	.n_banks = (_n_banks),						\
 	.page_size = 256
 
 /* Used when the "_ext_id" is two bytes at most */
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors)		\
 	SPI_NOR_ID((_jedec_id), (_ext_id)),				\
-	SPI_NOR_GEOMETRY((_sector_size), (_n_sectors)),
+	SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1),
 
 #define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors)		\
 	SPI_NOR_ID6((_jedec_id), (_ext_id)),				\
-	SPI_NOR_GEOMETRY((_sector_size), (_n_sectors)),
+	SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1),
 
 #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_nbytes)	\
 		.sector_size = (_sector_size),				\
 		.n_sectors = (_n_sectors),				\
+		.n_banks = 1,						\
 		.page_size = (_page_size),				\
 		.addr_nbytes = (_addr_nbytes),				\
 		.flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR,		\