[PATCH v4 6/9] mtd: spi-nor-core: Add overlaid sector erase feature
Takahiro Kuwano
tkuw584924 at gmail.com
Wed Feb 10 03:37:25 CET 2021
Hi Pratyush,
On 2/2/2021 3:56 AM, Pratyush Yadav wrote:
> Hi Takahiro,
>
> On 28/01/21 01:36PM, tkuw584924 at gmail.com wrote:
>> From: Takahiro Kuwano <Takahiro.Kuwano at 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. This patch adds an erase hook that emulates
>> uniform sector layout.
>>
>> Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano at infineon.com>
>> ---
>> drivers/mtd/spi/spi-nor-core.c | 48 ++++++++++++++++++++++++++++++++++
>> 1 file changed, 48 insertions(+)
>>
>> diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
>> index 1c0ba5abf9..70da0081b6 100644
>> --- a/drivers/mtd/spi/spi-nor-core.c
>> +++ b/drivers/mtd/spi/spi-nor-core.c
>> @@ -788,6 +788,54 @@ erase_err:
>> return ret;
>> }
>>
>> +#ifdef CONFIG_SPI_FLASH_SPANSION
>> +/*
>> + * Erase for Spansion/Cypress Flash devices that has overlaid 4KB sectors at
>> + * the top and/or bottom.
>> + */
>> +static int spansion_overlaid_erase(struct mtd_info *mtd,
>> + struct erase_info *instr)
>> +{
>> + struct spi_nor *nor = mtd_to_spi_nor(mtd);
>> + struct erase_info instr_4k;
>> + u8 opcode;
>> + u32 erasesize;
>> + int ret;
>> +
>> + /* Perform default erase operation (non-overlaid portion is erased) */
>> + ret = spi_nor_erase(mtd, instr);
>> + if (ret)
>> + return ret;
>> +
>> + /* Backup default erase opcode and size */
>> + opcode = nor->erase_opcode;
>> + erasesize = mtd->erasesize;
>> +
>> + /*
>> + * Erase 4KB sectors. Use the possible max length of 4KB sector region.
>> + * The Flash just ignores the command if the address is not configured
>> + * as 4KB sector and reports ready status immediately.
>> + */
>> + instr_4k.len = SZ_128K;
>> + nor->erase_opcode = SPINOR_OP_BE_4K_4B;
>> + mtd->erasesize = SZ_4K;
>> + if (instr->addr == 0) {
>> + instr_4k.addr = 0;
>> + ret = spi_nor_erase(mtd, &instr_4k);
>> + }
>> + if (!ret && instr->addr + instr->len == mtd->size) {
>> + instr_4k.addr = mtd->size - instr_4k.len;
>> + ret = spi_nor_erase(mtd, &instr_4k);
>> + }
>
> This feels like a hack to me. Does the flash datasheet explicitly say
> that erasing the overlaid area with the "normal" erase opcode is a
> no-op?
>
Sorry, I have noticed the datasheet I mentioned in the cover letter is a
summary version. Here is the link to he full version, but you need
registration to access.
https://community.cypress.com/t5/Semper-Flash-Access-Program/Datasheet-Semper-Flash-with-Quad-SPI/ta-p/260789?attachment-id=19522
So, let me quote the description about erasing overlaid area:
"If a sector erase transaction is applied to a 256 KB sector that is
overlaid by 4 KB sectors, the overlaid 4 KB sectors are not affected
by the erase. Only the visible (non-overlaid) portion of the 128 KB
or 192 KB sector is erased."
And about 4 KB sector erase:
"This transaction is ignored when the device is configured for uniform
sector only (CFR3V[3] = 1). If the Erase 4K B sector transaction is issued
to a non-4 KB sector address, the device will abort the operation and will
not set the ERSERR status fail bit."
> I don't see a big reason to run this hack. You are already in a
> flash-specific erase hook. Why not just directly issue the correct erase
> commands to the sectors? That is, why not issue 4k erase to overlaid
> sectors and normal erase to the rest? Why do you need to emulate uniform
> erase?
>
Thanks for pointing this out. I should probably hook nor->erase() instead
of mtd->_erase(), then issue 4k or normal erase depending on the address.
I will introduce that in v5.
>> +
>> + /* Restore erase opcode and size */
>> + nor->erase_opcode = opcode;
>> + mtd->erasesize = erasesize;
>> +
>> + 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
>>
>
Best Regards,
Takahiro
More information about the U-Boot
mailing list