All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more)
@ 2020-04-27  8:20 Boris Brezillon
  2020-04-27  8:20 ` [PATCH 01/17] mtd: rawnand: cafe: Get rid of an inaccurate kernel doc header Boris Brezillon
                   ` (19 more replies)
  0 siblings, 20 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Hello,

A bit of context to explain the motivation behind those conversions
I've been sending for the last couple of weeks. The raw NAND subsystem
carries a lot of history which makes any rework not only painful, but
also subject to regressions which we only detect when someone dares to
update its kernel on one of those ancient HW. While carrying drivers
for old HW is not a problem per se, carrying ancient and unmaintained
drivers that are not converted to new APIs is a maintenance burden,
hence this massive conversion attempt I'm conducting here.

So here it is, a series converting the CAFE NAND controller driver to
exec_op(), plus a bunch of minor improvements done along the way.
I hope I'll find someone to test those changes, but if there's no one
still owning OLPC HW or no interest in keeping it supported in recent
kernel versions, we should definitely consider removing the driver
instead.

Regards,

Boris

Boris Brezillon (17):
  mtd: rawnand: cafe: Get rid of an inaccurate kernel doc header
  mtd: rawnand: cafe: Rename cafe_nand_write_page_lowlevel()
  mtd: rawnand: cafe: Use a correct ECC mode and pass the ECC alg
  mtd: rawnand: cafe: Include linux/io.h instead of asm/io.h
  mtd: rawnand: cafe: Demistify register fields
  mtd: rawnand: cafe: Factor out the controller initialization logic
  mtd: rawnand: cafe: Get rid of the debug module param
  mtd: rawnand: cafe: Use devm_kzalloc and devm_request_irq()
  mtd: rawnand: cafe: Get rid of a useless label
  mtd: rawnand: cafe: Explicitly inherit from nand_controller
  mtd: rawnand: cafe: Don't leave ECC enabled in the write path
  mtd: rawnand: cafe: Don't split things when reading/writing a page
  mtd: rawnand: cafe: Add exec_op() support
  mtd: rawnand: cafe: Get rid of the legacy interface implementation
  mtd: rawnand: cafe: Adjust the cafe_{read,write}_buf() prototypes
  mtd: rawnand: cafe: Handle non-32bit aligned reads/writes
  mtd: rawnand: cafe: s/uint{8,16,32}_t/u{8,16,32}/

 drivers/mtd/nand/raw/cafe_nand.c | 805 ++++++++++++++++---------------
 1 file changed, 423 insertions(+), 382 deletions(-)

-- 
2.25.3


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

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

* [PATCH 01/17] mtd: rawnand: cafe: Get rid of an inaccurate kernel doc header
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:33   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 02/17] mtd: rawnand: cafe: Rename cafe_nand_write_page_lowlevel() Boris Brezillon
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Driver files are not parsed for doc generation, and the
cafe_nand_read_page() kernel-doc header was wrong, so let's get rid of
it.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 2a0df13df5f3..1296380a4996 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -357,13 +357,8 @@ static int cafe_nand_read_oob(struct nand_chip *chip, int page)
 
 	return nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
 }
-/**
- * cafe_nand_read_page_syndrome - [REPLACEABLE] hardware ecc syndrome based page read
- * @mtd:	mtd info structure
- * @chip:	nand chip info structure
- * @buf:	buffer to store read data
- * @oob_required:	caller expects OOB data read to chip->oob_poi
- *
+
+/*
  * The hw generator calculates the error syndrome automatically. Therefore
  * we need a special oob layout and handling.
  */
-- 
2.25.3


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

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

* [PATCH 02/17] mtd: rawnand: cafe: Rename cafe_nand_write_page_lowlevel()
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
  2020-04-27  8:20 ` [PATCH 01/17] mtd: rawnand: cafe: Get rid of an inaccurate kernel doc header Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:33   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 03/17] mtd: rawnand: cafe: Use a correct ECC mode and pass the ECC alg Boris Brezillon
                   ` (17 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Let's rename that one cafe_nand_write_page() to be consistent with other
function names.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 1296380a4996..03964e092243 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -525,9 +525,9 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
 };
 
 
-static int cafe_nand_write_page_lowlevel(struct nand_chip *chip,
-					 const uint8_t *buf, int oob_required,
-					 int page)
+static int cafe_nand_write_page(struct nand_chip *chip,
+				const uint8_t *buf, int oob_required,
+				int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
@@ -628,7 +628,7 @@ static int cafe_nand_attach_chip(struct nand_chip *chip)
 	cafe->nand.ecc.size = mtd->writesize;
 	cafe->nand.ecc.bytes = 14;
 	cafe->nand.ecc.strength = 4;
-	cafe->nand.ecc.write_page = cafe_nand_write_page_lowlevel;
+	cafe->nand.ecc.write_page = cafe_nand_write_page;
 	cafe->nand.ecc.write_oob = cafe_nand_write_oob;
 	cafe->nand.ecc.read_page = cafe_nand_read_page;
 	cafe->nand.ecc.read_oob = cafe_nand_read_oob;
-- 
2.25.3


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

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

* [PATCH 03/17] mtd: rawnand: cafe: Use a correct ECC mode and pass the ECC alg
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
  2020-04-27  8:20 ` [PATCH 01/17] mtd: rawnand: cafe: Get rid of an inaccurate kernel doc header Boris Brezillon
  2020-04-27  8:20 ` [PATCH 02/17] mtd: rawnand: cafe: Rename cafe_nand_write_page_lowlevel() Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:34   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 04/17] mtd: rawnand: cafe: Include linux/io.h instead of asm/io.h Boris Brezillon
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

The NAND_ECC_HW_SYNDROME name is a bit misleading. It's actually used
for drivers that interleave data and ECC bytes inside a page, which is
not the case here. Let's fix that and pass the ECC algorithm used by the
ECC engine.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 03964e092243..47aacfab8ecb 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -624,7 +624,8 @@ static int cafe_nand_attach_chip(struct nand_chip *chip)
 		goto out_free_dma;
 	}
 
-	cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
+	cafe->nand.ecc.mode = NAND_ECC_HW;
+	cafe->nand.ecc.algo = NAND_ECC_RS;
 	cafe->nand.ecc.size = mtd->writesize;
 	cafe->nand.ecc.bytes = 14;
 	cafe->nand.ecc.strength = 4;
-- 
2.25.3


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

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

* [PATCH 04/17] mtd: rawnand: cafe: Include linux/io.h instead of asm/io.h
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (2 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 03/17] mtd: rawnand: cafe: Use a correct ECC mode and pass the ECC alg Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:35   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 05/17] mtd: rawnand: cafe: Demistify register fields Boris Brezillon
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Drivers should include the asm headers directly.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 47aacfab8ecb..156a308b530b 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -23,7 +23,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define CAFE_NAND_CTRL1		0x00
 #define CAFE_NAND_CTRL2		0x04
-- 
2.25.3


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

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

* [PATCH 05/17] mtd: rawnand: cafe: Demistify register fields
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (3 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 04/17] mtd: rawnand: cafe: Include linux/io.h instead of asm/io.h Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:42   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 06/17] mtd: rawnand: cafe: Factor out the controller initialization logic Boris Brezillon
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

The driver has a bunch of magic values. Let's define proper register
fields based on the this spec
http://wiki.laptop.org/images/5/5c/88ALP01_Datasheet_July_2007.pdf and
use them.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 351 ++++++++++++++++++++++++-------
 1 file changed, 270 insertions(+), 81 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 156a308b530b..fbc18bc3d46b 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -9,6 +9,7 @@
  * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
  */
 
+#include <linux/bitfield.h>
 #define DEBUG
 
 #include <linux/device.h>
@@ -25,37 +26,127 @@
 #include <linux/module.h>
 #include <linux/io.h>
 
-#define CAFE_NAND_CTRL1		0x00
-#define CAFE_NAND_CTRL2		0x04
-#define CAFE_NAND_CTRL3		0x08
-#define CAFE_NAND_STATUS	0x0c
-#define CAFE_NAND_IRQ		0x10
-#define CAFE_NAND_IRQ_MASK	0x14
-#define CAFE_NAND_DATA_LEN	0x18
-#define CAFE_NAND_ADDR1		0x1c
-#define CAFE_NAND_ADDR2		0x20
-#define CAFE_NAND_TIMING1	0x24
-#define CAFE_NAND_TIMING2	0x28
-#define CAFE_NAND_TIMING3	0x2c
-#define CAFE_NAND_NONMEM	0x30
-#define CAFE_NAND_ECC_RESULT	0x3C
-#define CAFE_NAND_DMA_CTRL	0x40
-#define CAFE_NAND_DMA_ADDR0	0x44
-#define CAFE_NAND_DMA_ADDR1	0x48
-#define CAFE_NAND_ECC_SYN01	0x50
-#define CAFE_NAND_ECC_SYN23	0x54
-#define CAFE_NAND_ECC_SYN45	0x58
-#define CAFE_NAND_ECC_SYN67	0x5c
-#define CAFE_NAND_READ_DATA	0x1000
-#define CAFE_NAND_WRITE_DATA	0x2000
+#define CAFE_NAND_CTRL1				0x00
+#define CAFE_NAND_CTRL1_HAS_CMD			BIT(31)
+#define CAFE_NAND_CTRL1_HAS_ADDR		BIT(30)
+#define CAFE_NAND_CTRL1_NUM_ADDR_CYC		GENMASK(29, 27)
+#define CAFE_NAND_CTRL1_HAS_DATA_IN		BIT(26)
+#define CAFE_NAND_CTRL1_HAS_DATA_OUT		BIT(25)
+#define CAFE_NAND_CTRL1_NUM_NONMEM_READ_HIGH	GENMASK(24, 22)
+#define CAFE_NAND_CTRL1_WAIT_BSY_AFTER_SEQ	BIT(21)
+#define CAFE_NAND_CTRL1_NUM_NONMEM_READ_LOW	BIT(20)
+#define CAFE_NAND_CTRL1_CE			BIT(19)
+#define CAFE_NAND_CTRL1_CMD			GENMASK(7, 0)
 
-#define CAFE_GLOBAL_CTRL	0x3004
-#define CAFE_GLOBAL_IRQ		0x3008
-#define CAFE_GLOBAL_IRQ_MASK	0x300c
-#define CAFE_NAND_RESET		0x3034
+#define CAFE_NAND_CTRL2				0x04
+#define CAFE_NAND_CTRL2_AUTO_WRITE_ECC		BIT(30)
+#define CAFE_NAND_CTRL2_PAGE_SIZE		GENMASK(29, 28)
+#define CAFE_NAND_CTRL2_ECC_ALG_RS		BIT(27)
+#define CAFE_NAND_CTRL2_HAS_CMD2		BIT(8)
+#define CAFE_NAND_CTRL2_CMD2			GENMASK(7, 0)
 
-/* Missing from the datasheet: bit 19 of CTRL1 sets CE0 vs. CE1 */
-#define CTRL1_CHIPSELECT	(1<<19)
+#define CAFE_NAND_CTRL3				0x08
+#define CAFE_NAND_CTRL3_READ_BUSY_RESET		BIT(31)
+#define CAFE_NAND_CTRL3_WP			BIT(30)
+
+#define CAFE_NAND_STATUS			0x0c
+#define CAFE_NAND_STATUS_CONTROLLER_BUSY	BIT(31)
+#define CAFE_NAND_STATUS_FLASH_BUSY		BIT(30)
+
+#define CAFE_NAND_IRQ				0x10
+#define CAFE_NAND_IRQ_MASK			0x14
+#define CAFE_NAND_IRQ_CMD_DONE			BIT(31)
+#define CAFE_NAND_IRQ_FLASH_RDY			BIT(30)
+#define CAFE_NAND_IRQ_DMA_DONE			BIT(28)
+#define CAFE_NAND_IRQ_BOOT_DONE			BIT(27)
+
+#define CAFE_NAND_DATA_LEN			0x18
+#define CAFE_NAND_ADDR1				0x1c
+#define CAFE_NAND_ADDR2				0x20
+
+#define CAFE_NAND_TIMING1			0x24
+#define CAFE_NAND_TIMING1_TCLS			GENMASK(31, 28)
+#define CAFE_NAND_TIMING1_TCLH			GENMASK(27, 24)
+#define CAFE_NAND_TIMING1_TALS			GENMASK(23, 20)
+#define CAFE_NAND_TIMING1_TALH			GENMASK(19, 16)
+#define CAFE_NAND_TIMING1_TWB			GENMASK(15, 8)
+#define CAFE_NAND_TIMING1_TRB			GENMASK(7, 0)
+
+#define CAFE_NAND_TIMING2			0x28
+#define CAFE_NAND_TIMING2_TRR			GENMASK(31, 28)
+#define CAFE_NAND_TIMING2_TREA			GENMASK(27, 24)
+#define CAFE_NAND_TIMING2_TDH			GENMASK(23, 20)
+#define CAFE_NAND_TIMING2_TDS			GENMASK(19, 16)
+#define CAFE_NAND_TIMING2_TRH			GENMASK(15, 12)
+#define CAFE_NAND_TIMING2_TRP			GENMASK(11, 8)
+#define CAFE_NAND_TIMING2_TWH			GENMASK(7, 4)
+#define CAFE_NAND_TIMING2_TWP			GENMASK(3, 0)
+
+#define CAFE_NAND_TIMING3			0x2c
+#define CAFE_NAND_TIMING3_TAR			GENMASK(31, 28)
+#define CAFE_NAND_TIMING3_TCLR			GENMASK(27, 24)
+
+#define CAFE_NAND_NONMEM_READ_DATA		0x30
+#define CAFE_NAND_ECC_READ_CODE			0x38
+
+#define CAFE_NAND_ECC_RESULT			0x3C
+#define CAFE_NAND_ECC_RESULT_RS_ERRORS		BIT(18)
+#define CAFE_NAND_ECC_RESULT_STATUS		GENMASK(17, 16)
+#define CAFE_NAND_ECC_RESULT_NO_ERROR		(0 << 16)
+#define CAFE_NAND_ECC_RESULT_CORRECTABLE_ERRS	(1 << 16)
+#define CAFE_NAND_ECC_RESULT_UNCORRECTABLE_ERRS	(2 << 16)
+#define CAFE_NAND_ECC_RESULT_FAIL_BIT_LOC	GENMASK(13, 0)
+
+#define CAFE_NAND_DMA_CTRL			0x40
+#define CAFE_NAND_DMA_CTRL_ENABLE		BIT(31)
+#define CAFE_NAND_DMA_CTRL_RESERVED		BIT(30)
+#define CAFE_NAND_DMA_CTRL_DATA_IN		BIT(29)
+#define CAFE_NAND_DMA_CTRL_DATA_LEN		GENMASK(11, 0)
+
+#define CAFE_NAND_DMA_ADDR0			0x44
+#define CAFE_NAND_DMA_ADDR1			0x48
+#define CAFE_NAND_ECC_SYN_REG(x)		(((x) / 2) + 0x50)
+#define CAFE_NAND_ECC_SYN_FIELD(x)		(((x) % 2) ? GENMASK(31, 16) : GENMASK(15, 0))
+
+#define CAFE_NAND_CTRL4				0x60
+#define CAFE_NAND_CTRL4_NO_READ_DELAY		BIT(8)
+
+#define CAFE_NAND_DRIVE_STRENGTH		0x64
+#define CAFE_NAND_DRIVE_STRENGTH_VAL		GENMASK(4, 0)
+
+#define CAFE_NAND_READ_DATA			0x1000
+#define CAFE_NAND_WRITE_DATA			0x2000
+
+#define CAFE_GLOBAL_CTRL			0x3004
+#define CAFE_GLOBAL_CCIC_CLK_ENABLE		BIT(14)
+#define CAFE_GLOBAL_SDH_CLK_ENABLE		BIT(13)
+#define CAFE_GLOBAL_NAND_CLK_ENABLE		BIT(12)
+#define CAFE_GLOBAL_CLKRUN_ENABLE_SET		BIT(11)
+#define CAFE_GLOBAL_CLKRUN_ENABLE_CLEAR		BIT(10)
+#define CAFE_GLOBAL_SW_IRQ_SET			BIT(7)
+#define CAFE_GLOBAL_SW_IRQ_CLEAR		BIT(6)
+#define CAFE_GLOBAL_STOP_MASTER_DONE		BIT(5)
+#define CAFE_GLOBAL_STOP_MASTER			BIT(4)
+#define CAFE_GLOBAL_MASTER_RESET_CLEAR		BIT(3)
+#define CAFE_GLOBAL_MASTER_RESET_SET		BIT(2)
+#define CAFE_GLOBAL_SW_RESET_CLEAR		BIT(1)
+#define CAFE_GLOBAL_SW_RESET_SET		BIT(0)
+
+#define CAFE_GLOBAL_IRQ				0x3008
+#define CAFE_GLOBAL_IRQ_MASK			0x300c
+#define CAFE_GLOBAL_IRQ_PCI_ERROR		BIT(31)
+#define CAFE_GLOBAL_IRQ_VPD_TWSI		BIT(26)
+#define CAFE_GLOBAL_IRQ_CCIC			BIT(2)
+#define CAFE_GLOBAL_IRQ_SDH			BIT(1)
+#define CAFE_GLOBAL_IRQ_NAND			BIT(0)
+
+#define CAFE_GLOBAL_RESET			0x3034
+#define CAFE_GLOBAL_RESET_CCIC			BIT(2)
+#define CAFE_GLOBAL_RESET_SDH			BIT(1)
+#define CAFE_GLOBAL_RESET_NAND			BIT(0)
+
+#define CAFE_FIELD_PREP(reg, field, val)	FIELD_PREP(CAFE_##reg##_##field, val)
+#define CAFE_FIELD_GET(reg, field, val)		FIELD_GET(CAFE_##reg##_##field, val)
 
 struct cafe_priv {
 	struct nand_chip nand;
@@ -104,7 +195,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 static int cafe_device_ready(struct nand_chip *chip)
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
-	int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000);
+	int result = !!(cafe_readl(cafe, NAND_STATUS) &
+			CAFE_NAND_STATUS_FLASH_BUSY);
 	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
 
 	cafe_writel(cafe, irqs, NAND_IRQ);
@@ -164,16 +256,20 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 	int adrbytes = 0;
 	uint32_t ctl1;
-	uint32_t doneint = 0x80000000;
+	uint32_t doneint = CAFE_NAND_IRQ_CMD_DONE;
 
 	cafe_dev_dbg(&cafe->pdev->dev, "cmdfunc %02x, 0x%x, 0x%x\n",
 		command, column, page_addr);
 
 	if (command == NAND_CMD_ERASE2 || command == NAND_CMD_PAGEPROG) {
 		/* Second half of a command we already calculated */
-		cafe_writel(cafe, cafe->ctl2 | 0x100 | command, NAND_CTRL2);
+		cafe_writel(cafe,
+			    cafe->ctl2 |
+			    CAFE_NAND_CTRL2_CMD2 |
+			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, command),
+			    NAND_CTRL2);
 		ctl1 = cafe->ctl1;
-		cafe->ctl2 &= ~(1<<30);
+		cafe->ctl2 &= ~CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
 		cafe_dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n",
 			  cafe->ctl1, cafe->nr_data);
 		goto do_command;
@@ -209,26 +305,29 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 	cafe->data_pos = cafe->datalen = 0;
 
 	/* Set command valid bit, mask in the chip select bit  */
-	ctl1 = 0x80000000 | command | (cafe->ctl1 & CTRL1_CHIPSELECT);
+	ctl1 = CAFE_NAND_CTRL1_HAS_CMD |
+	       CAFE_FIELD_PREP(NAND_CTRL1, CMD, command) |
+	       (cafe->ctl1 & CAFE_NAND_CTRL1_CE);
 
 	/* Set RD or WR bits as appropriate */
 	if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) {
-		ctl1 |= (1<<26); /* rd */
+		ctl1 |= CAFE_NAND_CTRL1_HAS_DATA_IN;
 		/* Always 5 bytes, for now */
 		cafe->datalen = 4;
 		/* And one address cycle -- even for STATUS, since the controller doesn't work without */
 		adrbytes = 1;
 	} else if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 ||
 		   command == NAND_CMD_READOOB || command == NAND_CMD_RNDOUT) {
-		ctl1 |= 1<<26; /* rd */
+		ctl1 |= CAFE_NAND_CTRL1_HAS_DATA_IN;
 		/* For now, assume just read to end of page */
 		cafe->datalen = mtd->writesize + mtd->oobsize - column;
 	} else if (command == NAND_CMD_SEQIN)
-		ctl1 |= 1<<25; /* wr */
+		ctl1 |= CAFE_NAND_CTRL1_HAS_DATA_OUT;
 
 	/* Set number of address bytes */
 	if (adrbytes)
-		ctl1 |= ((adrbytes-1)|8) << 27;
+		ctl1 |= CAFE_NAND_CTRL1_HAS_ADDR |
+			CAFE_FIELD_PREP(NAND_CTRL1, NUM_ADDR_CYC, adrbytes - 1);
 
 	if (command == NAND_CMD_SEQIN || command == NAND_CMD_ERASE1) {
 		/* Ignore the first command of a pair; the hardware
@@ -240,9 +339,15 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 	}
 	/* RNDOUT and READ0 commands need a following byte */
 	if (command == NAND_CMD_RNDOUT)
-		cafe_writel(cafe, cafe->ctl2 | 0x100 | NAND_CMD_RNDOUTSTART, NAND_CTRL2);
+		cafe_writel(cafe,
+			    cafe->ctl2 | CAFE_NAND_CTRL2_CMD2 |
+			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, NAND_CMD_RNDOUTSTART),
+			    NAND_CTRL2);
 	else if (command == NAND_CMD_READ0 && mtd->writesize > 512)
-		cafe_writel(cafe, cafe->ctl2 | 0x100 | NAND_CMD_READSTART, NAND_CTRL2);
+		cafe_writel(cafe,
+			    cafe->ctl2 | CAFE_NAND_CTRL2_CMD2 |
+			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, NAND_CMD_READSTART),
+			    NAND_CTRL2);
 
  do_command:
 	cafe_dev_dbg(&cafe->pdev->dev, "dlen %x, ctl1 %x, ctl2 %x\n",
@@ -250,16 +355,23 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 
 	/* NB: The datasheet lies -- we really should be subtracting 1 here */
 	cafe_writel(cafe, cafe->datalen, NAND_DATA_LEN);
-	cafe_writel(cafe, 0x90000000, NAND_IRQ);
-	if (cafe->usedma && (ctl1 & (3<<25))) {
-		uint32_t dmactl = 0xc0000000 + cafe->datalen;
+	cafe_writel(cafe, CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE,
+		    NAND_IRQ);
+	if (cafe->usedma &&
+	    (ctl1 & (CAFE_NAND_CTRL1_HAS_DATA_IN |
+		     CAFE_NAND_CTRL1_HAS_DATA_OUT))) {
+		uint32_t dmactl = CAFE_NAND_DMA_CTRL_ENABLE |
+				  CAFE_NAND_DMA_CTRL_RESERVED;
+
+		dmactl |= CAFE_FIELD_PREP(NAND_DMA_CTRL, DATA_LEN,
+					  cafe->datalen);
 		/* If WR or RD bits set, set up DMA */
-		if (ctl1 & (1<<26)) {
+		if (ctl1 & CAFE_NAND_CTRL1_HAS_DATA_IN) {
 			/* It's a read */
-			dmactl |= (1<<29);
+			dmactl |= CAFE_NAND_DMA_CTRL_DATA_IN;
 			/* ... so it's done when the DMA is done, not just
 			   the command. */
-			doneint = 0x10000000;
+			doneint = CAFE_NAND_IRQ_DMA_DONE;
 		}
 		cafe_writel(cafe, dmactl, NAND_DMA_CTRL);
 	}
@@ -295,7 +407,7 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 			     command, 500000-c, irqs, cafe_readl(cafe, NAND_IRQ));
 	}
 
-	WARN_ON(cafe->ctl2 & (1<<30));
+	WARN_ON(cafe->ctl2 & CAFE_NAND_CTRL2_AUTO_WRITE_ECC);
 
 	switch (command) {
 
@@ -318,14 +430,14 @@ static void cafe_select_chip(struct nand_chip *chip, int chipnr)
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
+	if (chipnr < 0 || chipnr > 1)
+		return;
+
 	cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
 
 	/* Mask the appropriate bit into the stored value of ctl1
 	   which will be used by cafe_nand_cmdfunc() */
-	if (chipnr)
-		cafe->ctl1 |= CTRL1_CHIPSELECT;
-	else
-		cafe->ctl1 &= ~CTRL1_CHIPSELECT;
+	cafe->ctl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, chipnr);
 }
 
 static irqreturn_t cafe_nand_interrupt(int irq, void *id)
@@ -334,7 +446,9 @@ static irqreturn_t cafe_nand_interrupt(int irq, void *id)
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
-	cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ);
+	cafe_writel(cafe,
+		    irqs & ~(CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE),
+		    NAND_IRQ);
 	if (!irqs)
 		return IRQ_NONE;
 
@@ -368,25 +482,31 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 	unsigned int max_bitflips = 0;
+	u32 ecc_result, status;
 
 	cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n",
 		     cafe_readl(cafe, NAND_ECC_RESULT),
-		     cafe_readl(cafe, NAND_ECC_SYN01));
+		     cafe_readl(cafe, NAND_ECC_SYN_REG(0)));
 
 	nand_read_page_op(chip, page, 0, buf, mtd->writesize);
 	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);
 
-	if (checkecc && cafe_readl(cafe, NAND_ECC_RESULT) & (1<<18)) {
+	ecc_result = cafe_readl(cafe, NAND_ECC_RESULT);
+	status = CAFE_FIELD_GET(NAND_ECC_RESULT, STATUS, ecc_result);
+	if (checkecc && status == CAFE_NAND_ECC_RESULT_CORRECTABLE_ERRS) {
 		unsigned short syn[8], pat[4];
 		int pos[4];
 		u8 *oob = chip->oob_poi;
 		int i, n;
 
 		for (i=0; i<8; i+=2) {
-			uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN01 + (i*2));
+			uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN_REG(i));
+			uint16_t idx;
 
-			syn[i] = cafe->rs->codec->index_of[tmp & 0xfff];
-			syn[i+1] = cafe->rs->codec->index_of[(tmp >> 16) & 0xfff];
+			idx = FIELD_GET(CAFE_NAND_ECC_SYN_FIELD(i), tmp);
+			syn[i] = cafe->rs->codec->index_of[idx];
+			idx = FIELD_GET(CAFE_NAND_ECC_SYN_FIELD(i + 1), tmp);
+			syn[i+1] = cafe->rs->codec->index_of[idx];
 		}
 
 		n = decode_rs16(cafe->rs, NULL, NULL, 1367, syn, 0, pos, 0,
@@ -536,7 +656,7 @@ static int cafe_nand_write_page(struct nand_chip *chip,
 	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
 
 	/* Set up ECC autogeneration */
-	cafe->ctl2 |= (1<<30);
+	cafe->ctl2 |= CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
 
 	return nand_prog_page_end_op(chip);
 }
@@ -604,9 +724,9 @@ static int cafe_nand_attach_chip(struct nand_chip *chip)
 	/* Restore the DMA flag */
 	cafe->usedma = usedma;
 
-	cafe->ctl2 = BIT(27); /* Reed-Solomon ECC */
-	if (mtd->writesize == 2048)
-		cafe->ctl2 |= BIT(29); /* 2KiB page size */
+	cafe->ctl2 = CAFE_NAND_CTRL2_ECC_ALG_RS |
+		     CAFE_FIELD_PREP(NAND_CTRL2, PAGE_SIZE,
+				     mtd->writesize / 512);
 
 	/* Set up ECC according to the type of chip we found */
 	mtd_set_ooblayout(mtd, &cafe_ooblayout_ops);
@@ -734,8 +854,8 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 	}
 
 	/* Start off by resetting the NAND controller completely */
-	cafe_writel(cafe, 1, NAND_RESET);
-	cafe_writel(cafe, 0, NAND_RESET);
+	cafe_writel(cafe, CAFE_GLOBAL_RESET_NAND, GLOBAL_RESET);
+	cafe_writel(cafe, 0, GLOBAL_RESET);
 
 	cafe_writel(cafe, timing[0], NAND_TIMING1);
 	cafe_writel(cafe, timing[1], NAND_TIMING2);
@@ -751,17 +871,49 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 
 	/* Disable master reset, enable NAND clock */
 	ctrl = cafe_readl(cafe, GLOBAL_CTRL);
-	ctrl &= 0xffffeff0;
-	ctrl |= 0x00007000;
-	cafe_writel(cafe, ctrl | 0x05, GLOBAL_CTRL);
-	cafe_writel(cafe, ctrl | 0x0a, GLOBAL_CTRL);
+	ctrl &= ~(CAFE_GLOBAL_SW_RESET_SET |
+		  CAFE_GLOBAL_SW_RESET_CLEAR |
+		  CAFE_GLOBAL_MASTER_RESET_SET |
+		  CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		  CAFE_GLOBAL_NAND_CLK_ENABLE);
+	ctrl |= CAFE_GLOBAL_NAND_CLK_ENABLE |
+		CAFE_GLOBAL_SDH_CLK_ENABLE |
+		CAFE_GLOBAL_CCIC_CLK_ENABLE;
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_SET,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+
 	cafe_writel(cafe, 0, NAND_DMA_CTRL);
 
-	cafe_writel(cafe, 0x7006, GLOBAL_CTRL);
-	cafe_writel(cafe, 0x700a, GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
 
 	/* Enable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_IRQ_PCI_ERROR |
+		    CAFE_GLOBAL_IRQ_CCIC |
+		    CAFE_GLOBAL_IRQ_SDH |
+		    CAFE_GLOBAL_IRQ_NAND,
+		    GLOBAL_IRQ_MASK);
 	cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n",
 		cafe_readl(cafe, GLOBAL_CTRL),
 		cafe_readl(cafe, GLOBAL_IRQ_MASK));
@@ -788,7 +940,9 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 	nand_cleanup(&cafe->nand);
  out_irq:
 	/* Disable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK);
+	cafe_writel(cafe,
+		    cafe_readl(cafe, GLOBAL_IRQ_MASK) & ~CAFE_GLOBAL_IRQ_NAND,
+		    GLOBAL_IRQ_MASK);
 	free_irq(pdev->irq, mtd);
  out_ior:
 	pci_iounmap(pdev, cafe->mmio);
@@ -805,7 +959,9 @@ static void cafe_nand_remove(struct pci_dev *pdev)
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
 	/* Disable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK);
+	cafe_writel(cafe,
+		    cafe_readl(cafe, GLOBAL_IRQ_MASK) & ~CAFE_GLOBAL_IRQ_NAND,
+		    GLOBAL_IRQ_MASK);
 	free_irq(pdev->irq, mtd);
 	nand_release(chip);
 	free_rs(cafe->rs);
@@ -830,8 +986,8 @@ static int cafe_nand_resume(struct pci_dev *pdev)
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
        /* Start off by resetting the NAND controller completely */
-	cafe_writel(cafe, 1, NAND_RESET);
-	cafe_writel(cafe, 0, NAND_RESET);
+	cafe_writel(cafe, CAFE_GLOBAL_RESET_NAND, GLOBAL_RESET);
+	cafe_writel(cafe, 0, GLOBAL_RESET);
 	cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
 
 	/* Restore timing configuration */
@@ -841,13 +997,41 @@ static int cafe_nand_resume(struct pci_dev *pdev)
 
         /* Disable master reset, enable NAND clock */
 	ctrl = cafe_readl(cafe, GLOBAL_CTRL);
-	ctrl &= 0xffffeff0;
-	ctrl |= 0x00007000;
-	cafe_writel(cafe, ctrl | 0x05, GLOBAL_CTRL);
-	cafe_writel(cafe, ctrl | 0x0a, GLOBAL_CTRL);
+	ctrl &= ~(CAFE_GLOBAL_SW_RESET_SET |
+		  CAFE_GLOBAL_SW_RESET_CLEAR |
+		  CAFE_GLOBAL_MASTER_RESET_SET |
+		  CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		  CAFE_GLOBAL_NAND_CLK_ENABLE);
+	ctrl |= CAFE_GLOBAL_NAND_CLK_ENABLE |
+		CAFE_GLOBAL_SDH_CLK_ENABLE |
+		CAFE_GLOBAL_CCIC_CLK_ENABLE;
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_SET,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+
 	cafe_writel(cafe, 0, NAND_DMA_CTRL);
-	cafe_writel(cafe, 0x7006, GLOBAL_CTRL);
-	cafe_writel(cafe, 0x700a, GLOBAL_CTRL);
+
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
 
 	/* Set up DMA address */
 	cafe_writel(cafe, cafe->dmaaddr & 0xffffffff, NAND_DMA_ADDR0);
@@ -858,7 +1042,12 @@ static int cafe_nand_resume(struct pci_dev *pdev)
 		cafe_writel(cafe, 0, NAND_DMA_ADDR1);
 
 	/* Enable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_IRQ_PCI_ERROR |
+		    CAFE_GLOBAL_IRQ_CCIC |
+		    CAFE_GLOBAL_IRQ_SDH |
+		    CAFE_GLOBAL_IRQ_NAND,
+		    GLOBAL_IRQ_MASK);
 	return 0;
 }
 
-- 
2.25.3


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

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

* [PATCH 06/17] mtd: rawnand: cafe: Factor out the controller initialization logic
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (4 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 05/17] mtd: rawnand: cafe: Demistify register fields Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:45   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 07/17] mtd: rawnand: cafe: Get rid of the debug module param Boris Brezillon
                   ` (13 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

The same code is present in the probe and resume path. Let's create
an init helper to factor that out.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 189 +++++++++++--------------------
 1 file changed, 67 insertions(+), 122 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index fbc18bc3d46b..863dd4a8dd42 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -774,12 +774,76 @@ static const struct nand_controller_ops cafe_nand_controller_ops = {
 	.detach_chip = cafe_nand_detach_chip,
 };
 
+static void cafe_nand_init(struct cafe_priv *cafe)
+{
+	u32 ctrl;
+
+	/* Start off by resetting the NAND controller completely */
+	cafe_writel(cafe, CAFE_GLOBAL_RESET_NAND, GLOBAL_RESET);
+	cafe_writel(cafe, 0, GLOBAL_RESET);
+	cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
+
+	/* Restore timing configuration */
+	cafe_writel(cafe, timing[0], NAND_TIMING1);
+	cafe_writel(cafe, timing[1], NAND_TIMING2);
+	cafe_writel(cafe, timing[2], NAND_TIMING3);
+
+	/* Disable master reset, enable NAND clock */
+	ctrl = cafe_readl(cafe, GLOBAL_CTRL);
+	ctrl &= ~(CAFE_GLOBAL_SW_RESET_SET |
+		  CAFE_GLOBAL_SW_RESET_CLEAR |
+		  CAFE_GLOBAL_MASTER_RESET_SET |
+		  CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		  CAFE_GLOBAL_NAND_CLK_ENABLE);
+	ctrl |= CAFE_GLOBAL_NAND_CLK_ENABLE |
+		CAFE_GLOBAL_SDH_CLK_ENABLE |
+		CAFE_GLOBAL_CCIC_CLK_ENABLE;
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_SET,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+
+	cafe_writel(cafe, 0, NAND_DMA_CTRL);
+
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+
+	/* Set up DMA address */
+	cafe_writel(cafe, lower_32_bits(cafe->dmaaddr), NAND_DMA_ADDR0);
+	cafe_writel(cafe, upper_32_bits(cafe->dmaaddr), NAND_DMA_ADDR1);
+
+	/* Enable NAND IRQ in global IRQ mask register */
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_IRQ_PCI_ERROR |
+		    CAFE_GLOBAL_IRQ_CCIC |
+		    CAFE_GLOBAL_IRQ_SDH |
+		    CAFE_GLOBAL_IRQ_NAND,
+		    GLOBAL_IRQ_MASK);
+}
+
 static int cafe_nand_probe(struct pci_dev *pdev,
 				     const struct pci_device_id *ent)
 {
 	struct mtd_info *mtd;
 	struct cafe_priv *cafe;
-	uint32_t ctrl;
 	int err = 0;
 
 	/* Very old versions shared the same PCI ident for all three
@@ -853,15 +917,8 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 		}
 	}
 
-	/* Start off by resetting the NAND controller completely */
-	cafe_writel(cafe, CAFE_GLOBAL_RESET_NAND, GLOBAL_RESET);
-	cafe_writel(cafe, 0, GLOBAL_RESET);
+	cafe_nand_init(cafe);
 
-	cafe_writel(cafe, timing[0], NAND_TIMING1);
-	cafe_writel(cafe, timing[1], NAND_TIMING2);
-	cafe_writel(cafe, timing[2], NAND_TIMING3);
-
-	cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
 	err = request_irq(pdev->irq, &cafe_nand_interrupt, IRQF_SHARED,
 			  "CAFE NAND", mtd);
 	if (err) {
@@ -869,55 +926,6 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 		goto out_ior;
 	}
 
-	/* Disable master reset, enable NAND clock */
-	ctrl = cafe_readl(cafe, GLOBAL_CTRL);
-	ctrl &= ~(CAFE_GLOBAL_SW_RESET_SET |
-		  CAFE_GLOBAL_SW_RESET_CLEAR |
-		  CAFE_GLOBAL_MASTER_RESET_SET |
-		  CAFE_GLOBAL_MASTER_RESET_CLEAR |
-		  CAFE_GLOBAL_NAND_CLK_ENABLE);
-	ctrl |= CAFE_GLOBAL_NAND_CLK_ENABLE |
-		CAFE_GLOBAL_SDH_CLK_ENABLE |
-		CAFE_GLOBAL_CCIC_CLK_ENABLE;
-	cafe_writel(cafe,
-		    ctrl |
-		    CAFE_GLOBAL_MASTER_RESET_SET |
-		    CAFE_GLOBAL_SW_RESET_SET,
-		    GLOBAL_CTRL);
-	cafe_writel(cafe,
-		    ctrl |
-		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
-		    CAFE_GLOBAL_SW_RESET_CLEAR,
-		    GLOBAL_CTRL);
-
-	cafe_writel(cafe, 0, NAND_DMA_CTRL);
-
-	cafe_writel(cafe,
-		    CAFE_GLOBAL_NAND_CLK_ENABLE |
-		    CAFE_GLOBAL_SDH_CLK_ENABLE |
-		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
-		    CAFE_GLOBAL_MASTER_RESET_SET |
-		    CAFE_GLOBAL_SW_RESET_CLEAR,
-		    GLOBAL_CTRL);
-	cafe_writel(cafe,
-		    CAFE_GLOBAL_NAND_CLK_ENABLE |
-		    CAFE_GLOBAL_SDH_CLK_ENABLE |
-		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
-		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
-		    CAFE_GLOBAL_SW_RESET_CLEAR,
-		    GLOBAL_CTRL);
-
-	/* Enable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe,
-		    CAFE_GLOBAL_IRQ_PCI_ERROR |
-		    CAFE_GLOBAL_IRQ_CCIC |
-		    CAFE_GLOBAL_IRQ_SDH |
-		    CAFE_GLOBAL_IRQ_NAND,
-		    GLOBAL_IRQ_MASK);
-	cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n",
-		cafe_readl(cafe, GLOBAL_CTRL),
-		cafe_readl(cafe, GLOBAL_IRQ_MASK));
-
 	/* Do not use the DMA during the NAND identification */
 	cafe->usedma = 0;
 
@@ -980,74 +988,11 @@ MODULE_DEVICE_TABLE(pci, cafe_nand_tbl);
 
 static int cafe_nand_resume(struct pci_dev *pdev)
 {
-	uint32_t ctrl;
 	struct mtd_info *mtd = pci_get_drvdata(pdev);
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
-       /* Start off by resetting the NAND controller completely */
-	cafe_writel(cafe, CAFE_GLOBAL_RESET_NAND, GLOBAL_RESET);
-	cafe_writel(cafe, 0, GLOBAL_RESET);
-	cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
-
-	/* Restore timing configuration */
-	cafe_writel(cafe, timing[0], NAND_TIMING1);
-	cafe_writel(cafe, timing[1], NAND_TIMING2);
-	cafe_writel(cafe, timing[2], NAND_TIMING3);
-
-        /* Disable master reset, enable NAND clock */
-	ctrl = cafe_readl(cafe, GLOBAL_CTRL);
-	ctrl &= ~(CAFE_GLOBAL_SW_RESET_SET |
-		  CAFE_GLOBAL_SW_RESET_CLEAR |
-		  CAFE_GLOBAL_MASTER_RESET_SET |
-		  CAFE_GLOBAL_MASTER_RESET_CLEAR |
-		  CAFE_GLOBAL_NAND_CLK_ENABLE);
-	ctrl |= CAFE_GLOBAL_NAND_CLK_ENABLE |
-		CAFE_GLOBAL_SDH_CLK_ENABLE |
-		CAFE_GLOBAL_CCIC_CLK_ENABLE;
-	cafe_writel(cafe,
-		    ctrl |
-		    CAFE_GLOBAL_MASTER_RESET_SET |
-		    CAFE_GLOBAL_SW_RESET_SET,
-		    GLOBAL_CTRL);
-	cafe_writel(cafe,
-		    ctrl |
-		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
-		    CAFE_GLOBAL_SW_RESET_CLEAR,
-		    GLOBAL_CTRL);
-
-	cafe_writel(cafe, 0, NAND_DMA_CTRL);
-
-	cafe_writel(cafe,
-		    CAFE_GLOBAL_NAND_CLK_ENABLE |
-		    CAFE_GLOBAL_SDH_CLK_ENABLE |
-		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
-		    CAFE_GLOBAL_MASTER_RESET_SET |
-		    CAFE_GLOBAL_SW_RESET_CLEAR,
-		    GLOBAL_CTRL);
-	cafe_writel(cafe,
-		    CAFE_GLOBAL_NAND_CLK_ENABLE |
-		    CAFE_GLOBAL_SDH_CLK_ENABLE |
-		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
-		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
-		    CAFE_GLOBAL_SW_RESET_CLEAR,
-		    GLOBAL_CTRL);
-
-	/* Set up DMA address */
-	cafe_writel(cafe, cafe->dmaaddr & 0xffffffff, NAND_DMA_ADDR0);
-	if (sizeof(cafe->dmaaddr) > 4)
-	/* Shift in two parts to shut the compiler up */
-		cafe_writel(cafe, (cafe->dmaaddr >> 16) >> 16, NAND_DMA_ADDR1);
-	else
-		cafe_writel(cafe, 0, NAND_DMA_ADDR1);
-
-	/* Enable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe,
-		    CAFE_GLOBAL_IRQ_PCI_ERROR |
-		    CAFE_GLOBAL_IRQ_CCIC |
-		    CAFE_GLOBAL_IRQ_SDH |
-		    CAFE_GLOBAL_IRQ_NAND,
-		    GLOBAL_IRQ_MASK);
+	cafe_nand_init(cafe);
 	return 0;
 }
 
-- 
2.25.3


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

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

* [PATCH 07/17] mtd: rawnand: cafe: Get rid of the debug module param
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (5 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 06/17] mtd: rawnand: cafe: Factor out the controller initialization logic Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:46   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 08/17] mtd: rawnand: cafe: Use devm_kzalloc and devm_request_irq() Boris Brezillon
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Dynamic prink already offers conditional debug traces enablement, let's
not define a new way to do the same thing.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 59 ++++++++++++++------------------
 1 file changed, 25 insertions(+), 34 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 863dd4a8dd42..55fa0bf2806a 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -10,10 +10,7 @@
  */
 
 #include <linux/bitfield.h>
-#define DEBUG
-
 #include <linux/device.h>
-#undef DEBUG
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/partitions.h>
@@ -170,9 +167,6 @@ module_param(usedma, int, 0644);
 static int skipbbt = 0;
 module_param(skipbbt, int, 0644);
 
-static int debug = 0;
-module_param(debug, int, 0644);
-
 static int regdebug = 0;
 module_param(regdebug, int, 0644);
 
@@ -185,9 +179,6 @@ module_param_array(timing, int, &numtimings, 0644);
 
 static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 
-/* Hrm. Why isn't this already conditional on something in the struct device? */
-#define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0)
-
 /* Make it easier to switch to PIO if we need to */
 #define cafe_readl(cafe, addr)			readl((cafe)->mmio + CAFE_##addr)
 #define cafe_writel(cafe, datum, addr)		writel(datum, (cafe)->mmio + CAFE_##addr)
@@ -201,7 +192,7 @@ static int cafe_device_ready(struct nand_chip *chip)
 
 	cafe_writel(cafe, irqs, NAND_IRQ);
 
-	cafe_dev_dbg(&cafe->pdev->dev, "NAND device is%s ready, IRQ %x (%x) (%x,%x)\n",
+	dev_dbg(&cafe->pdev->dev, "NAND device is%s ready, IRQ %x (%x) (%x,%x)\n",
 		result?"":" not", irqs, cafe_readl(cafe, NAND_IRQ),
 		cafe_readl(cafe, GLOBAL_IRQ), cafe_readl(cafe, GLOBAL_IRQ_MASK));
 
@@ -220,7 +211,7 @@ static void cafe_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)
 
 	cafe->datalen += len;
 
-	cafe_dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer. datalen 0x%x\n",
+	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer. datalen 0x%x\n",
 		len, cafe->datalen);
 }
 
@@ -233,8 +224,8 @@ static void cafe_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
 	else
 		memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA + cafe->datalen, len);
 
-	cafe_dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from position 0x%x in read buffer.\n",
-		  len, cafe->datalen);
+	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from position 0x%x in read buffer.\n",
+		len, cafe->datalen);
 	cafe->datalen += len;
 }
 
@@ -244,7 +235,7 @@ static uint8_t cafe_read_byte(struct nand_chip *chip)
 	uint8_t d;
 
 	cafe_read_buf(chip, &d, 1);
-	cafe_dev_dbg(&cafe->pdev->dev, "Read %02x\n", d);
+	dev_dbg(&cafe->pdev->dev, "Read %02x\n", d);
 
 	return d;
 }
@@ -258,7 +249,7 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 	uint32_t ctl1;
 	uint32_t doneint = CAFE_NAND_IRQ_CMD_DONE;
 
-	cafe_dev_dbg(&cafe->pdev->dev, "cmdfunc %02x, 0x%x, 0x%x\n",
+	dev_dbg(&cafe->pdev->dev, "cmdfunc %02x, 0x%x, 0x%x\n",
 		command, column, page_addr);
 
 	if (command == NAND_CMD_ERASE2 || command == NAND_CMD_PAGEPROG) {
@@ -270,8 +261,8 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 			    NAND_CTRL2);
 		ctl1 = cafe->ctl1;
 		cafe->ctl2 &= ~CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
-		cafe_dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n",
-			  cafe->ctl1, cafe->nr_data);
+		dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n",
+			cafe->ctl1, cafe->nr_data);
 		goto do_command;
 	}
 	/* Reset ECC engine */
@@ -333,8 +324,8 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 		/* Ignore the first command of a pair; the hardware
 		   deals with them both at once, later */
 		cafe->ctl1 = ctl1;
-		cafe_dev_dbg(&cafe->pdev->dev, "Setup for delayed command, ctl1 %08x, dlen %x\n",
-			  cafe->ctl1, cafe->datalen);
+		dev_dbg(&cafe->pdev->dev, "Setup for delayed command, ctl1 %08x, dlen %x\n",
+			cafe->ctl1, cafe->datalen);
 		return;
 	}
 	/* RNDOUT and READ0 commands need a following byte */
@@ -350,7 +341,7 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 			    NAND_CTRL2);
 
  do_command:
-	cafe_dev_dbg(&cafe->pdev->dev, "dlen %x, ctl1 %x, ctl2 %x\n",
+	dev_dbg(&cafe->pdev->dev, "dlen %x, ctl1 %x, ctl2 %x\n",
 		cafe->datalen, ctl1, cafe_readl(cafe, NAND_CTRL2));
 
 	/* NB: The datasheet lies -- we really should be subtracting 1 here */
@@ -399,12 +390,12 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 				break;
 			udelay(1);
 			if (!(c % 100000))
-				cafe_dev_dbg(&cafe->pdev->dev, "Wait for ready, IRQ %x\n", irqs);
+				dev_dbg(&cafe->pdev->dev, "Wait for ready, IRQ %x\n", irqs);
 			cpu_relax();
 		}
 		cafe_writel(cafe, doneint, NAND_IRQ);
-		cafe_dev_dbg(&cafe->pdev->dev, "Command %x completed after %d usec, irqs %x (%x)\n",
-			     command, 500000-c, irqs, cafe_readl(cafe, NAND_IRQ));
+		dev_dbg(&cafe->pdev->dev, "Command %x completed after %d usec, irqs %x (%x)\n",
+			command, 500000-c, irqs, cafe_readl(cafe, NAND_IRQ));
 	}
 
 	WARN_ON(cafe->ctl2 & CAFE_NAND_CTRL2_AUTO_WRITE_ECC);
@@ -433,7 +424,7 @@ static void cafe_select_chip(struct nand_chip *chip, int chipnr)
 	if (chipnr < 0 || chipnr > 1)
 		return;
 
-	cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
+	dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
 
 	/* Mask the appropriate bit into the stored value of ctl1
 	   which will be used by cafe_nand_cmdfunc() */
@@ -452,7 +443,7 @@ static irqreturn_t cafe_nand_interrupt(int irq, void *id)
 	if (!irqs)
 		return IRQ_NONE;
 
-	cafe_dev_dbg(&cafe->pdev->dev, "irq, bits %x (%x)\n", irqs, cafe_readl(cafe, NAND_IRQ));
+	dev_dbg(&cafe->pdev->dev, "irq, bits %x (%x)\n", irqs, cafe_readl(cafe, NAND_IRQ));
 	return IRQ_HANDLED;
 }
 
@@ -484,9 +475,9 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
 	unsigned int max_bitflips = 0;
 	u32 ecc_result, status;
 
-	cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n",
-		     cafe_readl(cafe, NAND_ECC_RESULT),
-		     cafe_readl(cafe, NAND_ECC_SYN_REG(0)));
+	dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n",
+		cafe_readl(cafe, NAND_ECC_RESULT),
+		cafe_readl(cafe, NAND_ECC_SYN_REG(0)));
 
 	nand_read_page_op(chip, page, 0, buf, mtd->writesize);
 	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);
@@ -718,8 +709,8 @@ static int cafe_nand_attach_chip(struct nand_chip *chip)
 	cafe_writel(cafe, lower_32_bits(cafe->dmaaddr), NAND_DMA_ADDR0);
 	cafe_writel(cafe, upper_32_bits(cafe->dmaaddr), NAND_DMA_ADDR1);
 
-	cafe_dev_dbg(&cafe->pdev->dev, "Set DMA address to %x (virt %p)\n",
-		     cafe_readl(cafe, NAND_DMA_ADDR0), cafe->dmabuf);
+	dev_dbg(&cafe->pdev->dev, "Set DMA address to %x (virt %p)\n",
+		cafe_readl(cafe, NAND_DMA_ADDR0), cafe->dmabuf);
 
 	/* Restore the DMA flag */
 	cafe->usedma = usedma;
@@ -901,16 +892,16 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 	}
 
 	if (numtimings == 3) {
-		cafe_dev_dbg(&cafe->pdev->dev, "Using provided timings (%08x %08x %08x)\n",
-			     timing[0], timing[1], timing[2]);
+		dev_dbg(&cafe->pdev->dev, "Using provided timings (%08x %08x %08x)\n",
+			timing[0], timing[1], timing[2]);
 	} else {
 		timing[0] = cafe_readl(cafe, NAND_TIMING1);
 		timing[1] = cafe_readl(cafe, NAND_TIMING2);
 		timing[2] = cafe_readl(cafe, NAND_TIMING3);
 
 		if (timing[0] | timing[1] | timing[2]) {
-			cafe_dev_dbg(&cafe->pdev->dev, "Timing registers already set (%08x %08x %08x)\n",
-				     timing[0], timing[1], timing[2]);
+			dev_dbg(&cafe->pdev->dev, "Timing registers already set (%08x %08x %08x)\n",
+				timing[0], timing[1], timing[2]);
 		} else {
 			dev_warn(&cafe->pdev->dev, "Timing registers unset; using most conservative defaults\n");
 			timing[0] = timing[1] = timing[2] = 0xffffffff;
-- 
2.25.3


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

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

* [PATCH 08/17] mtd: rawnand: cafe: Use devm_kzalloc and devm_request_irq()
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (6 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 07/17] mtd: rawnand: cafe: Get rid of the debug module param Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:47   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 09/17] mtd: rawnand: cafe: Get rid of a useless label Boris Brezillon
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

This simplifies the error/remove path.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 55fa0bf2806a..3eab57e63215 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -848,7 +848,7 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 
 	pci_set_master(pdev);
 
-	cafe = kzalloc(sizeof(*cafe), GFP_KERNEL);
+	cafe = devm_kzalloc(&pdev->dev, sizeof(*cafe), GFP_KERNEL);
 	if (!cafe)
 		return  -ENOMEM;
 
@@ -860,8 +860,7 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 	cafe->mmio = pci_iomap(pdev, 0, 0);
 	if (!cafe->mmio) {
 		dev_warn(&pdev->dev, "failed to iomap\n");
-		err = -ENOMEM;
-		goto out_free_mtd;
+		return -ENOMEM;
 	}
 
 	cafe->rs = init_rs_non_canonical(12, &cafe_mul, 0, 1, 8);
@@ -910,8 +909,8 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 
 	cafe_nand_init(cafe);
 
-	err = request_irq(pdev->irq, &cafe_nand_interrupt, IRQF_SHARED,
-			  "CAFE NAND", mtd);
+	err = devm_request_irq(&pdev->dev, pdev->irq, cafe_nand_interrupt,
+			       IRQF_SHARED, "CAFE NAND", mtd);
 	if (err) {
 		dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq);
 		goto out_ior;
@@ -942,11 +941,8 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 	cafe_writel(cafe,
 		    cafe_readl(cafe, GLOBAL_IRQ_MASK) & ~CAFE_GLOBAL_IRQ_NAND,
 		    GLOBAL_IRQ_MASK);
-	free_irq(pdev->irq, mtd);
  out_ior:
 	pci_iounmap(pdev, cafe->mmio);
- out_free_mtd:
-	kfree(cafe);
  out:
 	return err;
 }
@@ -961,12 +957,10 @@ static void cafe_nand_remove(struct pci_dev *pdev)
 	cafe_writel(cafe,
 		    cafe_readl(cafe, GLOBAL_IRQ_MASK) & ~CAFE_GLOBAL_IRQ_NAND,
 		    GLOBAL_IRQ_MASK);
-	free_irq(pdev->irq, mtd);
 	nand_release(chip);
 	free_rs(cafe->rs);
 	pci_iounmap(pdev, cafe->mmio);
 	dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr);
-	kfree(cafe);
 }
 
 static const struct pci_device_id cafe_nand_tbl[] = {
-- 
2.25.3


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

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

* [PATCH 09/17] mtd: rawnand: cafe: Get rid of a useless label
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (7 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 08/17] mtd: rawnand: cafe: Use devm_kzalloc and devm_request_irq() Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:47   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 10/17] mtd: rawnand: cafe: Explicitly inherit from nand_controller Boris Brezillon
                   ` (10 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

We can return 0 directly instead of branching to the out label.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 3eab57e63215..348debbc04af 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -932,7 +932,7 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 	if (err)
 		goto out_cleanup_nand;
 
-	goto out;
+	return 0;
 
  out_cleanup_nand:
 	nand_cleanup(&cafe->nand);
@@ -943,7 +943,6 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 		    GLOBAL_IRQ_MASK);
  out_ior:
 	pci_iounmap(pdev, cafe->mmio);
- out:
 	return err;
 }
 
-- 
2.25.3


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

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

* [PATCH 10/17] mtd: rawnand: cafe: Explicitly inherit from nand_controller
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (8 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 09/17] mtd: rawnand: cafe: Get rid of a useless label Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:49   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 11/17] mtd: rawnand: cafe: Don't leave ECC enabled in the write path Boris Brezillon
                   ` (9 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Explicitly inherit from nand_controller instead of using the dummy
controller object.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 348debbc04af..2825489a71b8 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -146,6 +146,7 @@
 #define CAFE_FIELD_GET(reg, field, val)		FIELD_GET(CAFE_##reg##_##field, val)
 
 struct cafe_priv {
+	struct nand_controller base;
 	struct nand_chip nand;
 	struct pci_dev *pdev;
 	void __iomem *mmio;
@@ -920,7 +921,9 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 	cafe->usedma = 0;
 
 	/* Scan to find existence of the device */
-	cafe->nand.legacy.dummy_controller.ops = &cafe_nand_controller_ops;
+	nand_controller_init(&cafe->base);
+	cafe->base.ops = &cafe_nand_controller_ops;
+	cafe->nand.controller = &cafe->base;
 	err = nand_scan(&cafe->nand, 2);
 	if (err)
 		goto out_irq;
-- 
2.25.3


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

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

* [PATCH 11/17] mtd: rawnand: cafe: Don't leave ECC enabled in the write path
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (9 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 10/17] mtd: rawnand: cafe: Explicitly inherit from nand_controller Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:51   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 12/17] mtd: rawnand: cafe: Don't split things when reading/writing a page Boris Brezillon
                   ` (8 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

cafe_nand_write_page_lowlevel() sets the ECC auto-generation flag but
never clears it, thus forcing the cafe_nand_cmdfunc() to clear it
in certain circumstances. Let's just clear this flag in
cafe_nand_write_page_lowlevel() instead.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 2825489a71b8..31493a201a02 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -261,7 +261,6 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, command),
 			    NAND_CTRL2);
 		ctl1 = cafe->ctl1;
-		cafe->ctl2 &= ~CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
 		dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n",
 			cafe->ctl1, cafe->nr_data);
 		goto do_command;
@@ -643,6 +642,7 @@ static int cafe_nand_write_page(struct nand_chip *chip,
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
+	int ret;
 
 	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
 	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
@@ -650,7 +650,14 @@ static int cafe_nand_write_page(struct nand_chip *chip,
 	/* Set up ECC autogeneration */
 	cafe->ctl2 |= CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
 
-	return nand_prog_page_end_op(chip);
+	ret = nand_prog_page_end_op(chip);
+
+	/*
+	 * And clear it before returning so that following write operations
+	 * that do not involve ECC don't generate ECC bytes.
+	 */
+	cafe->ctl2 &= ~CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
+	return ret;
 }
 
 /* F_2[X]/(X**6+X+1)  */
-- 
2.25.3


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

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

* [PATCH 12/17] mtd: rawnand: cafe: Don't split things when reading/writing a page
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (10 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 11/17] mtd: rawnand: cafe: Don't leave ECC enabled in the write path Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:53   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support Boris Brezillon
                   ` (7 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Calling nand_read_page_op(pagesize)/nand_prog_page_begin_op(pagesize)
and expecting to get a pagesize+oobsize read from/written to the
read/write buffer is fragile and only works because of hacks done
in cmdfunc(). Let's read/write the page in one go, using the page
cache buffer as a bounce buffer.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 31493a201a02..edf65197604b 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -472,6 +472,7 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
+	void *pagebuf = nand_get_data_buf(chip);
 	unsigned int max_bitflips = 0;
 	u32 ecc_result, status;
 
@@ -479,8 +480,11 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
 		cafe_readl(cafe, NAND_ECC_RESULT),
 		cafe_readl(cafe, NAND_ECC_SYN_REG(0)));
 
-	nand_read_page_op(chip, page, 0, buf, mtd->writesize);
-	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);
+	nand_read_page_op(chip, page, 0, pagebuf,
+			  mtd->writesize + mtd->oobsize);
+
+	if (buf != pagebuf)
+		memcpy(buf, pagebuf, mtd->writesize);
 
 	ecc_result = cafe_readl(cafe, NAND_ECC_RESULT);
 	status = CAFE_FIELD_GET(NAND_ECC_RESULT, STATUS, ecc_result);
@@ -642,15 +646,17 @@ static int cafe_nand_write_page(struct nand_chip *chip,
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
+	void *pagebuf = nand_get_data_buf(chip);
 	int ret;
 
-	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
-	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
+	if (pagebuf != buf)
+		memcpy(pagebuf, buf, mtd->writesize);
 
 	/* Set up ECC autogeneration */
 	cafe->ctl2 |= CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
 
-	ret = nand_prog_page_end_op(chip);
+	ret = nand_prog_page_op(chip, page, 0, pagebuf,
+				mtd->writesize + mtd->oobsize);
 
 	/*
 	 * And clear it before returning so that following write operations
-- 
2.25.3


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

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

* [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (11 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 12/17] mtd: rawnand: cafe: Don't split things when reading/writing a page Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 19:59   ` Miquel Raynal
       [not found]   ` <20200502111410.330584-1-lkundrak@v3.sk>
  2020-04-27  8:20 ` [PATCH 14/17] mtd: rawnand: cafe: Get rid of the legacy interface implementation Boris Brezillon
                   ` (6 subsequent siblings)
  19 siblings, 2 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Implementing exec_op() will help us get rid of the legacy interface and
should make drivers much cleaner too.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 137 ++++++++++++++++++++++++++++++-
 1 file changed, 136 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index edf65197604b..ada9c8b06a41 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -21,7 +21,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/io.h>
+#include <linux/iopoll.h>
 
 #define CAFE_NAND_CTRL1				0x00
 #define CAFE_NAND_CTRL1_HAS_CMD			BIT(31)
@@ -774,9 +774,144 @@ static void cafe_nand_detach_chip(struct nand_chip *chip)
 	dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr);
 }
 
+static int cafe_nand_exec_subop(struct nand_chip *chip,
+				const struct nand_subop *subop)
+{
+	struct cafe_priv *cafe = nand_get_controller_data(chip);
+	u32 ctrl1 = 0, ctrl2 = cafe->ctl2, addr1 = 0, addr2 = 0;
+	const struct nand_op_instr *data_instr = NULL;
+	u32 status, wait = CAFE_NAND_IRQ_CMD_DONE;
+	bool waitrdy = false;
+	unsigned int i, j;
+	int ret;
+
+	if (WARN_ON(subop->cs > 1))
+		return -EINVAL;
+
+	cafe->datalen = 0;
+	ctrl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, subop->cs);
+
+	for (i = 0; i < subop->ninstrs; i++) {
+		const struct nand_op_instr *instr = &subop->instrs[i];
+
+		switch (instr->type) {
+		case NAND_OP_CMD_INSTR:
+			if (WARN_ON((ctrl1 & CAFE_NAND_CTRL1_HAS_CMD) &&
+				    (ctrl2 & CAFE_NAND_CTRL2_HAS_CMD2)))
+				return -EINVAL;
+
+			if (!(ctrl1 & CAFE_NAND_CTRL1_HAS_CMD))
+				ctrl1 |= CAFE_NAND_CTRL1_HAS_CMD |
+					 CAFE_FIELD_PREP(NAND_CTRL1, CMD,
+							 instr->ctx.cmd.opcode);
+			else
+				ctrl2 |= CAFE_NAND_CTRL2_HAS_CMD2 |
+					 CAFE_FIELD_PREP(NAND_CTRL2, CMD2,
+							 instr->ctx.cmd.opcode);
+			break;
+
+		case NAND_OP_ADDR_INSTR:
+			if (WARN_ON(instr->ctx.addr.naddrs > 5 ||
+				    !instr->ctx.addr.naddrs))
+				return -EINVAL;
+
+			for (j = 0; j < instr->ctx.addr.naddrs; j++) {
+				u32 addr = instr->ctx.addr.addrs[j];
+
+				if (j < 2)
+					addr1 |= addr << (8 * j);
+				else
+					addr2 |= addr << (8 * (j - 2));
+			}
+
+			ctrl1 |= CAFE_NAND_CTRL1_HAS_ADDR |
+				 CAFE_FIELD_PREP(NAND_CTRL1, NUM_ADDR_CYC,
+						 instr->ctx.addr.naddrs - 1);
+			cafe_writel(cafe, addr1, NAND_ADDR1);
+			if (instr->ctx.addr.naddrs > 2)
+				cafe_writel(cafe, addr2, NAND_ADDR2);
+			break;
+
+		case NAND_OP_DATA_IN_INSTR:
+			data_instr = instr;
+			ctrl1 |= CAFE_NAND_CTRL1_HAS_DATA_IN;
+			break;
+
+		case NAND_OP_DATA_OUT_INSTR:
+			data_instr = instr;
+			ctrl1 |= CAFE_NAND_CTRL1_HAS_DATA_OUT;
+			cafe_write_buf(chip, instr->ctx.data.buf.out,
+				       instr->ctx.data.len);
+			break;
+
+		case NAND_OP_WAITRDY_INSTR:
+			wait |= CAFE_NAND_IRQ_FLASH_RDY;
+			waitrdy = true;
+			break;
+		}
+	}
+
+	if (data_instr)
+		cafe_writel(cafe, data_instr->ctx.data.len, NAND_DATA_LEN);
+
+	if (cafe->usedma && data_instr) {
+		u32 dmactrl = CAFE_NAND_DMA_CTRL_ENABLE |
+			      CAFE_NAND_DMA_CTRL_RESERVED;
+
+		wait |= CAFE_NAND_IRQ_DMA_DONE;
+		dmactrl |= CAFE_FIELD_PREP(NAND_DMA_CTRL, DATA_LEN,
+					   data_instr->ctx.data.len);
+		if (ctrl1 & CAFE_NAND_CTRL1_HAS_DATA_IN)
+			dmactrl |= CAFE_NAND_DMA_CTRL_DATA_IN;
+
+		cafe_writel(cafe, dmactrl, NAND_DMA_CTRL);
+	}
+
+	/* Clear the pending interrupts before starting the operation. */
+	cafe_writel(cafe, wait, NAND_IRQ);
+
+	cafe_writel(cafe, ctrl2, NAND_CTRL2);
+	cafe_writel(cafe, ctrl1, NAND_CTRL1);
+
+	ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
+				 (status & wait) == wait, 1, USEC_PER_SEC);
+	if (ret)
+		return ret;
+
+	if (ctrl1 & CAFE_NAND_DMA_CTRL_DATA_IN)
+		cafe_read_buf(chip, data_instr->ctx.data.buf.in,
+			      data_instr->ctx.data.len);
+
+	return 0;
+}
+
+static const struct nand_op_parser cafe_nand_op_parser = NAND_OP_PARSER(
+	NAND_OP_PARSER_PATTERN(cafe_nand_exec_subop,
+			       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_PAT_WAITRDY_ELEM(true),
+			       NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, 2112)),
+	NAND_OP_PARSER_PATTERN(cafe_nand_exec_subop,
+			       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_PAT_DATA_IN_ELEM(true, 2112),
+			       NAND_OP_PARSER_PAT_WAITRDY_ELEM(true))
+);
+
+static int cafe_nand_exec_op(struct nand_chip *chip,
+			     const struct nand_operation *op,
+			     bool check_only)
+{
+	return nand_op_parser_exec_op(chip, &cafe_nand_op_parser, op,
+				      check_only);
+}
+
 static const struct nand_controller_ops cafe_nand_controller_ops = {
 	.attach_chip = cafe_nand_attach_chip,
 	.detach_chip = cafe_nand_detach_chip,
+	.exec_op = cafe_nand_exec_op,
 };
 
 static void cafe_nand_init(struct cafe_priv *cafe)
-- 
2.25.3


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

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

* [PATCH 14/17] mtd: rawnand: cafe: Get rid of the legacy interface implementation
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (12 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 20:00   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read, write}_buf() prototypes Boris Brezillon
                   ` (5 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

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

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 252 +------------------------------
 1 file changed, 6 insertions(+), 246 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index ada9c8b06a41..5b38d496d923 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -151,12 +151,7 @@ struct cafe_priv {
 	struct pci_dev *pdev;
 	void __iomem *mmio;
 	struct rs_control *rs;
-	uint32_t ctl1;
 	uint32_t ctl2;
-	int datalen;
-	int nr_data;
-	int data_pos;
-	int page_addr;
 	bool usedma;
 	dma_addr_t dmaaddr;
 	unsigned char *dmabuf;
@@ -184,36 +179,16 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 #define cafe_readl(cafe, addr)			readl((cafe)->mmio + CAFE_##addr)
 #define cafe_writel(cafe, datum, addr)		writel(datum, (cafe)->mmio + CAFE_##addr)
 
-static int cafe_device_ready(struct nand_chip *chip)
-{
-	struct cafe_priv *cafe = nand_get_controller_data(chip);
-	int result = !!(cafe_readl(cafe, NAND_STATUS) &
-			CAFE_NAND_STATUS_FLASH_BUSY);
-	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
-
-	cafe_writel(cafe, irqs, NAND_IRQ);
-
-	dev_dbg(&cafe->pdev->dev, "NAND device is%s ready, IRQ %x (%x) (%x,%x)\n",
-		result?"":" not", irqs, cafe_readl(cafe, NAND_IRQ),
-		cafe_readl(cafe, GLOBAL_IRQ), cafe_readl(cafe, GLOBAL_IRQ_MASK));
-
-	return result;
-}
-
-
 static void cafe_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
 	if (cafe->usedma)
-		memcpy(cafe->dmabuf + cafe->datalen, buf, len);
+		memcpy(cafe->dmabuf, buf, len);
 	else
-		memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA + cafe->datalen, buf, len);
+		memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA, buf, len);
 
-	cafe->datalen += len;
-
-	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer. datalen 0x%x\n",
-		len, cafe->datalen);
+	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer.\n",	len);
 }
 
 static void cafe_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
@@ -221,214 +196,11 @@ static void cafe_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
 	if (cafe->usedma)
-		memcpy(buf, cafe->dmabuf + cafe->datalen, len);
+		memcpy(buf, cafe->dmabuf, len);
 	else
-		memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA + cafe->datalen, len);
+		memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA, len);
 
-	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from position 0x%x in read buffer.\n",
-		len, cafe->datalen);
-	cafe->datalen += len;
-}
-
-static uint8_t cafe_read_byte(struct nand_chip *chip)
-{
-	struct cafe_priv *cafe = nand_get_controller_data(chip);
-	uint8_t d;
-
-	cafe_read_buf(chip, &d, 1);
-	dev_dbg(&cafe->pdev->dev, "Read %02x\n", d);
-
-	return d;
-}
-
-static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
-			      int column, int page_addr)
-{
-	struct mtd_info *mtd = nand_to_mtd(chip);
-	struct cafe_priv *cafe = nand_get_controller_data(chip);
-	int adrbytes = 0;
-	uint32_t ctl1;
-	uint32_t doneint = CAFE_NAND_IRQ_CMD_DONE;
-
-	dev_dbg(&cafe->pdev->dev, "cmdfunc %02x, 0x%x, 0x%x\n",
-		command, column, page_addr);
-
-	if (command == NAND_CMD_ERASE2 || command == NAND_CMD_PAGEPROG) {
-		/* Second half of a command we already calculated */
-		cafe_writel(cafe,
-			    cafe->ctl2 |
-			    CAFE_NAND_CTRL2_CMD2 |
-			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, command),
-			    NAND_CTRL2);
-		ctl1 = cafe->ctl1;
-		dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n",
-			cafe->ctl1, cafe->nr_data);
-		goto do_command;
-	}
-	/* Reset ECC engine */
-	cafe_writel(cafe, 0, NAND_CTRL2);
-
-	/* Emulate NAND_CMD_READOOB on large-page chips */
-	if (mtd->writesize > 512 &&
-	    command == NAND_CMD_READOOB) {
-		column += mtd->writesize;
-		command = NAND_CMD_READ0;
-	}
-
-	/* FIXME: Do we need to send read command before sending data
-	   for small-page chips, to position the buffer correctly? */
-
-	if (column != -1) {
-		cafe_writel(cafe, column, NAND_ADDR1);
-		adrbytes = 2;
-		if (page_addr != -1)
-			goto write_adr2;
-	} else if (page_addr != -1) {
-		cafe_writel(cafe, page_addr & 0xffff, NAND_ADDR1);
-		page_addr >>= 16;
-	write_adr2:
-		cafe_writel(cafe, page_addr, NAND_ADDR2);
-		adrbytes += 2;
-		if (mtd->size > mtd->writesize << 16)
-			adrbytes++;
-	}
-
-	cafe->data_pos = cafe->datalen = 0;
-
-	/* Set command valid bit, mask in the chip select bit  */
-	ctl1 = CAFE_NAND_CTRL1_HAS_CMD |
-	       CAFE_FIELD_PREP(NAND_CTRL1, CMD, command) |
-	       (cafe->ctl1 & CAFE_NAND_CTRL1_CE);
-
-	/* Set RD or WR bits as appropriate */
-	if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) {
-		ctl1 |= CAFE_NAND_CTRL1_HAS_DATA_IN;
-		/* Always 5 bytes, for now */
-		cafe->datalen = 4;
-		/* And one address cycle -- even for STATUS, since the controller doesn't work without */
-		adrbytes = 1;
-	} else if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 ||
-		   command == NAND_CMD_READOOB || command == NAND_CMD_RNDOUT) {
-		ctl1 |= CAFE_NAND_CTRL1_HAS_DATA_IN;
-		/* For now, assume just read to end of page */
-		cafe->datalen = mtd->writesize + mtd->oobsize - column;
-	} else if (command == NAND_CMD_SEQIN)
-		ctl1 |= CAFE_NAND_CTRL1_HAS_DATA_OUT;
-
-	/* Set number of address bytes */
-	if (adrbytes)
-		ctl1 |= CAFE_NAND_CTRL1_HAS_ADDR |
-			CAFE_FIELD_PREP(NAND_CTRL1, NUM_ADDR_CYC, adrbytes - 1);
-
-	if (command == NAND_CMD_SEQIN || command == NAND_CMD_ERASE1) {
-		/* Ignore the first command of a pair; the hardware
-		   deals with them both at once, later */
-		cafe->ctl1 = ctl1;
-		dev_dbg(&cafe->pdev->dev, "Setup for delayed command, ctl1 %08x, dlen %x\n",
-			cafe->ctl1, cafe->datalen);
-		return;
-	}
-	/* RNDOUT and READ0 commands need a following byte */
-	if (command == NAND_CMD_RNDOUT)
-		cafe_writel(cafe,
-			    cafe->ctl2 | CAFE_NAND_CTRL2_CMD2 |
-			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, NAND_CMD_RNDOUTSTART),
-			    NAND_CTRL2);
-	else if (command == NAND_CMD_READ0 && mtd->writesize > 512)
-		cafe_writel(cafe,
-			    cafe->ctl2 | CAFE_NAND_CTRL2_CMD2 |
-			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, NAND_CMD_READSTART),
-			    NAND_CTRL2);
-
- do_command:
-	dev_dbg(&cafe->pdev->dev, "dlen %x, ctl1 %x, ctl2 %x\n",
-		cafe->datalen, ctl1, cafe_readl(cafe, NAND_CTRL2));
-
-	/* NB: The datasheet lies -- we really should be subtracting 1 here */
-	cafe_writel(cafe, cafe->datalen, NAND_DATA_LEN);
-	cafe_writel(cafe, CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE,
-		    NAND_IRQ);
-	if (cafe->usedma &&
-	    (ctl1 & (CAFE_NAND_CTRL1_HAS_DATA_IN |
-		     CAFE_NAND_CTRL1_HAS_DATA_OUT))) {
-		uint32_t dmactl = CAFE_NAND_DMA_CTRL_ENABLE |
-				  CAFE_NAND_DMA_CTRL_RESERVED;
-
-		dmactl |= CAFE_FIELD_PREP(NAND_DMA_CTRL, DATA_LEN,
-					  cafe->datalen);
-		/* If WR or RD bits set, set up DMA */
-		if (ctl1 & CAFE_NAND_CTRL1_HAS_DATA_IN) {
-			/* It's a read */
-			dmactl |= CAFE_NAND_DMA_CTRL_DATA_IN;
-			/* ... so it's done when the DMA is done, not just
-			   the command. */
-			doneint = CAFE_NAND_IRQ_DMA_DONE;
-		}
-		cafe_writel(cafe, dmactl, NAND_DMA_CTRL);
-	}
-	cafe->datalen = 0;
-
-	if (unlikely(regdebug)) {
-		int i;
-		printk("About to write command %08x to register 0\n", ctl1);
-		for (i=4; i< 0x5c; i+=4)
-			printk("Register %x: %08x\n", i, readl(cafe->mmio + i));
-	}
-
-	cafe_writel(cafe, ctl1, NAND_CTRL1);
-	/* Apply this short delay always to ensure that we do wait tWB in
-	 * any case on any machine. */
-	ndelay(100);
-
-	if (1) {
-		int c;
-		uint32_t irqs;
-
-		for (c = 500000; c != 0; c--) {
-			irqs = cafe_readl(cafe, NAND_IRQ);
-			if (irqs & doneint)
-				break;
-			udelay(1);
-			if (!(c % 100000))
-				dev_dbg(&cafe->pdev->dev, "Wait for ready, IRQ %x\n", irqs);
-			cpu_relax();
-		}
-		cafe_writel(cafe, doneint, NAND_IRQ);
-		dev_dbg(&cafe->pdev->dev, "Command %x completed after %d usec, irqs %x (%x)\n",
-			command, 500000-c, irqs, cafe_readl(cafe, NAND_IRQ));
-	}
-
-	WARN_ON(cafe->ctl2 & CAFE_NAND_CTRL2_AUTO_WRITE_ECC);
-
-	switch (command) {
-
-	case NAND_CMD_CACHEDPROG:
-	case NAND_CMD_PAGEPROG:
-	case NAND_CMD_ERASE1:
-	case NAND_CMD_ERASE2:
-	case NAND_CMD_SEQIN:
-	case NAND_CMD_RNDIN:
-	case NAND_CMD_STATUS:
-	case NAND_CMD_RNDOUT:
-		cafe_writel(cafe, cafe->ctl2, NAND_CTRL2);
-		return;
-	}
-	nand_wait_ready(chip);
-	cafe_writel(cafe, cafe->ctl2, NAND_CTRL2);
-}
-
-static void cafe_select_chip(struct nand_chip *chip, int chipnr)
-{
-	struct cafe_priv *cafe = nand_get_controller_data(chip);
-
-	if (chipnr < 0 || chipnr > 1)
-		return;
-
-	dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
-
-	/* Mask the appropriate bit into the stored value of ctl1
-	   which will be used by cafe_nand_cmdfunc() */
-	cafe->ctl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, chipnr);
+	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from read buffer.\n", len);
 }
 
 static irqreturn_t cafe_nand_interrupt(int irq, void *id)
@@ -788,7 +560,6 @@ static int cafe_nand_exec_subop(struct nand_chip *chip,
 	if (WARN_ON(subop->cs > 1))
 		return -EINVAL;
 
-	cafe->datalen = 0;
 	ctrl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, subop->cs);
 
 	for (i = 0; i < subop->ninstrs; i++) {
@@ -1018,17 +789,6 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 		goto out_ior;
 	}
 
-	cafe->nand.legacy.cmdfunc = cafe_nand_cmdfunc;
-	cafe->nand.legacy.dev_ready = cafe_device_ready;
-	cafe->nand.legacy.read_byte = cafe_read_byte;
-	cafe->nand.legacy.read_buf = cafe_read_buf;
-	cafe->nand.legacy.write_buf = cafe_write_buf;
-	cafe->nand.legacy.select_chip = cafe_select_chip;
-	cafe->nand.legacy.set_features = nand_get_set_features_notsupp;
-	cafe->nand.legacy.get_features = nand_get_set_features_notsupp;
-
-	cafe->nand.legacy.chip_delay = 0;
-
 	/* Enable the following for a flash based bad block table */
 	cafe->nand.bbt_options = NAND_BBT_USE_FLASH;
 
-- 
2.25.3


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

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

* [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read, write}_buf() prototypes
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (13 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 14/17] mtd: rawnand: cafe: Get rid of the legacy interface implementation Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 20:00   ` [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read,write}_buf() prototypes Miquel Raynal
  2020-04-27  8:20 ` [PATCH 16/17] mtd: rawnand: cafe: Handle non-32bit aligned reads/writes Boris Brezillon
                   ` (4 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Replace the uint8_t pointer by a void pointer and make the length
unsigned so it matches what's passed through the nand instructions.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 5b38d496d923..26495085f285 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -179,7 +179,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 #define cafe_readl(cafe, addr)			readl((cafe)->mmio + CAFE_##addr)
 #define cafe_writel(cafe, datum, addr)		writel(datum, (cafe)->mmio + CAFE_##addr)
 
-static void cafe_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)
+static void cafe_write_buf(struct nand_chip *chip, const void *buf,
+			   unsigned int len)
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
@@ -191,7 +192,7 @@ static void cafe_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)
 	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer.\n",	len);
 }
 
-static void cafe_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
+static void cafe_read_buf(struct nand_chip *chip, void *buf, unsigned int len)
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
-- 
2.25.3


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

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

* [PATCH 16/17] mtd: rawnand: cafe: Handle non-32bit aligned reads/writes
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (14 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read, write}_buf() prototypes Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 20:04   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 17/17] mtd: rawnand: cafe: s/uint{8,16,32}_t/u{8,16,32}/ Boris Brezillon
                   ` (3 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

The spec says the write/read buffers should be filled/read 32bits at a
time. While most of the time the reads/writes are aligned on 4 bytes,
we should make the implementation more robust to non-usual NAND
operations.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 26495085f285..955dc78c57be 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -184,10 +184,18 @@ static void cafe_write_buf(struct nand_chip *chip, const void *buf,
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
-	if (cafe->usedma)
+	if (cafe->usedma) {
 		memcpy(cafe->dmabuf, buf, len);
-	else
-		memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA, buf, len);
+	} else {
+		memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA, buf,
+			    len & ~0x3);
+		if (len & 0x3) {
+			u32 tmp = 0;
+
+			memcpy(&tmp, buf + (len & ~0x3), len & 0x3);
+			cafe_writel(cafe, tmp, NAND_WRITE_DATA);
+		}
+	}
 
 	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer.\n",	len);
 }
@@ -196,10 +204,17 @@ static void cafe_read_buf(struct nand_chip *chip, void *buf, unsigned int len)
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
-	if (cafe->usedma)
+	if (cafe->usedma) {
 		memcpy(buf, cafe->dmabuf, len);
-	else
-		memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA, len);
+	} else {
+		memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA,
+			      len & ~0x3);
+		if (len & 0x3) {
+			u32 tmp = cafe_readl(cafe, NAND_READ_DATA);
+
+			memcpy(buf + (len & ~0x3), &tmp, len & 0x3);
+		}
+	}
 
 	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from read buffer.\n", len);
 }
-- 
2.25.3


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

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

* [PATCH 17/17] mtd: rawnand: cafe: s/uint{8,16,32}_t/u{8,16,32}/
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (15 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 16/17] mtd: rawnand: cafe: Handle non-32bit aligned reads/writes Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27 20:05   ` Miquel Raynal
  2020-04-27  8:20 ` [PATCH 17/17] mtd: rawnand: s/uint{8,16,32}_t/u{8,16,32}/ Boris Brezillon
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Replace uint{8,16,32}_t by u{8,16,32} to make checkpatch happy.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 955dc78c57be..658c95804297 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -151,7 +151,7 @@ struct cafe_priv {
 	struct pci_dev *pdev;
 	void __iomem *mmio;
 	struct rs_control *rs;
-	uint32_t ctl2;
+	u32 ctl2;
 	bool usedma;
 	dma_addr_t dmaaddr;
 	unsigned char *dmabuf;
@@ -224,7 +224,7 @@ static irqreturn_t cafe_nand_interrupt(int irq, void *id)
 	struct mtd_info *mtd = id;
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
-	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
+	u32 irqs = cafe_readl(cafe, NAND_IRQ);
 	cafe_writel(cafe,
 		    irqs & ~(CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE),
 		    NAND_IRQ);
@@ -255,7 +255,7 @@ static int cafe_nand_read_oob(struct nand_chip *chip, int page)
  * The hw generator calculates the error syndrome automatically. Therefore
  * we need a special oob layout and handling.
  */
-static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
+static int cafe_nand_read_page(struct nand_chip *chip, u8 *buf,
 			       int oob_required, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
@@ -283,8 +283,8 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
 		int i, n;
 
 		for (i=0; i<8; i+=2) {
-			uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN_REG(i));
-			uint16_t idx;
+			u32 tmp = cafe_readl(cafe, NAND_ECC_SYN_REG(i));
+			u16 idx;
 
 			idx = FIELD_GET(CAFE_NAND_ECC_SYN_FIELD(i), tmp);
 			syn[i] = cafe->rs->codec->index_of[idx];
@@ -380,11 +380,11 @@ static const struct mtd_ooblayout_ops cafe_ooblayout_ops = {
 
 /* Ick. The BBT code really ought to be able to work this bit out
    for itself from the above, at least for the 2KiB case */
-static uint8_t cafe_bbt_pattern_2048[] = { 'B', 'b', 't', '0' };
-static uint8_t cafe_mirror_pattern_2048[] = { '1', 't', 'b', 'B' };
+static u8 cafe_bbt_pattern_2048[] = { 'B', 'b', 't', '0' };
+static u8 cafe_mirror_pattern_2048[] = { '1', 't', 'b', 'B' };
 
-static uint8_t cafe_bbt_pattern_512[] = { 0xBB };
-static uint8_t cafe_mirror_pattern_512[] = { 0xBC };
+static u8 cafe_bbt_pattern_512[] = { 0xBB };
+static u8 cafe_mirror_pattern_512[] = { 0xBC };
 
 
 static struct nand_bbt_descr cafe_bbt_main_descr_2048 = {
@@ -429,7 +429,7 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
 
 
 static int cafe_nand_write_page(struct nand_chip *chip,
-				const uint8_t *buf, int oob_required,
+				const u8 *buf, int oob_required,
 				int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
-- 
2.25.3


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

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

* [PATCH 17/17] mtd: rawnand: s/uint{8,16,32}_t/u{8,16,32}/
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (16 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 17/17] mtd: rawnand: cafe: s/uint{8,16,32}_t/u{8,16,32}/ Boris Brezillon
@ 2020-04-27  8:20 ` Boris Brezillon
  2020-04-27  8:25   ` Boris Brezillon
  2020-04-29  6:37 ` [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Thomas Petazzoni
       [not found] ` <20200502112732.330971-1-lkundrak@v3.sk>
  19 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:20 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Boris Brezillon, Vignesh Raghavendra, Tudor Ambarus

Replace uint{8,16,32}_t by u{8,16,32} to make checkpatch happy.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 955dc78c57be..658c95804297 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -151,7 +151,7 @@ struct cafe_priv {
 	struct pci_dev *pdev;
 	void __iomem *mmio;
 	struct rs_control *rs;
-	uint32_t ctl2;
+	u32 ctl2;
 	bool usedma;
 	dma_addr_t dmaaddr;
 	unsigned char *dmabuf;
@@ -224,7 +224,7 @@ static irqreturn_t cafe_nand_interrupt(int irq, void *id)
 	struct mtd_info *mtd = id;
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
-	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
+	u32 irqs = cafe_readl(cafe, NAND_IRQ);
 	cafe_writel(cafe,
 		    irqs & ~(CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE),
 		    NAND_IRQ);
@@ -255,7 +255,7 @@ static int cafe_nand_read_oob(struct nand_chip *chip, int page)
  * The hw generator calculates the error syndrome automatically. Therefore
  * we need a special oob layout and handling.
  */
-static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
+static int cafe_nand_read_page(struct nand_chip *chip, u8 *buf,
 			       int oob_required, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
@@ -283,8 +283,8 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
 		int i, n;
 
 		for (i=0; i<8; i+=2) {
-			uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN_REG(i));
-			uint16_t idx;
+			u32 tmp = cafe_readl(cafe, NAND_ECC_SYN_REG(i));
+			u16 idx;
 
 			idx = FIELD_GET(CAFE_NAND_ECC_SYN_FIELD(i), tmp);
 			syn[i] = cafe->rs->codec->index_of[idx];
@@ -380,11 +380,11 @@ static const struct mtd_ooblayout_ops cafe_ooblayout_ops = {
 
 /* Ick. The BBT code really ought to be able to work this bit out
    for itself from the above, at least for the 2KiB case */
-static uint8_t cafe_bbt_pattern_2048[] = { 'B', 'b', 't', '0' };
-static uint8_t cafe_mirror_pattern_2048[] = { '1', 't', 'b', 'B' };
+static u8 cafe_bbt_pattern_2048[] = { 'B', 'b', 't', '0' };
+static u8 cafe_mirror_pattern_2048[] = { '1', 't', 'b', 'B' };
 
-static uint8_t cafe_bbt_pattern_512[] = { 0xBB };
-static uint8_t cafe_mirror_pattern_512[] = { 0xBC };
+static u8 cafe_bbt_pattern_512[] = { 0xBB };
+static u8 cafe_mirror_pattern_512[] = { 0xBC };
 
 
 static struct nand_bbt_descr cafe_bbt_main_descr_2048 = {
@@ -429,7 +429,7 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
 
 
 static int cafe_nand_write_page(struct nand_chip *chip,
-				const uint8_t *buf, int oob_required,
+				const u8 *buf, int oob_required,
 				int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
-- 
2.25.3


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

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

* Re: [PATCH 17/17] mtd: rawnand: s/uint{8,16,32}_t/u{8,16,32}/
  2020-04-27  8:20 ` [PATCH 17/17] mtd: rawnand: s/uint{8,16,32}_t/u{8,16,32}/ Boris Brezillon
@ 2020-04-27  8:25   ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-04-27  8:25 UTC (permalink / raw)
  To: David Woodhouse, Miquel Raynal, linux-mtd
  Cc: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus

On Mon, 27 Apr 2020 10:20:28 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:

> Replace uint{8,16,32}_t by u{8,16,32} to make checkpatch happy.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

Please ignore that one, it's just a duplicate of the other patch 17
but with a wrong prefix in the subject.

> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 955dc78c57be..658c95804297 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -151,7 +151,7 @@ struct cafe_priv {
>  	struct pci_dev *pdev;
>  	void __iomem *mmio;
>  	struct rs_control *rs;
> -	uint32_t ctl2;
> +	u32 ctl2;
>  	bool usedma;
>  	dma_addr_t dmaaddr;
>  	unsigned char *dmabuf;
> @@ -224,7 +224,7 @@ static irqreturn_t cafe_nand_interrupt(int irq, void *id)
>  	struct mtd_info *mtd = id;
>  	struct nand_chip *chip = mtd_to_nand(mtd);
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> -	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
> +	u32 irqs = cafe_readl(cafe, NAND_IRQ);
>  	cafe_writel(cafe,
>  		    irqs & ~(CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE),
>  		    NAND_IRQ);
> @@ -255,7 +255,7 @@ static int cafe_nand_read_oob(struct nand_chip *chip, int page)
>   * The hw generator calculates the error syndrome automatically. Therefore
>   * we need a special oob layout and handling.
>   */
> -static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
> +static int cafe_nand_read_page(struct nand_chip *chip, u8 *buf,
>  			       int oob_required, int page)
>  {
>  	struct mtd_info *mtd = nand_to_mtd(chip);
> @@ -283,8 +283,8 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
>  		int i, n;
>  
>  		for (i=0; i<8; i+=2) {
> -			uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN_REG(i));
> -			uint16_t idx;
> +			u32 tmp = cafe_readl(cafe, NAND_ECC_SYN_REG(i));
> +			u16 idx;
>  
>  			idx = FIELD_GET(CAFE_NAND_ECC_SYN_FIELD(i), tmp);
>  			syn[i] = cafe->rs->codec->index_of[idx];
> @@ -380,11 +380,11 @@ static const struct mtd_ooblayout_ops cafe_ooblayout_ops = {
>  
>  /* Ick. The BBT code really ought to be able to work this bit out
>     for itself from the above, at least for the 2KiB case */
> -static uint8_t cafe_bbt_pattern_2048[] = { 'B', 'b', 't', '0' };
> -static uint8_t cafe_mirror_pattern_2048[] = { '1', 't', 'b', 'B' };
> +static u8 cafe_bbt_pattern_2048[] = { 'B', 'b', 't', '0' };
> +static u8 cafe_mirror_pattern_2048[] = { '1', 't', 'b', 'B' };
>  
> -static uint8_t cafe_bbt_pattern_512[] = { 0xBB };
> -static uint8_t cafe_mirror_pattern_512[] = { 0xBC };
> +static u8 cafe_bbt_pattern_512[] = { 0xBB };
> +static u8 cafe_mirror_pattern_512[] = { 0xBC };
>  
>  
>  static struct nand_bbt_descr cafe_bbt_main_descr_2048 = {
> @@ -429,7 +429,7 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
>  
>  
>  static int cafe_nand_write_page(struct nand_chip *chip,
> -				const uint8_t *buf, int oob_required,
> +				const u8 *buf, int oob_required,
>  				int page)
>  {
>  	struct mtd_info *mtd = nand_to_mtd(chip);


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

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

* Re: [PATCH 01/17] mtd: rawnand: cafe: Get rid of an inaccurate kernel doc header
  2020-04-27  8:20 ` [PATCH 01/17] mtd: rawnand: cafe: Get rid of an inaccurate kernel doc header Boris Brezillon
@ 2020-04-27 19:33   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:33 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:11 +0200:

> Driver files are not parsed for doc generation, and the
> cafe_nand_read_page() kernel-doc header was wrong, so let's get rid of
> it.

Really? I didn't know. I like kernel doc syntax which is simple and
colorful when you have a decent editor but in this case it is indeed
useless.

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
 
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 9 ++-------
>  1 file changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 2a0df13df5f3..1296380a4996 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -357,13 +357,8 @@ static int cafe_nand_read_oob(struct nand_chip *chip, int page)
>  
>  	return nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
>  }
> -/**
> - * cafe_nand_read_page_syndrome - [REPLACEABLE] hardware ecc syndrome based page read
> - * @mtd:	mtd info structure
> - * @chip:	nand chip info structure
> - * @buf:	buffer to store read data
> - * @oob_required:	caller expects OOB data read to chip->oob_poi
> - *
> +
> +/*
>   * The hw generator calculates the error syndrome automatically. Therefore
>   * we need a special oob layout and handling.
>   */


Thanks,
Miquèl

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

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

* Re: [PATCH 02/17] mtd: rawnand: cafe: Rename cafe_nand_write_page_lowlevel()
  2020-04-27  8:20 ` [PATCH 02/17] mtd: rawnand: cafe: Rename cafe_nand_write_page_lowlevel() Boris Brezillon
@ 2020-04-27 19:33   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:33 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:12 +0200:

> Let's rename that one cafe_nand_write_page() to be consistent with other
> function names.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 1296380a4996..03964e092243 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -525,9 +525,9 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
>  };
>  
>  
> -static int cafe_nand_write_page_lowlevel(struct nand_chip *chip,
> -					 const uint8_t *buf, int oob_required,
> -					 int page)
> +static int cafe_nand_write_page(struct nand_chip *chip,
> +				const uint8_t *buf, int oob_required,
> +				int page)
>  {
>  	struct mtd_info *mtd = nand_to_mtd(chip);
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> @@ -628,7 +628,7 @@ static int cafe_nand_attach_chip(struct nand_chip *chip)
>  	cafe->nand.ecc.size = mtd->writesize;
>  	cafe->nand.ecc.bytes = 14;
>  	cafe->nand.ecc.strength = 4;
> -	cafe->nand.ecc.write_page = cafe_nand_write_page_lowlevel;
> +	cafe->nand.ecc.write_page = cafe_nand_write_page;
>  	cafe->nand.ecc.write_oob = cafe_nand_write_oob;
>  	cafe->nand.ecc.read_page = cafe_nand_read_page;
>  	cafe->nand.ecc.read_oob = cafe_nand_read_oob;


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


Thanks,
Miquèl

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

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

* Re: [PATCH 03/17] mtd: rawnand: cafe: Use a correct ECC mode and pass the ECC alg
  2020-04-27  8:20 ` [PATCH 03/17] mtd: rawnand: cafe: Use a correct ECC mode and pass the ECC alg Boris Brezillon
@ 2020-04-27 19:34   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:34 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:13 +0200:

> The NAND_ECC_HW_SYNDROME name is a bit misleading. It's actually used
> for drivers that interleave data and ECC bytes inside a page, which is
> not the case here. Let's fix that and pass the ECC algorithm used by the
> ECC engine.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 03964e092243..47aacfab8ecb 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -624,7 +624,8 @@ static int cafe_nand_attach_chip(struct nand_chip *chip)
>  		goto out_free_dma;
>  	}
>  
> -	cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
> +	cafe->nand.ecc.mode = NAND_ECC_HW;
> +	cafe->nand.ecc.algo = NAND_ECC_RS;
>  	cafe->nand.ecc.size = mtd->writesize;
>  	cafe->nand.ecc.bytes = 14;
>  	cafe->nand.ecc.strength = 4;


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


Thanks,
Miquèl

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

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

* Re: [PATCH 04/17] mtd: rawnand: cafe: Include linux/io.h instead of asm/io.h
  2020-04-27  8:20 ` [PATCH 04/17] mtd: rawnand: cafe: Include linux/io.h instead of asm/io.h Boris Brezillon
@ 2020-04-27 19:35   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:35 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:14 +0200:

> Drivers should include the asm headers directly.

                not ?

> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

With this changed,

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

> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 47aacfab8ecb..156a308b530b 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -23,7 +23,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>
> -#include <asm/io.h>
> +#include <linux/io.h>
>  
>  #define CAFE_NAND_CTRL1		0x00
>  #define CAFE_NAND_CTRL2		0x04

Thanks,
Miquèl

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

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

* Re: [PATCH 05/17] mtd: rawnand: cafe: Demistify register fields
  2020-04-27  8:20 ` [PATCH 05/17] mtd: rawnand: cafe: Demistify register fields Boris Brezillon
@ 2020-04-27 19:42   ` Miquel Raynal
  2020-04-28  6:06     ` Boris Brezillon
  0 siblings, 1 reply; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:42 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:15 +0200:

> The driver has a bunch of magic values. Let's define proper register
> fields based on the this spec

                  ^^^/^^^^
either one or the other

> http://wiki.laptop.org/images/5/5c/88ALP01_Datasheet_July_2007.pdf and
> use them.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 351 ++++++++++++++++++++++++-------
>  1 file changed, 270 insertions(+), 81 deletions(-)
> 

[...]

> +#define CAFE_GLOBAL_IRQ				0x3008
> +#define CAFE_GLOBAL_IRQ_MASK			0x300c
> +#define CAFE_GLOBAL_IRQ_PCI_ERROR		BIT(31)
> +#define CAFE_GLOBAL_IRQ_VPD_TWSI		BIT(26)
> +#define CAFE_GLOBAL_IRQ_CCIC			BIT(2)
> +#define CAFE_GLOBAL_IRQ_SDH			BIT(1)
> +#define CAFE_GLOBAL_IRQ_NAND			BIT(0)
> +
> +#define CAFE_GLOBAL_RESET			0x3034
> +#define CAFE_GLOBAL_RESET_CCIC			BIT(2)
> +#define CAFE_GLOBAL_RESET_SDH			BIT(1)
> +#define CAFE_GLOBAL_RESET_NAND			BIT(0)
> +
> +#define CAFE_FIELD_PREP(reg, field, val)	FIELD_PREP(CAFE_##reg##_##field, val)
> +#define CAFE_FIELD_GET(reg, field, val)		FIELD_GET(CAFE_##reg##_##field, val)

hehe :)

>  
>  struct cafe_priv {
>  	struct nand_chip nand;
> @@ -104,7 +195,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
>  static int cafe_device_ready(struct nand_chip *chip)
>  {
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> -	int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000);
> +	int result = !!(cafe_readl(cafe, NAND_STATUS) &
> +			CAFE_NAND_STATUS_FLASH_BUSY);
>  	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
>  
>  	cafe_writel(cafe, irqs, NAND_IRQ);

[...]

> @@ -318,14 +430,14 @@ static void cafe_select_chip(struct nand_chip *chip, int chipnr)
>  {
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
>  
> +	if (chipnr < 0 || chipnr > 1)
> +		return;
> +

I think this change should not be part of this patch?

>  	cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
>  
>  	/* Mask the appropriate bit into the stored value of ctl1
>  	   which will be used by cafe_nand_cmdfunc() */
> -	if (chipnr)
> -		cafe->ctl1 |= CTRL1_CHIPSELECT;
> -	else
> -		cafe->ctl1 &= ~CTRL1_CHIPSELECT;
> +	cafe->ctl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, chipnr);

I don't master these macros yet, but are you sure CTRL1_CHIPSELECT will
actually get cleared if (!chipnr) ?

>  }
>  
>  static irqreturn_t cafe_nand_interrupt(int irq, void *id)
> @@ -334,7 +446,9 @@ static irqreturn_t cafe_nand_interrupt(int irq, void *id)
>  	struct nand_chip *chip = mtd_to_nand(mtd);
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
>  	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
> -	cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ);
> +	cafe_writel(cafe,
> +		    irqs & ~(CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE),
> +		    NAND_IRQ);
>  	if (!irqs)
>  		return IRQ_NONE;
>  


Thanks,
Miquèl

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

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

* Re: [PATCH 06/17] mtd: rawnand: cafe: Factor out the controller initialization logic
  2020-04-27  8:20 ` [PATCH 06/17] mtd: rawnand: cafe: Factor out the controller initialization logic Boris Brezillon
@ 2020-04-27 19:45   ` Miquel Raynal
  2020-04-28  6:06     ` Boris Brezillon
  0 siblings, 1 reply; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:45 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:16 +0200:

> The same code is present in the probe and resume path. Let's create
> an init helper to factor that out.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

Nice catch! A nitpick below.

> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 189 +++++++++++--------------------
>  1 file changed, 67 insertions(+), 122 deletions(-)
> 

[...]

> @@ -980,74 +988,11 @@ MODULE_DEVICE_TABLE(pci, cafe_nand_tbl);
>  
>  static int cafe_nand_resume(struct pci_dev *pdev)
>  {
> -	uint32_t ctrl;
>  	struct mtd_info *mtd = pci_get_drvdata(pdev);
>  	struct nand_chip *chip = mtd_to_nand(mtd);
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
>  
> -       /* Start off by resetting the NAND controller completely */
> -	cafe_writel(cafe, CAFE_GLOBAL_RESET_NAND, GLOBAL_RESET);
> -	cafe_writel(cafe, 0, GLOBAL_RESET);
> -	cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
> -
> -	/* Restore timing configuration */
> -	cafe_writel(cafe, timing[0], NAND_TIMING1);
> -	cafe_writel(cafe, timing[1], NAND_TIMING2);
> -	cafe_writel(cafe, timing[2], NAND_TIMING3);
> -
> -        /* Disable master reset, enable NAND clock */
> -	ctrl = cafe_readl(cafe, GLOBAL_CTRL);
> -	ctrl &= ~(CAFE_GLOBAL_SW_RESET_SET |
> -		  CAFE_GLOBAL_SW_RESET_CLEAR |
> -		  CAFE_GLOBAL_MASTER_RESET_SET |
> -		  CAFE_GLOBAL_MASTER_RESET_CLEAR |
> -		  CAFE_GLOBAL_NAND_CLK_ENABLE);
> -	ctrl |= CAFE_GLOBAL_NAND_CLK_ENABLE |
> -		CAFE_GLOBAL_SDH_CLK_ENABLE |
> -		CAFE_GLOBAL_CCIC_CLK_ENABLE;
> -	cafe_writel(cafe,
> -		    ctrl |
> -		    CAFE_GLOBAL_MASTER_RESET_SET |
> -		    CAFE_GLOBAL_SW_RESET_SET,
> -		    GLOBAL_CTRL);
> -	cafe_writel(cafe,
> -		    ctrl |
> -		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
> -		    CAFE_GLOBAL_SW_RESET_CLEAR,
> -		    GLOBAL_CTRL);
> -
> -	cafe_writel(cafe, 0, NAND_DMA_CTRL);
> -
> -	cafe_writel(cafe,
> -		    CAFE_GLOBAL_NAND_CLK_ENABLE |
> -		    CAFE_GLOBAL_SDH_CLK_ENABLE |
> -		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
> -		    CAFE_GLOBAL_MASTER_RESET_SET |
> -		    CAFE_GLOBAL_SW_RESET_CLEAR,
> -		    GLOBAL_CTRL);
> -	cafe_writel(cafe,
> -		    CAFE_GLOBAL_NAND_CLK_ENABLE |
> -		    CAFE_GLOBAL_SDH_CLK_ENABLE |
> -		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
> -		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
> -		    CAFE_GLOBAL_SW_RESET_CLEAR,
> -		    GLOBAL_CTRL);
> -
> -	/* Set up DMA address */
> -	cafe_writel(cafe, cafe->dmaaddr & 0xffffffff, NAND_DMA_ADDR0);
> -	if (sizeof(cafe->dmaaddr) > 4)
> -	/* Shift in two parts to shut the compiler up */
> -		cafe_writel(cafe, (cafe->dmaaddr >> 16) >> 16, NAND_DMA_ADDR1);
> -	else
> -		cafe_writel(cafe, 0, NAND_DMA_ADDR1);
> -
> -	/* Enable NAND IRQ in global IRQ mask register */
> -	cafe_writel(cafe,
> -		    CAFE_GLOBAL_IRQ_PCI_ERROR |
> -		    CAFE_GLOBAL_IRQ_CCIC |
> -		    CAFE_GLOBAL_IRQ_SDH |
> -		    CAFE_GLOBAL_IRQ_NAND,
> -		    GLOBAL_IRQ_MASK);
> +	cafe_nand_init(cafe);

A new line would be nice here :p

>  	return 0;
>  }
>  

Thanks,
Miquèl

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

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

* Re: [PATCH 07/17] mtd: rawnand: cafe: Get rid of the debug module param
  2020-04-27  8:20 ` [PATCH 07/17] mtd: rawnand: cafe: Get rid of the debug module param Boris Brezillon
@ 2020-04-27 19:46   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:46 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:17 +0200:

> Dynamic prink already offers conditional debug traces enablement, let's
> not define a new way to do the same thing.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---

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


Thanks,
Miquèl

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

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

* Re: [PATCH 08/17] mtd: rawnand: cafe: Use devm_kzalloc and devm_request_irq()
  2020-04-27  8:20 ` [PATCH 08/17] mtd: rawnand: cafe: Use devm_kzalloc and devm_request_irq() Boris Brezillon
@ 2020-04-27 19:47   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:47 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:18 +0200:

> This simplifies the error/remove path.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---

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


Thanks,
Miquèl

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

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

* Re: [PATCH 09/17] mtd: rawnand: cafe: Get rid of a useless label
  2020-04-27  8:20 ` [PATCH 09/17] mtd: rawnand: cafe: Get rid of a useless label Boris Brezillon
@ 2020-04-27 19:47   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:47 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:19 +0200:

> We can return 0 directly instead of branching to the out label.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 3eab57e63215..348debbc04af 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -932,7 +932,7 @@ static int cafe_nand_probe(struct pci_dev *pdev,
>  	if (err)
>  		goto out_cleanup_nand;
>  
> -	goto out;
> +	return 0;
>  
>   out_cleanup_nand:
>  	nand_cleanup(&cafe->nand);
> @@ -943,7 +943,6 @@ static int cafe_nand_probe(struct pci_dev *pdev,
>  		    GLOBAL_IRQ_MASK);
>   out_ior:
>  	pci_iounmap(pdev, cafe->mmio);
> - out:
>  	return err;
>  }
>  


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


Thanks,
Miquèl

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

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

* Re: [PATCH 10/17] mtd: rawnand: cafe: Explicitly inherit from nand_controller
  2020-04-27  8:20 ` [PATCH 10/17] mtd: rawnand: cafe: Explicitly inherit from nand_controller Boris Brezillon
@ 2020-04-27 19:49   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:49 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:20 +0200:

> Explicitly inherit from nand_controller instead of using the dummy
> controller object.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 348debbc04af..2825489a71b8 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -146,6 +146,7 @@
>  #define CAFE_FIELD_GET(reg, field, val)		FIELD_GET(CAFE_##reg##_##field, val)
>  
>  struct cafe_priv {
> +	struct nand_controller base;
>  	struct nand_chip nand;
>  	struct pci_dev *pdev;
>  	void __iomem *mmio;
> @@ -920,7 +921,9 @@ static int cafe_nand_probe(struct pci_dev *pdev,
>  	cafe->usedma = 0;
>  
>  	/* Scan to find existence of the device */
> -	cafe->nand.legacy.dummy_controller.ops = &cafe_nand_controller_ops;
> +	nand_controller_init(&cafe->base);
> +	cafe->base.ops = &cafe_nand_controller_ops;
> +	cafe->nand.controller = &cafe->base;
>  	err = nand_scan(&cafe->nand, 2);
>  	if (err)
>  		goto out_irq;

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


Thanks,
Miquèl

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

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

* Re: [PATCH 11/17] mtd: rawnand: cafe: Don't leave ECC enabled in the write path
  2020-04-27  8:20 ` [PATCH 11/17] mtd: rawnand: cafe: Don't leave ECC enabled in the write path Boris Brezillon
@ 2020-04-27 19:51   ` Miquel Raynal
  2020-04-28  6:08     ` Boris Brezillon
  0 siblings, 1 reply; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:51 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:21 +0200:

> cafe_nand_write_page_lowlevel() sets the ECC auto-generation flag but

IIRC you renamed this function in patch 1 so now it is named
"_write_page()".

> never clears it, thus forcing the cafe_nand_cmdfunc() to clear it
> in certain circumstances. Let's just clear this flag in
> cafe_nand_write_page_lowlevel() instead.

Same here              ^

> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 2825489a71b8..31493a201a02 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -261,7 +261,6 @@ static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
>  			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, command),
>  			    NAND_CTRL2);
>  		ctl1 = cafe->ctl1;
> -		cafe->ctl2 &= ~CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
>  		dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n",
>  			cafe->ctl1, cafe->nr_data);
>  		goto do_command;
> @@ -643,6 +642,7 @@ static int cafe_nand_write_page(struct nand_chip *chip,
>  {
>  	struct mtd_info *mtd = nand_to_mtd(chip);
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> +	int ret;
>  
>  	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
>  	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
> @@ -650,7 +650,14 @@ static int cafe_nand_write_page(struct nand_chip *chip,
>  	/* Set up ECC autogeneration */
>  	cafe->ctl2 |= CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
>  
> -	return nand_prog_page_end_op(chip);
> +	ret = nand_prog_page_end_op(chip);
> +
> +	/*
> +	 * And clear it before returning so that following write operations
> +	 * that do not involve ECC don't generate ECC bytes.
> +	 */
> +	cafe->ctl2 &= ~CAFE_NAND_CTRL2_AUTO_WRITE_ECC;

I like spaces before returning, but again it's really a nitpick, you
can ignore that :)

> +	return ret;
>  }
>  
>  /* F_2[X]/(X**6+X+1)  */


With the commit log updated

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

Thanks,
Miquèl

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

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

* Re: [PATCH 12/17] mtd: rawnand: cafe: Don't split things when reading/writing a page
  2020-04-27  8:20 ` [PATCH 12/17] mtd: rawnand: cafe: Don't split things when reading/writing a page Boris Brezillon
@ 2020-04-27 19:53   ` Miquel Raynal
  2020-04-28  6:20     ` Boris Brezillon
  0 siblings, 1 reply; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:53 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:22 +0200:

> Calling nand_read_page_op(pagesize)/nand_prog_page_begin_op(pagesize)
> and expecting to get a pagesize+oobsize read from/written to the
> read/write buffer is fragile and only works because of hacks done
> in cmdfunc(). Let's read/write the page in one go, using the page
> cache buffer as a bounce buffer.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 31493a201a02..edf65197604b 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -472,6 +472,7 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
>  {
>  	struct mtd_info *mtd = nand_to_mtd(chip);
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> +	void *pagebuf = nand_get_data_buf(chip);
>  	unsigned int max_bitflips = 0;
>  	u32 ecc_result, status;
>  
> @@ -479,8 +480,11 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
>  		cafe_readl(cafe, NAND_ECC_RESULT),
>  		cafe_readl(cafe, NAND_ECC_SYN_REG(0)));
>  
> -	nand_read_page_op(chip, page, 0, buf, mtd->writesize);
> -	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);
> +	nand_read_page_op(chip, page, 0, pagebuf,
> +			  mtd->writesize + mtd->oobsize);
> +
> +	if (buf != pagebuf)
> +		memcpy(buf, pagebuf, mtd->writesize);
>  
>  	ecc_result = cafe_readl(cafe, NAND_ECC_RESULT);
>  	status = CAFE_FIELD_GET(NAND_ECC_RESULT, STATUS, ecc_result);
> @@ -642,15 +646,17 @@ static int cafe_nand_write_page(struct nand_chip *chip,
>  {
>  	struct mtd_info *mtd = nand_to_mtd(chip);
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> +	void *pagebuf = nand_get_data_buf(chip);
>  	int ret;
>  
> -	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
> -	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
> +	if (pagebuf != buf)
> +		memcpy(pagebuf, buf, mtd->writesize);
>  
>  	/* Set up ECC autogeneration */
>  	cafe->ctl2 |= CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
>  
> -	ret = nand_prog_page_end_op(chip);
> +	ret = nand_prog_page_op(chip, page, 0, pagebuf,
> +				mtd->writesize + mtd->oobsize);
>  
>  	/*
>  	 * And clear it before returning so that following write operations


You are replacing ->read/write_buf() calls into memcpy() calls,
shouldn't this be cleaned before? or at least mentioned?

Thanks,
Miquèl

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
  2020-04-27  8:20 ` [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support Boris Brezillon
@ 2020-04-27 19:59   ` Miquel Raynal
  2020-04-28  6:24     ` Boris Brezillon
       [not found]   ` <20200502111410.330584-1-lkundrak@v3.sk>
  1 sibling, 1 reply; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 19:59 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:23 +0200:

> Implementing exec_op() will help us get rid of the legacy interface and
> should make drivers much cleaner too.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 137 ++++++++++++++++++++++++++++++-
>  1 file changed, 136 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index edf65197604b..ada9c8b06a41 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -21,7 +21,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>
> -#include <linux/io.h>
> +#include <linux/iopoll.h>
>  
>  #define CAFE_NAND_CTRL1				0x00
>  #define CAFE_NAND_CTRL1_HAS_CMD			BIT(31)
> @@ -774,9 +774,144 @@ static void cafe_nand_detach_chip(struct nand_chip *chip)
>  	dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr);
>  }
>  
> +static int cafe_nand_exec_subop(struct nand_chip *chip,
> +				const struct nand_subop *subop)
> +{
> +	struct cafe_priv *cafe = nand_get_controller_data(chip);
> +	u32 ctrl1 = 0, ctrl2 = cafe->ctl2, addr1 = 0, addr2 = 0;
> +	const struct nand_op_instr *data_instr = NULL;
> +	u32 status, wait = CAFE_NAND_IRQ_CMD_DONE;
> +	bool waitrdy = false;
> +	unsigned int i, j;
> +	int ret;
> +
> +	if (WARN_ON(subop->cs > 1))
> +		return -EINVAL;
> +
> +	cafe->datalen = 0;
> +	ctrl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, subop->cs);
> +
> +	for (i = 0; i < subop->ninstrs; i++) {
> +		const struct nand_op_instr *instr = &subop->instrs[i];
> +
> +		switch (instr->type) {
> +		case NAND_OP_CMD_INSTR:
> +			if (WARN_ON((ctrl1 & CAFE_NAND_CTRL1_HAS_CMD) &&
> +				    (ctrl2 & CAFE_NAND_CTRL2_HAS_CMD2)))
> +				return -EINVAL;

Same comment as in the previous drivers, just showing it to do not
foget.

> +
> +			if (!(ctrl1 & CAFE_NAND_CTRL1_HAS_CMD))
> +				ctrl1 |= CAFE_NAND_CTRL1_HAS_CMD |
> +					 CAFE_FIELD_PREP(NAND_CTRL1, CMD,
> +							 instr->ctx.cmd.opcode);
> +			else
> +				ctrl2 |= CAFE_NAND_CTRL2_HAS_CMD2 |
> +					 CAFE_FIELD_PREP(NAND_CTRL2, CMD2,
> +							 instr->ctx.cmd.opcode);
> +			break;
> +
> +		case NAND_OP_ADDR_INSTR:
> +			if (WARN_ON(instr->ctx.addr.naddrs > 5 ||
> +				    !instr->ctx.addr.naddrs))
> +				return -EINVAL;
> +
> +			for (j = 0; j < instr->ctx.addr.naddrs; j++) {
> +				u32 addr = instr->ctx.addr.addrs[j];
> +
> +				if (j < 2)
> +					addr1 |= addr << (8 * j);
> +				else
> +					addr2 |= addr << (8 * (j - 2));
> +			}
> +
> +			ctrl1 |= CAFE_NAND_CTRL1_HAS_ADDR |
> +				 CAFE_FIELD_PREP(NAND_CTRL1, NUM_ADDR_CYC,
> +						 instr->ctx.addr.naddrs - 1);
> +			cafe_writel(cafe, addr1, NAND_ADDR1);
> +			if (instr->ctx.addr.naddrs > 2)
> +				cafe_writel(cafe, addr2, NAND_ADDR2);

Maybe it is safer to always write this register, no? I don't know if
the IP clears registers between operations. If it does not, you might
end up sending extra command cycles.

> +			break;
> +
> +		case NAND_OP_DATA_IN_INSTR:
> +			data_instr = instr;
> +			ctrl1 |= CAFE_NAND_CTRL1_HAS_DATA_IN;
> +			break;
> +
> +		case NAND_OP_DATA_OUT_INSTR:
> +			data_instr = instr;
> +			ctrl1 |= CAFE_NAND_CTRL1_HAS_DATA_OUT;
> +			cafe_write_buf(chip, instr->ctx.data.buf.out,
> +				       instr->ctx.data.len);
> +			break;
> +
> +		case NAND_OP_WAITRDY_INSTR:
> +			wait |= CAFE_NAND_IRQ_FLASH_RDY;
> +			waitrdy = true;
> +			break;
> +		}
> +	}
> +
> +	if (data_instr)
> +		cafe_writel(cafe, data_instr->ctx.data.len, NAND_DATA_LEN);
> +
> +	if (cafe->usedma && data_instr) {
> +		u32 dmactrl = CAFE_NAND_DMA_CTRL_ENABLE |
> +			      CAFE_NAND_DMA_CTRL_RESERVED;
> +
> +		wait |= CAFE_NAND_IRQ_DMA_DONE;
> +		dmactrl |= CAFE_FIELD_PREP(NAND_DMA_CTRL, DATA_LEN,
> +					   data_instr->ctx.data.len);
> +		if (ctrl1 & CAFE_NAND_CTRL1_HAS_DATA_IN)
> +			dmactrl |= CAFE_NAND_DMA_CTRL_DATA_IN;
> +
> +		cafe_writel(cafe, dmactrl, NAND_DMA_CTRL);
> +	}
> +
> +	/* Clear the pending interrupts before starting the operation. */
> +	cafe_writel(cafe, wait, NAND_IRQ);
> +
> +	cafe_writel(cafe, ctrl2, NAND_CTRL2);
> +	cafe_writel(cafe, ctrl1, NAND_CTRL1);
> +
> +	ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> +				 (status & wait) == wait, 1, USEC_PER_SEC);
> +	if (ret)
> +		return ret;
> +
> +	if (ctrl1 & CAFE_NAND_DMA_CTRL_DATA_IN)
> +		cafe_read_buf(chip, data_instr->ctx.data.buf.in,
> +			      data_instr->ctx.data.len);

As you are limiting the amount of data to 2112B and the number of
address cycles to 5, you should probably use the core's helper
nand_subop_data_len, nand_subob_data_buf and nand_subop_addr_len in
this function.

> +
> +	return 0;
> +}
> +
> +static const struct nand_op_parser cafe_nand_op_parser = NAND_OP_PARSER(
> +	NAND_OP_PARSER_PATTERN(cafe_nand_exec_subop,
> +			       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_PAT_WAITRDY_ELEM(true),
> +			       NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, 2112)),
> +	NAND_OP_PARSER_PATTERN(cafe_nand_exec_subop,
> +			       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_PAT_DATA_IN_ELEM(true, 2112),
> +			       NAND_OP_PARSER_PAT_WAITRDY_ELEM(true))
> +);
> +
> +static int cafe_nand_exec_op(struct nand_chip *chip,
> +			     const struct nand_operation *op,
> +			     bool check_only)
> +{

I didn't check but are you sure there is no chip-select/timings
handling to do here?

> +	return nand_op_parser_exec_op(chip, &cafe_nand_op_parser, op,
> +				      check_only);
> +}
> +
>  static const struct nand_controller_ops cafe_nand_controller_ops = {
>  	.attach_chip = cafe_nand_attach_chip,
>  	.detach_chip = cafe_nand_detach_chip,
> +	.exec_op = cafe_nand_exec_op,
>  };
>  
>  static void cafe_nand_init(struct cafe_priv *cafe)

Thanks,
Miquèl

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

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

* Re: [PATCH 14/17] mtd: rawnand: cafe: Get rid of the legacy interface implementation
  2020-04-27  8:20 ` [PATCH 14/17] mtd: rawnand: cafe: Get rid of the legacy interface implementation Boris Brezillon
@ 2020-04-27 20:00   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 20:00 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:24 +0200:

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

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


Thanks,
Miquèl

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

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

* Re: [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read,write}_buf() prototypes
  2020-04-27  8:20 ` [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read, write}_buf() prototypes Boris Brezillon
@ 2020-04-27 20:00   ` Miquel Raynal
  2020-04-28  6:24     ` Boris Brezillon
  0 siblings, 1 reply; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 20:00 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:25 +0200:

> Replace the uint8_t pointer by a void pointer and make the length
> unsigned so it matches what's passed through the nand instructions.
> 

Nit: I prefer NAND than nand in plain English.

> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

But whatever,

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

> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 5b38d496d923..26495085f285 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -179,7 +179,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
>  #define cafe_readl(cafe, addr)			readl((cafe)->mmio + CAFE_##addr)
>  #define cafe_writel(cafe, datum, addr)		writel(datum, (cafe)->mmio + CAFE_##addr)
>  
> -static void cafe_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)
> +static void cafe_write_buf(struct nand_chip *chip, const void *buf,
> +			   unsigned int len)
>  {
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
>  
> @@ -191,7 +192,7 @@ static void cafe_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)
>  	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer.\n",	len);
>  }
>  
> -static void cafe_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
> +static void cafe_read_buf(struct nand_chip *chip, void *buf, unsigned int len)
>  {
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
>  

Thanks,
Miquèl

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

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

* Re: [PATCH 16/17] mtd: rawnand: cafe: Handle non-32bit aligned reads/writes
  2020-04-27  8:20 ` [PATCH 16/17] mtd: rawnand: cafe: Handle non-32bit aligned reads/writes Boris Brezillon
@ 2020-04-27 20:04   ` Miquel Raynal
  2020-04-28  6:26     ` Boris Brezillon
  0 siblings, 1 reply; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 20:04 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:26 +0200:

> The spec says the write/read buffers should be filled/read 32bits at a
> time. While most of the time the reads/writes are aligned on 4 bytes,
> we should make the implementation more robust to non-usual NAND
> operations.

Well, if I didn't get confused by the previous changes, I think these
are used by ->exec_op() and at boot time there are 2B (ID), 3B (I
don't remember) and 5B (full ID) accesses that are performed. These are
not 32-bit aligned.

> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 27 +++++++++++++++++++++------
>  1 file changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 26495085f285..955dc78c57be 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -184,10 +184,18 @@ static void cafe_write_buf(struct nand_chip *chip, const void *buf,
>  {
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
>  
> -	if (cafe->usedma)
> +	if (cafe->usedma) {

Are you sure usedma will not be triggered in the case of unaligned
accesses? I didn't check but it could be nice to verify that this flag
is only set by read/write_page() helpers for instance (which only
handle 32-bit aligned data).

>  		memcpy(cafe->dmabuf, buf, len);
> -	else
> -		memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA, buf, len);
> +	} else {
> +		memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA, buf,
> +			    len & ~0x3);
> +		if (len & 0x3) {
> +			u32 tmp = 0;
> +
> +			memcpy(&tmp, buf + (len & ~0x3), len & 0x3);
> +			cafe_writel(cafe, tmp, NAND_WRITE_DATA);
> +		}
> +	}
>  
>  	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer.\n",	len);
>  }
> @@ -196,10 +204,17 @@ static void cafe_read_buf(struct nand_chip *chip, void *buf, unsigned int len)
>  {
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
>  
> -	if (cafe->usedma)
> +	if (cafe->usedma) {
>  		memcpy(buf, cafe->dmabuf, len);
> -	else
> -		memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA, len);
> +	} else {
> +		memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA,
> +			      len & ~0x3);
> +		if (len & 0x3) {
> +			u32 tmp = cafe_readl(cafe, NAND_READ_DATA);
> +
> +			memcpy(buf + (len & ~0x3), &tmp, len & 0x3);
> +		}
> +	}
>  
>  	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from read buffer.\n", len);
>  }

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

Thanks,
Miquèl

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

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

* Re: [PATCH 17/17] mtd: rawnand: cafe: s/uint{8,16,32}_t/u{8,16,32}/
  2020-04-27  8:20 ` [PATCH 17/17] mtd: rawnand: cafe: s/uint{8,16,32}_t/u{8,16,32}/ Boris Brezillon
@ 2020-04-27 20:05   ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-27 20:05 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:27 +0200:

> Replace uint{8,16,32}_t by u{8,16,32} to make checkpatch happy.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---

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


Thanks,
Miquèl

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

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

* Re: [PATCH 05/17] mtd: rawnand: cafe: Demistify register fields
  2020-04-27 19:42   ` Miquel Raynal
@ 2020-04-28  6:06     ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-04-28  6:06 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

On Mon, 27 Apr 2020 21:42:11 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> >  struct cafe_priv {
> >  	struct nand_chip nand;
> > @@ -104,7 +195,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
> >  static int cafe_device_ready(struct nand_chip *chip)
> >  {
> >  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> > -	int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000);
> > +	int result = !!(cafe_readl(cafe, NAND_STATUS) &
> > +			CAFE_NAND_STATUS_FLASH_BUSY);
> >  	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
> >  
> >  	cafe_writel(cafe, irqs, NAND_IRQ);  
> 
> [...]
> 
> > @@ -318,14 +430,14 @@ static void cafe_select_chip(struct nand_chip *chip, int chipnr)
> >  {
> >  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> >  
> > +	if (chipnr < 0 || chipnr > 1)
> > +		return;
> > +  
> 
> I think this change should not be part of this patch?

Or dropped entirely, since we're getting rid of this function anyway.

> 
> >  	cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
> >  
> >  	/* Mask the appropriate bit into the stored value of ctl1
> >  	   which will be used by cafe_nand_cmdfunc() */
> > -	if (chipnr)
> > -		cafe->ctl1 |= CTRL1_CHIPSELECT;
> > -	else
> > -		cafe->ctl1 &= ~CTRL1_CHIPSELECT;
> > +	cafe->ctl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, chipnr);  
> 
> I don't master these macros yet, but are you sure CTRL1_CHIPSELECT will
> actually get cleared if (!chipnr) ?

You're correct, I only ever set the field. I'll fix that.

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

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

* Re: [PATCH 06/17] mtd: rawnand: cafe: Factor out the controller initialization logic
  2020-04-27 19:45   ` Miquel Raynal
@ 2020-04-28  6:06     ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-04-28  6:06 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

On Mon, 27 Apr 2020 21:45:35 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> > -	/* Enable NAND IRQ in global IRQ mask register */
> > -	cafe_writel(cafe,
> > -		    CAFE_GLOBAL_IRQ_PCI_ERROR |
> > -		    CAFE_GLOBAL_IRQ_CCIC |
> > -		    CAFE_GLOBAL_IRQ_SDH |
> > -		    CAFE_GLOBAL_IRQ_NAND,
> > -		    GLOBAL_IRQ_MASK);
> > +	cafe_nand_init(cafe);  
> 
> A new line would be nice here :p

Will add one.

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

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

* Re: [PATCH 11/17] mtd: rawnand: cafe: Don't leave ECC enabled in the write path
  2020-04-27 19:51   ` Miquel Raynal
@ 2020-04-28  6:08     ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-04-28  6:08 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

On Mon, 27 Apr 2020 21:51:32 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> Hi Boris,
> 
> Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
> 2020 10:20:21 +0200:
> 
> > cafe_nand_write_page_lowlevel() sets the ECC auto-generation flag but  
> 
> IIRC you renamed this function in patch 1 so now it is named
> "_write_page()".
> 
> > never clears it, thus forcing the cafe_nand_cmdfunc() to clear it
> > in certain circumstances. Let's just clear this flag in
> > cafe_nand_write_page_lowlevel() instead.  
> 
> Same here              ^
> 

Right. That's what happens when you re-order commits without paying
attention to the commit message.


> > -	return nand_prog_page_end_op(chip);
> > +	ret = nand_prog_page_end_op(chip);
> > +
> > +	/*
> > +	 * And clear it before returning so that following write operations
> > +	 * that do not involve ECC don't generate ECC bytes.
> > +	 */
> > +	cafe->ctl2 &= ~CAFE_NAND_CTRL2_AUTO_WRITE_ECC;  
> 
> I like spaces before returning, but again it's really a nitpick, you
> can ignore that :)
>

Will add a blank line here as well.
 
> > +	return ret;
> >  }
> >  
> >  /* F_2[X]/(X**6+X+1)  */  


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

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

* Re: [PATCH 12/17] mtd: rawnand: cafe: Don't split things when reading/writing a page
  2020-04-27 19:53   ` Miquel Raynal
@ 2020-04-28  6:20     ` Boris Brezillon
  2020-04-28  7:44       ` Miquel Raynal
  0 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-28  6:20 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

On Mon, 27 Apr 2020 21:53:53 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> Hi Boris,
> 
> Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
> 2020 10:20:22 +0200:
> 
> > Calling nand_read_page_op(pagesize)/nand_prog_page_begin_op(pagesize)
> > and expecting to get a pagesize+oobsize read from/written to the
> > read/write buffer is fragile and only works because of hacks done
> > in cmdfunc(). Let's read/write the page in one go, using the page
> > cache buffer as a bounce buffer.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> > ---
> >  drivers/mtd/nand/raw/cafe_nand.c | 16 +++++++++++-----
> >  1 file changed, 11 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > index 31493a201a02..edf65197604b 100644
> > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > +++ b/drivers/mtd/nand/raw/cafe_nand.c
> > @@ -472,6 +472,7 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
> >  {
> >  	struct mtd_info *mtd = nand_to_mtd(chip);
> >  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> > +	void *pagebuf = nand_get_data_buf(chip);
> >  	unsigned int max_bitflips = 0;
> >  	u32 ecc_result, status;
> >  
> > @@ -479,8 +480,11 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
> >  		cafe_readl(cafe, NAND_ECC_RESULT),
> >  		cafe_readl(cafe, NAND_ECC_SYN_REG(0)));
> >  
> > -	nand_read_page_op(chip, page, 0, buf, mtd->writesize);
> > -	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);
> > +	nand_read_page_op(chip, page, 0, pagebuf,
> > +			  mtd->writesize + mtd->oobsize);
> > +
> > +	if (buf != pagebuf)
> > +		memcpy(buf, pagebuf, mtd->writesize);
> >  
> >  	ecc_result = cafe_readl(cafe, NAND_ECC_RESULT);
> >  	status = CAFE_FIELD_GET(NAND_ECC_RESULT, STATUS, ecc_result);
> > @@ -642,15 +646,17 @@ static int cafe_nand_write_page(struct nand_chip *chip,
> >  {
> >  	struct mtd_info *mtd = nand_to_mtd(chip);
> >  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> > +	void *pagebuf = nand_get_data_buf(chip);
> >  	int ret;
> >  
> > -	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
> > -	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
> > +	if (pagebuf != buf)
> > +		memcpy(pagebuf, buf, mtd->writesize);
> >  
> >  	/* Set up ECC autogeneration */
> >  	cafe->ctl2 |= CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
> >  
> > -	ret = nand_prog_page_end_op(chip);
> > +	ret = nand_prog_page_op(chip, page, 0, pagebuf,
> > +				mtd->writesize + mtd->oobsize);
> >  
> >  	/*
> >  	 * And clear it before returning so that following write operations  
> 
> 
> You are replacing ->read/write_buf() calls into memcpy() calls,
> shouldn't this be cleaned before? or at least mentioned?

Actually, those read/write_buf are still there, they're just hidden in
the nand_{prog,read}_page_op() call now (to be accurate, the read/write
buf in there now covers the data and oob portions). It's really what
should be done, the reason this worked so far is because cmdfunc()
guesses that the full page will be read/written and issues a read/write
of the data+oob portion. The extra memcpy that's added here is done to
account for the fact that the core might pass 2 different buffers for
OOB and data, but we want things to be done in one step, so we're using
the bounce buffer to do the transfer.

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
  2020-04-27 19:59   ` Miquel Raynal
@ 2020-04-28  6:24     ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-04-28  6:24 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

On Mon, 27 Apr 2020 21:59:33 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> > +	if (WARN_ON(subop->cs > 1))
> > +		return -EINVAL;
> > +
> > +	cafe->datalen = 0;
> > +	ctrl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, subop->cs);
> > +
> > +	for (i = 0; i < subop->ninstrs; i++) {
> > +		const struct nand_op_instr *instr = &subop->instrs[i];
> > +
> > +		switch (instr->type) {
> > +		case NAND_OP_CMD_INSTR:
> > +			if (WARN_ON((ctrl1 & CAFE_NAND_CTRL1_HAS_CMD) &&
> > +				    (ctrl2 & CAFE_NAND_CTRL2_HAS_CMD2)))
> > +				return -EINVAL;  
> 
> Same comment as in the previous drivers, just showing it to do not
> foget.

Will remove those WARN_ON()s.

> 
> > +
> > +			if (!(ctrl1 & CAFE_NAND_CTRL1_HAS_CMD))
> > +				ctrl1 |= CAFE_NAND_CTRL1_HAS_CMD |
> > +					 CAFE_FIELD_PREP(NAND_CTRL1, CMD,
> > +							 instr->ctx.cmd.opcode);
> > +			else
> > +				ctrl2 |= CAFE_NAND_CTRL2_HAS_CMD2 |
> > +					 CAFE_FIELD_PREP(NAND_CTRL2, CMD2,
> > +							 instr->ctx.cmd.opcode);
> > +			break;
> > +
> > +		case NAND_OP_ADDR_INSTR:
> > +			if (WARN_ON(instr->ctx.addr.naddrs > 5 ||
> > +				    !instr->ctx.addr.naddrs))
> > +				return -EINVAL;
> > +
> > +			for (j = 0; j < instr->ctx.addr.naddrs; j++) {
> > +				u32 addr = instr->ctx.addr.addrs[j];
> > +
> > +				if (j < 2)
> > +					addr1 |= addr << (8 * j);
> > +				else
> > +					addr2 |= addr << (8 * (j - 2));
> > +			}
> > +
> > +			ctrl1 |= CAFE_NAND_CTRL1_HAS_ADDR |
> > +				 CAFE_FIELD_PREP(NAND_CTRL1, NUM_ADDR_CYC,
> > +						 instr->ctx.addr.naddrs - 1);
> > +			cafe_writel(cafe, addr1, NAND_ADDR1);
> > +			if (instr->ctx.addr.naddrs > 2)
> > +				cafe_writel(cafe, addr2, NAND_ADDR2);  
> 
> Maybe it is safer to always write this register, no? I don't know if
> the IP clears registers between operations. If it does not, you might
> end up sending extra command cycles.

The number of cycles is controller by NUM_ADDR_CYC so that shouldn't be
a problem, but you're right, writing ADDR2 unconditionally shouldn't
hurt.

> 
> > +			break;
> > +
> > +		case NAND_OP_DATA_IN_INSTR:
> > +			data_instr = instr;
> > +			ctrl1 |= CAFE_NAND_CTRL1_HAS_DATA_IN;
> > +			break;
> > +
> > +		case NAND_OP_DATA_OUT_INSTR:
> > +			data_instr = instr;
> > +			ctrl1 |= CAFE_NAND_CTRL1_HAS_DATA_OUT;
> > +			cafe_write_buf(chip, instr->ctx.data.buf.out,
> > +				       instr->ctx.data.len);
> > +			break;
> > +
> > +		case NAND_OP_WAITRDY_INSTR:
> > +			wait |= CAFE_NAND_IRQ_FLASH_RDY;
> > +			waitrdy = true;
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (data_instr)
> > +		cafe_writel(cafe, data_instr->ctx.data.len, NAND_DATA_LEN);
> > +
> > +	if (cafe->usedma && data_instr) {
> > +		u32 dmactrl = CAFE_NAND_DMA_CTRL_ENABLE |
> > +			      CAFE_NAND_DMA_CTRL_RESERVED;
> > +
> > +		wait |= CAFE_NAND_IRQ_DMA_DONE;
> > +		dmactrl |= CAFE_FIELD_PREP(NAND_DMA_CTRL, DATA_LEN,
> > +					   data_instr->ctx.data.len);
> > +		if (ctrl1 & CAFE_NAND_CTRL1_HAS_DATA_IN)
> > +			dmactrl |= CAFE_NAND_DMA_CTRL_DATA_IN;
> > +
> > +		cafe_writel(cafe, dmactrl, NAND_DMA_CTRL);
> > +	}
> > +
> > +	/* Clear the pending interrupts before starting the operation. */
> > +	cafe_writel(cafe, wait, NAND_IRQ);
> > +
> > +	cafe_writel(cafe, ctrl2, NAND_CTRL2);
> > +	cafe_writel(cafe, ctrl1, NAND_CTRL1);
> > +
> > +	ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> > +				 (status & wait) == wait, 1, USEC_PER_SEC);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (ctrl1 & CAFE_NAND_DMA_CTRL_DATA_IN)
> > +		cafe_read_buf(chip, data_instr->ctx.data.buf.in,
> > +			      data_instr->ctx.data.len);  
> 
> As you are limiting the amount of data to 2112B and the number of
> address cycles to 5, you should probably use the core's helper
> nand_subop_data_len, nand_subob_data_buf and nand_subop_addr_len in
> this function.

Indeed. I'll fix that.

> 
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct nand_op_parser cafe_nand_op_parser = NAND_OP_PARSER(
> > +	NAND_OP_PARSER_PATTERN(cafe_nand_exec_subop,
> > +			       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_PAT_WAITRDY_ELEM(true),
> > +			       NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, 2112)),
> > +	NAND_OP_PARSER_PATTERN(cafe_nand_exec_subop,
> > +			       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_PAT_DATA_IN_ELEM(true, 2112),
> > +			       NAND_OP_PARSER_PAT_WAITRDY_ELEM(true))
> > +);
> > +
> > +static int cafe_nand_exec_op(struct nand_chip *chip,
> > +			     const struct nand_operation *op,
> > +			     bool check_only)
> > +{  
> 
> I didn't check but are you sure there is no chip-select/timings
> handling to do here?

Apparently no. Having the CS propagated to subops is enough here (CS
selection is done in the subop handler).



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

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

* Re: [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read,write}_buf() prototypes
  2020-04-27 20:00   ` [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read,write}_buf() prototypes Miquel Raynal
@ 2020-04-28  6:24     ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-04-28  6:24 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

On Mon, 27 Apr 2020 22:00:55 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> Hi Boris,
> 
> Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
> 2020 10:20:25 +0200:
> 
> > Replace the uint8_t pointer by a void pointer and make the length
> > unsigned so it matches what's passed through the nand instructions.
> >   
> 
> Nit: I prefer NAND than nand in plain English.

Will fix that.

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

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

* Re: [PATCH 16/17] mtd: rawnand: cafe: Handle non-32bit aligned reads/writes
  2020-04-27 20:04   ` Miquel Raynal
@ 2020-04-28  6:26     ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-04-28  6:26 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

On Mon, 27 Apr 2020 22:04:59 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> Hi Boris,
> 
> Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
> 2020 10:20:26 +0200:
> 
> > The spec says the write/read buffers should be filled/read 32bits at a
> > time. While most of the time the reads/writes are aligned on 4 bytes,
> > we should make the implementation more robust to non-usual NAND
> > operations.  
> 
> Well, if I didn't get confused by the previous changes, I think these
> are used by ->exec_op() and at boot time there are 2B (ID), 3B (I
> don't remember) and 5B (full ID) accesses that are performed. These are
> not 32-bit aligned.

Oh, you're right. Looks like read_byte() does single byte accesses
already, meaning that readb is allowed on the MMIO region. I'll just
drop this patch then.

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

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

* Re: [PATCH 12/17] mtd: rawnand: cafe: Don't split things when reading/writing a page
  2020-04-28  6:20     ` Boris Brezillon
@ 2020-04-28  7:44       ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-04-28  7:44 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: linux-mtd, Tudor Ambarus, David Woodhouse, Vignesh Raghavendra,
	Richard Weinberger

Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Tue, 28 Apr
2020 08:20:24 +0200:

> On Mon, 27 Apr 2020 21:53:53 +0200
> Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> 
> > Hi Boris,
> > 
> > Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
> > 2020 10:20:22 +0200:
> >   
> > > Calling nand_read_page_op(pagesize)/nand_prog_page_begin_op(pagesize)
> > > and expecting to get a pagesize+oobsize read from/written to the
> > > read/write buffer is fragile and only works because of hacks done
> > > in cmdfunc(). Let's read/write the page in one go, using the page
> > > cache buffer as a bounce buffer.
> > > 
> > > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> > > ---
> > >  drivers/mtd/nand/raw/cafe_nand.c | 16 +++++++++++-----
> > >  1 file changed, 11 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > > index 31493a201a02..edf65197604b 100644
> > > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > > +++ b/drivers/mtd/nand/raw/cafe_nand.c
> > > @@ -472,6 +472,7 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
> > >  {
> > >  	struct mtd_info *mtd = nand_to_mtd(chip);
> > >  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> > > +	void *pagebuf = nand_get_data_buf(chip);
> > >  	unsigned int max_bitflips = 0;
> > >  	u32 ecc_result, status;
> > >  
> > > @@ -479,8 +480,11 @@ static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
> > >  		cafe_readl(cafe, NAND_ECC_RESULT),
> > >  		cafe_readl(cafe, NAND_ECC_SYN_REG(0)));
> > >  
> > > -	nand_read_page_op(chip, page, 0, buf, mtd->writesize);
> > > -	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);
> > > +	nand_read_page_op(chip, page, 0, pagebuf,
> > > +			  mtd->writesize + mtd->oobsize);
> > > +
> > > +	if (buf != pagebuf)
> > > +		memcpy(buf, pagebuf, mtd->writesize);
> > >  
> > >  	ecc_result = cafe_readl(cafe, NAND_ECC_RESULT);
> > >  	status = CAFE_FIELD_GET(NAND_ECC_RESULT, STATUS, ecc_result);
> > > @@ -642,15 +646,17 @@ static int cafe_nand_write_page(struct nand_chip *chip,
> > >  {
> > >  	struct mtd_info *mtd = nand_to_mtd(chip);
> > >  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> > > +	void *pagebuf = nand_get_data_buf(chip);
> > >  	int ret;
> > >  
> > > -	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
> > > -	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
> > > +	if (pagebuf != buf)
> > > +		memcpy(pagebuf, buf, mtd->writesize);
> > >  
> > >  	/* Set up ECC autogeneration */
> > >  	cafe->ctl2 |= CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
> > >  
> > > -	ret = nand_prog_page_end_op(chip);
> > > +	ret = nand_prog_page_op(chip, page, 0, pagebuf,
> > > +				mtd->writesize + mtd->oobsize);
> > >  
> > >  	/*
> > >  	 * And clear it before returning so that following write operations    
> > 
> > 
> > You are replacing ->read/write_buf() calls into memcpy() calls,
> > shouldn't this be cleaned before? or at least mentioned?  
> 
> Actually, those read/write_buf are still there, they're just hidden in
> the nand_{prog,read}_page_op() call now (to be accurate, the read/write
> buf in there now covers the data and oob portions). It's really what
> should be done, the reason this worked so far is because cmdfunc()
> guesses that the full page will be read/written and issues a read/write
> of the data+oob portion. The extra memcpy that's added here is done to
> account for the fact that the core might pass 2 different buffers for
> OOB and data, but we want things to be done in one step, so we're using
> the bounce buffer to do the transfer.

Now that you mention it I fully understand.

Thanks for the clarification, maybe you can add these details to the
commit log.


Thanks,
Miquèl

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

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

* Re: [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more)
  2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
                   ` (17 preceding siblings ...)
  2020-04-27  8:20 ` [PATCH 17/17] mtd: rawnand: s/uint{8,16,32}_t/u{8,16,32}/ Boris Brezillon
@ 2020-04-29  6:37 ` Thomas Petazzoni
  2020-04-29  8:28   ` Boris Brezillon
       [not found] ` <20200502112732.330971-1-lkundrak@v3.sk>
  19 siblings, 1 reply; 58+ messages in thread
From: Thomas Petazzoni @ 2020-04-29  6:37 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Vignesh Raghavendra, Tudor Ambarus, Richard Weinberger,
	Lubomir Rintel, linux-mtd, Miquel Raynal, David Woodhouse

Hello,

+Lubomir Rintel in Cc.

On Mon, 27 Apr 2020 10:20:10 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:

> A bit of context to explain the motivation behind those conversions
> I've been sending for the last couple of weeks. The raw NAND subsystem
> carries a lot of history which makes any rework not only painful, but
> also subject to regressions which we only detect when someone dares to
> update its kernel on one of those ancient HW. While carrying drivers
> for old HW is not a problem per se, carrying ancient and unmaintained
> drivers that are not converted to new APIs is a maintenance burden,
> hence this massive conversion attempt I'm conducting here.
> 
> So here it is, a series converting the CAFE NAND controller driver to
> exec_op(), plus a bunch of minor improvements done along the way.
> I hope I'll find someone to test those changes, but if there's no one
> still owning OLPC HW or no interest in keeping it supported in recent
> kernel versions, we should definitely consider removing the driver
> instead.

Lubomir Rintel (in Cc) has very recently added defconfigs to Buildroot
to support the two OLPC platforms (the Intel based one and the Marvell
MMP based one). I suppose this means he has access to the hardware, so
hopefully he should be able to test these NAND driver changes.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more)
  2020-04-29  6:37 ` [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Thomas Petazzoni
@ 2020-04-29  8:28   ` Boris Brezillon
       [not found]     ` <20200501055209.GA44510@furthur.local>
  0 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-04-29  8:28 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Vignesh Raghavendra, Tudor Ambarus, Richard Weinberger,
	Lubomir Rintel, linux-mtd, Miquel Raynal, David Woodhouse

Hi Thomas,

On Wed, 29 Apr 2020 08:37:35 +0200
Thomas Petazzoni <thomas.petazzoni@bootlin.com> wrote:

> Hello,
> 
> +Lubomir Rintel in Cc.
> 
> On Mon, 27 Apr 2020 10:20:10 +0200
> Boris Brezillon <boris.brezillon@collabora.com> wrote:
> 
> > A bit of context to explain the motivation behind those conversions
> > I've been sending for the last couple of weeks. The raw NAND subsystem
> > carries a lot of history which makes any rework not only painful, but
> > also subject to regressions which we only detect when someone dares to
> > update its kernel on one of those ancient HW. While carrying drivers
> > for old HW is not a problem per se, carrying ancient and unmaintained
> > drivers that are not converted to new APIs is a maintenance burden,
> > hence this massive conversion attempt I'm conducting here.
> > 
> > So here it is, a series converting the CAFE NAND controller driver to
> > exec_op(), plus a bunch of minor improvements done along the way.
> > I hope I'll find someone to test those changes, but if there's no one
> > still owning OLPC HW or no interest in keeping it supported in recent
> > kernel versions, we should definitely consider removing the driver
> > instead.  
> 
> Lubomir Rintel (in Cc) has very recently added defconfigs to Buildroot
> to support the two OLPC platforms (the Intel based one and the Marvell
> MMP based one). I suppose this means he has access to the hardware, so
> hopefully he should be able to test these NAND driver changes.

Oh, that's great news! Thanks a lot for letting me know.

Lubomir, let me know if you'd be okay to test those changes. I can
provide a branch if that's easier.

Regards,

Boris

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

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

* Re: [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more)
       [not found]     ` <20200501055209.GA44510@furthur.local>
@ 2020-05-01  6:21       ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-05-01  6:21 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: Vignesh Raghavendra, Tudor Ambarus, Richard Weinberger,
	linux-mtd, Thomas Petazzoni, Miquel Raynal, David Woodhouse

On Fri, 1 May 2020 07:52:09 +0200
Lubomir Rintel <lkundrak@v3.sk> wrote:

> On Wed, Apr 29, 2020 at 10:28:41AM +0200, Boris Brezillon wrote:
> > Hi Thomas,
> > 
> > On Wed, 29 Apr 2020 08:37:35 +0200
> > Thomas Petazzoni <thomas.petazzoni@bootlin.com> wrote:
> >   
> > > Hello,
> > > 
> > > +Lubomir Rintel in Cc.
> > > 
> > > On Mon, 27 Apr 2020 10:20:10 +0200
> > > Boris Brezillon <boris.brezillon@collabora.com> wrote:
> > >   
> > > > A bit of context to explain the motivation behind those conversions
> > > > I've been sending for the last couple of weeks. The raw NAND subsystem
> > > > carries a lot of history which makes any rework not only painful, but
> > > > also subject to regressions which we only detect when someone dares to
> > > > update its kernel on one of those ancient HW. While carrying drivers
> > > > for old HW is not a problem per se, carrying ancient and unmaintained
> > > > drivers that are not converted to new APIs is a maintenance burden,
> > > > hence this massive conversion attempt I'm conducting here.
> > > > 
> > > > So here it is, a series converting the CAFE NAND controller driver to
> > > > exec_op(), plus a bunch of minor improvements done along the way.
> > > > I hope I'll find someone to test those changes, but if there's no one
> > > > still owning OLPC HW or no interest in keeping it supported in recent
> > > > kernel versions, we should definitely consider removing the driver
> > > > instead.    
> > > 
> > > Lubomir Rintel (in Cc) has very recently added defconfigs to Buildroot
> > > to support the two OLPC platforms (the Intel based one and the Marvell
> > > MMP based one). I suppose this means he has access to the hardware, so
> > > hopefully he should be able to test these NAND driver changes.  
> > 
> > Oh, that's great news! Thanks a lot for letting me know.
> > 
> > Lubomir, let me know if you'd be okay to test those changes. I can
> > provide a branch if that's easier.  
> 
> Boris, I'd be happy to test the changes. A branch would help.

Here it is [1].

> I've
> applied the patches on top of 5.7-rc3 and while they applied cleanly,
> they've failed to build:
> 
>   drivers/mtd/nand/raw/cafe_nand.c: In function ‘cafe_nand_exec_subop’:
>   drivers/mtd/nand/raw/cafe_nand.c:581:19: error: ‘const struct nand_subop’ has no member named ‘cs’
>     581 |  if (WARN_ON(subop->cs > 1))
>         |  
                 ^~

Yep, it depends on a patch that was part of a separate series.

I'm here to help if you have any issues.

Thanks,

Boris

[1]https://github.com/bbrezillon/linux/tree/nand/exec-op-conversion

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

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

* Re: [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more)
       [not found] ` <20200502112732.330971-1-lkundrak@v3.sk>
@ 2020-05-02 13:15   ` Boris Brezillon
  2020-05-08 10:32     ` Miquel Raynal
  0 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-05-02 13:15 UTC (permalink / raw)
  To: Lubomir Rintel, Thomas Petazzoni
  Cc: vigneshr, tudor.ambarus, richard, linux-mtd, miquel.raynal, dwmw2

On Sat,  2 May 2020 13:27:32 +0200
Lubomir Rintel <lkundrak@v3.sk> wrote:

> Boris Brezillon wrote:
> > Hello,
> > 
> > A bit of context to explain the motivation behind those conversions
> > I've been sending for the last couple of weeks. The raw NAND subsystem
> > carries a lot of history which makes any rework not only painful, but
> > also subject to regressions which we only detect when someone dares to
> > update its kernel on one of those ancient HW. While carrying drivers
> > for old HW is not a problem per se, carrying ancient and unmaintained
> > drivers that are not converted to new APIs is a maintenance burden,
> > hence this massive conversion attempt I'm conducting here.
> > 
> > So here it is, a series converting the CAFE NAND controller driver to
> > exec_op(), plus a bunch of minor improvements done along the way.
> > I hope I'll find someone to test those changes, but if there's no one
> > still owning OLPC HW or no interest in keeping it supported in recent
> > kernel versions, we should definitely consider removing the driver
> > instead.
> > 
> > Regards,
> > 
> > Boris
> > 
> > Boris Brezillon (17):
> >   mtd: rawnand: cafe: Get rid of an inaccurate kernel doc header
> >   mtd: rawnand: cafe: Rename cafe_nand_write_page_lowlevel()
> >   mtd: rawnand: cafe: Use a correct ECC mode and pass the ECC alg
> >   mtd: rawnand: cafe: Include linux/io.h instead of asm/io.h
> >   mtd: rawnand: cafe: Demistify register fields
> >   mtd: rawnand: cafe: Factor out the controller initialization logic
> >   mtd: rawnand: cafe: Get rid of the debug module param
> >   mtd: rawnand: cafe: Use devm_kzalloc and devm_request_irq()
> >   mtd: rawnand: cafe: Get rid of a useless label
> >   mtd: rawnand: cafe: Explicitly inherit from nand_controller
> >   mtd: rawnand: cafe: Don't leave ECC enabled in the write path
> >   mtd: rawnand: cafe: Don't split things when reading/writing a page
> >   mtd: rawnand: cafe: Add exec_op() support
> >   mtd: rawnand: cafe: Get rid of the legacy interface implementation
> >   mtd: rawnand: cafe: Adjust the cafe_{read,write}_buf() prototypes
> >   mtd: rawnand: cafe: Handle non-32bit aligned reads/writes
> >   mtd: rawnand: cafe: s/uint{8,16,32}_t/u{8,16,32}/
> > 
> >  drivers/mtd/nand/raw/cafe_nand.c | 805 ++++++++++++++++---------------
> >  1 file changed, 423 insertions(+), 382 deletions(-)  
> 
> Thanks for doing this. With a couple of changes I've indicated in responses to
> some of the patches this has been:
> 
> Tested-by: Lubomir Rintel <lkundrak@v3.sk>

Thanks a lot for testing *and debugging* my changes. I must admit that
was unexpected, and I'm amazed by how fast I got feedback on that one
:-). Kudos to Thomas as well for noticing the email and getting us in
touch.

> 
> Other than that, I have a couple of suggestions (I'm not really in a position 
> to demand them, but they would've done the review easier for me):
> 
> 1.) I'm wondering if we could remove these:
> 
>   /* Make it easier to switch to PIO if we need to */
>   #define cafe_readl(cafe, addr)                  readl((cafe)->mmio + CAFE_##addr)
>   #define cafe_writel(cafe, datum, addr)          writel(datum, (cafe)->mmio + CAFE_##addr)
> 
> Or at least don't add new calls to them in our patches and call 
> readl()/writel() directly. The string pasting makes it impossible to grep
> for the register names.
> 
> It's not like a switch to PIO is ever going to happen and with an instance
> of readl_poll_timeout() added it's not like it would be a matter of
> rewriting those macros.

I can certainly do that.

> 
> 2.) When the block after a conditional is multiple lines, could you please
> include the curly braces? That is:
> 
>         if (ctrl1 & CAFE_NAND_CTRL1_HAS_DATA_IN) {
>                 cafe_read_buf(chip,
>                               subop->instrs[data_instr].ctx.data.buf.in +
>                               nand_subop_get_data_start_off(subop, data_instr),
>                               nand_subop_get_data_len(subop, data_instr));
>         }
> 
> Instead of:
> 
>         if (ctrl1 & CAFE_NAND_CTRL1_HAS_DATA_IN)
>                 cafe_read_buf(chip,
>                               subop->instrs[data_instr].ctx.data.buf.in +
>                               nand_subop_get_data_start_off(subop, data_instr),
>                               nand_subop_get_data_len(subop, data_instr));
> 
> This makes things significantly easier to read for me, not to mention that it
> comes handy to have the braces around for printf debugging.

I do prefer the version without brackets, but given you debugged it,
I'd be okay changing that one ;-) (assuming Miquel is okay with that
too, of course).

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
       [not found]   ` <20200502111410.330584-1-lkundrak@v3.sk>
@ 2020-05-02 13:18     ` Boris Brezillon
       [not found]       ` <20200502191843.GA363829@furthur.local>
  0 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-05-02 13:18 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: vigneshr, tudor.ambarus, richard, linux-mtd, miquel.raynal, dwmw2

On Sat,  2 May 2020 13:14:10 +0200
Lubomir Rintel <lkundrak@v3.sk> wrote:

> Boris Brezillon wrote:
> > Implementing exec_op() will help us get rid of the legacy interface and
> > should make drivers much cleaner too.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> > ---
> >  drivers/mtd/nand/raw/cafe_nand.c | 137 ++++++++++++++++++++++++++++++-
> >  1 file changed, 136 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > index edf65197604b..ada9c8b06a41 100644
> > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > +++ b/drivers/mtd/nand/raw/cafe_nand.c  
> ...
> 
> > +	ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> > +				 (status & wait) == wait, 1, USEC_PER_SEC);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (ctrl1 & CAFE_NAND_DMA_CTRL_DATA_IN)  
>                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
> s/CAFE_NAND_DMA_CTRL_DATA_IN/CAFE_NAND_CTRL1_HAS_DATA_IN/ here please.
> 
> 
> > +		cafe_read_buf(chip, data_instr->ctx.data.buf.in,
> > +			      data_instr->ctx.data.len);
> > +
> > +	return 0;
> > +}  
> ...
> 
> Other than that, when DMA is in use, only CAFE_NAND_IRQ_DMA_DONE seem to pop
> up in CAFE_NAND_IRQ when the command completes, not CAFE_NAND_IRQ_CMD_DONE.
> I suppose you ought to do this or something equivalent:

I suspect it has to do with the fact that you might have operations with
DATA_IN() instructions only. I pushed an alternate fix [1] to my branch.
Would you mind testing it?

> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 307c9a68afa9..356a07e61c88 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -778,7 +778,7 @@ static int cafe_nand_exec_subop(struct nand_chip *chip,
>  {
>         struct cafe_priv *cafe = nand_get_controller_data(chip);
>         u32 ctrl1 = 0, ctrl2 = cafe->ctl2, addr1 = 0, addr2 = 0;
> -       u32 status, wait = CAFE_NAND_IRQ_CMD_DONE;
> +       u32 status, wait = 0;
>         int ret, data_instr = -1;
>         bool waitrdy = false;
>         unsigned int i, j;
> @@ -856,6 +856,8 @@ static int cafe_nand_exec_subop(struct nand_chip *chip,
>                         dmactrl |= CAFE_NAND_DMA_CTRL_DATA_IN;
>  
>                 cafe_writel(cafe, dmactrl, NAND_DMA_CTRL);
> +       } else {
> +               wait |= CAFE_NAND_IRQ_CMD_DONE;
>         }
>  
>         /* Clear the pending interrupts before starting the operation. */
> 
> cafe_nand_cmdfunc() seems to do the same thing (note the "=" instead of
> "|=") though the use of word "just" in the comment is somewhat misleading:
> 
>  244 static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
>  245                               int column, int page_addr)
>  246 {
>  ...
>  359                 /* If WR or RD bits set, set up DMA */
>  360                 if (ctl1 & CAFE_NAND_CTRL1_HAS_DATA_IN) {
>  361                         /* It's a read */
>  362                         dmactl |= CAFE_NAND_DMA_CTRL_DATA_IN;
>  363                         /* ... so it's done when the DMA is done, not just
>  364                            the command. */
>  365                         doneint = CAFE_NAND_IRQ_DMA_DONE;
>  366                 }
> 
> With the changes I suggested above, you can add:
> 
> Reviewed-by: Lubomir Rintel <lkundrak@v3.sk>
> 
> Thank you!
> Lubo

[1]https://github.com/bbrezillon/linux/commit/ecf93c3c2e94ab0710babe856f272ff2e8b2a35b

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
       [not found]       ` <20200502191843.GA363829@furthur.local>
@ 2020-05-02 22:34         ` Boris Brezillon
       [not found]           ` <20200503060610.GA386731@furthur.local>
  2020-05-09 20:10         ` Boris Brezillon
  1 sibling, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-05-02 22:34 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: vigneshr, tudor.ambarus, richard, linux-mtd, miquel.raynal, dwmw2

On Sat, 2 May 2020 21:18:43 +0200
Lubomir Rintel <lkundrak@v3.sk> wrote:

> On Sat, May 02, 2020 at 03:18:11PM +0200, Boris Brezillon wrote:
> > On Sat,  2 May 2020 13:14:10 +0200
> > Lubomir Rintel <lkundrak@v3.sk> wrote:
> >   
> > > Boris Brezillon wrote:  
> > > > Implementing exec_op() will help us get rid of the legacy interface and
> > > > should make drivers much cleaner too.
> > > > 
> > > > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> > > > ---
> > > >  drivers/mtd/nand/raw/cafe_nand.c | 137 ++++++++++++++++++++++++++++++-
> > > >  1 file changed, 136 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > > > index edf65197604b..ada9c8b06a41 100644
> > > > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > > > +++ b/drivers/mtd/nand/raw/cafe_nand.c    
> > > ...
> > >   
> > > > +	ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> > > > +				 (status & wait) == wait, 1, USEC_PER_SEC);
> > > > +	if (ret)
> > > > +		return ret;
> > > > +
> > > > +	if (ctrl1 & CAFE_NAND_DMA_CTRL_DATA_IN)    
> > >                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > s/CAFE_NAND_DMA_CTRL_DATA_IN/CAFE_NAND_CTRL1_HAS_DATA_IN/ here please.
> > > 
> > >   
> > > > +		cafe_read_buf(chip, data_instr->ctx.data.buf.in,
> > > > +			      data_instr->ctx.data.len);
> > > > +
> > > > +	return 0;
> > > > +}    
> > > ...
> > > 
> > > Other than that, when DMA is in use, only CAFE_NAND_IRQ_DMA_DONE seem to pop
> > > up in CAFE_NAND_IRQ when the command completes, not CAFE_NAND_IRQ_CMD_DONE.
> > > I suppose you ought to do this or something equivalent:  
> > 
> > I suspect it has to do with the fact that you might have operations with
> > DATA_IN() instructions only. I pushed an alternate fix [1] to my branch.
> > Would you mind testing it?  
> 
> That sounded plausible, but it doesn't seem to be to be the case. With
> the patch the operations doing DMA transfers still seem to time out (the
> identification succeeded, because at that point DMA is turned off):
> 
>    CAFÉ NAND 0000:00:0c.0: enabling device (0000 -> 0002)
>    nand: device found, Manufacturer ID: 0xad, Chip ID: 0xdc
>    nand: Hynix NAND 512MiB 3,3V 8-bit
>    nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
>    nand: 2 chips detected
>    Bad block table not found for chip 0
>    Bad block table not found for chip 0
>    Scanning device for bad blocks
>    nand_bbt: error while erasing BBT block -5
>    nand_bbt: error -30 while marking block 8191 bad
>    nand_bbt: error while erasing BBT block -5
>    nand_bbt: error -30 while marking block 8190 bad
>    nand_bbt: error while erasing BBT block -5
>    nand_bbt: error -30 while marking block 8189 bad
>    nand_bbt: error while erasing BBT block -5
>    nand_bbt: error -30 while marking block 8188 bad
>    No space left to write bad block table
>    nand_bbt: error while writing bad block table -28
> 
> I've done this on top of your branch:
> 
> diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> index 761d103e438f..2a769033392e 100644
> --- a/drivers/mtd/nand/raw/cafe_nand.c
> +++ b/drivers/mtd/nand/raw/cafe_nand.c
> @@ -642,6 +642,11 @@ static int cafe_nand_exec_subop(struct nand_chip *chip,
>  
>         ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
>                                  (status & wait) == wait, 1, USEC_PER_SEC);
> +       for (i = 0; i < subop->ninstrs; i++) {
> +               const struct nand_op_instr *instr = &subop->instrs[i];
> +               printk("%d: ret=%d instr=%d status=%08x wait=%08x\n", i, ret, instr->type, status, wait);
> +       }
> +
>         if (ret)
>                 return ret;
> 
> It indeed looks like CAFE_NAND_IRQ_CMD_DONE is never raised if there's a
> data operation involving DMA -- the status remains at 0x50000000. Full log:

I see. The reason I was not entirely happy with the "wait on DMA_DONE
when there's a DMA transfer" is because this transfer might not be the
last instruction in a sub operation, and I feared we would not wait for
the full operation to be done but only the DMA transfer itself. So I
went back to the spec [1], and there's an interesting note page 38:

"
Software waits for <dma_done> field in the Interrupt Register (Table 91
p. 93) for read operation because DMA is the last step of read
operation and waits for <cmd_done>field in the Interrupt Register
(Table 91 p. 93) for write operation because Command execution is the
last step of write operation.
"

I just pushed a new fixup commit implementing this logic. Let me know
if that solves the problem.

[1]http://wiki.laptop.org/images/5/5c/88ALP01_Datasheet_July_2007.pdf

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
       [not found]           ` <20200503060610.GA386731@furthur.local>
@ 2020-05-03  7:04             ` Boris Brezillon
  2020-05-03  7:26               ` Boris Brezillon
       [not found]               ` <20200503075208.GA387473@furthur.local>
  0 siblings, 2 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-05-03  7:04 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: vigneshr, tudor.ambarus, richard, linux-mtd, miquel.raynal, dwmw2

On Sun, 3 May 2020 08:06:10 +0200
Lubomir Rintel <lkundrak@v3.sk> wrote:

> On Sun, May 03, 2020 at 12:34:56AM +0200, Boris Brezillon wrote:
> > On Sat, 2 May 2020 21:18:43 +0200
> > Lubomir Rintel <lkundrak@v3.sk> wrote:
> >   
> > > On Sat, May 02, 2020 at 03:18:11PM +0200, Boris Brezillon wrote:  
> > > > On Sat,  2 May 2020 13:14:10 +0200
> > > > Lubomir Rintel <lkundrak@v3.sk> wrote:
> > > >     
> > > > > Boris Brezillon wrote:    
> > > > > > Implementing exec_op() will help us get rid of the legacy interface and
> > > > > > should make drivers much cleaner too.
> > > > > > 
> > > > > > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> > > > > > ---
> > > > > >  drivers/mtd/nand/raw/cafe_nand.c | 137 ++++++++++++++++++++++++++++++-
> > > > > >  1 file changed, 136 insertions(+), 1 deletion(-)
> > > > > > 
> > > > > > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > > > > > index edf65197604b..ada9c8b06a41 100644
> > > > > > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > > > > > +++ b/drivers/mtd/nand/raw/cafe_nand.c      
> > > > > ...
> > > > >     
> > > > > > +	ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> > > > > > +				 (status & wait) == wait, 1, USEC_PER_SEC);
> > > > > > +	if (ret)
> > > > > > +		return ret;
> > > > > > +
> > > > > > +	if (ctrl1 & CAFE_NAND_DMA_CTRL_DATA_IN)      
> > > > >                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > > > s/CAFE_NAND_DMA_CTRL_DATA_IN/CAFE_NAND_CTRL1_HAS_DATA_IN/ here please.
> > > > > 
> > > > >     
> > > > > > +		cafe_read_buf(chip, data_instr->ctx.data.buf.in,
> > > > > > +			      data_instr->ctx.data.len);
> > > > > > +
> > > > > > +	return 0;
> > > > > > +}      
> > > > > ...
> > > > > 
> > > > > Other than that, when DMA is in use, only CAFE_NAND_IRQ_DMA_DONE seem to pop
> > > > > up in CAFE_NAND_IRQ when the command completes, not CAFE_NAND_IRQ_CMD_DONE.
> > > > > I suppose you ought to do this or something equivalent:    
> > > > 
> > > > I suspect it has to do with the fact that you might have operations with
> > > > DATA_IN() instructions only. I pushed an alternate fix [1] to my branch.
> > > > Would you mind testing it?    
> > > 
> > > That sounded plausible, but it doesn't seem to be to be the case. With
> > > the patch the operations doing DMA transfers still seem to time out (the
> > > identification succeeded, because at that point DMA is turned off):
> > > 
> > >    CAFÉ NAND 0000:00:0c.0: enabling device (0000 -> 0002)
> > >    nand: device found, Manufacturer ID: 0xad, Chip ID: 0xdc
> > >    nand: Hynix NAND 512MiB 3,3V 8-bit
> > >    nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> > >    nand: 2 chips detected
> > >    Bad block table not found for chip 0
> > >    Bad block table not found for chip 0
> > >    Scanning device for bad blocks
> > >    nand_bbt: error while erasing BBT block -5
> > >    nand_bbt: error -30 while marking block 8191 bad
> > >    nand_bbt: error while erasing BBT block -5
> > >    nand_bbt: error -30 while marking block 8190 bad
> > >    nand_bbt: error while erasing BBT block -5
> > >    nand_bbt: error -30 while marking block 8189 bad
> > >    nand_bbt: error while erasing BBT block -5
> > >    nand_bbt: error -30 while marking block 8188 bad
> > >    No space left to write bad block table
> > >    nand_bbt: error while writing bad block table -28
> > > 
> > > I've done this on top of your branch:
> > > 
> > > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > > index 761d103e438f..2a769033392e 100644
> > > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > > +++ b/drivers/mtd/nand/raw/cafe_nand.c
> > > @@ -642,6 +642,11 @@ static int cafe_nand_exec_subop(struct nand_chip *chip,
> > >  
> > >         ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> > >                                  (status & wait) == wait, 1, USEC_PER_SEC);
> > > +       for (i = 0; i < subop->ninstrs; i++) {
> > > +               const struct nand_op_instr *instr = &subop->instrs[i];
> > > +               printk("%d: ret=%d instr=%d status=%08x wait=%08x\n", i, ret, instr->type, status, wait);
> > > +       }
> > > +
> > >         if (ret)
> > >                 return ret;
> > > 
> > > It indeed looks like CAFE_NAND_IRQ_CMD_DONE is never raised if there's a
> > > data operation involving DMA -- the status remains at 0x50000000. Full log:  
> > 
> > I see. The reason I was not entirely happy with the "wait on DMA_DONE
> > when there's a DMA transfer" is because this transfer might not be the
> > last instruction in a sub operation, and I feared we would not wait for
> > the full operation to be done but only the DMA transfer itself. So I
> > went back to the spec [1], and there's an interesting note page 38:
> > 
> > "
> > Software waits for <dma_done> field in the Interrupt Register (Table 91
> > p. 93) for read operation because DMA is the last step of read
> > operation and waits for <cmd_done>field in the Interrupt Register
> > (Table 91 p. 93) for write operation because Command execution is the
> > last step of write operation.
> > "
> > 
> > I just pushed a new fixup commit implementing this logic. Let me know
> > if that solves the problem.  
> 
> Hmm, it now fails differently. With the same debugging statements as
> above, instructions with NAND_OP_WAITRDY_INSTR and NAND_OP_DATA_IN_INSTR
> ops end up with CAFE_NAND_IRQ_CMD_DONE (without
> CAFE_NAND_IRQ_FLASH_RDY):
> 
> [    5.437591] 0: ret=-110 instr=4 status=80000000 wait=50000000
> [    5.445514] 1: ret=-110 instr=2 status=80000000 wait=50000000
> 
> The log is now very different from before, there seem to be a lot more
> insns invoked:
> 
> ...
> [    2.015391] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x6362d8c130, max_idle_ns: 440795220004 ns
> [    2.074923] CAF\xc3\x89 NAND 0000:00:0c.0: enabling device (0000 -> 0002)
> [    2.106786] clocksource: Switched to clocksource tsc
> [    2.143222] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.176055] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.208819] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.241588] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.274412] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.306431] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.337051] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.366696] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.395349] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.422788] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.448970] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.474571] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.498998] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.522198] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.544605] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.566084] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.586146] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.604824] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.622112] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.638020] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.652530] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.665652] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.677746] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.688759] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.698397] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.706697] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.713983] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.720317] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.725773] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.731212] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.736669] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.742105] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.747561] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.752997] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.758457] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.763892] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.769347] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.774808] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.780244] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.785703] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.791139] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.796596] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.802030] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.807491] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.812925] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.818385] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.823818] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.829275] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.834733] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.840163] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.845693] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> [    2.851150] 1: ret=0 instr=4 status=c0000000 wait=c0000000
> [    2.856691] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.862277] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.867894] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.873482] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.879099] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.884709] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.890298] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.895912] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.901503] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.907115] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.912700] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.918355] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.923937] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.929544] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.935160] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.940752] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.946369] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.951956] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.957574] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.963165] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.968777] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.974391] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.979976] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.985591] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.991181] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    2.996797] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.002360] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.007897] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.013393] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.018857] 1: ret=0 instr=1 status=c0000000 wait=80000000
> [    3.024361] 2: ret=0 instr=2 status=c0000000 wait=80000000
> [    3.029896] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.035509] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.041099] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.046718] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.052303] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.057921] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.063511] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.069128] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.074738] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.080324] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.085938] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.091528] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.097143] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.102736] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.108347] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.113932] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.119545] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.125201] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.130786] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.136405] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.141992] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.147609] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.153197] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.158813] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.164425] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.170010] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.175573] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.181064] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.186580] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.192018] 1: ret=0 instr=1 status=c0000000 wait=80000000
> [    3.197527] 2: ret=0 instr=2 status=c0000000 wait=80000000
> [    3.203081] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.208697] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.214287] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.219900] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.225506] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.231091] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.236704] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.242286] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.247902] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.253493] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.259108] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.264723] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.270313] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.275930] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.281518] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.287134] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.292714] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.298321] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.303907] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.309519] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.315123] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.320710] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.326322] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.331905] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.337561] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.343145] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.348711] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.354199] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.359716] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.365177] 1: ret=0 instr=1 status=c0000000 wait=80000000
> [    3.370663] 2: ret=0 instr=2 status=c0000000 wait=80000000
> [    3.376229] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.381816] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.387432] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.393022] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.398639] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.404224] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.409841] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.415454] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.421040] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.426656] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.432246] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.437858] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.443442] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.449057] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.454670] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.460256] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.465868] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.471460] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.477075] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.482666] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.488284] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.493871] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.499489] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.505099] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.510684] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.516297] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.521828] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.527342] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.532836] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.538300] 1: ret=0 instr=1 status=c0000000 wait=80000000
> [    3.543783] 2: ret=0 instr=2 status=c0000000 wait=80000000
> [    3.549387] nand: device found, Manufacturer ID: 0xad, Chip ID: 0xdc
> [    3.557013] nand: Hynix NAND 512MiB 3,3V 8-bit
> [    3.563159] nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> [    3.574263] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.584103] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.593947] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.603781] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.613618] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.623455] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.633290] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.643128] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.652961] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.662801] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.672638] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.682474] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.692319] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.702154] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.711991] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.721828] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.731649] random: fast init done
> [    3.739815] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.751384] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.762995] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.774571] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.786136] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.797705] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.809224] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.820693] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.831147] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.840734] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.849203] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.856386] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.863549] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.870739] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.877929] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.885115] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.892279] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.899469] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.906654] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.913812] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.920998] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.928191] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.935381] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.942541] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.949727] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.956917] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.964080] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.970442] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.975902] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.981335] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.986797] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.992228] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    3.997691] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.003124] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.008639] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> [    4.014093] 1: ret=0 instr=4 status=c0000000 wait=c0000000
> [    4.019634] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.025249] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.030836] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.036454] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.042041] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.047659] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.053248] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.058863] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.064475] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.070065] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.075678] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.081269] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.086879] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.092464] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.098075] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.103660] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.109276] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.114889] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.120472] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.126089] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.131676] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.137294] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.142882] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.148501] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.154087] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.159705] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.165290] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.170798] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.176360] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.181800] 1: ret=0 instr=1 status=c0000000 wait=80000000
> [    4.187310] 2: ret=0 instr=2 status=c0000000 wait=80000000
> [    4.192841] nand: 2 chips detected
> [    4.196736] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.204000] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.211291] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.218580] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.225864] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.233132] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.240420] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.247706] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.254993] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.262259] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.269546] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.276834] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.284098] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.291383] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.298675] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.305961] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.313225] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.320513] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.327803] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.335095] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.342362] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.349651] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.356940] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.364212] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.371505] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.378744] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.385967] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.392267] 0: ret=0 instr=0 status=c0000000 wait=80000000
> [    4.397788] 0: ret=0 instr=0 status=d0000000 wait=10000000
> [    4.403274] 1: ret=0 instr=1 status=d0000000 wait=10000000
> [    4.408832] 2: ret=0 instr=2 status=d0000000 wait=10000000
> [    4.414591] 0: ret=0 instr=0 status=d0000000 wait=c0000000
> [    4.420248] 1: ret=0 instr=1 status=d0000000 wait=c0000000
> [    4.425982] 2: ret=0 instr=0 status=d0000000 wait=c0000000
> [    4.431732] 3: ret=0 instr=4 status=d0000000 wait=c0000000
> [    5.100219] random: crng init done
> [    5.437591] 0: ret=-110 instr=4 status=80000000 wait=50000000
> [    5.445514] 1: ret=-110 instr=2 status=80000000 wait=50000000
> [    5.453530] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> [    5.461864] 1: ret=0 instr=1 status=c0000000 wait=c0000000
> [    5.470250] 2: ret=0 instr=0 status=c0000000 wait=c0000000
> [    5.478688] 3: ret=0 instr=4 status=c0000000 wait=c0000000
> [    6.487183] 0: ret=-110 instr=4 status=80000000 wait=50000000
> [    6.496679] 1: ret=-110 instr=2 status=80000000 wait=50000000
> [    6.506283] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> [    6.516185] 1: ret=0 instr=1 status=c0000000 wait=c0000000
> [    6.526139] 2: ret=0 instr=0 status=c0000000 wait=c0000000
> [    6.536148] 3: ret=0 instr=4 status=c0000000 wait=c0000000
> [    7.546203] 0: ret=-110 instr=4 status=80000000 wait=50000000
> [    7.557261] 1: ret=-110 instr=2 status=80000000 wait=50000000
> [    7.568434] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> [    7.579909] 1: ret=0 instr=1 status=c0000000 wait=c0000000
> [    7.591429] 2: ret=0 instr=0 status=c0000000 wait=c0000000
> [    7.602996] 3: ret=0 instr=4 status=c0000000 wait=c0000000
> [    8.614662] 0: ret=-110 instr=4 status=80000000 wait=50000000
> [    8.627294] 1: ret=-110 instr=2 status=80000000 wait=50000000
> [    8.639917] Bad block table not found for chip 0
> ...
> 
> I'm happy to test another patch, or add more tracing (I'm not at all
> familiar with NAND flashes or MTD for that matter, so I have little idea
> what to look for).

I pushed a new version with extended traces. That should tell us what
those operations.

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
  2020-05-03  7:04             ` Boris Brezillon
@ 2020-05-03  7:26               ` Boris Brezillon
       [not found]                 ` <20200503175537.GA404453@furthur.local>
       [not found]               ` <20200503075208.GA387473@furthur.local>
  1 sibling, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-05-03  7:26 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: vigneshr, tudor.ambarus, richard, linux-mtd, miquel.raynal, dwmw2

On Sun, 3 May 2020 09:04:49 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:

> On Sun, 3 May 2020 08:06:10 +0200
> Lubomir Rintel <lkundrak@v3.sk> wrote:
> 
> > On Sun, May 03, 2020 at 12:34:56AM +0200, Boris Brezillon wrote:  
> > > On Sat, 2 May 2020 21:18:43 +0200
> > > Lubomir Rintel <lkundrak@v3.sk> wrote:
> > >     
> > > > On Sat, May 02, 2020 at 03:18:11PM +0200, Boris Brezillon wrote:    
> > > > > On Sat,  2 May 2020 13:14:10 +0200
> > > > > Lubomir Rintel <lkundrak@v3.sk> wrote:
> > > > >       
> > > > > > Boris Brezillon wrote:      
> > > > > > > Implementing exec_op() will help us get rid of the legacy interface and
> > > > > > > should make drivers much cleaner too.
> > > > > > > 
> > > > > > > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> > > > > > > ---
> > > > > > >  drivers/mtd/nand/raw/cafe_nand.c | 137 ++++++++++++++++++++++++++++++-
> > > > > > >  1 file changed, 136 insertions(+), 1 deletion(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > > > > > > index edf65197604b..ada9c8b06a41 100644
> > > > > > > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > > > > > > +++ b/drivers/mtd/nand/raw/cafe_nand.c        
> > > > > > ...
> > > > > >       
> > > > > > > +	ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> > > > > > > +				 (status & wait) == wait, 1, USEC_PER_SEC);
> > > > > > > +	if (ret)
> > > > > > > +		return ret;
> > > > > > > +
> > > > > > > +	if (ctrl1 & CAFE_NAND_DMA_CTRL_DATA_IN)        
> > > > > >                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > > > > s/CAFE_NAND_DMA_CTRL_DATA_IN/CAFE_NAND_CTRL1_HAS_DATA_IN/ here please.
> > > > > > 
> > > > > >       
> > > > > > > +		cafe_read_buf(chip, data_instr->ctx.data.buf.in,
> > > > > > > +			      data_instr->ctx.data.len);
> > > > > > > +
> > > > > > > +	return 0;
> > > > > > > +}        
> > > > > > ...
> > > > > > 
> > > > > > Other than that, when DMA is in use, only CAFE_NAND_IRQ_DMA_DONE seem to pop
> > > > > > up in CAFE_NAND_IRQ when the command completes, not CAFE_NAND_IRQ_CMD_DONE.
> > > > > > I suppose you ought to do this or something equivalent:      
> > > > > 
> > > > > I suspect it has to do with the fact that you might have operations with
> > > > > DATA_IN() instructions only. I pushed an alternate fix [1] to my branch.
> > > > > Would you mind testing it?      
> > > > 
> > > > That sounded plausible, but it doesn't seem to be to be the case. With
> > > > the patch the operations doing DMA transfers still seem to time out (the
> > > > identification succeeded, because at that point DMA is turned off):
> > > > 
> > > >    CAFÉ NAND 0000:00:0c.0: enabling device (0000 -> 0002)
> > > >    nand: device found, Manufacturer ID: 0xad, Chip ID: 0xdc
> > > >    nand: Hynix NAND 512MiB 3,3V 8-bit
> > > >    nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> > > >    nand: 2 chips detected
> > > >    Bad block table not found for chip 0
> > > >    Bad block table not found for chip 0
> > > >    Scanning device for bad blocks
> > > >    nand_bbt: error while erasing BBT block -5
> > > >    nand_bbt: error -30 while marking block 8191 bad
> > > >    nand_bbt: error while erasing BBT block -5
> > > >    nand_bbt: error -30 while marking block 8190 bad
> > > >    nand_bbt: error while erasing BBT block -5
> > > >    nand_bbt: error -30 while marking block 8189 bad
> > > >    nand_bbt: error while erasing BBT block -5
> > > >    nand_bbt: error -30 while marking block 8188 bad
> > > >    No space left to write bad block table
> > > >    nand_bbt: error while writing bad block table -28
> > > > 
> > > > I've done this on top of your branch:
> > > > 
> > > > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > > > index 761d103e438f..2a769033392e 100644
> > > > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > > > +++ b/drivers/mtd/nand/raw/cafe_nand.c
> > > > @@ -642,6 +642,11 @@ static int cafe_nand_exec_subop(struct nand_chip *chip,
> > > >  
> > > >         ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> > > >                                  (status & wait) == wait, 1, USEC_PER_SEC);
> > > > +       for (i = 0; i < subop->ninstrs; i++) {
> > > > +               const struct nand_op_instr *instr = &subop->instrs[i];
> > > > +               printk("%d: ret=%d instr=%d status=%08x wait=%08x\n", i, ret, instr->type, status, wait);
> > > > +       }
> > > > +
> > > >         if (ret)
> > > >                 return ret;
> > > > 
> > > > It indeed looks like CAFE_NAND_IRQ_CMD_DONE is never raised if there's a
> > > > data operation involving DMA -- the status remains at 0x50000000. Full log:    
> > > 
> > > I see. The reason I was not entirely happy with the "wait on DMA_DONE
> > > when there's a DMA transfer" is because this transfer might not be the
> > > last instruction in a sub operation, and I feared we would not wait for
> > > the full operation to be done but only the DMA transfer itself. So I
> > > went back to the spec [1], and there's an interesting note page 38:
> > > 
> > > "
> > > Software waits for <dma_done> field in the Interrupt Register (Table 91
> > > p. 93) for read operation because DMA is the last step of read
> > > operation and waits for <cmd_done>field in the Interrupt Register
> > > (Table 91 p. 93) for write operation because Command execution is the
> > > last step of write operation.
> > > "
> > > 
> > > I just pushed a new fixup commit implementing this logic. Let me know
> > > if that solves the problem.    
> > 
> > Hmm, it now fails differently. With the same debugging statements as
> > above, instructions with NAND_OP_WAITRDY_INSTR and NAND_OP_DATA_IN_INSTR
> > ops end up with CAFE_NAND_IRQ_CMD_DONE (without
> > CAFE_NAND_IRQ_FLASH_RDY):
> > 
> > [    5.437591] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > [    5.445514] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > 
> > The log is now very different from before, there seem to be a lot more
> > insns invoked:
> > 
> > ...
> > [    2.015391] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x6362d8c130, max_idle_ns: 440795220004 ns
> > [    2.074923] CAF\xc3\x89 NAND 0000:00:0c.0: enabling device (0000 -> 0002)
> > [    2.106786] clocksource: Switched to clocksource tsc
> > [    2.143222] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.176055] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.208819] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.241588] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.274412] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.306431] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.337051] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.366696] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.395349] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.422788] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.448970] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.474571] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.498998] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.522198] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.544605] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.566084] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.586146] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.604824] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.622112] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.638020] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.652530] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.665652] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.677746] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.688759] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.698397] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.706697] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.713983] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.720317] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.725773] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.731212] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.736669] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.742105] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.747561] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.752997] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.758457] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.763892] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.769347] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.774808] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.780244] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.785703] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.791139] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.796596] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.802030] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.807491] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.812925] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.818385] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.823818] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.829275] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.834733] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.840163] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.845693] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > [    2.851150] 1: ret=0 instr=4 status=c0000000 wait=c0000000
> > [    2.856691] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.862277] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.867894] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.873482] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.879099] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.884709] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.890298] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.895912] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.901503] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.907115] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.912700] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.918355] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.923937] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.929544] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.935160] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.940752] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.946369] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.951956] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.957574] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.963165] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.968777] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.974391] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.979976] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.985591] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.991181] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    2.996797] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.002360] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.007897] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.013393] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.018857] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > [    3.024361] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > [    3.029896] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.035509] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.041099] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.046718] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.052303] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.057921] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.063511] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.069128] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.074738] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.080324] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.085938] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.091528] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.097143] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.102736] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.108347] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.113932] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.119545] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.125201] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.130786] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.136405] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.141992] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.147609] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.153197] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.158813] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.164425] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.170010] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.175573] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.181064] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.186580] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.192018] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > [    3.197527] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > [    3.203081] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.208697] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.214287] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.219900] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.225506] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.231091] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.236704] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.242286] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.247902] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.253493] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.259108] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.264723] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.270313] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.275930] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.281518] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.287134] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.292714] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.298321] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.303907] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.309519] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.315123] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.320710] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.326322] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.331905] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.337561] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.343145] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.348711] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.354199] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.359716] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.365177] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > [    3.370663] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > [    3.376229] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.381816] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.387432] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.393022] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.398639] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.404224] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.409841] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.415454] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.421040] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.426656] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.432246] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.437858] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.443442] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.449057] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.454670] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.460256] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.465868] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.471460] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.477075] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.482666] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.488284] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.493871] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.499489] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.505099] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.510684] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.516297] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.521828] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.527342] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.532836] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.538300] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > [    3.543783] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > [    3.549387] nand: device found, Manufacturer ID: 0xad, Chip ID: 0xdc
> > [    3.557013] nand: Hynix NAND 512MiB 3,3V 8-bit
> > [    3.563159] nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> > [    3.574263] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.584103] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.593947] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.603781] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.613618] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.623455] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.633290] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.643128] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.652961] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.662801] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.672638] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.682474] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.692319] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.702154] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.711991] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.721828] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.731649] random: fast init done
> > [    3.739815] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.751384] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.762995] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.774571] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.786136] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.797705] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.809224] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.820693] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.831147] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.840734] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.849203] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.856386] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.863549] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.870739] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.877929] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.885115] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.892279] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.899469] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.906654] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.913812] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.920998] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.928191] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.935381] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.942541] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.949727] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.956917] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.964080] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.970442] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.975902] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.981335] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.986797] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.992228] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    3.997691] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.003124] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.008639] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > [    4.014093] 1: ret=0 instr=4 status=c0000000 wait=c0000000
> > [    4.019634] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.025249] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.030836] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.036454] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.042041] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.047659] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.053248] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.058863] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.064475] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.070065] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.075678] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.081269] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.086879] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.092464] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.098075] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.103660] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.109276] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.114889] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.120472] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.126089] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.131676] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.137294] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.142882] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.148501] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.154087] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.159705] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.165290] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.170798] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.176360] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.181800] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > [    4.187310] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > [    4.192841] nand: 2 chips detected
> > [    4.196736] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.204000] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.211291] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.218580] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.225864] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.233132] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.240420] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.247706] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.254993] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.262259] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.269546] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.276834] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.284098] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.291383] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.298675] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.305961] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.313225] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.320513] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.327803] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.335095] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.342362] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.349651] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.356940] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.364212] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.371505] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.378744] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.385967] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.392267] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > [    4.397788] 0: ret=0 instr=0 status=d0000000 wait=10000000
> > [    4.403274] 1: ret=0 instr=1 status=d0000000 wait=10000000
> > [    4.408832] 2: ret=0 instr=2 status=d0000000 wait=10000000
> > [    4.414591] 0: ret=0 instr=0 status=d0000000 wait=c0000000
> > [    4.420248] 1: ret=0 instr=1 status=d0000000 wait=c0000000
> > [    4.425982] 2: ret=0 instr=0 status=d0000000 wait=c0000000
> > [    4.431732] 3: ret=0 instr=4 status=d0000000 wait=c0000000
> > [    5.100219] random: crng init done
> > [    5.437591] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > [    5.445514] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > [    5.453530] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > [    5.461864] 1: ret=0 instr=1 status=c0000000 wait=c0000000
> > [    5.470250] 2: ret=0 instr=0 status=c0000000 wait=c0000000
> > [    5.478688] 3: ret=0 instr=4 status=c0000000 wait=c0000000
> > [    6.487183] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > [    6.496679] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > [    6.506283] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > [    6.516185] 1: ret=0 instr=1 status=c0000000 wait=c0000000
> > [    6.526139] 2: ret=0 instr=0 status=c0000000 wait=c0000000
> > [    6.536148] 3: ret=0 instr=4 status=c0000000 wait=c0000000
> > [    7.546203] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > [    7.557261] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > [    7.568434] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > [    7.579909] 1: ret=0 instr=1 status=c0000000 wait=c0000000
> > [    7.591429] 2: ret=0 instr=0 status=c0000000 wait=c0000000
> > [    7.602996] 3: ret=0 instr=4 status=c0000000 wait=c0000000
> > [    8.614662] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > [    8.627294] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > [    8.639917] Bad block table not found for chip 0
> > ...
> > 
> > I'm happy to test another patch, or add more tracing (I'm not at all
> > familiar with NAND flashes or MTD for that matter, so I have little idea
> > what to look for).  
> 
> I pushed a new version with extended traces. That should tell us what
> those operations.

I pushed a new branch [1] containing only the cafe NAND changes (I fear
one of my other change in the nand/exec-op-conversion branch generates a
lot more operations that we should have).

[1]https://github.com/bbrezillon/linux/tree/nand/cafe-nand-exec-op-debug

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
       [not found]               ` <20200503075208.GA387473@furthur.local>
@ 2020-05-03  8:13                 ` Boris Brezillon
  2020-05-03  8:35                   ` Boris Brezillon
  0 siblings, 1 reply; 58+ messages in thread
From: Boris Brezillon @ 2020-05-03  8:13 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: vigneshr, tudor.ambarus, richard, linux-mtd, miquel.raynal, dwmw2

On Sun, 3 May 2020 09:52:08 +0200
Lubomir Rintel <lkundrak@v3.sk> wrote:

> On Sun, May 03, 2020 at 09:04:49AM +0200, Boris Brezillon wrote:
> > On Sun, 3 May 2020 08:06:10 +0200
> > Lubomir Rintel <lkundrak@v3.sk> wrote:
> >   
> > > On Sun, May 03, 2020 at 12:34:56AM +0200, Boris Brezillon wrote:  
> > > > On Sat, 2 May 2020 21:18:43 +0200
> > > > Lubomir Rintel <lkundrak@v3.sk> wrote:
> > > >     
> > > > > On Sat, May 02, 2020 at 03:18:11PM +0200, Boris Brezillon wrote:    
> > > > > > On Sat,  2 May 2020 13:14:10 +0200
> > > > > > Lubomir Rintel <lkundrak@v3.sk> wrote:
> > > > > >       
> > > > > > > Boris Brezillon wrote:      
> > > > > > > > Implementing exec_op() will help us get rid of the legacy interface and
> > > > > > > > should make drivers much cleaner too.
> > > > > > > > 
> > > > > > > > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> > > > > > > > ---
> > > > > > > >  drivers/mtd/nand/raw/cafe_nand.c | 137 ++++++++++++++++++++++++++++++-
> > > > > > > >  1 file changed, 136 insertions(+), 1 deletion(-)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > > > > > > > index edf65197604b..ada9c8b06a41 100644
> > > > > > > > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > > > > > > > +++ b/drivers/mtd/nand/raw/cafe_nand.c        
> > > > > > > ...
> > > > > > >       
> > > > > > > > +	ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> > > > > > > > +				 (status & wait) == wait, 1, USEC_PER_SEC);
> > > > > > > > +	if (ret)
> > > > > > > > +		return ret;
> > > > > > > > +
> > > > > > > > +	if (ctrl1 & CAFE_NAND_DMA_CTRL_DATA_IN)        
> > > > > > >                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > > > > > s/CAFE_NAND_DMA_CTRL_DATA_IN/CAFE_NAND_CTRL1_HAS_DATA_IN/ here please.
> > > > > > > 
> > > > > > >       
> > > > > > > > +		cafe_read_buf(chip, data_instr->ctx.data.buf.in,
> > > > > > > > +			      data_instr->ctx.data.len);
> > > > > > > > +
> > > > > > > > +	return 0;
> > > > > > > > +}        
> > > > > > > ...
> > > > > > > 
> > > > > > > Other than that, when DMA is in use, only CAFE_NAND_IRQ_DMA_DONE seem to pop
> > > > > > > up in CAFE_NAND_IRQ when the command completes, not CAFE_NAND_IRQ_CMD_DONE.
> > > > > > > I suppose you ought to do this or something equivalent:      
> > > > > > 
> > > > > > I suspect it has to do with the fact that you might have operations with
> > > > > > DATA_IN() instructions only. I pushed an alternate fix [1] to my branch.
> > > > > > Would you mind testing it?      
> > > > > 
> > > > > That sounded plausible, but it doesn't seem to be to be the case. With
> > > > > the patch the operations doing DMA transfers still seem to time out (the
> > > > > identification succeeded, because at that point DMA is turned off):
> > > > > 
> > > > >    CAFÉ NAND 0000:00:0c.0: enabling device (0000 -> 0002)
> > > > >    nand: device found, Manufacturer ID: 0xad, Chip ID: 0xdc
> > > > >    nand: Hynix NAND 512MiB 3,3V 8-bit
> > > > >    nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> > > > >    nand: 2 chips detected
> > > > >    Bad block table not found for chip 0
> > > > >    Bad block table not found for chip 0
> > > > >    Scanning device for bad blocks
> > > > >    nand_bbt: error while erasing BBT block -5
> > > > >    nand_bbt: error -30 while marking block 8191 bad
> > > > >    nand_bbt: error while erasing BBT block -5
> > > > >    nand_bbt: error -30 while marking block 8190 bad
> > > > >    nand_bbt: error while erasing BBT block -5
> > > > >    nand_bbt: error -30 while marking block 8189 bad
> > > > >    nand_bbt: error while erasing BBT block -5
> > > > >    nand_bbt: error -30 while marking block 8188 bad
> > > > >    No space left to write bad block table
> > > > >    nand_bbt: error while writing bad block table -28
> > > > > 
> > > > > I've done this on top of your branch:
> > > > > 
> > > > > diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
> > > > > index 761d103e438f..2a769033392e 100644
> > > > > --- a/drivers/mtd/nand/raw/cafe_nand.c
> > > > > +++ b/drivers/mtd/nand/raw/cafe_nand.c
> > > > > @@ -642,6 +642,11 @@ static int cafe_nand_exec_subop(struct nand_chip *chip,
> > > > >  
> > > > >         ret = readl_poll_timeout(cafe->mmio + CAFE_NAND_IRQ, status,
> > > > >                                  (status & wait) == wait, 1, USEC_PER_SEC);
> > > > > +       for (i = 0; i < subop->ninstrs; i++) {
> > > > > +               const struct nand_op_instr *instr = &subop->instrs[i];
> > > > > +               printk("%d: ret=%d instr=%d status=%08x wait=%08x\n", i, ret, instr->type, status, wait);
> > > > > +       }
> > > > > +
> > > > >         if (ret)
> > > > >                 return ret;
> > > > > 
> > > > > It indeed looks like CAFE_NAND_IRQ_CMD_DONE is never raised if there's a
> > > > > data operation involving DMA -- the status remains at 0x50000000. Full log:    
> > > > 
> > > > I see. The reason I was not entirely happy with the "wait on DMA_DONE
> > > > when there's a DMA transfer" is because this transfer might not be the
> > > > last instruction in a sub operation, and I feared we would not wait for
> > > > the full operation to be done but only the DMA transfer itself. So I
> > > > went back to the spec [1], and there's an interesting note page 38:
> > > > 
> > > > "
> > > > Software waits for <dma_done> field in the Interrupt Register (Table 91
> > > > p. 93) for read operation because DMA is the last step of read
> > > > operation and waits for <cmd_done>field in the Interrupt Register
> > > > (Table 91 p. 93) for write operation because Command execution is the
> > > > last step of write operation.
> > > > "
> > > > 
> > > > I just pushed a new fixup commit implementing this logic. Let me know
> > > > if that solves the problem.    
> > > 
> > > Hmm, it now fails differently. With the same debugging statements as
> > > above, instructions with NAND_OP_WAITRDY_INSTR and NAND_OP_DATA_IN_INSTR
> > > ops end up with CAFE_NAND_IRQ_CMD_DONE (without
> > > CAFE_NAND_IRQ_FLASH_RDY):
> > > 
> > > [    5.437591] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > > [    5.445514] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > > 
> > > The log is now very different from before, there seem to be a lot more
> > > insns invoked:
> > > 
> > > ...
> > > [    2.015391] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x6362d8c130, max_idle_ns: 440795220004 ns
> > > [    2.074923] CAF\xc3\x89 NAND 0000:00:0c.0: enabling device (0000 -> 0002)
> > > [    2.106786] clocksource: Switched to clocksource tsc
> > > [    2.143222] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.176055] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.208819] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.241588] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.274412] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.306431] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.337051] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.366696] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.395349] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.422788] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.448970] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.474571] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.498998] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.522198] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.544605] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.566084] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.586146] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.604824] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.622112] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.638020] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.652530] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.665652] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.677746] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.688759] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.698397] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.706697] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.713983] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.720317] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.725773] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.731212] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.736669] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.742105] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.747561] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.752997] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.758457] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.763892] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.769347] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.774808] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.780244] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.785703] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.791139] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.796596] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.802030] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.807491] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.812925] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.818385] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.823818] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.829275] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.834733] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.840163] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.845693] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > > [    2.851150] 1: ret=0 instr=4 status=c0000000 wait=c0000000
> > > [    2.856691] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.862277] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.867894] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.873482] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.879099] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.884709] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.890298] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.895912] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.901503] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.907115] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.912700] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.918355] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.923937] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.929544] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.935160] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.940752] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.946369] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.951956] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.957574] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.963165] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.968777] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.974391] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.979976] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.985591] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.991181] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    2.996797] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.002360] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.007897] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.013393] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.018857] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > > [    3.024361] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > > [    3.029896] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.035509] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.041099] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.046718] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.052303] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.057921] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.063511] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.069128] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.074738] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.080324] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.085938] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.091528] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.097143] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.102736] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.108347] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.113932] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.119545] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.125201] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.130786] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.136405] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.141992] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.147609] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.153197] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.158813] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.164425] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.170010] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.175573] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.181064] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.186580] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.192018] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > > [    3.197527] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > > [    3.203081] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.208697] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.214287] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.219900] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.225506] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.231091] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.236704] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.242286] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.247902] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.253493] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.259108] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.264723] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.270313] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.275930] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.281518] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.287134] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.292714] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.298321] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.303907] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.309519] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.315123] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.320710] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.326322] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.331905] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.337561] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.343145] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.348711] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.354199] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.359716] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.365177] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > > [    3.370663] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > > [    3.376229] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.381816] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.387432] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.393022] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.398639] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.404224] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.409841] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.415454] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.421040] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.426656] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.432246] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.437858] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.443442] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.449057] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.454670] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.460256] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.465868] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.471460] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.477075] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.482666] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.488284] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.493871] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.499489] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.505099] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.510684] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.516297] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.521828] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.527342] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.532836] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.538300] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > > [    3.543783] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > > [    3.549387] nand: device found, Manufacturer ID: 0xad, Chip ID: 0xdc
> > > [    3.557013] nand: Hynix NAND 512MiB 3,3V 8-bit
> > > [    3.563159] nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> > > [    3.574263] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.584103] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.593947] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.603781] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.613618] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.623455] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.633290] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.643128] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.652961] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.662801] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.672638] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.682474] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.692319] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.702154] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.711991] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.721828] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.731649] random: fast init done
> > > [    3.739815] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.751384] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.762995] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.774571] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.786136] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.797705] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.809224] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.820693] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.831147] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.840734] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.849203] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.856386] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.863549] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.870739] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.877929] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.885115] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.892279] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.899469] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.906654] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.913812] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.920998] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.928191] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.935381] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.942541] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.949727] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.956917] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.964080] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.970442] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.975902] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.981335] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.986797] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.992228] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    3.997691] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.003124] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.008639] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > > [    4.014093] 1: ret=0 instr=4 status=c0000000 wait=c0000000
> > > [    4.019634] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.025249] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.030836] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.036454] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.042041] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.047659] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.053248] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.058863] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.064475] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.070065] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.075678] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.081269] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.086879] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.092464] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.098075] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.103660] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.109276] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.114889] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.120472] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.126089] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.131676] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.137294] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.142882] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.148501] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.154087] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.159705] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.165290] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.170798] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.176360] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.181800] 1: ret=0 instr=1 status=c0000000 wait=80000000
> > > [    4.187310] 2: ret=0 instr=2 status=c0000000 wait=80000000
> > > [    4.192841] nand: 2 chips detected
> > > [    4.196736] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.204000] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.211291] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.218580] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.225864] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.233132] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.240420] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.247706] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.254993] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.262259] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.269546] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.276834] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.284098] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.291383] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.298675] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.305961] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.313225] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.320513] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.327803] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.335095] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.342362] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.349651] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.356940] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.364212] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.371505] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.378744] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.385967] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.392267] 0: ret=0 instr=0 status=c0000000 wait=80000000
> > > [    4.397788] 0: ret=0 instr=0 status=d0000000 wait=10000000
> > > [    4.403274] 1: ret=0 instr=1 status=d0000000 wait=10000000
> > > [    4.408832] 2: ret=0 instr=2 status=d0000000 wait=10000000
> > > [    4.414591] 0: ret=0 instr=0 status=d0000000 wait=c0000000
> > > [    4.420248] 1: ret=0 instr=1 status=d0000000 wait=c0000000
> > > [    4.425982] 2: ret=0 instr=0 status=d0000000 wait=c0000000
> > > [    4.431732] 3: ret=0 instr=4 status=d0000000 wait=c0000000
> > > [    5.100219] random: crng init done
> > > [    5.437591] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > > [    5.445514] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > > [    5.453530] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > > [    5.461864] 1: ret=0 instr=1 status=c0000000 wait=c0000000
> > > [    5.470250] 2: ret=0 instr=0 status=c0000000 wait=c0000000
> > > [    5.478688] 3: ret=0 instr=4 status=c0000000 wait=c0000000
> > > [    6.487183] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > > [    6.496679] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > > [    6.506283] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > > [    6.516185] 1: ret=0 instr=1 status=c0000000 wait=c0000000
> > > [    6.526139] 2: ret=0 instr=0 status=c0000000 wait=c0000000
> > > [    6.536148] 3: ret=0 instr=4 status=c0000000 wait=c0000000
> > > [    7.546203] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > > [    7.557261] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > > [    7.568434] 0: ret=0 instr=0 status=c0000000 wait=c0000000
> > > [    7.579909] 1: ret=0 instr=1 status=c0000000 wait=c0000000
> > > [    7.591429] 2: ret=0 instr=0 status=c0000000 wait=c0000000
> > > [    7.602996] 3: ret=0 instr=4 status=c0000000 wait=c0000000
> > > [    8.614662] 0: ret=-110 instr=4 status=80000000 wait=50000000
> > > [    8.627294] 1: ret=-110 instr=2 status=80000000 wait=50000000
> > > [    8.639917] Bad block table not found for chip 0
> > > ...
> > > 
> > > I'm happy to test another patch, or add more tracing (I'm not at all
> > > familiar with NAND flashes or MTD for that matter, so I have little idea
> > > what to look for).  
> > 
> > I pushed a new version with extended traces. That should tell us what
> > those operations.  
> 
> Thank you.
> 
> I moved the last debugging printk() right after the call to
> readl_poll_timeout(), otherwise we'd not be reaching it on errors.
> 
> A quick grep for ret=-110 in the log reveals two kinds of errors:
> 
>   [   15.046151] instr[0] = WAITRDY
>   [   15.065290] instr[1] = DATA_IN(len=2112)
>   [   16.085166] 2: ret=-110 status=80000000 wait=50000000

Ok, that's interesting. While the WAITRDY shouldn't be there, DATA-only
operations are allowed, and I'd expect at least a DMA_DONE event in
that case, but we get nothing. Maybe we should use DMA only if there's
at least one addr/cmd instruction. Or maybe the engine can't do
DATA-only operations.

> 
> and
>  
>   [   47.034418] instr[0] = WAITRDY
>   [   48.054781] 1: ret=-110 status=10000000 wait=c0000000

Yep, I don't expect operation to start with a WAITRDY, and this
situation is probably caused by this commit [1].

> 
> Full log here:
> https://people.freedesktop.org/~lkundrak/nand-raw-trace2.txt
> 
> A log of your original patch, just in case the move of the logging
> statement was incorrect:
> https://people.freedesktop.org/~lkundrak/nand-raw-trace.txt
> 
> Lubo

[1]https://github.com/bbrezillon/linux/commit/30248fb955ba5e33a1863c8654f286b98c35d233

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
  2020-05-03  8:13                 ` Boris Brezillon
@ 2020-05-03  8:35                   ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-05-03  8:35 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: vigneshr, tudor.ambarus, richard, linux-mtd, miquel.raynal, dwmw2

On Sun, 3 May 2020 10:13:03 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:

> > > > 
> > > > I'm happy to test another patch, or add more tracing (I'm not at all
> > > > familiar with NAND flashes or MTD for that matter, so I have little idea
> > > > what to look for).    
> > > 
> > > I pushed a new version with extended traces. That should tell us what
> > > those operations.    
> > 
> > Thank you.
> > 
> > I moved the last debugging printk() right after the call to
> > readl_poll_timeout(), otherwise we'd not be reaching it on errors.
> > 
> > A quick grep for ret=-110 in the log reveals two kinds of errors:
> > 
> >   [   15.046151] instr[0] = WAITRDY
> >   [   15.065290] instr[1] = DATA_IN(len=2112)
> >   [   16.085166] 2: ret=-110 status=80000000 wait=50000000  
> 
> Ok, that's interesting. While the WAITRDY shouldn't be there, DATA-only
> operations are allowed, and I'd expect at least a DMA_DONE event in
> that case, but we get nothing. Maybe we should use DMA only if there's
> at least one addr/cmd instruction. Or maybe the engine can't do
> DATA-only operations.

Or maybe length is actually 0 here, since my traces print
instr->ctx.data.len instead of nand_subop_get_data_len(subop, i).

> 
> > 
> > and
> >  
> >   [   47.034418] instr[0] = WAITRDY
> >   [   48.054781] 1: ret=-110 status=10000000 wait=c0000000  
> 
> Yep, I don't expect operation to start with a WAITRDY, and this
> situation is probably caused by this commit [1].

This commit is indeed introducing a regression (see the fix here [2]).
That should work better now.

> 
> > 
> > Full log here:
> > https://people.freedesktop.org/~lkundrak/nand-raw-trace2.txt
> > 
> > A log of your original patch, just in case the move of the logging
> > statement was incorrect:
> > https://people.freedesktop.org/~lkundrak/nand-raw-trace.txt
> > 
> > Lubo  
> 
> [1]https://github.com/bbrezillon/linux/commit/30248fb955ba5e33a1863c8654f286b98c35d233

[2]https://github.com/bbrezillon/linux/commit/ec0460c61343a539889ab6298dd043d00717f19b

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
       [not found]                 ` <20200503175537.GA404453@furthur.local>
@ 2020-05-03 19:49                   ` Boris Brezillon
  0 siblings, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-05-03 19:49 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: vigneshr, tudor.ambarus, richard, linux-mtd, miquel.raynal, dwmw2

On Sun, 3 May 2020 19:55:37 +0200
Lubomir Rintel <lkundrak@v3.sk> wrote:

> > > > ...
> > > > 
> > > > I'm happy to test another patch, or add more tracing (I'm not at all
> > > > familiar with NAND flashes or MTD for that matter, so I have little idea
> > > > what to look for).    
> > > 
> > > I pushed a new version with extended traces. That should tell us what
> > > those operations.  
> > 
> > I pushed a new branch [1] containing only the cafe NAND changes (I fear
> > one of my other change in the nand/exec-op-conversion branch generates a
> > lot more operations that we should have).
> > 
> > [1]https://github.com/bbrezillon/linux/tree/nand/cafe-nand-exec-op-debug  
> 
> Seems to work a treat and the log also looks reasonable now:
> https://people.freedesktop.org/~lkundrak/nand-raw-trace3.txt

Perfect, I'll send a v2 soon.

Thanks again for testing.

Boris

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

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

* Re: [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more)
  2020-05-02 13:15   ` Boris Brezillon
@ 2020-05-08 10:32     ` Miquel Raynal
  0 siblings, 0 replies; 58+ messages in thread
From: Miquel Raynal @ 2020-05-08 10:32 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: vigneshr, tudor.ambarus, richard, Lubomir Rintel, linux-mtd,
	Thomas Petazzoni, dwmw2


> > 2.) When the block after a conditional is multiple lines, could you please
> > include the curly braces? That is:
> > 
> >         if (ctrl1 & CAFE_NAND_CTRL1_HAS_DATA_IN) {
> >                 cafe_read_buf(chip,
> >                               subop->instrs[data_instr].ctx.data.buf.in +
> >                               nand_subop_get_data_start_off(subop, data_instr),
> >                               nand_subop_get_data_len(subop, data_instr));
> >         }
> > 
> > Instead of:
> > 
> >         if (ctrl1 & CAFE_NAND_CTRL1_HAS_DATA_IN)
> >                 cafe_read_buf(chip,
> >                               subop->instrs[data_instr].ctx.data.buf.in +
> >                               nand_subop_get_data_start_off(subop, data_instr),
> >                               nand_subop_get_data_len(subop, data_instr));
> > 
> > This makes things significantly easier to read for me, not to mention that it
> > comes handy to have the braces around for printf debugging.  
> 
> I do prefer the version without brackets, but given you debugged it,
> I'd be okay changing that one ;-) (assuming Miquel is okay with that
> too, of course).

I also prefer having curly braces around single-multiline-instructions
:)

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

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

* Re: [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support
       [not found]       ` <20200502191843.GA363829@furthur.local>
  2020-05-02 22:34         ` Boris Brezillon
@ 2020-05-09 20:10         ` Boris Brezillon
  1 sibling, 0 replies; 58+ messages in thread
From: Boris Brezillon @ 2020-05-09 20:10 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: vigneshr, tudor.ambarus, richard, linux-mtd, miquel.raynal, dwmw2

On Sat, 2 May 2020 21:18:43 +0200
Lubomir Rintel <lkundrak@v3.sk> wrote:

>    CAFÉ NAND 0000:00:0c.0: enabling device (0000 -> 0002)
>    nand: device found, Manufacturer ID: 0xad, Chip ID: 0xdc
>    nand: Hynix NAND 512MiB 3,3V 8-bit
>    nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
>    nand: 2 chips detected

Ok. Given the size of your NAND, you really should consider using
UBI/UBIFS if you want to have decent mount time (you might even want to
use UBI fastmap to speed up the attach time even more).

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

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

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

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-27  8:20 [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Boris Brezillon
2020-04-27  8:20 ` [PATCH 01/17] mtd: rawnand: cafe: Get rid of an inaccurate kernel doc header Boris Brezillon
2020-04-27 19:33   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 02/17] mtd: rawnand: cafe: Rename cafe_nand_write_page_lowlevel() Boris Brezillon
2020-04-27 19:33   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 03/17] mtd: rawnand: cafe: Use a correct ECC mode and pass the ECC alg Boris Brezillon
2020-04-27 19:34   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 04/17] mtd: rawnand: cafe: Include linux/io.h instead of asm/io.h Boris Brezillon
2020-04-27 19:35   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 05/17] mtd: rawnand: cafe: Demistify register fields Boris Brezillon
2020-04-27 19:42   ` Miquel Raynal
2020-04-28  6:06     ` Boris Brezillon
2020-04-27  8:20 ` [PATCH 06/17] mtd: rawnand: cafe: Factor out the controller initialization logic Boris Brezillon
2020-04-27 19:45   ` Miquel Raynal
2020-04-28  6:06     ` Boris Brezillon
2020-04-27  8:20 ` [PATCH 07/17] mtd: rawnand: cafe: Get rid of the debug module param Boris Brezillon
2020-04-27 19:46   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 08/17] mtd: rawnand: cafe: Use devm_kzalloc and devm_request_irq() Boris Brezillon
2020-04-27 19:47   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 09/17] mtd: rawnand: cafe: Get rid of a useless label Boris Brezillon
2020-04-27 19:47   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 10/17] mtd: rawnand: cafe: Explicitly inherit from nand_controller Boris Brezillon
2020-04-27 19:49   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 11/17] mtd: rawnand: cafe: Don't leave ECC enabled in the write path Boris Brezillon
2020-04-27 19:51   ` Miquel Raynal
2020-04-28  6:08     ` Boris Brezillon
2020-04-27  8:20 ` [PATCH 12/17] mtd: rawnand: cafe: Don't split things when reading/writing a page Boris Brezillon
2020-04-27 19:53   ` Miquel Raynal
2020-04-28  6:20     ` Boris Brezillon
2020-04-28  7:44       ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 13/17] mtd: rawnand: cafe: Add exec_op() support Boris Brezillon
2020-04-27 19:59   ` Miquel Raynal
2020-04-28  6:24     ` Boris Brezillon
     [not found]   ` <20200502111410.330584-1-lkundrak@v3.sk>
2020-05-02 13:18     ` Boris Brezillon
     [not found]       ` <20200502191843.GA363829@furthur.local>
2020-05-02 22:34         ` Boris Brezillon
     [not found]           ` <20200503060610.GA386731@furthur.local>
2020-05-03  7:04             ` Boris Brezillon
2020-05-03  7:26               ` Boris Brezillon
     [not found]                 ` <20200503175537.GA404453@furthur.local>
2020-05-03 19:49                   ` Boris Brezillon
     [not found]               ` <20200503075208.GA387473@furthur.local>
2020-05-03  8:13                 ` Boris Brezillon
2020-05-03  8:35                   ` Boris Brezillon
2020-05-09 20:10         ` Boris Brezillon
2020-04-27  8:20 ` [PATCH 14/17] mtd: rawnand: cafe: Get rid of the legacy interface implementation Boris Brezillon
2020-04-27 20:00   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read, write}_buf() prototypes Boris Brezillon
2020-04-27 20:00   ` [PATCH 15/17] mtd: rawnand: cafe: Adjust the cafe_{read,write}_buf() prototypes Miquel Raynal
2020-04-28  6:24     ` Boris Brezillon
2020-04-27  8:20 ` [PATCH 16/17] mtd: rawnand: cafe: Handle non-32bit aligned reads/writes Boris Brezillon
2020-04-27 20:04   ` Miquel Raynal
2020-04-28  6:26     ` Boris Brezillon
2020-04-27  8:20 ` [PATCH 17/17] mtd: rawnand: cafe: s/uint{8,16,32}_t/u{8,16,32}/ Boris Brezillon
2020-04-27 20:05   ` Miquel Raynal
2020-04-27  8:20 ` [PATCH 17/17] mtd: rawnand: s/uint{8,16,32}_t/u{8,16,32}/ Boris Brezillon
2020-04-27  8:25   ` Boris Brezillon
2020-04-29  6:37 ` [PATCH 00/17] mtd: rawnand: cafe: Convert to exec_op() (and more) Thomas Petazzoni
2020-04-29  8:28   ` Boris Brezillon
     [not found]     ` <20200501055209.GA44510@furthur.local>
2020-05-01  6:21       ` Boris Brezillon
     [not found] ` <20200502112732.330971-1-lkundrak@v3.sk>
2020-05-02 13:15   ` Boris Brezillon
2020-05-08 10:32     ` Miquel Raynal

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.