[PATCH] mtd: spi-nor: scale up timeout for full-chip erase

This patch fixes timeout issues seen on large NOR flash. For full-chip erase, where we use the SPINOR_OP_CHIP_ERASE (0xc7) opcode. Use a different timeout for full-chip erase than for other commands.
[Ported from Linux kernel commit 09b6a377687b ("mtd: spi-nor: scale up timeout for full-chip erase") ]
Signed-off-by: Venkatesh Yadav Abbarapu venkatesh.abbarapu@amd.com --- drivers/mtd/spi/spi-nor-core.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 9a1801ba93..171c68787c 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -45,6 +45,12 @@
#define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ)
+/* + * For full-chip erase, calibrated to a 2MB flash (M25P16); should be scaled up + * for larger flash + */ +#define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ) + #define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y))
struct sfdp_parameter_header { @@ -832,6 +838,20 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor) DEFAULT_READY_WAIT_JIFFIES); }
+static int spi_nor_erase_chip_wait_till_ready(struct spi_nor *nor, unsigned long size) +{ + /* + * Scale the timeout linearly with the size of the flash, with + * a minimum calibrated to an old 2MB flash. We could try to + * pull these from CFI/SFDP, but these values should be good + * enough for now. + */ + unsigned long timeout = max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES, + CHIP_ERASE_2MB_READY_WAIT_JIFFIES * + (unsigned long)(size / SZ_2M)); + return spi_nor_wait_till_ready_with_timeout(nor, timeout); +} + #ifdef CONFIG_SPI_FLASH_BAR /* * This "clean_bar" is necessary in a situation when one was accessing @@ -966,7 +986,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) { struct spi_nor *nor = mtd_to_spi_nor(mtd); bool addr_known = false; - u32 addr, len, rem; + u32 addr, len, rem, max_size; int ret, err;
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr, @@ -980,6 +1000,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
addr = instr->addr; len = instr->len; + max_size = instr->len;
instr->state = MTD_ERASING; addr_known = true; @@ -1012,7 +1033,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) addr += ret; len -= ret;
- ret = spi_nor_wait_till_ready(nor); + if (max_size == mtd->size && + !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) { + ret = spi_nor_erase_chip_wait_till_ready(nor, mtd->size); + } else { + ret = spi_nor_wait_till_ready(nor); + } + if (ret) goto erase_err; }

Do you have any update on this change?
Thanks Venkatesh
-----Original Message----- From: Venkatesh Yadav Abbarapu venkatesh.abbarapu@amd.com Sent: Tuesday, January 2, 2024 6:23 PM To: u-boot@lists.denx.de Cc: Simek, Michal michal.simek@amd.com; jagan@amarulasolutions.com; git@xilinx.com Subject: [PATCH] mtd: spi-nor: scale up timeout for full-chip erase
This patch fixes timeout issues seen on large NOR flash. For full-chip erase, where we use the SPINOR_OP_CHIP_ERASE (0xc7) opcode. Use a different timeout for full-chip erase than for other commands.
[Ported from Linux kernel commit 09b6a377687b ("mtd: spi-nor: scale up timeout for full-chip erase") ]
Signed-off-by: Venkatesh Yadav Abbarapu venkatesh.abbarapu@amd.com
drivers/mtd/spi/spi-nor-core.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 9a1801ba93..171c68787c 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -45,6 +45,12 @@
#define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ)
+/*
- For full-chip erase, calibrated to a 2MB flash (M25P16); should be
+scaled up
- for larger flash
- */
+#define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ)
#define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y))
struct sfdp_parameter_header { @@ -832,6 +838,20 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
DEFAULT_READY_WAIT_JIFFIES); }
+static int spi_nor_erase_chip_wait_till_ready(struct spi_nor *nor, +unsigned long size) {
- /*
* Scale the timeout linearly with the size of the flash, with
* a minimum calibrated to an old 2MB flash. We could try to
* pull these from CFI/SFDP, but these values should be good
* enough for now.
*/
- unsigned long timeout =
max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES,
CHIP_ERASE_2MB_READY_WAIT_JIFFIES *
(unsigned long)(size / SZ_2M));
- return spi_nor_wait_till_ready_with_timeout(nor, timeout); }
#ifdef CONFIG_SPI_FLASH_BAR /*
- This "clean_bar" is necessary in a situation when one was accessing @@ -
966,7 +986,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) { struct spi_nor *nor = mtd_to_spi_nor(mtd); bool addr_known = false;
- u32 addr, len, rem;
u32 addr, len, rem, max_size; int ret, err;
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr, @@
-980,6 +1000,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
addr = instr->addr; len = instr->len;
max_size = instr->len;
instr->state = MTD_ERASING; addr_known = true;
@@ -1012,7 +1033,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) addr += ret; len -= ret;
ret = spi_nor_wait_till_ready(nor);
if (max_size == mtd->size &&
!(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
ret = spi_nor_erase_chip_wait_till_ready(nor, mtd-
size);
} else {
ret = spi_nor_wait_till_ready(nor);
}
- if (ret) goto erase_err; }
-- 2.25.1

+Tom
Any update on this?
Thanks Venkatesh
-----Original Message----- From: Abbarapu, Venkatesh venkatesh.abbarapu@amd.com Sent: Tuesday, May 7, 2024 9:51 AM To: Abbarapu, Venkatesh venkatesh.abbarapu@amd.com; u-boot@lists.denx.de Cc: Simek, Michal michal.simek@amd.com; jagan@amarulasolutions.com; git@xilinx.com Subject: RE: [PATCH] mtd: spi-nor: scale up timeout for full-chip erase
Do you have any update on this change?
Thanks Venkatesh
-----Original Message----- From: Venkatesh Yadav Abbarapu venkatesh.abbarapu@amd.com Sent: Tuesday, January 2, 2024 6:23 PM To: u-boot@lists.denx.de Cc: Simek, Michal michal.simek@amd.com; jagan@amarulasolutions.com; git@xilinx.com Subject: [PATCH] mtd: spi-nor: scale up timeout for full-chip erase
This patch fixes timeout issues seen on large NOR flash. For full-chip erase, where we use the SPINOR_OP_CHIP_ERASE (0xc7) opcode. Use a different timeout for full-chip erase than for other commands.
[Ported from Linux kernel commit 09b6a377687b ("mtd: spi-nor: scale up timeout for full-chip erase") ]
Signed-off-by: Venkatesh Yadav Abbarapu venkatesh.abbarapu@amd.com
drivers/mtd/spi/spi-nor-core.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 9a1801ba93..171c68787c 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -45,6 +45,12 @@
#define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ)
+/*
- For full-chip erase, calibrated to a 2MB flash (M25P16); should be
+scaled up
- for larger flash
- */
+#define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ)
#define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y))
struct sfdp_parameter_header { @@ -832,6 +838,20 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
DEFAULT_READY_WAIT_JIFFIES); }
+static int spi_nor_erase_chip_wait_till_ready(struct spi_nor *nor, +unsigned long size) {
- /*
* Scale the timeout linearly with the size of the flash, with
* a minimum calibrated to an old 2MB flash. We could try to
* pull these from CFI/SFDP, but these values should be good
* enough for now.
*/
- unsigned long timeout =
max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES,
CHIP_ERASE_2MB_READY_WAIT_JIFFIES *
(unsigned long)(size / SZ_2M));
- return spi_nor_wait_till_ready_with_timeout(nor, timeout); }
#ifdef CONFIG_SPI_FLASH_BAR /*
- This "clean_bar" is necessary in a situation when one was
accessing @@ - 966,7 +986,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) { struct spi_nor *nor = mtd_to_spi_nor(mtd); bool addr_known = false;
- u32 addr, len, rem;
u32 addr, len, rem, max_size; int ret, err;
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -980,6 +1000,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
addr = instr->addr; len = instr->len;
max_size = instr->len;
instr->state = MTD_ERASING; addr_known = true;
@@ -1012,7 +1033,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) addr += ret; len -= ret;
ret = spi_nor_wait_till_ready(nor);
if (max_size == mtd->size &&
!(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
ret = spi_nor_erase_chip_wait_till_ready(nor, mtd-
size);
} else {
ret = spi_nor_wait_till_ready(nor);
}
- if (ret) goto erase_err; }
-- 2.25.1

On Tue, 02 Jan 2024 18:23:03 +0530, Venkatesh Yadav Abbarapu wrote:
This patch fixes timeout issues seen on large NOR flash. For full-chip erase, where we use the SPINOR_OP_CHIP_ERASE (0xc7) opcode. Use a different timeout for full-chip erase than for other commands.
[Ported from Linux kernel commit 09b6a377687b ("mtd: spi-nor: scale up timeout for full-chip erase") ]
[...]
Applied to u-boot/next, thanks!
participants (3)
-
Abbarapu, Venkatesh
-
Tom Rini
-
Venkatesh Yadav Abbarapu