All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-08 14:21 ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

Hello,

This series add the sunxi NFC support with up to 8 NAND chip connected.
I'm still in the early stages drivers development and some key features are
missing, but it's usable (I tested it on the cubietruck board).

Here's what's missing:
 - HW ECC support
 - DMA support
 - HW randomization support
 - many more improvements

This series depends on Emilio's patch series implementing mod0 clks
(http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
+ an other patch not yet posted
(http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)


Best Regards,

Boris

Boris BREZILLON (9):
  mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
  mtd: nand: define struct nand_timings
  of: mtd: add NAND timings retrieval support
  of: mtd: add NAND timings bindings documentation
  mtd: nand: add sunxi NFC support
  mtd: nand: add sunxi NFC dt bindings doc
  ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
  ARM: dt/sunxi: add NFC pinctrl pin definitions
  ARM: sunxi/dt: enable NAND on cubietruck board

 Documentation/devicetree/bindings/mtd/nand.txt     |   34 +
 .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |   33 +
 arch/arm/boot/dts/sun7i-a20.dtsi                   |   35 +
 drivers/mtd/nand/Kconfig                           |    6 +
 drivers/mtd/nand/Makefile                          |    1 +
 drivers/mtd/nand/nand_base.c                       |   37 ++
 drivers/mtd/nand/sunxi_nfc.c                       |  700 ++++++++++++++++++++
 drivers/of/of_mtd.c                                |   47 ++
 include/linux/mtd/nand.h                           |   44 ++
 include/linux/of_mtd.h                             |    9 +
 11 files changed, 1017 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt
 create mode 100644 drivers/mtd/nand/sunxi_nfc.c

-- 
1.7.9.5


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

* [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-08 14:21 ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

Hello,

This series add the sunxi NFC support with up to 8 NAND chip connected.
I'm still in the early stages drivers development and some key features are
missing, but it's usable (I tested it on the cubietruck board).

Here's what's missing:
 - HW ECC support
 - DMA support
 - HW randomization support
 - many more improvements

This series depends on Emilio's patch series implementing mod0 clks
(http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
+ an other patch not yet posted
(http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)


Best Regards,

Boris

Boris BREZILLON (9):
  mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
  mtd: nand: define struct nand_timings
  of: mtd: add NAND timings retrieval support
  of: mtd: add NAND timings bindings documentation
  mtd: nand: add sunxi NFC support
  mtd: nand: add sunxi NFC dt bindings doc
  ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
  ARM: dt/sunxi: add NFC pinctrl pin definitions
  ARM: sunxi/dt: enable NAND on cubietruck board

 Documentation/devicetree/bindings/mtd/nand.txt     |   34 +
 .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |   33 +
 arch/arm/boot/dts/sun7i-a20.dtsi                   |   35 +
 drivers/mtd/nand/Kconfig                           |    6 +
 drivers/mtd/nand/Makefile                          |    1 +
 drivers/mtd/nand/nand_base.c                       |   37 ++
 drivers/mtd/nand/sunxi_nfc.c                       |  700 ++++++++++++++++++++
 drivers/of/of_mtd.c                                |   47 ++
 include/linux/mtd/nand.h                           |   44 ++
 include/linux/of_mtd.h                             |    9 +
 11 files changed, 1017 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt
 create mode 100644 drivers/mtd/nand/sunxi_nfc.c

-- 
1.7.9.5

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

* [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-08 14:21 ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This series add the sunxi NFC support with up to 8 NAND chip connected.
I'm still in the early stages drivers development and some key features are
missing, but it's usable (I tested it on the cubietruck board).

Here's what's missing:
 - HW ECC support
 - DMA support
 - HW randomization support
 - many more improvements

This series depends on Emilio's patch series implementing mod0 clks
(http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
+ an other patch not yet posted
(http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)


Best Regards,

Boris

Boris BREZILLON (9):
  mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
  mtd: nand: define struct nand_timings
  of: mtd: add NAND timings retrieval support
  of: mtd: add NAND timings bindings documentation
  mtd: nand: add sunxi NFC support
  mtd: nand: add sunxi NFC dt bindings doc
  ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
  ARM: dt/sunxi: add NFC pinctrl pin definitions
  ARM: sunxi/dt: enable NAND on cubietruck board

 Documentation/devicetree/bindings/mtd/nand.txt     |   34 +
 .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |   33 +
 arch/arm/boot/dts/sun7i-a20.dtsi                   |   35 +
 drivers/mtd/nand/Kconfig                           |    6 +
 drivers/mtd/nand/Makefile                          |    1 +
 drivers/mtd/nand/nand_base.c                       |   37 ++
 drivers/mtd/nand/sunxi_nfc.c                       |  700 ++++++++++++++++++++
 drivers/of/of_mtd.c                                |   47 ++
 include/linux/mtd/nand.h                           |   44 ++
 include/linux/of_mtd.h                             |    9 +
 11 files changed, 1017 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt
 create mode 100644 drivers/mtd/nand/sunxi_nfc.c

-- 
1.7.9.5

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

* [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
  2014-01-08 14:21 ` Boris BREZILLON
  (?)
@ 2014-01-08 14:21   ` Boris BREZILLON
  -1 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

The Hynix nand flashes store their ECC requirements in byte 4 of its id
(returned on READ ID command).

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/mtd/nand/nand_base.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index bd39f7b..15069ec 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3202,6 +3202,43 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 		else
 			mtd->erasesize = (64 * 1024) << tmp;
 		*busw = 0;
+
+		/* Retrieve ECC infos */
+		switch ((id_data[4] >> 4) & 0x7) {
+		case 1:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 1;
+			break;
+		case 2:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 2;
+			break;
+		case 3:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 4;
+			break;
+		case 4:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 8;
+			break;
+		case 5:
+			chip->ecc_step_ds = 1024;
+			chip->ecc_strength_ds = 24;
+			break;
+		case 6:
+			chip->ecc_step_ds = 1024;
+			chip->ecc_strength_ds = 32;
+			break;
+		case 7:
+			chip->ecc_step_ds = 1024;
+			chip->ecc_strength_ds = 40;
+			break;
+		case 0:
+		default:
+			chip->ecc_step_ds = 0;
+			chip->ecc_strength_ds = 0;
+			break;
+		}
 	} else {
 		/* Calc pagesize */
 		mtd->writesize = 1024 << (extid & 0x03);
-- 
1.7.9.5


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

* [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-01-08 14:21   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

The Hynix nand flashes store their ECC requirements in byte 4 of its id
(returned on READ ID command).

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/mtd/nand/nand_base.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index bd39f7b..15069ec 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3202,6 +3202,43 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 		else
 			mtd->erasesize = (64 * 1024) << tmp;
 		*busw = 0;
+
+		/* Retrieve ECC infos */
+		switch ((id_data[4] >> 4) & 0x7) {
+		case 1:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 1;
+			break;
+		case 2:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 2;
+			break;
+		case 3:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 4;
+			break;
+		case 4:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 8;
+			break;
+		case 5:
+			chip->ecc_step_ds = 1024;
+			chip->ecc_strength_ds = 24;
+			break;
+		case 6:
+			chip->ecc_step_ds = 1024;
+			chip->ecc_strength_ds = 32;
+			break;
+		case 7:
+			chip->ecc_step_ds = 1024;
+			chip->ecc_strength_ds = 40;
+			break;
+		case 0:
+		default:
+			chip->ecc_step_ds = 0;
+			chip->ecc_strength_ds = 0;
+			break;
+		}
 	} else {
 		/* Calc pagesize */
 		mtd->writesize = 1024 << (extid & 0x03);
-- 
1.7.9.5

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

* [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-01-08 14:21   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

The Hynix nand flashes store their ECC requirements in byte 4 of its id
(returned on READ ID command).

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/mtd/nand/nand_base.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index bd39f7b..15069ec 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3202,6 +3202,43 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 		else
 			mtd->erasesize = (64 * 1024) << tmp;
 		*busw = 0;
+
+		/* Retrieve ECC infos */
+		switch ((id_data[4] >> 4) & 0x7) {
+		case 1:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 1;
+			break;
+		case 2:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 2;
+			break;
+		case 3:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 4;
+			break;
+		case 4:
+			chip->ecc_step_ds = 512;
+			chip->ecc_strength_ds = 8;
+			break;
+		case 5:
+			chip->ecc_step_ds = 1024;
+			chip->ecc_strength_ds = 24;
+			break;
+		case 6:
+			chip->ecc_step_ds = 1024;
+			chip->ecc_strength_ds = 32;
+			break;
+		case 7:
+			chip->ecc_step_ds = 1024;
+			chip->ecc_strength_ds = 40;
+			break;
+		case 0:
+		default:
+			chip->ecc_step_ds = 0;
+			chip->ecc_strength_ds = 0;
+			break;
+		}
 	} else {
 		/* Calc pagesize */
 		mtd->writesize = 1024 << (extid & 0x03);
-- 
1.7.9.5

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

* [RFC PATCH 2/9] mtd: nand: define struct nand_timings
  2014-01-08 14:21 ` Boris BREZILLON
  (?)
@ 2014-01-08 14:21   ` Boris BREZILLON
  -1 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

Define a struct containing the standard NAND timings as described in NAND
datasheets.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 include/linux/mtd/nand.h |   44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 9e6c8f9..3dda312 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -805,4 +805,48 @@ static inline bool nand_is_slc(struct nand_chip *chip)
 {
 	return chip->bits_per_cell == 1;
 }
+
+/**
+ * struct nand_timings - NAND chip timing definitions
+ *
+ * This struct defines the timing requirements of a NAND chip.
+ * These informations can be found in every NAND datasheets.
+ *
+ * All fields are optional and depend on the hardware driver requirements
+ */
+struct nand_timings {
+	u32 tCLS_min;
+	u32 tCLH_min;
+	u32 tCS_min;
+	u32 tCH_min;
+	u32 tWP_min;
+	u32 tALS_min;
+	u32 tALH_min;
+	u32 tDS_min;
+	u32 tDH_min;
+	u32 tWC_min;
+	u32 tWH_min;
+	u32 tR_max;
+	u32 tAR_min;
+	u32 tCLR_min;
+	u32 tRR_min;
+	u32 tRP_min;
+	u32 tWB_max;
+	u32 tRC_min;
+	u32 tREA_max;
+	u32 tRHZ_max;
+	u32 tCHZ_max;
+	u32 tRHOH_min;
+	u32 tRLOH_min;
+	u32 tCOH_min;
+	u32 tREH_min;
+	u32 tWHR_min;
+	u32 tRHW_min;
+	u32 tIR_min;
+	u32 tCR_min;
+	u32 tADL_min;
+	u32 tRST_max;
+	u32 tWW_min;
+};
+
 #endif /* __LINUX_MTD_NAND_H */
-- 
1.7.9.5


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

* [RFC PATCH 2/9] mtd: nand: define struct nand_timings
@ 2014-01-08 14:21   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

Define a struct containing the standard NAND timings as described in NAND
datasheets.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 include/linux/mtd/nand.h |   44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 9e6c8f9..3dda312 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -805,4 +805,48 @@ static inline bool nand_is_slc(struct nand_chip *chip)
 {
 	return chip->bits_per_cell == 1;
 }
+
+/**
+ * struct nand_timings - NAND chip timing definitions
+ *
+ * This struct defines the timing requirements of a NAND chip.
+ * These informations can be found in every NAND datasheets.
+ *
+ * All fields are optional and depend on the hardware driver requirements
+ */
+struct nand_timings {
+	u32 tCLS_min;
+	u32 tCLH_min;
+	u32 tCS_min;
+	u32 tCH_min;
+	u32 tWP_min;
+	u32 tALS_min;
+	u32 tALH_min;
+	u32 tDS_min;
+	u32 tDH_min;
+	u32 tWC_min;
+	u32 tWH_min;
+	u32 tR_max;
+	u32 tAR_min;
+	u32 tCLR_min;
+	u32 tRR_min;
+	u32 tRP_min;
+	u32 tWB_max;
+	u32 tRC_min;
+	u32 tREA_max;
+	u32 tRHZ_max;
+	u32 tCHZ_max;
+	u32 tRHOH_min;
+	u32 tRLOH_min;
+	u32 tCOH_min;
+	u32 tREH_min;
+	u32 tWHR_min;
+	u32 tRHW_min;
+	u32 tIR_min;
+	u32 tCR_min;
+	u32 tADL_min;
+	u32 tRST_max;
+	u32 tWW_min;
+};
+
 #endif /* __LINUX_MTD_NAND_H */
-- 
1.7.9.5

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

* [RFC PATCH 2/9] mtd: nand: define struct nand_timings
@ 2014-01-08 14:21   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

Define a struct containing the standard NAND timings as described in NAND
datasheets.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 include/linux/mtd/nand.h |   44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 9e6c8f9..3dda312 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -805,4 +805,48 @@ static inline bool nand_is_slc(struct nand_chip *chip)
 {
 	return chip->bits_per_cell == 1;
 }
+
+/**
+ * struct nand_timings - NAND chip timing definitions
+ *
+ * This struct defines the timing requirements of a NAND chip.
+ * These informations can be found in every NAND datasheets.
+ *
+ * All fields are optional and depend on the hardware driver requirements
+ */
+struct nand_timings {
+	u32 tCLS_min;
+	u32 tCLH_min;
+	u32 tCS_min;
+	u32 tCH_min;
+	u32 tWP_min;
+	u32 tALS_min;
+	u32 tALH_min;
+	u32 tDS_min;
+	u32 tDH_min;
+	u32 tWC_min;
+	u32 tWH_min;
+	u32 tR_max;
+	u32 tAR_min;
+	u32 tCLR_min;
+	u32 tRR_min;
+	u32 tRP_min;
+	u32 tWB_max;
+	u32 tRC_min;
+	u32 tREA_max;
+	u32 tRHZ_max;
+	u32 tCHZ_max;
+	u32 tRHOH_min;
+	u32 tRLOH_min;
+	u32 tCOH_min;
+	u32 tREH_min;
+	u32 tWHR_min;
+	u32 tRHW_min;
+	u32 tIR_min;
+	u32 tCR_min;
+	u32 tADL_min;
+	u32 tRST_max;
+	u32 tWW_min;
+};
+
 #endif /* __LINUX_MTD_NAND_H */
-- 
1.7.9.5

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
  2014-01-08 14:21 ` Boris BREZILLON
  (?)
@ 2014-01-08 14:21   ` Boris BREZILLON
  -1 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

Add a function to retrieve NAND timings from a given DT node.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_mtd.h |    9 +++++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
index a27ec94..52e07fd 100644
--- a/drivers/of/of_mtd.c
+++ b/drivers/of/of_mtd.c
@@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
 	return of_property_read_bool(np, "nand-on-flash-bbt");
 }
 EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
+
+/**
+ * of_get_nand_timings - Get nand timings for the given device_node
+ * @np:	Pointer to the given device_node
+ *
+ * return 0 on success errno other wise
+ */
+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
+{
+	memset(timings, 0, sizeof(*timings));
+
+	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
+	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
+	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
+	of_property_read_u32(np, "tCH-min", &timings->tCH_min);
+	of_property_read_u32(np, "tWP-min", &timings->tWP_min);
+	of_property_read_u32(np, "tALS-min", &timings->tALS_min);
+	of_property_read_u32(np, "tALH-min", &timings->tALH_min);
+	of_property_read_u32(np, "tDS-min", &timings->tDS_min);
+	of_property_read_u32(np, "tDH-min", &timings->tDH_min);
+	of_property_read_u32(np, "tWC-min", &timings->tWC_min);
+	of_property_read_u32(np, "tWH-min", &timings->tWH_min);
+	of_property_read_u32(np, "tR-max", &timings->tR_max);
+	of_property_read_u32(np, "tAR-min", &timings->tAR_min);
+	of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
+	of_property_read_u32(np, "tRR-min", &timings->tRR_min);
+	of_property_read_u32(np, "tRP-min", &timings->tRP_min);
+	of_property_read_u32(np, "tWB-max", &timings->tWB_max);
+	of_property_read_u32(np, "tRC-min", &timings->tRC_min);
+	of_property_read_u32(np, "tREA-max", &timings->tREA_max);
+	of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
+	of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
+	of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
+	of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
+	of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
+	of_property_read_u32(np, "tREH-min", &timings->tREH_min);
+	of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
+	of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
+	of_property_read_u32(np, "tIR-min", &timings->tIR_min);
+	of_property_read_u32(np, "tCR-min", &timings->tCR_min);
+	of_property_read_u32(np, "tADL-min", &timings->tADL_min);
+	of_property_read_u32(np, "tRST-max", &timings->tRST_max);
+	of_property_read_u32(np, "tWW-min", &timings->tWW_min);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_nand_timings);
diff --git a/include/linux/of_mtd.h b/include/linux/of_mtd.h
index 6f10e93..ecedb5f 100644
--- a/include/linux/of_mtd.h
+++ b/include/linux/of_mtd.h
@@ -9,12 +9,15 @@
 #ifndef __LINUX_OF_MTD_H
 #define __LINUX_OF_NET_H
 
+#include <linux/mtd/nand.h>
+
 #ifdef CONFIG_OF_MTD
 
 #include <linux/of.h>
 int of_get_nand_ecc_mode(struct device_node *np);
 int of_get_nand_bus_width(struct device_node *np);
 bool of_get_nand_on_flash_bbt(struct device_node *np);
+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings);
 
 #else /* CONFIG_OF_MTD */
 
@@ -33,6 +36,12 @@ static inline bool of_get_nand_on_flash_bbt(struct device_node *np)
 	return false;
 }
 
+static inline int of_get_nand_timings(struct device_node *np,
+				      struct nand_timings *timings)
+{
+	return -ENOSYS;
+}
+
 #endif /* CONFIG_OF_MTD */
 
 #endif /* __LINUX_OF_MTD_H */
-- 
1.7.9.5


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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 14:21   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

Add a function to retrieve NAND timings from a given DT node.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_mtd.h |    9 +++++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
index a27ec94..52e07fd 100644
--- a/drivers/of/of_mtd.c
+++ b/drivers/of/of_mtd.c
@@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
 	return of_property_read_bool(np, "nand-on-flash-bbt");
 }
 EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
+
+/**
+ * of_get_nand_timings - Get nand timings for the given device_node
+ * @np:	Pointer to the given device_node
+ *
+ * return 0 on success errno other wise
+ */
+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
+{
+	memset(timings, 0, sizeof(*timings));
+
+	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
+	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
+	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
+	of_property_read_u32(np, "tCH-min", &timings->tCH_min);
+	of_property_read_u32(np, "tWP-min", &timings->tWP_min);
+	of_property_read_u32(np, "tALS-min", &timings->tALS_min);
+	of_property_read_u32(np, "tALH-min", &timings->tALH_min);
+	of_property_read_u32(np, "tDS-min", &timings->tDS_min);
+	of_property_read_u32(np, "tDH-min", &timings->tDH_min);
+	of_property_read_u32(np, "tWC-min", &timings->tWC_min);
+	of_property_read_u32(np, "tWH-min", &timings->tWH_min);
+	of_property_read_u32(np, "tR-max", &timings->tR_max);
+	of_property_read_u32(np, "tAR-min", &timings->tAR_min);
+	of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
+	of_property_read_u32(np, "tRR-min", &timings->tRR_min);
+	of_property_read_u32(np, "tRP-min", &timings->tRP_min);
+	of_property_read_u32(np, "tWB-max", &timings->tWB_max);
+	of_property_read_u32(np, "tRC-min", &timings->tRC_min);
+	of_property_read_u32(np, "tREA-max", &timings->tREA_max);
+	of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
+	of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
+	of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
+	of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
+	of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
+	of_property_read_u32(np, "tREH-min", &timings->tREH_min);
+	of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
+	of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
+	of_property_read_u32(np, "tIR-min", &timings->tIR_min);
+	of_property_read_u32(np, "tCR-min", &timings->tCR_min);
+	of_property_read_u32(np, "tADL-min", &timings->tADL_min);
+	of_property_read_u32(np, "tRST-max", &timings->tRST_max);
+	of_property_read_u32(np, "tWW-min", &timings->tWW_min);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_nand_timings);
diff --git a/include/linux/of_mtd.h b/include/linux/of_mtd.h
index 6f10e93..ecedb5f 100644
--- a/include/linux/of_mtd.h
+++ b/include/linux/of_mtd.h
@@ -9,12 +9,15 @@
 #ifndef __LINUX_OF_MTD_H
 #define __LINUX_OF_NET_H
 
+#include <linux/mtd/nand.h>
+
 #ifdef CONFIG_OF_MTD
 
 #include <linux/of.h>
 int of_get_nand_ecc_mode(struct device_node *np);
 int of_get_nand_bus_width(struct device_node *np);
 bool of_get_nand_on_flash_bbt(struct device_node *np);
+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings);
 
 #else /* CONFIG_OF_MTD */
 
@@ -33,6 +36,12 @@ static inline bool of_get_nand_on_flash_bbt(struct device_node *np)
 	return false;
 }
 
+static inline int of_get_nand_timings(struct device_node *np,
+				      struct nand_timings *timings)
+{
+	return -ENOSYS;
+}
+
 #endif /* CONFIG_OF_MTD */
 
 #endif /* __LINUX_OF_MTD_H */
-- 
1.7.9.5

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 14:21   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

Add a function to retrieve NAND timings from a given DT node.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_mtd.h |    9 +++++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
index a27ec94..52e07fd 100644
--- a/drivers/of/of_mtd.c
+++ b/drivers/of/of_mtd.c
@@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
 	return of_property_read_bool(np, "nand-on-flash-bbt");
 }
 EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
+
+/**
+ * of_get_nand_timings - Get nand timings for the given device_node
+ * @np:	Pointer to the given device_node
+ *
+ * return 0 on success errno other wise
+ */
+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
+{
+	memset(timings, 0, sizeof(*timings));
+
+	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
+	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
+	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
+	of_property_read_u32(np, "tCH-min", &timings->tCH_min);
+	of_property_read_u32(np, "tWP-min", &timings->tWP_min);
+	of_property_read_u32(np, "tALS-min", &timings->tALS_min);
+	of_property_read_u32(np, "tALH-min", &timings->tALH_min);
+	of_property_read_u32(np, "tDS-min", &timings->tDS_min);
+	of_property_read_u32(np, "tDH-min", &timings->tDH_min);
+	of_property_read_u32(np, "tWC-min", &timings->tWC_min);
+	of_property_read_u32(np, "tWH-min", &timings->tWH_min);
+	of_property_read_u32(np, "tR-max", &timings->tR_max);
+	of_property_read_u32(np, "tAR-min", &timings->tAR_min);
+	of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
+	of_property_read_u32(np, "tRR-min", &timings->tRR_min);
+	of_property_read_u32(np, "tRP-min", &timings->tRP_min);
+	of_property_read_u32(np, "tWB-max", &timings->tWB_max);
+	of_property_read_u32(np, "tRC-min", &timings->tRC_min);
+	of_property_read_u32(np, "tREA-max", &timings->tREA_max);
+	of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
+	of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
+	of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
+	of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
+	of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
+	of_property_read_u32(np, "tREH-min", &timings->tREH_min);
+	of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
+	of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
+	of_property_read_u32(np, "tIR-min", &timings->tIR_min);
+	of_property_read_u32(np, "tCR-min", &timings->tCR_min);
+	of_property_read_u32(np, "tADL-min", &timings->tADL_min);
+	of_property_read_u32(np, "tRST-max", &timings->tRST_max);
+	of_property_read_u32(np, "tWW-min", &timings->tWW_min);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_nand_timings);
diff --git a/include/linux/of_mtd.h b/include/linux/of_mtd.h
index 6f10e93..ecedb5f 100644
--- a/include/linux/of_mtd.h
+++ b/include/linux/of_mtd.h
@@ -9,12 +9,15 @@
 #ifndef __LINUX_OF_MTD_H
 #define __LINUX_OF_NET_H
 
+#include <linux/mtd/nand.h>
+
 #ifdef CONFIG_OF_MTD
 
 #include <linux/of.h>
 int of_get_nand_ecc_mode(struct device_node *np);
 int of_get_nand_bus_width(struct device_node *np);
 bool of_get_nand_on_flash_bbt(struct device_node *np);
+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings);
 
 #else /* CONFIG_OF_MTD */
 
@@ -33,6 +36,12 @@ static inline bool of_get_nand_on_flash_bbt(struct device_node *np)
 	return false;
 }
 
+static inline int of_get_nand_timings(struct device_node *np,
+				      struct nand_timings *timings)
+{
+	return -ENOSYS;
+}
+
 #endif /* CONFIG_OF_MTD */
 
 #endif /* __LINUX_OF_MTD_H */
-- 
1.7.9.5

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

* [RFC PATCH 4/9] of: mtd: add NAND timings bindings documentation
  2014-01-08 14:21 ` Boris BREZILLON
  (?)
@ 2014-01-08 14:21   ` Boris BREZILLON
  -1 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

Add a NAND timing properties to NAND dt doc.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 Documentation/devicetree/bindings/mtd/nand.txt |   34 ++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/nand.txt b/Documentation/devicetree/bindings/mtd/nand.txt
index 03855c8..0dff600 100644
--- a/Documentation/devicetree/bindings/mtd/nand.txt
+++ b/Documentation/devicetree/bindings/mtd/nand.txt
@@ -5,3 +5,37 @@
   "soft_bch".
 - nand-bus-width : 8 or 16 bus width if not present 8
 - nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
+
+nand timings definition expressed in nanoseconds (found in NAND datasheets):
+ - tCLS-min : CLE setup time
+ - tCLH-min : CLE Hold time
+ - tCS-min : CE# setup time
+ - tCH-min : CE# hold time
+ - tWP-min : WE# pulse width
+ - tALS-min : ALE setup time
+ - tALH-min : ALE hold time
+ - tDS-min : Data setup time
+ - tDH-min : Data hold time
+ - tWC-min : Write cycle time
+ - tWH-min : WE# high hold time
+ - tR-max : Data transfer from cell to register
+ - tAR-min : ALE to RE# delay
+ - tCLR-min : CLE to RE# delay
+ - tRR-min : Ready to RE# low
+ - tRP-min : RE# pulse width
+ - tWB-max : WE# high to busy
+ - tRC-min : Read cycle time
+ - tREA-max : RE# access time
+ - tRHZ-max : RE# high to output high Z
+ - tCHZ-max : CE# high to output high Z
+ - tRHOH-min : RE# high to output hold
+ - tRLOH-min : RE# low to output hold
+ - tCOH-min : RE# or CE# high to output hold
+ - tREH-min : RE# high hold time
+ - tWHR-min : WE# high to RE# low
+ - tRHW-min : RE# high to WE# low
+ - tIR-min : Output high Z to RE# low
+ - tCR-min : CE# low to RE# low
+ - tADL-min : Address to data loading time
+ - tRST-max : Device resetting time
+ - tWW-min : Write protection time
-- 
1.7.9.5


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

* [RFC PATCH 4/9] of: mtd: add NAND timings bindings documentation
@ 2014-01-08 14:21   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

Add a NAND timing properties to NAND dt doc.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 Documentation/devicetree/bindings/mtd/nand.txt |   34 ++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/nand.txt b/Documentation/devicetree/bindings/mtd/nand.txt
index 03855c8..0dff600 100644
--- a/Documentation/devicetree/bindings/mtd/nand.txt
+++ b/Documentation/devicetree/bindings/mtd/nand.txt
@@ -5,3 +5,37 @@
   "soft_bch".
 - nand-bus-width : 8 or 16 bus width if not present 8
 - nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
+
+nand timings definition expressed in nanoseconds (found in NAND datasheets):
+ - tCLS-min : CLE setup time
+ - tCLH-min : CLE Hold time
+ - tCS-min : CE# setup time
+ - tCH-min : CE# hold time
+ - tWP-min : WE# pulse width
+ - tALS-min : ALE setup time
+ - tALH-min : ALE hold time
+ - tDS-min : Data setup time
+ - tDH-min : Data hold time
+ - tWC-min : Write cycle time
+ - tWH-min : WE# high hold time
+ - tR-max : Data transfer from cell to register
+ - tAR-min : ALE to RE# delay
+ - tCLR-min : CLE to RE# delay
+ - tRR-min : Ready to RE# low
+ - tRP-min : RE# pulse width
+ - tWB-max : WE# high to busy
+ - tRC-min : Read cycle time
+ - tREA-max : RE# access time
+ - tRHZ-max : RE# high to output high Z
+ - tCHZ-max : CE# high to output high Z
+ - tRHOH-min : RE# high to output hold
+ - tRLOH-min : RE# low to output hold
+ - tCOH-min : RE# or CE# high to output hold
+ - tREH-min : RE# high hold time
+ - tWHR-min : WE# high to RE# low
+ - tRHW-min : RE# high to WE# low
+ - tIR-min : Output high Z to RE# low
+ - tCR-min : CE# low to RE# low
+ - tADL-min : Address to data loading time
+ - tRST-max : Device resetting time
+ - tWW-min : Write protection time
-- 
1.7.9.5

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

* [RFC PATCH 4/9] of: mtd: add NAND timings bindings documentation
@ 2014-01-08 14:21   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

Add a NAND timing properties to NAND dt doc.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 Documentation/devicetree/bindings/mtd/nand.txt |   34 ++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/nand.txt b/Documentation/devicetree/bindings/mtd/nand.txt
index 03855c8..0dff600 100644
--- a/Documentation/devicetree/bindings/mtd/nand.txt
+++ b/Documentation/devicetree/bindings/mtd/nand.txt
@@ -5,3 +5,37 @@
   "soft_bch".
 - nand-bus-width : 8 or 16 bus width if not present 8
 - nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
+
+nand timings definition expressed in nanoseconds (found in NAND datasheets):
+ - tCLS-min : CLE setup time
+ - tCLH-min : CLE Hold time
+ - tCS-min : CE# setup time
+ - tCH-min : CE# hold time
+ - tWP-min : WE# pulse width
+ - tALS-min : ALE setup time
+ - tALH-min : ALE hold time
+ - tDS-min : Data setup time
+ - tDH-min : Data hold time
+ - tWC-min : Write cycle time
+ - tWH-min : WE# high hold time
+ - tR-max : Data transfer from cell to register
+ - tAR-min : ALE to RE# delay
+ - tCLR-min : CLE to RE# delay
+ - tRR-min : Ready to RE# low
+ - tRP-min : RE# pulse width
+ - tWB-max : WE# high to busy
+ - tRC-min : Read cycle time
+ - tREA-max : RE# access time
+ - tRHZ-max : RE# high to output high Z
+ - tCHZ-max : CE# high to output high Z
+ - tRHOH-min : RE# high to output hold
+ - tRLOH-min : RE# low to output hold
+ - tCOH-min : RE# or CE# high to output hold
+ - tREH-min : RE# high hold time
+ - tWHR-min : WE# high to RE# low
+ - tRHW-min : RE# high to WE# low
+ - tIR-min : Output high Z to RE# low
+ - tCR-min : CE# low to RE# low
+ - tADL-min : Address to data loading time
+ - tRST-max : Device resetting time
+ - tWW-min : Write protection time
-- 
1.7.9.5

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

* [RFC PATCH 5/9] mtd: nand: add sunxi NFC support
  2014-01-08 14:21 ` Boris BREZILLON
  (?)
@ 2014-01-08 14:22   ` Boris BREZILLON
  -1 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

Add the sunxi NAND Flash Controller driver.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/mtd/nand/Kconfig     |    6 +
 drivers/mtd/nand/Makefile    |    1 +
 drivers/mtd/nand/sunxi_nfc.c |  700 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 707 insertions(+)
 create mode 100644 drivers/mtd/nand/sunxi_nfc.c

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 93ae6a6..784dd42 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -510,4 +510,10 @@ config MTD_NAND_XWAY
 	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
 	  to the External Bus Unit (EBU).
 
+config MTD_NAND_SUNXI
+	tristate "Support for NAND on Allwinner SoCs"
+	depends on ARCH_SUNXI
+	help
+	  Enables support for NAND Flash chips on Allwinner SoCs.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 542b568..e8b210d 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
 obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
 obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
+obj-$(CONFIG_MTD_NAND_SUNXI)	+= sunxi_nfc.o
 
 nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/sunxi_nfc.c b/drivers/mtd/nand/sunxi_nfc.c
new file mode 100644
index 0000000..1c7a511
--- /dev/null
+++ b/drivers/mtd/nand/sunxi_nfc.c
@@ -0,0 +1,700 @@
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Derived from Qiang Yu work:
+ *	https://github.com/yuq/sunxi-nfc-mtd
+ *	Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_mtd.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#define NFC_REG_CTL		0x0000
+#define NFC_REG_ST		0x0004
+#define NFC_REG_INT		0x0008
+#define NFC_REG_TIMING_CTL	0x000C
+#define NFC_REG_TIMING_CFG	0x0010
+#define NFC_REG_ADDR_LOW	0x0014
+#define NFC_REG_ADDR_HIGH	0x0018
+#define NFC_REG_SECTOR_NUM	0x001C
+#define NFC_REG_CNT		0x0020
+#define NFC_REG_CMD		0x0024
+#define NFC_REG_RCMD_SET	0x0028
+#define NFC_REG_WCMD_SET	0x002C
+#define NFC_REG_IO_DATA		0x0030
+#define NFC_REG_ECC_CTL		0x0034
+#define NFC_REG_ECC_ST		0x0038
+#define NFC_REG_DEBUG		0x003C
+#define NFC_REG_ECC_CNT0	0x0040
+#define NFC_REG_ECC_CNT1	0x0044
+#define NFC_REG_ECC_CNT2	0x0048
+#define NFC_REG_ECC_CNT3	0x004c
+#define NFC_REG_USER_DATA_BASE	0x0050
+#define NFC_REG_SPARE_AREA	0x00A0
+#define NFC_RAM0_BASE		0x0400
+#define NFC_RAM1_BASE		0x0800
+
+/*define bit use in NFC_CTL*/
+#define NFC_EN				(1 << 0)
+#define NFC_RESET			(1 << 1)
+#define NFC_BUS_WIDYH			(1 << 2)
+#define NFC_RB_SEL			(1 << 3)
+#define NFC_CE_SEL			(7 << 24)
+#define NFC_CE_CTL			(1 << 6)
+#define NFC_CE_CTL1			(1 << 7)
+#define NFC_PAGE_SIZE			(0xf << 8)
+#define NFC_SAM				(1 << 12)
+#define NFC_RAM_METHOD			(1 << 14)
+#define NFC_DEBUG_CTL			(1 << 31)
+
+/*define bit use in NFC_ST*/
+#define NFC_RB_B2R			(1 << 0)
+#define NFC_CMD_INT_FLAG		(1 << 1)
+#define NFC_DMA_INT_FLAG		(1 << 2)
+#define NFC_CMD_FIFO_STATUS		(1 << 3)
+#define NFC_STA				(1 << 4)
+#define NFC_NATCH_INT_FLAG		(1 << 5)
+#define NFC_RB_STATE0			(1 << 8)
+#define NFC_RB_STATE1			(1 << 9)
+#define NFC_RB_STATE2			(1 << 10)
+#define NFC_RB_STATE3			(1 << 11)
+
+/*define bit use in NFC_INT*/
+#define NFC_B2R_INT_ENABLE		(1 << 0)
+#define NFC_CMD_INT_ENABLE		(1 << 1)
+#define NFC_DMA_INT_ENABLE		(1 << 2)
+#define NFC_INT_MASK			(NFC_B2R_INT_ENABLE | \
+					 NFC_CMD_INT_ENABLE | \
+					 NFC_DMA_INT_ENABLE)
+
+
+/*define bit use in NFC_CMD*/
+#define NFC_CMD_LOW_BYTE		(0xff << 0)
+#define NFC_CMD_HIGH_BYTE		(0xff << 8)
+#define NFC_ADR_NUM			(0x7 << 16)
+#define NFC_SEND_ADR			(1 << 19)
+#define NFC_ACCESS_DIR			(1 << 20)
+#define NFC_DATA_TRANS			(1 << 21)
+#define NFC_SEND_CMD1			(1 << 22)
+#define NFC_WAIT_FLAG			(1 << 23)
+#define NFC_SEND_CMD2			(1 << 24)
+#define NFC_SEQ				(1 << 25)
+#define NFC_DATA_SWAP_METHOD		(1 << 26)
+#define NFC_ROW_AUTO_INC		(1 << 27)
+#define NFC_SEND_CMD3			(1 << 28)
+#define NFC_SEND_CMD4			(1 << 29)
+#define NFC_CMD_TYPE			(3 << 30)
+
+/* define bit use in NFC_RCMD_SET*/
+#define NFC_READ_CMD			(0xff << 0)
+#define NFC_RANDOM_READ_CMD0		(0xff << 8)
+#define NFC_RANDOM_READ_CMD1		(0xff << 16)
+
+/*define bit use in NFC_WCMD_SET*/
+#define NFC_PROGRAM_CMD			(0xff << 0)
+#define NFC_RANDOM_WRITE_CMD		(0xff << 8)
+#define NFC_READ_CMD0			(0xff << 16)
+#define NFC_READ_CMD1			(0xff << 24)
+
+/*define bit use in NFC_ECC_CTL*/
+#define NFC_ECC_EN			(1 << 0)
+#define NFC_ECC_PIPELINE		(1 << 3)
+#define NFC_ECC_EXCEPTION		(1 << 4)
+#define NFC_ECC_BLOCK_SIZE		(1 << 5)
+#define NFC_RANDOM_EN			(1 << 9)
+#define NFC_RANDOM_DIRECTION		(1 << 10)
+#define NFC_ECC_MODE_SHIFT		12
+#define NFC_ECC_MODE			(0xf << NFC_ECC_MODE_SHIFT)
+#define NFC_RANDOM_SEED			(0x7fff << 16)
+
+
+
+enum sunxi_nand_rb_type {
+	RB_NONE,
+	RB_NATIVE,
+	RB_GPIO,
+};
+
+struct sunxi_nand_rb {
+	enum sunxi_nand_rb_type type;
+	union {
+		int gpio;
+		int nativeid;
+	} info;
+};
+
+struct sunxi_nand_chip_sel {
+	u8 cs;
+	struct sunxi_nand_rb rb;
+};
+
+#define DEFAULT_NAME_FORMAT	"nand@%d"
+#define MAX_NAME_SIZE		(sizeof("nand@") + 2)
+
+struct sunxi_nand_chip {
+	struct list_head node;
+	struct nand_chip nand;
+	struct mtd_info mtd;
+	char default_name[MAX_NAME_SIZE];
+	unsigned long clk_rate;
+	int selected;
+	int nsels;
+	struct sunxi_nand_chip_sel sels[0];
+};
+
+static inline struct sunxi_nand_chip *to_sunxi_nand(struct mtd_info *mtd)
+{
+	return container_of(mtd, struct sunxi_nand_chip, mtd);
+}
+
+struct sunxi_nfc {
+	struct nand_hw_control controller;
+	void __iomem *regs;
+	int irq;
+	struct clk *ahb_clk;
+	struct clk *sclk;
+	unsigned long assigned_cs;
+	struct list_head chips;
+	struct completion complete;
+};
+
+static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
+{
+	return container_of(ctrl, struct sunxi_nfc, controller);
+}
+
+static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
+{
+	struct sunxi_nfc *nfc = dev_id;
+	u32 st = readl(nfc->regs + NFC_REG_ST);
+	u32 ien = readl(nfc->regs + NFC_REG_INT);
+
+	if (!(ien & st))
+		return IRQ_NONE;
+
+	if ((ien & st) == ien)
+		complete(&nfc->complete);
+
+	writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
+	writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
+
+	return IRQ_HANDLED;
+}
+
+static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
+			      unsigned int timeout_ms)
+{
+	init_completion(&nfc->complete);
+
+	writel(flags, nfc->regs + NFC_REG_INT);
+	if (!timeout_ms)
+		wait_for_completion(&nfc->complete);
+	else if (!wait_for_completion_timeout(&nfc->complete,
+					      msecs_to_jiffies(timeout_ms)))
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	struct sunxi_nand_rb *rb;
+	unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
+	int ret;
+
+	if (sunxi_nand->selected < 0)
+		return 0;
+
+	rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
+
+	switch (rb->type) {
+	case RB_NATIVE:
+		ret = !!(readl(nfc->regs + NFC_REG_ST) &
+			 (NFC_RB_STATE0 << rb->info.nativeid));
+		if (ret)
+			break;
+
+		sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
+		ret = !!(readl(nfc->regs + NFC_REG_ST) &
+			 (NFC_RB_STATE0 << rb->info.nativeid));
+		break;
+	case RB_GPIO:
+		ret = gpio_get_value(rb->info.gpio);
+		break;
+	case RB_NONE:
+	default:
+		ret = 0;
+		dev_err(&mtd->dev, "cannot check R/B NAND status!");
+		break;
+	}
+
+	return ret;
+}
+
+static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	struct sunxi_nand_chip_sel *sel;
+	u32 ctl;
+
+	if (chip > 0 && chip >= sunxi_nand->nsels)
+		return;
+
+	if (chip == sunxi_nand->selected)
+		return;
+
+	ctl = readl(nfc->regs + NFC_REG_CTL) &
+	      ~(NFC_CE_SEL | NFC_RB_SEL | NFC_EN);
+
+	if (chip >= 0) {
+		sel = &sunxi_nand->sels[chip];
+
+		ctl |= (sel->cs << 24) | NFC_EN |
+		       (((sunxi_nand->nand.page_shift - 10) & 0xf) << 8);
+		if (sel->rb.type == RB_NONE) {
+			sunxi_nand->nand.dev_ready = NULL;
+		} else {
+			sunxi_nand->nand.dev_ready = sunxi_nfc_dev_ready;
+			if (sel->rb.type == RB_NATIVE)
+				ctl |= (sel->rb.info.nativeid << 3);
+		}
+	}
+
+	writel(ctl, nfc->regs + NFC_REG_CTL);
+	clk_set_rate(nfc->sclk, sunxi_nand->clk_rate);
+
+	sunxi_nand->selected = chip;
+}
+
+static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	int cnt;
+	int offs = 0;
+
+	while (len > 0) {
+		cnt = len > 1024 ? 1024 : len;
+		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+			;
+		writel(cnt, nfc->regs + NFC_REG_CNT);
+		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_SEQ,
+		       nfc->regs + NFC_REG_CMD);
+		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+		memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, cnt);
+		offs += cnt;
+		len -= cnt;
+	}
+}
+
+static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+				int len)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	int cnt;
+	int offs = 0;
+
+	while (len > 0) {
+		cnt = len > 1024 ? 1024 : len;
+		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+			;
+		writel(cnt, nfc->regs + NFC_REG_CNT);
+		memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
+		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
+		       NFC_ACCESS_DIR | NFC_SEQ, nfc->regs + NFC_REG_CMD);
+		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+		offs += cnt;
+		len -= cnt;
+	}
+}
+
+static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
+{
+	uint8_t ret;
+
+	sunxi_nfc_read_buf(mtd, &ret, 1);
+
+	return ret;
+}
+
+static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
+			       unsigned int ctrl)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	u32 tmp;
+
+	while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+		;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		tmp = readl(nfc->regs + NFC_REG_CTL);
+		if (ctrl & NAND_NCE)
+			tmp |= NFC_CE_CTL;
+		else
+			tmp &= ~NFC_CE_CTL;
+		writel(tmp, nfc->regs + NFC_REG_CTL);
+	}
+
+	if (dat == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE) {
+		writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
+	} else {
+		writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
+		writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
+	}
+
+	sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+}
+
+static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
+					struct device_node *np)
+{
+	struct nand_timings timings;
+	u32 min_clk_period = 0;
+	int ret;
+
+	ret = of_get_nand_timings(np, &timings);
+	if (ret)
+		return ret;
+
+	/* NFC timings defined in Allwinner Datasheets */
+
+	/* T1 <=> tCLS */
+	if (timings.tCLS_min > min_clk_period)
+		min_clk_period = timings.tCLS_min;
+
+	/* T2 <=> tCLH */
+	if (timings.tCLH_min > min_clk_period)
+		min_clk_period = timings.tCLH_min;
+
+	/* T3 <=> tCS */
+	if (timings.tCS_min > min_clk_period)
+		min_clk_period = timings.tCS_min;
+
+	/* T4 <=> tCH */
+	if (timings.tCH_min > min_clk_period)
+		min_clk_period = timings.tCH_min;
+
+	/* T5 <=> tWP */
+	if (timings.tWP_min > min_clk_period)
+		min_clk_period = timings.tWP_min;
+
+	/* T6 <=> tWH */
+	if (timings.tWH_min > min_clk_period)
+		min_clk_period = timings.tWH_min;
+
+	/* T7 <=> tALS */
+	if (timings.tALS_min > min_clk_period)
+		min_clk_period = timings.tALS_min;
+
+	/* T8 <=> tDS */
+	if (timings.tDS_min > min_clk_period)
+		min_clk_period = timings.tDS_min;
+
+	/* T9 <=> tDH */
+	if (timings.tDH_min > min_clk_period)
+		min_clk_period = timings.tDH_min;
+
+	/* T10 <=> tRR */
+	if (timings.tRR_min > (min_clk_period * 3))
+		min_clk_period = (timings.tRR_min + 2) / 3;
+
+	/* T11 <=> tALH */
+	if (timings.tALH_min > min_clk_period)
+		min_clk_period = timings.tALH_min;
+
+	/* T12 <=> tRP */
+	if (timings.tRP_min > min_clk_period)
+		min_clk_period = timings.tRP_min;
+
+	/* T13 <=> tREH */
+	if (timings.tREH_min > min_clk_period)
+		min_clk_period = timings.tREH_min;
+
+	/* T14 <=> tRC */
+	if (timings.tRC_min > (min_clk_period * 2))
+		min_clk_period = (timings.tRC_min + 1) / 2;
+
+	/* T15 <=> tWC */
+	if (timings.tWC_min > (min_clk_period * 2))
+		min_clk_period = (timings.tWC_min + 1) / 2;
+
+
+	/* min_clk_period = (NAND-clk-period * 2) */
+	if (!min_clk_period)
+		chip->clk_rate = 20000000;
+	else
+		chip->clk_rate = (2 * 1000000000) / min_clk_period;
+
+	/* TODO: configure T16-T19 */
+
+	return 0;
+}
+
+static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
+				struct device_node *np)
+{
+	struct sunxi_nand_chip *chip;
+	struct mtd_part_parser_data ppdata;
+	struct mtd_info *mtd;
+	struct nand_chip *nand;
+	int nsels;
+	int ret;
+	int i;
+	u32 tmp;
+
+	if (!of_get_property(np, "reg", &nsels))
+		return -EINVAL;
+
+	nsels /= sizeof(u32);
+	if (!nsels)
+		return -EINVAL;
+
+	chip = devm_kzalloc(dev,
+			    sizeof(*chip) +
+			    (nsels * sizeof(struct sunxi_nand_chip_sel)),
+			    GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->nsels = nsels;
+	chip->selected = -1;
+
+	for (i = 0; i < nsels; i++) {
+		ret = of_property_read_u32_index(np, "reg", i, &tmp);
+		if (ret)
+			return ret;
+
+		if (tmp > 7)
+			return -EINVAL;
+
+		if (test_and_set_bit(tmp, &nfc->assigned_cs))
+			return -EINVAL;
+
+		chip->sels[i].cs = tmp;
+
+		if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
+		    tmp < 2) {
+			chip->sels[i].rb.type = RB_NATIVE;
+			chip->sels[i].rb.info.nativeid = tmp;
+		} else {
+			ret = of_get_named_gpio(np, "rb-gpios", i);
+			if (ret >= 0) {
+				chip->sels[i].rb.type = RB_GPIO;
+				chip->sels[i].rb.info.gpio = tmp;
+				ret = devm_gpio_request(dev, tmp, "nand-rb");
+				if (ret)
+					return ret;
+			} else {
+				chip->sels[i].rb.type = RB_NONE;
+			}
+		}
+	}
+
+	ret = sunxi_nand_chip_init_timings(chip, np);
+	if (ret)
+		return ret;
+
+	nand = &chip->nand;
+	nand->IO_ADDR_R = nand->IO_ADDR_W = nfc->regs + NFC_REG_IO_DATA;
+	nand->controller = &nfc->controller;
+	nand->select_chip = sunxi_nfc_select_chip;
+	nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
+	nand->read_buf = sunxi_nfc_read_buf;
+	nand->write_buf = sunxi_nfc_write_buf;
+	nand->read_byte = sunxi_nfc_read_byte;
+
+	nand->ecc.mode = of_get_nand_ecc_mode(np);
+	if (of_get_nand_on_flash_bbt(np))
+		nand->bbt_options |= NAND_BBT_USE_FLASH;
+
+	mtd = &chip->mtd;
+	mtd->priv = nand;
+	mtd->owner = THIS_MODULE;
+
+	ret = nand_scan_ident(mtd, nsels, NULL);
+	if (ret)
+		return ret;
+
+	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
+		nand->ecc.size = nand->ecc_step_ds;
+		nand->ecc.bytes = (((nand->ecc_strength_ds *
+				     fls(8 * nand->ecc_step_ds)) + 7) / 8);
+	}
+
+	ret = nand_scan_tail(mtd);
+	if (ret)
+		return ret;
+
+	if (of_property_read_string(np, "nand-name", &mtd->name)) {
+		snprintf(chip->default_name, MAX_NAME_SIZE,
+			 DEFAULT_NAME_FORMAT, chip->sels[i].cs);
+		mtd->name = chip->default_name;
+	}
+
+	ppdata.of_node = np;
+	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+	if (!ret)
+		return ret;
+
+	list_add_tail(&chip->node, &nfc->chips);
+
+	return 0;
+}
+
+static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
+{
+	struct device_node *np = dev->of_node;
+	struct device_node *nand_np;
+	int nchips = of_get_child_count(np);
+	int ret;
+
+	if (nchips > 8)
+		return -EINVAL;
+
+	for_each_child_of_node(np, nand_np) {
+		ret = sunxi_nand_chip_init(dev, nfc, nand_np);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int sunxi_nfc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *r;
+	struct sunxi_nfc *nfc;
+	int ret;
+
+	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
+	if (!nfc) {
+		dev_err(dev, "failed to allocate NFC struct\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_init(&nfc->controller.lock);
+	init_waitqueue_head(&nfc->controller.wq);
+	INIT_LIST_HEAD(&nfc->chips);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	nfc->regs = devm_ioremap_resource(dev, r);
+	if (IS_ERR(nfc->regs)) {
+		dev_err(dev, "failed to remap iomem\n");
+		return PTR_ERR(nfc->regs);
+	}
+
+	nfc->irq = platform_get_irq(pdev, 0);
+	if (nfc->irq < 0) {
+		dev_err(dev, "failed to retrieve irq\n");
+		return nfc->irq;
+	}
+
+	nfc->ahb_clk = devm_clk_get(dev, "ahb_clk");
+	if (IS_ERR(nfc->ahb_clk)) {
+		dev_err(dev, "failed to retrieve ahb_clk\n");
+		return PTR_ERR(nfc->ahb_clk);
+	}
+
+	ret = clk_prepare_enable(nfc->ahb_clk);
+	if (ret)
+		return ret;
+
+	nfc->sclk = devm_clk_get(dev, "sclk");
+	if (IS_ERR(nfc->sclk)) {
+		dev_err(dev, "failed to retrieve nand_clk\n");
+		ret = PTR_ERR(nfc->sclk);
+		goto out_ahb_clk_unprepare;
+	}
+
+	ret = clk_prepare_enable(nfc->sclk);
+	if (ret)
+		goto out_ahb_clk_unprepare;
+
+	/* Reset NFC */
+	writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RESET,
+	       nfc->regs + NFC_REG_CTL);
+	while (readl(nfc->regs + NFC_REG_CTL) & NFC_RESET)
+		;
+
+	writel(0, nfc->regs + NFC_REG_INT);
+	ret = devm_request_irq(dev, nfc->irq, sunxi_nfc_interrupt,
+			       0, "sunxi-nfc", nfc);
+	if (ret)
+		goto out_sclk_unprepare;
+
+	platform_set_drvdata(pdev, nfc);
+
+	writel(0x100, nfc->regs + NFC_REG_TIMING_CTL);
+	writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG);
+
+	ret = sunxi_nand_chips_init(dev, nfc);
+	if (ret) {
+		dev_err(dev, "failed to init nand chips\n");
+		goto out_sclk_unprepare;
+	}
+
+	return 0;
+
+out_sclk_unprepare:
+	clk_disable_unprepare(nfc->sclk);
+out_ahb_clk_unprepare:
+	clk_disable_unprepare(nfc->ahb_clk);
+
+	return ret;
+}
+
+static const struct of_device_id sunxi_nfc_ids[] = {
+	{ .compatible = "allwinner,sun4i-nfc" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
+
+static struct platform_driver sunxi_nfc_driver = {
+	.driver = {
+		.name = "sunxi_nfc",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(sunxi_nfc_ids),
+	},
+	.probe = sunxi_nfc_probe,
+};
+module_platform_driver(sunxi_nfc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Boris BREZILLON");
+MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
+MODULE_ALIAS("platform:sunxi_nfc");
-- 
1.7.9.5


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

* [RFC PATCH 5/9] mtd: nand: add sunxi NFC support
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

Add the sunxi NAND Flash Controller driver.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/mtd/nand/Kconfig     |    6 +
 drivers/mtd/nand/Makefile    |    1 +
 drivers/mtd/nand/sunxi_nfc.c |  700 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 707 insertions(+)
 create mode 100644 drivers/mtd/nand/sunxi_nfc.c

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 93ae6a6..784dd42 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -510,4 +510,10 @@ config MTD_NAND_XWAY
 	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
 	  to the External Bus Unit (EBU).
 
+config MTD_NAND_SUNXI
+	tristate "Support for NAND on Allwinner SoCs"
+	depends on ARCH_SUNXI
+	help
+	  Enables support for NAND Flash chips on Allwinner SoCs.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 542b568..e8b210d 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
 obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
 obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
+obj-$(CONFIG_MTD_NAND_SUNXI)	+= sunxi_nfc.o
 
 nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/sunxi_nfc.c b/drivers/mtd/nand/sunxi_nfc.c
new file mode 100644
index 0000000..1c7a511
--- /dev/null
+++ b/drivers/mtd/nand/sunxi_nfc.c
@@ -0,0 +1,700 @@
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Derived from Qiang Yu work:
+ *	https://github.com/yuq/sunxi-nfc-mtd
+ *	Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_mtd.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#define NFC_REG_CTL		0x0000
+#define NFC_REG_ST		0x0004
+#define NFC_REG_INT		0x0008
+#define NFC_REG_TIMING_CTL	0x000C
+#define NFC_REG_TIMING_CFG	0x0010
+#define NFC_REG_ADDR_LOW	0x0014
+#define NFC_REG_ADDR_HIGH	0x0018
+#define NFC_REG_SECTOR_NUM	0x001C
+#define NFC_REG_CNT		0x0020
+#define NFC_REG_CMD		0x0024
+#define NFC_REG_RCMD_SET	0x0028
+#define NFC_REG_WCMD_SET	0x002C
+#define NFC_REG_IO_DATA		0x0030
+#define NFC_REG_ECC_CTL		0x0034
+#define NFC_REG_ECC_ST		0x0038
+#define NFC_REG_DEBUG		0x003C
+#define NFC_REG_ECC_CNT0	0x0040
+#define NFC_REG_ECC_CNT1	0x0044
+#define NFC_REG_ECC_CNT2	0x0048
+#define NFC_REG_ECC_CNT3	0x004c
+#define NFC_REG_USER_DATA_BASE	0x0050
+#define NFC_REG_SPARE_AREA	0x00A0
+#define NFC_RAM0_BASE		0x0400
+#define NFC_RAM1_BASE		0x0800
+
+/*define bit use in NFC_CTL*/
+#define NFC_EN				(1 << 0)
+#define NFC_RESET			(1 << 1)
+#define NFC_BUS_WIDYH			(1 << 2)
+#define NFC_RB_SEL			(1 << 3)
+#define NFC_CE_SEL			(7 << 24)
+#define NFC_CE_CTL			(1 << 6)
+#define NFC_CE_CTL1			(1 << 7)
+#define NFC_PAGE_SIZE			(0xf << 8)
+#define NFC_SAM				(1 << 12)
+#define NFC_RAM_METHOD			(1 << 14)
+#define NFC_DEBUG_CTL			(1 << 31)
+
+/*define bit use in NFC_ST*/
+#define NFC_RB_B2R			(1 << 0)
+#define NFC_CMD_INT_FLAG		(1 << 1)
+#define NFC_DMA_INT_FLAG		(1 << 2)
+#define NFC_CMD_FIFO_STATUS		(1 << 3)
+#define NFC_STA				(1 << 4)
+#define NFC_NATCH_INT_FLAG		(1 << 5)
+#define NFC_RB_STATE0			(1 << 8)
+#define NFC_RB_STATE1			(1 << 9)
+#define NFC_RB_STATE2			(1 << 10)
+#define NFC_RB_STATE3			(1 << 11)
+
+/*define bit use in NFC_INT*/
+#define NFC_B2R_INT_ENABLE		(1 << 0)
+#define NFC_CMD_INT_ENABLE		(1 << 1)
+#define NFC_DMA_INT_ENABLE		(1 << 2)
+#define NFC_INT_MASK			(NFC_B2R_INT_ENABLE | \
+					 NFC_CMD_INT_ENABLE | \
+					 NFC_DMA_INT_ENABLE)
+
+
+/*define bit use in NFC_CMD*/
+#define NFC_CMD_LOW_BYTE		(0xff << 0)
+#define NFC_CMD_HIGH_BYTE		(0xff << 8)
+#define NFC_ADR_NUM			(0x7 << 16)
+#define NFC_SEND_ADR			(1 << 19)
+#define NFC_ACCESS_DIR			(1 << 20)
+#define NFC_DATA_TRANS			(1 << 21)
+#define NFC_SEND_CMD1			(1 << 22)
+#define NFC_WAIT_FLAG			(1 << 23)
+#define NFC_SEND_CMD2			(1 << 24)
+#define NFC_SEQ				(1 << 25)
+#define NFC_DATA_SWAP_METHOD		(1 << 26)
+#define NFC_ROW_AUTO_INC		(1 << 27)
+#define NFC_SEND_CMD3			(1 << 28)
+#define NFC_SEND_CMD4			(1 << 29)
+#define NFC_CMD_TYPE			(3 << 30)
+
+/* define bit use in NFC_RCMD_SET*/
+#define NFC_READ_CMD			(0xff << 0)
+#define NFC_RANDOM_READ_CMD0		(0xff << 8)
+#define NFC_RANDOM_READ_CMD1		(0xff << 16)
+
+/*define bit use in NFC_WCMD_SET*/
+#define NFC_PROGRAM_CMD			(0xff << 0)
+#define NFC_RANDOM_WRITE_CMD		(0xff << 8)
+#define NFC_READ_CMD0			(0xff << 16)
+#define NFC_READ_CMD1			(0xff << 24)
+
+/*define bit use in NFC_ECC_CTL*/
+#define NFC_ECC_EN			(1 << 0)
+#define NFC_ECC_PIPELINE		(1 << 3)
+#define NFC_ECC_EXCEPTION		(1 << 4)
+#define NFC_ECC_BLOCK_SIZE		(1 << 5)
+#define NFC_RANDOM_EN			(1 << 9)
+#define NFC_RANDOM_DIRECTION		(1 << 10)
+#define NFC_ECC_MODE_SHIFT		12
+#define NFC_ECC_MODE			(0xf << NFC_ECC_MODE_SHIFT)
+#define NFC_RANDOM_SEED			(0x7fff << 16)
+
+
+
+enum sunxi_nand_rb_type {
+	RB_NONE,
+	RB_NATIVE,
+	RB_GPIO,
+};
+
+struct sunxi_nand_rb {
+	enum sunxi_nand_rb_type type;
+	union {
+		int gpio;
+		int nativeid;
+	} info;
+};
+
+struct sunxi_nand_chip_sel {
+	u8 cs;
+	struct sunxi_nand_rb rb;
+};
+
+#define DEFAULT_NAME_FORMAT	"nand@%d"
+#define MAX_NAME_SIZE		(sizeof("nand@") + 2)
+
+struct sunxi_nand_chip {
+	struct list_head node;
+	struct nand_chip nand;
+	struct mtd_info mtd;
+	char default_name[MAX_NAME_SIZE];
+	unsigned long clk_rate;
+	int selected;
+	int nsels;
+	struct sunxi_nand_chip_sel sels[0];
+};
+
+static inline struct sunxi_nand_chip *to_sunxi_nand(struct mtd_info *mtd)
+{
+	return container_of(mtd, struct sunxi_nand_chip, mtd);
+}
+
+struct sunxi_nfc {
+	struct nand_hw_control controller;
+	void __iomem *regs;
+	int irq;
+	struct clk *ahb_clk;
+	struct clk *sclk;
+	unsigned long assigned_cs;
+	struct list_head chips;
+	struct completion complete;
+};
+
+static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
+{
+	return container_of(ctrl, struct sunxi_nfc, controller);
+}
+
+static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
+{
+	struct sunxi_nfc *nfc = dev_id;
+	u32 st = readl(nfc->regs + NFC_REG_ST);
+	u32 ien = readl(nfc->regs + NFC_REG_INT);
+
+	if (!(ien & st))
+		return IRQ_NONE;
+
+	if ((ien & st) == ien)
+		complete(&nfc->complete);
+
+	writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
+	writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
+
+	return IRQ_HANDLED;
+}
+
+static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
+			      unsigned int timeout_ms)
+{
+	init_completion(&nfc->complete);
+
+	writel(flags, nfc->regs + NFC_REG_INT);
+	if (!timeout_ms)
+		wait_for_completion(&nfc->complete);
+	else if (!wait_for_completion_timeout(&nfc->complete,
+					      msecs_to_jiffies(timeout_ms)))
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	struct sunxi_nand_rb *rb;
+	unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
+	int ret;
+
+	if (sunxi_nand->selected < 0)
+		return 0;
+
+	rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
+
+	switch (rb->type) {
+	case RB_NATIVE:
+		ret = !!(readl(nfc->regs + NFC_REG_ST) &
+			 (NFC_RB_STATE0 << rb->info.nativeid));
+		if (ret)
+			break;
+
+		sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
+		ret = !!(readl(nfc->regs + NFC_REG_ST) &
+			 (NFC_RB_STATE0 << rb->info.nativeid));
+		break;
+	case RB_GPIO:
+		ret = gpio_get_value(rb->info.gpio);
+		break;
+	case RB_NONE:
+	default:
+		ret = 0;
+		dev_err(&mtd->dev, "cannot check R/B NAND status!");
+		break;
+	}
+
+	return ret;
+}
+
+static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	struct sunxi_nand_chip_sel *sel;
+	u32 ctl;
+
+	if (chip > 0 && chip >= sunxi_nand->nsels)
+		return;
+
+	if (chip == sunxi_nand->selected)
+		return;
+
+	ctl = readl(nfc->regs + NFC_REG_CTL) &
+	      ~(NFC_CE_SEL | NFC_RB_SEL | NFC_EN);
+
+	if (chip >= 0) {
+		sel = &sunxi_nand->sels[chip];
+
+		ctl |= (sel->cs << 24) | NFC_EN |
+		       (((sunxi_nand->nand.page_shift - 10) & 0xf) << 8);
+		if (sel->rb.type == RB_NONE) {
+			sunxi_nand->nand.dev_ready = NULL;
+		} else {
+			sunxi_nand->nand.dev_ready = sunxi_nfc_dev_ready;
+			if (sel->rb.type == RB_NATIVE)
+				ctl |= (sel->rb.info.nativeid << 3);
+		}
+	}
+
+	writel(ctl, nfc->regs + NFC_REG_CTL);
+	clk_set_rate(nfc->sclk, sunxi_nand->clk_rate);
+
+	sunxi_nand->selected = chip;
+}
+
+static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	int cnt;
+	int offs = 0;
+
+	while (len > 0) {
+		cnt = len > 1024 ? 1024 : len;
+		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+			;
+		writel(cnt, nfc->regs + NFC_REG_CNT);
+		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_SEQ,
+		       nfc->regs + NFC_REG_CMD);
+		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+		memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, cnt);
+		offs += cnt;
+		len -= cnt;
+	}
+}
+
+static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+				int len)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	int cnt;
+	int offs = 0;
+
+	while (len > 0) {
+		cnt = len > 1024 ? 1024 : len;
+		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+			;
+		writel(cnt, nfc->regs + NFC_REG_CNT);
+		memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
+		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
+		       NFC_ACCESS_DIR | NFC_SEQ, nfc->regs + NFC_REG_CMD);
+		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+		offs += cnt;
+		len -= cnt;
+	}
+}
+
+static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
+{
+	uint8_t ret;
+
+	sunxi_nfc_read_buf(mtd, &ret, 1);
+
+	return ret;
+}
+
+static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
+			       unsigned int ctrl)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	u32 tmp;
+
+	while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+		;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		tmp = readl(nfc->regs + NFC_REG_CTL);
+		if (ctrl & NAND_NCE)
+			tmp |= NFC_CE_CTL;
+		else
+			tmp &= ~NFC_CE_CTL;
+		writel(tmp, nfc->regs + NFC_REG_CTL);
+	}
+
+	if (dat == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE) {
+		writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
+	} else {
+		writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
+		writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
+	}
+
+	sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+}
+
+static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
+					struct device_node *np)
+{
+	struct nand_timings timings;
+	u32 min_clk_period = 0;
+	int ret;
+
+	ret = of_get_nand_timings(np, &timings);
+	if (ret)
+		return ret;
+
+	/* NFC timings defined in Allwinner Datasheets */
+
+	/* T1 <=> tCLS */
+	if (timings.tCLS_min > min_clk_period)
+		min_clk_period = timings.tCLS_min;
+
+	/* T2 <=> tCLH */
+	if (timings.tCLH_min > min_clk_period)
+		min_clk_period = timings.tCLH_min;
+
+	/* T3 <=> tCS */
+	if (timings.tCS_min > min_clk_period)
+		min_clk_period = timings.tCS_min;
+
+	/* T4 <=> tCH */
+	if (timings.tCH_min > min_clk_period)
+		min_clk_period = timings.tCH_min;
+
+	/* T5 <=> tWP */
+	if (timings.tWP_min > min_clk_period)
+		min_clk_period = timings.tWP_min;
+
+	/* T6 <=> tWH */
+	if (timings.tWH_min > min_clk_period)
+		min_clk_period = timings.tWH_min;
+
+	/* T7 <=> tALS */
+	if (timings.tALS_min > min_clk_period)
+		min_clk_period = timings.tALS_min;
+
+	/* T8 <=> tDS */
+	if (timings.tDS_min > min_clk_period)
+		min_clk_period = timings.tDS_min;
+
+	/* T9 <=> tDH */
+	if (timings.tDH_min > min_clk_period)
+		min_clk_period = timings.tDH_min;
+
+	/* T10 <=> tRR */
+	if (timings.tRR_min > (min_clk_period * 3))
+		min_clk_period = (timings.tRR_min + 2) / 3;
+
+	/* T11 <=> tALH */
+	if (timings.tALH_min > min_clk_period)
+		min_clk_period = timings.tALH_min;
+
+	/* T12 <=> tRP */
+	if (timings.tRP_min > min_clk_period)
+		min_clk_period = timings.tRP_min;
+
+	/* T13 <=> tREH */
+	if (timings.tREH_min > min_clk_period)
+		min_clk_period = timings.tREH_min;
+
+	/* T14 <=> tRC */
+	if (timings.tRC_min > (min_clk_period * 2))
+		min_clk_period = (timings.tRC_min + 1) / 2;
+
+	/* T15 <=> tWC */
+	if (timings.tWC_min > (min_clk_period * 2))
+		min_clk_period = (timings.tWC_min + 1) / 2;
+
+
+	/* min_clk_period = (NAND-clk-period * 2) */
+	if (!min_clk_period)
+		chip->clk_rate = 20000000;
+	else
+		chip->clk_rate = (2 * 1000000000) / min_clk_period;
+
+	/* TODO: configure T16-T19 */
+
+	return 0;
+}
+
+static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
+				struct device_node *np)
+{
+	struct sunxi_nand_chip *chip;
+	struct mtd_part_parser_data ppdata;
+	struct mtd_info *mtd;
+	struct nand_chip *nand;
+	int nsels;
+	int ret;
+	int i;
+	u32 tmp;
+
+	if (!of_get_property(np, "reg", &nsels))
+		return -EINVAL;
+
+	nsels /= sizeof(u32);
+	if (!nsels)
+		return -EINVAL;
+
+	chip = devm_kzalloc(dev,
+			    sizeof(*chip) +
+			    (nsels * sizeof(struct sunxi_nand_chip_sel)),
+			    GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->nsels = nsels;
+	chip->selected = -1;
+
+	for (i = 0; i < nsels; i++) {
+		ret = of_property_read_u32_index(np, "reg", i, &tmp);
+		if (ret)
+			return ret;
+
+		if (tmp > 7)
+			return -EINVAL;
+
+		if (test_and_set_bit(tmp, &nfc->assigned_cs))
+			return -EINVAL;
+
+		chip->sels[i].cs = tmp;
+
+		if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
+		    tmp < 2) {
+			chip->sels[i].rb.type = RB_NATIVE;
+			chip->sels[i].rb.info.nativeid = tmp;
+		} else {
+			ret = of_get_named_gpio(np, "rb-gpios", i);
+			if (ret >= 0) {
+				chip->sels[i].rb.type = RB_GPIO;
+				chip->sels[i].rb.info.gpio = tmp;
+				ret = devm_gpio_request(dev, tmp, "nand-rb");
+				if (ret)
+					return ret;
+			} else {
+				chip->sels[i].rb.type = RB_NONE;
+			}
+		}
+	}
+
+	ret = sunxi_nand_chip_init_timings(chip, np);
+	if (ret)
+		return ret;
+
+	nand = &chip->nand;
+	nand->IO_ADDR_R = nand->IO_ADDR_W = nfc->regs + NFC_REG_IO_DATA;
+	nand->controller = &nfc->controller;
+	nand->select_chip = sunxi_nfc_select_chip;
+	nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
+	nand->read_buf = sunxi_nfc_read_buf;
+	nand->write_buf = sunxi_nfc_write_buf;
+	nand->read_byte = sunxi_nfc_read_byte;
+
+	nand->ecc.mode = of_get_nand_ecc_mode(np);
+	if (of_get_nand_on_flash_bbt(np))
+		nand->bbt_options |= NAND_BBT_USE_FLASH;
+
+	mtd = &chip->mtd;
+	mtd->priv = nand;
+	mtd->owner = THIS_MODULE;
+
+	ret = nand_scan_ident(mtd, nsels, NULL);
+	if (ret)
+		return ret;
+
+	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
+		nand->ecc.size = nand->ecc_step_ds;
+		nand->ecc.bytes = (((nand->ecc_strength_ds *
+				     fls(8 * nand->ecc_step_ds)) + 7) / 8);
+	}
+
+	ret = nand_scan_tail(mtd);
+	if (ret)
+		return ret;
+
+	if (of_property_read_string(np, "nand-name", &mtd->name)) {
+		snprintf(chip->default_name, MAX_NAME_SIZE,
+			 DEFAULT_NAME_FORMAT, chip->sels[i].cs);
+		mtd->name = chip->default_name;
+	}
+
+	ppdata.of_node = np;
+	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+	if (!ret)
+		return ret;
+
+	list_add_tail(&chip->node, &nfc->chips);
+
+	return 0;
+}
+
+static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
+{
+	struct device_node *np = dev->of_node;
+	struct device_node *nand_np;
+	int nchips = of_get_child_count(np);
+	int ret;
+
+	if (nchips > 8)
+		return -EINVAL;
+
+	for_each_child_of_node(np, nand_np) {
+		ret = sunxi_nand_chip_init(dev, nfc, nand_np);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int sunxi_nfc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *r;
+	struct sunxi_nfc *nfc;
+	int ret;
+
+	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
+	if (!nfc) {
+		dev_err(dev, "failed to allocate NFC struct\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_init(&nfc->controller.lock);
+	init_waitqueue_head(&nfc->controller.wq);
+	INIT_LIST_HEAD(&nfc->chips);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	nfc->regs = devm_ioremap_resource(dev, r);
+	if (IS_ERR(nfc->regs)) {
+		dev_err(dev, "failed to remap iomem\n");
+		return PTR_ERR(nfc->regs);
+	}
+
+	nfc->irq = platform_get_irq(pdev, 0);
+	if (nfc->irq < 0) {
+		dev_err(dev, "failed to retrieve irq\n");
+		return nfc->irq;
+	}
+
+	nfc->ahb_clk = devm_clk_get(dev, "ahb_clk");
+	if (IS_ERR(nfc->ahb_clk)) {
+		dev_err(dev, "failed to retrieve ahb_clk\n");
+		return PTR_ERR(nfc->ahb_clk);
+	}
+
+	ret = clk_prepare_enable(nfc->ahb_clk);
+	if (ret)
+		return ret;
+
+	nfc->sclk = devm_clk_get(dev, "sclk");
+	if (IS_ERR(nfc->sclk)) {
+		dev_err(dev, "failed to retrieve nand_clk\n");
+		ret = PTR_ERR(nfc->sclk);
+		goto out_ahb_clk_unprepare;
+	}
+
+	ret = clk_prepare_enable(nfc->sclk);
+	if (ret)
+		goto out_ahb_clk_unprepare;
+
+	/* Reset NFC */
+	writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RESET,
+	       nfc->regs + NFC_REG_CTL);
+	while (readl(nfc->regs + NFC_REG_CTL) & NFC_RESET)
+		;
+
+	writel(0, nfc->regs + NFC_REG_INT);
+	ret = devm_request_irq(dev, nfc->irq, sunxi_nfc_interrupt,
+			       0, "sunxi-nfc", nfc);
+	if (ret)
+		goto out_sclk_unprepare;
+
+	platform_set_drvdata(pdev, nfc);
+
+	writel(0x100, nfc->regs + NFC_REG_TIMING_CTL);
+	writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG);
+
+	ret = sunxi_nand_chips_init(dev, nfc);
+	if (ret) {
+		dev_err(dev, "failed to init nand chips\n");
+		goto out_sclk_unprepare;
+	}
+
+	return 0;
+
+out_sclk_unprepare:
+	clk_disable_unprepare(nfc->sclk);
+out_ahb_clk_unprepare:
+	clk_disable_unprepare(nfc->ahb_clk);
+
+	return ret;
+}
+
+static const struct of_device_id sunxi_nfc_ids[] = {
+	{ .compatible = "allwinner,sun4i-nfc" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
+
+static struct platform_driver sunxi_nfc_driver = {
+	.driver = {
+		.name = "sunxi_nfc",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(sunxi_nfc_ids),
+	},
+	.probe = sunxi_nfc_probe,
+};
+module_platform_driver(sunxi_nfc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Boris BREZILLON");
+MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
+MODULE_ALIAS("platform:sunxi_nfc");
-- 
1.7.9.5

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

* [RFC PATCH 5/9] mtd: nand: add sunxi NFC support
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Add the sunxi NAND Flash Controller driver.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/mtd/nand/Kconfig     |    6 +
 drivers/mtd/nand/Makefile    |    1 +
 drivers/mtd/nand/sunxi_nfc.c |  700 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 707 insertions(+)
 create mode 100644 drivers/mtd/nand/sunxi_nfc.c

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 93ae6a6..784dd42 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -510,4 +510,10 @@ config MTD_NAND_XWAY
 	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
 	  to the External Bus Unit (EBU).
 
+config MTD_NAND_SUNXI
+	tristate "Support for NAND on Allwinner SoCs"
+	depends on ARCH_SUNXI
+	help
+	  Enables support for NAND Flash chips on Allwinner SoCs.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 542b568..e8b210d 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
 obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
 obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
+obj-$(CONFIG_MTD_NAND_SUNXI)	+= sunxi_nfc.o
 
 nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/sunxi_nfc.c b/drivers/mtd/nand/sunxi_nfc.c
new file mode 100644
index 0000000..1c7a511
--- /dev/null
+++ b/drivers/mtd/nand/sunxi_nfc.c
@@ -0,0 +1,700 @@
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
+ *
+ * Derived from Qiang Yu work:
+ *	https://github.com/yuq/sunxi-nfc-mtd
+ *	Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_mtd.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#define NFC_REG_CTL		0x0000
+#define NFC_REG_ST		0x0004
+#define NFC_REG_INT		0x0008
+#define NFC_REG_TIMING_CTL	0x000C
+#define NFC_REG_TIMING_CFG	0x0010
+#define NFC_REG_ADDR_LOW	0x0014
+#define NFC_REG_ADDR_HIGH	0x0018
+#define NFC_REG_SECTOR_NUM	0x001C
+#define NFC_REG_CNT		0x0020
+#define NFC_REG_CMD		0x0024
+#define NFC_REG_RCMD_SET	0x0028
+#define NFC_REG_WCMD_SET	0x002C
+#define NFC_REG_IO_DATA		0x0030
+#define NFC_REG_ECC_CTL		0x0034
+#define NFC_REG_ECC_ST		0x0038
+#define NFC_REG_DEBUG		0x003C
+#define NFC_REG_ECC_CNT0	0x0040
+#define NFC_REG_ECC_CNT1	0x0044
+#define NFC_REG_ECC_CNT2	0x0048
+#define NFC_REG_ECC_CNT3	0x004c
+#define NFC_REG_USER_DATA_BASE	0x0050
+#define NFC_REG_SPARE_AREA	0x00A0
+#define NFC_RAM0_BASE		0x0400
+#define NFC_RAM1_BASE		0x0800
+
+/*define bit use in NFC_CTL*/
+#define NFC_EN				(1 << 0)
+#define NFC_RESET			(1 << 1)
+#define NFC_BUS_WIDYH			(1 << 2)
+#define NFC_RB_SEL			(1 << 3)
+#define NFC_CE_SEL			(7 << 24)
+#define NFC_CE_CTL			(1 << 6)
+#define NFC_CE_CTL1			(1 << 7)
+#define NFC_PAGE_SIZE			(0xf << 8)
+#define NFC_SAM				(1 << 12)
+#define NFC_RAM_METHOD			(1 << 14)
+#define NFC_DEBUG_CTL			(1 << 31)
+
+/*define bit use in NFC_ST*/
+#define NFC_RB_B2R			(1 << 0)
+#define NFC_CMD_INT_FLAG		(1 << 1)
+#define NFC_DMA_INT_FLAG		(1 << 2)
+#define NFC_CMD_FIFO_STATUS		(1 << 3)
+#define NFC_STA				(1 << 4)
+#define NFC_NATCH_INT_FLAG		(1 << 5)
+#define NFC_RB_STATE0			(1 << 8)
+#define NFC_RB_STATE1			(1 << 9)
+#define NFC_RB_STATE2			(1 << 10)
+#define NFC_RB_STATE3			(1 << 11)
+
+/*define bit use in NFC_INT*/
+#define NFC_B2R_INT_ENABLE		(1 << 0)
+#define NFC_CMD_INT_ENABLE		(1 << 1)
+#define NFC_DMA_INT_ENABLE		(1 << 2)
+#define NFC_INT_MASK			(NFC_B2R_INT_ENABLE | \
+					 NFC_CMD_INT_ENABLE | \
+					 NFC_DMA_INT_ENABLE)
+
+
+/*define bit use in NFC_CMD*/
+#define NFC_CMD_LOW_BYTE		(0xff << 0)
+#define NFC_CMD_HIGH_BYTE		(0xff << 8)
+#define NFC_ADR_NUM			(0x7 << 16)
+#define NFC_SEND_ADR			(1 << 19)
+#define NFC_ACCESS_DIR			(1 << 20)
+#define NFC_DATA_TRANS			(1 << 21)
+#define NFC_SEND_CMD1			(1 << 22)
+#define NFC_WAIT_FLAG			(1 << 23)
+#define NFC_SEND_CMD2			(1 << 24)
+#define NFC_SEQ				(1 << 25)
+#define NFC_DATA_SWAP_METHOD		(1 << 26)
+#define NFC_ROW_AUTO_INC		(1 << 27)
+#define NFC_SEND_CMD3			(1 << 28)
+#define NFC_SEND_CMD4			(1 << 29)
+#define NFC_CMD_TYPE			(3 << 30)
+
+/* define bit use in NFC_RCMD_SET*/
+#define NFC_READ_CMD			(0xff << 0)
+#define NFC_RANDOM_READ_CMD0		(0xff << 8)
+#define NFC_RANDOM_READ_CMD1		(0xff << 16)
+
+/*define bit use in NFC_WCMD_SET*/
+#define NFC_PROGRAM_CMD			(0xff << 0)
+#define NFC_RANDOM_WRITE_CMD		(0xff << 8)
+#define NFC_READ_CMD0			(0xff << 16)
+#define NFC_READ_CMD1			(0xff << 24)
+
+/*define bit use in NFC_ECC_CTL*/
+#define NFC_ECC_EN			(1 << 0)
+#define NFC_ECC_PIPELINE		(1 << 3)
+#define NFC_ECC_EXCEPTION		(1 << 4)
+#define NFC_ECC_BLOCK_SIZE		(1 << 5)
+#define NFC_RANDOM_EN			(1 << 9)
+#define NFC_RANDOM_DIRECTION		(1 << 10)
+#define NFC_ECC_MODE_SHIFT		12
+#define NFC_ECC_MODE			(0xf << NFC_ECC_MODE_SHIFT)
+#define NFC_RANDOM_SEED			(0x7fff << 16)
+
+
+
+enum sunxi_nand_rb_type {
+	RB_NONE,
+	RB_NATIVE,
+	RB_GPIO,
+};
+
+struct sunxi_nand_rb {
+	enum sunxi_nand_rb_type type;
+	union {
+		int gpio;
+		int nativeid;
+	} info;
+};
+
+struct sunxi_nand_chip_sel {
+	u8 cs;
+	struct sunxi_nand_rb rb;
+};
+
+#define DEFAULT_NAME_FORMAT	"nand@%d"
+#define MAX_NAME_SIZE		(sizeof("nand@") + 2)
+
+struct sunxi_nand_chip {
+	struct list_head node;
+	struct nand_chip nand;
+	struct mtd_info mtd;
+	char default_name[MAX_NAME_SIZE];
+	unsigned long clk_rate;
+	int selected;
+	int nsels;
+	struct sunxi_nand_chip_sel sels[0];
+};
+
+static inline struct sunxi_nand_chip *to_sunxi_nand(struct mtd_info *mtd)
+{
+	return container_of(mtd, struct sunxi_nand_chip, mtd);
+}
+
+struct sunxi_nfc {
+	struct nand_hw_control controller;
+	void __iomem *regs;
+	int irq;
+	struct clk *ahb_clk;
+	struct clk *sclk;
+	unsigned long assigned_cs;
+	struct list_head chips;
+	struct completion complete;
+};
+
+static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
+{
+	return container_of(ctrl, struct sunxi_nfc, controller);
+}
+
+static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
+{
+	struct sunxi_nfc *nfc = dev_id;
+	u32 st = readl(nfc->regs + NFC_REG_ST);
+	u32 ien = readl(nfc->regs + NFC_REG_INT);
+
+	if (!(ien & st))
+		return IRQ_NONE;
+
+	if ((ien & st) == ien)
+		complete(&nfc->complete);
+
+	writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
+	writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
+
+	return IRQ_HANDLED;
+}
+
+static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
+			      unsigned int timeout_ms)
+{
+	init_completion(&nfc->complete);
+
+	writel(flags, nfc->regs + NFC_REG_INT);
+	if (!timeout_ms)
+		wait_for_completion(&nfc->complete);
+	else if (!wait_for_completion_timeout(&nfc->complete,
+					      msecs_to_jiffies(timeout_ms)))
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	struct sunxi_nand_rb *rb;
+	unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
+	int ret;
+
+	if (sunxi_nand->selected < 0)
+		return 0;
+
+	rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
+
+	switch (rb->type) {
+	case RB_NATIVE:
+		ret = !!(readl(nfc->regs + NFC_REG_ST) &
+			 (NFC_RB_STATE0 << rb->info.nativeid));
+		if (ret)
+			break;
+
+		sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
+		ret = !!(readl(nfc->regs + NFC_REG_ST) &
+			 (NFC_RB_STATE0 << rb->info.nativeid));
+		break;
+	case RB_GPIO:
+		ret = gpio_get_value(rb->info.gpio);
+		break;
+	case RB_NONE:
+	default:
+		ret = 0;
+		dev_err(&mtd->dev, "cannot check R/B NAND status!");
+		break;
+	}
+
+	return ret;
+}
+
+static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	struct sunxi_nand_chip_sel *sel;
+	u32 ctl;
+
+	if (chip > 0 && chip >= sunxi_nand->nsels)
+		return;
+
+	if (chip == sunxi_nand->selected)
+		return;
+
+	ctl = readl(nfc->regs + NFC_REG_CTL) &
+	      ~(NFC_CE_SEL | NFC_RB_SEL | NFC_EN);
+
+	if (chip >= 0) {
+		sel = &sunxi_nand->sels[chip];
+
+		ctl |= (sel->cs << 24) | NFC_EN |
+		       (((sunxi_nand->nand.page_shift - 10) & 0xf) << 8);
+		if (sel->rb.type == RB_NONE) {
+			sunxi_nand->nand.dev_ready = NULL;
+		} else {
+			sunxi_nand->nand.dev_ready = sunxi_nfc_dev_ready;
+			if (sel->rb.type == RB_NATIVE)
+				ctl |= (sel->rb.info.nativeid << 3);
+		}
+	}
+
+	writel(ctl, nfc->regs + NFC_REG_CTL);
+	clk_set_rate(nfc->sclk, sunxi_nand->clk_rate);
+
+	sunxi_nand->selected = chip;
+}
+
+static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	int cnt;
+	int offs = 0;
+
+	while (len > 0) {
+		cnt = len > 1024 ? 1024 : len;
+		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+			;
+		writel(cnt, nfc->regs + NFC_REG_CNT);
+		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_SEQ,
+		       nfc->regs + NFC_REG_CMD);
+		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+		memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, cnt);
+		offs += cnt;
+		len -= cnt;
+	}
+}
+
+static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+				int len)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	int cnt;
+	int offs = 0;
+
+	while (len > 0) {
+		cnt = len > 1024 ? 1024 : len;
+		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+			;
+		writel(cnt, nfc->regs + NFC_REG_CNT);
+		memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
+		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
+		       NFC_ACCESS_DIR | NFC_SEQ, nfc->regs + NFC_REG_CMD);
+		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+		offs += cnt;
+		len -= cnt;
+	}
+}
+
+static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
+{
+	uint8_t ret;
+
+	sunxi_nfc_read_buf(mtd, &ret, 1);
+
+	return ret;
+}
+
+static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
+			       unsigned int ctrl)
+{
+	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
+	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+	u32 tmp;
+
+	while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+		;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		tmp = readl(nfc->regs + NFC_REG_CTL);
+		if (ctrl & NAND_NCE)
+			tmp |= NFC_CE_CTL;
+		else
+			tmp &= ~NFC_CE_CTL;
+		writel(tmp, nfc->regs + NFC_REG_CTL);
+	}
+
+	if (dat == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE) {
+		writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
+	} else {
+		writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
+		writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
+	}
+
+	sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+}
+
+static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
+					struct device_node *np)
+{
+	struct nand_timings timings;
+	u32 min_clk_period = 0;
+	int ret;
+
+	ret = of_get_nand_timings(np, &timings);
+	if (ret)
+		return ret;
+
+	/* NFC timings defined in Allwinner Datasheets */
+
+	/* T1 <=> tCLS */
+	if (timings.tCLS_min > min_clk_period)
+		min_clk_period = timings.tCLS_min;
+
+	/* T2 <=> tCLH */
+	if (timings.tCLH_min > min_clk_period)
+		min_clk_period = timings.tCLH_min;
+
+	/* T3 <=> tCS */
+	if (timings.tCS_min > min_clk_period)
+		min_clk_period = timings.tCS_min;
+
+	/* T4 <=> tCH */
+	if (timings.tCH_min > min_clk_period)
+		min_clk_period = timings.tCH_min;
+
+	/* T5 <=> tWP */
+	if (timings.tWP_min > min_clk_period)
+		min_clk_period = timings.tWP_min;
+
+	/* T6 <=> tWH */
+	if (timings.tWH_min > min_clk_period)
+		min_clk_period = timings.tWH_min;
+
+	/* T7 <=> tALS */
+	if (timings.tALS_min > min_clk_period)
+		min_clk_period = timings.tALS_min;
+
+	/* T8 <=> tDS */
+	if (timings.tDS_min > min_clk_period)
+		min_clk_period = timings.tDS_min;
+
+	/* T9 <=> tDH */
+	if (timings.tDH_min > min_clk_period)
+		min_clk_period = timings.tDH_min;
+
+	/* T10 <=> tRR */
+	if (timings.tRR_min > (min_clk_period * 3))
+		min_clk_period = (timings.tRR_min + 2) / 3;
+
+	/* T11 <=> tALH */
+	if (timings.tALH_min > min_clk_period)
+		min_clk_period = timings.tALH_min;
+
+	/* T12 <=> tRP */
+	if (timings.tRP_min > min_clk_period)
+		min_clk_period = timings.tRP_min;
+
+	/* T13 <=> tREH */
+	if (timings.tREH_min > min_clk_period)
+		min_clk_period = timings.tREH_min;
+
+	/* T14 <=> tRC */
+	if (timings.tRC_min > (min_clk_period * 2))
+		min_clk_period = (timings.tRC_min + 1) / 2;
+
+	/* T15 <=> tWC */
+	if (timings.tWC_min > (min_clk_period * 2))
+		min_clk_period = (timings.tWC_min + 1) / 2;
+
+
+	/* min_clk_period = (NAND-clk-period * 2) */
+	if (!min_clk_period)
+		chip->clk_rate = 20000000;
+	else
+		chip->clk_rate = (2 * 1000000000) / min_clk_period;
+
+	/* TODO: configure T16-T19 */
+
+	return 0;
+}
+
+static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
+				struct device_node *np)
+{
+	struct sunxi_nand_chip *chip;
+	struct mtd_part_parser_data ppdata;
+	struct mtd_info *mtd;
+	struct nand_chip *nand;
+	int nsels;
+	int ret;
+	int i;
+	u32 tmp;
+
+	if (!of_get_property(np, "reg", &nsels))
+		return -EINVAL;
+
+	nsels /= sizeof(u32);
+	if (!nsels)
+		return -EINVAL;
+
+	chip = devm_kzalloc(dev,
+			    sizeof(*chip) +
+			    (nsels * sizeof(struct sunxi_nand_chip_sel)),
+			    GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->nsels = nsels;
+	chip->selected = -1;
+
+	for (i = 0; i < nsels; i++) {
+		ret = of_property_read_u32_index(np, "reg", i, &tmp);
+		if (ret)
+			return ret;
+
+		if (tmp > 7)
+			return -EINVAL;
+
+		if (test_and_set_bit(tmp, &nfc->assigned_cs))
+			return -EINVAL;
+
+		chip->sels[i].cs = tmp;
+
+		if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
+		    tmp < 2) {
+			chip->sels[i].rb.type = RB_NATIVE;
+			chip->sels[i].rb.info.nativeid = tmp;
+		} else {
+			ret = of_get_named_gpio(np, "rb-gpios", i);
+			if (ret >= 0) {
+				chip->sels[i].rb.type = RB_GPIO;
+				chip->sels[i].rb.info.gpio = tmp;
+				ret = devm_gpio_request(dev, tmp, "nand-rb");
+				if (ret)
+					return ret;
+			} else {
+				chip->sels[i].rb.type = RB_NONE;
+			}
+		}
+	}
+
+	ret = sunxi_nand_chip_init_timings(chip, np);
+	if (ret)
+		return ret;
+
+	nand = &chip->nand;
+	nand->IO_ADDR_R = nand->IO_ADDR_W = nfc->regs + NFC_REG_IO_DATA;
+	nand->controller = &nfc->controller;
+	nand->select_chip = sunxi_nfc_select_chip;
+	nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
+	nand->read_buf = sunxi_nfc_read_buf;
+	nand->write_buf = sunxi_nfc_write_buf;
+	nand->read_byte = sunxi_nfc_read_byte;
+
+	nand->ecc.mode = of_get_nand_ecc_mode(np);
+	if (of_get_nand_on_flash_bbt(np))
+		nand->bbt_options |= NAND_BBT_USE_FLASH;
+
+	mtd = &chip->mtd;
+	mtd->priv = nand;
+	mtd->owner = THIS_MODULE;
+
+	ret = nand_scan_ident(mtd, nsels, NULL);
+	if (ret)
+		return ret;
+
+	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
+		nand->ecc.size = nand->ecc_step_ds;
+		nand->ecc.bytes = (((nand->ecc_strength_ds *
+				     fls(8 * nand->ecc_step_ds)) + 7) / 8);
+	}
+
+	ret = nand_scan_tail(mtd);
+	if (ret)
+		return ret;
+
+	if (of_property_read_string(np, "nand-name", &mtd->name)) {
+		snprintf(chip->default_name, MAX_NAME_SIZE,
+			 DEFAULT_NAME_FORMAT, chip->sels[i].cs);
+		mtd->name = chip->default_name;
+	}
+
+	ppdata.of_node = np;
+	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+	if (!ret)
+		return ret;
+
+	list_add_tail(&chip->node, &nfc->chips);
+
+	return 0;
+}
+
+static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
+{
+	struct device_node *np = dev->of_node;
+	struct device_node *nand_np;
+	int nchips = of_get_child_count(np);
+	int ret;
+
+	if (nchips > 8)
+		return -EINVAL;
+
+	for_each_child_of_node(np, nand_np) {
+		ret = sunxi_nand_chip_init(dev, nfc, nand_np);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int sunxi_nfc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *r;
+	struct sunxi_nfc *nfc;
+	int ret;
+
+	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
+	if (!nfc) {
+		dev_err(dev, "failed to allocate NFC struct\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_init(&nfc->controller.lock);
+	init_waitqueue_head(&nfc->controller.wq);
+	INIT_LIST_HEAD(&nfc->chips);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	nfc->regs = devm_ioremap_resource(dev, r);
+	if (IS_ERR(nfc->regs)) {
+		dev_err(dev, "failed to remap iomem\n");
+		return PTR_ERR(nfc->regs);
+	}
+
+	nfc->irq = platform_get_irq(pdev, 0);
+	if (nfc->irq < 0) {
+		dev_err(dev, "failed to retrieve irq\n");
+		return nfc->irq;
+	}
+
+	nfc->ahb_clk = devm_clk_get(dev, "ahb_clk");
+	if (IS_ERR(nfc->ahb_clk)) {
+		dev_err(dev, "failed to retrieve ahb_clk\n");
+		return PTR_ERR(nfc->ahb_clk);
+	}
+
+	ret = clk_prepare_enable(nfc->ahb_clk);
+	if (ret)
+		return ret;
+
+	nfc->sclk = devm_clk_get(dev, "sclk");
+	if (IS_ERR(nfc->sclk)) {
+		dev_err(dev, "failed to retrieve nand_clk\n");
+		ret = PTR_ERR(nfc->sclk);
+		goto out_ahb_clk_unprepare;
+	}
+
+	ret = clk_prepare_enable(nfc->sclk);
+	if (ret)
+		goto out_ahb_clk_unprepare;
+
+	/* Reset NFC */
+	writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RESET,
+	       nfc->regs + NFC_REG_CTL);
+	while (readl(nfc->regs + NFC_REG_CTL) & NFC_RESET)
+		;
+
+	writel(0, nfc->regs + NFC_REG_INT);
+	ret = devm_request_irq(dev, nfc->irq, sunxi_nfc_interrupt,
+			       0, "sunxi-nfc", nfc);
+	if (ret)
+		goto out_sclk_unprepare;
+
+	platform_set_drvdata(pdev, nfc);
+
+	writel(0x100, nfc->regs + NFC_REG_TIMING_CTL);
+	writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG);
+
+	ret = sunxi_nand_chips_init(dev, nfc);
+	if (ret) {
+		dev_err(dev, "failed to init nand chips\n");
+		goto out_sclk_unprepare;
+	}
+
+	return 0;
+
+out_sclk_unprepare:
+	clk_disable_unprepare(nfc->sclk);
+out_ahb_clk_unprepare:
+	clk_disable_unprepare(nfc->ahb_clk);
+
+	return ret;
+}
+
+static const struct of_device_id sunxi_nfc_ids[] = {
+	{ .compatible = "allwinner,sun4i-nfc" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
+
+static struct platform_driver sunxi_nfc_driver = {
+	.driver = {
+		.name = "sunxi_nfc",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(sunxi_nfc_ids),
+	},
+	.probe = sunxi_nfc_probe,
+};
+module_platform_driver(sunxi_nfc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Boris BREZILLON");
+MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
+MODULE_ALIAS("platform:sunxi_nfc");
-- 
1.7.9.5

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

* [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
  2014-01-08 14:21 ` Boris BREZILLON
  (?)
@ 2014-01-08 14:22   ` Boris BREZILLON
  -1 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

Add the sunxi NAND Flash Controller dt bindings documentation.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
new file mode 100644
index 0000000..c3206fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
@@ -0,0 +1,71 @@
+Allwinner NAND Flash Controller (NFC)
+
+Required properties:
+- compatible : "allwinner,sun4i-nfc".
+- reg : shall contain registers location and length for data and reg.
+- interrupts : shall define the NFC interrupt.
+- #address-cells: shall be set to 1. Encode the nand CS.
+- #size-cells : shall be set to 0.
+- clocks : shall reference NFC clocks.
+- clock-names : NFC internal clock names. Shall contain :
+    * "ahb_clk" : AHB gating clock
+    * "sclk" : NFC clock
+
+Optional children nodes:
+Children nodes represent the available nand chips.
+
+Required properties:
+- reg : shall contain the CS ids (a given chip might use several CS)
+- tCLS-min : see Documentation/devicetree/mtd/nand.txt
+- tCLH-min : Documentation/devicetree/mtd/nand.txt
+- tCS-min : see Documentation/devicetree/mtd/nand.txt
+- tCH-min : see Documentation/devicetree/mtd/nand.txt
+- tWP-min : see Documentation/devicetree/mtd/nand.txt
+- tWH-min : see Documentation/devicetree/mtd/nand.txt
+- tALS-min : see Documentation/devicetree/mtd/nand.txt
+- tDS-min : see Documentation/devicetree/mtd/nand.txt
+- tDH-min : see Documentation/devicetree/mtd/nand.txt
+- tRR-min : see Documentation/devicetree/mtd/nand.txt
+- tALH-min : see Documentation/devicetree/mtd/nand.txt
+- tRP-min : see Documentation/devicetree/mtd/nand.txt
+- tREH-min : see Documentation/devicetree/mtd/nand.txt
+- tRC-min : see Documentation/devicetree/mtd/nand.txt
+- tWC-min : see Documentation/devicetree/mtd/nand.txt
+
+Optional properties:
+- allwinner,rb : shall contain the native Ready/Busy ids.
+ or
+- rb-gpios : shall contain the gpios used as R/B pins.
+
+see Documentation/devicetree/mtd/nand.txt for generic bindings.
+
+
+Examples:
+nfc: nand@01c03000 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+	status = "okay";
+
+	nand@0 {
+		reg = <0>;
+		allwinner,rb = <0>;
+		nand-ecc-mode = "soft_bch";
+
+		/* nand timings */
+		tCLS-min = <6>;
+		tCLH-min = <3>;
+		tCS-min = <20>;
+		tCH-min = <5>;
+		tWP-min = <8>;
+		tWH-min = <6>;
+		tALS-min = <6>;
+		tDS-min = <6>;
+		tDH-min = <2>;
+		tRR-min = <20>;
+		tALH-min = <3>;
+		tRP-min = <8>;
+		tREH-min = <6>;
+		tRC-min = <16>;
+		tWC-min = <16>;
+	};
+};
-- 
1.7.9.5


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

* [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

Add the sunxi NAND Flash Controller dt bindings documentation.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
new file mode 100644
index 0000000..c3206fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
@@ -0,0 +1,71 @@
+Allwinner NAND Flash Controller (NFC)
+
+Required properties:
+- compatible : "allwinner,sun4i-nfc".
+- reg : shall contain registers location and length for data and reg.
+- interrupts : shall define the NFC interrupt.
+- #address-cells: shall be set to 1. Encode the nand CS.
+- #size-cells : shall be set to 0.
+- clocks : shall reference NFC clocks.
+- clock-names : NFC internal clock names. Shall contain :
+    * "ahb_clk" : AHB gating clock
+    * "sclk" : NFC clock
+
+Optional children nodes:
+Children nodes represent the available nand chips.
+
+Required properties:
+- reg : shall contain the CS ids (a given chip might use several CS)
+- tCLS-min : see Documentation/devicetree/mtd/nand.txt
+- tCLH-min : Documentation/devicetree/mtd/nand.txt
+- tCS-min : see Documentation/devicetree/mtd/nand.txt
+- tCH-min : see Documentation/devicetree/mtd/nand.txt
+- tWP-min : see Documentation/devicetree/mtd/nand.txt
+- tWH-min : see Documentation/devicetree/mtd/nand.txt
+- tALS-min : see Documentation/devicetree/mtd/nand.txt
+- tDS-min : see Documentation/devicetree/mtd/nand.txt
+- tDH-min : see Documentation/devicetree/mtd/nand.txt
+- tRR-min : see Documentation/devicetree/mtd/nand.txt
+- tALH-min : see Documentation/devicetree/mtd/nand.txt
+- tRP-min : see Documentation/devicetree/mtd/nand.txt
+- tREH-min : see Documentation/devicetree/mtd/nand.txt
+- tRC-min : see Documentation/devicetree/mtd/nand.txt
+- tWC-min : see Documentation/devicetree/mtd/nand.txt
+
+Optional properties:
+- allwinner,rb : shall contain the native Ready/Busy ids.
+ or
+- rb-gpios : shall contain the gpios used as R/B pins.
+
+see Documentation/devicetree/mtd/nand.txt for generic bindings.
+
+
+Examples:
+nfc: nand@01c03000 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+	status = "okay";
+
+	nand@0 {
+		reg = <0>;
+		allwinner,rb = <0>;
+		nand-ecc-mode = "soft_bch";
+
+		/* nand timings */
+		tCLS-min = <6>;
+		tCLH-min = <3>;
+		tCS-min = <20>;
+		tCH-min = <5>;
+		tWP-min = <8>;
+		tWH-min = <6>;
+		tALS-min = <6>;
+		tDS-min = <6>;
+		tDH-min = <2>;
+		tRR-min = <20>;
+		tALH-min = <3>;
+		tRP-min = <8>;
+		tREH-min = <6>;
+		tRC-min = <16>;
+		tWC-min = <16>;
+	};
+};
-- 
1.7.9.5

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

* [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Add the sunxi NAND Flash Controller dt bindings documentation.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
new file mode 100644
index 0000000..c3206fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
@@ -0,0 +1,71 @@
+Allwinner NAND Flash Controller (NFC)
+
+Required properties:
+- compatible : "allwinner,sun4i-nfc".
+- reg : shall contain registers location and length for data and reg.
+- interrupts : shall define the NFC interrupt.
+- #address-cells: shall be set to 1. Encode the nand CS.
+- #size-cells : shall be set to 0.
+- clocks : shall reference NFC clocks.
+- clock-names : NFC internal clock names. Shall contain :
+    * "ahb_clk" : AHB gating clock
+    * "sclk" : NFC clock
+
+Optional children nodes:
+Children nodes represent the available nand chips.
+
+Required properties:
+- reg : shall contain the CS ids (a given chip might use several CS)
+- tCLS-min : see Documentation/devicetree/mtd/nand.txt
+- tCLH-min : Documentation/devicetree/mtd/nand.txt
+- tCS-min : see Documentation/devicetree/mtd/nand.txt
+- tCH-min : see Documentation/devicetree/mtd/nand.txt
+- tWP-min : see Documentation/devicetree/mtd/nand.txt
+- tWH-min : see Documentation/devicetree/mtd/nand.txt
+- tALS-min : see Documentation/devicetree/mtd/nand.txt
+- tDS-min : see Documentation/devicetree/mtd/nand.txt
+- tDH-min : see Documentation/devicetree/mtd/nand.txt
+- tRR-min : see Documentation/devicetree/mtd/nand.txt
+- tALH-min : see Documentation/devicetree/mtd/nand.txt
+- tRP-min : see Documentation/devicetree/mtd/nand.txt
+- tREH-min : see Documentation/devicetree/mtd/nand.txt
+- tRC-min : see Documentation/devicetree/mtd/nand.txt
+- tWC-min : see Documentation/devicetree/mtd/nand.txt
+
+Optional properties:
+- allwinner,rb : shall contain the native Ready/Busy ids.
+ or
+- rb-gpios : shall contain the gpios used as R/B pins.
+
+see Documentation/devicetree/mtd/nand.txt for generic bindings.
+
+
+Examples:
+nfc: nand at 01c03000 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+	status = "okay";
+
+	nand at 0 {
+		reg = <0>;
+		allwinner,rb = <0>;
+		nand-ecc-mode = "soft_bch";
+
+		/* nand timings */
+		tCLS-min = <6>;
+		tCLH-min = <3>;
+		tCS-min = <20>;
+		tCH-min = <5>;
+		tWP-min = <8>;
+		tWH-min = <6>;
+		tALS-min = <6>;
+		tDS-min = <6>;
+		tDH-min = <2>;
+		tRR-min = <20>;
+		tALH-min = <3>;
+		tRP-min = <8>;
+		tREH-min = <6>;
+		tRC-min = <16>;
+		tWC-min = <16>;
+	};
+};
-- 
1.7.9.5

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

* [RFC PATCH 7/9] ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
  2014-01-08 14:21 ` Boris BREZILLON
  (?)
@ 2014-01-08 14:22   ` Boris BREZILLON
  -1 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

Add NAND Flash controller node definition to the A20 SoC.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 arch/arm/boot/dts/sun7i-a20.dtsi |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 8e4cdcc..c00a577 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -299,6 +299,17 @@
 		#size-cells = <1>;
 		ranges;
 
+		nfc: nand@01c03000 {
+			compatible = "allwinner,sun4i-nfc";
+			reg = <0x01c03000 0x1000>;
+			interrupts = <0 37 1>;
+			clocks = <&ahb_gates 13>, <&nand_clk>;
+			clock-names = "ahb_clk", "sclk";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		emac: ethernet@01c0b000 {
 			compatible = "allwinner,sun4i-emac";
 			reg = <0x01c0b000 0x1000>;
-- 
1.7.9.5


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

* [RFC PATCH 7/9] ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

Add NAND Flash controller node definition to the A20 SoC.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 arch/arm/boot/dts/sun7i-a20.dtsi |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 8e4cdcc..c00a577 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -299,6 +299,17 @@
 		#size-cells = <1>;
 		ranges;
 
+		nfc: nand@01c03000 {
+			compatible = "allwinner,sun4i-nfc";
+			reg = <0x01c03000 0x1000>;
+			interrupts = <0 37 1>;
+			clocks = <&ahb_gates 13>, <&nand_clk>;
+			clock-names = "ahb_clk", "sclk";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		emac: ethernet@01c0b000 {
 			compatible = "allwinner,sun4i-emac";
 			reg = <0x01c0b000 0x1000>;
-- 
1.7.9.5

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

* [RFC PATCH 7/9] ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Add NAND Flash controller node definition to the A20 SoC.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 arch/arm/boot/dts/sun7i-a20.dtsi |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 8e4cdcc..c00a577 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -299,6 +299,17 @@
 		#size-cells = <1>;
 		ranges;
 
+		nfc: nand at 01c03000 {
+			compatible = "allwinner,sun4i-nfc";
+			reg = <0x01c03000 0x1000>;
+			interrupts = <0 37 1>;
+			clocks = <&ahb_gates 13>, <&nand_clk>;
+			clock-names = "ahb_clk", "sclk";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		emac: ethernet at 01c0b000 {
 			compatible = "allwinner,sun4i-emac";
 			reg = <0x01c0b000 0x1000>;
-- 
1.7.9.5

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

* [RFC PATCH 8/9] ARM: dt/sunxi: add NFC pinctrl pin definitions
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

Define the NAND pinctrl configs.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 arch/arm/boot/dts/sun7i-a20.dtsi |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index c00a577..34b1948 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -389,6 +389,30 @@
 				allwinner,drive = <0>;
 				allwinner,pull = <0>;
 			};
+
+			nand_pins_a: nand_base0@0 {
+				allwinner,pins = "PC0", "PC1", "PC2",
+						"PC5", "PC8", "PC9", "PC10",
+						"PC11", "PC12", "PC13", "PC14",
+						"PC15", "PC16";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			nand_cs0_pins_a: nand_cs@0 {
+				allwinner,pins = "PC4";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			nand_rb0_pins_a: nand_rb@0 {
+				allwinner,pins = "PC6";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
 		};
 
 		timer@01c20c00 {
-- 
1.7.9.5


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

* [RFC PATCH 8/9] ARM: dt/sunxi: add NFC pinctrl pin definitions
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	dev-3kdeTeqwOZ9EV1b7eY7vFQ, Boris BREZILLON

Define the NAND pinctrl configs.

Signed-off-by: Boris BREZILLON <b.brezillon-ZNYIgs0QAGpBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/boot/dts/sun7i-a20.dtsi |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index c00a577..34b1948 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -389,6 +389,30 @@
 				allwinner,drive = <0>;
 				allwinner,pull = <0>;
 			};
+
+			nand_pins_a: nand_base0@0 {
+				allwinner,pins = "PC0", "PC1", "PC2",
+						"PC5", "PC8", "PC9", "PC10",
+						"PC11", "PC12", "PC13", "PC14",
+						"PC15", "PC16";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			nand_cs0_pins_a: nand_cs@0 {
+				allwinner,pins = "PC4";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			nand_rb0_pins_a: nand_rb@0 {
+				allwinner,pins = "PC6";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
 		};
 
 		timer@01c20c00 {
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH 8/9] ARM: dt/sunxi: add NFC pinctrl pin definitions
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

Define the NAND pinctrl configs.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 arch/arm/boot/dts/sun7i-a20.dtsi |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index c00a577..34b1948 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -389,6 +389,30 @@
 				allwinner,drive = <0>;
 				allwinner,pull = <0>;
 			};
+
+			nand_pins_a: nand_base0@0 {
+				allwinner,pins = "PC0", "PC1", "PC2",
+						"PC5", "PC8", "PC9", "PC10",
+						"PC11", "PC12", "PC13", "PC14",
+						"PC15", "PC16";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			nand_cs0_pins_a: nand_cs@0 {
+				allwinner,pins = "PC4";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			nand_rb0_pins_a: nand_rb@0 {
+				allwinner,pins = "PC6";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
 		};
 
 		timer@01c20c00 {
-- 
1.7.9.5

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

* [RFC PATCH 8/9] ARM: dt/sunxi: add NFC pinctrl pin definitions
@ 2014-01-08 14:22   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Define the NAND pinctrl configs.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 arch/arm/boot/dts/sun7i-a20.dtsi |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index c00a577..34b1948 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -389,6 +389,30 @@
 				allwinner,drive = <0>;
 				allwinner,pull = <0>;
 			};
+
+			nand_pins_a: nand_base0 at 0 {
+				allwinner,pins = "PC0", "PC1", "PC2",
+						"PC5", "PC8", "PC9", "PC10",
+						"PC11", "PC12", "PC13", "PC14",
+						"PC15", "PC16";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			nand_cs0_pins_a: nand_cs at 0 {
+				allwinner,pins = "PC4";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			nand_rb0_pins_a: nand_rb at 0 {
+				allwinner,pins = "PC6";
+				allwinner,function = "nand0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
 		};
 
 		timer at 01c20c00 {
-- 
1.7.9.5

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

* [RFC PATCH 9/9] ARM: sunxi/dt: enable NAND on cubietruck board
@ 2014-01-08 15:28   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 15:28 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

Enable the NFC and describe the NAND flash connected to this controller.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts |   33 ++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index 8a1009d..08ee7d3 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -18,7 +18,40 @@
 	model = "Cubietech Cubietruck";
 	compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
 
+	chosen {
+		bootargs = "console=ttyS0,115200 earlyprintk root=/dev/ram0 rootfstype=ext2 rw";
+	};
+
 	soc@01c00000 {
+		nfc: nand@01c03000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+			status = "okay";
+
+			nand@0 {
+				reg = <0>;
+				allwinner,rb = <0>;
+				nand-ecc-mode = "soft_bch";
+
+				/* nand timings */
+				tCLS-min = <6>;
+				tCLH-min = <3>;
+				tCS-min = <20>;
+				tCH-min = <5>;
+				tWP-min = <8>;
+				tWH-min = <6>;
+				tALS-min = <6>;
+				tDS-min = <6>;
+				tDH-min = <2>;
+				tRR-min = <20>;
+				tALH-min = <3>;
+				tRP-min = <8>;
+				tREH-min = <6>;
+				tRC-min = <16>;
+				tWC-min = <16>;
+			};
+		};
+
 		pinctrl@01c20800 {
 			led_pins_cubietruck: led_pins@0 {
 				allwinner,pins = "PH7", "PH11", "PH20", "PH21";
-- 
1.7.9.5


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

* [RFC PATCH 9/9] ARM: sunxi/dt: enable NAND on cubietruck board
@ 2014-01-08 15:28   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 15:28 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	dev-3kdeTeqwOZ9EV1b7eY7vFQ, Boris BREZILLON

Enable the NFC and describe the NAND flash connected to this controller.

Signed-off-by: Boris BREZILLON <b.brezillon-ZNYIgs0QAGpBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts |   33 ++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index 8a1009d..08ee7d3 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -18,7 +18,40 @@
 	model = "Cubietech Cubietruck";
 	compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
 
+	chosen {
+		bootargs = "console=ttyS0,115200 earlyprintk root=/dev/ram0 rootfstype=ext2 rw";
+	};
+
 	soc@01c00000 {
+		nfc: nand@01c03000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+			status = "okay";
+
+			nand@0 {
+				reg = <0>;
+				allwinner,rb = <0>;
+				nand-ecc-mode = "soft_bch";
+
+				/* nand timings */
+				tCLS-min = <6>;
+				tCLH-min = <3>;
+				tCS-min = <20>;
+				tCH-min = <5>;
+				tWP-min = <8>;
+				tWH-min = <6>;
+				tALS-min = <6>;
+				tDS-min = <6>;
+				tDH-min = <2>;
+				tRR-min = <20>;
+				tALH-min = <3>;
+				tRP-min = <8>;
+				tREH-min = <6>;
+				tRC-min = <16>;
+				tWC-min = <16>;
+			};
+		};
+
 		pinctrl@01c20800 {
 			led_pins_cubietruck: led_pins@0 {
 				allwinner,pins = "PH7", "PH11", "PH20", "PH21";
-- 
1.7.9.5

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

* [RFC PATCH 9/9] ARM: sunxi/dt: enable NAND on cubietruck board
@ 2014-01-08 15:28   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 15:28 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

Enable the NFC and describe the NAND flash connected to this controller.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts |   33 ++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index 8a1009d..08ee7d3 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -18,7 +18,40 @@
 	model = "Cubietech Cubietruck";
 	compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
 
+	chosen {
+		bootargs = "console=ttyS0,115200 earlyprintk root=/dev/ram0 rootfstype=ext2 rw";
+	};
+
 	soc@01c00000 {
+		nfc: nand@01c03000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+			status = "okay";
+
+			nand@0 {
+				reg = <0>;
+				allwinner,rb = <0>;
+				nand-ecc-mode = "soft_bch";
+
+				/* nand timings */
+				tCLS-min = <6>;
+				tCLH-min = <3>;
+				tCS-min = <20>;
+				tCH-min = <5>;
+				tWP-min = <8>;
+				tWH-min = <6>;
+				tALS-min = <6>;
+				tDS-min = <6>;
+				tDH-min = <2>;
+				tRR-min = <20>;
+				tALH-min = <3>;
+				tRP-min = <8>;
+				tREH-min = <6>;
+				tRC-min = <16>;
+				tWC-min = <16>;
+			};
+		};
+
 		pinctrl@01c20800 {
 			led_pins_cubietruck: led_pins@0 {
 				allwinner,pins = "PH7", "PH11", "PH20", "PH21";
-- 
1.7.9.5

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

* [RFC PATCH 9/9] ARM: sunxi/dt: enable NAND on cubietruck board
@ 2014-01-08 15:28   ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-01-08 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the NFC and describe the NAND flash connected to this controller.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts |   33 ++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index 8a1009d..08ee7d3 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -18,7 +18,40 @@
 	model = "Cubietech Cubietruck";
 	compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
 
+	chosen {
+		bootargs = "console=ttyS0,115200 earlyprintk root=/dev/ram0 rootfstype=ext2 rw";
+	};
+
 	soc at 01c00000 {
+		nfc: nand at 01c03000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+			status = "okay";
+
+			nand at 0 {
+				reg = <0>;
+				allwinner,rb = <0>;
+				nand-ecc-mode = "soft_bch";
+
+				/* nand timings */
+				tCLS-min = <6>;
+				tCLH-min = <3>;
+				tCS-min = <20>;
+				tCH-min = <5>;
+				tWP-min = <8>;
+				tWH-min = <6>;
+				tALS-min = <6>;
+				tDS-min = <6>;
+				tDH-min = <2>;
+				tRR-min = <20>;
+				tALH-min = <3>;
+				tRP-min = <8>;
+				tREH-min = <6>;
+				tRC-min = <16>;
+				tWC-min = <16>;
+			};
+		};
+
 		pinctrl at 01c20800 {
 			led_pins_cubietruck: led_pins at 0 {
 				allwinner,pins = "PH7", "PH11", "PH20", "PH21";
-- 
1.7.9.5

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

* Re: [RFC PATCH 9/9] ARM: sunxi/dt: enable NAND on cubietruck board
  2014-01-08 15:28   ` Boris BREZILLON
  (?)
@ 2014-01-08 15:30     ` boris brezillon
  -1 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 15:30 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

On 08/01/2014 16:28, Boris BREZILLON wrote:
> Enable the NFC and describe the NAND flash connected to this controller.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>   arch/arm/boot/dts/sun7i-a20-cubietruck.dts |   33 ++++++++++++++++++++++++++++
>   1 file changed, 33 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> index 8a1009d..08ee7d3 100644
> --- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> @@ -18,7 +18,40 @@
>   	model = "Cubietech Cubietruck";
>   	compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
>   
> +	chosen {
> +		bootargs = "console=ttyS0,115200 earlyprintk root=/dev/ram0 rootfstype=ext2 rw";
> +	};
> +

Sorry, I messed up with the bootargs.
I'll remove it in the next version.

>   	soc@01c00000 {
> +		nfc: nand@01c03000 {
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
> +			status = "okay";
> +
> +			nand@0 {
> +				reg = <0>;
> +				allwinner,rb = <0>;
> +				nand-ecc-mode = "soft_bch";
> +
> +				/* nand timings */
> +				tCLS-min = <6>;
> +				tCLH-min = <3>;
> +				tCS-min = <20>;
> +				tCH-min = <5>;
> +				tWP-min = <8>;
> +				tWH-min = <6>;
> +				tALS-min = <6>;
> +				tDS-min = <6>;
> +				tDH-min = <2>;
> +				tRR-min = <20>;
> +				tALH-min = <3>;
> +				tRP-min = <8>;
> +				tREH-min = <6>;
> +				tRC-min = <16>;
> +				tWC-min = <16>;
> +			};
> +		};
> +
>   		pinctrl@01c20800 {
>   			led_pins_cubietruck: led_pins@0 {
>   				allwinner,pins = "PH7", "PH11", "PH20", "PH21";


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

* Re: [RFC PATCH 9/9] ARM: sunxi/dt: enable NAND on cubietruck board
@ 2014-01-08 15:30     ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 15:30 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

On 08/01/2014 16:28, Boris BREZILLON wrote:
> Enable the NFC and describe the NAND flash connected to this controller.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>   arch/arm/boot/dts/sun7i-a20-cubietruck.dts |   33 ++++++++++++++++++++++++++++
>   1 file changed, 33 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> index 8a1009d..08ee7d3 100644
> --- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> @@ -18,7 +18,40 @@
>   	model = "Cubietech Cubietruck";
>   	compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
>   
> +	chosen {
> +		bootargs = "console=ttyS0,115200 earlyprintk root=/dev/ram0 rootfstype=ext2 rw";
> +	};
> +

Sorry, I messed up with the bootargs.
I'll remove it in the next version.

>   	soc@01c00000 {
> +		nfc: nand@01c03000 {
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
> +			status = "okay";
> +
> +			nand@0 {
> +				reg = <0>;
> +				allwinner,rb = <0>;
> +				nand-ecc-mode = "soft_bch";
> +
> +				/* nand timings */
> +				tCLS-min = <6>;
> +				tCLH-min = <3>;
> +				tCS-min = <20>;
> +				tCH-min = <5>;
> +				tWP-min = <8>;
> +				tWH-min = <6>;
> +				tALS-min = <6>;
> +				tDS-min = <6>;
> +				tDH-min = <2>;
> +				tRR-min = <20>;
> +				tALH-min = <3>;
> +				tRP-min = <8>;
> +				tREH-min = <6>;
> +				tRC-min = <16>;
> +				tWC-min = <16>;
> +			};
> +		};
> +
>   		pinctrl@01c20800 {
>   			led_pins_cubietruck: led_pins@0 {
>   				allwinner,pins = "PH7", "PH11", "PH20", "PH21";

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

* [RFC PATCH 9/9] ARM: sunxi/dt: enable NAND on cubietruck board
@ 2014-01-08 15:30     ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 15:30 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/01/2014 16:28, Boris BREZILLON wrote:
> Enable the NFC and describe the NAND flash connected to this controller.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>   arch/arm/boot/dts/sun7i-a20-cubietruck.dts |   33 ++++++++++++++++++++++++++++
>   1 file changed, 33 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> index 8a1009d..08ee7d3 100644
> --- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> @@ -18,7 +18,40 @@
>   	model = "Cubietech Cubietruck";
>   	compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
>   
> +	chosen {
> +		bootargs = "console=ttyS0,115200 earlyprintk root=/dev/ram0 rootfstype=ext2 rw";
> +	};
> +

Sorry, I messed up with the bootargs.
I'll remove it in the next version.

>   	soc at 01c00000 {
> +		nfc: nand at 01c03000 {
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
> +			status = "okay";
> +
> +			nand at 0 {
> +				reg = <0>;
> +				allwinner,rb = <0>;
> +				nand-ecc-mode = "soft_bch";
> +
> +				/* nand timings */
> +				tCLS-min = <6>;
> +				tCLH-min = <3>;
> +				tCS-min = <20>;
> +				tCH-min = <5>;
> +				tWP-min = <8>;
> +				tWH-min = <6>;
> +				tALS-min = <6>;
> +				tDS-min = <6>;
> +				tDH-min = <2>;
> +				tRR-min = <20>;
> +				tALH-min = <3>;
> +				tRP-min = <8>;
> +				tREH-min = <6>;
> +				tRC-min = <16>;
> +				tWC-min = <16>;
> +			};
> +		};
> +
>   		pinctrl at 01c20800 {
>   			led_pins_cubietruck: led_pins at 0 {
>   				allwinner,pins = "PH7", "PH11", "PH20", "PH21";

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
  2014-01-08 14:21   ` Boris BREZILLON
  (?)
  (?)
@ 2014-01-08 16:30     ` Rob Herring
  -1 siblings, 0 replies; 123+ messages in thread
From: Rob Herring @ 2014-01-08 16:30 UTC (permalink / raw)
  To: Boris BREZILLON
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel

On Wed, Jan 8, 2014 at 8:21 AM, Boris BREZILLON <b.brezillon@overkiz.com> wrote:
> Add a function to retrieve NAND timings from a given DT node.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>  drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_mtd.h |    9 +++++++++
>  2 files changed, 56 insertions(+)
>
> diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
> index a27ec94..52e07fd 100644
> --- a/drivers/of/of_mtd.c
> +++ b/drivers/of/of_mtd.c
> @@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
>         return of_property_read_bool(np, "nand-on-flash-bbt");
>  }
>  EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
> +
> +/**
> + * of_get_nand_timings - Get nand timings for the given device_node
> + * @np:        Pointer to the given device_node
> + *
> + * return 0 on success errno other wise
> + */
> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> +{
> +       memset(timings, 0, sizeof(*timings));
> +
> +       of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> +       of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> +       of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> +       of_property_read_u32(np, "tCH-min", &timings->tCH_min);
> +       of_property_read_u32(np, "tWP-min", &timings->tWP_min);
> +       of_property_read_u32(np, "tALS-min", &timings->tALS_min);
> +       of_property_read_u32(np, "tALH-min", &timings->tALH_min);
> +       of_property_read_u32(np, "tDS-min", &timings->tDS_min);
> +       of_property_read_u32(np, "tDH-min", &timings->tDH_min);
> +       of_property_read_u32(np, "tWC-min", &timings->tWC_min);
> +       of_property_read_u32(np, "tWH-min", &timings->tWH_min);
> +       of_property_read_u32(np, "tR-max", &timings->tR_max);
> +       of_property_read_u32(np, "tAR-min", &timings->tAR_min);
> +       of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
> +       of_property_read_u32(np, "tRR-min", &timings->tRR_min);
> +       of_property_read_u32(np, "tRP-min", &timings->tRP_min);
> +       of_property_read_u32(np, "tWB-max", &timings->tWB_max);
> +       of_property_read_u32(np, "tRC-min", &timings->tRC_min);
> +       of_property_read_u32(np, "tREA-max", &timings->tREA_max);
> +       of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
> +       of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
> +       of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
> +       of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
> +       of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
> +       of_property_read_u32(np, "tREH-min", &timings->tREH_min);
> +       of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
> +       of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
> +       of_property_read_u32(np, "tIR-min", &timings->tIR_min);
> +       of_property_read_u32(np, "tCR-min", &timings->tCR_min);
> +       of_property_read_u32(np, "tADL-min", &timings->tADL_min);
> +       of_property_read_u32(np, "tRST-max", &timings->tRST_max);
> +       of_property_read_u32(np, "tWW-min", &timings->tWW_min);

These all need to be documented. These apply to which compatible
strings? They should also be suffixed with the unit the property is in
(i.e. -ms, -us, -ns).

Rob

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 16:30     ` Rob Herring
  0 siblings, 0 replies; 123+ messages in thread
From: Rob Herring @ 2014-01-08 16:30 UTC (permalink / raw)
  To: Boris BREZILLON
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel

On Wed, Jan 8, 2014 at 8:21 AM, Boris BREZILLON <b.brezillon@overkiz.com> wrote:
> Add a function to retrieve NAND timings from a given DT node.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>  drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_mtd.h |    9 +++++++++
>  2 files changed, 56 insertions(+)
>
> diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
> index a27ec94..52e07fd 100644
> --- a/drivers/of/of_mtd.c
> +++ b/drivers/of/of_mtd.c
> @@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
>         return of_property_read_bool(np, "nand-on-flash-bbt");
>  }
>  EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
> +
> +/**
> + * of_get_nand_timings - Get nand timings for the given device_node
> + * @np:        Pointer to the given device_node
> + *
> + * return 0 on success errno other wise
> + */
> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> +{
> +       memset(timings, 0, sizeof(*timings));
> +
> +       of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> +       of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> +       of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> +       of_property_read_u32(np, "tCH-min", &timings->tCH_min);
> +       of_property_read_u32(np, "tWP-min", &timings->tWP_min);
> +       of_property_read_u32(np, "tALS-min", &timings->tALS_min);
> +       of_property_read_u32(np, "tALH-min", &timings->tALH_min);
> +       of_property_read_u32(np, "tDS-min", &timings->tDS_min);
> +       of_property_read_u32(np, "tDH-min", &timings->tDH_min);
> +       of_property_read_u32(np, "tWC-min", &timings->tWC_min);
> +       of_property_read_u32(np, "tWH-min", &timings->tWH_min);
> +       of_property_read_u32(np, "tR-max", &timings->tR_max);
> +       of_property_read_u32(np, "tAR-min", &timings->tAR_min);
> +       of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
> +       of_property_read_u32(np, "tRR-min", &timings->tRR_min);
> +       of_property_read_u32(np, "tRP-min", &timings->tRP_min);
> +       of_property_read_u32(np, "tWB-max", &timings->tWB_max);
> +       of_property_read_u32(np, "tRC-min", &timings->tRC_min);
> +       of_property_read_u32(np, "tREA-max", &timings->tREA_max);
> +       of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
> +       of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
> +       of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
> +       of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
> +       of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
> +       of_property_read_u32(np, "tREH-min", &timings->tREH_min);
> +       of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
> +       of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
> +       of_property_read_u32(np, "tIR-min", &timings->tIR_min);
> +       of_property_read_u32(np, "tCR-min", &timings->tCR_min);
> +       of_property_read_u32(np, "tADL-min", &timings->tADL_min);
> +       of_property_read_u32(np, "tRST-max", &timings->tRST_max);
> +       of_property_read_u32(np, "tWW-min", &timings->tWW_min);

These all need to be documented. These apply to which compatible
strings? They should also be suffixed with the unit the property is in
(i.e. -ms, -us, -ns).

Rob

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 16:30     ` Rob Herring
  0 siblings, 0 replies; 123+ messages in thread
From: Rob Herring @ 2014-01-08 16:30 UTC (permalink / raw)
  To: Boris BREZILLON
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On Wed, Jan 8, 2014 at 8:21 AM, Boris BREZILLON <b.brezillon@overkiz.com> wrote:
> Add a function to retrieve NAND timings from a given DT node.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>  drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_mtd.h |    9 +++++++++
>  2 files changed, 56 insertions(+)
>
> diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
> index a27ec94..52e07fd 100644
> --- a/drivers/of/of_mtd.c
> +++ b/drivers/of/of_mtd.c
> @@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
>         return of_property_read_bool(np, "nand-on-flash-bbt");
>  }
>  EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
> +
> +/**
> + * of_get_nand_timings - Get nand timings for the given device_node
> + * @np:        Pointer to the given device_node
> + *
> + * return 0 on success errno other wise
> + */
> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> +{
> +       memset(timings, 0, sizeof(*timings));
> +
> +       of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> +       of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> +       of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> +       of_property_read_u32(np, "tCH-min", &timings->tCH_min);
> +       of_property_read_u32(np, "tWP-min", &timings->tWP_min);
> +       of_property_read_u32(np, "tALS-min", &timings->tALS_min);
> +       of_property_read_u32(np, "tALH-min", &timings->tALH_min);
> +       of_property_read_u32(np, "tDS-min", &timings->tDS_min);
> +       of_property_read_u32(np, "tDH-min", &timings->tDH_min);
> +       of_property_read_u32(np, "tWC-min", &timings->tWC_min);
> +       of_property_read_u32(np, "tWH-min", &timings->tWH_min);
> +       of_property_read_u32(np, "tR-max", &timings->tR_max);
> +       of_property_read_u32(np, "tAR-min", &timings->tAR_min);
> +       of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
> +       of_property_read_u32(np, "tRR-min", &timings->tRR_min);
> +       of_property_read_u32(np, "tRP-min", &timings->tRP_min);
> +       of_property_read_u32(np, "tWB-max", &timings->tWB_max);
> +       of_property_read_u32(np, "tRC-min", &timings->tRC_min);
> +       of_property_read_u32(np, "tREA-max", &timings->tREA_max);
> +       of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
> +       of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
> +       of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
> +       of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
> +       of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
> +       of_property_read_u32(np, "tREH-min", &timings->tREH_min);
> +       of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
> +       of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
> +       of_property_read_u32(np, "tIR-min", &timings->tIR_min);
> +       of_property_read_u32(np, "tCR-min", &timings->tCR_min);
> +       of_property_read_u32(np, "tADL-min", &timings->tADL_min);
> +       of_property_read_u32(np, "tRST-max", &timings->tRST_max);
> +       of_property_read_u32(np, "tWW-min", &timings->tWW_min);

These all need to be documented. These apply to which compatible
strings? They should also be suffixed with the unit the property is in
(i.e. -ms, -us, -ns).

Rob

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 16:30     ` Rob Herring
  0 siblings, 0 replies; 123+ messages in thread
From: Rob Herring @ 2014-01-08 16:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 8, 2014 at 8:21 AM, Boris BREZILLON <b.brezillon@overkiz.com> wrote:
> Add a function to retrieve NAND timings from a given DT node.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>  drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_mtd.h |    9 +++++++++
>  2 files changed, 56 insertions(+)
>
> diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
> index a27ec94..52e07fd 100644
> --- a/drivers/of/of_mtd.c
> +++ b/drivers/of/of_mtd.c
> @@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
>         return of_property_read_bool(np, "nand-on-flash-bbt");
>  }
>  EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
> +
> +/**
> + * of_get_nand_timings - Get nand timings for the given device_node
> + * @np:        Pointer to the given device_node
> + *
> + * return 0 on success errno other wise
> + */
> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> +{
> +       memset(timings, 0, sizeof(*timings));
> +
> +       of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> +       of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> +       of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> +       of_property_read_u32(np, "tCH-min", &timings->tCH_min);
> +       of_property_read_u32(np, "tWP-min", &timings->tWP_min);
> +       of_property_read_u32(np, "tALS-min", &timings->tALS_min);
> +       of_property_read_u32(np, "tALH-min", &timings->tALH_min);
> +       of_property_read_u32(np, "tDS-min", &timings->tDS_min);
> +       of_property_read_u32(np, "tDH-min", &timings->tDH_min);
> +       of_property_read_u32(np, "tWC-min", &timings->tWC_min);
> +       of_property_read_u32(np, "tWH-min", &timings->tWH_min);
> +       of_property_read_u32(np, "tR-max", &timings->tR_max);
> +       of_property_read_u32(np, "tAR-min", &timings->tAR_min);
> +       of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
> +       of_property_read_u32(np, "tRR-min", &timings->tRR_min);
> +       of_property_read_u32(np, "tRP-min", &timings->tRP_min);
> +       of_property_read_u32(np, "tWB-max", &timings->tWB_max);
> +       of_property_read_u32(np, "tRC-min", &timings->tRC_min);
> +       of_property_read_u32(np, "tREA-max", &timings->tREA_max);
> +       of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
> +       of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
> +       of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
> +       of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
> +       of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
> +       of_property_read_u32(np, "tREH-min", &timings->tREH_min);
> +       of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
> +       of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
> +       of_property_read_u32(np, "tIR-min", &timings->tIR_min);
> +       of_property_read_u32(np, "tCR-min", &timings->tCR_min);
> +       of_property_read_u32(np, "tADL-min", &timings->tADL_min);
> +       of_property_read_u32(np, "tRST-max", &timings->tRST_max);
> +       of_property_read_u32(np, "tWW-min", &timings->tWW_min);

These all need to be documented. These apply to which compatible
strings? They should also be suffixed with the unit the property is in
(i.e. -ms, -us, -ns).

Rob

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
  2014-01-08 16:30     ` Rob Herring
  (?)
  (?)
@ 2014-01-08 16:36       ` boris brezillon
  -1 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 16:36 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel

On 08/01/2014 17:30, Rob Herring wrote:
> On Wed, Jan 8, 2014 at 8:21 AM, Boris BREZILLON <b.brezillon@overkiz.com> wrote:
>> Add a function to retrieve NAND timings from a given DT node.
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
>> ---
>>   drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>>   include/linux/of_mtd.h |    9 +++++++++
>>   2 files changed, 56 insertions(+)
>>
>> diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
>> index a27ec94..52e07fd 100644
>> --- a/drivers/of/of_mtd.c
>> +++ b/drivers/of/of_mtd.c
>> @@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
>>          return of_property_read_bool(np, "nand-on-flash-bbt");
>>   }
>>   EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
>> +
>> +/**
>> + * of_get_nand_timings - Get nand timings for the given device_node
>> + * @np:        Pointer to the given device_node
>> + *
>> + * return 0 on success errno other wise
>> + */
>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>> +{
>> +       memset(timings, 0, sizeof(*timings));
>> +
>> +       of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>> +       of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>> +       of_property_read_u32(np, "tCS-min", &timings->tCS_min);
>> +       of_property_read_u32(np, "tCH-min", &timings->tCH_min);
>> +       of_property_read_u32(np, "tWP-min", &timings->tWP_min);
>> +       of_property_read_u32(np, "tALS-min", &timings->tALS_min);
>> +       of_property_read_u32(np, "tALH-min", &timings->tALH_min);
>> +       of_property_read_u32(np, "tDS-min", &timings->tDS_min);
>> +       of_property_read_u32(np, "tDH-min", &timings->tDH_min);
>> +       of_property_read_u32(np, "tWC-min", &timings->tWC_min);
>> +       of_property_read_u32(np, "tWH-min", &timings->tWH_min);
>> +       of_property_read_u32(np, "tR-max", &timings->tR_max);
>> +       of_property_read_u32(np, "tAR-min", &timings->tAR_min);
>> +       of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
>> +       of_property_read_u32(np, "tRR-min", &timings->tRR_min);
>> +       of_property_read_u32(np, "tRP-min", &timings->tRP_min);
>> +       of_property_read_u32(np, "tWB-max", &timings->tWB_max);
>> +       of_property_read_u32(np, "tRC-min", &timings->tRC_min);
>> +       of_property_read_u32(np, "tREA-max", &timings->tREA_max);
>> +       of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
>> +       of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
>> +       of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
>> +       of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
>> +       of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
>> +       of_property_read_u32(np, "tREH-min", &timings->tREH_min);
>> +       of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
>> +       of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
>> +       of_property_read_u32(np, "tIR-min", &timings->tIR_min);
>> +       of_property_read_u32(np, "tCR-min", &timings->tCR_min);
>> +       of_property_read_u32(np, "tADL-min", &timings->tADL_min);
>> +       of_property_read_u32(np, "tRST-max", &timings->tRST_max);
>> +       of_property_read_u32(np, "tWW-min", &timings->tWW_min);
> These all need to be documented.
They're document in PATCH 4/9 (but the description might be a bit
light).
> These apply to which compatible
> strings?
Actually this could apply to any nand chips.
The NAND Flash Controller driver is then responsible for converting
these values to use it.
> They should also be suffixed with the unit the property is in
> (i.e. -ms, -us, -ns).

Sure, I'll add the unit (which is -ns BTW).

Thanks.

Best Regards,

Boris
>
> Rob


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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 16:36       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 16:36 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel

On 08/01/2014 17:30, Rob Herring wrote:
> On Wed, Jan 8, 2014 at 8:21 AM, Boris BREZILLON <b.brezillon@overkiz.com> wrote:
>> Add a function to retrieve NAND timings from a given DT node.
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
>> ---
>>   drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>>   include/linux/of_mtd.h |    9 +++++++++
>>   2 files changed, 56 insertions(+)
>>
>> diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
>> index a27ec94..52e07fd 100644
>> --- a/drivers/of/of_mtd.c
>> +++ b/drivers/of/of_mtd.c
>> @@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
>>          return of_property_read_bool(np, "nand-on-flash-bbt");
>>   }
>>   EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
>> +
>> +/**
>> + * of_get_nand_timings - Get nand timings for the given device_node
>> + * @np:        Pointer to the given device_node
>> + *
>> + * return 0 on success errno other wise
>> + */
>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>> +{
>> +       memset(timings, 0, sizeof(*timings));
>> +
>> +       of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>> +       of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>> +       of_property_read_u32(np, "tCS-min", &timings->tCS_min);
>> +       of_property_read_u32(np, "tCH-min", &timings->tCH_min);
>> +       of_property_read_u32(np, "tWP-min", &timings->tWP_min);
>> +       of_property_read_u32(np, "tALS-min", &timings->tALS_min);
>> +       of_property_read_u32(np, "tALH-min", &timings->tALH_min);
>> +       of_property_read_u32(np, "tDS-min", &timings->tDS_min);
>> +       of_property_read_u32(np, "tDH-min", &timings->tDH_min);
>> +       of_property_read_u32(np, "tWC-min", &timings->tWC_min);
>> +       of_property_read_u32(np, "tWH-min", &timings->tWH_min);
>> +       of_property_read_u32(np, "tR-max", &timings->tR_max);
>> +       of_property_read_u32(np, "tAR-min", &timings->tAR_min);
>> +       of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
>> +       of_property_read_u32(np, "tRR-min", &timings->tRR_min);
>> +       of_property_read_u32(np, "tRP-min", &timings->tRP_min);
>> +       of_property_read_u32(np, "tWB-max", &timings->tWB_max);
>> +       of_property_read_u32(np, "tRC-min", &timings->tRC_min);
>> +       of_property_read_u32(np, "tREA-max", &timings->tREA_max);
>> +       of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
>> +       of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
>> +       of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
>> +       of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
>> +       of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
>> +       of_property_read_u32(np, "tREH-min", &timings->tREH_min);
>> +       of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
>> +       of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
>> +       of_property_read_u32(np, "tIR-min", &timings->tIR_min);
>> +       of_property_read_u32(np, "tCR-min", &timings->tCR_min);
>> +       of_property_read_u32(np, "tADL-min", &timings->tADL_min);
>> +       of_property_read_u32(np, "tRST-max", &timings->tRST_max);
>> +       of_property_read_u32(np, "tWW-min", &timings->tWW_min);
> These all need to be documented.
They're document in PATCH 4/9 (but the description might be a bit
light).
> These apply to which compatible
> strings?
Actually this could apply to any nand chips.
The NAND Flash Controller driver is then responsible for converting
these values to use it.
> They should also be suffixed with the unit the property is in
> (i.e. -ms, -us, -ns).

Sure, I'll add the unit (which is -ns BTW).

Thanks.

Best Regards,

Boris
>
> Rob


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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 16:36       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 16:36 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On 08/01/2014 17:30, Rob Herring wrote:
> On Wed, Jan 8, 2014 at 8:21 AM, Boris BREZILLON <b.brezillon@overkiz.com> wrote:
>> Add a function to retrieve NAND timings from a given DT node.
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
>> ---
>>   drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>>   include/linux/of_mtd.h |    9 +++++++++
>>   2 files changed, 56 insertions(+)
>>
>> diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
>> index a27ec94..52e07fd 100644
>> --- a/drivers/of/of_mtd.c
>> +++ b/drivers/of/of_mtd.c
>> @@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
>>          return of_property_read_bool(np, "nand-on-flash-bbt");
>>   }
>>   EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
>> +
>> +/**
>> + * of_get_nand_timings - Get nand timings for the given device_node
>> + * @np:        Pointer to the given device_node
>> + *
>> + * return 0 on success errno other wise
>> + */
>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>> +{
>> +       memset(timings, 0, sizeof(*timings));
>> +
>> +       of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>> +       of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>> +       of_property_read_u32(np, "tCS-min", &timings->tCS_min);
>> +       of_property_read_u32(np, "tCH-min", &timings->tCH_min);
>> +       of_property_read_u32(np, "tWP-min", &timings->tWP_min);
>> +       of_property_read_u32(np, "tALS-min", &timings->tALS_min);
>> +       of_property_read_u32(np, "tALH-min", &timings->tALH_min);
>> +       of_property_read_u32(np, "tDS-min", &timings->tDS_min);
>> +       of_property_read_u32(np, "tDH-min", &timings->tDH_min);
>> +       of_property_read_u32(np, "tWC-min", &timings->tWC_min);
>> +       of_property_read_u32(np, "tWH-min", &timings->tWH_min);
>> +       of_property_read_u32(np, "tR-max", &timings->tR_max);
>> +       of_property_read_u32(np, "tAR-min", &timings->tAR_min);
>> +       of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
>> +       of_property_read_u32(np, "tRR-min", &timings->tRR_min);
>> +       of_property_read_u32(np, "tRP-min", &timings->tRP_min);
>> +       of_property_read_u32(np, "tWB-max", &timings->tWB_max);
>> +       of_property_read_u32(np, "tRC-min", &timings->tRC_min);
>> +       of_property_read_u32(np, "tREA-max", &timings->tREA_max);
>> +       of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
>> +       of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
>> +       of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
>> +       of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
>> +       of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
>> +       of_property_read_u32(np, "tREH-min", &timings->tREH_min);
>> +       of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
>> +       of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
>> +       of_property_read_u32(np, "tIR-min", &timings->tIR_min);
>> +       of_property_read_u32(np, "tCR-min", &timings->tCR_min);
>> +       of_property_read_u32(np, "tADL-min", &timings->tADL_min);
>> +       of_property_read_u32(np, "tRST-max", &timings->tRST_max);
>> +       of_property_read_u32(np, "tWW-min", &timings->tWW_min);
> These all need to be documented.
They're document in PATCH 4/9 (but the description might be a bit
light).
> These apply to which compatible
> strings?
Actually this could apply to any nand chips.
The NAND Flash Controller driver is then responsible for converting
these values to use it.
> They should also be suffixed with the unit the property is in
> (i.e. -ms, -us, -ns).

Sure, I'll add the unit (which is -ns BTW).

Thanks.

Best Regards,

Boris
>
> Rob

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 16:36       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 16:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/01/2014 17:30, Rob Herring wrote:
> On Wed, Jan 8, 2014 at 8:21 AM, Boris BREZILLON <b.brezillon@overkiz.com> wrote:
>> Add a function to retrieve NAND timings from a given DT node.
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
>> ---
>>   drivers/of/of_mtd.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>>   include/linux/of_mtd.h |    9 +++++++++
>>   2 files changed, 56 insertions(+)
>>
>> diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
>> index a27ec94..52e07fd 100644
>> --- a/drivers/of/of_mtd.c
>> +++ b/drivers/of/of_mtd.c
>> @@ -83,3 +83,50 @@ bool of_get_nand_on_flash_bbt(struct device_node *np)
>>          return of_property_read_bool(np, "nand-on-flash-bbt");
>>   }
>>   EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
>> +
>> +/**
>> + * of_get_nand_timings - Get nand timings for the given device_node
>> + * @np:        Pointer to the given device_node
>> + *
>> + * return 0 on success errno other wise
>> + */
>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>> +{
>> +       memset(timings, 0, sizeof(*timings));
>> +
>> +       of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>> +       of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>> +       of_property_read_u32(np, "tCS-min", &timings->tCS_min);
>> +       of_property_read_u32(np, "tCH-min", &timings->tCH_min);
>> +       of_property_read_u32(np, "tWP-min", &timings->tWP_min);
>> +       of_property_read_u32(np, "tALS-min", &timings->tALS_min);
>> +       of_property_read_u32(np, "tALH-min", &timings->tALH_min);
>> +       of_property_read_u32(np, "tDS-min", &timings->tDS_min);
>> +       of_property_read_u32(np, "tDH-min", &timings->tDH_min);
>> +       of_property_read_u32(np, "tWC-min", &timings->tWC_min);
>> +       of_property_read_u32(np, "tWH-min", &timings->tWH_min);
>> +       of_property_read_u32(np, "tR-max", &timings->tR_max);
>> +       of_property_read_u32(np, "tAR-min", &timings->tAR_min);
>> +       of_property_read_u32(np, "tCLR-min", &timings->tCLR_min);
>> +       of_property_read_u32(np, "tRR-min", &timings->tRR_min);
>> +       of_property_read_u32(np, "tRP-min", &timings->tRP_min);
>> +       of_property_read_u32(np, "tWB-max", &timings->tWB_max);
>> +       of_property_read_u32(np, "tRC-min", &timings->tRC_min);
>> +       of_property_read_u32(np, "tREA-max", &timings->tREA_max);
>> +       of_property_read_u32(np, "tRHZ-max", &timings->tRHZ_max);
>> +       of_property_read_u32(np, "tCHZ-max", &timings->tCHZ_max);
>> +       of_property_read_u32(np, "tRHOH-min", &timings->tRHOH_min);
>> +       of_property_read_u32(np, "tRLOH-min", &timings->tRLOH_min);
>> +       of_property_read_u32(np, "tCOH-min", &timings->tCOH_min);
>> +       of_property_read_u32(np, "tREH-min", &timings->tREH_min);
>> +       of_property_read_u32(np, "tWHR-min", &timings->tWHR_min);
>> +       of_property_read_u32(np, "tRHW-min", &timings->tRHW_min);
>> +       of_property_read_u32(np, "tIR-min", &timings->tIR_min);
>> +       of_property_read_u32(np, "tCR-min", &timings->tCR_min);
>> +       of_property_read_u32(np, "tADL-min", &timings->tADL_min);
>> +       of_property_read_u32(np, "tRST-max", &timings->tRST_max);
>> +       of_property_read_u32(np, "tWW-min", &timings->tWW_min);
> These all need to be documented.
They're document in PATCH 4/9 (but the description might be a bit
light).
> These apply to which compatible
> strings?
Actually this could apply to any nand chips.
The NAND Flash Controller driver is then responsible for converting
these values to use it.
> They should also be suffixed with the unit the property is in
> (i.e. -ms, -us, -ns).

Sure, I'll add the unit (which is -ns BTW).

Thanks.

Best Regards,

Boris
>
> Rob

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
  2014-01-08 14:21   ` Boris BREZILLON
  (?)
@ 2014-01-08 18:34     ` Jason Gunthorpe
  -1 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-08 18:34 UTC (permalink / raw)
  To: Boris BREZILLON
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel

On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:

> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> +{
> +	memset(timings, 0, sizeof(*timings));
> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
[..]

A while ago when discussing another controller it was pointed out
these values are all auto-probable directly from the NAND via a ONFI
defined GET FEATURE @0x01 query, and adding these timings to the DT
was NAK'd..

Basically you set the interface to the slowest ONFI timing mode, do
the GET FEATURE to the NAND chip and then increase the interface speed
to the highest mutually supported ONFI mode.

Is there some reason you need to encode this in the DT?

Jason

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 18:34     ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-08 18:34 UTC (permalink / raw)
  To: Boris BREZILLON
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:

> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> +{
> +	memset(timings, 0, sizeof(*timings));
> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
[..]

A while ago when discussing another controller it was pointed out
these values are all auto-probable directly from the NAND via a ONFI
defined GET FEATURE @0x01 query, and adding these timings to the DT
was NAK'd..

Basically you set the interface to the slowest ONFI timing mode, do
the GET FEATURE to the NAND chip and then increase the interface speed
to the highest mutually supported ONFI mode.

Is there some reason you need to encode this in the DT?

Jason

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 18:34     ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-08 18:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:

> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> +{
> +	memset(timings, 0, sizeof(*timings));
> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
[..]

A while ago when discussing another controller it was pointed out
these values are all auto-probable directly from the NAND via a ONFI
defined GET FEATURE @0x01 query, and adding these timings to the DT
was NAK'd..

Basically you set the interface to the slowest ONFI timing mode, do
the GET FEATURE to the NAND chip and then increase the interface speed
to the highest mutually supported ONFI mode.

Is there some reason you need to encode this in the DT?

Jason

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 19:00       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 19:00 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel

Hello Jason,

Le 08/01/2014 19:34, Jason Gunthorpe a écrit :
> On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
>
>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>> +{
>> +	memset(timings, 0, sizeof(*timings));
>> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> [..]
>
> A while ago when discussing another controller it was pointed out
> these values are all auto-probable directly from the NAND via a ONFI
> defined GET FEATURE @0x01 query, and adding these timings to the DT
> was NAK'd..
>
> Basically you set the interface to the slowest ONFI timing mode, do
> the GET FEATURE to the NAND chip and then increase the interface speed
> to the highest mutually supported ONFI mode.

> Is there some reason you need to encode this in the DT?

What if the NAND does not support the ONFI interface (and this is
exactly the case for the NAND available on the cubietruck board:
H27UCG8T2ATR).

But I'm glag to hear about this ONFI feature :).
I'll add a function to retrieve these timings if the NAND support
the ONFI interface.

Best Regards,

Boris
>
> Jason


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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 19:00       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 19:00 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, dev-3kdeTeqwOZ9EV1b7eY7vFQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hello Jason,

Le 08/01/2014 19:34, Jason Gunthorpe a écrit :
> On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
>
>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>> +{
>> +	memset(timings, 0, sizeof(*timings));
>> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> [..]
>
> A while ago when discussing another controller it was pointed out
> these values are all auto-probable directly from the NAND via a ONFI
> defined GET FEATURE @0x01 query, and adding these timings to the DT
> was NAK'd..
>
> Basically you set the interface to the slowest ONFI timing mode, do
> the GET FEATURE to the NAND chip and then increase the interface speed
> to the highest mutually supported ONFI mode.

> Is there some reason you need to encode this in the DT?

What if the NAND does not support the ONFI interface (and this is
exactly the case for the NAND available on the cubietruck board:
H27UCG8T2ATR).

But I'm glag to hear about this ONFI feature :).
I'll add a function to retrieve these timings if the NAND support
the ONFI interface.

Best Regards,

Boris
>
> Jason

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 19:00       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 19:00 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

Hello Jason,

Le 08/01/2014 19:34, Jason Gunthorpe a écrit :
> On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
>
>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>> +{
>> +	memset(timings, 0, sizeof(*timings));
>> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> [..]
>
> A while ago when discussing another controller it was pointed out
> these values are all auto-probable directly from the NAND via a ONFI
> defined GET FEATURE @0x01 query, and adding these timings to the DT
> was NAK'd..
>
> Basically you set the interface to the slowest ONFI timing mode, do
> the GET FEATURE to the NAND chip and then increase the interface speed
> to the highest mutually supported ONFI mode.

> Is there some reason you need to encode this in the DT?

What if the NAND does not support the ONFI interface (and this is
exactly the case for the NAND available on the cubietruck board:
H27UCG8T2ATR).

But I'm glag to hear about this ONFI feature :).
I'll add a function to retrieve these timings if the NAND support
the ONFI interface.

Best Regards,

Boris
>
> Jason

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 19:00       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 19:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Jason,

Le 08/01/2014 19:34, Jason Gunthorpe a ?crit :
> On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
>
>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>> +{
>> +	memset(timings, 0, sizeof(*timings));
>> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> [..]
>
> A while ago when discussing another controller it was pointed out
> these values are all auto-probable directly from the NAND via a ONFI
> defined GET FEATURE @0x01 query, and adding these timings to the DT
> was NAK'd..
>
> Basically you set the interface to the slowest ONFI timing mode, do
> the GET FEATURE to the NAND chip and then increase the interface speed
> to the highest mutually supported ONFI mode.

> Is there some reason you need to encode this in the DT?

What if the NAND does not support the ONFI interface (and this is
exactly the case for the NAND available on the cubietruck board:
H27UCG8T2ATR).

But I'm glag to hear about this ONFI feature :).
I'll add a function to retrieve these timings if the NAND support
the ONFI interface.

Best Regards,

Boris
>
> Jason

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 19:13         ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-08 19:13 UTC (permalink / raw)
  To: boris brezillon
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel

On Wed, Jan 08, 2014 at 08:00:02PM +0100, boris brezillon wrote:
> Hello Jason,
> 
> Le 08/01/2014 19:34, Jason Gunthorpe a ?crit :
> >On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
> >
> >>+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> >>+{
> >>+	memset(timings, 0, sizeof(*timings));
> >>+	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> >>+	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> >>+	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> >[..]
> >
> >A while ago when discussing another controller it was pointed out
> >these values are all auto-probable directly from the NAND via a ONFI
> >defined GET FEATURE @0x01 query, and adding these timings to the DT
> >was NAK'd..
> >
> >Basically you set the interface to the slowest ONFI timing mode, do
> >the GET FEATURE to the NAND chip and then increase the interface speed
> >to the highest mutually supported ONFI mode.
> 
> >Is there some reason you need to encode this in the DT?
> 
> What if the NAND does not support the ONFI interface (and this is
> exactly the case for the NAND available on the cubietruck board:
> H27UCG8T2ATR).

Sounds like a good reason to me! 

You might want to check if you can boil down the DT timings from the
huge list to just an ONFI mode number..

I'd echo Rob's comments, the property needs to include the units
in the name, and I strongly recommend picoseconds for these
values.

Also, you might want to check that the ONFI names for these parameters
are used, not a vendor specific name to try and avoid confusion.

Jason

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 19:13         ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-08 19:13 UTC (permalink / raw)
  To: boris brezillon
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, dev-3kdeTeqwOZ9EV1b7eY7vFQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wed, Jan 08, 2014 at 08:00:02PM +0100, boris brezillon wrote:
> Hello Jason,
> 
> Le 08/01/2014 19:34, Jason Gunthorpe a ?crit :
> >On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
> >
> >>+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> >>+{
> >>+	memset(timings, 0, sizeof(*timings));
> >>+	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> >>+	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> >>+	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> >[..]
> >
> >A while ago when discussing another controller it was pointed out
> >these values are all auto-probable directly from the NAND via a ONFI
> >defined GET FEATURE @0x01 query, and adding these timings to the DT
> >was NAK'd..
> >
> >Basically you set the interface to the slowest ONFI timing mode, do
> >the GET FEATURE to the NAND chip and then increase the interface speed
> >to the highest mutually supported ONFI mode.
> 
> >Is there some reason you need to encode this in the DT?
> 
> What if the NAND does not support the ONFI interface (and this is
> exactly the case for the NAND available on the cubietruck board:
> H27UCG8T2ATR).

Sounds like a good reason to me! 

You might want to check if you can boil down the DT timings from the
huge list to just an ONFI mode number..

I'd echo Rob's comments, the property needs to include the units
in the name, and I strongly recommend picoseconds for these
values.

Also, you might want to check that the ONFI names for these parameters
are used, not a vendor specific name to try and avoid confusion.

Jason

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 19:13         ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-08 19:13 UTC (permalink / raw)
  To: boris brezillon
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On Wed, Jan 08, 2014 at 08:00:02PM +0100, boris brezillon wrote:
> Hello Jason,
> 
> Le 08/01/2014 19:34, Jason Gunthorpe a ?crit :
> >On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
> >
> >>+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> >>+{
> >>+	memset(timings, 0, sizeof(*timings));
> >>+	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> >>+	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> >>+	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> >[..]
> >
> >A while ago when discussing another controller it was pointed out
> >these values are all auto-probable directly from the NAND via a ONFI
> >defined GET FEATURE @0x01 query, and adding these timings to the DT
> >was NAK'd..
> >
> >Basically you set the interface to the slowest ONFI timing mode, do
> >the GET FEATURE to the NAND chip and then increase the interface speed
> >to the highest mutually supported ONFI mode.
> 
> >Is there some reason you need to encode this in the DT?
> 
> What if the NAND does not support the ONFI interface (and this is
> exactly the case for the NAND available on the cubietruck board:
> H27UCG8T2ATR).

Sounds like a good reason to me! 

You might want to check if you can boil down the DT timings from the
huge list to just an ONFI mode number..

I'd echo Rob's comments, the property needs to include the units
in the name, and I strongly recommend picoseconds for these
values.

Also, you might want to check that the ONFI names for these parameters
are used, not a vendor specific name to try and avoid confusion.

Jason

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-08 19:13         ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-08 19:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 08, 2014 at 08:00:02PM +0100, boris brezillon wrote:
> Hello Jason,
> 
> Le 08/01/2014 19:34, Jason Gunthorpe a ?crit :
> >On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
> >
> >>+int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
> >>+{
> >>+	memset(timings, 0, sizeof(*timings));
> >>+	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
> >>+	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
> >>+	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
> >[..]
> >
> >A while ago when discussing another controller it was pointed out
> >these values are all auto-probable directly from the NAND via a ONFI
> >defined GET FEATURE @0x01 query, and adding these timings to the DT
> >was NAK'd..
> >
> >Basically you set the interface to the slowest ONFI timing mode, do
> >the GET FEATURE to the NAND chip and then increase the interface speed
> >to the highest mutually supported ONFI mode.
> 
> >Is there some reason you need to encode this in the DT?
> 
> What if the NAND does not support the ONFI interface (and this is
> exactly the case for the NAND available on the cubietruck board:
> H27UCG8T2ATR).

Sounds like a good reason to me! 

You might want to check if you can boil down the DT timings from the
huge list to just an ONFI mode number..

I'd echo Rob's comments, the property needs to include the units
in the name, and I strongly recommend picoseconds for these
values.

Also, you might want to check that the ONFI names for these parameters
are used, not a vendor specific name to try and avoid confusion.

Jason

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

* Re: [RFC PATCH 5/9] mtd: nand: add sunxi NFC support
  2014-01-08 14:22   ` Boris BREZILLON
  (?)
@ 2014-01-08 19:21     ` boris brezillon
  -1 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 19:21 UTC (permalink / raw)
  To: Boris BREZILLON, Maxime Ripard, Rob Landley, Russell King,
	David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd, dev

Le 08/01/2014 15:22, Boris BREZILLON a écrit :
> Add the sunxi NAND Flash Controller driver.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>   drivers/mtd/nand/Kconfig     |    6 +
>   drivers/mtd/nand/Makefile    |    1 +
>   drivers/mtd/nand/sunxi_nfc.c |  700 ++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 707 insertions(+)
>   create mode 100644 drivers/mtd/nand/sunxi_nfc.c
>
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index 93ae6a6..784dd42 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -510,4 +510,10 @@ config MTD_NAND_XWAY
>   	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
>   	  to the External Bus Unit (EBU).
>   
> +config MTD_NAND_SUNXI
> +	tristate "Support for NAND on Allwinner SoCs"
> +	depends on ARCH_SUNXI
> +	help
> +	  Enables support for NAND Flash chips on Allwinner SoCs.
> +
>   endif # MTD_NAND
> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> index 542b568..e8b210d 100644
> --- a/drivers/mtd/nand/Makefile
> +++ b/drivers/mtd/nand/Makefile
> @@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
>   obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
>   obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
>   obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
> +obj-$(CONFIG_MTD_NAND_SUNXI)	+= sunxi_nfc.o
>   

BTW, I recently was one of the sources of a merge issue in the clk
subsystem because of unsorted Makefile lines.
Shouldn't we try to sort this Makefile too ?

>   nand-objs := nand_base.o nand_bbt.o
> diff --git a/drivers/mtd/nand/sunxi_nfc.c b/drivers/mtd/nand/sunxi_nfc.c
> new file mode 100644
> index 0000000..1c7a511
> --- /dev/null
> +++ b/drivers/mtd/nand/sunxi_nfc.c
> @@ -0,0 +1,700 @@
> +/*
> + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
> + *
> + * Derived from Qiang Yu work:
> + *	https://github.com/yuq/sunxi-nfc-mtd
> + *	Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/dma-mapping.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_mtd.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/nand.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/dmaengine.h>
> +#include <linux/gpio.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +
> +#define NFC_REG_CTL		0x0000
> +#define NFC_REG_ST		0x0004
> +#define NFC_REG_INT		0x0008
> +#define NFC_REG_TIMING_CTL	0x000C
> +#define NFC_REG_TIMING_CFG	0x0010
> +#define NFC_REG_ADDR_LOW	0x0014
> +#define NFC_REG_ADDR_HIGH	0x0018
> +#define NFC_REG_SECTOR_NUM	0x001C
> +#define NFC_REG_CNT		0x0020
> +#define NFC_REG_CMD		0x0024
> +#define NFC_REG_RCMD_SET	0x0028
> +#define NFC_REG_WCMD_SET	0x002C
> +#define NFC_REG_IO_DATA		0x0030
> +#define NFC_REG_ECC_CTL		0x0034
> +#define NFC_REG_ECC_ST		0x0038
> +#define NFC_REG_DEBUG		0x003C
> +#define NFC_REG_ECC_CNT0	0x0040
> +#define NFC_REG_ECC_CNT1	0x0044
> +#define NFC_REG_ECC_CNT2	0x0048
> +#define NFC_REG_ECC_CNT3	0x004c
> +#define NFC_REG_USER_DATA_BASE	0x0050
> +#define NFC_REG_SPARE_AREA	0x00A0
> +#define NFC_RAM0_BASE		0x0400
> +#define NFC_RAM1_BASE		0x0800
> +
> +/*define bit use in NFC_CTL*/
> +#define NFC_EN				(1 << 0)
> +#define NFC_RESET			(1 << 1)
> +#define NFC_BUS_WIDYH			(1 << 2)
> +#define NFC_RB_SEL			(1 << 3)
> +#define NFC_CE_SEL			(7 << 24)
> +#define NFC_CE_CTL			(1 << 6)
> +#define NFC_CE_CTL1			(1 << 7)
> +#define NFC_PAGE_SIZE			(0xf << 8)
> +#define NFC_SAM				(1 << 12)
> +#define NFC_RAM_METHOD			(1 << 14)
> +#define NFC_DEBUG_CTL			(1 << 31)
> +
> +/*define bit use in NFC_ST*/
> +#define NFC_RB_B2R			(1 << 0)
> +#define NFC_CMD_INT_FLAG		(1 << 1)
> +#define NFC_DMA_INT_FLAG		(1 << 2)
> +#define NFC_CMD_FIFO_STATUS		(1 << 3)
> +#define NFC_STA				(1 << 4)
> +#define NFC_NATCH_INT_FLAG		(1 << 5)
> +#define NFC_RB_STATE0			(1 << 8)
> +#define NFC_RB_STATE1			(1 << 9)
> +#define NFC_RB_STATE2			(1 << 10)
> +#define NFC_RB_STATE3			(1 << 11)
> +
> +/*define bit use in NFC_INT*/
> +#define NFC_B2R_INT_ENABLE		(1 << 0)
> +#define NFC_CMD_INT_ENABLE		(1 << 1)
> +#define NFC_DMA_INT_ENABLE		(1 << 2)
> +#define NFC_INT_MASK			(NFC_B2R_INT_ENABLE | \
> +					 NFC_CMD_INT_ENABLE | \
> +					 NFC_DMA_INT_ENABLE)
> +
> +
> +/*define bit use in NFC_CMD*/
> +#define NFC_CMD_LOW_BYTE		(0xff << 0)
> +#define NFC_CMD_HIGH_BYTE		(0xff << 8)
> +#define NFC_ADR_NUM			(0x7 << 16)
> +#define NFC_SEND_ADR			(1 << 19)
> +#define NFC_ACCESS_DIR			(1 << 20)
> +#define NFC_DATA_TRANS			(1 << 21)
> +#define NFC_SEND_CMD1			(1 << 22)
> +#define NFC_WAIT_FLAG			(1 << 23)
> +#define NFC_SEND_CMD2			(1 << 24)
> +#define NFC_SEQ				(1 << 25)
> +#define NFC_DATA_SWAP_METHOD		(1 << 26)
> +#define NFC_ROW_AUTO_INC		(1 << 27)
> +#define NFC_SEND_CMD3			(1 << 28)
> +#define NFC_SEND_CMD4			(1 << 29)
> +#define NFC_CMD_TYPE			(3 << 30)
> +
> +/* define bit use in NFC_RCMD_SET*/
> +#define NFC_READ_CMD			(0xff << 0)
> +#define NFC_RANDOM_READ_CMD0		(0xff << 8)
> +#define NFC_RANDOM_READ_CMD1		(0xff << 16)
> +
> +/*define bit use in NFC_WCMD_SET*/
> +#define NFC_PROGRAM_CMD			(0xff << 0)
> +#define NFC_RANDOM_WRITE_CMD		(0xff << 8)
> +#define NFC_READ_CMD0			(0xff << 16)
> +#define NFC_READ_CMD1			(0xff << 24)
> +
> +/*define bit use in NFC_ECC_CTL*/
> +#define NFC_ECC_EN			(1 << 0)
> +#define NFC_ECC_PIPELINE		(1 << 3)
> +#define NFC_ECC_EXCEPTION		(1 << 4)
> +#define NFC_ECC_BLOCK_SIZE		(1 << 5)
> +#define NFC_RANDOM_EN			(1 << 9)
> +#define NFC_RANDOM_DIRECTION		(1 << 10)
> +#define NFC_ECC_MODE_SHIFT		12
> +#define NFC_ECC_MODE			(0xf << NFC_ECC_MODE_SHIFT)
> +#define NFC_RANDOM_SEED			(0x7fff << 16)
> +
> +
> +
> +enum sunxi_nand_rb_type {
> +	RB_NONE,
> +	RB_NATIVE,
> +	RB_GPIO,
> +};
> +
> +struct sunxi_nand_rb {
> +	enum sunxi_nand_rb_type type;
> +	union {
> +		int gpio;
> +		int nativeid;
> +	} info;
> +};
> +
> +struct sunxi_nand_chip_sel {
> +	u8 cs;
> +	struct sunxi_nand_rb rb;
> +};
> +
> +#define DEFAULT_NAME_FORMAT	"nand@%d"
> +#define MAX_NAME_SIZE		(sizeof("nand@") + 2)
> +
> +struct sunxi_nand_chip {
> +	struct list_head node;
> +	struct nand_chip nand;
> +	struct mtd_info mtd;
> +	char default_name[MAX_NAME_SIZE];
> +	unsigned long clk_rate;
> +	int selected;
> +	int nsels;
> +	struct sunxi_nand_chip_sel sels[0];
> +};
> +
> +static inline struct sunxi_nand_chip *to_sunxi_nand(struct mtd_info *mtd)
> +{
> +	return container_of(mtd, struct sunxi_nand_chip, mtd);
> +}
> +
> +struct sunxi_nfc {
> +	struct nand_hw_control controller;
> +	void __iomem *regs;
> +	int irq;
> +	struct clk *ahb_clk;
> +	struct clk *sclk;
> +	unsigned long assigned_cs;
> +	struct list_head chips;
> +	struct completion complete;
> +};
> +
> +static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
> +{
> +	return container_of(ctrl, struct sunxi_nfc, controller);
> +}
> +
> +static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
> +{
> +	struct sunxi_nfc *nfc = dev_id;
> +	u32 st = readl(nfc->regs + NFC_REG_ST);
> +	u32 ien = readl(nfc->regs + NFC_REG_INT);
> +
> +	if (!(ien & st))
> +		return IRQ_NONE;
> +
> +	if ((ien & st) == ien)
> +		complete(&nfc->complete);
> +
> +	writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
> +	writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
> +			      unsigned int timeout_ms)
> +{
> +	init_completion(&nfc->complete);
> +
> +	writel(flags, nfc->regs + NFC_REG_INT);
> +	if (!timeout_ms)
> +		wait_for_completion(&nfc->complete);
> +	else if (!wait_for_completion_timeout(&nfc->complete,
> +					      msecs_to_jiffies(timeout_ms)))
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +
> +static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	struct sunxi_nand_rb *rb;
> +	unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
> +	int ret;
> +
> +	if (sunxi_nand->selected < 0)
> +		return 0;
> +
> +	rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
> +
> +	switch (rb->type) {
> +	case RB_NATIVE:
> +		ret = !!(readl(nfc->regs + NFC_REG_ST) &
> +			 (NFC_RB_STATE0 << rb->info.nativeid));
> +		if (ret)
> +			break;
> +
> +		sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
> +		ret = !!(readl(nfc->regs + NFC_REG_ST) &
> +			 (NFC_RB_STATE0 << rb->info.nativeid));
> +		break;
> +	case RB_GPIO:
> +		ret = gpio_get_value(rb->info.gpio);
> +		break;
> +	case RB_NONE:
> +	default:
> +		ret = 0;
> +		dev_err(&mtd->dev, "cannot check R/B NAND status!");
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	struct sunxi_nand_chip_sel *sel;
> +	u32 ctl;
> +
> +	if (chip > 0 && chip >= sunxi_nand->nsels)
> +		return;
> +
> +	if (chip == sunxi_nand->selected)
> +		return;
> +
> +	ctl = readl(nfc->regs + NFC_REG_CTL) &
> +	      ~(NFC_CE_SEL | NFC_RB_SEL | NFC_EN);
> +
> +	if (chip >= 0) {
> +		sel = &sunxi_nand->sels[chip];
> +
> +		ctl |= (sel->cs << 24) | NFC_EN |
> +		       (((sunxi_nand->nand.page_shift - 10) & 0xf) << 8);
> +		if (sel->rb.type == RB_NONE) {
> +			sunxi_nand->nand.dev_ready = NULL;
> +		} else {
> +			sunxi_nand->nand.dev_ready = sunxi_nfc_dev_ready;
> +			if (sel->rb.type == RB_NATIVE)
> +				ctl |= (sel->rb.info.nativeid << 3);
> +		}
> +	}
> +
> +	writel(ctl, nfc->regs + NFC_REG_CTL);
> +	clk_set_rate(nfc->sclk, sunxi_nand->clk_rate);
> +
> +	sunxi_nand->selected = chip;
> +}
> +
> +static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	int cnt;
> +	int offs = 0;
> +
> +	while (len > 0) {
> +		cnt = len > 1024 ? 1024 : len;
> +		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
> +			;
> +		writel(cnt, nfc->regs + NFC_REG_CNT);
> +		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_SEQ,
> +		       nfc->regs + NFC_REG_CMD);
> +		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
> +		memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, cnt);
> +		offs += cnt;
> +		len -= cnt;
> +	}
> +}
> +
> +static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
> +				int len)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	int cnt;
> +	int offs = 0;
> +
> +	while (len > 0) {
> +		cnt = len > 1024 ? 1024 : len;
> +		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
> +			;
> +		writel(cnt, nfc->regs + NFC_REG_CNT);
> +		memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
> +		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
> +		       NFC_ACCESS_DIR | NFC_SEQ, nfc->regs + NFC_REG_CMD);
> +		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
> +		offs += cnt;
> +		len -= cnt;
> +	}
> +}
> +
> +static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
> +{
> +	uint8_t ret;
> +
> +	sunxi_nfc_read_buf(mtd, &ret, 1);
> +
> +	return ret;
> +}
> +
> +static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
> +			       unsigned int ctrl)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	u32 tmp;
> +
> +	while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
> +		;
> +
> +	if (ctrl & NAND_CTRL_CHANGE) {
> +		tmp = readl(nfc->regs + NFC_REG_CTL);
> +		if (ctrl & NAND_NCE)
> +			tmp |= NFC_CE_CTL;
> +		else
> +			tmp &= ~NFC_CE_CTL;
> +		writel(tmp, nfc->regs + NFC_REG_CTL);
> +	}
> +
> +	if (dat == NAND_CMD_NONE)
> +		return;
> +
> +	if (ctrl & NAND_CLE) {
> +		writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
> +	} else {
> +		writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
> +		writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
> +	}
> +
> +	sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
> +}
> +
> +static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
> +					struct device_node *np)
> +{
> +	struct nand_timings timings;
> +	u32 min_clk_period = 0;
> +	int ret;
> +
> +	ret = of_get_nand_timings(np, &timings);
> +	if (ret)
> +		return ret;
> +
> +	/* NFC timings defined in Allwinner Datasheets */
> +
> +	/* T1 <=> tCLS */
> +	if (timings.tCLS_min > min_clk_period)
> +		min_clk_period = timings.tCLS_min;
> +
> +	/* T2 <=> tCLH */
> +	if (timings.tCLH_min > min_clk_period)
> +		min_clk_period = timings.tCLH_min;
> +
> +	/* T3 <=> tCS */
> +	if (timings.tCS_min > min_clk_period)
> +		min_clk_period = timings.tCS_min;
> +
> +	/* T4 <=> tCH */
> +	if (timings.tCH_min > min_clk_period)
> +		min_clk_period = timings.tCH_min;
> +
> +	/* T5 <=> tWP */
> +	if (timings.tWP_min > min_clk_period)
> +		min_clk_period = timings.tWP_min;
> +
> +	/* T6 <=> tWH */
> +	if (timings.tWH_min > min_clk_period)
> +		min_clk_period = timings.tWH_min;
> +
> +	/* T7 <=> tALS */
> +	if (timings.tALS_min > min_clk_period)
> +		min_clk_period = timings.tALS_min;
> +
> +	/* T8 <=> tDS */
> +	if (timings.tDS_min > min_clk_period)
> +		min_clk_period = timings.tDS_min;
> +
> +	/* T9 <=> tDH */
> +	if (timings.tDH_min > min_clk_period)
> +		min_clk_period = timings.tDH_min;
> +
> +	/* T10 <=> tRR */
> +	if (timings.tRR_min > (min_clk_period * 3))
> +		min_clk_period = (timings.tRR_min + 2) / 3;
> +
> +	/* T11 <=> tALH */
> +	if (timings.tALH_min > min_clk_period)
> +		min_clk_period = timings.tALH_min;
> +
> +	/* T12 <=> tRP */
> +	if (timings.tRP_min > min_clk_period)
> +		min_clk_period = timings.tRP_min;
> +
> +	/* T13 <=> tREH */
> +	if (timings.tREH_min > min_clk_period)
> +		min_clk_period = timings.tREH_min;
> +
> +	/* T14 <=> tRC */
> +	if (timings.tRC_min > (min_clk_period * 2))
> +		min_clk_period = (timings.tRC_min + 1) / 2;
> +
> +	/* T15 <=> tWC */
> +	if (timings.tWC_min > (min_clk_period * 2))
> +		min_clk_period = (timings.tWC_min + 1) / 2;
> +
> +
> +	/* min_clk_period = (NAND-clk-period * 2) */
> +	if (!min_clk_period)
> +		chip->clk_rate = 20000000;
> +	else
> +		chip->clk_rate = (2 * 1000000000) / min_clk_period;
> +
> +	/* TODO: configure T16-T19 */
> +
> +	return 0;
> +}
> +
> +static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
> +				struct device_node *np)
> +{
> +	struct sunxi_nand_chip *chip;
> +	struct mtd_part_parser_data ppdata;
> +	struct mtd_info *mtd;
> +	struct nand_chip *nand;
> +	int nsels;
> +	int ret;
> +	int i;
> +	u32 tmp;
> +
> +	if (!of_get_property(np, "reg", &nsels))
> +		return -EINVAL;
> +
> +	nsels /= sizeof(u32);
> +	if (!nsels)
> +		return -EINVAL;
> +
> +	chip = devm_kzalloc(dev,
> +			    sizeof(*chip) +
> +			    (nsels * sizeof(struct sunxi_nand_chip_sel)),
> +			    GFP_KERNEL);
> +	if (!chip)
> +		return -ENOMEM;
> +
> +	chip->nsels = nsels;
> +	chip->selected = -1;
> +
> +	for (i = 0; i < nsels; i++) {
> +		ret = of_property_read_u32_index(np, "reg", i, &tmp);
> +		if (ret)
> +			return ret;
> +
> +		if (tmp > 7)
> +			return -EINVAL;
> +
> +		if (test_and_set_bit(tmp, &nfc->assigned_cs))
> +			return -EINVAL;
> +
> +		chip->sels[i].cs = tmp;
> +
> +		if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
> +		    tmp < 2) {
> +			chip->sels[i].rb.type = RB_NATIVE;
> +			chip->sels[i].rb.info.nativeid = tmp;
> +		} else {
> +			ret = of_get_named_gpio(np, "rb-gpios", i);
> +			if (ret >= 0) {
> +				chip->sels[i].rb.type = RB_GPIO;
> +				chip->sels[i].rb.info.gpio = tmp;
> +				ret = devm_gpio_request(dev, tmp, "nand-rb");
> +				if (ret)
> +					return ret;
> +			} else {
> +				chip->sels[i].rb.type = RB_NONE;
> +			}
> +		}
> +	}
> +
> +	ret = sunxi_nand_chip_init_timings(chip, np);
> +	if (ret)
> +		return ret;
> +
> +	nand = &chip->nand;
> +	nand->IO_ADDR_R = nand->IO_ADDR_W = nfc->regs + NFC_REG_IO_DATA;
> +	nand->controller = &nfc->controller;
> +	nand->select_chip = sunxi_nfc_select_chip;
> +	nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
> +	nand->read_buf = sunxi_nfc_read_buf;
> +	nand->write_buf = sunxi_nfc_write_buf;
> +	nand->read_byte = sunxi_nfc_read_byte;
> +
> +	nand->ecc.mode = of_get_nand_ecc_mode(np);
> +	if (of_get_nand_on_flash_bbt(np))
> +		nand->bbt_options |= NAND_BBT_USE_FLASH;
> +
> +	mtd = &chip->mtd;
> +	mtd->priv = nand;
> +	mtd->owner = THIS_MODULE;
> +
> +	ret = nand_scan_ident(mtd, nsels, NULL);
> +	if (ret)
> +		return ret;
> +
> +	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
> +		nand->ecc.size = nand->ecc_step_ds;
> +		nand->ecc.bytes = (((nand->ecc_strength_ds *
> +				     fls(8 * nand->ecc_step_ds)) + 7) / 8);
> +	}
> +
> +	ret = nand_scan_tail(mtd);
> +	if (ret)
> +		return ret;
> +
> +	if (of_property_read_string(np, "nand-name", &mtd->name)) {
> +		snprintf(chip->default_name, MAX_NAME_SIZE,
> +			 DEFAULT_NAME_FORMAT, chip->sels[i].cs);
> +		mtd->name = chip->default_name;
> +	}
> +
> +	ppdata.of_node = np;
> +	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
> +	if (!ret)
> +		return ret;
> +
> +	list_add_tail(&chip->node, &nfc->chips);
> +
> +	return 0;
> +}
> +
> +static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct device_node *nand_np;
> +	int nchips = of_get_child_count(np);
> +	int ret;
> +
> +	if (nchips > 8)
> +		return -EINVAL;
> +
> +	for_each_child_of_node(np, nand_np) {
> +		ret = sunxi_nand_chip_init(dev, nfc, nand_np);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int sunxi_nfc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *r;
> +	struct sunxi_nfc *nfc;
> +	int ret;
> +
> +	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
> +	if (!nfc) {
> +		dev_err(dev, "failed to allocate NFC struct\n");
> +		return -ENOMEM;
> +	}
> +
> +	spin_lock_init(&nfc->controller.lock);
> +	init_waitqueue_head(&nfc->controller.wq);
> +	INIT_LIST_HEAD(&nfc->chips);
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	nfc->regs = devm_ioremap_resource(dev, r);
> +	if (IS_ERR(nfc->regs)) {
> +		dev_err(dev, "failed to remap iomem\n");
> +		return PTR_ERR(nfc->regs);
> +	}
> +
> +	nfc->irq = platform_get_irq(pdev, 0);
> +	if (nfc->irq < 0) {
> +		dev_err(dev, "failed to retrieve irq\n");
> +		return nfc->irq;
> +	}
> +
> +	nfc->ahb_clk = devm_clk_get(dev, "ahb_clk");
> +	if (IS_ERR(nfc->ahb_clk)) {
> +		dev_err(dev, "failed to retrieve ahb_clk\n");
> +		return PTR_ERR(nfc->ahb_clk);
> +	}
> +
> +	ret = clk_prepare_enable(nfc->ahb_clk);
> +	if (ret)
> +		return ret;
> +
> +	nfc->sclk = devm_clk_get(dev, "sclk");
> +	if (IS_ERR(nfc->sclk)) {
> +		dev_err(dev, "failed to retrieve nand_clk\n");
> +		ret = PTR_ERR(nfc->sclk);
> +		goto out_ahb_clk_unprepare;
> +	}
> +
> +	ret = clk_prepare_enable(nfc->sclk);
> +	if (ret)
> +		goto out_ahb_clk_unprepare;
> +
> +	/* Reset NFC */
> +	writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RESET,
> +	       nfc->regs + NFC_REG_CTL);
> +	while (readl(nfc->regs + NFC_REG_CTL) & NFC_RESET)
> +		;
> +
> +	writel(0, nfc->regs + NFC_REG_INT);
> +	ret = devm_request_irq(dev, nfc->irq, sunxi_nfc_interrupt,
> +			       0, "sunxi-nfc", nfc);
> +	if (ret)
> +		goto out_sclk_unprepare;
> +
> +	platform_set_drvdata(pdev, nfc);
> +
> +	writel(0x100, nfc->regs + NFC_REG_TIMING_CTL);
> +	writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG);
> +
> +	ret = sunxi_nand_chips_init(dev, nfc);
> +	if (ret) {
> +		dev_err(dev, "failed to init nand chips\n");
> +		goto out_sclk_unprepare;
> +	}
> +
> +	return 0;
> +
> +out_sclk_unprepare:
> +	clk_disable_unprepare(nfc->sclk);
> +out_ahb_clk_unprepare:
> +	clk_disable_unprepare(nfc->ahb_clk);
> +
> +	return ret;
> +}
> +
> +static const struct of_device_id sunxi_nfc_ids[] = {
> +	{ .compatible = "allwinner,sun4i-nfc" },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
> +
> +static struct platform_driver sunxi_nfc_driver = {
> +	.driver = {
> +		.name = "sunxi_nfc",
> +		.owner = THIS_MODULE,
> +		.of_match_table = of_match_ptr(sunxi_nfc_ids),
> +	},
> +	.probe = sunxi_nfc_probe,
> +};
> +module_platform_driver(sunxi_nfc_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Boris BREZILLON");
> +MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
> +MODULE_ALIAS("platform:sunxi_nfc");


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

* Re: [RFC PATCH 5/9] mtd: nand: add sunxi NFC support
@ 2014-01-08 19:21     ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 19:21 UTC (permalink / raw)
  To: Boris BREZILLON, Maxime Ripard, Rob Landley, Russell King,
	David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, linux-mtd, linux-arm-kernel

Le 08/01/2014 15:22, Boris BREZILLON a écrit :
> Add the sunxi NAND Flash Controller driver.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>   drivers/mtd/nand/Kconfig     |    6 +
>   drivers/mtd/nand/Makefile    |    1 +
>   drivers/mtd/nand/sunxi_nfc.c |  700 ++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 707 insertions(+)
>   create mode 100644 drivers/mtd/nand/sunxi_nfc.c
>
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index 93ae6a6..784dd42 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -510,4 +510,10 @@ config MTD_NAND_XWAY
>   	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
>   	  to the External Bus Unit (EBU).
>   
> +config MTD_NAND_SUNXI
> +	tristate "Support for NAND on Allwinner SoCs"
> +	depends on ARCH_SUNXI
> +	help
> +	  Enables support for NAND Flash chips on Allwinner SoCs.
> +
>   endif # MTD_NAND
> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> index 542b568..e8b210d 100644
> --- a/drivers/mtd/nand/Makefile
> +++ b/drivers/mtd/nand/Makefile
> @@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
>   obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
>   obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
>   obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
> +obj-$(CONFIG_MTD_NAND_SUNXI)	+= sunxi_nfc.o
>   

BTW, I recently was one of the sources of a merge issue in the clk
subsystem because of unsorted Makefile lines.
Shouldn't we try to sort this Makefile too ?

>   nand-objs := nand_base.o nand_bbt.o
> diff --git a/drivers/mtd/nand/sunxi_nfc.c b/drivers/mtd/nand/sunxi_nfc.c
> new file mode 100644
> index 0000000..1c7a511
> --- /dev/null
> +++ b/drivers/mtd/nand/sunxi_nfc.c
> @@ -0,0 +1,700 @@
> +/*
> + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
> + *
> + * Derived from Qiang Yu work:
> + *	https://github.com/yuq/sunxi-nfc-mtd
> + *	Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/dma-mapping.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_mtd.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/nand.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/dmaengine.h>
> +#include <linux/gpio.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +
> +#define NFC_REG_CTL		0x0000
> +#define NFC_REG_ST		0x0004
> +#define NFC_REG_INT		0x0008
> +#define NFC_REG_TIMING_CTL	0x000C
> +#define NFC_REG_TIMING_CFG	0x0010
> +#define NFC_REG_ADDR_LOW	0x0014
> +#define NFC_REG_ADDR_HIGH	0x0018
> +#define NFC_REG_SECTOR_NUM	0x001C
> +#define NFC_REG_CNT		0x0020
> +#define NFC_REG_CMD		0x0024
> +#define NFC_REG_RCMD_SET	0x0028
> +#define NFC_REG_WCMD_SET	0x002C
> +#define NFC_REG_IO_DATA		0x0030
> +#define NFC_REG_ECC_CTL		0x0034
> +#define NFC_REG_ECC_ST		0x0038
> +#define NFC_REG_DEBUG		0x003C
> +#define NFC_REG_ECC_CNT0	0x0040
> +#define NFC_REG_ECC_CNT1	0x0044
> +#define NFC_REG_ECC_CNT2	0x0048
> +#define NFC_REG_ECC_CNT3	0x004c
> +#define NFC_REG_USER_DATA_BASE	0x0050
> +#define NFC_REG_SPARE_AREA	0x00A0
> +#define NFC_RAM0_BASE		0x0400
> +#define NFC_RAM1_BASE		0x0800
> +
> +/*define bit use in NFC_CTL*/
> +#define NFC_EN				(1 << 0)
> +#define NFC_RESET			(1 << 1)
> +#define NFC_BUS_WIDYH			(1 << 2)
> +#define NFC_RB_SEL			(1 << 3)
> +#define NFC_CE_SEL			(7 << 24)
> +#define NFC_CE_CTL			(1 << 6)
> +#define NFC_CE_CTL1			(1 << 7)
> +#define NFC_PAGE_SIZE			(0xf << 8)
> +#define NFC_SAM				(1 << 12)
> +#define NFC_RAM_METHOD			(1 << 14)
> +#define NFC_DEBUG_CTL			(1 << 31)
> +
> +/*define bit use in NFC_ST*/
> +#define NFC_RB_B2R			(1 << 0)
> +#define NFC_CMD_INT_FLAG		(1 << 1)
> +#define NFC_DMA_INT_FLAG		(1 << 2)
> +#define NFC_CMD_FIFO_STATUS		(1 << 3)
> +#define NFC_STA				(1 << 4)
> +#define NFC_NATCH_INT_FLAG		(1 << 5)
> +#define NFC_RB_STATE0			(1 << 8)
> +#define NFC_RB_STATE1			(1 << 9)
> +#define NFC_RB_STATE2			(1 << 10)
> +#define NFC_RB_STATE3			(1 << 11)
> +
> +/*define bit use in NFC_INT*/
> +#define NFC_B2R_INT_ENABLE		(1 << 0)
> +#define NFC_CMD_INT_ENABLE		(1 << 1)
> +#define NFC_DMA_INT_ENABLE		(1 << 2)
> +#define NFC_INT_MASK			(NFC_B2R_INT_ENABLE | \
> +					 NFC_CMD_INT_ENABLE | \
> +					 NFC_DMA_INT_ENABLE)
> +
> +
> +/*define bit use in NFC_CMD*/
> +#define NFC_CMD_LOW_BYTE		(0xff << 0)
> +#define NFC_CMD_HIGH_BYTE		(0xff << 8)
> +#define NFC_ADR_NUM			(0x7 << 16)
> +#define NFC_SEND_ADR			(1 << 19)
> +#define NFC_ACCESS_DIR			(1 << 20)
> +#define NFC_DATA_TRANS			(1 << 21)
> +#define NFC_SEND_CMD1			(1 << 22)
> +#define NFC_WAIT_FLAG			(1 << 23)
> +#define NFC_SEND_CMD2			(1 << 24)
> +#define NFC_SEQ				(1 << 25)
> +#define NFC_DATA_SWAP_METHOD		(1 << 26)
> +#define NFC_ROW_AUTO_INC		(1 << 27)
> +#define NFC_SEND_CMD3			(1 << 28)
> +#define NFC_SEND_CMD4			(1 << 29)
> +#define NFC_CMD_TYPE			(3 << 30)
> +
> +/* define bit use in NFC_RCMD_SET*/
> +#define NFC_READ_CMD			(0xff << 0)
> +#define NFC_RANDOM_READ_CMD0		(0xff << 8)
> +#define NFC_RANDOM_READ_CMD1		(0xff << 16)
> +
> +/*define bit use in NFC_WCMD_SET*/
> +#define NFC_PROGRAM_CMD			(0xff << 0)
> +#define NFC_RANDOM_WRITE_CMD		(0xff << 8)
> +#define NFC_READ_CMD0			(0xff << 16)
> +#define NFC_READ_CMD1			(0xff << 24)
> +
> +/*define bit use in NFC_ECC_CTL*/
> +#define NFC_ECC_EN			(1 << 0)
> +#define NFC_ECC_PIPELINE		(1 << 3)
> +#define NFC_ECC_EXCEPTION		(1 << 4)
> +#define NFC_ECC_BLOCK_SIZE		(1 << 5)
> +#define NFC_RANDOM_EN			(1 << 9)
> +#define NFC_RANDOM_DIRECTION		(1 << 10)
> +#define NFC_ECC_MODE_SHIFT		12
> +#define NFC_ECC_MODE			(0xf << NFC_ECC_MODE_SHIFT)
> +#define NFC_RANDOM_SEED			(0x7fff << 16)
> +
> +
> +
> +enum sunxi_nand_rb_type {
> +	RB_NONE,
> +	RB_NATIVE,
> +	RB_GPIO,
> +};
> +
> +struct sunxi_nand_rb {
> +	enum sunxi_nand_rb_type type;
> +	union {
> +		int gpio;
> +		int nativeid;
> +	} info;
> +};
> +
> +struct sunxi_nand_chip_sel {
> +	u8 cs;
> +	struct sunxi_nand_rb rb;
> +};
> +
> +#define DEFAULT_NAME_FORMAT	"nand@%d"
> +#define MAX_NAME_SIZE		(sizeof("nand@") + 2)
> +
> +struct sunxi_nand_chip {
> +	struct list_head node;
> +	struct nand_chip nand;
> +	struct mtd_info mtd;
> +	char default_name[MAX_NAME_SIZE];
> +	unsigned long clk_rate;
> +	int selected;
> +	int nsels;
> +	struct sunxi_nand_chip_sel sels[0];
> +};
> +
> +static inline struct sunxi_nand_chip *to_sunxi_nand(struct mtd_info *mtd)
> +{
> +	return container_of(mtd, struct sunxi_nand_chip, mtd);
> +}
> +
> +struct sunxi_nfc {
> +	struct nand_hw_control controller;
> +	void __iomem *regs;
> +	int irq;
> +	struct clk *ahb_clk;
> +	struct clk *sclk;
> +	unsigned long assigned_cs;
> +	struct list_head chips;
> +	struct completion complete;
> +};
> +
> +static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
> +{
> +	return container_of(ctrl, struct sunxi_nfc, controller);
> +}
> +
> +static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
> +{
> +	struct sunxi_nfc *nfc = dev_id;
> +	u32 st = readl(nfc->regs + NFC_REG_ST);
> +	u32 ien = readl(nfc->regs + NFC_REG_INT);
> +
> +	if (!(ien & st))
> +		return IRQ_NONE;
> +
> +	if ((ien & st) == ien)
> +		complete(&nfc->complete);
> +
> +	writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
> +	writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
> +			      unsigned int timeout_ms)
> +{
> +	init_completion(&nfc->complete);
> +
> +	writel(flags, nfc->regs + NFC_REG_INT);
> +	if (!timeout_ms)
> +		wait_for_completion(&nfc->complete);
> +	else if (!wait_for_completion_timeout(&nfc->complete,
> +					      msecs_to_jiffies(timeout_ms)))
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +
> +static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	struct sunxi_nand_rb *rb;
> +	unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
> +	int ret;
> +
> +	if (sunxi_nand->selected < 0)
> +		return 0;
> +
> +	rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
> +
> +	switch (rb->type) {
> +	case RB_NATIVE:
> +		ret = !!(readl(nfc->regs + NFC_REG_ST) &
> +			 (NFC_RB_STATE0 << rb->info.nativeid));
> +		if (ret)
> +			break;
> +
> +		sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
> +		ret = !!(readl(nfc->regs + NFC_REG_ST) &
> +			 (NFC_RB_STATE0 << rb->info.nativeid));
> +		break;
> +	case RB_GPIO:
> +		ret = gpio_get_value(rb->info.gpio);
> +		break;
> +	case RB_NONE:
> +	default:
> +		ret = 0;
> +		dev_err(&mtd->dev, "cannot check R/B NAND status!");
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	struct sunxi_nand_chip_sel *sel;
> +	u32 ctl;
> +
> +	if (chip > 0 && chip >= sunxi_nand->nsels)
> +		return;
> +
> +	if (chip == sunxi_nand->selected)
> +		return;
> +
> +	ctl = readl(nfc->regs + NFC_REG_CTL) &
> +	      ~(NFC_CE_SEL | NFC_RB_SEL | NFC_EN);
> +
> +	if (chip >= 0) {
> +		sel = &sunxi_nand->sels[chip];
> +
> +		ctl |= (sel->cs << 24) | NFC_EN |
> +		       (((sunxi_nand->nand.page_shift - 10) & 0xf) << 8);
> +		if (sel->rb.type == RB_NONE) {
> +			sunxi_nand->nand.dev_ready = NULL;
> +		} else {
> +			sunxi_nand->nand.dev_ready = sunxi_nfc_dev_ready;
> +			if (sel->rb.type == RB_NATIVE)
> +				ctl |= (sel->rb.info.nativeid << 3);
> +		}
> +	}
> +
> +	writel(ctl, nfc->regs + NFC_REG_CTL);
> +	clk_set_rate(nfc->sclk, sunxi_nand->clk_rate);
> +
> +	sunxi_nand->selected = chip;
> +}
> +
> +static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	int cnt;
> +	int offs = 0;
> +
> +	while (len > 0) {
> +		cnt = len > 1024 ? 1024 : len;
> +		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
> +			;
> +		writel(cnt, nfc->regs + NFC_REG_CNT);
> +		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_SEQ,
> +		       nfc->regs + NFC_REG_CMD);
> +		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
> +		memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, cnt);
> +		offs += cnt;
> +		len -= cnt;
> +	}
> +}
> +
> +static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
> +				int len)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	int cnt;
> +	int offs = 0;
> +
> +	while (len > 0) {
> +		cnt = len > 1024 ? 1024 : len;
> +		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
> +			;
> +		writel(cnt, nfc->regs + NFC_REG_CNT);
> +		memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
> +		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
> +		       NFC_ACCESS_DIR | NFC_SEQ, nfc->regs + NFC_REG_CMD);
> +		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
> +		offs += cnt;
> +		len -= cnt;
> +	}
> +}
> +
> +static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
> +{
> +	uint8_t ret;
> +
> +	sunxi_nfc_read_buf(mtd, &ret, 1);
> +
> +	return ret;
> +}
> +
> +static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
> +			       unsigned int ctrl)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	u32 tmp;
> +
> +	while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
> +		;
> +
> +	if (ctrl & NAND_CTRL_CHANGE) {
> +		tmp = readl(nfc->regs + NFC_REG_CTL);
> +		if (ctrl & NAND_NCE)
> +			tmp |= NFC_CE_CTL;
> +		else
> +			tmp &= ~NFC_CE_CTL;
> +		writel(tmp, nfc->regs + NFC_REG_CTL);
> +	}
> +
> +	if (dat == NAND_CMD_NONE)
> +		return;
> +
> +	if (ctrl & NAND_CLE) {
> +		writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
> +	} else {
> +		writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
> +		writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
> +	}
> +
> +	sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
> +}
> +
> +static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
> +					struct device_node *np)
> +{
> +	struct nand_timings timings;
> +	u32 min_clk_period = 0;
> +	int ret;
> +
> +	ret = of_get_nand_timings(np, &timings);
> +	if (ret)
> +		return ret;
> +
> +	/* NFC timings defined in Allwinner Datasheets */
> +
> +	/* T1 <=> tCLS */
> +	if (timings.tCLS_min > min_clk_period)
> +		min_clk_period = timings.tCLS_min;
> +
> +	/* T2 <=> tCLH */
> +	if (timings.tCLH_min > min_clk_period)
> +		min_clk_period = timings.tCLH_min;
> +
> +	/* T3 <=> tCS */
> +	if (timings.tCS_min > min_clk_period)
> +		min_clk_period = timings.tCS_min;
> +
> +	/* T4 <=> tCH */
> +	if (timings.tCH_min > min_clk_period)
> +		min_clk_period = timings.tCH_min;
> +
> +	/* T5 <=> tWP */
> +	if (timings.tWP_min > min_clk_period)
> +		min_clk_period = timings.tWP_min;
> +
> +	/* T6 <=> tWH */
> +	if (timings.tWH_min > min_clk_period)
> +		min_clk_period = timings.tWH_min;
> +
> +	/* T7 <=> tALS */
> +	if (timings.tALS_min > min_clk_period)
> +		min_clk_period = timings.tALS_min;
> +
> +	/* T8 <=> tDS */
> +	if (timings.tDS_min > min_clk_period)
> +		min_clk_period = timings.tDS_min;
> +
> +	/* T9 <=> tDH */
> +	if (timings.tDH_min > min_clk_period)
> +		min_clk_period = timings.tDH_min;
> +
> +	/* T10 <=> tRR */
> +	if (timings.tRR_min > (min_clk_period * 3))
> +		min_clk_period = (timings.tRR_min + 2) / 3;
> +
> +	/* T11 <=> tALH */
> +	if (timings.tALH_min > min_clk_period)
> +		min_clk_period = timings.tALH_min;
> +
> +	/* T12 <=> tRP */
> +	if (timings.tRP_min > min_clk_period)
> +		min_clk_period = timings.tRP_min;
> +
> +	/* T13 <=> tREH */
> +	if (timings.tREH_min > min_clk_period)
> +		min_clk_period = timings.tREH_min;
> +
> +	/* T14 <=> tRC */
> +	if (timings.tRC_min > (min_clk_period * 2))
> +		min_clk_period = (timings.tRC_min + 1) / 2;
> +
> +	/* T15 <=> tWC */
> +	if (timings.tWC_min > (min_clk_period * 2))
> +		min_clk_period = (timings.tWC_min + 1) / 2;
> +
> +
> +	/* min_clk_period = (NAND-clk-period * 2) */
> +	if (!min_clk_period)
> +		chip->clk_rate = 20000000;
> +	else
> +		chip->clk_rate = (2 * 1000000000) / min_clk_period;
> +
> +	/* TODO: configure T16-T19 */
> +
> +	return 0;
> +}
> +
> +static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
> +				struct device_node *np)
> +{
> +	struct sunxi_nand_chip *chip;
> +	struct mtd_part_parser_data ppdata;
> +	struct mtd_info *mtd;
> +	struct nand_chip *nand;
> +	int nsels;
> +	int ret;
> +	int i;
> +	u32 tmp;
> +
> +	if (!of_get_property(np, "reg", &nsels))
> +		return -EINVAL;
> +
> +	nsels /= sizeof(u32);
> +	if (!nsels)
> +		return -EINVAL;
> +
> +	chip = devm_kzalloc(dev,
> +			    sizeof(*chip) +
> +			    (nsels * sizeof(struct sunxi_nand_chip_sel)),
> +			    GFP_KERNEL);
> +	if (!chip)
> +		return -ENOMEM;
> +
> +	chip->nsels = nsels;
> +	chip->selected = -1;
> +
> +	for (i = 0; i < nsels; i++) {
> +		ret = of_property_read_u32_index(np, "reg", i, &tmp);
> +		if (ret)
> +			return ret;
> +
> +		if (tmp > 7)
> +			return -EINVAL;
> +
> +		if (test_and_set_bit(tmp, &nfc->assigned_cs))
> +			return -EINVAL;
> +
> +		chip->sels[i].cs = tmp;
> +
> +		if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
> +		    tmp < 2) {
> +			chip->sels[i].rb.type = RB_NATIVE;
> +			chip->sels[i].rb.info.nativeid = tmp;
> +		} else {
> +			ret = of_get_named_gpio(np, "rb-gpios", i);
> +			if (ret >= 0) {
> +				chip->sels[i].rb.type = RB_GPIO;
> +				chip->sels[i].rb.info.gpio = tmp;
> +				ret = devm_gpio_request(dev, tmp, "nand-rb");
> +				if (ret)
> +					return ret;
> +			} else {
> +				chip->sels[i].rb.type = RB_NONE;
> +			}
> +		}
> +	}
> +
> +	ret = sunxi_nand_chip_init_timings(chip, np);
> +	if (ret)
> +		return ret;
> +
> +	nand = &chip->nand;
> +	nand->IO_ADDR_R = nand->IO_ADDR_W = nfc->regs + NFC_REG_IO_DATA;
> +	nand->controller = &nfc->controller;
> +	nand->select_chip = sunxi_nfc_select_chip;
> +	nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
> +	nand->read_buf = sunxi_nfc_read_buf;
> +	nand->write_buf = sunxi_nfc_write_buf;
> +	nand->read_byte = sunxi_nfc_read_byte;
> +
> +	nand->ecc.mode = of_get_nand_ecc_mode(np);
> +	if (of_get_nand_on_flash_bbt(np))
> +		nand->bbt_options |= NAND_BBT_USE_FLASH;
> +
> +	mtd = &chip->mtd;
> +	mtd->priv = nand;
> +	mtd->owner = THIS_MODULE;
> +
> +	ret = nand_scan_ident(mtd, nsels, NULL);
> +	if (ret)
> +		return ret;
> +
> +	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
> +		nand->ecc.size = nand->ecc_step_ds;
> +		nand->ecc.bytes = (((nand->ecc_strength_ds *
> +				     fls(8 * nand->ecc_step_ds)) + 7) / 8);
> +	}
> +
> +	ret = nand_scan_tail(mtd);
> +	if (ret)
> +		return ret;
> +
> +	if (of_property_read_string(np, "nand-name", &mtd->name)) {
> +		snprintf(chip->default_name, MAX_NAME_SIZE,
> +			 DEFAULT_NAME_FORMAT, chip->sels[i].cs);
> +		mtd->name = chip->default_name;
> +	}
> +
> +	ppdata.of_node = np;
> +	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
> +	if (!ret)
> +		return ret;
> +
> +	list_add_tail(&chip->node, &nfc->chips);
> +
> +	return 0;
> +}
> +
> +static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct device_node *nand_np;
> +	int nchips = of_get_child_count(np);
> +	int ret;
> +
> +	if (nchips > 8)
> +		return -EINVAL;
> +
> +	for_each_child_of_node(np, nand_np) {
> +		ret = sunxi_nand_chip_init(dev, nfc, nand_np);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int sunxi_nfc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *r;
> +	struct sunxi_nfc *nfc;
> +	int ret;
> +
> +	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
> +	if (!nfc) {
> +		dev_err(dev, "failed to allocate NFC struct\n");
> +		return -ENOMEM;
> +	}
> +
> +	spin_lock_init(&nfc->controller.lock);
> +	init_waitqueue_head(&nfc->controller.wq);
> +	INIT_LIST_HEAD(&nfc->chips);
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	nfc->regs = devm_ioremap_resource(dev, r);
> +	if (IS_ERR(nfc->regs)) {
> +		dev_err(dev, "failed to remap iomem\n");
> +		return PTR_ERR(nfc->regs);
> +	}
> +
> +	nfc->irq = platform_get_irq(pdev, 0);
> +	if (nfc->irq < 0) {
> +		dev_err(dev, "failed to retrieve irq\n");
> +		return nfc->irq;
> +	}
> +
> +	nfc->ahb_clk = devm_clk_get(dev, "ahb_clk");
> +	if (IS_ERR(nfc->ahb_clk)) {
> +		dev_err(dev, "failed to retrieve ahb_clk\n");
> +		return PTR_ERR(nfc->ahb_clk);
> +	}
> +
> +	ret = clk_prepare_enable(nfc->ahb_clk);
> +	if (ret)
> +		return ret;
> +
> +	nfc->sclk = devm_clk_get(dev, "sclk");
> +	if (IS_ERR(nfc->sclk)) {
> +		dev_err(dev, "failed to retrieve nand_clk\n");
> +		ret = PTR_ERR(nfc->sclk);
> +		goto out_ahb_clk_unprepare;
> +	}
> +
> +	ret = clk_prepare_enable(nfc->sclk);
> +	if (ret)
> +		goto out_ahb_clk_unprepare;
> +
> +	/* Reset NFC */
> +	writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RESET,
> +	       nfc->regs + NFC_REG_CTL);
> +	while (readl(nfc->regs + NFC_REG_CTL) & NFC_RESET)
> +		;
> +
> +	writel(0, nfc->regs + NFC_REG_INT);
> +	ret = devm_request_irq(dev, nfc->irq, sunxi_nfc_interrupt,
> +			       0, "sunxi-nfc", nfc);
> +	if (ret)
> +		goto out_sclk_unprepare;
> +
> +	platform_set_drvdata(pdev, nfc);
> +
> +	writel(0x100, nfc->regs + NFC_REG_TIMING_CTL);
> +	writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG);
> +
> +	ret = sunxi_nand_chips_init(dev, nfc);
> +	if (ret) {
> +		dev_err(dev, "failed to init nand chips\n");
> +		goto out_sclk_unprepare;
> +	}
> +
> +	return 0;
> +
> +out_sclk_unprepare:
> +	clk_disable_unprepare(nfc->sclk);
> +out_ahb_clk_unprepare:
> +	clk_disable_unprepare(nfc->ahb_clk);
> +
> +	return ret;
> +}
> +
> +static const struct of_device_id sunxi_nfc_ids[] = {
> +	{ .compatible = "allwinner,sun4i-nfc" },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
> +
> +static struct platform_driver sunxi_nfc_driver = {
> +	.driver = {
> +		.name = "sunxi_nfc",
> +		.owner = THIS_MODULE,
> +		.of_match_table = of_match_ptr(sunxi_nfc_ids),
> +	},
> +	.probe = sunxi_nfc_probe,
> +};
> +module_platform_driver(sunxi_nfc_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Boris BREZILLON");
> +MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
> +MODULE_ALIAS("platform:sunxi_nfc");

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

* [RFC PATCH 5/9] mtd: nand: add sunxi NFC support
@ 2014-01-08 19:21     ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-08 19:21 UTC (permalink / raw)
  To: linux-arm-kernel

Le 08/01/2014 15:22, Boris BREZILLON a ?crit :
> Add the sunxi NAND Flash Controller driver.
>
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> ---
>   drivers/mtd/nand/Kconfig     |    6 +
>   drivers/mtd/nand/Makefile    |    1 +
>   drivers/mtd/nand/sunxi_nfc.c |  700 ++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 707 insertions(+)
>   create mode 100644 drivers/mtd/nand/sunxi_nfc.c
>
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index 93ae6a6..784dd42 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -510,4 +510,10 @@ config MTD_NAND_XWAY
>   	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
>   	  to the External Bus Unit (EBU).
>   
> +config MTD_NAND_SUNXI
> +	tristate "Support for NAND on Allwinner SoCs"
> +	depends on ARCH_SUNXI
> +	help
> +	  Enables support for NAND Flash chips on Allwinner SoCs.
> +
>   endif # MTD_NAND
> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> index 542b568..e8b210d 100644
> --- a/drivers/mtd/nand/Makefile
> +++ b/drivers/mtd/nand/Makefile
> @@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
>   obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
>   obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
>   obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
> +obj-$(CONFIG_MTD_NAND_SUNXI)	+= sunxi_nfc.o
>   

BTW, I recently was one of the sources of a merge issue in the clk
subsystem because of unsorted Makefile lines.
Shouldn't we try to sort this Makefile too ?

>   nand-objs := nand_base.o nand_bbt.o
> diff --git a/drivers/mtd/nand/sunxi_nfc.c b/drivers/mtd/nand/sunxi_nfc.c
> new file mode 100644
> index 0000000..1c7a511
> --- /dev/null
> +++ b/drivers/mtd/nand/sunxi_nfc.c
> @@ -0,0 +1,700 @@
> +/*
> + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
> + *
> + * Derived from Qiang Yu work:
> + *	https://github.com/yuq/sunxi-nfc-mtd
> + *	Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/dma-mapping.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_mtd.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/nand.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/dmaengine.h>
> +#include <linux/gpio.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +
> +#define NFC_REG_CTL		0x0000
> +#define NFC_REG_ST		0x0004
> +#define NFC_REG_INT		0x0008
> +#define NFC_REG_TIMING_CTL	0x000C
> +#define NFC_REG_TIMING_CFG	0x0010
> +#define NFC_REG_ADDR_LOW	0x0014
> +#define NFC_REG_ADDR_HIGH	0x0018
> +#define NFC_REG_SECTOR_NUM	0x001C
> +#define NFC_REG_CNT		0x0020
> +#define NFC_REG_CMD		0x0024
> +#define NFC_REG_RCMD_SET	0x0028
> +#define NFC_REG_WCMD_SET	0x002C
> +#define NFC_REG_IO_DATA		0x0030
> +#define NFC_REG_ECC_CTL		0x0034
> +#define NFC_REG_ECC_ST		0x0038
> +#define NFC_REG_DEBUG		0x003C
> +#define NFC_REG_ECC_CNT0	0x0040
> +#define NFC_REG_ECC_CNT1	0x0044
> +#define NFC_REG_ECC_CNT2	0x0048
> +#define NFC_REG_ECC_CNT3	0x004c
> +#define NFC_REG_USER_DATA_BASE	0x0050
> +#define NFC_REG_SPARE_AREA	0x00A0
> +#define NFC_RAM0_BASE		0x0400
> +#define NFC_RAM1_BASE		0x0800
> +
> +/*define bit use in NFC_CTL*/
> +#define NFC_EN				(1 << 0)
> +#define NFC_RESET			(1 << 1)
> +#define NFC_BUS_WIDYH			(1 << 2)
> +#define NFC_RB_SEL			(1 << 3)
> +#define NFC_CE_SEL			(7 << 24)
> +#define NFC_CE_CTL			(1 << 6)
> +#define NFC_CE_CTL1			(1 << 7)
> +#define NFC_PAGE_SIZE			(0xf << 8)
> +#define NFC_SAM				(1 << 12)
> +#define NFC_RAM_METHOD			(1 << 14)
> +#define NFC_DEBUG_CTL			(1 << 31)
> +
> +/*define bit use in NFC_ST*/
> +#define NFC_RB_B2R			(1 << 0)
> +#define NFC_CMD_INT_FLAG		(1 << 1)
> +#define NFC_DMA_INT_FLAG		(1 << 2)
> +#define NFC_CMD_FIFO_STATUS		(1 << 3)
> +#define NFC_STA				(1 << 4)
> +#define NFC_NATCH_INT_FLAG		(1 << 5)
> +#define NFC_RB_STATE0			(1 << 8)
> +#define NFC_RB_STATE1			(1 << 9)
> +#define NFC_RB_STATE2			(1 << 10)
> +#define NFC_RB_STATE3			(1 << 11)
> +
> +/*define bit use in NFC_INT*/
> +#define NFC_B2R_INT_ENABLE		(1 << 0)
> +#define NFC_CMD_INT_ENABLE		(1 << 1)
> +#define NFC_DMA_INT_ENABLE		(1 << 2)
> +#define NFC_INT_MASK			(NFC_B2R_INT_ENABLE | \
> +					 NFC_CMD_INT_ENABLE | \
> +					 NFC_DMA_INT_ENABLE)
> +
> +
> +/*define bit use in NFC_CMD*/
> +#define NFC_CMD_LOW_BYTE		(0xff << 0)
> +#define NFC_CMD_HIGH_BYTE		(0xff << 8)
> +#define NFC_ADR_NUM			(0x7 << 16)
> +#define NFC_SEND_ADR			(1 << 19)
> +#define NFC_ACCESS_DIR			(1 << 20)
> +#define NFC_DATA_TRANS			(1 << 21)
> +#define NFC_SEND_CMD1			(1 << 22)
> +#define NFC_WAIT_FLAG			(1 << 23)
> +#define NFC_SEND_CMD2			(1 << 24)
> +#define NFC_SEQ				(1 << 25)
> +#define NFC_DATA_SWAP_METHOD		(1 << 26)
> +#define NFC_ROW_AUTO_INC		(1 << 27)
> +#define NFC_SEND_CMD3			(1 << 28)
> +#define NFC_SEND_CMD4			(1 << 29)
> +#define NFC_CMD_TYPE			(3 << 30)
> +
> +/* define bit use in NFC_RCMD_SET*/
> +#define NFC_READ_CMD			(0xff << 0)
> +#define NFC_RANDOM_READ_CMD0		(0xff << 8)
> +#define NFC_RANDOM_READ_CMD1		(0xff << 16)
> +
> +/*define bit use in NFC_WCMD_SET*/
> +#define NFC_PROGRAM_CMD			(0xff << 0)
> +#define NFC_RANDOM_WRITE_CMD		(0xff << 8)
> +#define NFC_READ_CMD0			(0xff << 16)
> +#define NFC_READ_CMD1			(0xff << 24)
> +
> +/*define bit use in NFC_ECC_CTL*/
> +#define NFC_ECC_EN			(1 << 0)
> +#define NFC_ECC_PIPELINE		(1 << 3)
> +#define NFC_ECC_EXCEPTION		(1 << 4)
> +#define NFC_ECC_BLOCK_SIZE		(1 << 5)
> +#define NFC_RANDOM_EN			(1 << 9)
> +#define NFC_RANDOM_DIRECTION		(1 << 10)
> +#define NFC_ECC_MODE_SHIFT		12
> +#define NFC_ECC_MODE			(0xf << NFC_ECC_MODE_SHIFT)
> +#define NFC_RANDOM_SEED			(0x7fff << 16)
> +
> +
> +
> +enum sunxi_nand_rb_type {
> +	RB_NONE,
> +	RB_NATIVE,
> +	RB_GPIO,
> +};
> +
> +struct sunxi_nand_rb {
> +	enum sunxi_nand_rb_type type;
> +	union {
> +		int gpio;
> +		int nativeid;
> +	} info;
> +};
> +
> +struct sunxi_nand_chip_sel {
> +	u8 cs;
> +	struct sunxi_nand_rb rb;
> +};
> +
> +#define DEFAULT_NAME_FORMAT	"nand@%d"
> +#define MAX_NAME_SIZE		(sizeof("nand@") + 2)
> +
> +struct sunxi_nand_chip {
> +	struct list_head node;
> +	struct nand_chip nand;
> +	struct mtd_info mtd;
> +	char default_name[MAX_NAME_SIZE];
> +	unsigned long clk_rate;
> +	int selected;
> +	int nsels;
> +	struct sunxi_nand_chip_sel sels[0];
> +};
> +
> +static inline struct sunxi_nand_chip *to_sunxi_nand(struct mtd_info *mtd)
> +{
> +	return container_of(mtd, struct sunxi_nand_chip, mtd);
> +}
> +
> +struct sunxi_nfc {
> +	struct nand_hw_control controller;
> +	void __iomem *regs;
> +	int irq;
> +	struct clk *ahb_clk;
> +	struct clk *sclk;
> +	unsigned long assigned_cs;
> +	struct list_head chips;
> +	struct completion complete;
> +};
> +
> +static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
> +{
> +	return container_of(ctrl, struct sunxi_nfc, controller);
> +}
> +
> +static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
> +{
> +	struct sunxi_nfc *nfc = dev_id;
> +	u32 st = readl(nfc->regs + NFC_REG_ST);
> +	u32 ien = readl(nfc->regs + NFC_REG_INT);
> +
> +	if (!(ien & st))
> +		return IRQ_NONE;
> +
> +	if ((ien & st) == ien)
> +		complete(&nfc->complete);
> +
> +	writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
> +	writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
> +			      unsigned int timeout_ms)
> +{
> +	init_completion(&nfc->complete);
> +
> +	writel(flags, nfc->regs + NFC_REG_INT);
> +	if (!timeout_ms)
> +		wait_for_completion(&nfc->complete);
> +	else if (!wait_for_completion_timeout(&nfc->complete,
> +					      msecs_to_jiffies(timeout_ms)))
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +
> +static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	struct sunxi_nand_rb *rb;
> +	unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
> +	int ret;
> +
> +	if (sunxi_nand->selected < 0)
> +		return 0;
> +
> +	rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
> +
> +	switch (rb->type) {
> +	case RB_NATIVE:
> +		ret = !!(readl(nfc->regs + NFC_REG_ST) &
> +			 (NFC_RB_STATE0 << rb->info.nativeid));
> +		if (ret)
> +			break;
> +
> +		sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
> +		ret = !!(readl(nfc->regs + NFC_REG_ST) &
> +			 (NFC_RB_STATE0 << rb->info.nativeid));
> +		break;
> +	case RB_GPIO:
> +		ret = gpio_get_value(rb->info.gpio);
> +		break;
> +	case RB_NONE:
> +	default:
> +		ret = 0;
> +		dev_err(&mtd->dev, "cannot check R/B NAND status!");
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	struct sunxi_nand_chip_sel *sel;
> +	u32 ctl;
> +
> +	if (chip > 0 && chip >= sunxi_nand->nsels)
> +		return;
> +
> +	if (chip == sunxi_nand->selected)
> +		return;
> +
> +	ctl = readl(nfc->regs + NFC_REG_CTL) &
> +	      ~(NFC_CE_SEL | NFC_RB_SEL | NFC_EN);
> +
> +	if (chip >= 0) {
> +		sel = &sunxi_nand->sels[chip];
> +
> +		ctl |= (sel->cs << 24) | NFC_EN |
> +		       (((sunxi_nand->nand.page_shift - 10) & 0xf) << 8);
> +		if (sel->rb.type == RB_NONE) {
> +			sunxi_nand->nand.dev_ready = NULL;
> +		} else {
> +			sunxi_nand->nand.dev_ready = sunxi_nfc_dev_ready;
> +			if (sel->rb.type == RB_NATIVE)
> +				ctl |= (sel->rb.info.nativeid << 3);
> +		}
> +	}
> +
> +	writel(ctl, nfc->regs + NFC_REG_CTL);
> +	clk_set_rate(nfc->sclk, sunxi_nand->clk_rate);
> +
> +	sunxi_nand->selected = chip;
> +}
> +
> +static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	int cnt;
> +	int offs = 0;
> +
> +	while (len > 0) {
> +		cnt = len > 1024 ? 1024 : len;
> +		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
> +			;
> +		writel(cnt, nfc->regs + NFC_REG_CNT);
> +		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_SEQ,
> +		       nfc->regs + NFC_REG_CMD);
> +		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
> +		memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, cnt);
> +		offs += cnt;
> +		len -= cnt;
> +	}
> +}
> +
> +static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
> +				int len)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	int cnt;
> +	int offs = 0;
> +
> +	while (len > 0) {
> +		cnt = len > 1024 ? 1024 : len;
> +		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
> +			;
> +		writel(cnt, nfc->regs + NFC_REG_CNT);
> +		memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
> +		writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
> +		       NFC_ACCESS_DIR | NFC_SEQ, nfc->regs + NFC_REG_CMD);
> +		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
> +		offs += cnt;
> +		len -= cnt;
> +	}
> +}
> +
> +static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
> +{
> +	uint8_t ret;
> +
> +	sunxi_nfc_read_buf(mtd, &ret, 1);
> +
> +	return ret;
> +}
> +
> +static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
> +			       unsigned int ctrl)
> +{
> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
> +	u32 tmp;
> +
> +	while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
> +		;
> +
> +	if (ctrl & NAND_CTRL_CHANGE) {
> +		tmp = readl(nfc->regs + NFC_REG_CTL);
> +		if (ctrl & NAND_NCE)
> +			tmp |= NFC_CE_CTL;
> +		else
> +			tmp &= ~NFC_CE_CTL;
> +		writel(tmp, nfc->regs + NFC_REG_CTL);
> +	}
> +
> +	if (dat == NAND_CMD_NONE)
> +		return;
> +
> +	if (ctrl & NAND_CLE) {
> +		writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
> +	} else {
> +		writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
> +		writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
> +	}
> +
> +	sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
> +}
> +
> +static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
> +					struct device_node *np)
> +{
> +	struct nand_timings timings;
> +	u32 min_clk_period = 0;
> +	int ret;
> +
> +	ret = of_get_nand_timings(np, &timings);
> +	if (ret)
> +		return ret;
> +
> +	/* NFC timings defined in Allwinner Datasheets */
> +
> +	/* T1 <=> tCLS */
> +	if (timings.tCLS_min > min_clk_period)
> +		min_clk_period = timings.tCLS_min;
> +
> +	/* T2 <=> tCLH */
> +	if (timings.tCLH_min > min_clk_period)
> +		min_clk_period = timings.tCLH_min;
> +
> +	/* T3 <=> tCS */
> +	if (timings.tCS_min > min_clk_period)
> +		min_clk_period = timings.tCS_min;
> +
> +	/* T4 <=> tCH */
> +	if (timings.tCH_min > min_clk_period)
> +		min_clk_period = timings.tCH_min;
> +
> +	/* T5 <=> tWP */
> +	if (timings.tWP_min > min_clk_period)
> +		min_clk_period = timings.tWP_min;
> +
> +	/* T6 <=> tWH */
> +	if (timings.tWH_min > min_clk_period)
> +		min_clk_period = timings.tWH_min;
> +
> +	/* T7 <=> tALS */
> +	if (timings.tALS_min > min_clk_period)
> +		min_clk_period = timings.tALS_min;
> +
> +	/* T8 <=> tDS */
> +	if (timings.tDS_min > min_clk_period)
> +		min_clk_period = timings.tDS_min;
> +
> +	/* T9 <=> tDH */
> +	if (timings.tDH_min > min_clk_period)
> +		min_clk_period = timings.tDH_min;
> +
> +	/* T10 <=> tRR */
> +	if (timings.tRR_min > (min_clk_period * 3))
> +		min_clk_period = (timings.tRR_min + 2) / 3;
> +
> +	/* T11 <=> tALH */
> +	if (timings.tALH_min > min_clk_period)
> +		min_clk_period = timings.tALH_min;
> +
> +	/* T12 <=> tRP */
> +	if (timings.tRP_min > min_clk_period)
> +		min_clk_period = timings.tRP_min;
> +
> +	/* T13 <=> tREH */
> +	if (timings.tREH_min > min_clk_period)
> +		min_clk_period = timings.tREH_min;
> +
> +	/* T14 <=> tRC */
> +	if (timings.tRC_min > (min_clk_period * 2))
> +		min_clk_period = (timings.tRC_min + 1) / 2;
> +
> +	/* T15 <=> tWC */
> +	if (timings.tWC_min > (min_clk_period * 2))
> +		min_clk_period = (timings.tWC_min + 1) / 2;
> +
> +
> +	/* min_clk_period = (NAND-clk-period * 2) */
> +	if (!min_clk_period)
> +		chip->clk_rate = 20000000;
> +	else
> +		chip->clk_rate = (2 * 1000000000) / min_clk_period;
> +
> +	/* TODO: configure T16-T19 */
> +
> +	return 0;
> +}
> +
> +static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
> +				struct device_node *np)
> +{
> +	struct sunxi_nand_chip *chip;
> +	struct mtd_part_parser_data ppdata;
> +	struct mtd_info *mtd;
> +	struct nand_chip *nand;
> +	int nsels;
> +	int ret;
> +	int i;
> +	u32 tmp;
> +
> +	if (!of_get_property(np, "reg", &nsels))
> +		return -EINVAL;
> +
> +	nsels /= sizeof(u32);
> +	if (!nsels)
> +		return -EINVAL;
> +
> +	chip = devm_kzalloc(dev,
> +			    sizeof(*chip) +
> +			    (nsels * sizeof(struct sunxi_nand_chip_sel)),
> +			    GFP_KERNEL);
> +	if (!chip)
> +		return -ENOMEM;
> +
> +	chip->nsels = nsels;
> +	chip->selected = -1;
> +
> +	for (i = 0; i < nsels; i++) {
> +		ret = of_property_read_u32_index(np, "reg", i, &tmp);
> +		if (ret)
> +			return ret;
> +
> +		if (tmp > 7)
> +			return -EINVAL;
> +
> +		if (test_and_set_bit(tmp, &nfc->assigned_cs))
> +			return -EINVAL;
> +
> +		chip->sels[i].cs = tmp;
> +
> +		if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
> +		    tmp < 2) {
> +			chip->sels[i].rb.type = RB_NATIVE;
> +			chip->sels[i].rb.info.nativeid = tmp;
> +		} else {
> +			ret = of_get_named_gpio(np, "rb-gpios", i);
> +			if (ret >= 0) {
> +				chip->sels[i].rb.type = RB_GPIO;
> +				chip->sels[i].rb.info.gpio = tmp;
> +				ret = devm_gpio_request(dev, tmp, "nand-rb");
> +				if (ret)
> +					return ret;
> +			} else {
> +				chip->sels[i].rb.type = RB_NONE;
> +			}
> +		}
> +	}
> +
> +	ret = sunxi_nand_chip_init_timings(chip, np);
> +	if (ret)
> +		return ret;
> +
> +	nand = &chip->nand;
> +	nand->IO_ADDR_R = nand->IO_ADDR_W = nfc->regs + NFC_REG_IO_DATA;
> +	nand->controller = &nfc->controller;
> +	nand->select_chip = sunxi_nfc_select_chip;
> +	nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
> +	nand->read_buf = sunxi_nfc_read_buf;
> +	nand->write_buf = sunxi_nfc_write_buf;
> +	nand->read_byte = sunxi_nfc_read_byte;
> +
> +	nand->ecc.mode = of_get_nand_ecc_mode(np);
> +	if (of_get_nand_on_flash_bbt(np))
> +		nand->bbt_options |= NAND_BBT_USE_FLASH;
> +
> +	mtd = &chip->mtd;
> +	mtd->priv = nand;
> +	mtd->owner = THIS_MODULE;
> +
> +	ret = nand_scan_ident(mtd, nsels, NULL);
> +	if (ret)
> +		return ret;
> +
> +	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
> +		nand->ecc.size = nand->ecc_step_ds;
> +		nand->ecc.bytes = (((nand->ecc_strength_ds *
> +				     fls(8 * nand->ecc_step_ds)) + 7) / 8);
> +	}
> +
> +	ret = nand_scan_tail(mtd);
> +	if (ret)
> +		return ret;
> +
> +	if (of_property_read_string(np, "nand-name", &mtd->name)) {
> +		snprintf(chip->default_name, MAX_NAME_SIZE,
> +			 DEFAULT_NAME_FORMAT, chip->sels[i].cs);
> +		mtd->name = chip->default_name;
> +	}
> +
> +	ppdata.of_node = np;
> +	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
> +	if (!ret)
> +		return ret;
> +
> +	list_add_tail(&chip->node, &nfc->chips);
> +
> +	return 0;
> +}
> +
> +static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct device_node *nand_np;
> +	int nchips = of_get_child_count(np);
> +	int ret;
> +
> +	if (nchips > 8)
> +		return -EINVAL;
> +
> +	for_each_child_of_node(np, nand_np) {
> +		ret = sunxi_nand_chip_init(dev, nfc, nand_np);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int sunxi_nfc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *r;
> +	struct sunxi_nfc *nfc;
> +	int ret;
> +
> +	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
> +	if (!nfc) {
> +		dev_err(dev, "failed to allocate NFC struct\n");
> +		return -ENOMEM;
> +	}
> +
> +	spin_lock_init(&nfc->controller.lock);
> +	init_waitqueue_head(&nfc->controller.wq);
> +	INIT_LIST_HEAD(&nfc->chips);
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	nfc->regs = devm_ioremap_resource(dev, r);
> +	if (IS_ERR(nfc->regs)) {
> +		dev_err(dev, "failed to remap iomem\n");
> +		return PTR_ERR(nfc->regs);
> +	}
> +
> +	nfc->irq = platform_get_irq(pdev, 0);
> +	if (nfc->irq < 0) {
> +		dev_err(dev, "failed to retrieve irq\n");
> +		return nfc->irq;
> +	}
> +
> +	nfc->ahb_clk = devm_clk_get(dev, "ahb_clk");
> +	if (IS_ERR(nfc->ahb_clk)) {
> +		dev_err(dev, "failed to retrieve ahb_clk\n");
> +		return PTR_ERR(nfc->ahb_clk);
> +	}
> +
> +	ret = clk_prepare_enable(nfc->ahb_clk);
> +	if (ret)
> +		return ret;
> +
> +	nfc->sclk = devm_clk_get(dev, "sclk");
> +	if (IS_ERR(nfc->sclk)) {
> +		dev_err(dev, "failed to retrieve nand_clk\n");
> +		ret = PTR_ERR(nfc->sclk);
> +		goto out_ahb_clk_unprepare;
> +	}
> +
> +	ret = clk_prepare_enable(nfc->sclk);
> +	if (ret)
> +		goto out_ahb_clk_unprepare;
> +
> +	/* Reset NFC */
> +	writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RESET,
> +	       nfc->regs + NFC_REG_CTL);
> +	while (readl(nfc->regs + NFC_REG_CTL) & NFC_RESET)
> +		;
> +
> +	writel(0, nfc->regs + NFC_REG_INT);
> +	ret = devm_request_irq(dev, nfc->irq, sunxi_nfc_interrupt,
> +			       0, "sunxi-nfc", nfc);
> +	if (ret)
> +		goto out_sclk_unprepare;
> +
> +	platform_set_drvdata(pdev, nfc);
> +
> +	writel(0x100, nfc->regs + NFC_REG_TIMING_CTL);
> +	writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG);
> +
> +	ret = sunxi_nand_chips_init(dev, nfc);
> +	if (ret) {
> +		dev_err(dev, "failed to init nand chips\n");
> +		goto out_sclk_unprepare;
> +	}
> +
> +	return 0;
> +
> +out_sclk_unprepare:
> +	clk_disable_unprepare(nfc->sclk);
> +out_ahb_clk_unprepare:
> +	clk_disable_unprepare(nfc->ahb_clk);
> +
> +	return ret;
> +}
> +
> +static const struct of_device_id sunxi_nfc_ids[] = {
> +	{ .compatible = "allwinner,sun4i-nfc" },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
> +
> +static struct platform_driver sunxi_nfc_driver = {
> +	.driver = {
> +		.name = "sunxi_nfc",
> +		.owner = THIS_MODULE,
> +		.of_match_table = of_match_ptr(sunxi_nfc_ids),
> +	},
> +	.probe = sunxi_nfc_probe,
> +};
> +module_platform_driver(sunxi_nfc_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Boris BREZILLON");
> +MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
> +MODULE_ALIAS("platform:sunxi_nfc");

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

* Re: [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
  2014-01-08 14:22   ` Boris BREZILLON
  (?)
@ 2014-01-08 21:28     ` Arnd Bergmann
  -1 siblings, 0 replies; 123+ messages in thread
From: Arnd Bergmann @ 2014-01-08 21:28 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Boris BREZILLON, Maxime Ripard, Rob Landley, Russell King,
	David Woodhouse, Grant Likely, devicetree, linux-doc, dev,
	linux-kernel, linux-mtd

On Wednesday 08 January 2014, Boris BREZILLON wrote:
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
> @@ -0,0 +1,71 @@
> +Allwinner NAND Flash Controller (NFC)
> +
> +Required properties:
> +- compatible : "allwinner,sun4i-nfc".
> +- reg : shall contain registers location and length for data and reg.
> +- interrupts : shall define the NFC interrupt.
> +- #address-cells: shall be set to 1. Encode the nand CS.
> +- #size-cells : shall be set to 0.
> +- clocks : shall reference NFC clocks.
> +- clock-names : NFC internal clock names. Shall contain :
> +    * "ahb_clk" : AHB gating clock
> +    * "sclk" : NFC clock
> +

One small request: Can we try to avoid the "NFC" name here? I think it's
too overloaded and people may confuse it with near-field communication,
which I'm sure will be supported in sunxi based devices at some point.

It doesn't hurt to also mention that the function block is called
nfc, but I think references to it are better named "nand", which is
less confusing.

	Arnd

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

* Re: [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
@ 2014-01-08 21:28     ` Arnd Bergmann
  0 siblings, 0 replies; 123+ messages in thread
From: Arnd Bergmann @ 2014-01-08 21:28 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	Boris BREZILLON, linux-mtd, Rob Landley, Grant Likely,
	Maxime Ripard, David Woodhouse

On Wednesday 08 January 2014, Boris BREZILLON wrote:
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
> @@ -0,0 +1,71 @@
> +Allwinner NAND Flash Controller (NFC)
> +
> +Required properties:
> +- compatible : "allwinner,sun4i-nfc".
> +- reg : shall contain registers location and length for data and reg.
> +- interrupts : shall define the NFC interrupt.
> +- #address-cells: shall be set to 1. Encode the nand CS.
> +- #size-cells : shall be set to 0.
> +- clocks : shall reference NFC clocks.
> +- clock-names : NFC internal clock names. Shall contain :
> +    * "ahb_clk" : AHB gating clock
> +    * "sclk" : NFC clock
> +

One small request: Can we try to avoid the "NFC" name here? I think it's
too overloaded and people may confuse it with near-field communication,
which I'm sure will be supported in sunxi based devices at some point.

It doesn't hurt to also mention that the function block is called
nfc, but I think references to it are better named "nand", which is
less confusing.

	Arnd

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

* [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
@ 2014-01-08 21:28     ` Arnd Bergmann
  0 siblings, 0 replies; 123+ messages in thread
From: Arnd Bergmann @ 2014-01-08 21:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 08 January 2014, Boris BREZILLON wrote:
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
> @@ -0,0 +1,71 @@
> +Allwinner NAND Flash Controller (NFC)
> +
> +Required properties:
> +- compatible : "allwinner,sun4i-nfc".
> +- reg : shall contain registers location and length for data and reg.
> +- interrupts : shall define the NFC interrupt.
> +- #address-cells: shall be set to 1. Encode the nand CS.
> +- #size-cells : shall be set to 0.
> +- clocks : shall reference NFC clocks.
> +- clock-names : NFC internal clock names. Shall contain :
> +    * "ahb_clk" : AHB gating clock
> +    * "sclk" : NFC clock
> +

One small request: Can we try to avoid the "NFC" name here? I think it's
too overloaded and people may confuse it with near-field communication,
which I'm sure will be supported in sunxi based devices at some point.

It doesn't hurt to also mention that the function block is called
nfc, but I think references to it are better named "nand", which is
less confusing.

	Arnd

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

* Re: [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
  2014-01-08 21:28     ` Arnd Bergmann
  (?)
@ 2014-01-09  8:31       ` boris brezillon
  -1 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-09  8:31 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd

On 08/01/2014 22:28, Arnd Bergmann wrote:
> On Wednesday 08 January 2014, Boris BREZILLON wrote:
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
>> @@ -0,0 +1,71 @@
>> +Allwinner NAND Flash Controller (NFC)
>> +
>> +Required properties:
>> +- compatible : "allwinner,sun4i-nfc".
>> +- reg : shall contain registers location and length for data and reg.
>> +- interrupts : shall define the NFC interrupt.
>> +- #address-cells: shall be set to 1. Encode the nand CS.
>> +- #size-cells : shall be set to 0.
>> +- clocks : shall reference NFC clocks.
>> +- clock-names : NFC internal clock names. Shall contain :
>> +    * "ahb_clk" : AHB gating clock
>> +    * "sclk" : NFC clock
>> +
> One small request: Can we try to avoid the "NFC" name here? I think it's
> too overloaded and people may confuse it with near-field communication,
> which I'm sure will be supported in sunxi based devices at some point.
>
> It doesn't hurt to also mention that the function block is called
> nfc, but I think references to it are better named "nand", which is
> less confusing.

Sure, I'll remove references to the NFC acronym:
  - change compatible string to "allwinner,sun4i-nand"
  - avoid NFC references in the doc
  - rename the driver into sunxi-nand.c (formerly sunxi_nfc.c)

Do you see any other references to this acronym ?


Best Regards,

Boris
> 	Arnd


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

* Re: [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
@ 2014-01-09  8:31       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-09  8:31 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse

On 08/01/2014 22:28, Arnd Bergmann wrote:
> On Wednesday 08 January 2014, Boris BREZILLON wrote:
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
>> @@ -0,0 +1,71 @@
>> +Allwinner NAND Flash Controller (NFC)
>> +
>> +Required properties:
>> +- compatible : "allwinner,sun4i-nfc".
>> +- reg : shall contain registers location and length for data and reg.
>> +- interrupts : shall define the NFC interrupt.
>> +- #address-cells: shall be set to 1. Encode the nand CS.
>> +- #size-cells : shall be set to 0.
>> +- clocks : shall reference NFC clocks.
>> +- clock-names : NFC internal clock names. Shall contain :
>> +    * "ahb_clk" : AHB gating clock
>> +    * "sclk" : NFC clock
>> +
> One small request: Can we try to avoid the "NFC" name here? I think it's
> too overloaded and people may confuse it with near-field communication,
> which I'm sure will be supported in sunxi based devices at some point.
>
> It doesn't hurt to also mention that the function block is called
> nfc, but I think references to it are better named "nand", which is
> less confusing.

Sure, I'll remove references to the NFC acronym:
  - change compatible string to "allwinner,sun4i-nand"
  - avoid NFC references in the doc
  - rename the driver into sunxi-nand.c (formerly sunxi_nfc.c)

Do you see any other references to this acronym ?


Best Regards,

Boris
> 	Arnd

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

* [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
@ 2014-01-09  8:31       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-09  8:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/01/2014 22:28, Arnd Bergmann wrote:
> On Wednesday 08 January 2014, Boris BREZILLON wrote:
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
>> @@ -0,0 +1,71 @@
>> +Allwinner NAND Flash Controller (NFC)
>> +
>> +Required properties:
>> +- compatible : "allwinner,sun4i-nfc".
>> +- reg : shall contain registers location and length for data and reg.
>> +- interrupts : shall define the NFC interrupt.
>> +- #address-cells: shall be set to 1. Encode the nand CS.
>> +- #size-cells : shall be set to 0.
>> +- clocks : shall reference NFC clocks.
>> +- clock-names : NFC internal clock names. Shall contain :
>> +    * "ahb_clk" : AHB gating clock
>> +    * "sclk" : NFC clock
>> +
> One small request: Can we try to avoid the "NFC" name here? I think it's
> too overloaded and people may confuse it with near-field communication,
> which I'm sure will be supported in sunxi based devices at some point.
>
> It doesn't hurt to also mention that the function block is called
> nfc, but I think references to it are better named "nand", which is
> less confusing.

Sure, I'll remove references to the NFC acronym:
  - change compatible string to "allwinner,sun4i-nand"
  - avoid NFC references in the doc
  - rename the driver into sunxi-nand.c (formerly sunxi_nfc.c)

Do you see any other references to this acronym ?


Best Regards,

Boris
> 	Arnd

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-09  8:36           ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-09  8:36 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel

On 08/01/2014 20:13, Jason Gunthorpe wrote:
> On Wed, Jan 08, 2014 at 08:00:02PM +0100, boris brezillon wrote:
>> Hello Jason,
>>
>> Le 08/01/2014 19:34, Jason Gunthorpe a ?crit :
>>> On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
>>>
>>>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>>>> +{
>>>> +	memset(timings, 0, sizeof(*timings));
>>>> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>>>> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>>>> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
>>> [..]
>>>
>>> A while ago when discussing another controller it was pointed out
>>> these values are all auto-probable directly from the NAND via a ONFI
>>> defined GET FEATURE @0x01 query, and adding these timings to the DT
>>> was NAK'd..
>>>
>>> Basically you set the interface to the slowest ONFI timing mode, do
>>> the GET FEATURE to the NAND chip and then increase the interface speed
>>> to the highest mutually supported ONFI mode.
>>> Is there some reason you need to encode this in the DT?
>> What if the NAND does not support the ONFI interface (and this is
>> exactly the case for the NAND available on the cubietruck board:
>> H27UCG8T2ATR).
> Sounds like a good reason to me!
>
> You might want to check if you can boil down the DT timings from the
> huge list to just an ONFI mode number..

Sure, but the sunxi driver needs at least 19 of them...

>
> I'd echo Rob's comments, the property needs to include the units
> in the name, and I strongly recommend picoseconds for these
> values.

Agreed, picosecond is a more future-proof unit.

>
> Also, you might want to check that the ONFI names for these parameters
> are used, not a vendor specific name to try and avoid confusion.

I'll check it.

Thanks.

Best Regards,

Boris

>
> Jason


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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-09  8:36           ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-09  8:36 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, dev-3kdeTeqwOZ9EV1b7eY7vFQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 08/01/2014 20:13, Jason Gunthorpe wrote:
> On Wed, Jan 08, 2014 at 08:00:02PM +0100, boris brezillon wrote:
>> Hello Jason,
>>
>> Le 08/01/2014 19:34, Jason Gunthorpe a ?crit :
>>> On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
>>>
>>>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>>>> +{
>>>> +	memset(timings, 0, sizeof(*timings));
>>>> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>>>> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>>>> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
>>> [..]
>>>
>>> A while ago when discussing another controller it was pointed out
>>> these values are all auto-probable directly from the NAND via a ONFI
>>> defined GET FEATURE @0x01 query, and adding these timings to the DT
>>> was NAK'd..
>>>
>>> Basically you set the interface to the slowest ONFI timing mode, do
>>> the GET FEATURE to the NAND chip and then increase the interface speed
>>> to the highest mutually supported ONFI mode.
>>> Is there some reason you need to encode this in the DT?
>> What if the NAND does not support the ONFI interface (and this is
>> exactly the case for the NAND available on the cubietruck board:
>> H27UCG8T2ATR).
> Sounds like a good reason to me!
>
> You might want to check if you can boil down the DT timings from the
> huge list to just an ONFI mode number..

Sure, but the sunxi driver needs at least 19 of them...

>
> I'd echo Rob's comments, the property needs to include the units
> in the name, and I strongly recommend picoseconds for these
> values.

Agreed, picosecond is a more future-proof unit.

>
> Also, you might want to check that the ONFI names for these parameters
> are used, not a vendor specific name to try and avoid confusion.

I'll check it.

Thanks.

Best Regards,

Boris

>
> Jason

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-09  8:36           ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-09  8:36 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On 08/01/2014 20:13, Jason Gunthorpe wrote:
> On Wed, Jan 08, 2014 at 08:00:02PM +0100, boris brezillon wrote:
>> Hello Jason,
>>
>> Le 08/01/2014 19:34, Jason Gunthorpe a ?crit :
>>> On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
>>>
>>>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>>>> +{
>>>> +	memset(timings, 0, sizeof(*timings));
>>>> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>>>> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>>>> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
>>> [..]
>>>
>>> A while ago when discussing another controller it was pointed out
>>> these values are all auto-probable directly from the NAND via a ONFI
>>> defined GET FEATURE @0x01 query, and adding these timings to the DT
>>> was NAK'd..
>>>
>>> Basically you set the interface to the slowest ONFI timing mode, do
>>> the GET FEATURE to the NAND chip and then increase the interface speed
>>> to the highest mutually supported ONFI mode.
>>> Is there some reason you need to encode this in the DT?
>> What if the NAND does not support the ONFI interface (and this is
>> exactly the case for the NAND available on the cubietruck board:
>> H27UCG8T2ATR).
> Sounds like a good reason to me!
>
> You might want to check if you can boil down the DT timings from the
> huge list to just an ONFI mode number..

Sure, but the sunxi driver needs at least 19 of them...

>
> I'd echo Rob's comments, the property needs to include the units
> in the name, and I strongly recommend picoseconds for these
> values.

Agreed, picosecond is a more future-proof unit.

>
> Also, you might want to check that the ONFI names for these parameters
> are used, not a vendor specific name to try and avoid confusion.

I'll check it.

Thanks.

Best Regards,

Boris

>
> Jason

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-09  8:36           ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-09  8:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/01/2014 20:13, Jason Gunthorpe wrote:
> On Wed, Jan 08, 2014 at 08:00:02PM +0100, boris brezillon wrote:
>> Hello Jason,
>>
>> Le 08/01/2014 19:34, Jason Gunthorpe a ?crit :
>>> On Wed, Jan 08, 2014 at 03:21:58PM +0100, Boris BREZILLON wrote:
>>>
>>>> +int of_get_nand_timings(struct device_node *np, struct nand_timings *timings)
>>>> +{
>>>> +	memset(timings, 0, sizeof(*timings));
>>>> +	of_property_read_u32(np, "tCLS-min", &timings->tCLS_min);
>>>> +	of_property_read_u32(np, "tCLH-min", &timings->tCLH_min);
>>>> +	of_property_read_u32(np, "tCS-min", &timings->tCS_min);
>>> [..]
>>>
>>> A while ago when discussing another controller it was pointed out
>>> these values are all auto-probable directly from the NAND via a ONFI
>>> defined GET FEATURE @0x01 query, and adding these timings to the DT
>>> was NAK'd..
>>>
>>> Basically you set the interface to the slowest ONFI timing mode, do
>>> the GET FEATURE to the NAND chip and then increase the interface speed
>>> to the highest mutually supported ONFI mode.
>>> Is there some reason you need to encode this in the DT?
>> What if the NAND does not support the ONFI interface (and this is
>> exactly the case for the NAND available on the cubietruck board:
>> H27UCG8T2ATR).
> Sounds like a good reason to me!
>
> You might want to check if you can boil down the DT timings from the
> huge list to just an ONFI mode number..

Sure, but the sunxi driver needs at least 19 of them...

>
> I'd echo Rob's comments, the property needs to include the units
> in the name, and I strongly recommend picoseconds for these
> values.

Agreed, picosecond is a more future-proof unit.

>
> Also, you might want to check that the ONFI names for these parameters
> are used, not a vendor specific name to try and avoid confusion.

I'll check it.

Thanks.

Best Regards,

Boris

>
> Jason

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

* Re: [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
  2014-01-09  8:31       ` boris brezillon
  (?)
@ 2014-01-09 10:00         ` Arnd Bergmann
  -1 siblings, 0 replies; 123+ messages in thread
From: Arnd Bergmann @ 2014-01-09 10:00 UTC (permalink / raw)
  To: boris brezillon
  Cc: linux-arm-kernel, Maxime Ripard, Rob Landley, Russell King,
	David Woodhouse, Grant Likely, devicetree, linux-doc, dev,
	linux-kernel, linux-mtd

On Thursday 09 January 2014, boris brezillon wrote:
> Sure, I'll remove references to the NFC acronym:
>   - change compatible string to "allwinner,sun4i-nand"
>   - avoid NFC references in the doc
>   - rename the driver into sunxi-nand.c (formerly sunxi_nfc.c)
> 
> Do you see any other references to this acronym ?
> 

Those are the important ones, thanks!

Regarding the binding, I would mention nfc once there to help people
that happen to look for that.

	Arnd

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

* Re: [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
@ 2014-01-09 10:00         ` Arnd Bergmann
  0 siblings, 0 replies; 123+ messages in thread
From: Arnd Bergmann @ 2014-01-09 10:00 UTC (permalink / raw)
  To: boris brezillon
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On Thursday 09 January 2014, boris brezillon wrote:
> Sure, I'll remove references to the NFC acronym:
>   - change compatible string to "allwinner,sun4i-nand"
>   - avoid NFC references in the doc
>   - rename the driver into sunxi-nand.c (formerly sunxi_nfc.c)
> 
> Do you see any other references to this acronym ?
> 

Those are the important ones, thanks!

Regarding the binding, I would mention nfc once there to help people
that happen to look for that.

	Arnd

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

* [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc
@ 2014-01-09 10:00         ` Arnd Bergmann
  0 siblings, 0 replies; 123+ messages in thread
From: Arnd Bergmann @ 2014-01-09 10:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 09 January 2014, boris brezillon wrote:
> Sure, I'll remove references to the NFC acronym:
>   - change compatible string to "allwinner,sun4i-nand"
>   - avoid NFC references in the doc
>   - rename the driver into sunxi-nand.c (formerly sunxi_nfc.c)
> 
> Do you see any other references to this acronym ?
> 

Those are the important ones, thanks!

Regarding the binding, I would mention nfc once there to help people
that happen to look for that.

	Arnd

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-09 17:35             ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-09 17:35 UTC (permalink / raw)
  To: boris brezillon
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On Thu, Jan 09, 2014 at 09:36:18AM +0100, boris brezillon wrote:

> >You might want to check if you can boil down the DT timings from the
> >huge list to just an ONFI mode number..
> 
> Sure, but the sunxi driver needs at least 19 of them...

So does mvebu's NAND driver..

What I ment was you could have a

  onfi,nand-timing-mode = 0

in the DT. Each of the modes defines all ~19 parameters, higher modes
are faster.

Pick a mode value that fits all the parameters of the connected
non-ONFI flash.

This would be instead of defining each parameter
individually.. Provide some helpers to convert from a onfi mode number
to all the onfi defined timing parameters so that drivers can
configure the HW..

Jason

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-09 17:35             ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-09 17:35 UTC (permalink / raw)
  To: boris brezillon
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Russell King,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, dev-3kdeTeqwOZ9EV1b7eY7vFQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Landley,
	Grant Likely, Maxime Ripard, David Woodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Thu, Jan 09, 2014 at 09:36:18AM +0100, boris brezillon wrote:

> >You might want to check if you can boil down the DT timings from the
> >huge list to just an ONFI mode number..
> 
> Sure, but the sunxi driver needs at least 19 of them...

So does mvebu's NAND driver..

What I ment was you could have a

  onfi,nand-timing-mode = 0

in the DT. Each of the modes defines all ~19 parameters, higher modes
are faster.

Pick a mode value that fits all the parameters of the connected
non-ONFI flash.

This would be instead of defining each parameter
individually.. Provide some helpers to convert from a onfi mode number
to all the onfi defined timing parameters so that drivers can
configure the HW..

Jason

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-09 17:35             ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-09 17:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 09, 2014 at 09:36:18AM +0100, boris brezillon wrote:

> >You might want to check if you can boil down the DT timings from the
> >huge list to just an ONFI mode number..
> 
> Sure, but the sunxi driver needs at least 19 of them...

So does mvebu's NAND driver..

What I ment was you could have a

  onfi,nand-timing-mode = 0

in the DT. Each of the modes defines all ~19 parameters, higher modes
are faster.

Pick a mode value that fits all the parameters of the connected
non-ONFI flash.

This would be instead of defining each parameter
individually.. Provide some helpers to convert from a onfi mode number
to all the onfi defined timing parameters so that drivers can
configure the HW..

Jason

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

* Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-11 13:38   ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-11 13:38 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, linux-kernel, linux-arm-kernel, linux-mtd,
	dev, Boris BREZILLON

On 08/01/2014 15:21, Boris BREZILLON wrote:
> Hello,
>
> This series add the sunxi NFC support with up to 8 NAND chip connected.
> I'm still in the early stages drivers development and some key features are
> missing, but it's usable (I tested it on the cubietruck board).
>
> Here's what's missing:
>   - HW ECC support
>   - DMA support
>   - HW randomization support
>   - many more improvements
>
> This series depends on Emilio's patch series implementing mod0 clks
> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
> + an other patch not yet posted
> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)

During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
NAND flash controller I found this document describing the Altera NAND 
flash controller
(which is in turn based on a cadence IP):

http://www.altera.com/literature/hb/arria-v/av_54010.pdf

This really looks like the sunxi NAND flash controller (except for the 
registers positions
and contents) ;-)

>
> Best Regards,
>
> Boris
>
> Boris BREZILLON (9):
>    mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
>    mtd: nand: define struct nand_timings
>    of: mtd: add NAND timings retrieval support
>    of: mtd: add NAND timings bindings documentation
>    mtd: nand: add sunxi NFC support
>    mtd: nand: add sunxi NFC dt bindings doc
>    ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
>    ARM: dt/sunxi: add NFC pinctrl pin definitions
>    ARM: sunxi/dt: enable NAND on cubietruck board
>
>   Documentation/devicetree/bindings/mtd/nand.txt     |   34 +
>   .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++
>   arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |   33 +
>   arch/arm/boot/dts/sun7i-a20.dtsi                   |   35 +
>   drivers/mtd/nand/Kconfig                           |    6 +
>   drivers/mtd/nand/Makefile                          |    1 +
>   drivers/mtd/nand/nand_base.c                       |   37 ++
>   drivers/mtd/nand/sunxi_nfc.c                       |  700 ++++++++++++++++++++
>   drivers/of/of_mtd.c                                |   47 ++
>   include/linux/mtd/nand.h                           |   44 ++
>   include/linux/of_mtd.h                             |    9 +
>   11 files changed, 1017 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt
>   create mode 100644 drivers/mtd/nand/sunxi_nfc.c
>


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

* Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-11 13:38   ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-11 13:38 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	dev-3kdeTeqwOZ9EV1b7eY7vFQ, Boris BREZILLON

On 08/01/2014 15:21, Boris BREZILLON wrote:
> Hello,
>
> This series add the sunxi NFC support with up to 8 NAND chip connected.
> I'm still in the early stages drivers development and some key features are
> missing, but it's usable (I tested it on the cubietruck board).
>
> Here's what's missing:
>   - HW ECC support
>   - DMA support
>   - HW randomization support
>   - many more improvements
>
> This series depends on Emilio's patch series implementing mod0 clks
> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
> + an other patch not yet posted
> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)

During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
NAND flash controller I found this document describing the Altera NAND 
flash controller
(which is in turn based on a cadence IP):

http://www.altera.com/literature/hb/arria-v/av_54010.pdf

This really looks like the sunxi NAND flash controller (except for the 
registers positions
and contents) ;-)

>
> Best Regards,
>
> Boris
>
> Boris BREZILLON (9):
>    mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
>    mtd: nand: define struct nand_timings
>    of: mtd: add NAND timings retrieval support
>    of: mtd: add NAND timings bindings documentation
>    mtd: nand: add sunxi NFC support
>    mtd: nand: add sunxi NFC dt bindings doc
>    ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
>    ARM: dt/sunxi: add NFC pinctrl pin definitions
>    ARM: sunxi/dt: enable NAND on cubietruck board
>
>   Documentation/devicetree/bindings/mtd/nand.txt     |   34 +
>   .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++
>   arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |   33 +
>   arch/arm/boot/dts/sun7i-a20.dtsi                   |   35 +
>   drivers/mtd/nand/Kconfig                           |    6 +
>   drivers/mtd/nand/Makefile                          |    1 +
>   drivers/mtd/nand/nand_base.c                       |   37 ++
>   drivers/mtd/nand/sunxi_nfc.c                       |  700 ++++++++++++++++++++
>   drivers/of/of_mtd.c                                |   47 ++
>   include/linux/mtd/nand.h                           |   44 ++
>   include/linux/of_mtd.h                             |    9 +
>   11 files changed, 1017 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt
>   create mode 100644 drivers/mtd/nand/sunxi_nfc.c
>

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

* Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-11 13:38   ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-11 13:38 UTC (permalink / raw)
  To: Maxime Ripard, Rob Landley, Russell King, David Woodhouse, Grant Likely
  Cc: devicetree, linux-doc, dev, linux-kernel, Boris BREZILLON,
	linux-mtd, linux-arm-kernel

On 08/01/2014 15:21, Boris BREZILLON wrote:
> Hello,
>
> This series add the sunxi NFC support with up to 8 NAND chip connected.
> I'm still in the early stages drivers development and some key features are
> missing, but it's usable (I tested it on the cubietruck board).
>
> Here's what's missing:
>   - HW ECC support
>   - DMA support
>   - HW randomization support
>   - many more improvements
>
> This series depends on Emilio's patch series implementing mod0 clks
> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
> + an other patch not yet posted
> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)

During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
NAND flash controller I found this document describing the Altera NAND 
flash controller
(which is in turn based on a cadence IP):

http://www.altera.com/literature/hb/arria-v/av_54010.pdf

This really looks like the sunxi NAND flash controller (except for the 
registers positions
and contents) ;-)

>
> Best Regards,
>
> Boris
>
> Boris BREZILLON (9):
>    mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
>    mtd: nand: define struct nand_timings
>    of: mtd: add NAND timings retrieval support
>    of: mtd: add NAND timings bindings documentation
>    mtd: nand: add sunxi NFC support
>    mtd: nand: add sunxi NFC dt bindings doc
>    ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
>    ARM: dt/sunxi: add NFC pinctrl pin definitions
>    ARM: sunxi/dt: enable NAND on cubietruck board
>
>   Documentation/devicetree/bindings/mtd/nand.txt     |   34 +
>   .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++
>   arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |   33 +
>   arch/arm/boot/dts/sun7i-a20.dtsi                   |   35 +
>   drivers/mtd/nand/Kconfig                           |    6 +
>   drivers/mtd/nand/Makefile                          |    1 +
>   drivers/mtd/nand/nand_base.c                       |   37 ++
>   drivers/mtd/nand/sunxi_nfc.c                       |  700 ++++++++++++++++++++
>   drivers/of/of_mtd.c                                |   47 ++
>   include/linux/mtd/nand.h                           |   44 ++
>   include/linux/of_mtd.h                             |    9 +
>   11 files changed, 1017 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt
>   create mode 100644 drivers/mtd/nand/sunxi_nfc.c
>

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

* [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-11 13:38   ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-11 13:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/01/2014 15:21, Boris BREZILLON wrote:
> Hello,
>
> This series add the sunxi NFC support with up to 8 NAND chip connected.
> I'm still in the early stages drivers development and some key features are
> missing, but it's usable (I tested it on the cubietruck board).
>
> Here's what's missing:
>   - HW ECC support
>   - DMA support
>   - HW randomization support
>   - many more improvements
>
> This series depends on Emilio's patch series implementing mod0 clks
> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
> + an other patch not yet posted
> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)

During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
NAND flash controller I found this document describing the Altera NAND 
flash controller
(which is in turn based on a cadence IP):

http://www.altera.com/literature/hb/arria-v/av_54010.pdf

This really looks like the sunxi NAND flash controller (except for the 
registers positions
and contents) ;-)

>
> Best Regards,
>
> Boris
>
> Boris BREZILLON (9):
>    mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
>    mtd: nand: define struct nand_timings
>    of: mtd: add NAND timings retrieval support
>    of: mtd: add NAND timings bindings documentation
>    mtd: nand: add sunxi NFC support
>    mtd: nand: add sunxi NFC dt bindings doc
>    ARM: dt/sunxi: add NFC node to Allwinner A20 SoC
>    ARM: dt/sunxi: add NFC pinctrl pin definitions
>    ARM: sunxi/dt: enable NAND on cubietruck board
>
>   Documentation/devicetree/bindings/mtd/nand.txt     |   34 +
>   .../devicetree/bindings/mtd/sunxi-nand.txt         |   71 ++
>   arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |   33 +
>   arch/arm/boot/dts/sun7i-a20.dtsi                   |   35 +
>   drivers/mtd/nand/Kconfig                           |    6 +
>   drivers/mtd/nand/Makefile                          |    1 +
>   drivers/mtd/nand/nand_base.c                       |   37 ++
>   drivers/mtd/nand/sunxi_nfc.c                       |  700 ++++++++++++++++++++
>   drivers/of/of_mtd.c                                |   47 ++
>   include/linux/mtd/nand.h                           |   44 ++
>   include/linux/of_mtd.h                             |    9 +
>   11 files changed, 1017 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt
>   create mode 100644 drivers/mtd/nand/sunxi_nfc.c
>

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
       [not found]         ` <1389474709.22660.4.camel@localhost>
@ 2014-01-13  9:02             ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-13  9:02 UTC (permalink / raw)
  To: Henrik Nordström
  Cc: dev, Maxime Ripard, David Woodhouse, linux-mtd, linux-kernel

Hi Henrik,

On 11/01/2014 22:11, Henrik Nordström wrote:
> <bbrezillon> thanks for pointing out your documents
> <bbrezillon> I'm trying to get the NAND driver with HW ECC (and HW RND)
> without using DMA at all
>
> I tried many things but did not quite get the ECC reading command to
> return meaningful resuts. But should work somehow.
>
> <bbrezillon> do you have any other information I could use to do this ?
>
> Not really. There is no known code to look at using the nand controller
> without DMA. All allwinner code uses DMA even the boot ROM (BROM).
>
> <bbrezillon> For example, I wonder why there are 2 RAM sectors (the
> driver I found only make use of RAM0)
>
> I think it's used during DMA to fetch next sector while the previous one
> is transferred by DMA. But not sure.

Some feedback on my tests:

- I managed to get HW ECC working without any DMA transfer (using CMD = 01):
   * I only tested the sequential ECC => ECC are stored between 2 data 
blocks (1024 byte)
   * Non sequential ECC should work if I store ECC bytes in the OOB area 
too (I'll just have
      to send RANDOM_OUT commands to move to the OOB area before sending 
the ECC
      cmd and another RANDOM_OUT to go back to the DATA area)

- The HW RND (randomizer) works too, I'll just have to figure out how 
this could be
   mainlined:
    * using a simple dt property to tell the controller it should enable 
the randomizer
    * provide an interface (like the nand_ecc_ctrl struct ) for other to 
add their own
       randomizer implementation (this was requested: 
https://lkml.org/lkml/2013/12/13/154)


The most complicated part is the boot0 partition.

Tell me if I'm wrong, but here's what I understood from your work (and 
yuq's work too):

boot 0 part properties:
- uses sequential ECC
- uses 1024 bytes ECC blocks
- boot0 code is stored only on the first ECC block of each page (1024 
bytes + ecc bytes)
- boot0 code is stored on the first 64 pages of the first block
- boot0 uses HW randomizer with a specific rnd seed (0x4a80)

It's not that complicated to read/write from/to boot0, but it's a bit 
more to mainline this
implementation:
  - the nand chip must use the same ECC algorithm and ECC layout on the 
whole flash
    (no partition specific config available)
- you cannot mark some part of pages as unused => the nand driver will 
write the
   whole page, not just the first ECC block (1024 bytes)

I thought about manually creating an mtd device that fullfils these 
needs (in case we
encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm 
not sure
this is the right approach.

Any ideas ?


Best Regards,

Boris
>
> Regards
> Henrik
>


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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-13  9:02             ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-13  9:02 UTC (permalink / raw)
  To: Henrik Nordström
  Cc: dev, linux-mtd, Maxime Ripard, David Woodhouse, linux-kernel

Hi Henrik,

On 11/01/2014 22:11, Henrik Nordström wrote:
> <bbrezillon> thanks for pointing out your documents
> <bbrezillon> I'm trying to get the NAND driver with HW ECC (and HW RND)
> without using DMA at all
>
> I tried many things but did not quite get the ECC reading command to
> return meaningful resuts. But should work somehow.
>
> <bbrezillon> do you have any other information I could use to do this ?
>
> Not really. There is no known code to look at using the nand controller
> without DMA. All allwinner code uses DMA even the boot ROM (BROM).
>
> <bbrezillon> For example, I wonder why there are 2 RAM sectors (the
> driver I found only make use of RAM0)
>
> I think it's used during DMA to fetch next sector while the previous one
> is transferred by DMA. But not sure.

Some feedback on my tests:

- I managed to get HW ECC working without any DMA transfer (using CMD = 01):
   * I only tested the sequential ECC => ECC are stored between 2 data 
blocks (1024 byte)
   * Non sequential ECC should work if I store ECC bytes in the OOB area 
too (I'll just have
      to send RANDOM_OUT commands to move to the OOB area before sending 
the ECC
      cmd and another RANDOM_OUT to go back to the DATA area)

- The HW RND (randomizer) works too, I'll just have to figure out how 
this could be
   mainlined:
    * using a simple dt property to tell the controller it should enable 
the randomizer
    * provide an interface (like the nand_ecc_ctrl struct ) for other to 
add their own
       randomizer implementation (this was requested: 
https://lkml.org/lkml/2013/12/13/154)


The most complicated part is the boot0 partition.

Tell me if I'm wrong, but here's what I understood from your work (and 
yuq's work too):

boot 0 part properties:
- uses sequential ECC
- uses 1024 bytes ECC blocks
- boot0 code is stored only on the first ECC block of each page (1024 
bytes + ecc bytes)
- boot0 code is stored on the first 64 pages of the first block
- boot0 uses HW randomizer with a specific rnd seed (0x4a80)

It's not that complicated to read/write from/to boot0, but it's a bit 
more to mainline this
implementation:
  - the nand chip must use the same ECC algorithm and ECC layout on the 
whole flash
    (no partition specific config available)
- you cannot mark some part of pages as unused => the nand driver will 
write the
   whole page, not just the first ECC block (1024 bytes)

I thought about manually creating an mtd device that fullfils these 
needs (in case we
encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm 
not sure
this is the right approach.

Any ideas ?


Best Regards,

Boris
>
> Regards
> Henrik
>

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
  2014-01-13  9:02             ` boris brezillon
@ 2014-01-13  9:48               ` Henrik Nordström
  -1 siblings, 0 replies; 123+ messages in thread
From: Henrik Nordström @ 2014-01-13  9:48 UTC (permalink / raw)
  To: linux-sunxi; +Cc: dev, Maxime Ripard, David Woodhouse, linux-mtd, linux-kernel

mån 2014-01-13 klockan 10:02 +0100 skrev boris brezillon:

> The most complicated part is the boot0 partition.

Not really. It's only a little different (sequential ECC, static
randomizer seed on every page).

> Tell me if I'm wrong, but here's what I understood from your work (and 
> yuq's work too):
> 
> boot 0 part properties:
> - uses sequential ECC

Yes

> - uses 1024 bytes ECC blocks

Seems to support a couple modes.

> - boot0 code is stored only on the first ECC block of each page (1024 
> bytes + ecc bytes)

No, it reads a whole page at a time in sequental mode
(data,ecc,data,ecc,data,ecc,data,ecc...).

> - boot0 code is stored on the first 64 pages of the first block

boot0 is restricted in size by available memory size (24KB max). 

iirc multiple blocks is tried until a valid one is found.

also I am pretty sure boot1 is stored using the same flash format, but
have not looked in detail at how boot0 reads boot1 as it's a detail of
boot0 software implementation and not needed when using u-boot.

> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)

Yes.

> It's not that complicated to read/write from/to boot0, but it's a bit 
> more to mainline this
> implementation:

Ah, yes. It's different.

But isn't there other SoCs having similar issue with NAND boot blocks?
Maybe some guidance can be found there?

Qiang Yu (yuq) selected to implement the sunxi boot area driver using a
custom character device in his attempt in writing a sunxi mtd driver.
That approach works, but can't comment on if it's the right approach or
not.

   https://github.com/yuq/sunxi-nfc-mtd

>   - the nand chip must use the same ECC algorithm and ECC layout on the 
> whole flash
>     (no partition specific config available)

iirc there is an interface for dynamically selecting ECC mode and other
parameers. Or maybe that's only u-boot mtd?

> - you cannot mark some part of pages as unused => the nand driver will 
> write the
>    whole page, not just the first ECC block (1024 bytes)

Not sure what you mean. Why would something be marked as unused? The
boot area is not a filesystem, it is a single linear blob (or two if
boot1 is in the same format, but mostly irrelevant).

> I thought about manually creating an mtd device that fullfils these 
> needs (in case we
> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm 
> not sure
> this is the right approach.

Would work, if you also can make sure the two do not stomp on each
others. Should be divided by NAND block range.

Regards
Henrik


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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-13  9:48               ` Henrik Nordström
  0 siblings, 0 replies; 123+ messages in thread
From: Henrik Nordström @ 2014-01-13  9:48 UTC (permalink / raw)
  To: linux-sunxi; +Cc: dev, linux-mtd, Maxime Ripard, David Woodhouse, linux-kernel

mån 2014-01-13 klockan 10:02 +0100 skrev boris brezillon:

> The most complicated part is the boot0 partition.

Not really. It's only a little different (sequential ECC, static
randomizer seed on every page).

> Tell me if I'm wrong, but here's what I understood from your work (and 
> yuq's work too):
> 
> boot 0 part properties:
> - uses sequential ECC

Yes

> - uses 1024 bytes ECC blocks

Seems to support a couple modes.

> - boot0 code is stored only on the first ECC block of each page (1024 
> bytes + ecc bytes)

No, it reads a whole page at a time in sequental mode
(data,ecc,data,ecc,data,ecc,data,ecc...).

> - boot0 code is stored on the first 64 pages of the first block

boot0 is restricted in size by available memory size (24KB max). 

iirc multiple blocks is tried until a valid one is found.

also I am pretty sure boot1 is stored using the same flash format, but
have not looked in detail at how boot0 reads boot1 as it's a detail of
boot0 software implementation and not needed when using u-boot.

> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)

Yes.

> It's not that complicated to read/write from/to boot0, but it's a bit 
> more to mainline this
> implementation:

Ah, yes. It's different.

But isn't there other SoCs having similar issue with NAND boot blocks?
Maybe some guidance can be found there?

Qiang Yu (yuq) selected to implement the sunxi boot area driver using a
custom character device in his attempt in writing a sunxi mtd driver.
That approach works, but can't comment on if it's the right approach or
not.

   https://github.com/yuq/sunxi-nfc-mtd

>   - the nand chip must use the same ECC algorithm and ECC layout on the 
> whole flash
>     (no partition specific config available)

iirc there is an interface for dynamically selecting ECC mode and other
parameers. Or maybe that's only u-boot mtd?

> - you cannot mark some part of pages as unused => the nand driver will 
> write the
>    whole page, not just the first ECC block (1024 bytes)

Not sure what you mean. Why would something be marked as unused? The
boot area is not a filesystem, it is a single linear blob (or two if
boot1 is in the same format, but mostly irrelevant).

> I thought about manually creating an mtd device that fullfils these 
> needs (in case we
> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm 
> not sure
> this is the right approach.

Would work, if you also can make sure the two do not stomp on each
others. Should be divided by NAND block range.

Regards
Henrik

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-15 15:09               ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-15 15:09 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

Hello Jason,

On 09/01/2014 18:35, Jason Gunthorpe wrote:
> On Thu, Jan 09, 2014 at 09:36:18AM +0100, boris brezillon wrote:
>
>>> You might want to check if you can boil down the DT timings from the
>>> huge list to just an ONFI mode number..
>> Sure, but the sunxi driver needs at least 19 of them...
> So does mvebu's NAND driver..
>
> What I ment was you could have a
>
>    onfi,nand-timing-mode = 0
>
> in the DT. Each of the modes defines all ~19 parameters, higher modes
> are faster.
>
> Pick a mode value that fits all the parameters of the connected
> non-ONFI flash.
>
> This would be instead of defining each parameter
> individually.. Provide some helpers to convert from a onfi mode number
> to all the onfi defined timing parameters so that drivers can
> configure the HW..

Are you suggesting we should provide a function that converts these
modes into a nand_timings struct, or just use the timing modes and
let the NAND controller drivers configure its IP accordingly ?

I found the ONFI timing tables in this document:

www.*onfi*.org/~/media/*ONFI*/specs/*onfi*_3_1_spec.pdf‎ (chapter 4.16).

I suppose my nand_timings struct should use the names described
page 110-111 (at least if we decide to use nand_timings and not
nand_timing_modes), right ?

Best Regards,

Boris

>
> Jason


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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-15 15:09               ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-15 15:09 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Russell King,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, dev-3kdeTeqwOZ9EV1b7eY7vFQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Landley,
	Grant Likely, Maxime Ripard, David Woodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hello Jason,

On 09/01/2014 18:35, Jason Gunthorpe wrote:
> On Thu, Jan 09, 2014 at 09:36:18AM +0100, boris brezillon wrote:
>
>>> You might want to check if you can boil down the DT timings from the
>>> huge list to just an ONFI mode number..
>> Sure, but the sunxi driver needs at least 19 of them...
> So does mvebu's NAND driver..
>
> What I ment was you could have a
>
>    onfi,nand-timing-mode = 0
>
> in the DT. Each of the modes defines all ~19 parameters, higher modes
> are faster.
>
> Pick a mode value that fits all the parameters of the connected
> non-ONFI flash.
>
> This would be instead of defining each parameter
> individually.. Provide some helpers to convert from a onfi mode number
> to all the onfi defined timing parameters so that drivers can
> configure the HW..

Are you suggesting we should provide a function that converts these
modes into a nand_timings struct, or just use the timing modes and
let the NAND controller drivers configure its IP accordingly ?

I found the ONFI timing tables in this document:

www.*onfi*.org/~/media/*ONFI*/specs/*onfi*_3_1_spec.pdf‎ (chapter 4.16).

I suppose my nand_timings struct should use the names described
page 110-111 (at least if we decide to use nand_timings and not
nand_timing_modes), right ?

Best Regards,

Boris

>
> Jason

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-15 15:09               ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-15 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Jason,

On 09/01/2014 18:35, Jason Gunthorpe wrote:
> On Thu, Jan 09, 2014 at 09:36:18AM +0100, boris brezillon wrote:
>
>>> You might want to check if you can boil down the DT timings from the
>>> huge list to just an ONFI mode number..
>> Sure, but the sunxi driver needs at least 19 of them...
> So does mvebu's NAND driver..
>
> What I ment was you could have a
>
>    onfi,nand-timing-mode = 0
>
> in the DT. Each of the modes defines all ~19 parameters, higher modes
> are faster.
>
> Pick a mode value that fits all the parameters of the connected
> non-ONFI flash.
>
> This would be instead of defining each parameter
> individually.. Provide some helpers to convert from a onfi mode number
> to all the onfi defined timing parameters so that drivers can
> configure the HW..

Are you suggesting we should provide a function that converts these
modes into a nand_timings struct, or just use the timing modes and
let the NAND controller drivers configure its IP accordingly ?

I found the ONFI timing tables in this document:

www.*onfi*.org/~/media/*ONFI*/specs/*onfi*_3_1_spec.pdf? (chapter 4.16).

I suppose my nand_timings struct should use the names described
page 110-111 (at least if we decide to use nand_timings and not
nand_timing_modes), right ?

Best Regards,

Boris

>
> Jason

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-15 17:03                 ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-15 17:03 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On 15/01/2014 16:09, boris brezillon wrote:
> Hello Jason,
>
> On 09/01/2014 18:35, Jason Gunthorpe wrote:
>> On Thu, Jan 09, 2014 at 09:36:18AM +0100, boris brezillon wrote:
>>
>>>> You might want to check if you can boil down the DT timings from the
>>>> huge list to just an ONFI mode number..
>>> Sure, but the sunxi driver needs at least 19 of them...
>> So does mvebu's NAND driver..
>>
>> What I ment was you could have a
>>
>>    onfi,nand-timing-mode = 0
>>
>> in the DT. Each of the modes defines all ~19 parameters, higher modes
>> are faster.
>>
>> Pick a mode value that fits all the parameters of the connected
>> non-ONFI flash.
>>
>> This would be instead of defining each parameter
>> individually.. Provide some helpers to convert from a onfi mode number
>> to all the onfi defined timing parameters so that drivers can
>> configure the HW..
>
> Are you suggesting we should provide a function that converts these
> modes into a nand_timings struct, or just use the timing modes and
> let the NAND controller drivers configure its IP accordingly ?
>
> I found the ONFI timing tables in this document:
>
> www.*onfi*.org/~/media/*ONFI*/specs/*onfi*_3_1_spec.pdf‎ (chapter 4.16).
>
> I suppose my nand_timings struct should use the names described
> page 110-111 (at least if we decide to use nand_timings and not
> nand_timing_modes), right ?

After taking a closer look at this document, the only parameter 
available in my
nand_timings struct that is not defined in the standard is tR_max (data 
transfer
from cell to register).

And the ONFI standard defines 4 more timings:
- tCEA_max
- tCEH_min
- tFEAT_max
- tITC_max



>
> Best Regards,
>
> Boris
>
>>
>> Jason
>


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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-15 17:03                 ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-15 17:03 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Russell King,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, dev-3kdeTeqwOZ9EV1b7eY7vFQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Landley,
	Grant Likely, Maxime Ripard, David Woodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 15/01/2014 16:09, boris brezillon wrote:
> Hello Jason,
>
> On 09/01/2014 18:35, Jason Gunthorpe wrote:
>> On Thu, Jan 09, 2014 at 09:36:18AM +0100, boris brezillon wrote:
>>
>>>> You might want to check if you can boil down the DT timings from the
>>>> huge list to just an ONFI mode number..
>>> Sure, but the sunxi driver needs at least 19 of them...
>> So does mvebu's NAND driver..
>>
>> What I ment was you could have a
>>
>>    onfi,nand-timing-mode = 0
>>
>> in the DT. Each of the modes defines all ~19 parameters, higher modes
>> are faster.
>>
>> Pick a mode value that fits all the parameters of the connected
>> non-ONFI flash.
>>
>> This would be instead of defining each parameter
>> individually.. Provide some helpers to convert from a onfi mode number
>> to all the onfi defined timing parameters so that drivers can
>> configure the HW..
>
> Are you suggesting we should provide a function that converts these
> modes into a nand_timings struct, or just use the timing modes and
> let the NAND controller drivers configure its IP accordingly ?
>
> I found the ONFI timing tables in this document:
>
> www.*onfi*.org/~/media/*ONFI*/specs/*onfi*_3_1_spec.pdf‎ (chapter 4.16).
>
> I suppose my nand_timings struct should use the names described
> page 110-111 (at least if we decide to use nand_timings and not
> nand_timing_modes), right ?

After taking a closer look at this document, the only parameter 
available in my
nand_timings struct that is not defined in the standard is tR_max (data 
transfer
from cell to register).

And the ONFI standard defines 4 more timings:
- tCEA_max
- tCEH_min
- tFEAT_max
- tITC_max



>
> Best Regards,
>
> Boris
>
>>
>> Jason
>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-15 17:03                 ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-15 17:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 15/01/2014 16:09, boris brezillon wrote:
> Hello Jason,
>
> On 09/01/2014 18:35, Jason Gunthorpe wrote:
>> On Thu, Jan 09, 2014 at 09:36:18AM +0100, boris brezillon wrote:
>>
>>>> You might want to check if you can boil down the DT timings from the
>>>> huge list to just an ONFI mode number..
>>> Sure, but the sunxi driver needs at least 19 of them...
>> So does mvebu's NAND driver..
>>
>> What I ment was you could have a
>>
>>    onfi,nand-timing-mode = 0
>>
>> in the DT. Each of the modes defines all ~19 parameters, higher modes
>> are faster.
>>
>> Pick a mode value that fits all the parameters of the connected
>> non-ONFI flash.
>>
>> This would be instead of defining each parameter
>> individually.. Provide some helpers to convert from a onfi mode number
>> to all the onfi defined timing parameters so that drivers can
>> configure the HW..
>
> Are you suggesting we should provide a function that converts these
> modes into a nand_timings struct, or just use the timing modes and
> let the NAND controller drivers configure its IP accordingly ?
>
> I found the ONFI timing tables in this document:
>
> www.*onfi*.org/~/media/*ONFI*/specs/*onfi*_3_1_spec.pdf? (chapter 4.16).
>
> I suppose my nand_timings struct should use the names described
> page 110-111 (at least if we decide to use nand_timings and not
> nand_timing_modes), right ?

After taking a closer look at this document, the only parameter 
available in my
nand_timings struct that is not defined in the standard is tR_max (data 
transfer
from cell to register).

And the ONFI standard defines 4 more timings:
- tCEA_max
- tCEH_min
- tFEAT_max
- tITC_max



>
> Best Regards,
>
> Boris
>
>>
>> Jason
>

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
       [not found]               ` <6de6ead1-e437-410b-91c0-74afb37dbf39@googlegroups.com>
@ 2014-01-21 18:13                   ` Henrik Nordström
  0 siblings, 0 replies; 123+ messages in thread
From: Henrik Nordström @ 2014-01-21 18:13 UTC (permalink / raw)
  To: linux-sunxi; +Cc: dev, Maxime Ripard, David Woodhouse, linux-mtd, linux-kernel

lör 2014-01-18 klockan 05:46 -0800 skrev Boris BREZILLON:

> Do you know which mode are used (X ECC strength / 512 or 1024 bytes ?)
> and
> when they are are selected  (does it depend on the connected NAND
> chip ?) ?

It seems to blindly try some modes until something usable is found.
Varying both chip address size and ECC layout.

Sorry I do not have the exact details on the ECC modes used. Only
analyzed nand controller command traces of A13 BROM trying to load
boot0. The trace can be found at
https://github.com/hno/Allwinner-Info/blob/master/NAND/boot0/A13-brom

>  
>         
>         > - boot0 code is stored only on the first ECC block of each
>         page (1024 
>         > bytes + ecc bytes) 
>         
>         No, it reads a whole page at a time in sequental mode 
>         (data,ecc,data,ecc,data,ecc,data,ecc...).
> 
> 
> Are you sure ?
> This thread says that only the first 1024 bytes of data (+ 96 bytes of
> ECC) of each page are used:

yes I am sure. There was no page access commands between the sectors,
only linear read of data,ecc,data,ecc.

> I'm not a big fan of this approach, because the real media is an MTD
> (NAND) device,
> not a block device.

Hit implementation acks this by not providing a block device.


>         iirc there is an interface for dynamically selecting ECC mode
>         and other 
>         parameers. Or maybe that's only u-boot mtd?
> 
> 
> Haven't found anything authorizing per partiton ECC config, though
> this could be an
> enhancement of the MTD framework.

u-boot have user selectable ecc scheme for some boards. I.e. omap3 based
ones.

other boards select based on NAND size etc.
 
Regards
Henrik



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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-21 18:13                   ` Henrik Nordström
  0 siblings, 0 replies; 123+ messages in thread
From: Henrik Nordström @ 2014-01-21 18:13 UTC (permalink / raw)
  To: linux-sunxi; +Cc: dev, linux-mtd, Maxime Ripard, David Woodhouse, linux-kernel

lör 2014-01-18 klockan 05:46 -0800 skrev Boris BREZILLON:

> Do you know which mode are used (X ECC strength / 512 or 1024 bytes ?)
> and
> when they are are selected  (does it depend on the connected NAND
> chip ?) ?

It seems to blindly try some modes until something usable is found.
Varying both chip address size and ECC layout.

Sorry I do not have the exact details on the ECC modes used. Only
analyzed nand controller command traces of A13 BROM trying to load
boot0. The trace can be found at
https://github.com/hno/Allwinner-Info/blob/master/NAND/boot0/A13-brom

>  
>         
>         > - boot0 code is stored only on the first ECC block of each
>         page (1024 
>         > bytes + ecc bytes) 
>         
>         No, it reads a whole page at a time in sequental mode 
>         (data,ecc,data,ecc,data,ecc,data,ecc...).
> 
> 
> Are you sure ?
> This thread says that only the first 1024 bytes of data (+ 96 bytes of
> ECC) of each page are used:

yes I am sure. There was no page access commands between the sectors,
only linear read of data,ecc,data,ecc.

> I'm not a big fan of this approach, because the real media is an MTD
> (NAND) device,
> not a block device.

Hit implementation acks this by not providing a block device.


>         iirc there is an interface for dynamically selecting ECC mode
>         and other 
>         parameers. Or maybe that's only u-boot mtd?
> 
> 
> Haven't found anything authorizing per partiton ECC config, though
> this could be an
> enhancement of the MTD framework.

u-boot have user selectable ecc scheme for some boards. I.e. omap3 based
ones.

other boards select based on NAND size etc.
 
Regards
Henrik

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
  2014-01-21 18:13                   ` Henrik Nordström
@ 2014-01-21 20:55                     ` Henrik Nordström
  -1 siblings, 0 replies; 123+ messages in thread
From: Henrik Nordström @ 2014-01-21 20:55 UTC (permalink / raw)
  To: linux-sunxi; +Cc: dev, Maxime Ripard, David Woodhouse, linux-mtd, linux-kernel

tis 2014-01-21 klockan 19:13 +0100 skrev Henrik Nordström:
> > Are you sure ?
> > This thread says that only the first 1024 bytes of data (+ 96 bytes of
> > ECC) of each page are used:
> 
> yes I am sure. There was no page access commands between the sectors,
> only linear read of data,ecc,data,ecc.

Hmm.. but thinking back I am no longer so sure. Need to test this again
while verifying with logic probe what is going on.

Regards
Henrik


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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-21 20:55                     ` Henrik Nordström
  0 siblings, 0 replies; 123+ messages in thread
From: Henrik Nordström @ 2014-01-21 20:55 UTC (permalink / raw)
  To: linux-sunxi; +Cc: dev, linux-mtd, Maxime Ripard, David Woodhouse, linux-kernel

tis 2014-01-21 klockan 19:13 +0100 skrev Henrik Nordström:
> > Are you sure ?
> > This thread says that only the first 1024 bytes of data (+ 96 bytes of
> > ECC) of each page are used:
> 
> yes I am sure. There was no page access commands between the sectors,
> only linear read of data,ecc,data,ecc.

Hmm.. but thinking back I am no longer so sure. Need to test this again
while verifying with logic probe what is going on.

Regards
Henrik

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-21 22:57                   ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-21 22:57 UTC (permalink / raw)
  To: boris brezillon
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On Wed, Jan 15, 2014 at 06:03:01PM +0100, boris brezillon wrote:

> >>Pick a mode value that fits all the parameters of the connected
> >>non-ONFI flash.
> >>
> >>This would be instead of defining each parameter
> >>individually.. Provide some helpers to convert from a onfi mode number
> >>to all the onfi defined timing parameters so that drivers can
> >>configure the HW..
> >
> >Are you suggesting we should provide a function that converts these
> >modes into a nand_timings struct, or just use the timing modes and
> >let the NAND controller drivers configure its IP accordingly ?

Either seems reasonable to me, but passing the ONFI mode directly from
the NAND core to the driver seems a little safer..

The NAND core can provide a helper function to xlate the mode number
to the timing struct to help drivers that need broken out timing.

> >I found the ONFI timing tables in this document:
> >
> >www.*onfi*.org/~/media/*ONFI*/specs/*onfi*_3_1_spec.pdf‎ (chapter 4.16).
> >
> >I suppose my nand_timings struct should use the names described
> >page 110-111 (at least if we decide to use nand_timings and not
> >nand_timing_modes), right ?

Yah, I think follow the standard. The standard has timing diagrams
that show what all these parameters actually are.

> After taking a closer look at this document, the only parameter
> available in my nand_timings struct that is not defined in the
> standard is tR_max (data transfer from cell to register).

Maybe it can be derived from the other parameters? The ONFI values
seemed pretty comprehensive to me.

I think the mvebu driver was similar, not all of the ONFI values were
used and some translation was needed.

Jason

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-21 22:57                   ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-21 22:57 UTC (permalink / raw)
  To: boris brezillon
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Russell King,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, dev-3kdeTeqwOZ9EV1b7eY7vFQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Landley,
	Grant Likely, Maxime Ripard, David Woodhouse,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wed, Jan 15, 2014 at 06:03:01PM +0100, boris brezillon wrote:

> >>Pick a mode value that fits all the parameters of the connected
> >>non-ONFI flash.
> >>
> >>This would be instead of defining each parameter
> >>individually.. Provide some helpers to convert from a onfi mode number
> >>to all the onfi defined timing parameters so that drivers can
> >>configure the HW..
> >
> >Are you suggesting we should provide a function that converts these
> >modes into a nand_timings struct, or just use the timing modes and
> >let the NAND controller drivers configure its IP accordingly ?

Either seems reasonable to me, but passing the ONFI mode directly from
the NAND core to the driver seems a little safer..

The NAND core can provide a helper function to xlate the mode number
to the timing struct to help drivers that need broken out timing.

> >I found the ONFI timing tables in this document:
> >
> >www.*onfi*.org/~/media/*ONFI*/specs/*onfi*_3_1_spec.pdf‎ (chapter 4.16).
> >
> >I suppose my nand_timings struct should use the names described
> >page 110-111 (at least if we decide to use nand_timings and not
> >nand_timing_modes), right ?

Yah, I think follow the standard. The standard has timing diagrams
that show what all these parameters actually are.

> After taking a closer look at this document, the only parameter
> available in my nand_timings struct that is not defined in the
> standard is tR_max (data transfer from cell to register).

Maybe it can be derived from the other parameters? The ONFI values
seemed pretty comprehensive to me.

I think the mvebu driver was similar, not all of the ONFI values were
used and some translation was needed.

Jason
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-01-21 22:57                   ` Jason Gunthorpe
  0 siblings, 0 replies; 123+ messages in thread
From: Jason Gunthorpe @ 2014-01-21 22:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 15, 2014 at 06:03:01PM +0100, boris brezillon wrote:

> >>Pick a mode value that fits all the parameters of the connected
> >>non-ONFI flash.
> >>
> >>This would be instead of defining each parameter
> >>individually.. Provide some helpers to convert from a onfi mode number
> >>to all the onfi defined timing parameters so that drivers can
> >>configure the HW..
> >
> >Are you suggesting we should provide a function that converts these
> >modes into a nand_timings struct, or just use the timing modes and
> >let the NAND controller drivers configure its IP accordingly ?

Either seems reasonable to me, but passing the ONFI mode directly from
the NAND core to the driver seems a little safer..

The NAND core can provide a helper function to xlate the mode number
to the timing struct to help drivers that need broken out timing.

> >I found the ONFI timing tables in this document:
> >
> >www.*onfi*.org/~/media/*ONFI*/specs/*onfi*_3_1_spec.pdf? (chapter 4.16).
> >
> >I suppose my nand_timings struct should use the names described
> >page 110-111 (at least if we decide to use nand_timings and not
> >nand_timing_modes), right ?

Yah, I think follow the standard. The standard has timing diagrams
that show what all these parameters actually are.

> After taking a closer look at this document, the only parameter
> available in my nand_timings struct that is not defined in the
> standard is tR_max (data transfer from cell to register).

Maybe it can be derived from the other parameters? The ONFI values
seemed pretty comprehensive to me.

I think the mvebu driver was similar, not all of the ONFI values were
used and some translation was needed.

Jason

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

* Re: [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
  2014-01-08 14:21   ` Boris BREZILLON
  (?)
@ 2014-01-23  1:49     ` Brian Norris
  -1 siblings, 0 replies; 123+ messages in thread
From: Brian Norris @ 2014-01-23  1:49 UTC (permalink / raw)
  To: Boris BREZILLON
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel, Huang Shijie

+ Huang

Hi Boris,

On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
> The Hynix nand flashes store their ECC requirements in byte 4 of its id
> (returned on READ ID command).
> 
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>

I haven't verified yet (perhaps Huang can confirm?), but this may be
similar to a patch Huang submitted recently. In his case, we found that
this table is actually quite unreliable and is likely hard to maintain.

Why do you need this ECC information, for my reference?

Brian

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

* Re: [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-01-23  1:49     ` Brian Norris
  0 siblings, 0 replies; 123+ messages in thread
From: Brian Norris @ 2014-01-23  1:49 UTC (permalink / raw)
  To: Boris BREZILLON
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	Huang Shijie, linux-mtd, Rob Landley, Grant Likely,
	Maxime Ripard, David Woodhouse, linux-arm-kernel

+ Huang

Hi Boris,

On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
> The Hynix nand flashes store their ECC requirements in byte 4 of its id
> (returned on READ ID command).
> 
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>

I haven't verified yet (perhaps Huang can confirm?), but this may be
similar to a patch Huang submitted recently. In his case, we found that
this table is actually quite unreliable and is likely hard to maintain.

Why do you need this ECC information, for my reference?

Brian

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

* [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-01-23  1:49     ` Brian Norris
  0 siblings, 0 replies; 123+ messages in thread
From: Brian Norris @ 2014-01-23  1:49 UTC (permalink / raw)
  To: linux-arm-kernel

+ Huang

Hi Boris,

On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
> The Hynix nand flashes store their ECC requirements in byte 4 of its id
> (returned on READ ID command).
> 
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>

I haven't verified yet (perhaps Huang can confirm?), but this may be
similar to a patch Huang submitted recently. In his case, we found that
this table is actually quite unreliable and is likely hard to maintain.

Why do you need this ECC information, for my reference?

Brian

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

* Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
  2014-01-11 13:38   ` boris brezillon
  (?)
  (?)
@ 2014-01-23 15:22     ` Rob Herring
  -1 siblings, 0 replies; 123+ messages in thread
From: Rob Herring @ 2014-01-23 15:22 UTC (permalink / raw)
  To: boris brezillon
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, linux-kernel,
	linux-arm-kernel, linux-mtd, dev

On Sat, Jan 11, 2014 at 7:38 AM, boris brezillon
<b.brezillon@overkiz.com> wrote:
> On 08/01/2014 15:21, Boris BREZILLON wrote:
>>
>> Hello,
>>
>> This series add the sunxi NFC support with up to 8 NAND chip connected.
>> I'm still in the early stages drivers development and some key features
>> are
>> missing, but it's usable (I tested it on the cubietruck board).
>>
>> Here's what's missing:
>>   - HW ECC support
>>   - DMA support
>>   - HW randomization support
>>   - many more improvements
>>
>> This series depends on Emilio's patch series implementing mod0 clks
>>
>> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
>> + an other patch not yet posted
>>
>> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)
>
>
> During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
> NAND flash controller I found this document describing the Altera NAND flash
> controller
> (which is in turn based on a cadence IP):

Which may be similar to drivers/mtd/nand/denali.c as Cadence bought Denali?

Rob

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

* Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-23 15:22     ` Rob Herring
  0 siblings, 0 replies; 123+ messages in thread
From: Rob Herring @ 2014-01-23 15:22 UTC (permalink / raw)
  To: boris brezillon
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, linux-kernel,
	linux-arm-kernel, linux-mtd, dev

On Sat, Jan 11, 2014 at 7:38 AM, boris brezillon
<b.brezillon@overkiz.com> wrote:
> On 08/01/2014 15:21, Boris BREZILLON wrote:
>>
>> Hello,
>>
>> This series add the sunxi NFC support with up to 8 NAND chip connected.
>> I'm still in the early stages drivers development and some key features
>> are
>> missing, but it's usable (I tested it on the cubietruck board).
>>
>> Here's what's missing:
>>   - HW ECC support
>>   - DMA support
>>   - HW randomization support
>>   - many more improvements
>>
>> This series depends on Emilio's patch series implementing mod0 clks
>>
>> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
>> + an other patch not yet posted
>>
>> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)
>
>
> During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
> NAND flash controller I found this document describing the Altera NAND flash
> controller
> (which is in turn based on a cadence IP):

Which may be similar to drivers/mtd/nand/denali.c as Cadence bought Denali?

Rob

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

* Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-23 15:22     ` Rob Herring
  0 siblings, 0 replies; 123+ messages in thread
From: Rob Herring @ 2014-01-23 15:22 UTC (permalink / raw)
  To: boris brezillon
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

On Sat, Jan 11, 2014 at 7:38 AM, boris brezillon
<b.brezillon@overkiz.com> wrote:
> On 08/01/2014 15:21, Boris BREZILLON wrote:
>>
>> Hello,
>>
>> This series add the sunxi NFC support with up to 8 NAND chip connected.
>> I'm still in the early stages drivers development and some key features
>> are
>> missing, but it's usable (I tested it on the cubietruck board).
>>
>> Here's what's missing:
>>   - HW ECC support
>>   - DMA support
>>   - HW randomization support
>>   - many more improvements
>>
>> This series depends on Emilio's patch series implementing mod0 clks
>>
>> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
>> + an other patch not yet posted
>>
>> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)
>
>
> During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
> NAND flash controller I found this document describing the Altera NAND flash
> controller
> (which is in turn based on a cadence IP):

Which may be similar to drivers/mtd/nand/denali.c as Cadence bought Denali?

Rob

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

* [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-23 15:22     ` Rob Herring
  0 siblings, 0 replies; 123+ messages in thread
From: Rob Herring @ 2014-01-23 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jan 11, 2014 at 7:38 AM, boris brezillon
<b.brezillon@overkiz.com> wrote:
> On 08/01/2014 15:21, Boris BREZILLON wrote:
>>
>> Hello,
>>
>> This series add the sunxi NFC support with up to 8 NAND chip connected.
>> I'm still in the early stages drivers development and some key features
>> are
>> missing, but it's usable (I tested it on the cubietruck board).
>>
>> Here's what's missing:
>>   - HW ECC support
>>   - DMA support
>>   - HW randomization support
>>   - many more improvements
>>
>> This series depends on Emilio's patch series implementing mod0 clks
>>
>> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
>> + an other patch not yet posted
>>
>> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)
>
>
> During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
> NAND flash controller I found this document describing the Altera NAND flash
> controller
> (which is in turn based on a cadence IP):

Which may be similar to drivers/mtd/nand/denali.c as Cadence bought Denali?

Rob

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

* Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-29 10:20       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-29 10:20 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, linux-kernel,
	linux-arm-kernel, linux-mtd, dev

Hello Rob,

On 23/01/2014 16:22, Rob Herring wrote:
> On Sat, Jan 11, 2014 at 7:38 AM, boris brezillon
> <b.brezillon@overkiz.com> wrote:
>> On 08/01/2014 15:21, Boris BREZILLON wrote:
>>> Hello,
>>>
>>> This series add the sunxi NFC support with up to 8 NAND chip connected.
>>> I'm still in the early stages drivers development and some key features
>>> are
>>> missing, but it's usable (I tested it on the cubietruck board).
>>>
>>> Here's what's missing:
>>>    - HW ECC support
>>>    - DMA support
>>>    - HW randomization support
>>>    - many more improvements
>>>
>>> This series depends on Emilio's patch series implementing mod0 clks
>>>
>>> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
>>> + an other patch not yet posted
>>>
>>> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)
>>
>> During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
>> NAND flash controller I found this document describing the Altera NAND flash
>> controller
>> (which is in turn based on a cadence IP):
> Which may be similar to drivers/mtd/nand/denali.c as Cadence bought Denali?
Actually I was wrong, the sunxi and the cadence IP have nothing in common.
This was pointed out by Henrik (see this thread :
https://groups.google.com/forum/#!searchin/linux-sunxi/nand/linux-sunxi/x69tFBi95Zk/bNyJlWWOV8oJ 
<https://groups.google.com/forum/#%21searchin/linux-sunxi/nand/linux-sunxi/x69tFBi95Zk/bNyJlWWOV8oJ>).


Sorry for the false hopes.

Best Regards,

Boris

>
> Rob


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

* Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-29 10:20       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-29 10:20 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	dev-3kdeTeqwOZ9EV1b7eY7vFQ

Hello Rob,

On 23/01/2014 16:22, Rob Herring wrote:
> On Sat, Jan 11, 2014 at 7:38 AM, boris brezillon
> <b.brezillon-ZNYIgs0QAGpBDgjK7y7TUQ@public.gmane.org> wrote:
>> On 08/01/2014 15:21, Boris BREZILLON wrote:
>>> Hello,
>>>
>>> This series add the sunxi NFC support with up to 8 NAND chip connected.
>>> I'm still in the early stages drivers development and some key features
>>> are
>>> missing, but it's usable (I tested it on the cubietruck board).
>>>
>>> Here's what's missing:
>>>    - HW ECC support
>>>    - DMA support
>>>    - HW randomization support
>>>    - many more improvements
>>>
>>> This series depends on Emilio's patch series implementing mod0 clks
>>>
>>> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
>>> + an other patch not yet posted
>>>
>>> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)
>>
>> During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
>> NAND flash controller I found this document describing the Altera NAND flash
>> controller
>> (which is in turn based on a cadence IP):
> Which may be similar to drivers/mtd/nand/denali.c as Cadence bought Denali?
Actually I was wrong, the sunxi and the cadence IP have nothing in common.
This was pointed out by Henrik (see this thread :
https://groups.google.com/forum/#!searchin/linux-sunxi/nand/linux-sunxi/x69tFBi95Zk/bNyJlWWOV8oJ 
<https://groups.google.com/forum/#%21searchin/linux-sunxi/nand/linux-sunxi/x69tFBi95Zk/bNyJlWWOV8oJ>).


Sorry for the false hopes.

Best Regards,

Boris

>
> Rob

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

* Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-29 10:20       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-29 10:20 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Grant Likely, Maxime Ripard,
	David Woodhouse, linux-arm-kernel

Hello Rob,

On 23/01/2014 16:22, Rob Herring wrote:
> On Sat, Jan 11, 2014 at 7:38 AM, boris brezillon
> <b.brezillon@overkiz.com> wrote:
>> On 08/01/2014 15:21, Boris BREZILLON wrote:
>>> Hello,
>>>
>>> This series add the sunxi NFC support with up to 8 NAND chip connected.
>>> I'm still in the early stages drivers development and some key features
>>> are
>>> missing, but it's usable (I tested it on the cubietruck board).
>>>
>>> Here's what's missing:
>>>    - HW ECC support
>>>    - DMA support
>>>    - HW randomization support
>>>    - many more improvements
>>>
>>> This series depends on Emilio's patch series implementing mod0 clks
>>>
>>> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
>>> + an other patch not yet posted
>>>
>>> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)
>>
>> During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
>> NAND flash controller I found this document describing the Altera NAND flash
>> controller
>> (which is in turn based on a cadence IP):
> Which may be similar to drivers/mtd/nand/denali.c as Cadence bought Denali?
Actually I was wrong, the sunxi and the cadence IP have nothing in common.
This was pointed out by Henrik (see this thread :
https://groups.google.com/forum/#!searchin/linux-sunxi/nand/linux-sunxi/x69tFBi95Zk/bNyJlWWOV8oJ 
<https://groups.google.com/forum/#%21searchin/linux-sunxi/nand/linux-sunxi/x69tFBi95Zk/bNyJlWWOV8oJ>).


Sorry for the false hopes.

Best Regards,

Boris

>
> Rob

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

* [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-29 10:20       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-29 10:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Rob,

On 23/01/2014 16:22, Rob Herring wrote:
> On Sat, Jan 11, 2014 at 7:38 AM, boris brezillon
> <b.brezillon@overkiz.com> wrote:
>> On 08/01/2014 15:21, Boris BREZILLON wrote:
>>> Hello,
>>>
>>> This series add the sunxi NFC support with up to 8 NAND chip connected.
>>> I'm still in the early stages drivers development and some key features
>>> are
>>> missing, but it's usable (I tested it on the cubietruck board).
>>>
>>> Here's what's missing:
>>>    - HW ECC support
>>>    - DMA support
>>>    - HW randomization support
>>>    - many more improvements
>>>
>>> This series depends on Emilio's patch series implementing mod0 clks
>>>
>>> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/185478.html)
>>> + an other patch not yet posted
>>>
>>> (http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0)
>>
>> During my reasearch regarding the HW ECC and HW randomizer of the Allwinner
>> NAND flash controller I found this document describing the Altera NAND flash
>> controller
>> (which is in turn based on a cadence IP):
> Which may be similar to drivers/mtd/nand/denali.c as Cadence bought Denali?
Actually I was wrong, the sunxi and the cadence IP have nothing in common.
This was pointed out by Henrik (see this thread :
https://groups.google.com/forum/#!searchin/linux-sunxi/nand/linux-sunxi/x69tFBi95Zk/bNyJlWWOV8oJ 
<https://groups.google.com/forum/#%21searchin/linux-sunxi/nand/linux-sunxi/x69tFBi95Zk/bNyJlWWOV8oJ>).


Sorry for the false hopes.

Best Regards,

Boris

>
> Rob

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

* Re: [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
  2014-01-23  1:49     ` Brian Norris
  (?)
  (?)
@ 2014-01-29 10:29       ` boris brezillon
  -1 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-29 10:29 UTC (permalink / raw)
  To: Brian Norris
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel, Huang Shijie

Hello Brian,

On 23/01/2014 02:49, Brian Norris wrote:
> + Huang
>
> Hi Boris,
>
> On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
>> The Hynix nand flashes store their ECC requirements in byte 4 of its id
>> (returned on READ ID command).
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> I haven't verified yet (perhaps Huang can confirm?), but this may be
> similar to a patch Huang submitted recently. In his case, we found that
> this table is actually quite unreliable and is likely hard to maintain.

You mean these bytes are not reliable within the whole Hynix LP (Large Page)
NAND product line ?

>
> Why do you need this ECC information, for my reference?

Because the NAND flash available on the cubietruck board does not 
support the
ONFI standard, and I thought this could be a option to retrieve the ECC 
strength
requirements.

Anyway, I added a new helper function to retrieve ecc informations from 
device
tree (I'll post it in the 2nd version of this series). We'll see if this 
approach is
accepted...

>
> Brian


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

* Re: [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-01-29 10:29       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-29 10:29 UTC (permalink / raw)
  To: Brian Norris
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, dev-3kdeTeqwOZ9EV1b7eY7vFQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Huang Shijie

Hello Brian,

On 23/01/2014 02:49, Brian Norris wrote:
> + Huang
>
> Hi Boris,
>
> On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
>> The Hynix nand flashes store their ECC requirements in byte 4 of its id
>> (returned on READ ID command).
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon-ZNYIgs0QAGpBDgjK7y7TUQ@public.gmane.org>
> I haven't verified yet (perhaps Huang can confirm?), but this may be
> similar to a patch Huang submitted recently. In his case, we found that
> this table is actually quite unreliable and is likely hard to maintain.

You mean these bytes are not reliable within the whole Hynix LP (Large Page)
NAND product line ?

>
> Why do you need this ECC information, for my reference?

Because the NAND flash available on the cubietruck board does not 
support the
ONFI standard, and I thought this could be a option to retrieve the ECC 
strength
requirements.

Anyway, I added a new helper function to retrieve ecc informations from 
device
tree (I'll post it in the 2nd version of this series). We'll see if this 
approach is
accepted...

>
> Brian

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-01-29 10:29       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-29 10:29 UTC (permalink / raw)
  To: Brian Norris
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	Huang Shijie, linux-mtd, Rob Landley, Grant Likely,
	Maxime Ripard, David Woodhouse, linux-arm-kernel

Hello Brian,

On 23/01/2014 02:49, Brian Norris wrote:
> + Huang
>
> Hi Boris,
>
> On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
>> The Hynix nand flashes store their ECC requirements in byte 4 of its id
>> (returned on READ ID command).
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> I haven't verified yet (perhaps Huang can confirm?), but this may be
> similar to a patch Huang submitted recently. In his case, we found that
> this table is actually quite unreliable and is likely hard to maintain.

You mean these bytes are not reliable within the whole Hynix LP (Large Page)
NAND product line ?

>
> Why do you need this ECC information, for my reference?

Because the NAND flash available on the cubietruck board does not 
support the
ONFI standard, and I thought this could be a option to retrieve the ECC 
strength
requirements.

Anyway, I added a new helper function to retrieve ecc informations from 
device
tree (I'll post it in the 2nd version of this series). We'll see if this 
approach is
accepted...

>
> Brian

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

* [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-01-29 10:29       ` boris brezillon
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon @ 2014-01-29 10:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Brian,

On 23/01/2014 02:49, Brian Norris wrote:
> + Huang
>
> Hi Boris,
>
> On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
>> The Hynix nand flashes store their ECC requirements in byte 4 of its id
>> (returned on READ ID command).
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> I haven't verified yet (perhaps Huang can confirm?), but this may be
> similar to a patch Huang submitted recently. In his case, we found that
> this table is actually quite unreliable and is likely hard to maintain.

You mean these bytes are not reliable within the whole Hynix LP (Large Page)
NAND product line ?

>
> Why do you need this ECC information, for my reference?

Because the NAND flash available on the cubietruck board does not 
support the
ONFI standard, and I thought this could be a option to retrieve the ECC 
strength
requirements.

Anyway, I added a new helper function to retrieve ecc informations from 
device
tree (I'll post it in the 2nd version of this series). We'll see if this 
approach is
accepted...

>
> Brian

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
  2014-01-13  9:02             ` boris brezillon
@ 2014-01-29 15:11               ` Michal Suchanek
  -1 siblings, 0 replies; 123+ messages in thread
From: Michal Suchanek @ 2014-01-29 15:11 UTC (permalink / raw)
  To: linux-sunxi
  Cc: Henrik Nordström, dev, Maxime Ripard, David Woodhouse,
	linux-mtd, linux-kernel

On 13 January 2014 10:02, boris brezillon <b.brezillon@overkiz.com> wrote:
> Hi Henrik,
>
>
> On 11/01/2014 22:11, Henrik Nordström wrote:
>>
>> <bbrezillon> thanks for pointing out your documents
>> <bbrezillon> I'm trying to get the NAND driver with HW ECC (and HW RND)
>> without using DMA at all
>>
>> I tried many things but did not quite get the ECC reading command to
>> return meaningful resuts. But should work somehow.
>>
>> <bbrezillon> do you have any other information I could use to do this ?
>>
>> Not really. There is no known code to look at using the nand controller
>> without DMA. All allwinner code uses DMA even the boot ROM (BROM).
>>
>> <bbrezillon> For example, I wonder why there are 2 RAM sectors (the
>> driver I found only make use of RAM0)
>>
>> I think it's used during DMA to fetch next sector while the previous one
>> is transferred by DMA. But not sure.
>
>
> Some feedback on my tests:
>
> - I managed to get HW ECC working without any DMA transfer (using CMD = 01):
>   * I only tested the sequential ECC => ECC are stored between 2 data blocks
> (1024 byte)
>   * Non sequential ECC should work if I store ECC bytes in the OOB area too
> (I'll just have
>      to send RANDOM_OUT commands to move to the OOB area before sending the
> ECC
>      cmd and another RANDOM_OUT to go back to the DATA area)
>
> - The HW RND (randomizer) works too, I'll just have to figure out how this
> could be
>   mainlined:
>    * using a simple dt property to tell the controller it should enable the
> randomizer
>    * provide an interface (like the nand_ecc_ctrl struct ) for other to add
> their own
>       randomizer implementation (this was requested:
> https://lkml.org/lkml/2013/12/13/154)
>
>
> The most complicated part is the boot0 partition.
>
> Tell me if I'm wrong, but here's what I understood from your work (and yuq's
> work too):
>
> boot 0 part properties:
> - uses sequential ECC
> - uses 1024 bytes ECC blocks
> - boot0 code is stored only on the first ECC block of each page (1024 bytes
> + ecc bytes)
> - boot0 code is stored on the first 64 pages of the first block
> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>
> It's not that complicated to read/write from/to boot0, but it's a bit more
> to mainline this
> implementation:
>  - the nand chip must use the same ECC algorithm and ECC layout on the whole
> flash
>    (no partition specific config available)
> - you cannot mark some part of pages as unused => the nand driver will write
> the
>   whole page, not just the first ECC block (1024 bytes)
>
> I thought about manually creating an mtd device that fullfils these needs
> (in case we
> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm not
> sure
> this is the right approach.
>
> Any ideas ?

Maybe if varying parameters on one MTD device is not acceptable you
could export parts of the flash as different MTD devices each with its
own parameters. Since the boot0 part is fixed size this should not
really be an issue. Existing MTD drivers that share hardware with
other devices exist - eg. the MTD driver which exports part of RAM as
MDT device.

I wonder if it would be good idea to make it possible to use the NAND
only for storage without a boot0 area. If this is selected by a DT
parameter as suggested changing the parameter will probably make the
NAND unreadable.

Thanks

Michal

>
>
> Best Regards,
>
> Boris
>
>>
>> Regards
>> Henrik
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-29 15:11               ` Michal Suchanek
  0 siblings, 0 replies; 123+ messages in thread
From: Michal Suchanek @ 2014-01-29 15:11 UTC (permalink / raw)
  To: linux-sunxi
  Cc: dev, linux-kernel, Henrik Nordström, linux-mtd,
	Maxime Ripard, David Woodhouse

On 13 January 2014 10:02, boris brezillon <b.brezillon@overkiz.com> wrote:
> Hi Henrik,
>
>
> On 11/01/2014 22:11, Henrik Nordström wrote:
>>
>> <bbrezillon> thanks for pointing out your documents
>> <bbrezillon> I'm trying to get the NAND driver with HW ECC (and HW RND)
>> without using DMA at all
>>
>> I tried many things but did not quite get the ECC reading command to
>> return meaningful resuts. But should work somehow.
>>
>> <bbrezillon> do you have any other information I could use to do this ?
>>
>> Not really. There is no known code to look at using the nand controller
>> without DMA. All allwinner code uses DMA even the boot ROM (BROM).
>>
>> <bbrezillon> For example, I wonder why there are 2 RAM sectors (the
>> driver I found only make use of RAM0)
>>
>> I think it's used during DMA to fetch next sector while the previous one
>> is transferred by DMA. But not sure.
>
>
> Some feedback on my tests:
>
> - I managed to get HW ECC working without any DMA transfer (using CMD = 01):
>   * I only tested the sequential ECC => ECC are stored between 2 data blocks
> (1024 byte)
>   * Non sequential ECC should work if I store ECC bytes in the OOB area too
> (I'll just have
>      to send RANDOM_OUT commands to move to the OOB area before sending the
> ECC
>      cmd and another RANDOM_OUT to go back to the DATA area)
>
> - The HW RND (randomizer) works too, I'll just have to figure out how this
> could be
>   mainlined:
>    * using a simple dt property to tell the controller it should enable the
> randomizer
>    * provide an interface (like the nand_ecc_ctrl struct ) for other to add
> their own
>       randomizer implementation (this was requested:
> https://lkml.org/lkml/2013/12/13/154)
>
>
> The most complicated part is the boot0 partition.
>
> Tell me if I'm wrong, but here's what I understood from your work (and yuq's
> work too):
>
> boot 0 part properties:
> - uses sequential ECC
> - uses 1024 bytes ECC blocks
> - boot0 code is stored only on the first ECC block of each page (1024 bytes
> + ecc bytes)
> - boot0 code is stored on the first 64 pages of the first block
> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>
> It's not that complicated to read/write from/to boot0, but it's a bit more
> to mainline this
> implementation:
>  - the nand chip must use the same ECC algorithm and ECC layout on the whole
> flash
>    (no partition specific config available)
> - you cannot mark some part of pages as unused => the nand driver will write
> the
>   whole page, not just the first ECC block (1024 bytes)
>
> I thought about manually creating an mtd device that fullfils these needs
> (in case we
> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm not
> sure
> this is the right approach.
>
> Any ideas ?

Maybe if varying parameters on one MTD device is not acceptable you
could export parts of the flash as different MTD devices each with its
own parameters. Since the boot0 part is fixed size this should not
really be an issue. Existing MTD drivers that share hardware with
other devices exist - eg. the MTD driver which exports part of RAM as
MDT device.

I wonder if it would be good idea to make it possible to use the NAND
only for storage without a boot0 area. If this is selected by a DT
parameter as suggested changing the parameter will probably make the
NAND unreadable.

Thanks

Michal

>
>
> Best Regards,
>
> Boris
>
>>
>> Regards
>> Henrik
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
  2014-01-29 15:11               ` Michal Suchanek
@ 2014-01-29 15:43                 ` boris brezillon dev
  -1 siblings, 0 replies; 123+ messages in thread
From: boris brezillon dev @ 2014-01-29 15:43 UTC (permalink / raw)
  To: linux-sunxi
  Cc: Henrik Nordström, dev, Maxime Ripard, David Woodhouse,
	linux-mtd, linux-kernel, Michal Suchanek

Hello Michal,

On 29/01/2014 16:11, Michal Suchanek wrote:
> On 13 January 2014 10:02, boris brezillon <b.brezillon@overkiz.com> wrote:
>> Hi Henrik,
>>
>>
>> On 11/01/2014 22:11, Henrik Nordström wrote:
>>> <bbrezillon> thanks for pointing out your documents
>>> <bbrezillon> I'm trying to get the NAND driver with HW ECC (and HW RND)
>>> without using DMA at all
>>>
>>> I tried many things but did not quite get the ECC reading command to
>>> return meaningful resuts. But should work somehow.
>>>
>>> <bbrezillon> do you have any other information I could use to do this ?
>>>
>>> Not really. There is no known code to look at using the nand controller
>>> without DMA. All allwinner code uses DMA even the boot ROM (BROM).
>>>
>>> <bbrezillon> For example, I wonder why there are 2 RAM sectors (the
>>> driver I found only make use of RAM0)
>>>
>>> I think it's used during DMA to fetch next sector while the previous one
>>> is transferred by DMA. But not sure.
>>
>> Some feedback on my tests:
>>
>> - I managed to get HW ECC working without any DMA transfer (using CMD = 01):
>>    * I only tested the sequential ECC => ECC are stored between 2 data blocks
>> (1024 byte)
>>    * Non sequential ECC should work if I store ECC bytes in the OOB area too
>> (I'll just have
>>       to send RANDOM_OUT commands to move to the OOB area before sending the
>> ECC
>>       cmd and another RANDOM_OUT to go back to the DATA area)
>>
>> - The HW RND (randomizer) works too, I'll just have to figure out how this
>> could be
>>    mainlined:
>>     * using a simple dt property to tell the controller it should enable the
>> randomizer
>>     * provide an interface (like the nand_ecc_ctrl struct ) for other to add
>> their own
>>        randomizer implementation (this was requested:
>> https://lkml.org/lkml/2013/12/13/154)
>>
>>
>> The most complicated part is the boot0 partition.
>>
>> Tell me if I'm wrong, but here's what I understood from your work (and yuq's
>> work too):
>>
>> boot 0 part properties:
>> - uses sequential ECC
>> - uses 1024 bytes ECC blocks
>> - boot0 code is stored only on the first ECC block of each page (1024 bytes
>> + ecc bytes)
>> - boot0 code is stored on the first 64 pages of the first block
>> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>>
>> It's not that complicated to read/write from/to boot0, but it's a bit more
>> to mainline this
>> implementation:
>>   - the nand chip must use the same ECC algorithm and ECC layout on the whole
>> flash
>>     (no partition specific config available)
>> - you cannot mark some part of pages as unused => the nand driver will write
>> the
>>    whole page, not just the first ECC block (1024 bytes)
>>
>> I thought about manually creating an mtd device that fullfils these needs
>> (in case we
>> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm not
>> sure
>> this is the right approach.
>>
>> Any ideas ?
> Maybe if varying parameters on one MTD device is not acceptable you
> could export parts of the flash as different MTD devices each with its
> own parameters. Since the boot0 part is fixed size this should not
> really be an issue. Existing MTD drivers that share hardware with
> other devices exist - eg. the MTD driver which exports part of RAM as
> MDT device.

I considered this option (exposing 2 mtd devices which use the
same nand chip: one for the boot partition and the other one
for the remaining space).
I might give it a try.

For the moment I'm trying to use standard partitions and then
attach one of these partitions as a sunxi-nand-boot-interface.
Something similar to what UBI is doing when attaching to an MTD
device.

This way we can use the NAND as a standard MTD dev and when one
partition is attached as a sunxi-nand-boot-interface you can access
the boot0 partition using a char dev (/dev/snbi0 ?).
The sunxi-nand-boot-interface will provide the appropriate abstraction
to hide the specific boot0 layout...

What do you think ?

>
> I wonder if it would be good idea to make it possible to use the NAND
> only for storage without a boot0 area. If this is selected by a DT
> parameter as suggested changing the parameter will probably make the
> NAND unreadable.
Actually the NAND controller supports up to 8 chips. I guess only the
first one can be used as a boot device.
Reserving space for the boot partition on all of these chips is kind of
useless.
Moreover, we can't tell if the user wants to boot from the NAND or
from another storage (MMC for example), in this case we don't need
to expose the boot0 partition.


Best Regards,

Boris
>
> Thanks
>
> Michal
>
>>
>> Best Regards,
>>
>> Boris
>>
>>> Regards
>>> Henrik
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "linux-sunxi" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to linux-sunxi+unsubscribe@googlegroups.com.
>> For more options, visit https://groups.google.com/groups/opt_out.


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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-29 15:43                 ` boris brezillon dev
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon dev @ 2014-01-29 15:43 UTC (permalink / raw)
  To: linux-sunxi
  Cc: Michal Suchanek, dev, linux-kernel, Henrik Nordström,
	linux-mtd, Maxime Ripard, David Woodhouse

Hello Michal,

On 29/01/2014 16:11, Michal Suchanek wrote:
> On 13 January 2014 10:02, boris brezillon <b.brezillon@overkiz.com> wrote:
>> Hi Henrik,
>>
>>
>> On 11/01/2014 22:11, Henrik Nordström wrote:
>>> <bbrezillon> thanks for pointing out your documents
>>> <bbrezillon> I'm trying to get the NAND driver with HW ECC (and HW RND)
>>> without using DMA at all
>>>
>>> I tried many things but did not quite get the ECC reading command to
>>> return meaningful resuts. But should work somehow.
>>>
>>> <bbrezillon> do you have any other information I could use to do this ?
>>>
>>> Not really. There is no known code to look at using the nand controller
>>> without DMA. All allwinner code uses DMA even the boot ROM (BROM).
>>>
>>> <bbrezillon> For example, I wonder why there are 2 RAM sectors (the
>>> driver I found only make use of RAM0)
>>>
>>> I think it's used during DMA to fetch next sector while the previous one
>>> is transferred by DMA. But not sure.
>>
>> Some feedback on my tests:
>>
>> - I managed to get HW ECC working without any DMA transfer (using CMD = 01):
>>    * I only tested the sequential ECC => ECC are stored between 2 data blocks
>> (1024 byte)
>>    * Non sequential ECC should work if I store ECC bytes in the OOB area too
>> (I'll just have
>>       to send RANDOM_OUT commands to move to the OOB area before sending the
>> ECC
>>       cmd and another RANDOM_OUT to go back to the DATA area)
>>
>> - The HW RND (randomizer) works too, I'll just have to figure out how this
>> could be
>>    mainlined:
>>     * using a simple dt property to tell the controller it should enable the
>> randomizer
>>     * provide an interface (like the nand_ecc_ctrl struct ) for other to add
>> their own
>>        randomizer implementation (this was requested:
>> https://lkml.org/lkml/2013/12/13/154)
>>
>>
>> The most complicated part is the boot0 partition.
>>
>> Tell me if I'm wrong, but here's what I understood from your work (and yuq's
>> work too):
>>
>> boot 0 part properties:
>> - uses sequential ECC
>> - uses 1024 bytes ECC blocks
>> - boot0 code is stored only on the first ECC block of each page (1024 bytes
>> + ecc bytes)
>> - boot0 code is stored on the first 64 pages of the first block
>> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>>
>> It's not that complicated to read/write from/to boot0, but it's a bit more
>> to mainline this
>> implementation:
>>   - the nand chip must use the same ECC algorithm and ECC layout on the whole
>> flash
>>     (no partition specific config available)
>> - you cannot mark some part of pages as unused => the nand driver will write
>> the
>>    whole page, not just the first ECC block (1024 bytes)
>>
>> I thought about manually creating an mtd device that fullfils these needs
>> (in case we
>> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm not
>> sure
>> this is the right approach.
>>
>> Any ideas ?
> Maybe if varying parameters on one MTD device is not acceptable you
> could export parts of the flash as different MTD devices each with its
> own parameters. Since the boot0 part is fixed size this should not
> really be an issue. Existing MTD drivers that share hardware with
> other devices exist - eg. the MTD driver which exports part of RAM as
> MDT device.

I considered this option (exposing 2 mtd devices which use the
same nand chip: one for the boot partition and the other one
for the remaining space).
I might give it a try.

For the moment I'm trying to use standard partitions and then
attach one of these partitions as a sunxi-nand-boot-interface.
Something similar to what UBI is doing when attaching to an MTD
device.

This way we can use the NAND as a standard MTD dev and when one
partition is attached as a sunxi-nand-boot-interface you can access
the boot0 partition using a char dev (/dev/snbi0 ?).
The sunxi-nand-boot-interface will provide the appropriate abstraction
to hide the specific boot0 layout...

What do you think ?

>
> I wonder if it would be good idea to make it possible to use the NAND
> only for storage without a boot0 area. If this is selected by a DT
> parameter as suggested changing the parameter will probably make the
> NAND unreadable.
Actually the NAND controller supports up to 8 chips. I guess only the
first one can be used as a boot device.
Reserving space for the boot partition on all of these chips is kind of
useless.
Moreover, we can't tell if the user wants to boot from the NAND or
from another storage (MMC for example), in this case we don't need
to expose the boot0 partition.


Best Regards,

Boris
>
> Thanks
>
> Michal
>
>>
>> Best Regards,
>>
>> Boris
>>
>>> Regards
>>> Henrik
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "linux-sunxi" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to linux-sunxi+unsubscribe@googlegroups.com.
>> For more options, visit https://groups.google.com/groups/opt_out.

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
  2014-01-29 15:43                 ` boris brezillon dev
@ 2014-01-29 16:08                   ` Michal Suchanek
  -1 siblings, 0 replies; 123+ messages in thread
From: Michal Suchanek @ 2014-01-29 16:08 UTC (permalink / raw)
  To: boris brezillon dev
  Cc: linux-sunxi, Henrik Nordström, dev, Maxime Ripard,
	David Woodhouse, linux-mtd, linux-kernel

On 29 January 2014 16:43, boris brezillon dev <b.brezillon.dev@gmail.com> wrote:
> Hello Michal,
>
>
> On 29/01/2014 16:11, Michal Suchanek wrote:
>>
>> On 13 January 2014 10:02, boris brezillon <b.brezillon@overkiz.com> wrote:
>>>
>>>
>>> boot 0 part properties:
>>> - uses sequential ECC
>>> - uses 1024 bytes ECC blocks
>>> - boot0 code is stored only on the first ECC block of each page (1024
>>> bytes
>>> + ecc bytes)
>>> - boot0 code is stored on the first 64 pages of the first block
>>> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>>>
>>> It's not that complicated to read/write from/to boot0, but it's a bit
>>> more
>>> to mainline this
>>> implementation:
>>>   - the nand chip must use the same ECC algorithm and ECC layout on the
>>> whole
>>> flash
>>>     (no partition specific config available)
>>> - you cannot mark some part of pages as unused => the nand driver will
>>> write
>>> the
>>>    whole page, not just the first ECC block (1024 bytes)
>>>
>>> I thought about manually creating an mtd device that fullfils these needs
>>> (in case we
>>> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm
>>> not
>>> sure
>>> this is the right approach.
>>>
>>> Any ideas ?
>>
>> Maybe if varying parameters on one MTD device is not acceptable you
>> could export parts of the flash as different MTD devices each with its
>> own parameters. Since the boot0 part is fixed size this should not
>> really be an issue. Existing MTD drivers that share hardware with
>> other devices exist - eg. the MTD driver which exports part of RAM as
>> MDT device.
>
>
> I considered this option (exposing 2 mtd devices which use the
> same nand chip: one for the boot partition and the other one
> for the remaining space).
> I might give it a try.
>
> For the moment I'm trying to use standard partitions and then
> attach one of these partitions as a sunxi-nand-boot-interface.
> Something similar to what UBI is doing when attaching to an MTD
> device.
>
> This way we can use the NAND as a standard MTD dev and when one
> partition is attached as a sunxi-nand-boot-interface you can access
> the boot0 partition using a char dev (/dev/snbi0 ?).
> The sunxi-nand-boot-interface will provide the appropriate abstraction
> to hide the specific boot0 layout...
>
> What do you think ?

If it works with MTD, sure.

The problem the two devices avoid is that with uniform parameters
across MTD device the boot0 partition is invalid.

>
>
>>
>> I wonder if it would be good idea to make it possible to use the NAND
>> only for storage without a boot0 area. If this is selected by a DT
>> parameter as suggested changing the parameter will probably make the
>> NAND unreadable.
>
> Actually the NAND controller supports up to 8 chips. I guess only the
> first one can be used as a boot device.
> Reserving space for the boot partition on all of these chips is kind of
> useless.

This actually depends on the BROM.

I did not read the BROM code so I don't know what it does.

> Moreover, we can't tell if the user wants to boot from the NAND or
> from another storage (MMC for example), in this case we don't need
> to expose the boot0 partition.

It's possible to use the NAND only for storage, sure.

However, a NAND on which the boo0 area is reserved would be unreadable
without reserving boot0 area in the driver, right?

The best we can tell is if user specified to reserve the area in the
DT. It might be possible to verify the boot0 area the same way BROM
does when booting from it. This might be nice option when you don't
know what you have on the chip and want to read it but most of the
time you will want to enforce bootable or non-bootable format when
writing the NAND.

Thanks

Michal

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-29 16:08                   ` Michal Suchanek
  0 siblings, 0 replies; 123+ messages in thread
From: Michal Suchanek @ 2014-01-29 16:08 UTC (permalink / raw)
  To: boris brezillon dev
  Cc: dev, linux-kernel, Henrik Nordström, linux-sunxi, linux-mtd,
	Maxime Ripard, David Woodhouse

On 29 January 2014 16:43, boris brezillon dev <b.brezillon.dev@gmail.com> wrote:
> Hello Michal,
>
>
> On 29/01/2014 16:11, Michal Suchanek wrote:
>>
>> On 13 January 2014 10:02, boris brezillon <b.brezillon@overkiz.com> wrote:
>>>
>>>
>>> boot 0 part properties:
>>> - uses sequential ECC
>>> - uses 1024 bytes ECC blocks
>>> - boot0 code is stored only on the first ECC block of each page (1024
>>> bytes
>>> + ecc bytes)
>>> - boot0 code is stored on the first 64 pages of the first block
>>> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>>>
>>> It's not that complicated to read/write from/to boot0, but it's a bit
>>> more
>>> to mainline this
>>> implementation:
>>>   - the nand chip must use the same ECC algorithm and ECC layout on the
>>> whole
>>> flash
>>>     (no partition specific config available)
>>> - you cannot mark some part of pages as unused => the nand driver will
>>> write
>>> the
>>>    whole page, not just the first ECC block (1024 bytes)
>>>
>>> I thought about manually creating an mtd device that fullfils these needs
>>> (in case we
>>> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm
>>> not
>>> sure
>>> this is the right approach.
>>>
>>> Any ideas ?
>>
>> Maybe if varying parameters on one MTD device is not acceptable you
>> could export parts of the flash as different MTD devices each with its
>> own parameters. Since the boot0 part is fixed size this should not
>> really be an issue. Existing MTD drivers that share hardware with
>> other devices exist - eg. the MTD driver which exports part of RAM as
>> MDT device.
>
>
> I considered this option (exposing 2 mtd devices which use the
> same nand chip: one for the boot partition and the other one
> for the remaining space).
> I might give it a try.
>
> For the moment I'm trying to use standard partitions and then
> attach one of these partitions as a sunxi-nand-boot-interface.
> Something similar to what UBI is doing when attaching to an MTD
> device.
>
> This way we can use the NAND as a standard MTD dev and when one
> partition is attached as a sunxi-nand-boot-interface you can access
> the boot0 partition using a char dev (/dev/snbi0 ?).
> The sunxi-nand-boot-interface will provide the appropriate abstraction
> to hide the specific boot0 layout...
>
> What do you think ?

If it works with MTD, sure.

The problem the two devices avoid is that with uniform parameters
across MTD device the boot0 partition is invalid.

>
>
>>
>> I wonder if it would be good idea to make it possible to use the NAND
>> only for storage without a boot0 area. If this is selected by a DT
>> parameter as suggested changing the parameter will probably make the
>> NAND unreadable.
>
> Actually the NAND controller supports up to 8 chips. I guess only the
> first one can be used as a boot device.
> Reserving space for the boot partition on all of these chips is kind of
> useless.

This actually depends on the BROM.

I did not read the BROM code so I don't know what it does.

> Moreover, we can't tell if the user wants to boot from the NAND or
> from another storage (MMC for example), in this case we don't need
> to expose the boot0 partition.

It's possible to use the NAND only for storage, sure.

However, a NAND on which the boo0 area is reserved would be unreadable
without reserving boot0 area in the driver, right?

The best we can tell is if user specified to reserve the area in the
DT. It might be possible to verify the boot0 area the same way BROM
does when booting from it. This might be nice option when you don't
know what you have on the chip and want to read it but most of the
time you will want to enforce bootable or non-bootable format when
writing the NAND.

Thanks

Michal

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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
  2014-01-29 16:08                   ` Michal Suchanek
@ 2014-01-29 16:55                     ` boris brezillon dev
  -1 siblings, 0 replies; 123+ messages in thread
From: boris brezillon dev @ 2014-01-29 16:55 UTC (permalink / raw)
  To: Michal Suchanek
  Cc: linux-sunxi, Henrik Nordström, dev, Maxime Ripard,
	David Woodhouse, linux-mtd, linux-kernel

On 29/01/2014 17:08, Michal Suchanek wrote:
> On 29 January 2014 16:43, boris brezillon dev <b.brezillon.dev@gmail.com> wrote:
>> Hello Michal,
>>
>>
>> On 29/01/2014 16:11, Michal Suchanek wrote:
>>> On 13 January 2014 10:02, boris brezillon <b.brezillon@overkiz.com> wrote:
>>>>
>>>> boot 0 part properties:
>>>> - uses sequential ECC
>>>> - uses 1024 bytes ECC blocks
>>>> - boot0 code is stored only on the first ECC block of each page (1024
>>>> bytes
>>>> + ecc bytes)
>>>> - boot0 code is stored on the first 64 pages of the first block
>>>> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>>>>
>>>> It's not that complicated to read/write from/to boot0, but it's a bit
>>>> more
>>>> to mainline this
>>>> implementation:
>>>>    - the nand chip must use the same ECC algorithm and ECC layout on the
>>>> whole
>>>> flash
>>>>      (no partition specific config available)
>>>> - you cannot mark some part of pages as unused => the nand driver will
>>>> write
>>>> the
>>>>     whole page, not just the first ECC block (1024 bytes)
>>>>
>>>> I thought about manually creating an mtd device that fullfils these needs
>>>> (in case we
>>>> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm
>>>> not
>>>> sure
>>>> this is the right approach.
>>>>
>>>> Any ideas ?
>>> Maybe if varying parameters on one MTD device is not acceptable you
>>> could export parts of the flash as different MTD devices each with its
>>> own parameters. Since the boot0 part is fixed size this should not
>>> really be an issue. Existing MTD drivers that share hardware with
>>> other devices exist - eg. the MTD driver which exports part of RAM as
>>> MDT device.
>>
>> I considered this option (exposing 2 mtd devices which use the
>> same nand chip: one for the boot partition and the other one
>> for the remaining space).
>> I might give it a try.
>>
>> For the moment I'm trying to use standard partitions and then
>> attach one of these partitions as a sunxi-nand-boot-interface.
>> Something similar to what UBI is doing when attaching to an MTD
>> device.
>>
>> This way we can use the NAND as a standard MTD dev and when one
>> partition is attached as a sunxi-nand-boot-interface you can access
>> the boot0 partition using a char dev (/dev/snbi0 ?).
>> The sunxi-nand-boot-interface will provide the appropriate abstraction
>> to hide the specific boot0 layout...
>>
>> What do you think ?
> If it works with MTD, sure.
>
> The problem the two devices avoid is that with uniform parameters
> across MTD device the boot0 partition is invalid.

Using partitions we would still have X char devices (X = number of MTD
partitions). But indeed, we need to provide a way to configure ECC and
randomizer specifically on each partition.

>
>>
>>> I wonder if it would be good idea to make it possible to use the NAND
>>> only for storage without a boot0 area. If this is selected by a DT
>>> parameter as suggested changing the parameter will probably make the
>>> NAND unreadable.
>> Actually the NAND controller supports up to 8 chips. I guess only the
>> first one can be used as a boot device.
>> Reserving space for the boot partition on all of these chips is kind of
>> useless.
> This actually depends on the BROM.
>
> I did not read the BROM code so I don't know what it does.
>
>> Moreover, we can't tell if the user wants to boot from the NAND or
>> from another storage (MMC for example), in this case we don't need
>> to expose the boot0 partition.
> It's possible to use the NAND only for storage, sure.
>
> However, a NAND on which the boo0 area is reserved would be unreadable
> without reserving boot0 area in the driver, right?

Not exactly: the NAND would still be readable but the blocks reserved for
boot0 (boot0 partition) won't be read correctly (ECC layout differs).
If you define a partition boot0 with the appropriate size and never access
it, the other partitions defined on the same NAND chip will work perfectly.

To solve this ECC config issue we might need to provide a way to configure
the ECC engine per partition and not on the whole NAND chip.

Moreover, IRC, BROM only uses 1K on each page of a given block to store
boot0 code and data.

And eventually the randomizer config (random seed) is specific for this
partition too.
Note that the current driver does not support randomization at all.
I'm still working on providing a generic framework to support HW and SW
randomization (in the same way HW and SW ECC are supported).

For all the reasons exposed above we need a specific handling for the boot0
partition. But I'd like to keep the NAND Flash controller driver as 
simple and
as generic as possible.
I'd prefer adding a new driver for the sunxi boot0 partition handling than
adding this code in the sunxi_nand driver.
Atfer all, this boot partition has nothing to do with NAND, this is just 
a specific
format for the sunxi BROM to load code from NAND to RAM, right ?

>
> The best we can tell is if user specified to reserve the area in the
> DT. It might be possible to verify the boot0 area the same way BROM
> does when booting from it. This might be nice option when you don't
> know what you have on the chip and want to read it but most of the
> time you will want to enforce bootable or non-bootable format when
> writing the NAND.
>
> Thanks
>
> Michal


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

* Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support
@ 2014-01-29 16:55                     ` boris brezillon dev
  0 siblings, 0 replies; 123+ messages in thread
From: boris brezillon dev @ 2014-01-29 16:55 UTC (permalink / raw)
  To: Michal Suchanek
  Cc: dev, linux-kernel, Henrik Nordström, linux-sunxi, linux-mtd,
	Maxime Ripard, David Woodhouse

On 29/01/2014 17:08, Michal Suchanek wrote:
> On 29 January 2014 16:43, boris brezillon dev <b.brezillon.dev@gmail.com> wrote:
>> Hello Michal,
>>
>>
>> On 29/01/2014 16:11, Michal Suchanek wrote:
>>> On 13 January 2014 10:02, boris brezillon <b.brezillon@overkiz.com> wrote:
>>>>
>>>> boot 0 part properties:
>>>> - uses sequential ECC
>>>> - uses 1024 bytes ECC blocks
>>>> - boot0 code is stored only on the first ECC block of each page (1024
>>>> bytes
>>>> + ecc bytes)
>>>> - boot0 code is stored on the first 64 pages of the first block
>>>> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>>>>
>>>> It's not that complicated to read/write from/to boot0, but it's a bit
>>>> more
>>>> to mainline this
>>>> implementation:
>>>>    - the nand chip must use the same ECC algorithm and ECC layout on the
>>>> whole
>>>> flash
>>>>      (no partition specific config available)
>>>> - you cannot mark some part of pages as unused => the nand driver will
>>>> write
>>>> the
>>>>     whole page, not just the first ECC block (1024 bytes)
>>>>
>>>> I thought about manually creating an mtd device that fullfils these needs
>>>> (in case we
>>>> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm
>>>> not
>>>> sure
>>>> this is the right approach.
>>>>
>>>> Any ideas ?
>>> Maybe if varying parameters on one MTD device is not acceptable you
>>> could export parts of the flash as different MTD devices each with its
>>> own parameters. Since the boot0 part is fixed size this should not
>>> really be an issue. Existing MTD drivers that share hardware with
>>> other devices exist - eg. the MTD driver which exports part of RAM as
>>> MDT device.
>>
>> I considered this option (exposing 2 mtd devices which use the
>> same nand chip: one for the boot partition and the other one
>> for the remaining space).
>> I might give it a try.
>>
>> For the moment I'm trying to use standard partitions and then
>> attach one of these partitions as a sunxi-nand-boot-interface.
>> Something similar to what UBI is doing when attaching to an MTD
>> device.
>>
>> This way we can use the NAND as a standard MTD dev and when one
>> partition is attached as a sunxi-nand-boot-interface you can access
>> the boot0 partition using a char dev (/dev/snbi0 ?).
>> The sunxi-nand-boot-interface will provide the appropriate abstraction
>> to hide the specific boot0 layout...
>>
>> What do you think ?
> If it works with MTD, sure.
>
> The problem the two devices avoid is that with uniform parameters
> across MTD device the boot0 partition is invalid.

Using partitions we would still have X char devices (X = number of MTD
partitions). But indeed, we need to provide a way to configure ECC and
randomizer specifically on each partition.

>
>>
>>> I wonder if it would be good idea to make it possible to use the NAND
>>> only for storage without a boot0 area. If this is selected by a DT
>>> parameter as suggested changing the parameter will probably make the
>>> NAND unreadable.
>> Actually the NAND controller supports up to 8 chips. I guess only the
>> first one can be used as a boot device.
>> Reserving space for the boot partition on all of these chips is kind of
>> useless.
> This actually depends on the BROM.
>
> I did not read the BROM code so I don't know what it does.
>
>> Moreover, we can't tell if the user wants to boot from the NAND or
>> from another storage (MMC for example), in this case we don't need
>> to expose the boot0 partition.
> It's possible to use the NAND only for storage, sure.
>
> However, a NAND on which the boo0 area is reserved would be unreadable
> without reserving boot0 area in the driver, right?

Not exactly: the NAND would still be readable but the blocks reserved for
boot0 (boot0 partition) won't be read correctly (ECC layout differs).
If you define a partition boot0 with the appropriate size and never access
it, the other partitions defined on the same NAND chip will work perfectly.

To solve this ECC config issue we might need to provide a way to configure
the ECC engine per partition and not on the whole NAND chip.

Moreover, IRC, BROM only uses 1K on each page of a given block to store
boot0 code and data.

And eventually the randomizer config (random seed) is specific for this
partition too.
Note that the current driver does not support randomization at all.
I'm still working on providing a generic framework to support HW and SW
randomization (in the same way HW and SW ECC are supported).

For all the reasons exposed above we need a specific handling for the boot0
partition. But I'd like to keep the NAND Flash controller driver as 
simple and
as generic as possible.
I'd prefer adding a new driver for the sunxi boot0 partition handling than
adding this code in the sunxi_nand driver.
Atfer all, this boot partition has nothing to do with NAND, this is just 
a specific
format for the sunxi BROM to load code from NAND to RAM, right ?

>
> The best we can tell is if user specified to reserve the area in the
> DT. It might be possible to verify the boot0 area the same way BROM
> does when booting from it. This might be nice option when you don't
> know what you have on the chip and want to read it but most of the
> time you will want to enforce bootable or non-bootable format when
> writing the NAND.
>
> Thanks
>
> Michal

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

* Re: [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
  2014-01-21 22:57                   ` Jason Gunthorpe
@ 2014-02-04 17:02                     ` Grant Likely
  -1 siblings, 0 replies; 123+ messages in thread
From: Grant Likely @ 2014-02-04 17:02 UTC (permalink / raw)
  To: Jason Gunthorpe, boris brezillon
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	linux-mtd, Rob Landley, Maxime Ripard, David Woodhouse,
	linux-arm-kernel

On Tue, 21 Jan 2014 15:57:40 -0700, Jason Gunthorpe <jgunthorpe@obsidianresearch.com> wrote:
> On Wed, Jan 15, 2014 at 06:03:01PM +0100, boris brezillon wrote:
> 
> > >>Pick a mode value that fits all the parameters of the connected
> > >>non-ONFI flash.
> > >>
> > >>This would be instead of defining each parameter
> > >>individually.. Provide some helpers to convert from a onfi mode number
> > >>to all the onfi defined timing parameters so that drivers can
> > >>configure the HW..
> > >
> > >Are you suggesting we should provide a function that converts these
> > >modes into a nand_timings struct, or just use the timing modes and
> > >let the NAND controller drivers configure its IP accordingly ?
> 
> Either seems reasonable to me, but passing the ONFI mode directly from
> the NAND core to the driver seems a little safer..

I agree here. There are a lot of parameters being defined. If it can be
boiled down to an ONFI mode that will make for a much more robust
binding. Far fewer things to get wrong.

g.


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

* [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support
@ 2014-02-04 17:02                     ` Grant Likely
  0 siblings, 0 replies; 123+ messages in thread
From: Grant Likely @ 2014-02-04 17:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 21 Jan 2014 15:57:40 -0700, Jason Gunthorpe <jgunthorpe@obsidianresearch.com> wrote:
> On Wed, Jan 15, 2014 at 06:03:01PM +0100, boris brezillon wrote:
> 
> > >>Pick a mode value that fits all the parameters of the connected
> > >>non-ONFI flash.
> > >>
> > >>This would be instead of defining each parameter
> > >>individually.. Provide some helpers to convert from a onfi mode number
> > >>to all the onfi defined timing parameters so that drivers can
> > >>configure the HW..
> > >
> > >Are you suggesting we should provide a function that converts these
> > >modes into a nand_timings struct, or just use the timing modes and
> > >let the NAND controller drivers configure its IP accordingly ?
> 
> Either seems reasonable to me, but passing the ONFI mode directly from
> the NAND core to the driver seems a little safer..

I agree here. There are a lot of parameters being defined. If it can be
boiled down to an ONFI mode that will make for a much more robust
binding. Far fewer things to get wrong.

g.

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

* Re: [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
  2014-01-23  1:49     ` Brian Norris
  (?)
  (?)
@ 2014-02-05 13:53       ` Boris BREZILLON
  -1 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-02-05 13:53 UTC (permalink / raw)
  To: Brian Norris
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree, linux-doc, dev, linux-kernel,
	linux-mtd, linux-arm-kernel, Huang Shijie

Hello Brian,

On 23/01/2014 02:49, Brian Norris wrote:
> + Huang
>
> Hi Boris,
>
> On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
>> The Hynix nand flashes store their ECC requirements in byte 4 of its id
>> (returned on READ ID command).
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> I haven't verified yet (perhaps Huang can confirm?), but this may be
> similar to a patch Huang submitted recently. In his case, we found that
> this table is actually quite unreliable and is likely hard to maintain.

Indeed (as stated in this thread 
http://comments.gmane.org/gmane.linux.drivers.mtd/50252).
I'll remove this patch from the next version of this series and make use 
of the
nand-ecc-strength /nand-ecc-size DT properties instead.

Thanks.

Best Regards,

Boris
>
> Why do you need this ECC information, for my reference?
>
> Brian


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

* Re: [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-02-05 13:53       ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-02-05 13:53 UTC (permalink / raw)
  To: Brian Norris
  Cc: Maxime Ripard, Rob Landley, Russell King, David Woodhouse,
	Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, dev-3kdeTeqwOZ9EV1b7eY7vFQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Huang Shijie

Hello Brian,

On 23/01/2014 02:49, Brian Norris wrote:
> + Huang
>
> Hi Boris,
>
> On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
>> The Hynix nand flashes store their ECC requirements in byte 4 of its id
>> (returned on READ ID command).
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon-ZNYIgs0QAGpBDgjK7y7TUQ@public.gmane.org>
> I haven't verified yet (perhaps Huang can confirm?), but this may be
> similar to a patch Huang submitted recently. In his case, we found that
> this table is actually quite unreliable and is likely hard to maintain.

Indeed (as stated in this thread 
http://comments.gmane.org/gmane.linux.drivers.mtd/50252).
I'll remove this patch from the next version of this series and make use 
of the
nand-ecc-strength /nand-ecc-size DT properties instead.

Thanks.

Best Regards,

Boris
>
> Why do you need this ECC information, for my reference?
>
> Brian

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

* Re: [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-02-05 13:53       ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-02-05 13:53 UTC (permalink / raw)
  To: Brian Norris
  Cc: devicetree, Russell King, linux-doc, dev, linux-kernel,
	Huang Shijie, linux-mtd, Rob Landley, Grant Likely,
	Maxime Ripard, David Woodhouse, linux-arm-kernel

Hello Brian,

On 23/01/2014 02:49, Brian Norris wrote:
> + Huang
>
> Hi Boris,
>
> On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
>> The Hynix nand flashes store their ECC requirements in byte 4 of its id
>> (returned on READ ID command).
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> I haven't verified yet (perhaps Huang can confirm?), but this may be
> similar to a patch Huang submitted recently. In his case, we found that
> this table is actually quite unreliable and is likely hard to maintain.

Indeed (as stated in this thread 
http://comments.gmane.org/gmane.linux.drivers.mtd/50252).
I'll remove this patch from the next version of this series and make use 
of the
nand-ecc-strength /nand-ecc-size DT properties instead.

Thanks.

Best Regards,

Boris
>
> Why do you need this ECC information, for my reference?
>
> Brian

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

* [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4
@ 2014-02-05 13:53       ` Boris BREZILLON
  0 siblings, 0 replies; 123+ messages in thread
From: Boris BREZILLON @ 2014-02-05 13:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Brian,

On 23/01/2014 02:49, Brian Norris wrote:
> + Huang
>
> Hi Boris,
>
> On Wed, Jan 08, 2014 at 03:21:56PM +0100, Boris BREZILLON wrote:
>> The Hynix nand flashes store their ECC requirements in byte 4 of its id
>> (returned on READ ID command).
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> I haven't verified yet (perhaps Huang can confirm?), but this may be
> similar to a patch Huang submitted recently. In his case, we found that
> this table is actually quite unreliable and is likely hard to maintain.

Indeed (as stated in this thread 
http://comments.gmane.org/gmane.linux.drivers.mtd/50252).
I'll remove this patch from the next version of this series and make use 
of the
nand-ecc-strength /nand-ecc-size DT properties instead.

Thanks.

Best Regards,

Boris
>
> Why do you need this ECC information, for my reference?
>
> Brian

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

end of thread, other threads:[~2014-02-05 13:54 UTC | newest]

Thread overview: 123+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-08 14:21 [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support Boris BREZILLON
2014-01-08 14:21 ` Boris BREZILLON
2014-01-08 14:21 ` Boris BREZILLON
     [not found] ` < 1389190924-26226-4-git-send-email-b.brezillon@overkiz.com>
2014-01-08 14:21 ` [RFC PATCH 1/9] mtd: nand: retrieve ECC requirements from Hynix READ ID byte 4 Boris BREZILLON
2014-01-08 14:21   ` Boris BREZILLON
2014-01-08 14:21   ` Boris BREZILLON
2014-01-23  1:49   ` Brian Norris
2014-01-23  1:49     ` Brian Norris
2014-01-23  1:49     ` Brian Norris
2014-01-29 10:29     ` boris brezillon
2014-01-29 10:29       ` boris brezillon
2014-01-29 10:29       ` boris brezillon
2014-01-29 10:29       ` boris brezillon
2014-02-05 13:53     ` Boris BREZILLON
2014-02-05 13:53       ` Boris BREZILLON
2014-02-05 13:53       ` Boris BREZILLON
2014-02-05 13:53       ` Boris BREZILLON
2014-01-08 14:21 ` [RFC PATCH 2/9] mtd: nand: define struct nand_timings Boris BREZILLON
2014-01-08 14:21   ` Boris BREZILLON
2014-01-08 14:21   ` Boris BREZILLON
2014-01-08 14:21 ` [RFC PATCH 3/9] of: mtd: add NAND timings retrieval support Boris BREZILLON
2014-01-08 14:21   ` Boris BREZILLON
2014-01-08 14:21   ` Boris BREZILLON
2014-01-08 16:30   ` Rob Herring
2014-01-08 16:30     ` Rob Herring
2014-01-08 16:30     ` Rob Herring
2014-01-08 16:30     ` Rob Herring
2014-01-08 16:36     ` boris brezillon
2014-01-08 16:36       ` boris brezillon
2014-01-08 16:36       ` boris brezillon
2014-01-08 16:36       ` boris brezillon
2014-01-08 18:34   ` Jason Gunthorpe
2014-01-08 18:34     ` Jason Gunthorpe
2014-01-08 18:34     ` Jason Gunthorpe
2014-01-08 19:00     ` boris brezillon
2014-01-08 19:00       ` boris brezillon
2014-01-08 19:00       ` boris brezillon
2014-01-08 19:00       ` boris brezillon
2014-01-08 19:13       ` Jason Gunthorpe
2014-01-08 19:13         ` Jason Gunthorpe
2014-01-08 19:13         ` Jason Gunthorpe
2014-01-08 19:13         ` Jason Gunthorpe
2014-01-09  8:36         ` boris brezillon
2014-01-09  8:36           ` boris brezillon
2014-01-09  8:36           ` boris brezillon
2014-01-09  8:36           ` boris brezillon
2014-01-09 17:35           ` Jason Gunthorpe
2014-01-09 17:35             ` Jason Gunthorpe
2014-01-09 17:35             ` Jason Gunthorpe
2014-01-15 15:09             ` boris brezillon
2014-01-15 15:09               ` boris brezillon
2014-01-15 15:09               ` boris brezillon
2014-01-15 17:03               ` boris brezillon
2014-01-15 17:03                 ` boris brezillon
2014-01-15 17:03                 ` boris brezillon
2014-01-21 22:57                 ` Jason Gunthorpe
2014-01-21 22:57                   ` Jason Gunthorpe
2014-01-21 22:57                   ` Jason Gunthorpe
2014-02-04 17:02                   ` Grant Likely
2014-02-04 17:02                     ` Grant Likely
2014-01-08 14:21 ` [RFC PATCH 4/9] of: mtd: add NAND timings bindings documentation Boris BREZILLON
2014-01-08 14:21   ` Boris BREZILLON
2014-01-08 14:21   ` Boris BREZILLON
2014-01-08 14:22 ` [RFC PATCH 5/9] mtd: nand: add sunxi NFC support Boris BREZILLON
2014-01-08 14:22   ` Boris BREZILLON
2014-01-08 14:22   ` Boris BREZILLON
2014-01-08 19:21   ` boris brezillon
2014-01-08 19:21     ` boris brezillon
2014-01-08 19:21     ` boris brezillon
2014-01-08 14:22 ` [RFC PATCH 6/9] mtd: nand: add sunxi NFC dt bindings doc Boris BREZILLON
2014-01-08 14:22   ` Boris BREZILLON
2014-01-08 14:22   ` Boris BREZILLON
2014-01-08 21:28   ` Arnd Bergmann
2014-01-08 21:28     ` Arnd Bergmann
2014-01-08 21:28     ` Arnd Bergmann
2014-01-09  8:31     ` boris brezillon
2014-01-09  8:31       ` boris brezillon
2014-01-09  8:31       ` boris brezillon
2014-01-09 10:00       ` Arnd Bergmann
2014-01-09 10:00         ` Arnd Bergmann
2014-01-09 10:00         ` Arnd Bergmann
2014-01-08 14:22 ` [RFC PATCH 7/9] ARM: dt/sunxi: add NFC node to Allwinner A20 SoC Boris BREZILLON
2014-01-08 14:22   ` Boris BREZILLON
2014-01-08 14:22   ` Boris BREZILLON
2014-01-08 14:22 ` [RFC PATCH 8/9] ARM: dt/sunxi: add NFC pinctrl pin definitions Boris BREZILLON
2014-01-08 14:22   ` Boris BREZILLON
2014-01-08 14:22   ` Boris BREZILLON
2014-01-08 14:22   ` Boris BREZILLON
2014-01-08 15:28 ` [RFC PATCH 9/9] ARM: sunxi/dt: enable NAND on cubietruck board Boris BREZILLON
2014-01-08 15:28   ` Boris BREZILLON
2014-01-08 15:28   ` Boris BREZILLON
2014-01-08 15:28   ` Boris BREZILLON
2014-01-08 15:30   ` boris brezillon
2014-01-08 15:30     ` boris brezillon
2014-01-08 15:30     ` boris brezillon
2014-01-11 13:38 ` [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support boris brezillon
2014-01-11 13:38   ` boris brezillon
2014-01-11 13:38   ` boris brezillon
2014-01-11 13:38   ` boris brezillon
     [not found]   ` <1389449230.19197.2.camel@localhost>
     [not found]     ` <52D1541F.4040400@overkiz.com>
     [not found]       ` <1389456075.20989.11.camel@localhost>
     [not found]         ` <1389474709.22660.4.camel@localhost>
2014-01-13  9:02           ` [linux-sunxi] " boris brezillon
2014-01-13  9:02             ` boris brezillon
2014-01-13  9:48             ` Henrik Nordström
2014-01-13  9:48               ` Henrik Nordström
     [not found]               ` <6de6ead1-e437-410b-91c0-74afb37dbf39@googlegroups.com>
2014-01-21 18:13                 ` Henrik Nordström
2014-01-21 18:13                   ` Henrik Nordström
2014-01-21 20:55                   ` Henrik Nordström
2014-01-21 20:55                     ` Henrik Nordström
2014-01-29 15:11             ` Michal Suchanek
2014-01-29 15:11               ` Michal Suchanek
2014-01-29 15:43               ` boris brezillon dev
2014-01-29 15:43                 ` boris brezillon dev
2014-01-29 16:08                 ` Michal Suchanek
2014-01-29 16:08                   ` Michal Suchanek
2014-01-29 16:55                   ` boris brezillon dev
2014-01-29 16:55                     ` boris brezillon dev
2014-01-23 15:22   ` Rob Herring
2014-01-23 15:22     ` Rob Herring
2014-01-23 15:22     ` Rob Herring
2014-01-23 15:22     ` Rob Herring
2014-01-29 10:20     ` boris brezillon
2014-01-29 10:20       ` boris brezillon
2014-01-29 10:20       ` boris brezillon
2014-01-29 10:20       ` boris brezillon

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.