All of lore.kernel.org
 help / color / mirror / Atom feed
* RFC: [PATCH] MTD OneNAND: multiblock erase support
@ 2009-06-15  7:03 Mika Korhonen
  2009-06-15  7:29 ` Artem Bityutskiy
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Mika Korhonen @ 2009-06-15  7:03 UTC (permalink / raw)
  To: linux-mtd Mailing List

[-- Attachment #1: Type: text/plain, Size: 452 bytes --]

Hi,

I wrote an initial support for OneNAND multiblock erase feature.  When
done in maximum 64 eraseblock batches multiblock erase is up to 30x
faster than block-by-block erase (not including erase verify, though).

However, I only had possibility to test this with an OMAP board, so I
don't know if e.g. the default onenand_wait needs adjustment. Also for
Flex-OneNAND the support goes off. Does Flex even have mb erase?

What do you think?

br,
Mika

[-- Attachment #2: 0001-MTD-OneNAND-multiblock-erase-support.patch --]
[-- Type: text/x-diff, Size: 6845 bytes --]

From 71ebb2166f129824ad3b82ba3372d104b98fb3a6 Mon Sep 17 00:00:00 2001
From: Mika Korhonen <mika.j.korhonen@gmail.com>
Date: Mon, 15 Jun 2009 09:48:36 +0300
Subject: [PATCH] MTD OneNAND: multiblock erase support

Add support for multiblock erase command. OneNAND is capable of
simultaneous erase of up to 64 eraseblocks. In case this kernel
option is enabled the erase requests for regions of size 2..64
eraseblocks are performed using multiblock erase.

Signed-off-by: Mika Korhonen <mika.j.korhonen@gmail.com>
---
 drivers/mtd/onenand/Kconfig        |    9 ++++
 drivers/mtd/onenand/omap2.c        |    6 +++
 drivers/mtd/onenand/onenand_base.c |   84 ++++++++++++++++++++++++++++++++++++
 include/linux/mtd/onenand.h        |    2 +
 include/linux/mtd/onenand_regs.h   |    2 +
 5 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index 79fa79e..f7037c3 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -64,6 +64,15 @@ config MTD_ONENAND_2X_PROGRAM
 
 	  And more recent chips
 
+config MTD_ONENAND_MULTIBLOCK_ERASE
+	bool "OneNAND multiblock erase support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	help
+	  Support for multiblock erase command. OneNAND is capable of
+	  simultaneous erase of up to 64 eraseblocks. If this option is
+	  enabled the erase requests for regions of size 2..64 eraseblocks
+	  are performed using multiblock erase.
+
 config MTD_ONENAND_SIM
 	tristate "OneNAND simulator support"
 	depends on MTD_PARTITIONS
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index df26db8..cc2b48b 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -255,6 +255,12 @@ retry:
 		return -EIO;
 	}
 
+#ifdef CONFIG_MTD_ONENAND_MULTIBLOCK_ERASE
+	/* multiblock erase command: ONGO | ERASE (0x8800) */
+	if (state == FL_PREPARING_ERASE && !(ctrl & 0x769F)) {
+		return 0;
+	}
+#endif
 	if (ctrl & 0xFE9F)
 		wait_warn("unexpected controller status", state, ctrl, intr);
 
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 864327e..1525fd7 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -31,9 +31,15 @@
 
 #include <asm/io.h>
 
+/* Multiblock erase if number of blocks to erase is 2..64 */
+#define MB_ERASE_MIN_BLK_COUNT 2
+#define MB_ERASE_MAX_BLK_COUNT 64
+
+
 /* Default Flex-OneNAND boundary and lock respectively */
 static int flex_bdry[MAX_DIES * 2] = { -1, 0, -1, 0 };
 
+
 /**
  *  onenand_oob_128 - oob info for Flex-Onenand with 4KB page
  *  For now, we expose only 64 out of 80 ecc bytes
@@ -330,6 +336,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
 		break;
 
 	case ONENAND_CMD_ERASE:
+	case ONENAND_CMD_MULTIBLOCK_ERASE:
+	case ONENAND_CMD_ERASE_VERIFY:
 	case ONENAND_CMD_BUFFERRAM:
 	case ONENAND_CMD_OTP_ACCESS:
 		block = onenand_block(this, addr);
@@ -2147,6 +2155,9 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
 	int ret = 0, i;
 	struct mtd_erase_region_info *region = NULL;
 	loff_t region_end = 0;
+#ifdef CONFIG_MTD_ONENAND_MULTIBLOCK_ERASE
+	int do_mb_erase = 0;
+#endif
 
 	DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%012llx, len = %llu\n", (unsigned long long) instr->addr, (unsigned long long) instr->len);
 
@@ -2193,6 +2204,52 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
 	onenand_get_device(mtd, FL_ERASING);
 
 	/* Loop throught the pages */
+#ifdef CONFIG_MTD_ONENAND_MULTIBLOCK_ERASE
+
+	instr->state = MTD_ERASING;
+	if (!FLEXONENAND(this) &&
+	    (len >= MB_ERASE_MIN_BLK_COUNT * block_size)) {
+		if (len <= MB_ERASE_MAX_BLK_COUNT * block_size) {
+			do_mb_erase = 1;
+		} else {
+			/* OneNAND would seem capable of handling more than
+			   64 blocks (how much more?) with multiblock erase
+			   command. However, 64 is the max for simultaneous
+			   erase */
+			printk(KERN_WARNING "onenand_erase: performance warning: "
+                               "erase over %d blocks\n", MB_ERASE_MAX_BLK_COUNT);
+			do_mb_erase = 0;
+		}
+	}
+
+	while (do_mb_erase && len > block_size) {
+		/* Check if we have a bad block, we do not erase bad blocks */
+		if (onenand_block_isbad_nolock(mtd, addr, 0)) {
+			printk(KERN_WARNING "onenand_erase: attempt to erase "
+			       "a bad block at addr 0x%08x\n", (unsigned int) addr);
+			instr->state = MTD_ERASE_FAILED;
+			goto erase_exit;
+		}
+
+		this->command(mtd, ONENAND_CMD_MULTIBLOCK_ERASE, addr, block_size);
+
+		onenand_invalidate_bufferram(mtd, addr, block_size);
+
+		ret = this->wait(mtd, FL_PREPARING_ERASE);
+		/* Check, if it is write protected */
+		if (ret) {
+			printk(KERN_ERR "onenand_erase: Failed multiblock erase, "
+                               "block %d\n", (unsigned) (addr >> this->erase_shift));
+			instr->state = MTD_ERASE_FAILED;
+			instr->fail_addr = addr;
+			goto erase_exit;
+		}
+		len -= block_size;
+		addr += block_size;
+	}
+#endif /* CONFIG_MTD_ONENAND_MULTIBLOCK_ERASE */
+
+	/* single block erase, also called for the last block of multiblock erase */
 	instr->state = MTD_ERASING;
 
 	while (len) {
@@ -2239,6 +2296,33 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 	}
 
+
+#ifdef CONFIG_MTD_ONENAND_MULTIBLOCK_ERASE
+
+	/* multiblock erase verify */
+	if (do_mb_erase) {
+		/* Loop through the blocks */
+		len = instr->len;
+		addr = instr->addr;
+
+		while (len) {
+			this->command(mtd, ONENAND_CMD_ERASE_VERIFY, addr, block_size);
+			ret = this->wait(mtd, FL_VERIFYING_ERASE);
+			if (ret) {
+				printk(KERN_ERR "onenand_erase: Failed verify, "
+					"block %d\n", (unsigned) (addr >> this->erase_shift));
+				instr->state = MTD_ERASE_FAILED;
+				instr->fail_addr = addr;
+				goto erase_exit;
+			}
+
+			len -= block_size;
+			addr += block_size;
+		}
+	}
+
+#endif /* CONFIG_MTD_ONENAND_MULTIBLOCK_ERASE */
+
 	instr->state = MTD_ERASE_DONE;
 
 erase_exit:
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 8ed8733..42384f3 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -39,6 +39,8 @@ typedef enum {
 	FL_RESETING,
 	FL_OTPING,
 	FL_PM_SUSPENDED,
+	FL_PREPARING_ERASE,
+	FL_VERIFYING_ERASE
 } onenand_state_t;
 
 /**
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index 86a6bbe..bd346e5 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -131,6 +131,8 @@
 #define ONENAND_CMD_LOCK_TIGHT		(0x2C)
 #define ONENAND_CMD_UNLOCK_ALL		(0x27)
 #define ONENAND_CMD_ERASE		(0x94)
+#define ONENAND_CMD_MULTIBLOCK_ERASE	(0x95)
+#define ONENAND_CMD_ERASE_VERIFY	(0x71)
 #define ONENAND_CMD_RESET		(0xF0)
 #define ONENAND_CMD_OTP_ACCESS		(0x65)
 #define ONENAND_CMD_READID		(0x90)
-- 
1.5.6.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: RFC: [PATCH] MTD OneNAND: multiblock erase support
  2009-06-15  7:03 RFC: [PATCH] MTD OneNAND: multiblock erase support Mika Korhonen
@ 2009-06-15  7:29 ` Artem Bityutskiy
  2009-06-15  7:54 ` Kyungmin Park
  2009-06-15 10:11 ` Adrian Hunter
  2 siblings, 0 replies; 7+ messages in thread
From: Artem Bityutskiy @ 2009-06-15  7:29 UTC (permalink / raw)
  To: Mika Korhonen; +Cc: linux-mtd Mailing List

On Mon, 2009-06-15 at 10:03 +0300, Mika Korhonen wrote:
> Hi,
> 
> I wrote an initial support for OneNAND multiblock erase feature.  When
> done in maximum 64 eraseblock batches multiblock erase is up to 30x
> faster than block-by-block erase (not including erase verify, though).
> 
> However, I only had possibility to test this with an OMAP board, so I
> don't know if e.g. the default onenand_wait needs adjustment. Also for
> Flex-OneNAND the support goes off. Does Flex even have mb erase?
> 
> What do you think?

Would it be please possible to send the patch inlined?

Also, I suggest you to CC:

Adrian Hunter <adrian.hunter@nokia.com>
Kyungmin Park <kyungmin.park@samsung.com>
Amul Saha <amul.saha@samsung.com>

because they are OneNAND-relevent.

-- 
Best regards,
Artem Bityutskiy (Битюцкий Артём)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: [PATCH] MTD OneNAND: multiblock erase support
  2009-06-15  7:03 RFC: [PATCH] MTD OneNAND: multiblock erase support Mika Korhonen
  2009-06-15  7:29 ` Artem Bityutskiy
@ 2009-06-15  7:54 ` Kyungmin Park
  2009-06-15  8:20   ` Mika Korhonen
  2009-06-15 10:11 ` Adrian Hunter
  2 siblings, 1 reply; 7+ messages in thread
From: Kyungmin Park @ 2009-06-15  7:54 UTC (permalink / raw)
  To: Mika Korhonen; +Cc: linux-mtd Mailing List

On Mon, Jun 15, 2009 at 4:03 PM, Mika Korhonen<mika.j.korhonen@gmail.com> wrote:
> Hi,
>
> I wrote an initial support for OneNAND multiblock erase feature.  When
> done in maximum 64 eraseblock batches multiblock erase is up to 30x
> faster than block-by-block erase (not including erase verify, though).
>
> However, I only had possibility to test this with an OMAP board, so I
> don't know if e.g. the default onenand_wait needs adjustment. Also for
> Flex-OneNAND the support goes off. Does Flex even have mb erase?
>
> What do you think?
>

Hi,

I think you should also modify onenand_wait. and Flex-OneNAND supports
the multi-block erase.

Do you consider the exception case if the multi-block erase failed?

I think you don't consider the bad block handling in case of multi-block erase

You first check the there's no bad block in multi-block erase. the
following code only exit. it means we never erase if we have bad
block.

+	while (do_mb_erase && len > block_size) {
+		/* Check if we have a bad block, we do not erase bad blocks */
+		if (onenand_block_isbad_nolock(mtd, addr, 0)) {
+			printk(KERN_WARNING "onenand_erase: attempt to erase "
+			       "a bad block at addr 0x%08x\n", (unsigned int) addr);
+			instr->state = MTD_ERASE_FAILED;
+			goto erase_exit;
+		}
+
+		this->command(mtd, ONENAND_CMD_MULTIBLOCK_ERASE, addr, block_size);
+
+		onenand_invalidate_bufferram(mtd, addr, block_size);
+
+		ret = this->wait(mtd, FL_PREPARING_ERASE);
+		/* Check, if it is write protected */
+		if (ret) {
+			printk(KERN_ERR "onenand_erase: Failed multiblock erase, "
+                               "block %d\n", (unsigned) (addr >>
this->erase_shift));
+			instr->state = MTD_ERASE_FAILED;
+			instr->fail_addr = addr;
+			goto erase_exit;
+		}
+		len -= block_size;
+		addr += block_size;
+	}

Thank you,
Kyungmin Park

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: [PATCH] MTD OneNAND: multiblock erase support
  2009-06-15  7:54 ` Kyungmin Park
@ 2009-06-15  8:20   ` Mika Korhonen
  0 siblings, 0 replies; 7+ messages in thread
From: Mika Korhonen @ 2009-06-15  8:20 UTC (permalink / raw)
  To: kyungmin78; +Cc: linux-mtd Mailing List

2009/6/15 Kyungmin Park <kyungmin78@gmail.com>:
> On Mon, Jun 15, 2009 at 4:03 PM, Mika Korhonen<mika.j.korhonen@gmail.com> wrote:
>> Hi,
>>
>> I wrote an initial support for OneNAND multiblock erase feature.  When
>> done in maximum 64 eraseblock batches multiblock erase is up to 30x
>> faster than block-by-block erase (not including erase verify, though).
>>
>> However, I only had possibility to test this with an OMAP board, so I
>> don't know if e.g. the default onenand_wait needs adjustment. Also for
>> Flex-OneNAND the support goes off. Does Flex even have mb erase?
>>
>> What do you think?
>>
>
> Hi,
>
> I think you should also modify onenand_wait. and Flex-OneNAND supports
> the multi-block erase.

Ok, could I actually test the default onenand_wait() by not overriding
them in OMAP-specific side? Is there anything special that should be
considered with Flex? Likely just removing the if condition would not
work, would it? :)

> Do you consider the exception case if the multi-block erase failed?
>
> I think you don't consider the bad block handling in case of multi-block erase
>
> You first check the there's no bad block in multi-block erase. the
> following code only exit. it means we never erase if we have bad
> block.

You're right but that's also how the current implementation works in
case the area to be erased contains multiple eraseblocks and a bad one
is encountered. I tried to keep the behaviour the same. To change that
for better would require some way to inform the caller which eb's were
bad. New ioctl()?

Thank you for the good comments!
Mika

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: [PATCH] MTD OneNAND: multiblock erase support
  2009-06-15  7:03 RFC: [PATCH] MTD OneNAND: multiblock erase support Mika Korhonen
  2009-06-15  7:29 ` Artem Bityutskiy
  2009-06-15  7:54 ` Kyungmin Park
@ 2009-06-15 10:11 ` Adrian Hunter
  2009-06-15 11:02   ` Mika Korhonen
  2 siblings, 1 reply; 7+ messages in thread
From: Adrian Hunter @ 2009-06-15 10:11 UTC (permalink / raw)
  To: Mika Korhonen; +Cc: kyungmin78, linux-mtd Mailing List, kyungmin.park

Mika Korhonen wrote:
> I wrote an initial support for OneNAND multiblock erase feature.  When
> done in maximum 64 eraseblock batches multiblock erase is up to 30x
> faster than block-by-block erase (not including erase verify, though).
> 
> However, I only had possibility to test this with an OMAP board, so I
> don't know if e.g. the default onenand_wait needs adjustment. Also for
> Flex-OneNAND the support goes off. Does Flex even have mb erase?
> 
> What do you think?

I expect all OneNAND support multiblock erase, so the config should
go away.  Kyungmin can probably comment on that.

Waiting for multiblock-erase, you should probably spin, not use the
interrupt line.  You should change the wait function in
onenand_base and omap2.c.

You should handle multiple multiblock erases.

You should check for bad blocks *before* doing command 0x95

Waiting for erase-verify, you should probably spin too.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: [PATCH] MTD OneNAND: multiblock erase support
  2009-06-15 10:11 ` Adrian Hunter
@ 2009-06-15 11:02   ` Mika Korhonen
  2009-06-18  7:01     ` Kyungmin Park
  0 siblings, 1 reply; 7+ messages in thread
From: Mika Korhonen @ 2009-06-15 11:02 UTC (permalink / raw)
  To: Adrian Hunter; +Cc: kyungmin.park, linux-mtd Mailing List

2009/6/15 Adrian Hunter <adrian.hunter@nokia.com>:
> Mika Korhonen wrote:
>>
>> I wrote an initial support for OneNAND multiblock erase feature.  When
>> done in maximum 64 eraseblock batches multiblock erase is up to 30x
>> faster than block-by-block erase (not including erase verify, though).
>>
>> However, I only had possibility to test this with an OMAP board, so I
>> don't know if e.g. the default onenand_wait needs adjustment. Also for
>> Flex-OneNAND the support goes off. Does Flex even have mb erase?
>>
>> What do you think?
>
> I expect all OneNAND support multiblock erase, so the config should
> go away.  Kyungmin can probably comment on that.

Yes, I was thinking about that as well. Is it included in all chips?

> Waiting for multiblock-erase, you should probably spin, not use the
> interrupt line.  You should change the wait function in
> onenand_base and omap2.c.
>
> You should handle multiple multiblock erases.
>
> You should check for bad blocks *before* doing command 0x95

Ok

> Waiting for erase-verify, you should probably spin too.
>
I just tried that and it looks like spinning in verify read makes a
difference as I got 30% faster total time for 1600 block erase.

Thanks for good advice!
Mika

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: [PATCH] MTD OneNAND: multiblock erase support
  2009-06-15 11:02   ` Mika Korhonen
@ 2009-06-18  7:01     ` Kyungmin Park
  0 siblings, 0 replies; 7+ messages in thread
From: Kyungmin Park @ 2009-06-18  7:01 UTC (permalink / raw)
  To: Mika Korhonen; +Cc: linux-mtd Mailing List, Adrian Hunter

On Mon, Jun 15, 2009 at 8:02 PM, Mika Korhonen<mika.j.korhonen@gmail.com> wrote:
> 2009/6/15 Adrian Hunter <adrian.hunter@nokia.com>:
>> Mika Korhonen wrote:
>>>
>>> I wrote an initial support for OneNAND multiblock erase feature.  When
>>> done in maximum 64 eraseblock batches multiblock erase is up to 30x
>>> faster than block-by-block erase (not including erase verify, though).
>>>
>>> However, I only had possibility to test this with an OMAP board, so I
>>> don't know if e.g. the default onenand_wait needs adjustment. Also for
>>> Flex-OneNAND the support goes off. Does Flex even have mb erase?
>>>
>>> What do you think?
>>
>> I expect all OneNAND support multiblock erase, so the config should
>> go away.  Kyungmin can probably comment on that.
>
> Yes, I was thinking about that as well. Is it included in all chips?

So I got mistake, the Flex-OneNAND don't support the multi-block
erase. Instead it support the erase suspend & resume

Thank you,
Kyungmin Park

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-06-18  7:01 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-15  7:03 RFC: [PATCH] MTD OneNAND: multiblock erase support Mika Korhonen
2009-06-15  7:29 ` Artem Bityutskiy
2009-06-15  7:54 ` Kyungmin Park
2009-06-15  8:20   ` Mika Korhonen
2009-06-15 10:11 ` Adrian Hunter
2009-06-15 11:02   ` Mika Korhonen
2009-06-18  7:01     ` Kyungmin Park

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.