public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Graham Moore <grmoore@altera.com>
To: <ggrahammoore@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>,
	Brian Norris <computersforpeace@gmail.com>,
	ZY - marex <marex@denx.de>,
	Artem Bityutskiy <artem.bityutskiy@linux.intel.com>,
	Sourav Poddar <sourav.poddar@ti.com>,
	Sascha Hauer <s.hauer@pengutronix.de>,
	Geert Uytterhoeven <geert+renesas@linux-m68k.org>,
	Jingoo Han <jg1.han@samsung.com>,
	Insop Song <insop.song@gainspeed.com>,
	Graham Moore <grmoore@altera.com>,
	<linux-mtd@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
	Alan Tull <atull@altera.com>, Dinh Nguyen <dinguyen@altera.com>,
	Yves Vandervennet <rocket.yvanderv@gmail.com>
Subject: [PATCH V3] Add support for flag status register on Micron chips.
Date: Tue, 22 Apr 2014 09:03:16 -0500	[thread overview]
Message-ID: <1398175396-7560-2-git-send-email-grmoore@altera.com> (raw)
In-Reply-To: <1398175396-7560-1-git-send-email-grmoore@altera.com>

Some new Micron flash chips require reading the flag
status register to determine when operations have completed.

Furthermore, chips with multi-die stacks of the 65nm 256Mb QSPI also
require reading the status register before reading the flag status register.

This patch adds support for the flag status register in the n25q512ax3 and n25q00
Micron QSPI flash chips.

Signed-off-by: Graham Moore <grmoore@altera.com>
---
V3:
Rebase to l2-mtd spinor branch.
V2:
Remove leading underscore in function names.
Remove type cast in dev_err call and use the proper format
specifier instead.
---
 drivers/mtd/spi-nor/spi-nor.c |   51 +++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/spi-nor.h   |    4 ++++
 2 files changed, 55 insertions(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index d6f44d5..24b84d8 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -48,6 +48,25 @@ static int read_sr(struct spi_nor *nor)
 }
 
 /*
+ * Read the flag status register, returning its value in the location
+ * Return the status register value.
+ * Returns negative if error occurred.
+ */
+static int read_fsr(struct spi_nor *nor)
+{
+	int ret;
+	u8 val;
+
+	ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1);
+	if (ret < 0) {
+		pr_err("error %d reading FSR\n", ret);
+		return ret;
+	}
+
+	return val;
+}
+
+/*
  * Read configuration register, returning its value in the
  * location. Return the configuration register value.
  * Returns negative if error occured.
@@ -165,6 +184,32 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
 	return -ETIMEDOUT;
 }
 
+static int spi_nor_wait_till_fsr_ready(struct spi_nor *nor)
+{
+	unsigned long deadline;
+	int sr;
+	int fsr;
+
+	deadline = jiffies + MAX_READY_WAIT_JIFFIES;
+
+	do {
+		cond_resched();
+
+		sr = read_sr(nor);
+		if (sr < 0)
+			break;
+		else if (!(sr & SR_WIP)) {
+			fsr = read_fsr(nor);
+			if (fsr < 0)
+				break;
+			if (fsr & FSR_READY)
+				return 0;			
+		}
+	} while (!time_after_eq(jiffies, deadline));
+
+	return -ETIMEDOUT;
+}
+
 /*
  * Service routine to read status register until ready, or timeout occurs.
  * Returns non-zero if error.
@@ -402,6 +447,7 @@ struct flash_info {
 #define	SECT_4K_PMC		0x10	/* SPINOR_OP_BE_4K_PMC works uniformly */
 #define	SPI_NOR_DUAL_READ	0x20    /* Flash supports Dual Read */
 #define	SPI_NOR_QUAD_READ	0x40    /* Flash supports Quad Read */
+#define	USE_FSR			0x80	/* use flag status register */
 };
 
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
@@ -488,6 +534,8 @@ const struct spi_device_id spi_nor_ids[] = {
 	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, 0) },
 	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K) },
 	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
+	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, USE_FSR) },
+	{ "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, USE_FSR) },
 
 	/* PMC */
 	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
@@ -965,6 +1013,9 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
 	else
 		mtd->_write = spi_nor_write;
 
+	if (info->flags & USE_FSR)
+		nor->wait_till_ready = spi_nor_wait_till_fsr_ready;
+
 	/* prefer "small sector" erase if possible */
 	if (info->flags & SECT_4K) {
 		nor->erase_opcode = SPINOR_OP_BE_4K;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 5324184..9e6294f 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -34,6 +34,7 @@
 #define SPINOR_OP_SE		0xd8	/* Sector erase (usually 64KiB) */
 #define SPINOR_OP_RDID		0x9f	/* Read JEDEC ID */
 #define SPINOR_OP_RDCR		0x35	/* Read configuration register */
+#define SPINOR_OP_RDFSR		0x70	/* Read flag status register */
 
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define SPINOR_OP_READ4		0x13	/* Read data bytes (low frequency) */
@@ -66,6 +67,9 @@
 
 #define SR_QUAD_EN_MX		0x40	/* Macronix Quad I/O */
 
+/* Flag Status Register bits */
+#define FSR_READY		0x80
+
 /* Configuration Register bits. */
 #define CR_QUAD_EN_SPAN		0x2	/* Spansion Quad I/O */
 
-- 
1.7.9.5


  reply	other threads:[~2014-04-22 14:04 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-22 14:03 [PATCH V3] Add support for flag status register on Micron chips Graham Moore
2014-04-22 14:03 ` Graham Moore [this message]
2014-04-22 16:55   ` Marek Vasut
2014-04-22 18:48     ` Graham Moore
2014-04-22 18:58       ` Marek Vasut
2014-04-25  4:47       ` Huang Shijie
2014-04-25 15:50         ` Marek Vasut
2014-04-22 18:45   ` Gerhard Sittig
2014-04-22 19:17     ` Graham Moore
2014-04-25  1:34   ` Huang Shijie
2014-04-25  2:42     ` Marek Vasut
2014-04-25  1:52       ` Huang Shijie
2014-04-25 22:12         ` Marek Vasut
2014-04-26  3:10           ` Huang Shijie
2014-04-28  5:06             ` Marek Vasut
2014-04-28  7:06               ` Huang Shijie
2014-04-28 14:22                 ` Graham Moore
2014-04-28 15:37                   ` Huang Shijie
2014-07-12  2:07               ` Brian Norris
2014-04-25  1:54       ` Huang Shijie

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=1398175396-7560-2-git-send-email-grmoore@altera.com \
    --to=grmoore@altera.com \
    --cc=artem.bityutskiy@linux.intel.com \
    --cc=atull@altera.com \
    --cc=computersforpeace@gmail.com \
    --cc=dinguyen@altera.com \
    --cc=dwmw2@infradead.org \
    --cc=geert+renesas@linux-m68k.org \
    --cc=ggrahammoore@gmail.com \
    --cc=insop.song@gainspeed.com \
    --cc=jg1.han@samsung.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=marex@denx.de \
    --cc=rocket.yvanderv@gmail.com \
    --cc=s.hauer@pengutronix.de \
    --cc=sourav.poddar@ti.com \
    /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