All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] mtd: spinand: Add continuous read mode support
@ 2022-02-09  9:10 Zhengxun
  2022-02-09  9:10 ` [PATCH v2 1/4] mtd: spinand: Add support continuous read mode Zhengxun
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Zhengxun @ 2022-02-09  9:10 UTC (permalink / raw)
  To: miquel.raynal, linux-mtd; +Cc: zhengxunli, Zhengxun

This series add support continuous read mode for SPI NAND.

Changes in v2:
- Modify the naming and add some descriptions
- Create a new function for continuous read
- Check data length to determine whether to enter the mode
- Remove the continuous read exit command and replace to reset command
- Add the performances of continuous read mode

Zhengxun (4):
  mtd: spinand: Add support continuous read mode
  mtd: spinand: Add continuous read state
  mtd: spinand: Add support continuous read operation
  mtd: spinand: macronix: Add continuous read support for MX35LF2GE4AD

 drivers/mtd/nand/spi/core.c     | 116 +++++++++++++++++++++++++++++++-
 drivers/mtd/nand/spi/macronix.c |   2 +-
 include/linux/mtd/spinand.h     |   4 ++
 3 files changed, 120 insertions(+), 2 deletions(-)

-- 
2.17.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/4] mtd: spinand: Add support continuous read mode
  2022-02-09  9:10 [PATCH v2 0/4] mtd: spinand: Add continuous read mode support Zhengxun
@ 2022-02-09  9:10 ` Zhengxun
  2022-05-19 16:08   ` Miquel Raynal
  2022-02-09  9:10 ` [PATCH v2 2/4] mtd: spinand: Add continuous read state Zhengxun
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Zhengxun @ 2022-02-09  9:10 UTC (permalink / raw)
  To: miquel.raynal, linux-mtd; +Cc: zhengxunli, Zhengxun

The patch supports setting the "CONT" bit of the configuration
register and adding a continuous read mode flag for identification.

Signed-off-by: Zhengxun <zhengxunli.mxic@gmail.com>
---
 drivers/mtd/nand/spi/core.c | 11 +++++++++++
 include/linux/mtd/spinand.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 2c8685f1f2fa..dc2e1dc1dbee 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -193,6 +193,17 @@ static int spinand_init_quad_enable(struct spinand_device *spinand)
 			       enable ? CFG_QUAD_ENABLE : 0);
 }
 
+static int spinand_continuous_read_enable(struct spinand_device *spinand)
+{
+	return spinand_upd_cfg(spinand, CFG_CONT_READ_ENABLE,
+			       CFG_CONT_READ_ENABLE);
+}
+
+static int spinand_continuous_read_disable(struct spinand_device *spinand)
+{
+	return spinand_upd_cfg(spinand, CFG_CONT_READ_ENABLE, 0);
+}
+
 static int spinand_ecc_enable(struct spinand_device *spinand,
 			      bool enable)
 {
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6988956b8492..04be10ec8fb0 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -154,6 +154,7 @@
 #define REG_CFG			0xb0
 #define CFG_OTP_ENABLE		BIT(6)
 #define CFG_ECC_ENABLE		BIT(4)
+#define CFG_CONT_READ_ENABLE	BIT(2)
 #define CFG_QUAD_ENABLE		BIT(0)
 
 /* status register */
@@ -307,6 +308,7 @@ struct spinand_ecc_info {
 
 #define SPINAND_HAS_QE_BIT		BIT(0)
 #define SPINAND_HAS_CR_FEAT_BIT		BIT(1)
+#define SPINAND_HAS_CONT_READ_BIT	BIT(2)
 
 /**
  * struct spinand_ondie_ecc_conf - private SPI-NAND on-die ECC engine structure
-- 
2.17.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/4] mtd: spinand: Add continuous read state
  2022-02-09  9:10 [PATCH v2 0/4] mtd: spinand: Add continuous read mode support Zhengxun
  2022-02-09  9:10 ` [PATCH v2 1/4] mtd: spinand: Add support continuous read mode Zhengxun
@ 2022-02-09  9:10 ` Zhengxun
  2022-02-09  9:10 ` [PATCH v2 3/4] mtd: spinand: Add support continuous read operation Zhengxun
  2022-02-09  9:10 ` [PATCH v2 4/4] mtd: spinand: macronix: Add continuous read support for MX35LF2GE4AD Zhengxun
  3 siblings, 0 replies; 9+ messages in thread
From: Zhengxun @ 2022-02-09  9:10 UTC (permalink / raw)
  To: miquel.raynal, linux-mtd; +Cc: zhengxunli, Zhengxun

Add continuous read state and initialize state to
default false.

Signed-off-by: Zhengxun <zhengxunli.mxic@gmail.com>
---
 drivers/mtd/nand/spi/core.c | 8 ++++++++
 include/linux/mtd/spinand.h | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index dc2e1dc1dbee..380411feab6c 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -193,6 +193,11 @@ static int spinand_init_quad_enable(struct spinand_device *spinand)
 			       enable ? CFG_QUAD_ENABLE : 0);
 }
 
+static void spinand_init_continuous_read(struct spinand_device *spinand)
+{
+	spinand->use_continuous_read = false;
+}
+
 static int spinand_continuous_read_enable(struct spinand_device *spinand)
 {
 	return spinand_upd_cfg(spinand, CFG_CONT_READ_ENABLE,
@@ -1261,6 +1266,9 @@ static int spinand_init(struct spinand_device *spinand)
 	mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength;
 	mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size;
 
+	/* Init continuous read */
+	spinand_init_continuous_read(spinand);
+
 	return 0;
 
 err_cleanup_ecc_engine:
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 04be10ec8fb0..c296d4d0dda5 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -416,6 +416,7 @@ struct spinand_dirmap {
  *		because the spi-mem interface explicitly requests that buffers
  *		passed in spi_mem_op be DMA-able, so we can't based the bufs on
  *		the stack
+ * @use_continuous_read: record the continuous read status
  * @manufacturer: SPI NAND manufacturer information
  * @priv: manufacturer private data
  */
@@ -444,6 +445,7 @@ struct spinand_device {
 	u8 *databuf;
 	u8 *oobbuf;
 	u8 *scratchbuf;
+	bool use_continuous_read;
 	const struct spinand_manufacturer *manufacturer;
 	void *priv;
 };
-- 
2.17.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/4] mtd: spinand: Add support continuous read operation
  2022-02-09  9:10 [PATCH v2 0/4] mtd: spinand: Add continuous read mode support Zhengxun
  2022-02-09  9:10 ` [PATCH v2 1/4] mtd: spinand: Add support continuous read mode Zhengxun
  2022-02-09  9:10 ` [PATCH v2 2/4] mtd: spinand: Add continuous read state Zhengxun
@ 2022-02-09  9:10 ` Zhengxun
  2022-05-19 16:06   ` Miquel Raynal
  2022-02-09  9:10 ` [PATCH v2 4/4] mtd: spinand: macronix: Add continuous read support for MX35LF2GE4AD Zhengxun
  3 siblings, 1 reply; 9+ messages in thread
From: Zhengxun @ 2022-02-09  9:10 UTC (permalink / raw)
  To: miquel.raynal, linux-mtd; +Cc: zhengxunli, Zhengxun

The continuous read operation including: firstly, starting
with the page read command and the 1st page data will be
read into the cache after the read latency tRD. Secondly,
Issuing the Read From Cache commands (03h/0Bh/3Bh/6Bh/BBh/EBh)
to read out the data from cache continuously. After all the
data is read out, the host should pull CS# high to terminate
this continuous read operation and wait tRST for the NAND
device resets read operation.

The continuous read usuage is enable by read mutiple page
(at least larger than 1 page size) and the column address is
don't care in this operation, since the data output for each
page will always start from byte 0 and a full page data should
be read out for each page.

On the other hand, since the continuous read mode can only read
the entire page of data and cannot read the oob data, the dynamic
change mode is added to enable continuous read mode and disable
continuous read mode in spinand_mtd_continuous_read to avoid
writing and erasing operation is abnormal.

The performance of continuous read mode is as follows. Set the
flash to QUAD mode and run 25MZ direct mapping mode on the SPI
bus and use the MTD test module to show the performance of
continuous reads.

=================================================
mtd_speedtest: MTD device: 0    count: 100 
mtd_speedtest: MTD device size 268435456, eraseblock size 131072,
               page size 2048, count of eraseblocks 2048, pages per
	       eraseblock 64, OOB size 64
mtd_test: scanning for bad eraseblocks
mtd_test: scanned 100 eraseblocks, 0 are bad 
mtd_speedtest: testing eraseblock write speed
mtd_speedtest: eraseblock write speed is 1298 KiB/s
mtd_speedtest: testing eraseblock read speed
mtd_speedtest: eraseblock read speed is 11053 KiB/s
mtd_speedtest: testing page write speed
mtd_speedtest: page write speed is 1291 KiB/s
mtd_speedtest: testing page read speed
mtd_speedtest: page read speed is 3240 KiB/s
mtd_speedtest: testing 2 page write speed
mtd_speedtest: 2 page write speed is 1289 KiB/s
mtd_speedtest: testing 2 page read speed
mtd_speedtest: 2 page read speed is 2909 KiB/s
mtd_speedtest: Testing erase speed
mtd_speedtest: erase speed is 45229 KiB/s
mtd_speedtest: Testing 2x multi-block erase speed
mtd_speedtest: 2x multi-block erase speed is 62135 KiB/s
mtd_speedtest: Testing 4x multi-block erase speed
mtd_speedtest: 4x multi-block erase speed is 60093 KiB/s
mtd_speedtest: Testing 8x multi-block erase speed
mtd_speedtest: 8x multi-block erase speed is 61244 KiB/s
mtd_speedtest: Testing 16x multi-block erase speed
mtd_speedtest: 16x multi-block erase speed is 61538 KiB/s
mtd_speedtest: Testing 32x multi-block erase speed
mtd_speedtest: 32x multi-block erase speed is 61835 KiB/s
mtd_speedtest: Testing 64x multi-block erase speed
mtd_speedtest: 64x multi-block erase speed is 60663 KiB/s
mtd_speedtest: finished
=================================================

Signed-off-by: Zhengxun <zhengxunli.mxic@gmail.com>
---
 drivers/mtd/nand/spi/core.c | 97 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 380411feab6c..990836fff924 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -383,7 +383,10 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
 	u16 column = 0;
 	ssize_t ret;
 
-	if (req->datalen) {
+	if (spinand->use_continuous_read) {
+		buf = req->databuf.in;
+		nbytes = req->datalen;
+	} else if (req->datalen) {
 		buf = spinand->databuf;
 		nbytes = nanddev_page_size(nand);
 		column = 0;
@@ -412,6 +415,9 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
 		buf += ret;
 	}
 
+	if (spinand->use_continuous_read)
+		return 0;
+
 	if (req->datalen)
 		memcpy(req->databuf.in, spinand->databuf + req->dataoffs,
 		       req->datalen);
@@ -640,6 +646,81 @@ static int spinand_write_page(struct spinand_device *spinand,
 	return nand_ecc_finish_io_req(nand, (struct nand_page_io_req *)req);
 }
 
+static int spinand_mtd_continuous_read(struct mtd_info *mtd, loff_t from,
+				       struct mtd_oob_ops *ops,
+				       struct nand_io_iter *iter)
+{
+	struct spinand_device *spinand = mtd_to_spinand(mtd);
+	struct nand_device *nand = mtd_to_nanddev(mtd);
+	int ret = 0;
+
+	/*
+	 * Since the continuous read mode can only read the entire page of data
+	 * and cannot read the oob data, therefore, only ECC-Free SPI-NAND support
+	 * continuous read mode now.
+	 */
+	iter->req.type = NAND_PAGE_READ;
+	iter->req.mode = MTD_OPS_RAW;
+	iter->req.dataoffs = nanddev_offs_to_pos(nand, from, &iter->req.pos);
+	iter->req.databuf.in = ops->datbuf;
+	iter->req.datalen = ops->len;
+
+	if (from & (nanddev_page_size(nand) - 1)) {
+		pr_debug("%s: unaligned address\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = spinand_continuous_read_enable(spinand);
+	if (ret)
+		return ret;
+
+	spinand->use_continuous_read = true;
+
+	ret = spinand_select_target(spinand, iter->req.pos.target);
+	if (ret)
+		return ret;
+
+	/*
+	 * The continuous read operation including: firstly, starting with the
+	 * page read command and the 1 st page data will be read into the cache
+	 * after the read latency tRD. Secondly, Issuing the Read From Cache
+	 * commands (03h/0Bh/3Bh/6Bh/BBh/EBh) to read out the data from cache
+	 * continuously.
+	 *
+	 * The cache is divided into two halves, while one half of the cache is
+	 * outputting the data, the other half will be loaded for the new data;
+	 * therefore, the host can read out the data continuously from page to
+	 * page. Multiple of Read From Cache commands can be issued in one
+	 * continuous read operation, each Read From Cache command is required
+	 * to read multiple 4-byte data exactly; otherwise, the data output will
+	 * be out of sequence from one Read From Cache command to another Read
+	 * From Cache command.
+	 *
+	 * After all the data is read out, the host should pull CS# high to
+	 * terminate this continuous read operation and wait a 6us of tRST for
+	 * the NAND device resets read operation. The data output for each page
+	 * will always start from byte 0 and a full page data should be read out
+	 * for each page.
+	 */
+	ret = spinand_read_page(spinand, &iter->req);
+	if (ret)
+		return ret;
+
+	ret = spinand_reset_op(spinand);
+	if (ret)
+		return ret;
+
+	ret = spinand_continuous_read_disable(spinand);
+	if (ret)
+		return ret;
+
+	spinand->use_continuous_read = false;
+
+	ops->retlen = iter->req.datalen;
+
+	return ret;
+}
+
 static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
 			    struct mtd_oob_ops *ops)
 {
@@ -656,6 +737,19 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
 
 	mutex_lock(&spinand->lock);
 
+	/*
+	 * If the device support continuous read mode and read length larger
+	 * than one page size will enter the continuous read mode. This mode
+	 * helps avoid issuing a page read command and read from cache command
+	 * again, and improves read performance for continuous addresses.
+	 */
+	if ((spinand->flags & SPINAND_HAS_CONT_READ_BIT) &&
+	    (ops->len > nanddev_page_size(nand))) {
+		ret = spinand_mtd_continuous_read(mtd, from, ops, &iter);
+
+		goto continuous_read_finish;
+	}
+
 	nanddev_io_for_each_page(nand, NAND_PAGE_READ, from, ops, &iter) {
 		if (disable_ecc)
 			iter.req.mode = MTD_OPS_RAW;
@@ -678,6 +772,7 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
 		ops->oobretlen += iter.req.ooblen;
 	}
 
+continuous_read_finish:
 	mutex_unlock(&spinand->lock);
 
 	if (ecc_failed && !ret)
-- 
2.17.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 4/4] mtd: spinand: macronix: Add continuous read support for MX35LF2GE4AD
  2022-02-09  9:10 [PATCH v2 0/4] mtd: spinand: Add continuous read mode support Zhengxun
                   ` (2 preceding siblings ...)
  2022-02-09  9:10 ` [PATCH v2 3/4] mtd: spinand: Add support continuous read operation Zhengxun
@ 2022-02-09  9:10 ` Zhengxun
  2022-05-19 16:07   ` Miquel Raynal
  3 siblings, 1 reply; 9+ messages in thread
From: Zhengxun @ 2022-02-09  9:10 UTC (permalink / raw)
  To: miquel.raynal, linux-mtd; +Cc: zhengxunli, Zhengxun

Add continuous read flag for MX35LF2GE4AD

Signed-off-by: Zhengxun <zhengxunli.mxic@gmail.com>
---
 drivers/mtd/nand/spi/macronix.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
index 3f31f1381a62..02fb8f37947d 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
@@ -126,7 +126,7 @@ static const struct spinand_info macronix_spinand_table[] = {
 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
 					      &write_cache_variants,
 					      &update_cache_variants),
-		     SPINAND_HAS_QE_BIT,
+		     SPINAND_HAS_QE_BIT | SPINAND_HAS_CONT_READ_BIT,
 		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
 				     mx35lf1ge4ab_ecc_get_status)),
 	SPINAND_INFO("MX35LF4GE4AD",
-- 
2.17.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/4] mtd: spinand: Add support continuous read operation
  2022-02-09  9:10 ` [PATCH v2 3/4] mtd: spinand: Add support continuous read operation Zhengxun
@ 2022-05-19 16:06   ` Miquel Raynal
  0 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2022-05-19 16:06 UTC (permalink / raw)
  To: Zhengxun; +Cc: linux-mtd, zhengxunli

Hi Zhengxun,

Sorry for the delay in reviewing this patchset, here are a few comments
below.

Also, I seem to remember that you sent a similar patchset for rawnand,
is this still something that you want to push? IIRC there were issues
with the support of the continuous commands for all the controllers.
Please send a new iteration of this patchset if you want help about it.

zhengxunli.mxic@gmail.com wrote on Wed,  9 Feb 2022 17:10:21 +0800:

> The continuous read operation including: firstly, starting

                                includes three phases:
- starting ...
- issuing...
- pulling...

> with the page read command and the 1st page data will be
> read into the cache after the read latency tRD. Secondly,
> Issuing the Read From Cache commands (03h/0Bh/3Bh/6Bh/BBh/EBh)
> to read out the data from cache continuously. After all the
> data is read out, the host should pull CS# high to terminate
> this continuous read operation and wait tRST for the NAND
> device resets read operation.
> 
> The continuous read usuage is enable by read mutiple page

Continuous reads have a positive impact when reading more than one
page.

> (at least larger than 1 page size) and the column address is
> don't care in this operation, since the data output for each
> page will always start from byte 0 and a full page data should
> be read out for each page.

This is not entirely true, the user can request to read from a
different offset, it will be translated into a page access anyway.

> On the other hand, since the continuous read mode can only read
> the entire page of data and cannot read the oob data, the dynamic
> change mode is added to enable continuous read mode and disable
> continuous read mode in spinand_mtd_continuous_read to avoid
> writing and erasing operation is abnormal.

This sentence is not very clear. I don't see how it translates in the
below code.

> The performance of continuous read mode is as follows.

Here is a benchmark of what can be achieved with a flash configured
into quad mode accessed on a SPI bus running at 25MHz.

> Set the
> flash to QUAD mode and run 25MZ direct mapping mode on the SPI
> bus and use the MTD test module to show the performance of
> continuous reads.
> 
> =================================================
> mtd_speedtest: MTD device: 0    count: 100 
> mtd_speedtest: MTD device size 268435456, eraseblock size 131072,
>                page size 2048, count of eraseblocks 2048, pages per
> 	       eraseblock 64, OOB size 64
> mtd_test: scanning for bad eraseblocks
> mtd_test: scanned 100 eraseblocks, 0 are bad 
> mtd_speedtest: testing eraseblock write speed
> mtd_speedtest: eraseblock write speed is 1298 KiB/s
> mtd_speedtest: testing eraseblock read speed
> mtd_speedtest: eraseblock read speed is 11053 KiB/s
> mtd_speedtest: testing page write speed
> mtd_speedtest: page write speed is 1291 KiB/s
> mtd_speedtest: testing page read speed
> mtd_speedtest: page read speed is 3240 KiB/s
> mtd_speedtest: testing 2 page write speed
> mtd_speedtest: 2 page write speed is 1289 KiB/s
> mtd_speedtest: testing 2 page read speed
> mtd_speedtest: 2 page read speed is 2909 KiB/s
> mtd_speedtest: Testing erase speed
> mtd_speedtest: erase speed is 45229 KiB/s
> mtd_speedtest: Testing 2x multi-block erase speed
> mtd_speedtest: 2x multi-block erase speed is 62135 KiB/s
> mtd_speedtest: Testing 4x multi-block erase speed
> mtd_speedtest: 4x multi-block erase speed is 60093 KiB/s
> mtd_speedtest: Testing 8x multi-block erase speed
> mtd_speedtest: 8x multi-block erase speed is 61244 KiB/s
> mtd_speedtest: Testing 16x multi-block erase speed
> mtd_speedtest: 16x multi-block erase speed is 61538 KiB/s
> mtd_speedtest: Testing 32x multi-block erase speed
> mtd_speedtest: 32x multi-block erase speed is 61835 KiB/s
> mtd_speedtest: Testing 64x multi-block erase speed
> mtd_speedtest: 64x multi-block erase speed is 60663 KiB/s
> mtd_speedtest: finished
> =================================================
> 
> Signed-off-by: Zhengxun <zhengxunli.mxic@gmail.com>

                          Li ?

> ---
>  drivers/mtd/nand/spi/core.c | 97 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 96 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> index 380411feab6c..990836fff924 100644
> --- a/drivers/mtd/nand/spi/core.c
> +++ b/drivers/mtd/nand/spi/core.c
> @@ -383,7 +383,10 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
>  	u16 column = 0;
>  	ssize_t ret;
>  
> -	if (req->datalen) {
> +	if (spinand->use_continuous_read) {
> +		buf = req->databuf.in;
> +		nbytes = req->datalen;

That does not sound necessary, please try to keep the existing logic.

> +	} else if (req->datalen) {
>  		buf = spinand->databuf;
>  		nbytes = nanddev_page_size(nand);
>  		column = 0;
> @@ -412,6 +415,9 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
>  		buf += ret;
>  	}
>  
> +	if (spinand->use_continuous_read)
> +		return 0;
> +
>  	if (req->datalen)
>  		memcpy(req->databuf.in, spinand->databuf + req->dataoffs,
>  		       req->datalen);
> @@ -640,6 +646,81 @@ static int spinand_write_page(struct spinand_device *spinand,
>  	return nand_ecc_finish_io_req(nand, (struct nand_page_io_req *)req);
>  }
>  
> +static int spinand_mtd_continuous_read(struct mtd_info *mtd, loff_t from,
> +				       struct mtd_oob_ops *ops,
> +				       struct nand_io_iter *iter)
> +{
> +	struct spinand_device *spinand = mtd_to_spinand(mtd);
> +	struct nand_device *nand = mtd_to_nanddev(mtd);
> +	int ret = 0;
> +
> +	/*
> +	 * Since the continuous read mode can only read the entire page of data
> +	 * and cannot read the oob data, therefore, only ECC-Free SPI-NAND support
> +	 * continuous read mode now.

That is simply not possible. At the very least we need on-die ECC NAND
chips to work otherwise the feature will have not impact. The raw path
is the slow path, we don't care about performances there.

> +	 */
> +	iter->req.type = NAND_PAGE_READ;
> +	iter->req.mode = MTD_OPS_RAW;
> +	iter->req.dataoffs = nanddev_offs_to_pos(nand, from, &iter->req.pos);
> +	iter->req.databuf.in = ops->datbuf;
> +	iter->req.datalen = ops->len;
> +
> +	if (from & (nanddev_page_size(nand) - 1)) {
> +		pr_debug("%s: unaligned address\n", __func__);

We can support unaligned addresses, just like we do for normal accesses.

> +		return -EINVAL;
> +	}
> +
> +	ret = spinand_continuous_read_enable(spinand);
> +	if (ret)
> +		return ret;
> +
> +	spinand->use_continuous_read = true;
> +
> +	ret = spinand_select_target(spinand, iter->req.pos.target);
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * The continuous read operation including: firstly, starting with the
> +	 * page read command and the 1 st page data will be read into the cache
> +	 * after the read latency tRD. Secondly, Issuing the Read From Cache
> +	 * commands (03h/0Bh/3Bh/6Bh/BBh/EBh) to read out the data from cache
> +	 * continuously.
> +	 *
> +	 * The cache is divided into two halves, while one half of the cache is
> +	 * outputting the data, the other half will be loaded for the new data;
> +	 * therefore, the host can read out the data continuously from page to
> +	 * page. Multiple of Read From Cache commands can be issued in one
> +	 * continuous read operation, each Read From Cache command is required
> +	 * to read multiple 4-byte data exactly; otherwise, the data output will
> +	 * be out of sequence from one Read From Cache command to another Read
> +	 * From Cache command.
> +	 *
> +	 * After all the data is read out, the host should pull CS# high to
> +	 * terminate this continuous read operation and wait a 6us of tRST for
> +	 * the NAND device resets read operation. The data output for each page
> +	 * will always start from byte 0 and a full page data should be read out
> +	 * for each page.
> +	 */
> +	ret = spinand_read_page(spinand, &iter->req);
> +	if (ret)
> +		return ret;
> +
> +	ret = spinand_reset_op(spinand);
> +	if (ret)
> +		return ret;
> +
> +	ret = spinand_continuous_read_disable(spinand);
> +	if (ret)
> +		return ret;
> +
> +	spinand->use_continuous_read = false;
> +
> +	ops->retlen = iter->req.datalen;
> +
> +	return ret;
> +}
> +
>  static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
>  			    struct mtd_oob_ops *ops)
>  {
> @@ -656,6 +737,19 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
>  
>  	mutex_lock(&spinand->lock);
>  
> +	/*
> +	 * If the device support continuous read mode and read length larger
> +	 * than one page size will enter the continuous read mode. This mode
> +	 * helps avoid issuing a page read command and read from cache command
> +	 * again, and improves read performance for continuous addresses.
> +	 */
> +	if ((spinand->flags & SPINAND_HAS_CONT_READ_BIT) &&
> +	    (ops->len > nanddev_page_size(nand))) {
> +		ret = spinand_mtd_continuous_read(mtd, from, ops, &iter);
> +
> +		goto continuous_read_finish;

You can release the mutex and return immediately.

> +	}
> +
>  	nanddev_io_for_each_page(nand, NAND_PAGE_READ, from, ops, &iter) {
>  		if (disable_ecc)
>  			iter.req.mode = MTD_OPS_RAW;
> @@ -678,6 +772,7 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
>  		ops->oobretlen += iter.req.ooblen;
>  	}
>  
> +continuous_read_finish:
>  	mutex_unlock(&spinand->lock);
>  
>  	if (ecc_failed && !ret)


Thanks,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 4/4] mtd: spinand: macronix: Add continuous read support for MX35LF2GE4AD
  2022-02-09  9:10 ` [PATCH v2 4/4] mtd: spinand: macronix: Add continuous read support for MX35LF2GE4AD Zhengxun
@ 2022-05-19 16:07   ` Miquel Raynal
  0 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2022-05-19 16:07 UTC (permalink / raw)
  To: Zhengxun; +Cc: linux-mtd, zhengxunli

Hi Zhengxun,

zhengxunli.mxic@gmail.com wrote on Wed,  9 Feb 2022 17:10:22 +0800:

> Add continuous read flag for MX35LF2GE4AD

                           to MXxxxxxxx.

> 
> Signed-off-by: Zhengxun <zhengxunli.mxic@gmail.com>
> ---
>  drivers/mtd/nand/spi/macronix.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
> index 3f31f1381a62..02fb8f37947d 100644
> --- a/drivers/mtd/nand/spi/macronix.c
> +++ b/drivers/mtd/nand/spi/macronix.c
> @@ -126,7 +126,7 @@ static const struct spinand_info macronix_spinand_table[] = {
>  		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
>  					      &write_cache_variants,
>  					      &update_cache_variants),
> -		     SPINAND_HAS_QE_BIT,
> +		     SPINAND_HAS_QE_BIT | SPINAND_HAS_CONT_READ_BIT,
>  		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
>  				     mx35lf1ge4ab_ecc_get_status)),
>  	SPINAND_INFO("MX35LF4GE4AD",


Thanks,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/4] mtd: spinand: Add support continuous read mode
  2022-02-09  9:10 ` [PATCH v2 1/4] mtd: spinand: Add support continuous read mode Zhengxun
@ 2022-05-19 16:08   ` Miquel Raynal
  0 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2022-05-19 16:08 UTC (permalink / raw)
  To: Zhengxun; +Cc: linux-mtd, zhengxunli

Hi Zhengxun,

zhengxunli.mxic@gmail.com wrote on Wed,  9 Feb 2022 17:10:19 +0800:

> The patch supports setting the "CONT" bit of the configuration

            add support for

> register and adding a continuous read mode flag for identification.

It's not really a configuration register, it's capability flag.

> 
> Signed-off-by: Zhengxun <zhengxunli.mxic@gmail.com>
> ---
>  drivers/mtd/nand/spi/core.c | 11 +++++++++++
>  include/linux/mtd/spinand.h |  2 ++
>  2 files changed, 13 insertions(+)
> 
> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> index 2c8685f1f2fa..dc2e1dc1dbee 100644
> --- a/drivers/mtd/nand/spi/core.c
> +++ b/drivers/mtd/nand/spi/core.c
> @@ -193,6 +193,17 @@ static int spinand_init_quad_enable(struct spinand_device *spinand)
>  			       enable ? CFG_QUAD_ENABLE : 0);
>  }
>  
> +static int spinand_continuous_read_enable(struct spinand_device *spinand)
> +{
> +	return spinand_upd_cfg(spinand, CFG_CONT_READ_ENABLE,
> +			       CFG_CONT_READ_ENABLE);
> +}
> +
> +static int spinand_continuous_read_disable(struct spinand_device *spinand)
> +{
> +	return spinand_upd_cfg(spinand, CFG_CONT_READ_ENABLE, 0);
> +}
> +
>  static int spinand_ecc_enable(struct spinand_device *spinand,
>  			      bool enable)
>  {
> diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
> index 6988956b8492..04be10ec8fb0 100644
> --- a/include/linux/mtd/spinand.h
> +++ b/include/linux/mtd/spinand.h
> @@ -154,6 +154,7 @@
>  #define REG_CFG			0xb0
>  #define CFG_OTP_ENABLE		BIT(6)
>  #define CFG_ECC_ENABLE		BIT(4)
> +#define CFG_CONT_READ_ENABLE	BIT(2)
>  #define CFG_QUAD_ENABLE		BIT(0)
>  
>  /* status register */
> @@ -307,6 +308,7 @@ struct spinand_ecc_info {
>  
>  #define SPINAND_HAS_QE_BIT		BIT(0)
>  #define SPINAND_HAS_CR_FEAT_BIT		BIT(1)
> +#define SPINAND_HAS_CONT_READ_BIT	BIT(2)

Not related to this patch.

>  
>  /**
>   * struct spinand_ondie_ecc_conf - private SPI-NAND on-die ECC engine structure


Thanks,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/4] mtd: spinand: Add support continuous read mode
  2023-02-09 12:08 [PATCH v2 0/4] mtd: spinand: Add continuous read mode support Jaime Liao
@ 2023-02-09 12:08 ` Jaime Liao
  0 siblings, 0 replies; 9+ messages in thread
From: Jaime Liao @ 2023-02-09 12:08 UTC (permalink / raw)
  To: linux-mtd, miquel.raynal, richard; +Cc: jaimeliao, jaimeliao.tw

The patch supports setting the "CONT" bit of the configuration
register and create spinand_continuous_read_enable/disable functions.

Signed-off-by: Jaime Liao <jaimeliao.tw@gmail.com>
---
 drivers/mtd/nand/spi/core.c | 11 +++++++++++
 include/linux/mtd/spinand.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index dacd9c0e8b20..c13374933372 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -193,6 +193,17 @@ static int spinand_init_quad_enable(struct spinand_device *spinand)
 			       enable ? CFG_QUAD_ENABLE : 0);
 }
 
+static int spinand_continuous_read_enable(struct spinand_device *spinand)
+{
+	return spinand_upd_cfg(spinand, CFG_CONT_READ_ENABLE,
+			       CFG_CONT_READ_ENABLE);
+}
+
+static int spinand_continuous_read_disable(struct spinand_device *spinand)
+{
+	return spinand_upd_cfg(spinand, CFG_CONT_READ_ENABLE, 0);
+}
+
 static int spinand_ecc_enable(struct spinand_device *spinand,
 			      bool enable)
 {
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6d3392a7edc6..e98d770173dc 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -154,6 +154,7 @@
 #define REG_CFG			0xb0
 #define CFG_OTP_ENABLE		BIT(6)
 #define CFG_ECC_ENABLE		BIT(4)
+#define CFG_CONT_READ_ENABLE	BIT(2)
 #define CFG_QUAD_ENABLE		BIT(0)
 
 /* status register */
-- 
2.34.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-02-09 12:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-09  9:10 [PATCH v2 0/4] mtd: spinand: Add continuous read mode support Zhengxun
2022-02-09  9:10 ` [PATCH v2 1/4] mtd: spinand: Add support continuous read mode Zhengxun
2022-05-19 16:08   ` Miquel Raynal
2022-02-09  9:10 ` [PATCH v2 2/4] mtd: spinand: Add continuous read state Zhengxun
2022-02-09  9:10 ` [PATCH v2 3/4] mtd: spinand: Add support continuous read operation Zhengxun
2022-05-19 16:06   ` Miquel Raynal
2022-02-09  9:10 ` [PATCH v2 4/4] mtd: spinand: macronix: Add continuous read support for MX35LF2GE4AD Zhengxun
2022-05-19 16:07   ` Miquel Raynal
2023-02-09 12:08 [PATCH v2 0/4] mtd: spinand: Add continuous read mode support Jaime Liao
2023-02-09 12:08 ` [PATCH v2 1/4] mtd: spinand: Add support continuous read mode Jaime Liao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.