[PATCH v3 2/9] mtd: spi-nor: Introduce the concept of bank

Tudor Ambarus tudor.ambarus at linaro.org
Thu Mar 16 20:33:02 PDT 2023



On 2/1/23 11:32, Miquel Raynal wrote:
> Hi Tudor,
> 
> Jaime, a few questions for you below.
> 
> tudor.ambarus at linaro.org wrote on Thu, 19 Jan 2023 16:34:28 +0000:
> 
>> Hi, Miquel,
>>
>> On 12/15/22 08:12, Miquel Raynal wrote:
>>> SPI-NOR chips are made of pages, which gathered in small groups make  
>>
>> nit: s/SPI-NOR/ SPI NOR
> 
> Noted.
> 
>>
>>> (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 at bootlin.com>
>>> Reviewed-by: Pratyush Yadav <pratyush at kernel.org>
>>> ---
>>>   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;  
>>
>> Is the datasheet for these chips public? I see JESD216 says nothing
>> about flash banks.
> 
> Jaime, do you have a public datasheet for the MX25UW51245G ?
> 
>> I'm wondering whether we should keep the n_sectors as the total number of sectors per flash or not.
> 
> This is indeed a good point and I did think about it when I wrote the
> initial support. For me it looks like the banks are only relevant for
> the RWW purpose (for now) so I decided I would keep the changes minimal
> and not mess with the existing variables further. So I just added a
> "bank" member, and if you want the number of sectors per bank, you can
> divide nsectors by the number of banks. Another approach might be, as
> you ask, to count the number of sectors based on the number of sectors
> per bank and the number of banks. We can move to this approach later I
> believe, if ever useful.
> 
>> Does this flash type support Software Block
>> Protection? How do they count the sectors on Block Protection, per flash
>> or per bank?
> 
> Yes it supports block protection, AFAICS it is a per-sector
> configuration, which does not care about banks at all. It looks like
> you can protect 2^n sectors (called "blocks" in the datasheet) from the
> start or from the end of the device.

then you shouldn't change the n_sectors meaning, and keep it per flash,
and not per bank. Otherwise you break the block protection support for
these flashes. If you really need the number of sectors per bank, you
can divide n_sectors (per flash) by nbanks, can't you? So bank_size
should look like (n_sectors / nbanks) * sector_size.

> 
> Jaime, do you confirm?
> 
>>>   	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;  
>>
>> We can try u8 nbanks for now. And we would define it here, to avoid
>> struct padding.
> 
> Ok.
> 
>>>   	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,		\  
>>
>> you need to update S3AN_INFO as well.
> 
> Completely missed that one, thanks!
> 
> Cheers,
> Miquèl



More information about the linux-mtd mailing list