* [PATCH v1 0/7] mtd: spi-nor: Add the DDR quad read support
[not found] <a>
@ 2014-04-23 10:16 ` Huang Shijie
2014-04-23 10:16 ` [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value Huang Shijie
` (6 subsequent siblings)
7 siblings, 0 replies; 19+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
To: dwmw2
Cc: computersforpeace, marex, linux-mtd, linux-doc, linux-spi,
linux-arm-kernel, devicetree, Huang Shijie
(0) This patch set depends on the patch:
http://lists.infradead.org/pipermail/linux-mtd/2014-April/053308.html
(1) This patch set tries to add the DDR quad read support for the SPI
NOR framework, and it also adds the DDR quad read support for FREESCALE
quadspi controller driver.
(2) Test this patch set with Spansion s25fl128s, the performance with mtd_speedtest.ko:
=================================================
mtd_speedtest: MTD device: 0
mtd_speedtest: not NAND flash, assume page size is 512 bytes.
mtd_speedtest: MTD device size 16777216, eraseblock size 65536, page size 512,
count of eraseblocks 256, pages per eraseblock 128, OOB size 0
mtd_speedtest: testing eraseblock write speed
mtd_speedtest: eraseblock write speed is 665 KiB/s
mtd_speedtest: testing eraseblock read speed
mtd_speedtest: eraseblock read speed is 49799 KiB/s
mtd_speedtest: testing page write speed
mtd_speedtest: page write speed is 662 KiB/s
mtd_speedtest: testing page read speed
mtd_speedtest: page read speed is 24236 KiB/s
mtd_speedtest: testing 2 page write speed
mtd_speedtest: 2 page write speed is 657 KiB/s
mtd_speedtest: testing 2 page read speed
mtd_speedtest: 2 page read speed is 32637 KiB/s
mtd_speedtest: Testing erase speed
mtd_speedtest: erase speed is 518 KiB/s
mtd_speedtest: Testing 2x multi-block erase speed
mtd_speedtest: 2x multi-block erase speed is 506 KiB/s
mtd_speedtest: Testing 4x multi-block erase speed
mtd_speedtest: 4x multi-block erase speed is 503 KiB/s
mtd_speedtest: Testing 8x multi-block erase speed
mtd_speedtest: 8x multi-block erase speed is 501 KiB/s
mtd_speedtest: Testing 16x multi-block erase speed
mtd_speedtest: 16x multi-block erase speed is 498 KiB/s
mtd_speedtest: Testing 32x multi-block erase speed
mtd_speedtest: 32x multi-block erase speed is 496 KiB/s
mtd_speedtest: Testing 64x multi-block erase speed
mtd_speedtest: 64x multi-block erase speed is 495 KiB/s
mtd_speedtest: finished
=================================================
(3) Conclusion:
The DDR quad read could be 49799 KiB/s.
Changlog:
About this patch set:
For patch 1, please see the old discusstion:
http://lists.infradead.org/pipermail/linux-mtd/2014-April/053370.html
For patch 2, please see the old discusstion:
http://lists.infradead.org/pipermail/linux-mtd/2014-April/053374.html
Huang Shijie (7):
mtd: spi-nor: fix the wrong dummy value
mtd: spi-nor: add DDR quad read support
Documentation: mtd: add a new document for SPI NOR flash
Documentation: fsl-quadspi: update the document
mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT
property
mtd: fsl-quadspi: use the information stored in spi-nor{}
mtd: fsl-quadspi: add the DDR quad read support
.../devicetree/bindings/mtd/fsl-quadspi.txt | 16 +++
.../devicetree/bindings/mtd/spi-nor-flash.txt | 7 +
drivers/mtd/devices/m25p80.c | 5 +-
drivers/mtd/spi-nor/fsl-quadspi.c | 121 +++++++++++++-------
drivers/mtd/spi-nor/spi-nor.c | 52 ++++++++-
include/linux/mtd/spi-nor.h | 8 +-
6 files changed, 162 insertions(+), 47 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
--
1.7.2.rc3
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value
[not found] <a>
2014-04-23 10:16 ` [PATCH v1 0/7] mtd: spi-nor: Add the DDR quad read support Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
2014-04-23 19:41 ` Marek Vasut
2014-04-23 10:16 ` [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support Huang Shijie
` (5 subsequent siblings)
7 siblings, 1 reply; 19+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
To: dwmw2-wEGCiKHe2LqWVfeAwA7xHQ
Cc: computersforpeace-Re5JQEeQqe8AvxtiuMwx3w, marex-ynQEQJNshbs,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Huang Shijie
For the DDR Quad read, the dummy cycles maybe 3 or 6 which is less then 8.
The dummy cycles is actually 8 for SPI fast/dual/quad read.
This patch makes preparations for the DDR quad read, it fixes the wrong dummy
value for both the spi-nor.c and m25p80.c.
Signed-off-by: Huang Shijie <b32955-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
---
drivers/mtd/devices/m25p80.c | 5 ++++-
drivers/mtd/spi-nor/spi-nor.c | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 1557d8f..693e25f 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -128,9 +128,12 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
struct spi_device *spi = flash->spi;
struct spi_transfer t[2];
struct spi_message m;
- int dummy = nor->read_dummy;
+ unsigned int dummy = nor->read_dummy;
int ret;
+ /* convert the dummy cycles to the number of byte */
+ dummy /= 8;
+
/* Wait till previous write/erase is done. */
ret = nor->wait_till_ready(nor);
if (ret)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index f76f3fc..1a12f81 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -77,7 +77,7 @@ static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
case SPI_NOR_FAST:
case SPI_NOR_DUAL:
case SPI_NOR_QUAD:
- return 1;
+ return 8;
case SPI_NOR_NORMAL:
return 0;
}
--
1.7.2.rc3
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value
2014-04-23 10:16 ` [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value Huang Shijie
@ 2014-04-23 19:41 ` Marek Vasut
[not found] ` <201404232141.27005.marex-ynQEQJNshbs@public.gmane.org>
0 siblings, 1 reply; 19+ messages in thread
From: Marek Vasut @ 2014-04-23 19:41 UTC (permalink / raw)
To: Huang Shijie
Cc: dwmw2, computersforpeace, linux-mtd, linux-doc, linux-spi,
linux-arm-kernel, devicetree
On Wednesday, April 23, 2014 at 12:16:49 PM, Huang Shijie wrote:
> For the DDR Quad read, the dummy cycles maybe 3 or 6 which is less then 8.
> The dummy cycles is actually 8 for SPI fast/dual/quad read.
>
> This patch makes preparations for the DDR quad read, it fixes the wrong
> dummy value for both the spi-nor.c and m25p80.c.
>
> Signed-off-by: Huang Shijie <b32955@freescale.com>
This patch is actually V2, right ?
> ---
> drivers/mtd/devices/m25p80.c | 5 ++++-
> drivers/mtd/spi-nor/spi-nor.c | 2 +-
> 2 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 1557d8f..693e25f 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -128,9 +128,12 @@ static int m25p80_read(struct spi_nor *nor, loff_t
> from, size_t len, struct spi_device *spi = flash->spi;
> struct spi_transfer t[2];
> struct spi_message m;
> - int dummy = nor->read_dummy;
> + unsigned int dummy = nor->read_dummy;
> int ret;
>
> + /* convert the dummy cycles to the number of byte */
'bytes', plural ...
[...]
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support
[not found] <a>
2014-04-23 10:16 ` [PATCH v1 0/7] mtd: spi-nor: Add the DDR quad read support Huang Shijie
2014-04-23 10:16 ` [PATCH v1 1/7] mtd: spi-nor: fix the wrong dummy value Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
[not found] ` <1398248215-26768-3-git-send-email-b32955-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
2014-04-23 10:16 ` [PATCH v1 3/7] Documentation: mtd: add a new document for SPI NOR flash Huang Shijie
` (4 subsequent siblings)
7 siblings, 1 reply; 19+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
To: dwmw2
Cc: computersforpeace, marex, linux-mtd, linux-doc, linux-spi,
linux-arm-kernel, devicetree, Huang Shijie
This patch adds the DDR quad read support by the following:
[1] add SPI_NOR_DDR_QUAD read mode.
[2] add DDR Quad read opcodes:
SPINOR_OP_READ_1_4_4_D / SPINOR_OP_READ4_1_4_4_D
[3] add set_ddr_quad_mode() to initialize for the DDR quad read.
Currently it only works for Spansion NOR.
[3] set the dummy with 8 for DDR quad read.
The m25p80.c can not support the DDR quad read, the SPI NOR controller
can set the dummy value in its driver, such as fsl-quadspi.c.
Test this patch for Spansion s25fl128s NOR flash.
Signed-off-by: Huang Shijie <b32955@freescale.com>
---
drivers/mtd/spi-nor/spi-nor.c | 50 +++++++++++++++++++++++++++++++++++++++-
include/linux/mtd/spi-nor.h | 8 +++++-
2 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 1a12f81..e2f69db 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -74,6 +74,15 @@ static int read_cr(struct spi_nor *nor)
static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
{
switch (nor->flash_read) {
+ case SPI_NOR_DDR_QUAD:
+ /*
+ * The m25p80.c can not support the DDR quad read.
+ * We set the dummy cycles to 8 by default. If the SPI NOR
+ * controller driver has already set it before call the
+ * spi_nor_scan(), we just keep it as it is.
+ */
+ if (nor->read_dummy)
+ return nor->read_dummy;
case SPI_NOR_FAST:
case SPI_NOR_DUAL:
case SPI_NOR_QUAD:
@@ -402,6 +411,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 SPI_NOR_DDR_QUAD_READ 0x80 /* Flash supports DDR Quad Read */
};
#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
@@ -846,6 +856,24 @@ static int spansion_quad_enable(struct spi_nor *nor)
return 0;
}
+static int set_ddr_quad_mode(struct spi_nor *nor, u32 jedec_id)
+{
+ int status;
+
+ switch (JEDEC_MFR(jedec_id)) {
+ case CFI_MFR_AMD: /* Spansion, actually */
+ status = spansion_quad_enable(nor);
+ if (status) {
+ dev_err(nor->dev,
+ "Spansion DDR quad-read not enabled\n");
+ return -EINVAL;
+ }
+ return status;
+ default:
+ return -EINVAL;
+ }
+}
+
static int set_quad_mode(struct spi_nor *nor, u32 jedec_id)
{
int status;
@@ -1016,8 +1044,15 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
if (info->flags & SPI_NOR_NO_FR)
nor->flash_read = SPI_NOR_NORMAL;
- /* Quad/Dual-read mode takes precedence over fast/normal */
- if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
+ /* DDR Quad/Quad/Dual-read mode takes precedence over fast/normal */
+ if (mode == SPI_NOR_DDR_QUAD && info->flags & SPI_NOR_DDR_QUAD_READ) {
+ ret = set_ddr_quad_mode(nor, info->jedec_id);
+ if (ret) {
+ dev_err(dev, "DDR quad mode not supported\n");
+ return ret;
+ }
+ nor->flash_read = SPI_NOR_DDR_QUAD;
+ } else if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
ret = set_quad_mode(nor, info->jedec_id);
if (ret) {
dev_err(dev, "quad mode not supported\n");
@@ -1030,6 +1065,14 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
/* Default commands */
switch (nor->flash_read) {
+ case SPI_NOR_DDR_QUAD:
+ if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) { /* Spansion */
+ nor->read_opcode = SPINOR_OP_READ_1_4_4_D;
+ } else {
+ dev_err(dev, "DDR Quad Read is not supported.\n");
+ return -EINVAL;
+ }
+ break;
case SPI_NOR_QUAD:
nor->read_opcode = SPINOR_OP_READ_1_1_4;
break;
@@ -1057,6 +1100,9 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
/* Dedicated 4-byte command set */
switch (nor->flash_read) {
+ case SPI_NOR_DDR_QUAD:
+ nor->read_opcode = SPINOR_OP_READ4_1_4_4_D;
+ break;
case SPI_NOR_QUAD:
nor->read_opcode = SPINOR_OP_READ4_1_1_4;
break;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 5324184..fea7769 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -12,10 +12,11 @@
/*
* Note on opcode nomenclature: some opcodes have a format like
- * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
+ * SPINOR_OP_FUNCTION{4,}_x_y_z{_D}. The numbers x, y, and z stand for the number
* of I/O lines used for the opcode, address, and data (respectively). The
* FUNCTION has an optional suffix of '4', to represent an opcode which
- * requires a 4-byte (32-bit) address.
+ * requires a 4-byte (32-bit) address. The suffix of 'D' stands for the
+ * DDR mode.
*/
/* Flash opcodes. */
@@ -26,6 +27,7 @@
#define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */
#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */
#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */
+#define SPINOR_OP_READ_1_4_4_D 0xed /* Read data bytes (DDR Quad SPI) */
#define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */
#define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */
#define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */
@@ -40,6 +42,7 @@
#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */
#define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */
#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */
+#define SPINOR_OP_READ4_1_4_4_D 0xee /* Read data bytes (DDR Quad SPI) */
#define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */
#define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */
@@ -74,6 +77,7 @@ enum read_mode {
SPI_NOR_FAST,
SPI_NOR_DUAL,
SPI_NOR_QUAD,
+ SPI_NOR_DDR_QUAD,
};
/**
--
1.7.2.rc3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 3/7] Documentation: mtd: add a new document for SPI NOR flash
[not found] <a>
` (2 preceding siblings ...)
2014-04-23 10:16 ` [PATCH v1 2/7] mtd: spi-nor: add DDR quad read support Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
2014-04-23 10:16 ` [PATCH v1 4/7] Documentation: fsl-quadspi: update the document Huang Shijie
` (3 subsequent siblings)
7 siblings, 0 replies; 19+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
To: dwmw2
Cc: marex, devicetree, linux-doc, linux-spi, Huang Shijie, linux-mtd,
computersforpeace, linux-arm-kernel
We need a DT property to store the dummy cycles for DDR Quad read.
This is a common feature for the SPI NOR flash, such as Spansion and Micron
chips.
Add this file to describe this specific SPI NOR flash features which will
be referred by the SPI NOR flash drivers.
Signed-off-by: Huang Shijie <b32955@freescale.com>
---
.../devicetree/bindings/mtd/spi-nor-flash.txt | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
diff --git a/Documentation/devicetree/bindings/mtd/spi-nor-flash.txt b/Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
new file mode 100644
index 0000000..aba4d54
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
@@ -0,0 +1,7 @@
+This file defines some DT properties for specific SPI NOR flash features.
+The SPI NOR controller drivers may refer to this file, such as fsl-quadspi.txt
+
+Optional properties:
+ - spi-nor,ddr-quad-read-dummy: The dummy cycles used by the DDR Quad read.
+ Please refer to the chip's datasheet. This
+ property can be 4 or 6 which is less then 8.
--
1.7.2.rc3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 4/7] Documentation: fsl-quadspi: update the document
[not found] <a>
` (3 preceding siblings ...)
2014-04-23 10:16 ` [PATCH v1 3/7] Documentation: mtd: add a new document for SPI NOR flash Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
2014-04-23 10:16 ` [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property Huang Shijie
` (2 subsequent siblings)
7 siblings, 0 replies; 19+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
To: dwmw2-wEGCiKHe2LqWVfeAwA7xHQ
Cc: computersforpeace-Re5JQEeQqe8AvxtiuMwx3w, marex-ynQEQJNshbs,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Huang Shijie
The patch updates the document by adding more information to describe the
DT proporties used by the Freescale Quadspi driver and the childs nodes.
For the child node for SPI NOR flash, we add the required property
("spi-max-frequency"), and refer to spi-nor-flash.txt for the optional
properties.
Signed-off-by: Huang Shijie <b32955-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
---
.../devicetree/bindings/mtd/fsl-quadspi.txt | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 823d134..7e1dbaf 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -1,5 +1,11 @@
* Freescale Quad Serial Peripheral Interface(QuadSPI)
+The QuadSPI controller acts as the SPI master. It is described with a node
+for the controller and a set of child nodes for each SPI NOR flash.
+
+Part I - The DT node for the controller:
+------------------------------
+
Required properties:
- compatible : Should be "fsl,vf610-qspi"
- reg : the first contains the register location and length,
@@ -18,6 +24,16 @@ Optional properties:
bus, you should enable this property.
(Please check the board's schematic.)
+Part II - The DT nodes for each SPI NOR flash
+------------------------------
+Required properties:
+- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at
+
+Optional properties:
+ Please refer to the Documentation/devicetree/bindings/mtd/spi-nor-flash.txt
+ If you set the "spi-nor,ddr-quad-read-dummy", it means you enable the DDR
+ quad read feature for the driver.
+
Example:
qspi0: quadspi@40044000 {
--
1.7.2.rc3
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property
[not found] <a>
` (4 preceding siblings ...)
2014-04-23 10:16 ` [PATCH v1 4/7] Documentation: fsl-quadspi: update the document Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
2014-04-23 19:48 ` Marek Vasut
2014-04-23 10:16 ` [PATCH v1 6/7] mtd: fsl-quadspi: use the information stored in spi-nor{} Huang Shijie
2014-04-23 10:16 ` [PATCH v1 7/7] mtd: fsl-quadspi: add the DDR quad read support Huang Shijie
7 siblings, 1 reply; 19+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
To: dwmw2
Cc: computersforpeace, marex, linux-mtd, linux-doc, linux-spi,
linux-arm-kernel, devicetree, Huang Shijie
Check the "spi-nor,ddr-quad-read-dummy" DT property to get the
dummy cycles for DDR quad read.
Signed-off-by: Huang Shijie <b32955@freescale.com>
---
drivers/mtd/spi-nor/fsl-quadspi.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 8d659a2..15bdeb9 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -883,6 +883,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
for_each_available_child_of_node(dev->of_node, np) {
const struct spi_device_id *id;
char modalias[40];
+ u32 dummy = 0;
/* skip the holes */
if (!has_second_chip)
@@ -918,6 +919,12 @@ static int fsl_qspi_probe(struct platform_device *pdev)
if (ret < 0)
goto map_failed;
+ /* Set the dummy cycles for the DDR Quad Read */
+ ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
+ &dummy);
+ if (!ret && dummy > 0 && dummy < 8)
+ nor->read_dummy = dummy;
+
/* set the chip address for READID */
fsl_qspi_set_base_addr(q, nor);
--
1.7.2.rc3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property
2014-04-23 10:16 ` [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property Huang Shijie
@ 2014-04-23 19:48 ` Marek Vasut
[not found] ` <201404232148.51034.marex-ynQEQJNshbs@public.gmane.org>
0 siblings, 1 reply; 19+ messages in thread
From: Marek Vasut @ 2014-04-23 19:48 UTC (permalink / raw)
To: Huang Shijie
Cc: dwmw2, computersforpeace, linux-mtd, linux-doc, linux-spi,
linux-arm-kernel, devicetree
On Wednesday, April 23, 2014 at 12:16:53 PM, Huang Shijie wrote:
> Check the "spi-nor,ddr-quad-read-dummy" DT property to get the
> dummy cycles for DDR quad read.
>
> Signed-off-by: Huang Shijie <b32955@freescale.com>
> ---
> drivers/mtd/spi-nor/fsl-quadspi.c | 7 +++++++
> 1 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c
> b/drivers/mtd/spi-nor/fsl-quadspi.c index 8d659a2..15bdeb9 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -883,6 +883,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
> for_each_available_child_of_node(dev->of_node, np) {
> const struct spi_device_id *id;
> char modalias[40];
> + u32 dummy = 0;
>
> /* skip the holes */
> if (!has_second_chip)
> @@ -918,6 +919,12 @@ static int fsl_qspi_probe(struct platform_device
> *pdev) if (ret < 0)
> goto map_failed;
>
> + /* Set the dummy cycles for the DDR Quad Read */
> + ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
> + &dummy);
> + if (!ret && dummy > 0 && dummy < 8)
> + nor->read_dummy = dummy;
Is there any reason for the upper limit on number of dummy cycles ?
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v1 6/7] mtd: fsl-quadspi: use the information stored in spi-nor{}
[not found] <a>
` (5 preceding siblings ...)
2014-04-23 10:16 ` [PATCH v1 5/7] mtd: fsl-quadspi: get the dummy cycles for DDR Quad read from the DT property Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
2014-04-23 10:16 ` [PATCH v1 7/7] mtd: fsl-quadspi: add the DDR quad read support Huang Shijie
7 siblings, 0 replies; 19+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
To: dwmw2-wEGCiKHe2LqWVfeAwA7xHQ
Cc: computersforpeace-Re5JQEeQqe8AvxtiuMwx3w, marex-ynQEQJNshbs,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Huang Shijie
We can get the read/write/erase opcode from the spi nor framework now.
What's more is that we can get the correct dummy cycles.
This patch uses the information stored in the spi_nor{} to remove the
hardcode in the fsl_qspi_init_lut().
Signed-off-by: Huang Shijie <b32955-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
---
drivers/mtd/spi-nor/fsl-quadspi.c | 57 ++++++++++++------------------------
1 files changed, 19 insertions(+), 38 deletions(-)
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 15bdeb9..0a2901e 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -280,8 +280,10 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
{
void __iomem *base = q->iobase;
int rxfifo = q->devtype_data->rxfifo;
+ struct spi_nor *nor = &q->nor[0];
+ u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
u32 lut_base;
- u8 cmd, addrlen, dummy;
+ u8 op, dm;
int i;
fsl_qspi_unlock_lut(q);
@@ -292,40 +294,29 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
/* Quad Read */
lut_base = SEQID_QUAD_READ * 4;
-
- if (q->nor_size <= SZ_16M) {
- cmd = SPINOR_OP_READ_1_1_4;
- addrlen = ADDR24BIT;
- dummy = 8;
- } else {
- /* use the 4-byte address */
- cmd = SPINOR_OP_READ_1_1_4;
- addrlen = ADDR32BIT;
- dummy = 8;
+ op = nor->read_opcode;
+ dm = nor->read_dummy;
+ if (nor->flash_read == SPI_NOR_QUAD) {
+ if (op == SPINOR_OP_READ_1_1_4 || op == SPINOR_OP_READ4_1_1_4) {
+ /* read mode : 1-1-4 */
+ writel(LUT0(CMD, PAD1, op) | LUT1(ADDR, PAD1, addrlen),
+ base + QUADSPI_LUT(lut_base));
+
+ writel(LUT0(DUMMY, PAD1, dm) | LUT1(READ, PAD4, rxfifo),
+ base + QUADSPI_LUT(lut_base + 1));
+ } else {
+ dev_err(nor->dev,
+ "Unsupported cmd:%.2x\n", nor->read_opcode);
+ }
}
- writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
- base + QUADSPI_LUT(lut_base));
- writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
- base + QUADSPI_LUT(lut_base + 1));
-
/* Write enable */
lut_base = SEQID_WREN * 4;
writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base));
/* Page Program */
lut_base = SEQID_PP * 4;
-
- if (q->nor_size <= SZ_16M) {
- cmd = SPINOR_OP_PP;
- addrlen = ADDR24BIT;
- } else {
- /* use the 4-byte address */
- cmd = SPINOR_OP_PP;
- addrlen = ADDR32BIT;
- }
-
- writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+ writel(LUT0(CMD, PAD1, nor->program_opcode) | LUT1(ADDR, PAD1, addrlen),
base + QUADSPI_LUT(lut_base));
writel(LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
@@ -336,17 +327,7 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
/* Erase a sector */
lut_base = SEQID_SE * 4;
-
- if (q->nor_size <= SZ_16M) {
- cmd = SPINOR_OP_SE;
- addrlen = ADDR24BIT;
- } else {
- /* use the 4-byte address */
- cmd = SPINOR_OP_SE;
- addrlen = ADDR32BIT;
- }
-
- writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+ writel(LUT0(CMD, PAD1, nor->erase_opcode) | LUT1(ADDR, PAD1, addrlen),
base + QUADSPI_LUT(lut_base));
/* Erase the whole chip */
--
1.7.2.rc3
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v1 7/7] mtd: fsl-quadspi: add the DDR quad read support
[not found] <a>
` (6 preceding siblings ...)
2014-04-23 10:16 ` [PATCH v1 6/7] mtd: fsl-quadspi: use the information stored in spi-nor{} Huang Shijie
@ 2014-04-23 10:16 ` Huang Shijie
7 siblings, 0 replies; 19+ messages in thread
From: Huang Shijie @ 2014-04-23 10:16 UTC (permalink / raw)
To: dwmw2-wEGCiKHe2LqWVfeAwA7xHQ
Cc: computersforpeace-Re5JQEeQqe8AvxtiuMwx3w, marex-ynQEQJNshbs,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Huang Shijie
Add the DDR quad read support for the fsl-quadspi driver.
(1) Test this patch with imx6sx-sdb board (Spansion s25fl128s)
The clock rate is 66MHz.
(2) The information of NOR flash:
-----------------------------------------------
root@imx6qdlsolo:~# mtdinfo /dev/mtd0
mtd0
Name: 21e4000.qspi
Type: nor
Eraseblock size: 65536 bytes, 64.0 KiB
Amount of eraseblocks: 256 (16777216 bytes, 16.0 MiB)
Minimum input/output unit size: 1 byte
Sub-page size: 1 byte
Character device major/minor: 90:0
Bad blocks are allowed: false
Device is writable: true
-----------------------------------------------
(3) Test this patch set with UBIFS & bonnie++:
-----------------------------------------------
ubiattach /dev/ubi_ctrl -m 0
ubimkvol /dev/ubi0 -N test -m
mount -t ubifs ubi0:test tmp
bonnie++ -d tmp -u 0 -s 10 -r 5
-----------------------------------------------
(4) Test this patch with mtd_speedtest.ko
root@imx6qdlsolo:~# insmod mtd_speedtest.ko dev=0
=================================================
mtd_speedtest: MTD device: 0
mtd_speedtest: not NAND flash, assume page size is 512 bytes.
mtd_speedtest: MTD device size 16777216, eraseblock size 65536, page size 512,
count of eraseblocks 256, pages per eraseblock 128, OOB size 0
mtd_speedtest: testing eraseblock write speed
mtd_speedtest: eraseblock write speed is 665 KiB/s
mtd_speedtest: testing eraseblock read speed
mtd_speedtest: eraseblock read speed is 49799 KiB/s
mtd_speedtest: testing page write speed
mtd_speedtest: page write speed is 662 KiB/s
mtd_speedtest: testing page read speed
mtd_speedtest: page read speed is 24236 KiB/s
mtd_speedtest: testing 2 page write speed
mtd_speedtest: 2 page write speed is 657 KiB/s
mtd_speedtest: testing 2 page read speed
mtd_speedtest: 2 page read speed is 32637 KiB/s
mtd_speedtest: Testing erase speed
mtd_speedtest: erase speed is 518 KiB/s
mtd_speedtest: Testing 2x multi-block erase speed
mtd_speedtest: 2x multi-block erase speed is 506 KiB/s
mtd_speedtest: Testing 4x multi-block erase speed
mtd_speedtest: 4x multi-block erase speed is 503 KiB/s
mtd_speedtest: Testing 8x multi-block erase speed
mtd_speedtest: 8x multi-block erase speed is 501 KiB/s
mtd_speedtest: Testing 16x multi-block erase speed
mtd_speedtest: 16x multi-block erase speed is 498 KiB/s
mtd_speedtest: Testing 32x multi-block erase speed
mtd_speedtest: 32x multi-block erase speed is 496 KiB/s
mtd_speedtest: Testing 64x multi-block erase speed
mtd_speedtest: 64x multi-block erase speed is 495 KiB/s
mtd_speedtest: finished
=================================================
(5) Conclusion:
The DDR quad read could be 49799 KiB/s.
Signed-off-by: Huang Shijie <b32955-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
---
drivers/mtd/spi-nor/fsl-quadspi.c | 59 ++++++++++++++++++++++++++++++++++--
1 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 0a2901e..fcb963f 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -29,6 +29,9 @@
/* The registers */
#define QUADSPI_MCR 0x00
+#define MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_SHIFT 29
+#define MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_MASK \
+ (1 << MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_SHIFT)
#define QUADSPI_MCR_RESERVED_SHIFT 16
#define QUADSPI_MCR_RESERVED_MASK (0xF << QUADSPI_MCR_RESERVED_SHIFT)
#define QUADSPI_MCR_MDIS_SHIFT 14
@@ -292,7 +295,7 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
for (i = 0; i < QUADSPI_LUT_NUM; i++)
writel(0, base + QUADSPI_LUT_BASE + i * 4);
- /* Quad Read */
+ /* Quad Read and DDR Quad Read*/
lut_base = SEQID_QUAD_READ * 4;
op = nor->read_opcode;
dm = nor->read_dummy;
@@ -308,6 +311,24 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
dev_err(nor->dev,
"Unsupported cmd:%.2x\n", nor->read_opcode);
}
+ } else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
+ if (op == SPINOR_OP_READ_1_4_4_D ||
+ op == SPINOR_OP_READ4_1_4_4_D) {
+ /* read mode : 1-4-4, such as Spansion s25fl128s. */
+ writel(LUT0(CMD, PAD1, op)
+ | LUT1(ADDR_DDR, PAD4, addrlen),
+ base + QUADSPI_LUT(lut_base));
+
+ writel(LUT0(MODE_DDR, PAD1, 4) | LUT1(DUMMY, PAD1, dm),
+ base + QUADSPI_LUT(lut_base + 1));
+
+ writel(LUT0(READ_DDR, PAD4, rxfifo)
+ | LUT1(JMP_ON_CS, PAD1, 0),
+ base + QUADSPI_LUT(lut_base + 2));
+ } else {
+ dev_err(nor->dev,
+ "Unsupported cmd:%.2x\n", nor->read_opcode);
+ }
}
/* Write enable */
@@ -369,6 +390,9 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
{
switch (cmd) {
+ case SPINOR_OP_READ_1_4_4_D:
+ case SPINOR_OP_READ4_1_4_4_D:
+ case SPINOR_OP_READ4_1_1_4:
case SPINOR_OP_READ_1_1_4:
return SEQID_QUAD_READ;
case SPINOR_OP_WREN:
@@ -558,6 +582,8 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
{
void __iomem *base = q->iobase;
+ struct spi_nor *nor = &q->nor[0];
+ u32 reg, reg2;
int seqid;
/* AHB configuration for access buffer 0/1/2 .*/
@@ -572,9 +598,30 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
writel(0, base + QUADSPI_BUF2IND);
/* Set the default lut sequence for AHB Read. */
- seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
+ seqid = fsl_qspi_get_seqid(q, nor->read_opcode);
writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
q->iobase + QUADSPI_BFGENCR);
+
+ /* enable the DDR quad read */
+ if (nor->flash_read == SPI_NOR_DDR_QUAD) {
+ reg = readl(q->iobase + QUADSPI_MCR);
+
+ /* Firstly, disable the module */
+ writel(reg | QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
+
+ /* Set the Sampling Register for DDR */
+ reg2 = readl(q->iobase + QUADSPI_SMPR);
+ reg2 &= ~QUADSPI_SMPR_DDRSMP_MASK;
+ reg2 |= (2 << QUADSPI_SMPR_DDRSMP_SHIFT);
+ writel(reg2, q->iobase + QUADSPI_SMPR);
+
+ /* Enable the module again (enable the DDR too) */
+ reg |= QUADSPI_MCR_DDR_EN_MASK;
+ if (is_imx6sx_qspi(q))
+ reg |= MX6SX_QUADSPI_MCR_TX_DDR_DELAY_EN_MASK;
+
+ writel(reg, q->iobase + QUADSPI_MCR);
+ }
}
/* We use this function to do some basic init for spi_nor_scan(). */
@@ -863,6 +910,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
/* iterate the subnodes. */
for_each_available_child_of_node(dev->of_node, np) {
const struct spi_device_id *id;
+ enum read_mode mode = SPI_NOR_QUAD;
char modalias[40];
u32 dummy = 0;
@@ -903,13 +951,16 @@ static int fsl_qspi_probe(struct platform_device *pdev)
/* Set the dummy cycles for the DDR Quad Read */
ret = of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy",
&dummy);
- if (!ret && dummy > 0 && dummy < 8)
+ if (!ret && dummy > 0 && dummy < 8) {
nor->read_dummy = dummy;
+ mode = SPI_NOR_DDR_QUAD;
+ dev_dbg(dev, "The DDR quad read dummy is %d.\n", dummy);
+ }
/* set the chip address for READID */
fsl_qspi_set_base_addr(q, nor);
- ret = spi_nor_scan(nor, id, SPI_NOR_QUAD);
+ ret = spi_nor_scan(nor, id, mode);
if (ret)
goto map_failed;
--
1.7.2.rc3
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 19+ messages in thread