From: Sascha Hauer <s.hauer@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 5/6] nor m25p80: optimize erase
Date: Tue, 31 Jul 2012 19:59:15 +0200 [thread overview]
Message-ID: <1343757556-11897-6-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1343757556-11897-1-git-send-email-s.hauer@pengutronix.de>
The driver currently erases blocks in 4kb chunks if 4kb support is
available. This patch uses bigger blocks for suitable areas to speed
up erasing areas.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/nor/m25p80.c | 59 +++++++++++++++++++++++++++++++++++---------------
drivers/nor/m25p80.h | 2 ++
2 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/drivers/nor/m25p80.c b/drivers/nor/m25p80.c
index 7ff4546..4b62e93 100644
--- a/drivers/nor/m25p80.c
+++ b/drivers/nor/m25p80.c
@@ -168,7 +168,7 @@ static int m25p_cmdsz(struct m25p *flash)
*
* Returns 0 if successful, non-zero otherwise.
*/
-static int erase_sector(struct m25p *flash, u32 offset)
+static int erase_sector(struct m25p *flash, u32 offset, u32 command)
{
dev_dbg(&flash->spi->dev, "%s %dKiB at 0x%08x\n",
__func__, flash->erasesize / 1024, offset);
@@ -181,7 +181,7 @@ static int erase_sector(struct m25p *flash, u32 offset)
write_enable(flash);
/* Set up command buffer. */
- flash->command[0] = flash->erase_opcode;
+ flash->command[0] = command;
m25p_addr2cmd(flash, offset, flash->command);
spi_write(flash->spi, flash->command, m25p_cmdsz(flash));
@@ -216,22 +216,45 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
return 0;
}
- /* REVISIT in some cases we could speed up erasing large regions
- * by using OPCODE_SE instead of OPCODE_BE_4K. We may have set up
- * to use "small sector erase", but that's not always optimal.
- */
+ if (flash->erase_opcode_4k) {
+ while (len && (addr & (flash->sector_size - 1))) {
+ if (ctrlc())
+ return -EINTR;
+ if (erase_sector(flash, addr, flash->erase_opcode_4k))
+ return -EIO;
+ addr += flash->erasesize;
+ len -= flash->erasesize;
+ }
- /* "sector"-at-a-time erase */
- while (len) {
- if (ctrlc())
- return -EINTR;
- if (erase_sector(flash, addr))
- return -EIO;
+ while (len >= flash->sector_size) {
+ if (ctrlc())
+ return -EINTR;
+ if (erase_sector(flash, addr, flash->erase_opcode))
+ return -EIO;
+ addr += flash->sector_size;
+ len -= flash->sector_size;
+ }
- if (len <= flash->erasesize)
- break;
- addr += flash->erasesize;
- len -= flash->erasesize;
+ while (len) {
+ if (ctrlc())
+ return -EINTR;
+ if (erase_sector(flash, addr, flash->erase_opcode_4k))
+ return -EIO;
+ addr += flash->erasesize;
+ len -= flash->erasesize;
+ }
+ } else {
+ while (len) {
+ if (ctrlc())
+ return -EINTR;
+ if (erase_sector(flash, addr, flash->erase_opcode))
+ return -EIO;
+
+ if (len <= flash->erasesize)
+ break;
+ addr += flash->erasesize;
+ len -= flash->erasesize;
+ }
}
return 0;
@@ -753,6 +776,7 @@ static int m25p_probe(struct device_d *dev)
flash->info = info;
flash->size = info->sector_size * info->n_sectors;
flash->erasesize = info->sector_size;
+ flash->sector_size = info->sector_size;
flash->cdev.size = info->sector_size * info->n_sectors;
flash->cdev.dev = dev;
flash->cdev.ops = &m25p80_ops;
@@ -773,7 +797,8 @@ static int m25p_probe(struct device_d *dev)
/* prefer "small sector" erase if possible */
if (info->flags & SECT_4K) {
- flash->erase_opcode = OPCODE_BE_4K;
+ flash->erase_opcode_4k = OPCODE_BE_4K;
+ flash->erase_opcode = OPCODE_SE;
flash->erasesize = 4096;
} else {
flash->erase_opcode = OPCODE_SE;
diff --git a/drivers/nor/m25p80.h b/drivers/nor/m25p80.h
index 3f9dd9c..ce48ba7 100644
--- a/drivers/nor/m25p80.h
+++ b/drivers/nor/m25p80.h
@@ -58,9 +58,11 @@ struct m25p {
struct cdev cdev;
char *name;
u32 erasesize;
+ u32 sector_size;
u16 page_size;
u16 addr_width;
u8 erase_opcode;
+ u8 erase_opcode_4k;
u8 *command;
u32 size;
};
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2012-07-31 17:59 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-31 17:59 [PATCH] m25p80 spi flash updates Sascha Hauer
2012-07-31 17:59 ` [PATCH 1/6] nor m25p80: remove progression bar Sascha Hauer
2012-07-31 17:59 ` [PATCH 2/6] nor m25p80: remove unused variables Sascha Hauer
2012-07-31 17:59 ` [PATCH 3/6] nor m25p80: refactor chip erase Sascha Hauer
2012-07-31 17:59 ` [PATCH 4/6] nor m25p80: align start and end to erase blocks Sascha Hauer
2012-07-31 17:59 ` Sascha Hauer [this message]
2012-07-31 17:59 ` [PATCH 6/6] nor m25p80: implement fast read Sascha Hauer
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=1343757556-11897-6-git-send-email-s.hauer@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=barebox@lists.infradead.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox