All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op()
@ 2020-04-29 13:20 Boris Brezillon
  2020-04-29 13:20 ` [PATCH v2 1/6] mtd: rawnand: atmel: Enable the NFC controller at probe time Boris Brezillon
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Boris Brezillon @ 2020-04-29 13:20 UTC (permalink / raw)
  To: Miquel Raynal, linux-mtd, Tudor Ambarus
  Cc: Alexandre Belloni, Vignesh Raghavendra, Richard Weinberger,
	Nicolas Ferre, Ludovic Desroches, Boris Brezillon

Hello,

This v2 splits changes to make the diff more readable and fixes a bug
reported by Tudor (thanks for testing/helping me debug the issue BTW).
Note that the patch propagating the CS information to sub operations
has been dropped since the new version no longer depends on it, but
will be posted as part of another series where it's needed (the
cafe_nand conversion).

Regards,

Boris

Boris Brezillon (6):
  mtd: rawnand: atmel: Enable the NFC controller at probe time
  mtd: rawnand: atmel: Drop redundant nand_read_page_op()
  mtd: rawnand: atmel: Use nand_{write,read}_data_op()
  mtd: rawnand: atmel: Use nand_prog_page_end_op()
  mtd: rawnand: atmel: Convert the driver to exec_op()
  mtd: rawnand: atmel: Get rid of the legacy interface implementation

 drivers/mtd/nand/raw/atmel/nand-controller.c | 464 +++++++++++--------
 1 file changed, 258 insertions(+), 206 deletions(-)

-- 
2.25.3


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

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

* [PATCH v2 1/6] mtd: rawnand: atmel: Enable the NFC controller at probe time
  2020-04-29 13:20 [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
@ 2020-04-29 13:20 ` Boris Brezillon
  2020-05-10 21:25   ` Miquel Raynal
  2020-05-12 13:00   ` Tudor.Ambarus
  2020-04-29 13:20 ` [PATCH v2 2/6] mtd: rawnand: atmel: Drop redundant nand_read_page_op() Boris Brezillon
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 16+ messages in thread
From: Boris Brezillon @ 2020-04-29 13:20 UTC (permalink / raw)
  To: Miquel Raynal, linux-mtd, Tudor Ambarus
  Cc: Alexandre Belloni, Vignesh Raghavendra, Richard Weinberger,
	Nicolas Ferre, Ludovic Desroches, Boris Brezillon

No need to enable it everytime select_chip() is called. If we really
care about PM, we should implement runtime PM hooks and disable the
controller and all its clocks when the controller has been unused for
some time.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
Changes in v2:
* New patch
---
 drivers/mtd/nand/raw/atmel/nand-controller.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 3ba17a98df4d..1ba60b61dedc 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -525,11 +525,8 @@ static void atmel_hsmc_nand_select_chip(struct nand_chip *chip, int cs)
 
 	atmel_nand_select_chip(chip, cs);
 
-	if (!nand->activecs) {
-		regmap_write(nc->base.smc, ATMEL_HSMC_NFC_CTRL,
-			     ATMEL_HSMC_NFC_CTRL_DIS);
+	if (!nand->activecs)
 		return;
-	}
 
 	if (nand->activecs->rb.type == ATMEL_NAND_NATIVE_RB)
 		chip->legacy.dev_ready = atmel_hsmc_nand_dev_ready;
@@ -542,8 +539,6 @@ static void atmel_hsmc_nand_select_chip(struct nand_chip *chip, int cs)
 			   ATMEL_HSMC_NFC_CFG_PAGESIZE(mtd->writesize) |
 			   ATMEL_HSMC_NFC_CFG_SPARESIZE(mtd->oobsize) |
 			   ATMEL_HSMC_NFC_CFG_RSPARE);
-	regmap_write(nc->base.smc, ATMEL_HSMC_NFC_CTRL,
-		     ATMEL_HSMC_NFC_CTRL_EN);
 }
 
 static int atmel_nfc_exec_op(struct atmel_hsmc_nand_controller *nc, bool poll)
@@ -2248,6 +2243,9 @@ atmel_hsmc_nand_controller_remove(struct atmel_nand_controller *nc)
 		return ret;
 
 	hsmc_nc = container_of(nc, struct atmel_hsmc_nand_controller, base);
+	regmap_write(hsmc_nc->base.smc, ATMEL_HSMC_NFC_CTRL,
+		     ATMEL_HSMC_NFC_CTRL_DIS);
+
 	if (hsmc_nc->sram.pool)
 		gen_pool_free(hsmc_nc->sram.pool,
 			      (unsigned long)hsmc_nc->sram.virt,
@@ -2300,6 +2298,8 @@ static int atmel_hsmc_nand_controller_probe(struct platform_device *pdev,
 	/* Initial NFC configuration. */
 	regmap_write(nc->base.smc, ATMEL_HSMC_NFC_CFG,
 		     ATMEL_HSMC_NFC_CFG_DTO_MAX);
+	regmap_write(nc->base.smc, ATMEL_HSMC_NFC_CTRL,
+		     ATMEL_HSMC_NFC_CTRL_EN);
 
 	ret = atmel_nand_controller_add_nands(&nc->base);
 	if (ret)
-- 
2.25.3


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

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

* [PATCH v2 2/6] mtd: rawnand: atmel: Drop redundant nand_read_page_op()
  2020-04-29 13:20 [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
  2020-04-29 13:20 ` [PATCH v2 1/6] mtd: rawnand: atmel: Enable the NFC controller at probe time Boris Brezillon
@ 2020-04-29 13:20 ` Boris Brezillon
  2020-05-10 21:26   ` Miquel Raynal
  2020-05-12 13:06   ` Tudor.Ambarus
  2020-04-29 13:20 ` [PATCH v2 3/6] mtd: rawnand: atmel: Use nand_{write,read}_data_op() Boris Brezillon
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 16+ messages in thread
From: Boris Brezillon @ 2020-04-29 13:20 UTC (permalink / raw)
  To: Miquel Raynal, linux-mtd, Tudor Ambarus
  Cc: Alexandre Belloni, Vignesh Raghavendra, Richard Weinberger,
	Nicolas Ferre, Ludovic Desroches, Boris Brezillon

The legacy page read path in atmel_hsmc_nand_pmecc_read_pg() issues
a nand_read_page_op() that's already issued by
atmel_nand_pmecc_read_pg(). Let's get rid of the unneeded one.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
Changes in v2:
* New patch
---
 drivers/mtd/nand/raw/atmel/nand-controller.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 1ba60b61dedc..8e5cfb5cf70b 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -983,12 +983,9 @@ static int atmel_hsmc_nand_pmecc_read_pg(struct nand_chip *chip, u8 *buf,
 	 * connected to a native SoC R/B pin. If that's not the case, fallback
 	 * to the non-optimized one.
 	 */
-	if (nand->activecs->rb.type != ATMEL_NAND_NATIVE_RB) {
-		nand_read_page_op(chip, page, 0, NULL, 0);
-
+	if (nand->activecs->rb.type != ATMEL_NAND_NATIVE_RB)
 		return atmel_nand_pmecc_read_pg(chip, buf, oob_required, page,
 						raw);
-	}
 
 	nc->op.cmds[nc->op.ncmds++] = NAND_CMD_READ0;
 
-- 
2.25.3


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

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

* [PATCH v2 3/6] mtd: rawnand: atmel: Use nand_{write,read}_data_op()
  2020-04-29 13:20 [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
  2020-04-29 13:20 ` [PATCH v2 1/6] mtd: rawnand: atmel: Enable the NFC controller at probe time Boris Brezillon
  2020-04-29 13:20 ` [PATCH v2 2/6] mtd: rawnand: atmel: Drop redundant nand_read_page_op() Boris Brezillon
@ 2020-04-29 13:20 ` Boris Brezillon
  2020-05-10 21:28   ` Miquel Raynal
  2020-05-12 13:10   ` Tudor.Ambarus
  2020-04-29 13:20 ` [PATCH v2 4/6] mtd: rawnand: atmel: Use nand_prog_page_end_op() Boris Brezillon
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 16+ messages in thread
From: Boris Brezillon @ 2020-04-29 13:20 UTC (permalink / raw)
  To: Miquel Raynal, linux-mtd, Tudor Ambarus
  Cc: Alexandre Belloni, Vignesh Raghavendra, Richard Weinberger,
	Nicolas Ferre, Ludovic Desroches, Boris Brezillon

Use the nand_{write,read}_data_op() helpers instead of calling the
atmel_nand_{read,write}_buf() functions directly. This will ease the
transition to exec_op().

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
Changes in v2:
* New patch
---
 drivers/mtd/nand/raw/atmel/nand-controller.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 8e5cfb5cf70b..8be911ef9a6c 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -833,7 +833,7 @@ static int atmel_nand_pmecc_write_pg(struct nand_chip *chip, const u8 *buf,
 	if (ret)
 		return ret;
 
-	atmel_nand_write_buf(chip, buf, mtd->writesize);
+	nand_write_data_op(chip, buf, mtd->writesize, false);
 
 	ret = atmel_nand_pmecc_generate_eccbytes(chip, raw);
 	if (ret) {
@@ -843,7 +843,7 @@ static int atmel_nand_pmecc_write_pg(struct nand_chip *chip, const u8 *buf,
 
 	atmel_nand_pmecc_disable(chip, raw);
 
-	atmel_nand_write_buf(chip, chip->oob_poi, mtd->oobsize);
+	nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false);
 
 	return nand_prog_page_end_op(chip);
 }
@@ -873,8 +873,8 @@ static int atmel_nand_pmecc_read_pg(struct nand_chip *chip, u8 *buf,
 	if (ret)
 		return ret;
 
-	atmel_nand_read_buf(chip, buf, mtd->writesize);
-	atmel_nand_read_buf(chip, chip->oob_poi, mtd->oobsize);
+	nand_read_data_op(chip, buf, mtd->writesize, false);
+	nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false);
 
 	ret = atmel_nand_pmecc_correct_data(chip, buf, raw);
 
@@ -934,7 +934,7 @@ static int atmel_hsmc_nand_pmecc_write_pg(struct nand_chip *chip,
 	if (ret)
 		return ret;
 
-	atmel_nand_write_buf(chip, chip->oob_poi, mtd->oobsize);
+	nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false);
 
 	nc->op.cmds[0] = NAND_CMD_PAGEPROG;
 	nc->op.ncmds = 1;
-- 
2.25.3


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

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

* [PATCH v2 4/6] mtd: rawnand: atmel: Use nand_prog_page_end_op()
  2020-04-29 13:20 [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
                   ` (2 preceding siblings ...)
  2020-04-29 13:20 ` [PATCH v2 3/6] mtd: rawnand: atmel: Use nand_{write,read}_data_op() Boris Brezillon
@ 2020-04-29 13:20 ` Boris Brezillon
  2020-05-10 21:30   ` Miquel Raynal
  2020-04-29 13:20 ` [PATCH v2 5/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Boris Brezillon @ 2020-04-29 13:20 UTC (permalink / raw)
  To: Miquel Raynal, linux-mtd, Tudor Ambarus
  Cc: Alexandre Belloni, Vignesh Raghavendra, Richard Weinberger,
	Nicolas Ferre, Ludovic Desroches, Boris Brezillon

The nand_prog_page_end_op() sequence is open-coded in
atmel_hsmc_nand_pmecc_write_pg(). Let's use the generic helper here.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
Changes in v2:
* New patch
---
 drivers/mtd/nand/raw/atmel/nand-controller.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 8be911ef9a6c..4bd131a34408 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -902,7 +902,7 @@ static int atmel_hsmc_nand_pmecc_write_pg(struct nand_chip *chip,
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct atmel_nand *nand = to_atmel_nand(chip);
 	struct atmel_hsmc_nand_controller *nc;
-	int ret, status;
+	int ret;
 
 	nc = to_hsmc_nand_controller(chip->controller);
 
@@ -936,19 +936,7 @@ static int atmel_hsmc_nand_pmecc_write_pg(struct nand_chip *chip,
 
 	nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false);
 
-	nc->op.cmds[0] = NAND_CMD_PAGEPROG;
-	nc->op.ncmds = 1;
-	nc->op.cs = nand->activecs->id;
-	ret = atmel_nfc_exec_op(nc, false);
-	if (ret)
-		dev_err(nc->base.dev, "Failed to program NAND page (err = %d)\n",
-			ret);
-
-	status = chip->legacy.waitfunc(chip);
-	if (status & NAND_STATUS_FAIL)
-		return -EIO;
-
-	return ret;
+	return nand_prog_page_end_op(chip);
 }
 
 static int atmel_hsmc_nand_pmecc_write_page(struct nand_chip *chip,
-- 
2.25.3


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

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

* [PATCH v2 5/6] mtd: rawnand: atmel: Convert the driver to exec_op()
  2020-04-29 13:20 [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
                   ` (3 preceding siblings ...)
  2020-04-29 13:20 ` [PATCH v2 4/6] mtd: rawnand: atmel: Use nand_prog_page_end_op() Boris Brezillon
@ 2020-04-29 13:20 ` Boris Brezillon
  2020-04-29 13:20 ` [PATCH v2 6/6] mtd: rawnand: atmel: Get rid of the legacy interface implementation Boris Brezillon
  2020-05-12  8:20 ` [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Tudor.Ambarus
  6 siblings, 0 replies; 16+ messages in thread
From: Boris Brezillon @ 2020-04-29 13:20 UTC (permalink / raw)
  To: Miquel Raynal, linux-mtd, Tudor Ambarus
  Cc: Alexandre Belloni, Vignesh Raghavendra, Richard Weinberger,
	Nicolas Ferre, Ludovic Desroches, Boris Brezillon

Both SMC and HSMC are converted to exec_op().

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
Changes in v2:
* Fix the data-in/out patterns
* Drop all WARN_ON() on things that should be checked by the core
* Split changes to make the diff more readable
* Fix bugs reported by Tudor
* Add Miquel's R-b
---
 drivers/mtd/nand/raw/atmel/nand-controller.c | 263 +++++++++++++++++++
 1 file changed, 263 insertions(+)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 4bd131a34408..107efdfe1a4f 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -202,6 +202,8 @@ struct atmel_nand_controller_ops {
 	int (*ecc_init)(struct nand_chip *chip);
 	int (*setup_data_interface)(struct atmel_nand *nand, int csline,
 				    const struct nand_data_interface *conf);
+	int (*exec_op)(struct atmel_nand *nand,
+		       const struct nand_operation *op, bool check_only);
 };
 
 struct atmel_nand_controller_caps {
@@ -638,6 +640,249 @@ static void atmel_nand_cmd_ctrl(struct nand_chip *chip, int cmd,
 		writeb(cmd, nand->activecs->io.virt + nc->caps->cle_offs);
 }
 
+static void atmel_nand_data_in(struct atmel_nand *nand, void *buf,
+			       unsigned int len, bool force_8bit)
+{
+	struct atmel_nand_controller *nc;
+
+	nc = to_nand_controller(nand->base.controller);
+
+	/*
+	 * If the controller supports DMA, the buffer address is DMA-able and
+	 * len is long enough to make DMA transfers profitable, let's trigger
+	 * a DMA transfer. If it fails, fallback to PIO mode.
+	 */
+	if (nc->dmac && virt_addr_valid(buf) &&
+	    len >= MIN_DMA_LEN && !force_8bit &&
+	    !atmel_nand_dma_transfer(nc, buf, nand->activecs->io.dma, len,
+				     DMA_FROM_DEVICE))
+		return;
+
+	if ((nand->base.options & NAND_BUSWIDTH_16) && !force_8bit)
+		ioread16_rep(nand->activecs->io.virt, buf, len / 2);
+	else
+		ioread8_rep(nand->activecs->io.virt, buf, len);
+}
+
+static void atmel_nand_data_out(struct atmel_nand *nand, const void *buf,
+				unsigned int len, bool force_8bit)
+{
+	struct atmel_nand_controller *nc;
+
+	nc = to_nand_controller(nand->base.controller);
+
+	/*
+	 * If the controller supports DMA, the buffer address is DMA-able and
+	 * len is long enough to make DMA transfers profitable, let's trigger
+	 * a DMA transfer. If it fails, fallback to PIO mode.
+	 */
+	if (nc->dmac && virt_addr_valid(buf) &&
+	    len >= MIN_DMA_LEN && !force_8bit &&
+	    !atmel_nand_dma_transfer(nc, (void *)buf, nand->activecs->io.dma,
+				     len, DMA_TO_DEVICE))
+		return;
+
+	if ((nand->base.options & NAND_BUSWIDTH_16) && !force_8bit)
+		iowrite16_rep(nand->activecs->io.virt, buf, len / 2);
+	else
+		iowrite8_rep(nand->activecs->io.virt, buf, len);
+}
+
+static int atmel_nand_waitrdy(struct atmel_nand *nand, unsigned int timeout_ms)
+{
+	if (nand->activecs->rb.type == ATMEL_NAND_NO_RB)
+		return nand_soft_waitrdy(&nand->base, timeout_ms);
+
+	return nand_gpio_waitrdy(&nand->base, nand->activecs->rb.gpio,
+				 timeout_ms);
+}
+
+static int atmel_hsmc_nand_waitrdy(struct atmel_nand *nand,
+				   unsigned int timeout_ms)
+{
+	struct atmel_hsmc_nand_controller *nc;
+	u32 status, mask;
+
+	if (nand->activecs->rb.type != ATMEL_NAND_NATIVE_RB)
+		return atmel_nand_waitrdy(nand, timeout_ms);
+
+	nc = to_hsmc_nand_controller(nand->base.controller);
+	mask = ATMEL_HSMC_NFC_SR_RBEDGE(nand->activecs->rb.id);
+	return regmap_read_poll_timeout(nc->base.smc, ATMEL_HSMC_NFC_SR,
+					status, status & mask,
+					20, timeout_ms * 1000);
+}
+
+static void atmel_nand_select_target(struct atmel_nand *nand,
+				     unsigned int cs)
+{
+	nand->activecs = &nand->cs[cs];
+}
+
+static void atmel_hsmc_nand_select_target(struct atmel_nand *nand,
+					  unsigned int cs)
+{
+	struct mtd_info *mtd = nand_to_mtd(&nand->base);
+	struct atmel_hsmc_nand_controller *nc;
+
+	nand->activecs = &nand->cs[cs];
+	nc = to_hsmc_nand_controller(nand->base.controller);
+	regmap_update_bits(nc->base.smc, ATMEL_HSMC_NFC_CFG,
+			   ATMEL_HSMC_NFC_CFG_PAGESIZE_MASK |
+			   ATMEL_HSMC_NFC_CFG_SPARESIZE_MASK |
+			   ATMEL_HSMC_NFC_CFG_RSPARE |
+			   ATMEL_HSMC_NFC_CFG_WSPARE,
+			   ATMEL_HSMC_NFC_CFG_PAGESIZE(mtd->writesize) |
+			   ATMEL_HSMC_NFC_CFG_SPARESIZE(mtd->oobsize) |
+			   ATMEL_HSMC_NFC_CFG_RSPARE);
+}
+
+static int atmel_smc_nand_exec_instr(struct atmel_nand *nand,
+				     const struct nand_op_instr *instr)
+{
+	struct atmel_nand_controller *nc;
+	unsigned int i;
+
+	nc = to_nand_controller(nand->base.controller);
+	switch (instr->type) {
+	case NAND_OP_CMD_INSTR:
+		writeb(instr->ctx.cmd.opcode,
+		       nand->activecs->io.virt + nc->caps->cle_offs);
+		return 0;
+	case NAND_OP_ADDR_INSTR:
+		for (i = 0; i < instr->ctx.addr.naddrs; i++)
+			writeb(instr->ctx.addr.addrs[i],
+			       nand->activecs->io.virt + nc->caps->ale_offs);
+		return 0;
+	case NAND_OP_DATA_IN_INSTR:
+		atmel_nand_data_in(nand, instr->ctx.data.buf.in,
+				   instr->ctx.data.len,
+				   instr->ctx.data.force_8bit);
+		return 0;
+	case NAND_OP_DATA_OUT_INSTR:
+		atmel_nand_data_out(nand, instr->ctx.data.buf.out,
+				    instr->ctx.data.len,
+				    instr->ctx.data.force_8bit);
+		return 0;
+	case NAND_OP_WAITRDY_INSTR:
+		return atmel_nand_waitrdy(nand,
+					  instr->ctx.waitrdy.timeout_ms);
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int atmel_smc_nand_exec_op(struct atmel_nand *nand,
+				  const struct nand_operation *op,
+				  bool check_only)
+{
+	struct atmel_nand_controller *nc;
+	unsigned int i;
+	int ret = 0;
+
+	if (check_only)
+		return 0;
+
+	nc = to_nand_controller(nand->base.controller);
+	atmel_nand_select_target(nand, op->cs);
+	gpiod_set_value(nand->activecs->csgpio, 0);
+	for (i = 0; i < op->ninstrs; i++) {
+		ret = atmel_smc_nand_exec_instr(nand, &op->instrs[i]);
+		if (ret)
+			break;
+	}
+	gpiod_set_value(nand->activecs->csgpio, 1);
+
+	return ret;
+}
+
+static int atmel_hsmc_exec_cmd_addr(struct nand_chip *chip,
+				    const struct nand_subop *subop)
+{
+	struct atmel_nand *nand = to_atmel_nand(chip);
+	struct atmel_hsmc_nand_controller *nc;
+	unsigned int i, j;
+
+	nc = to_hsmc_nand_controller(chip->controller);
+
+	nc->op.cs = nand->activecs->id;
+	for (i = 0; i < subop->ninstrs; i++) {
+		const struct nand_op_instr *instr = &subop->instrs[i];
+
+		if (instr->type == NAND_OP_CMD_INSTR) {
+			nc->op.cmds[nc->op.ncmds++] = instr->ctx.cmd.opcode;
+			continue;
+		}
+
+		for (j = nand_subop_get_addr_start_off(subop, i);
+		     j < nand_subop_get_num_addr_cyc(subop, i); j++) {
+			nc->op.addrs[nc->op.naddrs] = instr->ctx.addr.addrs[j];
+			nc->op.naddrs++;
+		}
+	}
+
+	return atmel_nfc_exec_op(nc, true);
+}
+
+static int atmel_hsmc_exec_rw(struct nand_chip *chip,
+			      const struct nand_subop *subop)
+{
+	const struct nand_op_instr *instr = subop->instrs;
+	struct atmel_nand *nand = to_atmel_nand(chip);
+
+	if (instr->type == NAND_OP_DATA_IN_INSTR)
+		atmel_nand_data_in(nand, instr->ctx.data.buf.in,
+				    instr->ctx.data.len,
+				    instr->ctx.data.force_8bit);
+	else
+		atmel_nand_data_out(nand, instr->ctx.data.buf.out,
+				    instr->ctx.data.len,
+				    instr->ctx.data.force_8bit);
+
+	return 0;
+}
+
+static int atmel_hsmc_exec_waitrdy(struct nand_chip *chip,
+				   const struct nand_subop *subop)
+{
+	const struct nand_op_instr *instr = subop->instrs;
+	struct atmel_nand *nand = to_atmel_nand(chip);
+
+	return atmel_hsmc_nand_waitrdy(nand, instr->ctx.waitrdy.timeout_ms);
+}
+
+static const struct nand_op_parser atmel_hsmc_op_parser = NAND_OP_PARSER(
+	NAND_OP_PARSER_PATTERN(atmel_hsmc_exec_cmd_addr,
+		NAND_OP_PARSER_PAT_CMD_ELEM(true),
+		NAND_OP_PARSER_PAT_ADDR_ELEM(true, 5),
+		NAND_OP_PARSER_PAT_CMD_ELEM(true)),
+	NAND_OP_PARSER_PATTERN(atmel_hsmc_exec_rw,
+		NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, 0)),
+	NAND_OP_PARSER_PATTERN(atmel_hsmc_exec_rw,
+		NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, 0)),
+	NAND_OP_PARSER_PATTERN(atmel_hsmc_exec_waitrdy,
+		NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+);
+
+static int atmel_hsmc_nand_exec_op(struct atmel_nand *nand,
+				   const struct nand_operation *op,
+				   bool check_only)
+{
+	int ret;
+
+	if (check_only)
+		return nand_op_parser_exec_op(&nand->base,
+					      &atmel_hsmc_op_parser, op, true);
+
+	atmel_hsmc_nand_select_target(nand, op->cs);
+	ret = nand_op_parser_exec_op(&nand->base, &atmel_hsmc_op_parser, op,
+				     false);
+
+	return ret;
+}
+
 static void atmel_nfc_copy_to_sram(struct nand_chip *chip, const u8 *buf,
 				   bool oob_required)
 {
@@ -904,6 +1149,7 @@ static int atmel_hsmc_nand_pmecc_write_pg(struct nand_chip *chip,
 	struct atmel_hsmc_nand_controller *nc;
 	int ret;
 
+	atmel_hsmc_nand_select_target(nand, chip->cur_cs);
 	nc = to_hsmc_nand_controller(chip->controller);
 
 	atmel_nfc_copy_to_sram(chip, buf, false);
@@ -964,6 +1210,7 @@ static int atmel_hsmc_nand_pmecc_read_pg(struct nand_chip *chip, u8 *buf,
 	struct atmel_hsmc_nand_controller *nc;
 	int ret;
 
+	atmel_hsmc_nand_select_target(nand, chip->cur_cs);
 	nc = to_hsmc_nand_controller(chip->controller);
 
 	/*
@@ -1447,6 +1694,18 @@ static int atmel_nand_setup_data_interface(struct nand_chip *chip, int csline,
 	return nc->caps->ops->setup_data_interface(nand, csline, conf);
 }
 
+static int atmel_nand_exec_op(struct nand_chip *chip,
+			      const struct nand_operation *op,
+			      bool check_only)
+{
+	struct atmel_nand *nand = to_atmel_nand(chip);
+	struct atmel_nand_controller *nc;
+
+	nc = to_nand_controller(nand->base.controller);
+
+	return nc->caps->ops->exec_op(nand, op, check_only);
+}
+
 static void atmel_nand_init(struct atmel_nand_controller *nc,
 			    struct atmel_nand *nand)
 {
@@ -1937,6 +2196,7 @@ static int atmel_nand_attach_chip(struct nand_chip *chip)
 static const struct nand_controller_ops atmel_nand_controller_ops = {
 	.attach_chip = atmel_nand_attach_chip,
 	.setup_data_interface = atmel_nand_setup_data_interface,
+	.exec_op = atmel_nand_exec_op,
 };
 
 static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
@@ -2304,6 +2564,7 @@ static const struct atmel_nand_controller_ops atmel_hsmc_nc_ops = {
 	.ecc_init = atmel_hsmc_nand_ecc_init,
 	.nand_init = atmel_hsmc_nand_init,
 	.setup_data_interface = atmel_hsmc_nand_setup_data_interface,
+	.exec_op = atmel_hsmc_nand_exec_op,
 };
 
 static const struct atmel_nand_controller_caps atmel_sama5_nc_caps = {
@@ -2370,6 +2631,7 @@ static const struct atmel_nand_controller_ops at91rm9200_nc_ops = {
 	.remove = atmel_smc_nand_controller_remove,
 	.ecc_init = atmel_nand_ecc_init,
 	.nand_init = atmel_smc_nand_init,
+	.exec_op = atmel_smc_nand_exec_op,
 };
 
 static const struct atmel_nand_controller_caps atmel_rm9200_nc_caps = {
@@ -2385,6 +2647,7 @@ static const struct atmel_nand_controller_ops atmel_smc_nc_ops = {
 	.ecc_init = atmel_nand_ecc_init,
 	.nand_init = atmel_smc_nand_init,
 	.setup_data_interface = atmel_smc_nand_setup_data_interface,
+	.exec_op = atmel_smc_nand_exec_op,
 };
 
 static const struct atmel_nand_controller_caps atmel_sam9260_nc_caps = {
-- 
2.25.3


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

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

* [PATCH v2 6/6] mtd: rawnand: atmel: Get rid of the legacy interface implementation
  2020-04-29 13:20 [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
                   ` (4 preceding siblings ...)
  2020-04-29 13:20 ` [PATCH v2 5/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
@ 2020-04-29 13:20 ` Boris Brezillon
  2020-05-10 21:32   ` Miquel Raynal
  2020-05-12  8:20 ` [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Tudor.Ambarus
  6 siblings, 1 reply; 16+ messages in thread
From: Boris Brezillon @ 2020-04-29 13:20 UTC (permalink / raw)
  To: Miquel Raynal, linux-mtd, Tudor Ambarus
  Cc: Alexandre Belloni, Vignesh Raghavendra, Richard Weinberger,
	Nicolas Ferre, Ludovic Desroches, Boris Brezillon

Now that exec_op() is implemented, we can get rid of all the legacy
hooks.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
Changes in v2:
* New patch
---
 drivers/mtd/nand/raw/atmel/nand-controller.c | 198 +------------------
 1 file changed, 1 insertion(+), 197 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 107efdfe1a4f..c69f2500c844 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -416,133 +416,6 @@ static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc,
 	return -EIO;
 }
 
-static u8 atmel_nand_read_byte(struct nand_chip *chip)
-{
-	struct atmel_nand *nand = to_atmel_nand(chip);
-
-	return ioread8(nand->activecs->io.virt);
-}
-
-static void atmel_nand_write_byte(struct nand_chip *chip, u8 byte)
-{
-	struct atmel_nand *nand = to_atmel_nand(chip);
-
-	if (chip->options & NAND_BUSWIDTH_16)
-		iowrite16(byte | (byte << 8), nand->activecs->io.virt);
-	else
-		iowrite8(byte, nand->activecs->io.virt);
-}
-
-static void atmel_nand_read_buf(struct nand_chip *chip, u8 *buf, int len)
-{
-	struct atmel_nand *nand = to_atmel_nand(chip);
-	struct atmel_nand_controller *nc;
-
-	nc = to_nand_controller(chip->controller);
-
-	/*
-	 * If the controller supports DMA, the buffer address is DMA-able and
-	 * len is long enough to make DMA transfers profitable, let's trigger
-	 * a DMA transfer. If it fails, fallback to PIO mode.
-	 */
-	if (nc->dmac && virt_addr_valid(buf) &&
-	    len >= MIN_DMA_LEN &&
-	    !atmel_nand_dma_transfer(nc, buf, nand->activecs->io.dma, len,
-				     DMA_FROM_DEVICE))
-		return;
-
-	if (chip->options & NAND_BUSWIDTH_16)
-		ioread16_rep(nand->activecs->io.virt, buf, len / 2);
-	else
-		ioread8_rep(nand->activecs->io.virt, buf, len);
-}
-
-static void atmel_nand_write_buf(struct nand_chip *chip, const u8 *buf, int len)
-{
-	struct atmel_nand *nand = to_atmel_nand(chip);
-	struct atmel_nand_controller *nc;
-
-	nc = to_nand_controller(chip->controller);
-
-	/*
-	 * If the controller supports DMA, the buffer address is DMA-able and
-	 * len is long enough to make DMA transfers profitable, let's trigger
-	 * a DMA transfer. If it fails, fallback to PIO mode.
-	 */
-	if (nc->dmac && virt_addr_valid(buf) &&
-	    len >= MIN_DMA_LEN &&
-	    !atmel_nand_dma_transfer(nc, (void *)buf, nand->activecs->io.dma,
-				     len, DMA_TO_DEVICE))
-		return;
-
-	if (chip->options & NAND_BUSWIDTH_16)
-		iowrite16_rep(nand->activecs->io.virt, buf, len / 2);
-	else
-		iowrite8_rep(nand->activecs->io.virt, buf, len);
-}
-
-static int atmel_nand_dev_ready(struct nand_chip *chip)
-{
-	struct atmel_nand *nand = to_atmel_nand(chip);
-
-	return gpiod_get_value(nand->activecs->rb.gpio);
-}
-
-static void atmel_nand_select_chip(struct nand_chip *chip, int cs)
-{
-	struct atmel_nand *nand = to_atmel_nand(chip);
-
-	if (cs < 0 || cs >= nand->numcs) {
-		nand->activecs = NULL;
-		chip->legacy.dev_ready = NULL;
-		return;
-	}
-
-	nand->activecs = &nand->cs[cs];
-
-	if (nand->activecs->rb.type == ATMEL_NAND_GPIO_RB)
-		chip->legacy.dev_ready = atmel_nand_dev_ready;
-}
-
-static int atmel_hsmc_nand_dev_ready(struct nand_chip *chip)
-{
-	struct atmel_nand *nand = to_atmel_nand(chip);
-	struct atmel_hsmc_nand_controller *nc;
-	u32 status;
-
-	nc = to_hsmc_nand_controller(chip->controller);
-
-	regmap_read(nc->base.smc, ATMEL_HSMC_NFC_SR, &status);
-
-	return status & ATMEL_HSMC_NFC_SR_RBEDGE(nand->activecs->rb.id);
-}
-
-static void atmel_hsmc_nand_select_chip(struct nand_chip *chip, int cs)
-{
-	struct mtd_info *mtd = nand_to_mtd(chip);
-	struct atmel_nand *nand = to_atmel_nand(chip);
-	struct atmel_hsmc_nand_controller *nc;
-
-	nc = to_hsmc_nand_controller(chip->controller);
-
-	atmel_nand_select_chip(chip, cs);
-
-	if (!nand->activecs)
-		return;
-
-	if (nand->activecs->rb.type == ATMEL_NAND_NATIVE_RB)
-		chip->legacy.dev_ready = atmel_hsmc_nand_dev_ready;
-
-	regmap_update_bits(nc->base.smc, ATMEL_HSMC_NFC_CFG,
-			   ATMEL_HSMC_NFC_CFG_PAGESIZE_MASK |
-			   ATMEL_HSMC_NFC_CFG_SPARESIZE_MASK |
-			   ATMEL_HSMC_NFC_CFG_RSPARE |
-			   ATMEL_HSMC_NFC_CFG_WSPARE,
-			   ATMEL_HSMC_NFC_CFG_PAGESIZE(mtd->writesize) |
-			   ATMEL_HSMC_NFC_CFG_SPARESIZE(mtd->oobsize) |
-			   ATMEL_HSMC_NFC_CFG_RSPARE);
-}
-
 static int atmel_nfc_exec_op(struct atmel_hsmc_nand_controller *nc, bool poll)
 {
 	u8 *addrs = nc->op.addrs;
@@ -593,53 +466,6 @@ static int atmel_nfc_exec_op(struct atmel_hsmc_nand_controller *nc, bool poll)
 	return ret;
 }
 
-static void atmel_hsmc_nand_cmd_ctrl(struct nand_chip *chip, int dat,
-				     unsigned int ctrl)
-{
-	struct atmel_nand *nand = to_atmel_nand(chip);
-	struct atmel_hsmc_nand_controller *nc;
-
-	nc = to_hsmc_nand_controller(chip->controller);
-
-	if (ctrl & NAND_ALE) {
-		if (nc->op.naddrs == ATMEL_NFC_MAX_ADDR_CYCLES)
-			return;
-
-		nc->op.addrs[nc->op.naddrs++] = dat;
-	} else if (ctrl & NAND_CLE) {
-		if (nc->op.ncmds > 1)
-			return;
-
-		nc->op.cmds[nc->op.ncmds++] = dat;
-	}
-
-	if (dat == NAND_CMD_NONE) {
-		nc->op.cs = nand->activecs->id;
-		atmel_nfc_exec_op(nc, true);
-	}
-}
-
-static void atmel_nand_cmd_ctrl(struct nand_chip *chip, int cmd,
-				unsigned int ctrl)
-{
-	struct atmel_nand *nand = to_atmel_nand(chip);
-	struct atmel_nand_controller *nc;
-
-	nc = to_nand_controller(chip->controller);
-
-	if ((ctrl & NAND_CTRL_CHANGE) && nand->activecs->csgpio) {
-		if (ctrl & NAND_NCE)
-			gpiod_set_value(nand->activecs->csgpio, 0);
-		else
-			gpiod_set_value(nand->activecs->csgpio, 1);
-	}
-
-	if (ctrl & NAND_ALE)
-		writeb(cmd, nand->activecs->io.virt + nc->caps->ale_offs);
-	else if (ctrl & NAND_CLE)
-		writeb(cmd, nand->activecs->io.virt + nc->caps->cle_offs);
-}
-
 static void atmel_nand_data_in(struct atmel_nand *nand, void *buf,
 			       unsigned int len, bool force_8bit)
 {
@@ -1715,19 +1541,9 @@ static void atmel_nand_init(struct atmel_nand_controller *nc,
 	mtd->dev.parent = nc->dev;
 	nand->base.controller = &nc->base;
 
-	chip->legacy.cmd_ctrl = atmel_nand_cmd_ctrl;
-	chip->legacy.read_byte = atmel_nand_read_byte;
-	chip->legacy.write_byte = atmel_nand_write_byte;
-	chip->legacy.read_buf = atmel_nand_read_buf;
-	chip->legacy.write_buf = atmel_nand_write_buf;
-	chip->legacy.select_chip = atmel_nand_select_chip;
-
 	if (!nc->mck || !nc->caps->ops->setup_data_interface)
 		chip->options |= NAND_KEEP_TIMINGS;
 
-	/* Some NANDs require a longer delay than the default one (20us). */
-	chip->legacy.chip_delay = 40;
-
 	/*
 	 * Use a bounce buffer when the buffer passed by the MTD user is not
 	 * suitable for DMA.
@@ -1766,18 +1582,6 @@ static void atmel_smc_nand_init(struct atmel_nand_controller *nc,
 				   smc_nc->ebi_csa->nfd0_on_d16);
 }
 
-static void atmel_hsmc_nand_init(struct atmel_nand_controller *nc,
-				 struct atmel_nand *nand)
-{
-	struct nand_chip *chip = &nand->base;
-
-	atmel_nand_init(nc, nand);
-
-	/* Overload some methods for the HSMC controller. */
-	chip->legacy.cmd_ctrl = atmel_hsmc_nand_cmd_ctrl;
-	chip->legacy.select_chip = atmel_hsmc_nand_select_chip;
-}
-
 static int atmel_nand_controller_remove_nand(struct atmel_nand *nand)
 {
 	struct nand_chip *chip = &nand->base;
@@ -2562,7 +2366,7 @@ static const struct atmel_nand_controller_ops atmel_hsmc_nc_ops = {
 	.probe = atmel_hsmc_nand_controller_probe,
 	.remove = atmel_hsmc_nand_controller_remove,
 	.ecc_init = atmel_hsmc_nand_ecc_init,
-	.nand_init = atmel_hsmc_nand_init,
+	.nand_init = atmel_nand_init,
 	.setup_data_interface = atmel_hsmc_nand_setup_data_interface,
 	.exec_op = atmel_hsmc_nand_exec_op,
 };
-- 
2.25.3


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

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

* Re: [PATCH v2 1/6] mtd: rawnand: atmel: Enable the NFC controller at probe time
  2020-04-29 13:20 ` [PATCH v2 1/6] mtd: rawnand: atmel: Enable the NFC controller at probe time Boris Brezillon
@ 2020-05-10 21:25   ` Miquel Raynal
  2020-05-12 13:00   ` Tudor.Ambarus
  1 sibling, 0 replies; 16+ messages in thread
From: Miquel Raynal @ 2020-05-10 21:25 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Alexandre Belloni, Vignesh Raghavendra, Tudor Ambarus,
	Richard Weinberger, Nicolas Ferre, Ludovic Desroches, linux-mtd

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Wed, 29 Apr
2020 15:20:41 +0200:

> No need to enable it everytime select_chip() is called. If we really
> care about PM, we should implement runtime PM hooks and disable the
> controller and all its clocks when the controller has been unused for
> some time.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>

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

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

* Re: [PATCH v2 2/6] mtd: rawnand: atmel: Drop redundant nand_read_page_op()
  2020-04-29 13:20 ` [PATCH v2 2/6] mtd: rawnand: atmel: Drop redundant nand_read_page_op() Boris Brezillon
@ 2020-05-10 21:26   ` Miquel Raynal
  2020-05-12 13:06   ` Tudor.Ambarus
  1 sibling, 0 replies; 16+ messages in thread
From: Miquel Raynal @ 2020-05-10 21:26 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Alexandre Belloni, Vignesh Raghavendra, Tudor Ambarus,
	Richard Weinberger, Nicolas Ferre, Ludovic Desroches, linux-mtd

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Wed, 29 Apr
2020 15:20:42 +0200:

> The legacy page read path in atmel_hsmc_nand_pmecc_read_pg() issues
> a nand_read_page_op() that's already issued by
> atmel_nand_pmecc_read_pg(). Let's get rid of the unneeded one.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
> Changes in v2:
> * New patch

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>

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

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

* Re: [PATCH v2 3/6] mtd: rawnand: atmel: Use nand_{write,read}_data_op()
  2020-04-29 13:20 ` [PATCH v2 3/6] mtd: rawnand: atmel: Use nand_{write,read}_data_op() Boris Brezillon
@ 2020-05-10 21:28   ` Miquel Raynal
  2020-05-12 13:10   ` Tudor.Ambarus
  1 sibling, 0 replies; 16+ messages in thread
From: Miquel Raynal @ 2020-05-10 21:28 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Alexandre Belloni, Vignesh Raghavendra, Tudor Ambarus,
	Richard Weinberger, Nicolas Ferre, Ludovic Desroches, linux-mtd

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Wed, 29 Apr
2020 15:20:43 +0200:

> Use the nand_{write,read}_data_op() helpers instead of calling the
> atmel_nand_{read,write}_buf() functions directly. This will ease the
> transition to exec_op().
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>

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

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

* Re: [PATCH v2 4/6] mtd: rawnand: atmel: Use nand_prog_page_end_op()
  2020-04-29 13:20 ` [PATCH v2 4/6] mtd: rawnand: atmel: Use nand_prog_page_end_op() Boris Brezillon
@ 2020-05-10 21:30   ` Miquel Raynal
  0 siblings, 0 replies; 16+ messages in thread
From: Miquel Raynal @ 2020-05-10 21:30 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Alexandre Belloni, Vignesh Raghavendra, Tudor Ambarus,
	Richard Weinberger, Nicolas Ferre, Ludovic Desroches, linux-mtd


Boris Brezillon <boris.brezillon@collabora.com> wrote on Wed, 29 Apr
2020 15:20:44 +0200:

> The nand_prog_page_end_op() sequence is open-coded in
> atmel_hsmc_nand_pmecc_write_pg(). Let's use the generic helper here.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>


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

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

* Re: [PATCH v2 6/6] mtd: rawnand: atmel: Get rid of the legacy interface implementation
  2020-04-29 13:20 ` [PATCH v2 6/6] mtd: rawnand: atmel: Get rid of the legacy interface implementation Boris Brezillon
@ 2020-05-10 21:32   ` Miquel Raynal
  0 siblings, 0 replies; 16+ messages in thread
From: Miquel Raynal @ 2020-05-10 21:32 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Alexandre Belloni, Vignesh Raghavendra, Tudor Ambarus,
	Richard Weinberger, Nicolas Ferre, Ludovic Desroches, linux-mtd


Boris Brezillon <boris.brezillon@collabora.com> wrote on Wed, 29 Apr
2020 15:20:46 +0200:

> Now that exec_op() is implemented, we can get rid of all the legacy
> hooks.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>

Thanks for the conversion, hopefully someone will test it, otherwise
I'll take it in next soon.

Thanks,
Miquèl

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

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

* Re: [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op()
  2020-04-29 13:20 [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
                   ` (5 preceding siblings ...)
  2020-04-29 13:20 ` [PATCH v2 6/6] mtd: rawnand: atmel: Get rid of the legacy interface implementation Boris Brezillon
@ 2020-05-12  8:20 ` Tudor.Ambarus
  6 siblings, 0 replies; 16+ messages in thread
From: Tudor.Ambarus @ 2020-05-12  8:20 UTC (permalink / raw)
  To: boris.brezillon
  Cc: alexandre.belloni, vigneshr, richard, Nicolas.Ferre,
	Ludovic.Desroches, linux-mtd, miquel.raynal

Hi, Boris,

On Wednesday, April 29, 2020 4:20:40 PM EEST Boris Brezillon wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
> content is safe
> 
> Hello,
> 
> This v2 splits changes to make the diff more readable and fixes a bug
> reported by Tudor (thanks for testing/helping me debug the issue BTW).
> Note that the patch propagating the CS information to sub operations
> has been dropped since the new version no longer depends on it, but
> will be posted as part of another series where it's needed (the
> cafe_nand conversion).
> 
> Regards,
> 
> Boris
> 
> Boris Brezillon (6):
>   mtd: rawnand: atmel: Enable the NFC controller at probe time
>   mtd: rawnand: atmel: Drop redundant nand_read_page_op()
>   mtd: rawnand: atmel: Use nand_{write,read}_data_op()
>   mtd: rawnand: atmel: Use nand_prog_page_end_op()
>   mtd: rawnand: atmel: Convert the driver to exec_op()
>   mtd: rawnand: atmel: Get rid of the legacy interface implementation
> 
>  drivers/mtd/nand/raw/atmel/nand-controller.c | 464 +++++++++++--------
>  1 file changed, 258 insertions(+), 206 deletions(-)
> 
> --

I got a -ETIMEOUT when trying to write to the NAND flash on sam9x60eK
# nandwrite /dev/mtd11 1M
Writing data to block 0 at offset 0x0
libmtd: error!: cannot write 4096 bytes to mtd11 (eraseblock 0, offset 176128)
        error 110 (Connection timed out)
nandwrite: error!: /dev/mtd11: MTD write failure
           error 110 (Connection timed out)
nandwrite: error!: Data was only partially written due to error
           error 110 (Connection timed out)

On sama5d4_xplained I did the following tests:
1/ check erase, write, read: OK
flash_erase /dev/mtd5 0 4
dd if=/dev/urandom of=1M bs=1M count=1
nandwrite /dev/mtd5 1M
mtd_debug read /dev/mtd5 0 1048576 read
sha1sum read 1M

2/ mtd_speedtest: sama5d4_xplained: 10% write speed drop
before:
mtd_speedtest: eraseblock write speed is 6468 KiB/s
mtd_speedtest: testing eraseblock read speed
mtd_speedtest: eraseblock read speed is 10330 KiB/s

after:
mtd_speedtest: eraseblock write speed is 5728 KiB/s
mtd_speedtest: testing eraseblock read speed
mtd_speedtest: eraseblock read speed is 10261 KiB/s

3/ rootfs on NAND. I could read/write reliably from the flash. Rebooted the 
platform and checked that no corruptions happened after write accesses.

Cheers,
ta



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

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

* Re: [PATCH v2 1/6] mtd: rawnand: atmel: Enable the NFC controller at probe time
  2020-04-29 13:20 ` [PATCH v2 1/6] mtd: rawnand: atmel: Enable the NFC controller at probe time Boris Brezillon
  2020-05-10 21:25   ` Miquel Raynal
@ 2020-05-12 13:00   ` Tudor.Ambarus
  1 sibling, 0 replies; 16+ messages in thread
From: Tudor.Ambarus @ 2020-05-12 13:00 UTC (permalink / raw)
  To: boris.brezillon
  Cc: alexandre.belloni, vigneshr, richard, Nicolas.Ferre,
	Ludovic.Desroches, linux-mtd, miquel.raynal

On Wednesday, April 29, 2020 4:20:41 PM EEST Boris Brezillon wrote:
> No need to enable it everytime select_chip() is called. If we really
> care about PM, we should implement runtime PM hooks and disable the
> controller and all its clocks when the controller has been unused for
> some time.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
> Changes in v2:
> * New patch
> ---
>  drivers/mtd/nand/raw/atmel/nand-controller.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


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

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

* Re: [PATCH v2 2/6] mtd: rawnand: atmel: Drop redundant nand_read_page_op()
  2020-04-29 13:20 ` [PATCH v2 2/6] mtd: rawnand: atmel: Drop redundant nand_read_page_op() Boris Brezillon
  2020-05-10 21:26   ` Miquel Raynal
@ 2020-05-12 13:06   ` Tudor.Ambarus
  1 sibling, 0 replies; 16+ messages in thread
From: Tudor.Ambarus @ 2020-05-12 13:06 UTC (permalink / raw)
  To: boris.brezillon
  Cc: alexandre.belloni, vigneshr, richard, Nicolas.Ferre,
	Ludovic.Desroches, linux-mtd, miquel.raynal

On Wednesday, April 29, 2020 4:20:42 PM EEST Boris Brezillon wrote:
> The legacy page read path in atmel_hsmc_nand_pmecc_read_pg() issues
> a nand_read_page_op() that's already issued by
> atmel_nand_pmecc_read_pg(). Let's get rid of the unneeded one.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
> Changes in v2:
> * New patch
> ---
>  drivers/mtd/nand/raw/atmel/nand-controller.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


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

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

* Re: [PATCH v2 3/6] mtd: rawnand: atmel: Use nand_{write,read}_data_op()
  2020-04-29 13:20 ` [PATCH v2 3/6] mtd: rawnand: atmel: Use nand_{write,read}_data_op() Boris Brezillon
  2020-05-10 21:28   ` Miquel Raynal
@ 2020-05-12 13:10   ` Tudor.Ambarus
  1 sibling, 0 replies; 16+ messages in thread
From: Tudor.Ambarus @ 2020-05-12 13:10 UTC (permalink / raw)
  To: boris.brezillon
  Cc: alexandre.belloni, vigneshr, richard, Nicolas.Ferre,
	Ludovic.Desroches, linux-mtd, miquel.raynal

On Wednesday, April 29, 2020 4:20:43 PM EEST Boris Brezillon wrote:
> Use the nand_{write,read}_data_op() helpers instead of calling the
> atmel_nand_{read,write}_buf() functions directly. This will ease the
> transition to exec_op().
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
> Changes in v2:
> * New patch
> ---
>  drivers/mtd/nand/raw/atmel/nand-controller.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


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

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

end of thread, other threads:[~2020-05-12 13:10 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-29 13:20 [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
2020-04-29 13:20 ` [PATCH v2 1/6] mtd: rawnand: atmel: Enable the NFC controller at probe time Boris Brezillon
2020-05-10 21:25   ` Miquel Raynal
2020-05-12 13:00   ` Tudor.Ambarus
2020-04-29 13:20 ` [PATCH v2 2/6] mtd: rawnand: atmel: Drop redundant nand_read_page_op() Boris Brezillon
2020-05-10 21:26   ` Miquel Raynal
2020-05-12 13:06   ` Tudor.Ambarus
2020-04-29 13:20 ` [PATCH v2 3/6] mtd: rawnand: atmel: Use nand_{write,read}_data_op() Boris Brezillon
2020-05-10 21:28   ` Miquel Raynal
2020-05-12 13:10   ` Tudor.Ambarus
2020-04-29 13:20 ` [PATCH v2 4/6] mtd: rawnand: atmel: Use nand_prog_page_end_op() Boris Brezillon
2020-05-10 21:30   ` Miquel Raynal
2020-04-29 13:20 ` [PATCH v2 5/6] mtd: rawnand: atmel: Convert the driver to exec_op() Boris Brezillon
2020-04-29 13:20 ` [PATCH v2 6/6] mtd: rawnand: atmel: Get rid of the legacy interface implementation Boris Brezillon
2020-05-10 21:32   ` Miquel Raynal
2020-05-12  8:20 ` [PATCH v2 0/6] mtd: rawnand: atmel: Convert the driver to exec_op() Tudor.Ambarus

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.