* [PATCH] m25p80 spi flash updates
@ 2012-07-31 17:59 Sascha Hauer
2012-07-31 17:59 ` [PATCH 1/6] nor m25p80: remove progression bar Sascha Hauer
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Sascha Hauer @ 2012-07-31 17:59 UTC (permalink / raw)
To: barebox
Mostly speed updates for the m25p80 SPI nor flash driver.
Sascha
----------------------------------------------------------------
Sascha Hauer (6):
nor m25p80: remove progression bar
nor m25p80: remove unused variables
nor m25p80: refactor chip erase
nor m25p80: align start and end to erase blocks
nor m25p80: optimize erase
nor m25p80: implement fast read
drivers/nor/m25p80.c | 75 ++++++++++++++++++++++++++++++--------------------
drivers/nor/m25p80.h | 12 ++------
2 files changed, 48 insertions(+), 39 deletions(-)
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/6] nor m25p80: remove progression bar
2012-07-31 17:59 [PATCH] m25p80 spi flash updates Sascha Hauer
@ 2012-07-31 17:59 ` Sascha Hauer
2012-07-31 17:59 ` [PATCH 2/6] nor m25p80: remove unused variables Sascha Hauer
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2012-07-31 17:59 UTC (permalink / raw)
To: barebox
Drivers should not print a progression bar.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/nor/m25p80.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/drivers/nor/m25p80.c b/drivers/nor/m25p80.c
index 1440227..594e9d2 100644
--- a/drivers/nor/m25p80.c
+++ b/drivers/nor/m25p80.c
@@ -28,7 +28,6 @@
#include <linux/err.h>
#include <clock.h>
#include <linux/mtd/mtd.h>
-#include <progress.h>
#include "m25p80.h"
/****************************************************************************/
@@ -200,7 +199,6 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
u32 addr, len;
u32 start_sector;
u32 end_sector;
- u32 progress = 0;
int eraseshift = ffs(flash->erasesize) - 1;
dev_dbg(&flash->spi->dev, "%s %s 0x%llx, len %lld\n",
@@ -215,15 +213,12 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
start_sector = offset >> eraseshift;
end_sector = (offset + count - 1) >> eraseshift;
- init_progression_bar(end_sector - start_sector + 1);
/* whole-chip erase? */
if (len == flash->size) {
- show_progress(start_sector);
if (erase_chip(flash))
return -EIO;
- show_progress(end_sector);
/* 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
@@ -238,7 +233,6 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
if (erase_sector(flash, addr))
return -EIO;
- show_progress(++progress);
if (len <= flash->erasesize)
break;
addr += flash->erasesize;
@@ -246,8 +240,6 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
}
}
- printf("\n");
-
return 0;
}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/6] nor m25p80: remove unused variables
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 ` Sascha Hauer
2012-07-31 17:59 ` [PATCH 3/6] nor m25p80: refactor chip erase Sascha Hauer
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2012-07-31 17:59 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/nor/m25p80.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/nor/m25p80.c b/drivers/nor/m25p80.c
index 594e9d2..13ce130 100644
--- a/drivers/nor/m25p80.c
+++ b/drivers/nor/m25p80.c
@@ -197,9 +197,6 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
{
struct m25p *flash = cdev->priv;
u32 addr, len;
- u32 start_sector;
- u32 end_sector;
- int eraseshift = ffs(flash->erasesize) - 1;
dev_dbg(&flash->spi->dev, "%s %s 0x%llx, len %lld\n",
__func__, "at", (long long)offset, (long long)count);
@@ -211,9 +208,6 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
addr = offset;
len = count;
- start_sector = offset >> eraseshift;
- end_sector = (offset + count - 1) >> eraseshift;
-
/* whole-chip erase? */
if (len == flash->size) {
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/6] nor m25p80: refactor chip erase
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 ` Sascha Hauer
2012-07-31 17:59 ` [PATCH 4/6] nor m25p80: align start and end to erase blocks Sascha Hauer
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2012-07-31 17:59 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/nor/m25p80.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/nor/m25p80.c b/drivers/nor/m25p80.c
index 13ce130..0f3bcd1 100644
--- a/drivers/nor/m25p80.c
+++ b/drivers/nor/m25p80.c
@@ -210,9 +210,10 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
/* whole-chip erase? */
if (len == flash->size) {
-
if (erase_chip(flash))
return -EIO;
+ 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
@@ -220,18 +221,16 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
*/
/* "sector"-at-a-time erase */
- } else {
- while (len) {
- if (ctrlc())
- return -EINTR;
- if (erase_sector(flash, addr))
- return -EIO;
-
- if (len <= flash->erasesize)
- break;
- addr += flash->erasesize;
- len -= flash->erasesize;
- }
+ while (len) {
+ if (ctrlc())
+ return -EINTR;
+ if (erase_sector(flash, addr))
+ return -EIO;
+
+ if (len <= flash->erasesize)
+ break;
+ addr += flash->erasesize;
+ len -= flash->erasesize;
}
return 0;
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 4/6] nor m25p80: align start and end to erase blocks
2012-07-31 17:59 [PATCH] m25p80 spi flash updates Sascha Hauer
` (2 preceding siblings ...)
2012-07-31 17:59 ` [PATCH 3/6] nor m25p80: refactor chip erase Sascha Hauer
@ 2012-07-31 17:59 ` Sascha Hauer
2012-07-31 17:59 ` [PATCH 5/6] nor m25p80: optimize erase Sascha Hauer
2012-07-31 17:59 ` [PATCH 6/6] nor m25p80: implement fast read Sascha Hauer
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2012-07-31 17:59 UTC (permalink / raw)
To: barebox
The erase command normally makes sure that the selected area is erased,
therefore align the parameters to eraseblock boundaries.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/nor/m25p80.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/nor/m25p80.c b/drivers/nor/m25p80.c
index 0f3bcd1..7ff4546 100644
--- a/drivers/nor/m25p80.c
+++ b/drivers/nor/m25p80.c
@@ -205,8 +205,9 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
if (offset + count > flash->size)
return -EINVAL;
- addr = offset;
- len = count;
+ /* Align start and len to erase blocks */
+ addr = offset & ~(flash->erasesize - 1);
+ len = ALIGN(offset + count, flash->erasesize) - addr;
/* whole-chip erase? */
if (len == flash->size) {
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 5/6] nor m25p80: optimize erase
2012-07-31 17:59 [PATCH] m25p80 spi flash updates Sascha Hauer
` (3 preceding siblings ...)
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
2012-07-31 17:59 ` [PATCH 6/6] nor m25p80: implement fast read Sascha Hauer
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2012-07-31 17:59 UTC (permalink / raw)
To: barebox
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 6/6] nor m25p80: implement fast read
2012-07-31 17:59 [PATCH] m25p80 spi flash updates Sascha Hauer
` (4 preceding siblings ...)
2012-07-31 17:59 ` [PATCH 5/6] nor m25p80: optimize erase Sascha Hauer
@ 2012-07-31 17:59 ` Sascha Hauer
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2012-07-31 17:59 UTC (permalink / raw)
To: barebox
The fast read command is needed for spi speeds > 25MHz, so use it for
higher speeds.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/nor/m25p80.c | 12 ++++++++----
drivers/nor/m25p80.h | 10 +---------
2 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/drivers/nor/m25p80.c b/drivers/nor/m25p80.c
index 4b62e93..daaf60c 100644
--- a/drivers/nor/m25p80.c
+++ b/drivers/nor/m25p80.c
@@ -267,6 +267,7 @@ ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, loff_t offset,
struct spi_transfer t[2];
struct spi_message m;
ssize_t retlen;
+ int fast_read = 0;
/* sanity checks */
if (!count)
@@ -275,6 +276,9 @@ ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, loff_t offset,
if (offset + count > flash->size)
return -EINVAL;
+ if (flash->spi->max_speed_hz >= 25000000)
+ fast_read = 1;
+
spi_message_init(&m);
memset(t, 0, (sizeof t));
@@ -283,7 +287,7 @@ ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, loff_t offset,
* Should add 1 byte DUMMY_BYTE.
*/
t[0].tx_buf = flash->command;
- t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE;
+ t[0].len = m25p_cmdsz(flash) + fast_read;
spi_message_add_tail(&t[0], &m);
t[1].rx_buf = buf;
@@ -303,12 +307,12 @@ ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, loff_t offset,
*/
/* Set up the write data buffer. */
- flash->command[0] = OPCODE_READ;
+ flash->command[0] = fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ;
m25p_addr2cmd(flash, offset, flash->command);
spi_sync(flash->spi, &m);
- retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE;
+ retlen = m.actual_length - m25p_cmdsz(flash) - fast_read;
return retlen;
}
@@ -756,7 +760,7 @@ static int m25p_probe(struct device_d *dev)
}
flash = xzalloc(sizeof *flash);
- flash->command = xmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE);
+ flash->command = xmalloc(MAX_CMD_SIZE);
flash->spi = spi;
dev->priv = (void *)flash;
diff --git a/drivers/nor/m25p80.h b/drivers/nor/m25p80.h
index ce48ba7..34bf2e2 100644
--- a/drivers/nor/m25p80.h
+++ b/drivers/nor/m25p80.h
@@ -34,15 +34,7 @@
/* Define max times to check status register before we give up. */
#define MAX_READY_WAIT 40 /* M25P16 specs 40s max chip erase */
-#define MAX_CMD_SIZE 5
-
-#ifdef CONFIG_M25PXX_USE_FAST_READ
-#define OPCODE_READ OPCODE_FAST_READ
-#define FAST_READ_DUMMY_BYTE 1
-#else
-#define OPCODE_READ OPCODE_NORM_READ
-#define FAST_READ_DUMMY_BYTE 0
-#endif
+#define MAX_CMD_SIZE 6
#define SPI_NAME_SIZE 32
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-07-31 17:59 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 5/6] nor m25p80: optimize erase Sascha Hauer
2012-07-31 17:59 ` [PATCH 6/6] nor m25p80: implement fast read Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox