All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takahiro Kuwano <tkuw584924@gmail.com>
To: u-boot@lists.denx.de
Subject: [PATCH v5 07/10] mtd: spi-nor-core: Add non-uniform erase for Spansion/Cypress
Date: Mon, 8 Mar 2021 16:15:22 +0900	[thread overview]
Message-ID: <f5d37f4d-3e75-4ba7-b34b-be1632327aff@gmail.com> (raw)
In-Reply-To: <20210224120551.54spe6niivvav7v6@ti.com>

Hi Pratyush,

On 2/24/2021 9:05 PM, Pratyush Yadav wrote:
> On 19/02/21 10:56AM, tkuw584924 at gmail.com wrote:
>> From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
>>
>> Some of Spansion/Cypress chips have overlaid 4KB sectors at top and/or
>> bottom, depending on the device configuration, while U-Boot supports
>> uniform sector layout only.
>>
>> The spansion_erase_non_uniform() erases overlaid 4KB sectors,
>> non-overlaid portion of normal sector, and remaining normal sectors, by
>> selecting correct erase command and size based on the address to erase
>> and size of overlaid portion in parameters.
>>
>> Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
>> ---
>> Changes in v5:
>>   - New in v5, introduce spansion_erase_non_uniform() as a replacement
>>     for spansion_overlaid_erase() in v4
>>
>>  drivers/mtd/spi/spi-nor-core.c | 72 ++++++++++++++++++++++++++++++++++
>>  1 file changed, 72 insertions(+)
>>
>> diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
>> index e5fc0e7965..46948ed41b 100644
>> --- a/drivers/mtd/spi/spi-nor-core.c
>> +++ b/drivers/mtd/spi/spi-nor-core.c
>> @@ -793,6 +793,78 @@ erase_err:
>>  	return ret;
>>  }
>>  
>> +#ifdef CONFIG_SPI_FLASH_SPANSION
>> +/**
>> + * spansion_erase_non_uniform() - erase non-uniform sectors for Spansion/Cypress
>> + *                                chips
>> + * @mtd:	pointer to a 'struct mtd_info'
>> + * @instr:	pointer to a 'struct erase_info'
>> + * @ovlsz_top:	size of overlaid portion at the top address
>> + * @ovlsz_btm:	size of overlaid portion at the bottom address
>> + *
>> + * Erase an address range on the nor chip that can contain 4KB sectors overlaid
>> + * on top and/or bottom. The appropriate erase opcode and size are chosen by
>> + * address to erase and size of overlaid portion.
>> + *
>> + * Return: 0 on success, -errno otherwise.
>> + */
>> +static int spansion_erase_non_uniform(struct mtd_info *mtd,
>> +				      struct erase_info *instr, u32 ovlsz_top,
>> +				      u32 ovlsz_btm)
> 
> Is there any reason why you are not using the nor->erase() hook? As far 
> as I can see it should also be able to perform the same erase while 
> avoiding all the boilerplate needed for keeping track of address, 
> remaining erase, write enable, error handling, etc.
> 
I tried to use the nor-erase() hook, but I saw the erasesize problem
you mentioned below and didn't think about changing the return value of
existing function.

> One problem I can see is that you don't always increment address by 
> nor->erasesize. That can change depending on which sector got erased. 
> spi_nor_erase() can't currently handle that. But IMO a reasonable fix 
> for this would be to return the size actually erased in nor->erase(), 
> like how it is done for the unix read() and write() system calls. A 
> negative value would still mean an error but now a positive return value 
> will tell the caller how much data was actually erased.
> 
> I think it is a relatively easy refactor and worth doing.
> 
I agree. Let me introduce it in v6.

>> +{
>> +	struct spi_nor *nor = mtd_to_spi_nor(mtd);
>> +	struct spi_mem_op op =
>> +		SPI_MEM_OP(SPI_MEM_OP_CMD(nor->erase_opcode, 1),
>> +			   SPI_MEM_OP_ADDR(nor->addr_width, instr->addr, 1),
>> +			   SPI_MEM_OP_NO_DUMMY,
>> +			   SPI_MEM_OP_NO_DATA);
>> +	u32 len = instr->len;
>> +	u32 erasesize;
>> +	int ret;
> 
> spi_nor_erase() does some sanity checking for instr->len. Even more 
> reason to use nor->erase() so we don't have to duplicate that code.
> 
>> +
>> +	while (len) {
>> +		/* 4KB sectors */
>> +		if (op.addr.val < ovlsz_btm ||
>> +		    op.addr.val >= mtd->size - ovlsz_top) {
>> +			op.cmd.opcode = SPINOR_OP_BE_4K;
>> +			erasesize = SZ_4K;
> 
> Ok.
> 
>> +
>> +		/* Non-overlaid portion in the normal sector at the bottom */
>> +		} else if (op.addr.val == ovlsz_btm) {
>> +			op.cmd.opcode = nor->erase_opcode;
>> +			erasesize = mtd->erasesize - ovlsz_btm;
>> +
>> +		/* Non-overlaid portion in the normal sector at the top */
>> +		} else if (op.addr.val == mtd->size - mtd->erasesize) {
>> +			op.cmd.opcode = nor->erase_opcode;
>> +			erasesize = mtd->erasesize - ovlsz_top;
> 
> Patch 9/10 does not check for uniform sector size configuration. But if 
> the check is to be added later, passing 0 to ovlsz_top and ovlsz_btm 
> will do the right thing because erasesize will end up equal to 
> mtd->erasesize in both cases. Neat!
> 
>> +
>> +		/* Normal sectors */
>> +		} else {
>> +			op.cmd.opcode = nor->erase_opcode;
>> +			erasesize = mtd->erasesize;
>> +		}
> 
> Ok.
> 
>> +
>> +		write_enable(nor);
>> +
>> +		ret = spi_mem_exec_op(nor->spi, &op);
>> +		if (ret)
>> +			break;
>> +
>> +		op.addr.val += erasesize;
>> +		len -= erasesize;
> 
> I recall a patch for Linux by Tudor recently that moved some code like 
> this to after spi_nor_wait_till_ready(). Let's do so here as well. Of 
> course, this will not matter if you are using nor->erase() instead. The 
> problem will still be there since spi_nor_erase() also does this but 
> that is a separate fix.
> 
>> +
>> +		ret = spi_nor_wait_till_ready(nor);
>> +		if (ret)
>> +			break;
>> +	}
>> +
>> +	write_disable(nor);
>> +
>> +	return ret;
>> +}
>> +#endif
>> +
>>  #if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST)
>>  /* Write status register and ensure bits in mask match written values */
>>  static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask)
>> -- 
>> 2.25.1
>>
> 

  reply	other threads:[~2021-03-08  7:15 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-19  1:55 [PATCH v5 00/10] mtd: spi-nor: Add support for Cypress s25hl-t/s25hs-t tkuw584924 at gmail.com
2021-02-19  1:55 ` [PATCH v5 01/10] mtd: spi-nor: Add Cypress manufacturer ID tkuw584924 at gmail.com
2021-02-19  1:55 ` [PATCH v5 02/10] mtd: spi-nor-ids: Add Cypress s25hl-t/s25hs-t tkuw584924 at gmail.com
2021-02-19  9:51   ` Pratyush Yadav
2021-02-26 10:35   ` Jagan Teki
2021-03-08  8:49     ` Takahiro Kuwano
2021-02-19  1:55 ` [PATCH v5 03/10] mtd: spi-nor-core: Add support for Read/Write Any Register tkuw584924 at gmail.com
2021-02-19  1:55 ` [PATCH v5 04/10] mtd: spi-nor-core: Add support for volatile QE bit tkuw584924 at gmail.com
2021-02-26 10:42   ` Jagan Teki
2021-03-08  9:10     ` Takahiro Kuwano
2021-03-08  9:20       ` Pratyush Yadav
2021-02-19  1:55 ` [PATCH v5 05/10] mtd: spi-nor-core: Add the ->ready() hook tkuw584924 at gmail.com
2021-02-19  9:57   ` Pratyush Yadav
2021-03-08  6:53     ` Takahiro Kuwano
2021-02-19  1:56 ` [PATCH v5 06/10] mtd: spi-nor-core: Read status by Read Any Register tkuw584924 at gmail.com
2021-02-19 10:09   ` Pratyush Yadav
2021-02-19  1:56 ` [PATCH v5 07/10] mtd: spi-nor-core: Add non-uniform erase for Spansion/Cypress tkuw584924 at gmail.com
2021-02-24 12:05   ` Pratyush Yadav
2021-03-08  7:15     ` Takahiro Kuwano [this message]
2021-02-19  1:56 ` [PATCH v5 08/10] mtd: spi-nor-core: Add Cypress manufacturer ID in set_4byte tkuw584924 at gmail.com
2021-02-24 12:11   ` Pratyush Yadav
2021-03-08  7:26     ` Takahiro Kuwano
2021-02-19  1:56 ` [PATCH v5 09/10] mtd: spi-nor-core: Add fixups for Cypress s25hl-t/s25hs-t tkuw584924 at gmail.com
2021-02-24 12:40   ` Pratyush Yadav
2021-03-08  8:47     ` Takahiro Kuwano
2021-03-08  8:54       ` Pratyush Yadav
2021-03-08  8:59         ` Takahiro Kuwano
2021-02-19  1:56 ` [PATCH v5 10/10] mtd: spi-nor-tiny: " tkuw584924 at gmail.com
2021-02-24 12:43   ` Pratyush Yadav
2021-04-06  3:00     ` Takahiro Kuwano
2021-02-24 12:45 ` [PATCH v5 00/10] mtd: spi-nor: Add support " Pratyush Yadav

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=f5d37f4d-3e75-4ba7-b34b-be1632327aff@gmail.com \
    --to=tkuw584924@gmail.com \
    --cc=u-boot@lists.denx.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.