mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [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