linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
@ 2015-09-18 14:53 Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 01/27] ARM: OMAP2+: gpmc: Add platform data Roger Quadros
                   ` (30 more replies)
  0 siblings, 31 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Hi,

We do a couple of things in this series which result in
cleaner device tree implementation, faster perfomance and
multi-platform support. As an added bonus we get new GPI/Interrupt pins
for use in the system.

- Establish a custom interface between NAND and GPMC driver. This is
needed because all of the NAND registers sit in the GPMC register space.
Some bits like NAND IRQ are even shared with GPMC.

- Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
This causes performance increase when using prefetch-irq mode.
30% increase in read, 17% increase in write in prefetch-irq mode.

- Clean up device tree support so that omap-gpmc IP and the omap2 NAND
driver can be used on non-OMAP platforms. e.g. Keystone.

- Implement GPIOCHIP + IRQCHIP for the GPMC WAITPINS. SoCs can contain
2 to 4 of these and most of them would be unused otherwise. It also
allows a cleaner implementation of NAND Ready pin status for the NAND driver.

- Implement GPIOlib based NAND ready pin checking for OMAP NAND driver.

This series is available at
git@github.com:rogerq/linux.git
in branch
for-v4.4/gpmc-v3

cheers,
-roger

Changelog:
v3:
-Fixed and tested NAND using legacy boot on omap3-beagle.
-Support rising and falling edge interrupts on WAITpins.
-Update DT node of all gpmc users.

Roger Quadros (27):
  ARM: OMAP2+: gpmc: Add platform data
  ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data
  memory: omap-gpmc: Introduce GPMC to NAND interface
  mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers
  memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status
  mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty
    check
  memory: omap-gpmc: Remove NAND IRQ code
  memory: omap-gpmc: Add IRQ ops for GPMC-NAND interface
  mtd: nand: omap2: manage NAND interrupts
  mtd: nand: omap: Copy platform data parameters to omap_nand_info data
  mtd: nand: omap: Clean up device tree support
  mtd: nand: omap: Update DT binding documentation
  memory: omap-gpmc: Prevent mapping into 1st 16MB
  memory: omap-gpmc: Move device tree binding to correct location
  memory: omap-gpmc: Support general purpose input for WAITPINs
  memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring
  memory: omap-gpmc: Add irqchip support to the gpiochip
  mtd: nand: omap2: Implement NAND ready using gpiolib
  memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via
    gpmc_regs
  ARM: dts: dra7: Fix NAND device nodes.
  ARM: dts: dra7x-evm: Provide NAND ready pin
  ARM: dts: am437x: Fix NAND device nodes
  ARM: dts: am437x-gp-evm: Provide NAND ready pin
  ARM: dts: am335x: Fix NAND device nodes
  ARM: dts: am335x: Provide NAND ready pin
  ARM: dts: dm816x: Fix gpmc and NAND node
  ARM: dts: omap3: Fix gpmc and NAND nodes

 Documentation/devicetree/bindings/bus/ti-gpmc.txt  | 130 -----
 .../bindings/memory-controllers/omap-gpmc.txt      | 130 +++++
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
 arch/arm/boot/dts/am335x-chilisom.dtsi             |   7 +-
 arch/arm/boot/dts/am335x-evm.dts                   |   7 +-
 arch/arm/boot/dts/am335x-igep0033.dtsi             |   7 +-
 arch/arm/boot/dts/am33xx.dtsi                      |   4 +
 arch/arm/boot/dts/am4372.dtsi                      |   4 +
 arch/arm/boot/dts/am437x-gp-evm.dts                |   8 +-
 arch/arm/boot/dts/am43x-epos-evm.dts               |   8 +-
 arch/arm/boot/dts/dm8168-evm.dts                   |   7 +-
 arch/arm/boot/dts/dm816x.dtsi                      |   4 +
 arch/arm/boot/dts/dra7-evm.dts                     |   6 +-
 arch/arm/boot/dts/dra7.dtsi                        |   4 +
 arch/arm/boot/dts/dra72-evm.dts                    |   6 +-
 arch/arm/boot/dts/logicpd-torpedo-som.dtsi         |   7 +-
 arch/arm/boot/dts/omap3-beagle.dts                 |   2 +
 arch/arm/boot/dts/omap3-cm-t3x.dtsi                |   5 +-
 arch/arm/boot/dts/omap3-devkit8000-common.dtsi     |   3 +
 arch/arm/boot/dts/omap3-evm-37xx.dts               |   7 +-
 arch/arm/boot/dts/omap3-gta04.dtsi                 |   3 +
 arch/arm/boot/dts/omap3-igep.dtsi                  |   5 +-
 arch/arm/boot/dts/omap3-igep0020-common.dtsi       |   4 +-
 arch/arm/boot/dts/omap3-igep0030-common.dtsi       |   4 +
 arch/arm/boot/dts/omap3-ldp.dts                    |   9 +-
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi            |   5 +-
 arch/arm/boot/dts/omap3-pandora-common.dtsi        |   3 +
 arch/arm/boot/dts/omap3-tao3530.dtsi               |   5 +-
 arch/arm/boot/dts/omap3.dtsi                       |   4 +
 arch/arm/boot/dts/omap3430-sdp.dts                 |   5 +-
 arch/arm/mach-omap2/gpmc-nand.c                    |  11 +-
 drivers/memory/omap-gpmc.c                         | 640 ++++++++++++---------
 drivers/mtd/nand/omap2.c                           | 261 ++++++---
 include/linux/omap-gpmc.h                          | 183 ++----
 include/linux/platform_data/gpmc-omap.h            | 167 ++++++
 include/linux/platform_data/mtd-nand-omap2.h       |  12 +-
 36 files changed, 1045 insertions(+), 648 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 create mode 100644 include/linux/platform_data/gpmc-omap.h

-- 
2.1.4


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

* [PATCH v3 01/27] ARM: OMAP2+: gpmc: Add platform data
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 02/27] ARM: OMAP2+: gpmc: Add gpmc timings and settings to " Roger Quadros
                   ` (29 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Add a platform data structure for GPMC. It contains all the necessary
platform information that needs to be passed from platform init code
to GPMC driver.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 include/linux/omap-gpmc.h               |  3 +--
 include/linux/platform_data/gpmc-omap.h | 30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/platform_data/gpmc-omap.h

diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index 7dee0014..5c79190 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -7,8 +7,7 @@
  *  option) any later version.
  */
 
-/* Maximum Number of Chip Selects */
-#define GPMC_CS_NUM		8
+#include <linux/platform_data/gpmc-omap.h>
 
 #define GPMC_CONFIG_WP		0x00000005
 
diff --git a/include/linux/platform_data/gpmc-omap.h b/include/linux/platform_data/gpmc-omap.h
new file mode 100644
index 0000000..d32d9de
--- /dev/null
+++ b/include/linux/platform_data/gpmc-omap.h
@@ -0,0 +1,30 @@
+/*
+ * OMAP GPMC Platform data
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc. - http://www.ti.com
+ *	Roger Quadros <rogerq@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef _GPMC_OMAP_H_
+#define _GPMC_OMAP_H_
+
+/* Maximum Number of Chip Selects */
+#define GPMC_CS_NUM		8
+
+/* Data for each chip select */
+struct gpmc_omap_cs_data {
+	bool valid;			/* data is valid */
+	bool is_nand;			/* device within this CS is NAND */
+	struct platform_device *pdev;	/* device within this CS region */
+	unsigned pdata_size;
+};
+
+struct gpmc_omap_platform_data {
+	struct gpmc_omap_cs_data cs[GPMC_CS_NUM];
+};
+
+#endif /* _GPMC_OMAP_H */
-- 
2.1.4


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

* [PATCH v3 02/27] ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 01/27] ARM: OMAP2+: gpmc: Add platform data Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 03/27] memory: omap-gpmc: Introduce GPMC to NAND interface Roger Quadros
                   ` (28 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Add device_timings, gpmc_timings and gpmc_setting to
gpmc platform data.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 include/linux/omap-gpmc.h               | 134 -------------------------------
 include/linux/platform_data/gpmc-omap.h | 137 ++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+), 134 deletions(-)

diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index 5c79190..2dcef1c 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -14,140 +14,6 @@
 #define GPMC_IRQ_FIFOEVENTENABLE	0x01
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
-#define GPMC_BURST_4			4	/* 4 word burst */
-#define GPMC_BURST_8			8	/* 8 word burst */
-#define GPMC_BURST_16			16	/* 16 word burst */
-#define GPMC_DEVWIDTH_8BIT		1	/* 8-bit device width */
-#define GPMC_DEVWIDTH_16BIT		2	/* 16-bit device width */
-#define GPMC_MUX_AAD			1	/* Addr-Addr-Data multiplex */
-#define GPMC_MUX_AD			2	/* Addr-Data multiplex */
-
-/* bool type time settings */
-struct gpmc_bool_timings {
-	bool cycle2cyclediffcsen;
-	bool cycle2cyclesamecsen;
-	bool we_extra_delay;
-	bool oe_extra_delay;
-	bool adv_extra_delay;
-	bool cs_extra_delay;
-	bool time_para_granularity;
-};
-
-/*
- * Note that all values in this struct are in nanoseconds except sync_clk
- * (which is in picoseconds), while the register values are in gpmc_fck cycles.
- */
-struct gpmc_timings {
-	/* Minimum clock period for synchronous mode (in picoseconds) */
-	u32 sync_clk;
-
-	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
-	u32 cs_on;		/* Assertion time */
-	u32 cs_rd_off;		/* Read deassertion time */
-	u32 cs_wr_off;		/* Write deassertion time */
-
-	/* ADV signal timings corresponding to GPMC_CONFIG3 */
-	u32 adv_on;		/* Assertion time */
-	u32 adv_rd_off;		/* Read deassertion time */
-	u32 adv_wr_off;		/* Write deassertion time */
-
-	/* WE signals timings corresponding to GPMC_CONFIG4 */
-	u32 we_on;		/* WE assertion time */
-	u32 we_off;		/* WE deassertion time */
-
-	/* OE signals timings corresponding to GPMC_CONFIG4 */
-	u32 oe_on;		/* OE assertion time */
-	u32 oe_off;		/* OE deassertion time */
-
-	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
-	u32 page_burst_access;	/* Multiple access word delay */
-	u32 access;		/* Start-cycle to first data valid delay */
-	u32 rd_cycle;		/* Total read cycle time */
-	u32 wr_cycle;		/* Total write cycle time */
-
-	u32 bus_turnaround;
-	u32 cycle2cycle_delay;
-
-	u32 wait_monitoring;
-	u32 clk_activation;
-
-	/* The following are only on OMAP3430 */
-	u32 wr_access;		/* WRACCESSTIME */
-	u32 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
-
-	struct gpmc_bool_timings bool_timings;
-};
-
-/* Device timings in picoseconds */
-struct gpmc_device_timings {
-	u32 t_ceasu;	/* address setup to CS valid */
-	u32 t_avdasu;	/* address setup to ADV valid */
-	/* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
-	 * of tusb using these timings even for sync whilst
-	 * ideally for adv_rd/(wr)_off it should have considered
-	 * t_avdh instead. This indirectly necessitates r/w
-	 * variations of t_avdp as it is possible to have one
-	 * sync & other async
-	 */
-	u32 t_avdp_r;	/* ADV low time (what about t_cer ?) */
-	u32 t_avdp_w;
-	u32 t_aavdh;	/* address hold time */
-	u32 t_oeasu;	/* address setup to OE valid */
-	u32 t_aa;	/* access time from ADV assertion */
-	u32 t_iaa;	/* initial access time */
-	u32 t_oe;	/* access time from OE assertion */
-	u32 t_ce;	/* access time from CS asertion */
-	u32 t_rd_cycle;	/* read cycle time */
-	u32 t_cez_r;	/* read CS deassertion to high Z */
-	u32 t_cez_w;	/* write CS deassertion to high Z */
-	u32 t_oez;	/* OE deassertion to high Z */
-	u32 t_weasu;	/* address setup to WE valid */
-	u32 t_wpl;	/* write assertion time */
-	u32 t_wph;	/* write deassertion time */
-	u32 t_wr_cycle;	/* write cycle time */
-
-	u32 clk;
-	u32 t_bacc;	/* burst access valid clock to output delay */
-	u32 t_ces;	/* CS setup time to clk */
-	u32 t_avds;	/* ADV setup time to clk */
-	u32 t_avdh;	/* ADV hold time from clk */
-	u32 t_ach;	/* address hold time from clk */
-	u32 t_rdyo;	/* clk to ready valid */
-
-	u32 t_ce_rdyz;	/* XXX: description ?, or use t_cez instead */
-	u32 t_ce_avd;	/* CS on to ADV on delay */
-
-	/* XXX: check the possibility of combining
-	 * cyc_aavhd_oe & cyc_aavdh_we
-	 */
-	u8 cyc_aavdh_oe;/* read address hold time in cycles */
-	u8 cyc_aavdh_we;/* write address hold time in cycles */
-	u8 cyc_oe;	/* access time from OE assertion in cycles */
-	u8 cyc_wpl;	/* write deassertion time in cycles */
-	u32 cyc_iaa;	/* initial access time in cycles */
-
-	/* extra delays */
-	bool ce_xdelay;
-	bool avd_xdelay;
-	bool oe_xdelay;
-	bool we_xdelay;
-};
-
-struct gpmc_settings {
-	bool burst_wrap;	/* enables wrap bursting */
-	bool burst_read;	/* enables read page/burst mode */
-	bool burst_write;	/* enables write page/burst mode */
-	bool device_nand;	/* device is NAND */
-	bool sync_read;		/* enables synchronous reads */
-	bool sync_write;	/* enables synchronous writes */
-	bool wait_on_read;	/* monitor wait on reads */
-	bool wait_on_write;	/* monitor wait on writes */
-	u32 burst_len;		/* page/burst length */
-	u32 device_width;	/* device bus width (8 or 16 bit) */
-	u32 mux_add_data;	/* multiplex address & data */
-	u32 wait_pin;		/* wait-pin to be used */
-};
-
 extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
 			     struct gpmc_settings *gpmc_s,
 			     struct gpmc_device_timings *dev_t);
diff --git a/include/linux/platform_data/gpmc-omap.h b/include/linux/platform_data/gpmc-omap.h
index d32d9de..4461fa8 100644
--- a/include/linux/platform_data/gpmc-omap.h
+++ b/include/linux/platform_data/gpmc-omap.h
@@ -15,10 +15,147 @@
 /* Maximum Number of Chip Selects */
 #define GPMC_CS_NUM		8
 
+/* bool type time settings */
+struct gpmc_bool_timings {
+	bool cycle2cyclediffcsen;
+	bool cycle2cyclesamecsen;
+	bool we_extra_delay;
+	bool oe_extra_delay;
+	bool adv_extra_delay;
+	bool cs_extra_delay;
+	bool time_para_granularity;
+};
+
+/*
+ * Note that all values in this struct are in nanoseconds except sync_clk
+ * (which is in picoseconds), while the register values are in gpmc_fck cycles.
+ */
+struct gpmc_timings {
+	/* Minimum clock period for synchronous mode (in picoseconds) */
+	u32 sync_clk;
+
+	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
+	u32 cs_on;		/* Assertion time */
+	u32 cs_rd_off;		/* Read deassertion time */
+	u32 cs_wr_off;		/* Write deassertion time */
+
+	/* ADV signal timings corresponding to GPMC_CONFIG3 */
+	u32 adv_on;		/* Assertion time */
+	u32 adv_rd_off;		/* Read deassertion time */
+	u32 adv_wr_off;		/* Write deassertion time */
+
+	/* WE signals timings corresponding to GPMC_CONFIG4 */
+	u32 we_on;		/* WE assertion time */
+	u32 we_off;		/* WE deassertion time */
+
+	/* OE signals timings corresponding to GPMC_CONFIG4 */
+	u32 oe_on;		/* OE assertion time */
+	u32 oe_off;		/* OE deassertion time */
+
+	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
+	u32 page_burst_access;	/* Multiple access word delay */
+	u32 access;		/* Start-cycle to first data valid delay */
+	u32 rd_cycle;		/* Total read cycle time */
+	u32 wr_cycle;		/* Total write cycle time */
+
+	u32 bus_turnaround;
+	u32 cycle2cycle_delay;
+
+	u32 wait_monitoring;
+	u32 clk_activation;
+
+	/* The following are only on OMAP3430 */
+	u32 wr_access;		/* WRACCESSTIME */
+	u32 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+
+	struct gpmc_bool_timings bool_timings;
+};
+
+/* Device timings in picoseconds */
+struct gpmc_device_timings {
+	u32 t_ceasu;	/* address setup to CS valid */
+	u32 t_avdasu;	/* address setup to ADV valid */
+	/* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
+	 * of tusb using these timings even for sync whilst
+	 * ideally for adv_rd/(wr)_off it should have considered
+	 * t_avdh instead. This indirectly necessitates r/w
+	 * variations of t_avdp as it is possible to have one
+	 * sync & other async
+	 */
+	u32 t_avdp_r;	/* ADV low time (what about t_cer ?) */
+	u32 t_avdp_w;
+	u32 t_aavdh;	/* address hold time */
+	u32 t_oeasu;	/* address setup to OE valid */
+	u32 t_aa;	/* access time from ADV assertion */
+	u32 t_iaa;	/* initial access time */
+	u32 t_oe;	/* access time from OE assertion */
+	u32 t_ce;	/* access time from CS asertion */
+	u32 t_rd_cycle;	/* read cycle time */
+	u32 t_cez_r;	/* read CS deassertion to high Z */
+	u32 t_cez_w;	/* write CS deassertion to high Z */
+	u32 t_oez;	/* OE deassertion to high Z */
+	u32 t_weasu;	/* address setup to WE valid */
+	u32 t_wpl;	/* write assertion time */
+	u32 t_wph;	/* write deassertion time */
+	u32 t_wr_cycle;	/* write cycle time */
+
+	u32 clk;
+	u32 t_bacc;	/* burst access valid clock to output delay */
+	u32 t_ces;	/* CS setup time to clk */
+	u32 t_avds;	/* ADV setup time to clk */
+	u32 t_avdh;	/* ADV hold time from clk */
+	u32 t_ach;	/* address hold time from clk */
+	u32 t_rdyo;	/* clk to ready valid */
+
+	u32 t_ce_rdyz;	/* XXX: description ?, or use t_cez instead */
+	u32 t_ce_avd;	/* CS on to ADV on delay */
+
+	/* XXX: check the possibility of combining
+	 * cyc_aavhd_oe & cyc_aavdh_we
+	 */
+	u8 cyc_aavdh_oe;/* read address hold time in cycles */
+	u8 cyc_aavdh_we;/* write address hold time in cycles */
+	u8 cyc_oe;	/* access time from OE assertion in cycles */
+	u8 cyc_wpl;	/* write deassertion time in cycles */
+	u32 cyc_iaa;	/* initial access time in cycles */
+
+	/* extra delays */
+	bool ce_xdelay;
+	bool avd_xdelay;
+	bool oe_xdelay;
+	bool we_xdelay;
+};
+
+#define GPMC_BURST_4			4	/* 4 word burst */
+#define GPMC_BURST_8			8	/* 8 word burst */
+#define GPMC_BURST_16			16	/* 16 word burst */
+#define GPMC_DEVWIDTH_8BIT		1	/* 8-bit device width */
+#define GPMC_DEVWIDTH_16BIT		2	/* 16-bit device width */
+#define GPMC_MUX_AAD			1	/* Addr-Addr-Data multiplex */
+#define GPMC_MUX_AD			2	/* Addr-Data multiplex */
+
+struct gpmc_settings {
+	bool burst_wrap;	/* enables wrap bursting */
+	bool burst_read;	/* enables read page/burst mode */
+	bool burst_write;	/* enables write page/burst mode */
+	bool device_nand;	/* device is NAND */
+	bool sync_read;		/* enables synchronous reads */
+	bool sync_write;	/* enables synchronous writes */
+	bool wait_on_read;	/* monitor wait on reads */
+	bool wait_on_write;	/* monitor wait on writes */
+	u32 burst_len;		/* page/burst length */
+	u32 device_width;	/* device bus width (8 or 16 bit) */
+	u32 mux_add_data;	/* multiplex address & data */
+	u32 wait_pin;		/* wait-pin to be used */
+};
+
 /* Data for each chip select */
 struct gpmc_omap_cs_data {
 	bool valid;			/* data is valid */
 	bool is_nand;			/* device within this CS is NAND */
+	struct gpmc_settings *settings;
+	struct gpmc_device_timings *device_timings;
+	struct gpmc_timings *gpmc_timings;
 	struct platform_device *pdev;	/* device within this CS region */
 	unsigned pdata_size;
 };
-- 
2.1.4


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

* [PATCH v3 03/27] memory: omap-gpmc: Introduce GPMC to NAND interface
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 01/27] ARM: OMAP2+: gpmc: Add platform data Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 02/27] ARM: OMAP2+: gpmc: Add gpmc timings and settings to " Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 04/27] mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers Roger Quadros
                   ` (27 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

The OMAP GPMC module has certain registers dedicated for NAND
access and some NAND bits mixed with other GPMC functionality.

For the NAND dedicated registers we have the struct gpmc_nand_regs.

The NAND driver needs to access NAND specific bits from the
following non-dedicated registers
1) FIFOEVENT and TERMCOUNT from GPMC_IRQENABLE and GPMC_IRQSTATUS
2) EMPTYWRITEBUFFERSTATUS from GPMC_STATUS

For accessing these bits we introduce the struct gpmc_nand_ops.

Rename the gpmc_update_nand_reg() API to gpmc_omap_get_nand_ops()
and make it return the gpmc_nand_ops along with updating the
gpmc_nand_regs. This API will be called by the OMAP NAND driver
to access the necessary bits in GPMC register space.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/memory/omap-gpmc.c | 21 ++++++++++++++++++++
 include/linux/omap-gpmc.h  | 49 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 32ac049..a80c53e 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -1099,6 +1099,27 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 	}
 }
 
+static struct gpmc_nand_ops nand_ops;
+
+/**
+ * gpmc_omap_get_nand_ops - Get the GPMC NAND interface
+ * @regs: the GPMC NAND register map exclusive for NAND use.
+ * @cs: GPMC chip select number on which the NAND sits. The
+ *      register map returned will be specific to this chip select.
+ *
+ * Returns NULL on error e.g. invalid cs.
+ */
+struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
+{
+	if (cs >= gpmc_cs_num)
+		return NULL;
+
+	gpmc_update_nand_reg(reg, cs);
+
+	return &nand_ops;
+}
+EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
+
 int gpmc_get_client_irq(unsigned irq_config)
 {
 	int i;
diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index 2dcef1c..7de9f9b 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -14,14 +14,59 @@
 #define GPMC_IRQ_FIFOEVENTENABLE	0x01
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
+enum gpmc_nand_irq {
+	GPMC_NAND_IRQ_FIFOEVENT = 0,
+	GPMC_NAND_IRQ_TERMCOUNT,
+};
+
+/**
+ * gpmc_nand_ops - Interface between NAND and GPMC
+ * @nand_irq_enable: enable the requested GPMC NAND interrupt event.
+ * @nand_irq_disable: disable the requested GPMC NAND interrupt event.
+ * @nand_irq_clear: clears the GPMC NAND interrupt event status.
+ * @nand_irq_status: get the NAND interrupt event status.
+ * @nand_write_buffer_empty: get the NAND write buffer empty status.
+ */
+struct gpmc_nand_ops {
+	int (*nand_irq_enable)(enum gpmc_nand_irq irq);
+	int (*nand_irq_disable)(enum gpmc_nand_irq irq);
+	void (*nand_irq_clear)(enum gpmc_nand_irq irq);
+	u32 (*nand_irq_status)(void);
+	bool (*nand_writebuffer_empty)(void);
+};
+
+struct gpmc_nand_regs;
+
+#if IS_ENABLED(CONFIG_OMAP_GPMC)
+struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
+					     int cs);
+#else
+static inline gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
+						    int cs)
+{
+	return NULL;
+}
+#endif /* CONFIG_OMAP_GPMC */
+
+/*--------------------------------*/
+
+/* deprecated APIs */
+#if IS_ENABLED(CONFIG_OMAP_GPMC)
+void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+#else
+static inline void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
+{
+	reg = NULL;
+}
+#endif /* CONFIG_OMAP_GPMC */
+/*--------------------------------*/
+
 extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
 			     struct gpmc_settings *gpmc_s,
 			     struct gpmc_device_timings *dev_t);
 
-struct gpmc_nand_regs;
 struct device_node;
 
-extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
 extern int gpmc_get_client_irq(unsigned irq_config);
 
 extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
-- 
2.1.4


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

* [PATCH v3 04/27] mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (2 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 03/27] memory: omap-gpmc: Introduce GPMC to NAND interface Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-12-03  5:00   ` Brian Norris
  2015-09-18 14:53 ` [PATCH v3 05/27] memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status Roger Quadros
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Deprecate nand register passing via platform data and use
gpmc_omap_get_nand_ops() instead.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/mach-omap2/gpmc-nand.c              | 2 --
 drivers/mtd/nand/omap2.c                     | 9 ++++++++-
 include/linux/platform_data/mtd-nand-omap2.h | 4 +++-
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 72918c4..04e6998 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -121,8 +121,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 	if (err < 0)
 		goto out_free_cs;
 
-	gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
-
 	if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
 		pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
 		err = -EINVAL;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 60fa899..f214fe2 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -28,6 +28,7 @@
 #include <linux/mtd/nand_bch.h>
 #include <linux/platform_data/elm.h>
 
+#include <linux/omap-gpmc.h>
 #include <linux/platform_data/mtd-nand-omap2.h>
 
 #define	DRIVER_NAME	"omap2-nand"
@@ -169,7 +170,9 @@ struct omap_nand_info {
 	} iomode;
 	u_char				*buf;
 	int					buf_len;
+	/* Interface to GPMC */
 	struct gpmc_nand_regs		reg;
+	struct gpmc_nand_ops		*ops;
 	/* generated at runtime depending on ECC algorithm and layout selected */
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
@@ -1677,9 +1680,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, info);
 
+	info->ops = gpmc_omap_get_nand_ops(&info->reg, info->gpmc_cs);
+	if (!info->ops) {
+		dev_err(&pdev->dev, "Failed to get GPMC->NAND interface\n");
+		return -ENODEV;
+	}
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
-	info->reg		= pdata->reg;
 	info->of_node		= pdata->of_node;
 	info->ecc_opt		= pdata->ecc_opt;
 	mtd			= &info->mtd;
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 090bbab..a067f58 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -75,10 +75,12 @@ struct omap_nand_platform_data {
 	enum nand_io		xfer_type;
 	int			devsize;
 	enum omap_ecc           ecc_opt;
-	struct gpmc_nand_regs	reg;
 
 	/* for passing the partitions */
 	struct device_node	*of_node;
 	struct device_node	*elm_of_node;
+
+	/* deprecated */
+	struct gpmc_nand_regs	reg;
 };
 #endif
-- 
2.1.4


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

* [PATCH v3 05/27] memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (3 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 04/27] mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 06/27] mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty check Roger Quadros
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

This is needed by OMAP NAND driver to poll the empty status
of the writebuffer.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/memory/omap-gpmc.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index a80c53e..174c45b 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -81,6 +81,8 @@
 
 #define GPMC_CONFIG_LIMITEDADDRESS		BIT(1)
 
+#define GPMC_STATUS_EMPTYWRITEBUFFERSTATUS	BIT(0)
+
 #define	GPMC_CONFIG2_CSEXTRADELAY		BIT(7)
 #define	GPMC_CONFIG3_ADVEXTRADELAY		BIT(7)
 #define	GPMC_CONFIG4_OEEXTRADELAY		BIT(7)
@@ -1099,7 +1101,17 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 	}
 }
 
-static struct gpmc_nand_ops nand_ops;
+static bool gpmc_nand_writebuffer_empty(void)
+{
+	if (gpmc_read_reg(GPMC_STATUS) & GPMC_STATUS_EMPTYWRITEBUFFERSTATUS)
+		return true;
+
+	return false;
+}
+
+static struct gpmc_nand_ops nand_ops = {
+	.nand_writebuffer_empty = gpmc_nand_writebuffer_empty,
+};
 
 /**
  * gpmc_omap_get_nand_ops - Get the GPMC NAND interface
-- 
2.1.4


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

* [PATCH v3 06/27] mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty check
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (4 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 05/27] memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 07/27] memory: omap-gpmc: Remove NAND IRQ code Roger Quadros
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Instead of accessing the gpmc_status register directly start
using the gpmc_nand_ops->nand_writebuffer_empty() helper
to check write buffer empty status.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/mtd/nand/omap2.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index f214fe2..0eb0b8c 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -289,14 +289,13 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len)
 	struct omap_nand_info *info = container_of(mtd,
 						struct omap_nand_info, mtd);
 	u_char *p = (u_char *)buf;
-	u32	status = 0;
+	bool status;
 
 	while (len--) {
 		iowrite8(*p++, info->nand.IO_ADDR_W);
 		/* wait until buffer is available for write */
 		do {
-			status = readl(info->reg.gpmc_status) &
-					STATUS_BUFF_EMPTY;
+			status = info->ops->nand_writebuffer_empty();
 		} while (!status);
 	}
 }
@@ -325,7 +324,7 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
 	struct omap_nand_info *info = container_of(mtd,
 						struct omap_nand_info, mtd);
 	u16 *p = (u16 *) buf;
-	u32	status = 0;
+	bool status;
 	/* FIXME try bursts of writesw() or DMA ... */
 	len >>= 1;
 
@@ -333,8 +332,7 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
 		iowrite16(*p++, info->nand.IO_ADDR_W);
 		/* wait until buffer is available for write */
 		do {
-			status = readl(info->reg.gpmc_status) &
-					STATUS_BUFF_EMPTY;
+			status = info->ops->nand_writebuffer_empty();
 		} while (!status);
 	}
 }
-- 
2.1.4


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

* [PATCH v3 07/27] memory: omap-gpmc: Remove NAND IRQ code
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (5 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 06/27] mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty check Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 08/27] memory: omap-gpmc: Add IRQ ops for GPMC-NAND interface Roger Quadros
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

NAND IRQs will now be managed directly in the OMAP NAND driver
so remove the IRQchip model.

Another patch will add back GPIO-IRQchip code to handle the
WAITPIN interrupts.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/mach-omap2/gpmc-nand.c |   4 +-
 drivers/memory/omap-gpmc.c      | 163 +---------------------------------------
 include/linux/omap-gpmc.h       |  11 +--
 3 files changed, 10 insertions(+), 168 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 04e6998..ffe646a 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -80,7 +80,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 	struct resource gpmc_nand_res[] = {
 		{ .flags = IORESOURCE_MEM, },
 		{ .flags = IORESOURCE_IRQ, },
-		{ .flags = IORESOURCE_IRQ, },
 	};
 
 	BUG_ON(gpmc_nand_data->cs >= GPMC_CS_NUM);
@@ -93,8 +92,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 		return err;
 	}
 	gpmc_nand_res[0].end = gpmc_nand_res[0].start + NAND_IO_SIZE - 1;
-	gpmc_nand_res[1].start = gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
-	gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
+	gpmc_nand_res[1].start = gpmc_get_irq();
 
 	memset(&s, 0, sizeof(struct gpmc_settings));
 	if (gpmc_nand_data->of_node)
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 174c45b..a9071bb 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -123,12 +123,6 @@
 #define GPMC_CS_NAND_ADDRESS	0x20
 #define GPMC_CS_NAND_DATA	0x24
 
-/* Control Commands */
-#define GPMC_CONFIG_RDY_BSY	0x00000001
-#define GPMC_CONFIG_DEV_SIZE	0x00000002
-#define GPMC_CONFIG_DEV_TYPE	0x00000003
-#define GPMC_SET_IRQ_STATUS	0x00000004
-
 #define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
 #define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
 #define GPMC_CONFIG1_READTYPE_ASYNC     (0 << 29)
@@ -176,17 +170,11 @@
 #define GPMC_CONFIG_WRITEPROTECT	0x00000010
 #define WR_RD_PIN_MONITORING		0x00600000
 
-#define GPMC_ENABLE_IRQ		0x0000000d
-
 /* ECC commands */
 #define GPMC_ECC_READ		0 /* Reset Hardware ECC for read */
 #define GPMC_ECC_WRITE		1 /* Reset Hardware ECC for write */
 #define GPMC_ECC_READSYN	2 /* Reset before syndrom is read back */
 
-/* XXX: Only NAND irq has been considered,currently these are the only ones used
- */
-#define	GPMC_NR_IRQ		2
-
 enum gpmc_clk_domain {
 	GPMC_CD_FCLK,
 	GPMC_CD_CLK
@@ -201,11 +189,6 @@ struct gpmc_cs_data {
 	struct resource mem;
 };
 
-struct gpmc_client_irq	{
-	unsigned		irq;
-	u32			bitmask;
-};
-
 /* Structure to save gpmc cs context */
 struct gpmc_cs_config {
 	u32 config1;
@@ -233,10 +216,6 @@ struct omap3_gpmc_regs {
 	struct gpmc_cs_config cs_context[GPMC_CS_NUM];
 };
 
-static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
-static struct irq_chip gpmc_irq_chip;
-static int gpmc_irq_start;
-
 static struct resource	gpmc_mem_root;
 static struct gpmc_cs_data gpmc_cs[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
@@ -244,15 +223,13 @@ static DEFINE_SPINLOCK(gpmc_mem_lock);
 static unsigned int gpmc_cs_num = GPMC_CS_NUM;
 static unsigned int gpmc_nr_waitpins;
 static struct device *gpmc_dev;
-static int gpmc_irq;
+static int gpmc_irq = -EINVAL;
 static resource_size_t phys_base, mem_size;
 static unsigned gpmc_capability;
 static void __iomem *gpmc_base;
 
 static struct clk *gpmc_l3_clk;
 
-static irqreturn_t gpmc_handle_irq(int irq, void *dev);
-
 static void gpmc_write_reg(int idx, u32 val)
 {
 	writel_relaxed(val, gpmc_base + idx);
@@ -1037,14 +1014,6 @@ int gpmc_configure(int cmd, int wval)
 	u32 regval;
 
 	switch (cmd) {
-	case GPMC_ENABLE_IRQ:
-		gpmc_write_reg(GPMC_IRQENABLE, wval);
-		break;
-
-	case GPMC_SET_IRQ_STATUS:
-		gpmc_write_reg(GPMC_IRQSTATUS, wval);
-		break;
-
 	case GPMC_CONFIG_WP:
 		regval = gpmc_read_reg(GPMC_CONFIG);
 		if (wval)
@@ -1132,112 +1101,9 @@ struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
 }
 EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
 
-int gpmc_get_client_irq(unsigned irq_config)
-{
-	int i;
-
-	if (hweight32(irq_config) > 1)
-		return 0;
-
-	for (i = 0; i < GPMC_NR_IRQ; i++)
-		if (gpmc_client_irq[i].bitmask & irq_config)
-			return gpmc_client_irq[i].irq;
-
-	return 0;
-}
-
-static int gpmc_irq_endis(unsigned irq, bool endis)
-{
-	int i;
-	u32 regval;
-
-	for (i = 0; i < GPMC_NR_IRQ; i++)
-		if (irq == gpmc_client_irq[i].irq) {
-			regval = gpmc_read_reg(GPMC_IRQENABLE);
-			if (endis)
-				regval |= gpmc_client_irq[i].bitmask;
-			else
-				regval &= ~gpmc_client_irq[i].bitmask;
-			gpmc_write_reg(GPMC_IRQENABLE, regval);
-			break;
-		}
-
-	return 0;
-}
-
-static void gpmc_irq_disable(struct irq_data *p)
+int gpmc_get_irq(void)
 {
-	gpmc_irq_endis(p->irq, false);
-}
-
-static void gpmc_irq_enable(struct irq_data *p)
-{
-	gpmc_irq_endis(p->irq, true);
-}
-
-static void gpmc_irq_noop(struct irq_data *data) { }
-
-static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
-
-static int gpmc_setup_irq(void)
-{
-	int i;
-	u32 regval;
-
-	if (!gpmc_irq)
-		return -EINVAL;
-
-	gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0);
-	if (gpmc_irq_start < 0) {
-		pr_err("irq_alloc_descs failed\n");
-		return gpmc_irq_start;
-	}
-
-	gpmc_irq_chip.name = "gpmc";
-	gpmc_irq_chip.irq_startup = gpmc_irq_noop_ret;
-	gpmc_irq_chip.irq_enable = gpmc_irq_enable;
-	gpmc_irq_chip.irq_disable = gpmc_irq_disable;
-	gpmc_irq_chip.irq_shutdown = gpmc_irq_noop;
-	gpmc_irq_chip.irq_ack = gpmc_irq_noop;
-	gpmc_irq_chip.irq_mask = gpmc_irq_noop;
-	gpmc_irq_chip.irq_unmask = gpmc_irq_noop;
-
-	gpmc_client_irq[0].bitmask = GPMC_IRQ_FIFOEVENTENABLE;
-	gpmc_client_irq[1].bitmask = GPMC_IRQ_COUNT_EVENT;
-
-	for (i = 0; i < GPMC_NR_IRQ; i++) {
-		gpmc_client_irq[i].irq = gpmc_irq_start + i;
-		irq_set_chip_and_handler(gpmc_client_irq[i].irq,
-					&gpmc_irq_chip, handle_simple_irq);
-		irq_modify_status(gpmc_client_irq[i].irq, IRQ_NOREQUEST,
-				  IRQ_NOAUTOEN);
-	}
-
-	/* Disable interrupts */
-	gpmc_write_reg(GPMC_IRQENABLE, 0);
-
-	/* clear interrupts */
-	regval = gpmc_read_reg(GPMC_IRQSTATUS);
-	gpmc_write_reg(GPMC_IRQSTATUS, regval);
-
-	return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL);
-}
-
-static int gpmc_free_irq(void)
-{
-	int i;
-
-	if (gpmc_irq)
-		free_irq(gpmc_irq, NULL);
-
-	for (i = 0; i < GPMC_NR_IRQ; i++) {
-		irq_set_handler(gpmc_client_irq[i].irq, NULL);
-		irq_set_chip(gpmc_client_irq[i].irq, &no_irq_chip);
-	}
-
-	irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ);
-
-	return 0;
+	return gpmc_irq;
 }
 
 static void gpmc_mem_exit(void)
@@ -2182,9 +2048,6 @@ static int gpmc_probe(struct platform_device *pdev)
 
 	gpmc_mem_init();
 
-	if (gpmc_setup_irq() < 0)
-		dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
-
 	if (!pdev->dev.of_node) {
 		gpmc_cs_num	 = GPMC_CS_NUM;
 		gpmc_nr_waitpins = GPMC_NR_WAITPINS;
@@ -2202,7 +2065,6 @@ static int gpmc_probe(struct platform_device *pdev)
 
 static int gpmc_remove(struct platform_device *pdev)
 {
-	gpmc_free_irq();
 	gpmc_mem_exit();
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
@@ -2252,25 +2114,6 @@ static __exit void gpmc_exit(void)
 postcore_initcall(gpmc_init);
 module_exit(gpmc_exit);
 
-static irqreturn_t gpmc_handle_irq(int irq, void *dev)
-{
-	int i;
-	u32 regval;
-
-	regval = gpmc_read_reg(GPMC_IRQSTATUS);
-
-	if (!regval)
-		return IRQ_NONE;
-
-	for (i = 0; i < GPMC_NR_IRQ; i++)
-		if (regval & gpmc_client_irq[i].bitmask)
-			generic_handle_irq(gpmc_client_irq[i].irq);
-
-	gpmc_write_reg(GPMC_IRQSTATUS, regval);
-
-	return IRQ_HANDLED;
-}
-
 static struct omap3_gpmc_regs gpmc_context;
 
 void omap3_gpmc_save_context(void)
diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index 7de9f9b..58f6bd2 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -11,9 +11,6 @@
 
 #define GPMC_CONFIG_WP		0x00000005
 
-#define GPMC_IRQ_FIFOEVENTENABLE	0x01
-#define GPMC_IRQ_COUNT_EVENT		0x02
-
 enum gpmc_nand_irq {
 	GPMC_NAND_IRQ_FIFOEVENT = 0,
 	GPMC_NAND_IRQ_TERMCOUNT,
@@ -53,11 +50,17 @@ static inline gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
 /* deprecated APIs */
 #if IS_ENABLED(CONFIG_OMAP_GPMC)
 void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+int gpmc_get_irq(void);
 #else
 static inline void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 {
 	reg = NULL;
 }
+
+static inline int gpmc_get_irq(void)
+{
+	return -ENOTSUPP;
+}
 #endif /* CONFIG_OMAP_GPMC */
 /*--------------------------------*/
 
@@ -67,8 +70,6 @@ extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
 
 struct device_node;
 
-extern int gpmc_get_client_irq(unsigned irq_config);
-
 extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
 
 extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
-- 
2.1.4


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

* [PATCH v3 08/27] memory: omap-gpmc: Add IRQ ops for GPMC-NAND interface
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (6 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 07/27] memory: omap-gpmc: Remove NAND IRQ code Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 09/27] mtd: nand: omap2: manage NAND interrupts Roger Quadros
                   ` (22 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Provide functions to enable/disable NAND IRQs, get
NAND event status and clear NAND events.

The NAND events of interest are TERMCOUNT and FIFOEVENT.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/memory/omap-gpmc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/omap-gpmc.h  |  4 ++++
 2 files changed, 54 insertions(+)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index a9071bb..e75226d 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -1078,8 +1078,58 @@ static bool gpmc_nand_writebuffer_empty(void)
 	return false;
 }
 
+static int gpmc_nand_irq_enable(enum gpmc_nand_irq irq)
+{
+	u32 reg;
+
+	if (irq > GPMC_NAND_IRQ_TERMCOUNT)
+		return -EINVAL;
+
+	reg = gpmc_read_reg(GPMC_IRQENABLE);
+	reg |= BIT(irq);
+	gpmc_write_reg(GPMC_IRQENABLE, reg);
+
+	return 0;
+}
+
+static int gpmc_nand_irq_disable(enum gpmc_nand_irq irq)
+{
+	u32 reg;
+
+	if (irq > GPMC_NAND_IRQ_TERMCOUNT)
+		return -EINVAL;
+
+	reg = gpmc_read_reg(GPMC_IRQENABLE);
+	reg &= ~BIT(irq);
+	gpmc_write_reg(GPMC_IRQENABLE, reg);
+
+	return 0;
+}
+
+static void gpmc_nand_irq_clear(enum gpmc_nand_irq irq)
+{
+	if (irq > GPMC_NAND_IRQ_TERMCOUNT)
+		return;
+
+	/* setting bit to 1 clears the bit in IRQSTATUS */
+	gpmc_write_reg(GPMC_IRQSTATUS, BIT(irq));
+}
+
+static u32 gpmc_nand_irq_status(void)
+{
+	u32 reg = gpmc_read_reg(GPMC_IRQSTATUS);
+
+	/* Mask out non-NAND bits */
+	reg &= GPMC_IRQENABLE_FIFOEVENT | GPMC_IRQENABLE_TERMCOUNT;
+	return reg;
+}
+
 static struct gpmc_nand_ops nand_ops = {
 	.nand_writebuffer_empty = gpmc_nand_writebuffer_empty,
+	.nand_irq_enable = gpmc_nand_irq_enable,
+	.nand_irq_disable = gpmc_nand_irq_disable,
+	.nand_irq_clear = gpmc_nand_irq_clear,
+	.nand_irq_status = gpmc_nand_irq_status,
 };
 
 /**
diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index 58f6bd2..b76cec3 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -11,6 +11,10 @@
 
 #define GPMC_CONFIG_WP		0x00000005
 
+/* GPMC IRQENABLE/IRQSTATUS BIT defs */
+#define GPMC_IRQENABLE_FIFOEVENT	BIT(0)
+#define GPMC_IRQENABLE_TERMCOUNT	BIT(1)
+
 enum gpmc_nand_irq {
 	GPMC_NAND_IRQ_FIFOEVENT = 0,
 	GPMC_NAND_IRQ_TERMCOUNT,
-- 
2.1.4


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

* [PATCH v3 09/27] mtd: nand: omap2: manage NAND interrupts
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (7 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 08/27] memory: omap-gpmc: Add IRQ ops for GPMC-NAND interface Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 10/27] mtd: nand: omap: Copy platform data parameters to omap_nand_info data Roger Quadros
                   ` (21 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Manage NAND interrupts here using the GPMC IRQ ops.

This causes performance in prefetch-irq mode to be increased

from
[   38.252811] mtd_speedtest: eraseblock write speed is 5576 KiB/s
[   39.265259] mtd_speedtest: eraseblock read speed is 8192 KiB/s

to
[   35.666446] mtd_speedtest: eraseblock write speed is 6537 KiB/s
[   36.444842] mtd_speedtest: eraseblock read speed is 10680 KiB/s

Test results on dra7-evm using mtd_speedtest.ko

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/mtd/nand/omap2.c | 65 +++++++++++++++++++++++-------------------------
 1 file changed, 31 insertions(+), 34 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 0eb0b8c..267bcdd 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -162,8 +162,7 @@ struct omap_nand_info {
 	enum omap_ecc			ecc_opt;
 	struct completion		comp;
 	struct dma_chan			*dma;
-	int				gpmc_irq_fifo;
-	int				gpmc_irq_count;
+	int				gpmc_irq;
 	enum {
 		OMAP_NAND_IO_READ = 0,	/* read */
 		OMAP_NAND_IO_WRITE,	/* write */
@@ -579,12 +578,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
 {
 	struct omap_nand_info *info = (struct omap_nand_info *) dev;
 	u32 bytes;
+	u32 irqstatus;
+
+	irqstatus = info->ops->nand_irq_status();
+	if (!irqstatus)
+		return IRQ_NONE;
 
 	bytes = readl(info->reg.gpmc_prefetch_status);
 	bytes = PREFETCH_STATUS_FIFO_CNT(bytes);
 	bytes = bytes  & 0xFFFC; /* io in multiple of 4 bytes */
 	if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
-		if (this_irq == info->gpmc_irq_count)
+		if (irqstatus & GPMC_IRQENABLE_TERMCOUNT)
 			goto done;
 
 		if (info->buf_len && (info->buf_len < bytes))
@@ -601,17 +605,25 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
 						(u32 *)info->buf, bytes >> 2);
 		info->buf = info->buf + bytes;
 
-		if (this_irq == info->gpmc_irq_count)
+		if (irqstatus & GPMC_IRQENABLE_TERMCOUNT)
 			goto done;
 	}
 
+	/* Clear FIFOEVENT STATUS */
+	info->ops->nand_irq_clear(GPMC_NAND_IRQ_FIFOEVENT);
+
 	return IRQ_HANDLED;
 
 done:
 	complete(&info->comp);
 
-	disable_irq_nosync(info->gpmc_irq_fifo);
-	disable_irq_nosync(info->gpmc_irq_count);
+	/* Clear FIFOEVENT and TERMCOUNT STATUS */
+	info->ops->nand_irq_clear(GPMC_NAND_IRQ_FIFOEVENT);
+	info->ops->nand_irq_clear(GPMC_NAND_IRQ_TERMCOUNT);
+
+	/* Disable Interrupt generation */
+	info->ops->nand_irq_disable(GPMC_NAND_IRQ_FIFOEVENT);
+	info->ops->nand_irq_disable(GPMC_NAND_IRQ_TERMCOUNT);
 
 	return IRQ_HANDLED;
 }
@@ -646,8 +658,9 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
 
 	info->buf_len = len;
 
-	enable_irq(info->gpmc_irq_count);
-	enable_irq(info->gpmc_irq_fifo);
+	/* Enable Interrupt generation */
+	info->ops->nand_irq_enable(GPMC_NAND_IRQ_TERMCOUNT);
+	info->ops->nand_irq_enable(GPMC_NAND_IRQ_FIFOEVENT);
 
 	/* waiting for read to complete */
 	wait_for_completion(&info->comp);
@@ -696,8 +709,9 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
 
 	info->buf_len = len;
 
-	enable_irq(info->gpmc_irq_count);
-	enable_irq(info->gpmc_irq_fifo);
+	/* Enable Interrupt generation */
+	info->ops->nand_irq_enable(GPMC_NAND_IRQ_TERMCOUNT);
+	info->ops->nand_irq_enable(GPMC_NAND_IRQ_FIFOEVENT);
 
 	/* waiting for write to complete */
 	wait_for_completion(&info->comp);
@@ -1776,35 +1790,18 @@ static int omap_nand_probe(struct platform_device *pdev)
 		break;
 
 	case NAND_OMAP_PREFETCH_IRQ:
-		info->gpmc_irq_fifo = platform_get_irq(pdev, 0);
-		if (info->gpmc_irq_fifo <= 0) {
-			dev_err(&pdev->dev, "error getting fifo irq\n");
-			err = -ENODEV;
-			goto return_error;
-		}
-		err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo,
-					omap_nand_irq, IRQF_SHARED,
-					"gpmc-nand-fifo", info);
-		if (err) {
-			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
-						info->gpmc_irq_fifo, err);
-			info->gpmc_irq_fifo = 0;
-			goto return_error;
-		}
-
-		info->gpmc_irq_count = platform_get_irq(pdev, 1);
-		if (info->gpmc_irq_count <= 0) {
-			dev_err(&pdev->dev, "error getting count irq\n");
+		info->gpmc_irq = platform_get_irq(pdev, 0);
+		if (info->gpmc_irq <= 0) {
+			dev_err(&pdev->dev, "error getting GPMC irq\n");
 			err = -ENODEV;
 			goto return_error;
 		}
-		err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
-					omap_nand_irq, IRQF_SHARED,
-					"gpmc-nand-count", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq,
+				       omap_nand_irq, IRQF_SHARED,
+				       DRIVER_NAME, info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
-						info->gpmc_irq_count, err);
-			info->gpmc_irq_count = 0;
+						info->gpmc_irq, err);
 			goto return_error;
 		}
 
-- 
2.1.4


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

* [PATCH v3 10/27] mtd: nand: omap: Copy platform data parameters to omap_nand_info data
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (8 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 09/27] mtd: nand: omap2: manage NAND interrupts Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 11/27] mtd: nand: omap: Clean up device tree support Roger Quadros
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Copy all the platform data parameters to the driver's local data
structure 'omap_nand_info' and use it in the entire driver. This will
make it easer for device tree migration.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/mtd/nand/omap2.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 267bcdd..c35405c 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -152,14 +152,18 @@ static struct nand_hw_control omap_gpmc_controller = {
 };
 
 struct omap_nand_info {
-	struct omap_nand_platform_data	*pdata;
 	struct mtd_info			mtd;
 	struct nand_chip		nand;
 	struct platform_device		*pdev;
 
 	int				gpmc_cs;
-	unsigned long			phys_base;
+	bool				dev_ready;
+	enum nand_io			xfer_type;
+	int				devsize;
 	enum omap_ecc			ecc_opt;
+	struct device_node		*elm_of_node;
+
+	unsigned long			phys_base;
 	struct completion		comp;
 	struct dma_chan			*dma;
 	int				gpmc_irq;
@@ -1656,7 +1660,7 @@ static bool omap2_nand_ecc_check(struct omap_nand_info *info,
 			"CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
 		return false;
 	}
-	if (ecc_needs_elm && !is_elm_present(info, pdata->elm_of_node)) {
+	if (ecc_needs_elm && !is_elm_present(info, info->elm_of_node)) {
 		dev_err(&info->pdev->dev, "ELM not available\n");
 		return false;
 	}
@@ -1701,6 +1705,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->gpmc_cs		= pdata->cs;
 	info->of_node		= pdata->of_node;
 	info->ecc_opt		= pdata->ecc_opt;
+	info->dev_ready	= pdata->dev_ready;
+	info->xfer_type = pdata->xfer_type;
+	info->devsize = pdata->devsize;
+	info->elm_of_node = pdata->elm_of_node;
+
 	mtd			= &info->mtd;
 	mtd->priv		= &info->nand;
 	mtd->name		= dev_name(&pdev->dev);
@@ -1727,7 +1736,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * chip delay which is slightly more than tR (AC Timing) of the NAND
 	 * device and read status register until you get a failure or success
 	 */
-	if (pdata->dev_ready) {
+	if (info->dev_ready) {
 		nand_chip->dev_ready = omap_dev_ready;
 		nand_chip->chip_delay = 0;
 	} else {
@@ -1741,15 +1750,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->options |= NAND_SKIP_BBTSCAN;
 
 	/* scan NAND device connected to chip controller */
-	nand_chip->options |= pdata->devsize & NAND_BUSWIDTH_16;
+	nand_chip->options |= info->devsize & NAND_BUSWIDTH_16;
 	if (nand_scan_ident(mtd, 1, NULL)) {
-		dev_err(&info->pdev->dev, "scan failed, may be bus-width mismatch\n");
+		dev_err(&info->pdev->dev,
+			"scan failed, may be bus-width mismatch\n");
 		err = -ENXIO;
 		goto return_error;
 	}
 
 	/* re-populate low-level callbacks based on xfer modes */
-	switch (pdata->xfer_type) {
+	switch (info->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		nand_chip->read_buf   = omap_read_buf_pref;
 		nand_chip->write_buf  = omap_write_buf_pref;
@@ -1812,7 +1822,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	default:
 		dev_err(&pdev->dev,
-			"xfer_type(%d) not supported!\n", pdata->xfer_type);
+			"xfer_type(%d) not supported!\n", info->xfer_type);
 		err = -EINVAL;
 		goto return_error;
 	}
-- 
2.1.4


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

* [PATCH v3 11/27] mtd: nand: omap: Clean up device tree support
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (9 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 10/27] mtd: nand: omap: Copy platform data parameters to omap_nand_info data Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-10-06 10:35   ` [PATCH v4 " Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 12/27] mtd: nand: omap: Update DT binding documentation Roger Quadros
                   ` (19 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Move NAND specific device tree parsing to NAND driver.

The NAND controller node must have a compatible id, register space
resource and interrupt resource.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/mach-omap2/gpmc-nand.c              |   5 +-
 drivers/memory/omap-gpmc.c                   | 135 ++++++--------------------
 drivers/mtd/nand/omap2.c                     | 136 +++++++++++++++++++++++----
 include/linux/platform_data/mtd-nand-omap2.h |   3 +-
 4 files changed, 147 insertions(+), 132 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index ffe646a..e07ca27 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -95,10 +95,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 	gpmc_nand_res[1].start = gpmc_get_irq();
 
 	memset(&s, 0, sizeof(struct gpmc_settings));
-	if (gpmc_nand_data->of_node)
-		gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
-	else
-		gpmc_set_legacy(gpmc_nand_data, &s);
+	gpmc_set_legacy(gpmc_nand_data, &s);
 
 	s.device_nand = true;
 
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index e75226d..b09e1bc 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -29,7 +29,6 @@
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 #include <linux/omap-gpmc.h>
-#include <linux/mtd/nand.h>
 #include <linux/pm_runtime.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
@@ -1716,105 +1715,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 		of_property_read_bool(np, "gpmc,time-para-granularity");
 }
 
-#if IS_ENABLED(CONFIG_MTD_NAND)
-
-static const char * const nand_xfer_types[] = {
-	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
-	[NAND_OMAP_POLLED]			= "polled",
-	[NAND_OMAP_PREFETCH_DMA]		= "prefetch-dma",
-	[NAND_OMAP_PREFETCH_IRQ]		= "prefetch-irq",
-};
-
-static int gpmc_probe_nand_child(struct platform_device *pdev,
-				 struct device_node *child)
-{
-	u32 val;
-	const char *s;
-	struct gpmc_timings gpmc_t;
-	struct omap_nand_platform_data *gpmc_nand_data;
-
-	if (of_property_read_u32(child, "reg", &val) < 0) {
-		dev_err(&pdev->dev, "%s has no 'reg' property\n",
-			child->full_name);
-		return -ENODEV;
-	}
-
-	gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data),
-				      GFP_KERNEL);
-	if (!gpmc_nand_data)
-		return -ENOMEM;
-
-	gpmc_nand_data->cs = val;
-	gpmc_nand_data->of_node = child;
-
-	/* Detect availability of ELM module */
-	gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
-	if (gpmc_nand_data->elm_of_node == NULL)
-		gpmc_nand_data->elm_of_node =
-					of_parse_phandle(child, "elm_id", 0);
-
-	/* select ecc-scheme for NAND */
-	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
-		pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
-		return -ENODEV;
-	}
-
-	if (!strcmp(s, "sw"))
-		gpmc_nand_data->ecc_opt = OMAP_ECC_HAM1_CODE_SW;
-	else if (!strcmp(s, "ham1") ||
-		 !strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
-		gpmc_nand_data->ecc_opt =
-				OMAP_ECC_HAM1_CODE_HW;
-	else if (!strcmp(s, "bch4"))
-		if (gpmc_nand_data->elm_of_node)
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH4_CODE_HW;
-		else
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
-	else if (!strcmp(s, "bch8"))
-		if (gpmc_nand_data->elm_of_node)
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH8_CODE_HW;
-		else
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
-	else if (!strcmp(s, "bch16"))
-		if (gpmc_nand_data->elm_of_node)
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH16_CODE_HW;
-		else
-			pr_err("%s: BCH16 requires ELM support\n", __func__);
-	else
-		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
-
-	/* select data transfer mode for NAND controller */
-	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
-		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
-			if (!strcasecmp(s, nand_xfer_types[val])) {
-				gpmc_nand_data->xfer_type = val;
-				break;
-			}
-
-	gpmc_nand_data->flash_bbt = of_get_nand_on_flash_bbt(child);
-
-	val = of_get_nand_bus_width(child);
-	if (val == 16)
-		gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
-
-	gpmc_read_timings_dt(child, &gpmc_t);
-	gpmc_nand_init(gpmc_nand_data, &gpmc_t);
-
-	return 0;
-}
-#else
-static int gpmc_probe_nand_child(struct platform_device *pdev,
-				 struct device_node *child)
-{
-	return 0;
-}
-#endif
-
 #if IS_ENABLED(CONFIG_MTD_ONENAND)
 static int gpmc_probe_onenand_child(struct platform_device *pdev,
 				 struct device_node *child)
@@ -1933,9 +1833,34 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		goto err;
 	}
 
-	ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
-	if (ret < 0)
-		goto err;
+	if (of_node_cmp(child->name, "nand") == 0) {
+		/* NAND specific setup */
+		u32 val;
+
+		val = of_get_nand_bus_width(child);
+		switch (val) {
+		case 8:
+			gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
+			break;
+		case 16:
+			gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
+			break;
+		default:
+			dev_err(&pdev->dev, "%s: invalid 'nand-bus-width'\n",
+				child->name);
+			ret = -EINVAL;
+			goto err;
+		}
+
+		/* disable write protect */
+		gpmc_configure(GPMC_CONFIG_WP, 0);
+		gpmc_s.device_nand = true;
+	} else {
+		ret = of_property_read_u32(child, "bank-width",
+					   &gpmc_s.device_width);
+		if (ret < 0)
+			goto err;
+	}
 
 	ret = gpmc_cs_program_settings(cs, &gpmc_s);
 	if (ret < 0)
@@ -2018,9 +1943,7 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 		if (!child->name)
 			continue;
 
-		if (of_node_cmp(child->name, "nand") == 0)
-			ret = gpmc_probe_nand_child(pdev, child);
-		else if (of_node_cmp(child->name, "onenand") == 0)
+		if (of_node_cmp(child->name, "onenand") == 0)
 			ret = gpmc_probe_onenand_child(pdev, child);
 		else
 			ret = gpmc_probe_generic_child(pdev, child);
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index c35405c..228f498 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_mtd.h>
 
 #include <linux/mtd/nand_bch.h>
 #include <linux/platform_data/elm.h>
@@ -177,6 +178,8 @@ struct omap_nand_info {
 	struct gpmc_nand_regs		reg;
 	struct gpmc_nand_ops		*ops;
 	/* generated at runtime depending on ECC algorithm and layout selected */
+	bool				flash_bbt;
+	/* generated at runtime depending on ECC algorithm and layout */
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct device			*elm_dev;
@@ -1668,10 +1671,84 @@ static bool omap2_nand_ecc_check(struct omap_nand_info *info,
 	return true;
 }
 
+static const char * const nand_xfer_types[] = {
+	[NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled",
+	[NAND_OMAP_POLLED] = "polled",
+	[NAND_OMAP_PREFETCH_DMA] = "prefetch-dma",
+	[NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq",
+};
+
+static int omap_get_dt_info(struct device *dev, struct omap_nand_info *info)
+{
+	struct device_node *child = dev->of_node;
+	int i;
+	const char *s;
+
+	/* In old bindings, CS num is embedded in reg property */
+	if (of_property_read_u32(child, "reg", &info->gpmc_cs) < 0) {
+		dev_err(dev, "reg not found in DT\n");
+		return -EINVAL;
+	}
+
+	/* detect availability of ELM module. Won't be present pre-OMAP4 */
+	info->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
+	if (!info->elm_of_node)
+		dev_dbg(dev, "ti,elm-id not in DT\n");
+
+	/* select ecc-scheme for NAND */
+	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
+		dev_err(dev, "ti,nand-ecc-opt not found\n");
+		return -EINVAL;
+	}
+
+	if (!strcmp(s, "sw")) {
+		info->ecc_opt = OMAP_ECC_HAM1_CODE_SW;
+	} else if (!strcmp(s, "ham1") ||
+		   !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) {
+		info->ecc_opt =	OMAP_ECC_HAM1_CODE_HW;
+	} else if (!strcmp(s, "bch4")) {
+		if (info->elm_of_node)
+			info->ecc_opt = OMAP_ECC_BCH4_CODE_HW;
+		else
+			info->ecc_opt = OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
+	} else if (!strcmp(s, "bch8")) {
+		if (info->elm_of_node)
+			info->ecc_opt = OMAP_ECC_BCH8_CODE_HW;
+		else
+			info->ecc_opt = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+	} else if (!strcmp(s, "bch16")) {
+		info->ecc_opt =	OMAP_ECC_BCH16_CODE_HW;
+	} else {
+		dev_err(dev, "unrecognized value for ti,nand-ecc-opt\n");
+		return -EINVAL;
+	}
+
+	/* select data transfer mode */
+	if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) {
+		for (i = 0; i < ARRAY_SIZE(nand_xfer_types); i++) {
+			if (!strcasecmp(s, nand_xfer_types[i])) {
+				info->xfer_type = i;
+				goto next;
+			}
+		}
+
+		dev_err(dev, "unrecognized value for ti,nand-xfer-type\n");
+		return -EINVAL;
+	}
+
+next:
+	of_get_nand_on_flash_bbt(child);
+
+	if (of_get_nand_bus_width(child) == 16)
+		info->devsize = NAND_BUSWIDTH_16;
+
+	return 0;
+}
+
 static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
-	struct omap_nand_platform_data	*pdata;
+	struct omap_nand_platform_data	*pdata = NULL;
 	struct mtd_info			*mtd;
 	struct nand_chip		*nand_chip;
 	struct nand_ecclayout		*ecclayout;
@@ -1682,33 +1759,42 @@ static int omap_nand_probe(struct platform_device *pdev)
 	unsigned			oob_index;
 	struct resource			*res;
 	struct mtd_part_parser_data	ppdata = {};
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "platform data missing\n");
-		return -ENODEV;
-	}
+	struct device			*dev = &pdev->dev;
 
 	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
 				GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, info);
+	info->pdev = pdev;
 
+	if (dev->of_node) {
+		if (omap_get_dt_info(dev, info))
+			return -EINVAL;
+	} else {
+		pdata = dev_get_platdata(&pdev->dev);
+		if (!pdata) {
+			dev_err(&pdev->dev, "platform data missing\n");
+			return -EINVAL;
+		}
+
+		info->gpmc_cs = pdata->cs;
+		info->reg = pdata->reg;
+		info->of_node = pdata->of_node;
+		info->ecc_opt = pdata->ecc_opt;
+		info->dev_ready	= pdata->dev_ready;
+		info->xfer_type = pdata->xfer_type;
+		info->devsize = pdata->devsize;
+		info->elm_of_node = pdata->elm_of_node;
+		info->flash_bbt = pdata->flash_bbt;
+	}
+
+	platform_set_drvdata(pdev, info);
 	info->ops = gpmc_omap_get_nand_ops(&info->reg, info->gpmc_cs);
 	if (!info->ops) {
 		dev_err(&pdev->dev, "Failed to get GPMC->NAND interface\n");
 		return -ENODEV;
 	}
-	info->pdev		= pdev;
-	info->gpmc_cs		= pdata->cs;
-	info->of_node		= pdata->of_node;
-	info->ecc_opt		= pdata->ecc_opt;
-	info->dev_ready	= pdata->dev_ready;
-	info->xfer_type = pdata->xfer_type;
-	info->devsize = pdata->devsize;
-	info->elm_of_node = pdata->elm_of_node;
 
 	mtd			= &info->mtd;
 	mtd->priv		= &info->nand;
@@ -1744,7 +1830,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->chip_delay = 50;
 	}
 
-	if (pdata->flash_bbt)
+	if (info->flash_bbt)
 		nand_chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
 	else
 		nand_chip->options |= NAND_SKIP_BBTSCAN;
@@ -2049,9 +2135,13 @@ scan_tail:
 		goto return_error;
 	}
 
-	ppdata.of_node = pdata->of_node;
-	mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts,
-				  pdata->nr_parts);
+	if (dev->of_node) {
+		ppdata.of_node = dev->of_node;
+		mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+
+	} else {
+		mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
+	}
 
 	platform_set_drvdata(pdev, mtd);
 
@@ -2083,11 +2173,17 @@ static int omap_nand_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id omap_nand_ids[] = {
+	{ .compatible = "ti,omap2-nand", },
+	{},
+};
+
 static struct platform_driver omap_nand_driver = {
 	.probe		= omap_nand_probe,
 	.remove		= omap_nand_remove,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.of_match_table = of_match_ptr(omap_nand_ids),
 	},
 };
 
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index a067f58..ff27e5a 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -76,11 +76,10 @@ struct omap_nand_platform_data {
 	int			devsize;
 	enum omap_ecc           ecc_opt;
 
-	/* for passing the partitions */
-	struct device_node	*of_node;
 	struct device_node	*elm_of_node;
 
 	/* deprecated */
 	struct gpmc_nand_regs	reg;
+	struct device_node	*of_node;
 };
 #endif
-- 
2.1.4


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

* [PATCH v3 12/27] mtd: nand: omap: Update DT binding documentation
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (10 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 11/27] mtd: nand: omap: Clean up device tree support Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 13/27] memory: omap-gpmc: Prevent mapping into 1st 16MB Roger Quadros
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Add compatible id and interrupts. The NAND interrupts are
provided by the GPMC controller node.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index fb733c4..253e6de 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -13,7 +13,11 @@ Documentation/devicetree/bindings/mtd/nand.txt
 
 Required properties:
 
- - reg:		The CS line the peripheral is connected to
+ - compatible:	"ti,omap2-nand"
+ - reg:		range id (CS number), base offset and length of the
+		NAND I/O space
+ - interrupt-parent: must point to gpmc node
+ - interrupts: gpmc interrupt
 
 Optional properties:
 
@@ -55,20 +59,24 @@ Example for an AM33xx board:
 	gpmc: gpmc@50000000 {
 		compatible = "ti,am3352-gpmc";
 		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x1000000>;
+		reg = <0x50000000 0x36c>;
 		interrupts = <100>;
 		gpmc,num-cs = <8>;
 		gpmc,num-waitpins = <2>;
 		#address-cells = <2>;
 		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x2000>;	/* CS0: NAND */
+		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
 		elm_id = <&elm>;
 
 		nand@0,0 {
-			reg = <0 0 0>; /* CS0, offset 0 */
+			compatible = "ti,omap2-nand";
+			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
+			interrupts = <100>;
 			nand-bus-width = <16>;
 			ti,nand-ecc-opt = "bch8";
 			ti,nand-xfer-type = "polled";
+			interrupt-parent = <&gpmc>;
+			interrupts = <0>, <1>;
 
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
-- 
2.1.4


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

* [PATCH v3 13/27] memory: omap-gpmc: Prevent mapping into 1st 16MB
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (11 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 12/27] mtd: nand: omap: Update DT binding documentation Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 14/27] memory: omap-gpmc: Move device tree binding to correct location Roger Quadros
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

We have been preventing mapping GPMC children in the
first 1MB but really it has to be the first 16MB as
the minimum GPMC partition size is 16MB.

Also print an error message if CS mapping fails
due to DT requesting address outside the GPMC
map.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/memory/omap-gpmc.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index b09e1bc..bcf4b05 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -93,6 +93,14 @@
 #define GPMC_CS_SIZE		0x30
 #define	GPMC_BCH_SIZE		0x10
 
+/*
+ * The first 1MB of GPMC address space is typically mapped to
+ * the internal ROM. Never allocate the first page, to
+ * facilitate bug detection; even if we didn't boot from ROM.
+ * As GPMC minimum partition size is 16MB we can only start from
+ * there.
+ */
+#define GPMC_MEM_START		0x1000000
 #define GPMC_MEM_END		0x3FFFFFFF
 
 #define GPMC_CHUNK_SHIFT	24		/* 16 MB */
@@ -1171,12 +1179,7 @@ static void gpmc_mem_init(void)
 {
 	int cs;
 
-	/*
-	 * The first 1MB of GPMC address space is typically mapped to
-	 * the internal ROM. Never allocate the first page, to
-	 * facilitate bug detection; even if we didn't boot from ROM.
-	 */
-	gpmc_mem_root.start = SZ_1M;
+	gpmc_mem_root.start = GPMC_MEM_START;
 	gpmc_mem_root.end = GPMC_MEM_END;
 
 	/* Reserve all regions that has been set up by bootloader */
@@ -1830,6 +1833,15 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	if (ret < 0) {
 		dev_err(&pdev->dev, "cannot remap GPMC CS %d to %pa\n",
 			cs, &res.start);
+		if (res.start < GPMC_MEM_START) {
+			dev_info(&pdev->dev,
+				 "GPMC CS %d start cannot be lesser than 0x%x\n",
+				 cs, GPMC_MEM_START);
+		} else if (res.end > GPMC_MEM_END) {
+			dev_info(&pdev->dev,
+				 "GPMC CS %d end cannot be greater than 0x%x\n",
+				 cs, GPMC_MEM_END);
+		}
 		goto err;
 	}
 
-- 
2.1.4


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

* [PATCH v3 14/27] memory: omap-gpmc: Move device tree binding to correct location
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (12 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 13/27] memory: omap-gpmc: Prevent mapping into 1st 16MB Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 15/27] memory: omap-gpmc: Support general purpose input for WAITPINs Roger Quadros
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

omap-gpmc.c is a memory controller so move the binding to the
right place.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 .../bindings/{bus/ti-gpmc.txt => memory-controllers/omap-gpmc.txt}        | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/devicetree/bindings/{bus/ti-gpmc.txt => memory-controllers/omap-gpmc.txt} (100%)

diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
similarity index 100%
rename from Documentation/devicetree/bindings/bus/ti-gpmc.txt
rename to Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-- 
2.1.4


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

* [PATCH v3 15/27] memory: omap-gpmc: Support general purpose input for WAITPINs
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (13 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 14/27] memory: omap-gpmc: Move device tree binding to correct location Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 16/27] memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring Roger Quadros
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

OMAPs can have 2 to 4 WAITPINs that can be used as general purpose
input if not used for memory wait state insertion.

The first user will be the OMAP NAND chip to get the NAND
read/busy status using gpiolib.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/memory/omap-gpmc.c | 130 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 120 insertions(+), 10 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index bcf4b05..518b418 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -21,6 +21,7 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
@@ -223,6 +224,11 @@ struct omap3_gpmc_regs {
 	struct gpmc_cs_config cs_context[GPMC_CS_NUM];
 };
 
+struct gpmc_device {
+	struct device *dev;
+	struct gpio_chip gpio_chip;
+};
+
 static struct resource	gpmc_mem_root;
 static struct gpmc_cs_data gpmc_cs[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
@@ -1919,10 +1925,69 @@ err:
 	return ret;
 }
 
+static int gpmc_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+	return 1;	/* we're input only */
+}
+
+static int gpmc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return 0;	/* we're input only */
+}
+
+static int gpmc_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+				      int value)
+{
+	return -EINVAL;	/* we're input only */
+}
+
+static void gpmc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+}
+
+static int gpmc_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	u32 reg;
+
+	offset += 8;
+
+	reg = gpmc_read_reg(GPMC_STATUS) & BIT(offset);
+
+	return !!reg;
+}
+
+static int gpmc_gpio_init(struct gpmc_device *gpmc)
+{
+	int ret;
+
+	gpmc->gpio_chip.dev = gpmc->dev;
+	gpmc->gpio_chip.owner = THIS_MODULE;
+	gpmc->gpio_chip.label = DEVICE_NAME;
+	gpmc->gpio_chip.ngpio = gpmc_nr_waitpins;
+	gpmc->gpio_chip.get_direction = gpmc_gpio_get_direction;
+	gpmc->gpio_chip.direction_input = gpmc_gpio_direction_input;
+	gpmc->gpio_chip.direction_output = gpmc_gpio_direction_output;
+	gpmc->gpio_chip.set = gpmc_gpio_set;
+	gpmc->gpio_chip.get = gpmc_gpio_get;
+	gpmc->gpio_chip.base = -1;
+
+	ret = gpiochip_add(&gpmc->gpio_chip);
+	if (ret < 0) {
+		dev_err(gpmc->dev, "could not register gpio chip: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void gpmc_gpio_exit(struct gpmc_device *gpmc)
+{
+	gpiochip_remove(&gpmc->gpio_chip);
+}
+
 static int gpmc_probe_dt(struct platform_device *pdev)
 {
 	int ret;
-	struct device_node *child;
 	const struct of_device_id *of_id =
 		of_match_device(gpmc_dt_ids, &pdev->dev);
 
@@ -1950,6 +2015,14 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 		return ret;
 	}
 
+	return 0;
+}
+
+static int gpmc_probe_dt_children(struct platform_device *pdev)
+{
+	int ret;
+	struct device_node *child;
+
 	for_each_available_child_of_node(pdev->dev.of_node, child) {
 
 		if (!child->name)
@@ -1959,6 +2032,9 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 			ret = gpmc_probe_onenand_child(pdev, child);
 		else
 			ret = gpmc_probe_generic_child(pdev, child);
+
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -1968,6 +2044,11 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 {
 	return 0;
 }
+
+static int gpmc_probe_dt_children(struct platform_device *pdev)
+{
+	return 0;
+}
 #endif
 
 static int gpmc_probe(struct platform_device *pdev)
@@ -1975,6 +2056,7 @@ static int gpmc_probe(struct platform_device *pdev)
 	int rc;
 	u32 l;
 	struct resource *res;
+	struct gpmc_device *gpmc;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL)
@@ -2005,6 +2087,24 @@ static int gpmc_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+
+	if (pdev->dev.of_node) {
+		rc = gpmc_probe_dt(pdev);
+		if (rc)
+			return rc;
+	} else {
+		gpmc_cs_num = GPMC_CS_NUM;
+		gpmc_nr_waitpins = GPMC_NR_WAITPINS;
+	}
+
+
+	gpmc = devm_kzalloc(&pdev->dev, sizeof(*gpmc), GFP_KERNEL);
+	if (!gpmc)
+		return -ENOMEM;
+
+	gpmc->dev = &pdev->dev;
+	platform_set_drvdata(pdev, gpmc);
+
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 
@@ -2032,24 +2132,34 @@ static int gpmc_probe(struct platform_device *pdev)
 		 GPMC_REVISION_MINOR(l));
 
 	gpmc_mem_init();
+	rc = gpmc_gpio_init(gpmc);
+	if (rc)
+		goto gpio_init_failed;
 
-	if (!pdev->dev.of_node) {
-		gpmc_cs_num	 = GPMC_CS_NUM;
-		gpmc_nr_waitpins = GPMC_NR_WAITPINS;
-	}
-
-	rc = gpmc_probe_dt(pdev);
+	rc = gpmc_probe_dt_children(pdev);
 	if (rc < 0) {
-		pm_runtime_put_sync(&pdev->dev);
-		dev_err(gpmc_dev, "failed to probe DT parameters\n");
-		return rc;
+		dev_err(gpmc_dev, "failed to probe DT children\n");
+		goto dt_children_failed;
 	}
 
 	return 0;
+
+dt_children_failed:
+	gpmc_gpio_exit(gpmc);
+gpio_init_failed:
+	gpmc_mem_exit();
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	gpmc_dev = NULL;
+
+	return rc;
 }
 
 static int gpmc_remove(struct platform_device *pdev)
 {
+	struct gpmc_device *gpmc = platform_get_drvdata(pdev);
+
+	gpmc_gpio_exit(gpmc);
 	gpmc_mem_exit();
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-- 
2.1.4


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

* [PATCH v3 16/27] memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (14 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 15/27] memory: omap-gpmc: Support general purpose input for WAITPINs Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 17/27] memory: omap-gpmc: Add irqchip support to the gpiochip Roger Quadros
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

If the device attached to GPMC wants to use the WAIT pin
for WAIT monitoring then we reserve it internally for
exclusive use.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/memory/omap-gpmc.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 518b418..fdf19eeb 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -1779,6 +1779,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	const char *name;
 	int ret, cs;
 	u32 val;
+	struct gpio_desc *waitpin_desc = NULL;
+	struct gpmc_device *gpmc = platform_get_drvdata(pdev);
 
 	if (of_property_read_u32(child, "reg", &cs) < 0) {
 		dev_err(&pdev->dev, "%s has no 'reg' property\n",
@@ -1880,15 +1882,28 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 			goto err;
 	}
 
+	/* Reserve wait pin if it is required and valid */
+	if (gpmc_s.wait_on_read || gpmc_s.wait_on_write) {
+		unsigned wait_pin = gpmc_s.wait_pin;
+
+		waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip,
+							 wait_pin, "WAITPIN");
+		if (IS_ERR(waitpin_desc)) {
+			dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin);
+			ret = PTR_ERR(waitpin_desc);
+			goto err;
+		}
+	}
+
 	ret = gpmc_cs_program_settings(cs, &gpmc_s);
 	if (ret < 0)
-		goto err;
+		goto err_cs;
 
 	ret = gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to set gpmc timings for: %s\n",
 			child->name);
-		goto err;
+		goto err_cs;
 	}
 
 	/* Clear limited address i.e. enable A26-A11 */
@@ -1919,6 +1934,10 @@ err_child_fail:
 	dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
 	ret = -ENODEV;
 
+err_cs:
+	if (waitpin_desc)
+		gpiochip_free_own_desc(waitpin_desc);
+
 err:
 	gpmc_cs_free(cs);
 
-- 
2.1.4


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

* [PATCH v3 17/27] memory: omap-gpmc: Add irqchip support to the gpiochip
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (15 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 16/27] memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib Roger Quadros
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

The WAIT pins support either rising or falling edge interrupts
so add irqchip support to the gpiochip model.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/memory/omap-gpmc.c | 132 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index fdf19eeb..764e24a 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -13,6 +13,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
@@ -227,6 +228,7 @@ struct omap3_gpmc_regs {
 struct gpmc_device {
 	struct device *dev;
 	struct gpio_chip gpio_chip;
+	struct irq_chip	irq_chip;
 };
 
 static struct resource	gpmc_mem_root;
@@ -1944,6 +1946,99 @@ err:
 	return ret;
 }
 
+static int gpmc_irq_endis(unsigned long hwirq, bool endis)
+{
+	u32 regval;
+
+	/* WAITPIN starts at BIT 8 */
+	hwirq += 8;
+
+	regval = gpmc_read_reg(GPMC_IRQENABLE);
+	if (endis)
+		regval |= BIT(hwirq);
+	else
+		regval &= ~BIT(hwirq);
+	gpmc_write_reg(GPMC_IRQENABLE, regval);
+
+	return 0;
+}
+
+static void gpmc_irq_edge_config(unsigned long hwirq, bool rising_edge)
+{
+	u32 regval;
+
+	/* WAITPIN starts at BIT 8 */
+	hwirq += 8;
+
+	regval = gpmc_read_reg(GPMC_CONFIG);
+	if (rising_edge)
+		regval &= ~BIT(hwirq);
+	else
+		regval |= BIT(hwirq);
+
+	gpmc_write_reg(GPMC_CONFIG, regval);
+}
+
+static void gpmc_irq_mask(struct irq_data *d)
+{
+	gpmc_irq_endis(d->hwirq, false);
+}
+
+static void gpmc_irq_unmask(struct irq_data *d)
+{
+	gpmc_irq_endis(d->hwirq, true);
+}
+
+static void gpmc_irq_ack(struct irq_data *d)
+{
+	unsigned hwirq = d->hwirq + 8;
+
+	/* Setting bit to 1 clears (or Acks) the interrupt */
+	gpmc_write_reg(GPMC_IRQSTATUS, BIT(hwirq));
+}
+
+static int gpmc_irq_set_type(struct irq_data *d, unsigned trigger)
+{
+	/* We can support either rising or falling edge at a time */
+	if (trigger == IRQ_TYPE_EDGE_FALLING)
+		gpmc_irq_edge_config(d->hwirq, false);
+	else if (trigger == IRQ_TYPE_EDGE_RISING)
+		gpmc_irq_edge_config(d->hwirq, true);
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static irqreturn_t gpmc_handle_irq(int irq, void *data)
+{
+	int hwirq, virq;
+	u32 regval;
+	struct gpmc_device *gpmc = data;
+
+	regval = gpmc_read_reg(GPMC_IRQSTATUS);
+	regval >>= 8;	/* we're only interested in WAIT pins */
+
+	if (!regval)
+		return IRQ_NONE;
+
+	for (hwirq = 0; hwirq < gpmc->gpio_chip.ngpio; hwirq++) {
+		if (regval & BIT(hwirq)) {
+			virq = irq_find_mapping(gpmc->gpio_chip.irqdomain,
+						hwirq);
+			if (!virq) {
+				dev_warn(gpmc_dev,
+					 "spurious irq detected hwirq %d, virq %d\n",
+					 hwirq, virq);
+			}
+
+			generic_handle_irq(virq);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
 static int gpmc_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
 {
 	return 1;	/* we're input only */
@@ -1978,6 +2073,7 @@ static int gpmc_gpio_get(struct gpio_chip *chip, unsigned offset)
 static int gpmc_gpio_init(struct gpmc_device *gpmc)
 {
 	int ret;
+	u32 regval;
 
 	gpmc->gpio_chip.dev = gpmc->dev;
 	gpmc->gpio_chip.owner = THIS_MODULE;
@@ -1996,7 +2092,43 @@ static int gpmc_gpio_init(struct gpmc_device *gpmc)
 		return ret;
 	}
 
+	/* Disable interrupts */
+	gpmc_write_reg(GPMC_IRQENABLE, 0);
+
+	/* clear interrupts */
+	regval = gpmc_read_reg(GPMC_IRQSTATUS);
+	gpmc_write_reg(GPMC_IRQSTATUS, regval);
+
+	gpmc->irq_chip.name = DEVICE_NAME;
+	gpmc->irq_chip.irq_ack = gpmc_irq_ack;
+	gpmc->irq_chip.irq_mask = gpmc_irq_mask;
+	gpmc->irq_chip.irq_unmask = gpmc_irq_unmask;
+	gpmc->irq_chip.irq_set_type = gpmc_irq_set_type;
+
+	ret = gpiochip_irqchip_add(&gpmc->gpio_chip, &gpmc->irq_chip, 0,
+				   handle_edge_irq, IRQ_TYPE_NONE);
+
+	if (ret) {
+		dev_err(gpmc->dev, "could not add irqchip to gpiochip: %d\n",
+			ret);
+		goto fail;
+	}
+
+	/* We're sharing this IRQ with OMAP NAND driver */
+	ret = devm_request_irq(gpmc->dev, gpmc_irq, gpmc_handle_irq,
+			       IRQF_SHARED, DEVICE_NAME, gpmc);
+	if (ret) {
+		dev_err(gpmc->dev, "could not request gpmc irq (%d): %d\n",
+			gpmc_irq, ret);
+		goto fail;
+	}
+
 	return 0;
+
+fail:
+	gpiochip_remove(&gpmc->gpio_chip);
+
+	return ret;
 }
 
 static void gpmc_gpio_exit(struct gpmc_device *gpmc)
-- 
2.1.4


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

* [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (16 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 17/27] memory: omap-gpmc: Add irqchip support to the gpiochip Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-10-26 20:49   ` Brian Norris
  2015-09-18 14:53 ` [PATCH v3 19/27] memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via gpmc_regs Roger Quadros
                   ` (12 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

The GPMC WAIT pin status are now available over gpiolib.
Update the omap_dev_ready() function to use gpio instead of
directly accessing GPMC register space.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/mtd/nand/omap2.c                     | 29 +++++++++++++++++-----------
 include/linux/platform_data/mtd-nand-omap2.h |  2 +-
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 228f498..d0f2620 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -12,6 +12,7 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
@@ -184,6 +185,8 @@ struct omap_nand_info {
 	/* fields specific for BCHx_HW ECC scheme */
 	struct device			*elm_dev;
 	struct device_node		*of_node;
+	/* NAND ready gpio */
+	struct gpio_desc		*ready_gpiod;
 };
 
 /**
@@ -1047,22 +1050,17 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
 }
 
 /**
- * omap_dev_ready - calls the platform specific dev_ready function
+ * omap_dev_ready - checks the NAND Ready GPIO line
  * @mtd: MTD device structure
+ *
+ * Returns true if ready and false if busy.
  */
 static int omap_dev_ready(struct mtd_info *mtd)
 {
-	unsigned int val = 0;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
 
-	val = readl(info->reg.gpmc_status);
-
-	if ((val & 0x100) == 0x100) {
-		return 1;
-	} else {
-		return 0;
-	}
+	return gpiod_get_value(info->ready_gpiod);
 }
 
 /**
@@ -1782,7 +1780,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 		info->reg = pdata->reg;
 		info->of_node = pdata->of_node;
 		info->ecc_opt = pdata->ecc_opt;
-		info->dev_ready	= pdata->dev_ready;
+		if (pdata->dev_ready)
+			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
+
 		info->xfer_type = pdata->xfer_type;
 		info->devsize = pdata->devsize;
 		info->elm_of_node = pdata->elm_of_node;
@@ -1815,6 +1815,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
 	nand_chip->cmd_ctrl  = omap_hwcontrol;
 
+	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "ready",
+						    GPIOD_IN);
+	if (IS_ERR(info->ready_gpiod)) {
+		dev_err(dev, "failed to get ready gpio\n");
+		return PTR_ERR(info->ready_gpiod);
+	}
+
 	/*
 	 * If RDY/BSY line is connected to OMAP then use the omap ready
 	 * function and the generic nand_wait function which reads the status
@@ -1822,7 +1829,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * chip delay which is slightly more than tR (AC Timing) of the NAND
 	 * device and read status register until you get a failure or success
 	 */
-	if (info->dev_ready) {
+	if (info->ready_gpiod) {
 		nand_chip->dev_ready = omap_dev_ready;
 		nand_chip->chip_delay = 0;
 	} else {
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index ff27e5a..19e509d 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -70,7 +70,6 @@ struct omap_nand_platform_data {
 	int			cs;
 	struct mtd_partition	*parts;
 	int			nr_parts;
-	bool			dev_ready;
 	bool			flash_bbt;
 	enum nand_io		xfer_type;
 	int			devsize;
@@ -81,5 +80,6 @@ struct omap_nand_platform_data {
 	/* deprecated */
 	struct gpmc_nand_regs	reg;
 	struct device_node	*of_node;
+	bool			dev_ready;
 };
 #endif
-- 
2.1.4


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

* [PATCH v3 19/27] memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via gpmc_regs
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (17 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes Roger Quadros
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

GPMC_STATUS register is private to the GPMC module and must not be
accessed directly by NAND driver through the gpmc_regs.

They must use gpmc_omap_get_nand_ops() instead.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/memory/omap-gpmc.c                   | 2 +-
 include/linux/platform_data/mtd-nand-omap2.h | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 764e24a..4c630ad 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -1051,7 +1051,7 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 {
 	int i;
 
-	reg->gpmc_status = gpmc_base + GPMC_STATUS;
+	reg->gpmc_status = NULL;	/* deprecated */
 	reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET +
 				GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
 	reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET +
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 19e509d..17d57a1 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -45,7 +45,6 @@ enum omap_ecc {
 };
 
 struct gpmc_nand_regs {
-	void __iomem	*gpmc_status;
 	void __iomem	*gpmc_nand_command;
 	void __iomem	*gpmc_nand_address;
 	void __iomem	*gpmc_nand_data;
@@ -64,6 +63,8 @@ struct gpmc_nand_regs {
 	void __iomem	*gpmc_bch_result4[GPMC_BCH_NUM_REMAINDER];
 	void __iomem	*gpmc_bch_result5[GPMC_BCH_NUM_REMAINDER];
 	void __iomem	*gpmc_bch_result6[GPMC_BCH_NUM_REMAINDER];
+	/* Deprecated. Do not use */
+	void __iomem	*gpmc_status;
 };
 
 struct omap_nand_platform_data {
-- 
2.1.4


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

* [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes.
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (18 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 19/27] memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via gpmc_regs Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-10-14 13:34   ` Franklin S Cooper Jr.
  2015-09-18 14:53 ` [PATCH v3 21/27] ARM: dts: dra7x-evm: Provide NAND ready pin Roger Quadros
                   ` (10 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Add compatible id, GPMC register resource and interrupt
resource to NAND controller nodes.

The GPMC driver now implements gpiochip and irqchip so
enable gpio-controller and interrupt-controller properties.

With this the interrupt parent of NAND node changes so fix it
accordingly.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/dra7-evm.dts  | 5 ++++-
 arch/arm/boot/dts/dra7.dtsi     | 4 ++++
 arch/arm/boot/dts/dra72-evm.dts | 5 ++++-
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index a6c82e5..8a31161 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -585,9 +585,12 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_flash_x16>;
-	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
+	ranges = <0 0 0x08000000 0x01000000>;	/* minimum GPMC partition = 16MB */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;		/* device IO registers */
+		interrupt-parent = <&crossbar_mpu>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <16>;
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 5d65db9..f0a3616 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1389,6 +1389,10 @@
 			gpmc,num-waitpins = <2>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
index 6f6bd98..245f5f9 100644
--- a/arch/arm/boot/dts/dra72-evm.dts
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -395,13 +395,16 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_default>;
-	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
+	ranges = <0 0 0x08000000 0x01000000>;	/* minimum GPMC partition = 16MB */
 	nand@0,0 {
 		/* To use NAND, DIP switch SW5 must be set like so:
 		 * SW5.1 (NAND_SELn) = ON (LOW)
 		 * SW5.9 (GPMC_WPN) = OFF (HIGH)
 		 */
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;		/* device IO registers */
+		interrupt-parent = <&crossbar_mpu>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <16>;
-- 
2.1.4


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

* [PATCH v3 21/27] ARM: dts: dra7x-evm: Provide NAND ready pin
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (19 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 22/27] ARM: dts: am437x: Fix NAND device nodes Roger Quadros
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

On these boards NAND ready pin status is avilable over
GPMC_WAIT0 pin.

Read speed increases from 13768 KiB/ to 17246 KiB/s.
Write speed was unchanged at 7123 KiB/s.
Measured using mtd_speedtest.ko.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/dra7-evm.dts  | 1 +
 arch/arm/boot/dts/dra72-evm.dts | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index 8a31161..4760562 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -591,6 +591,7 @@
 		reg = <0 0 4>;		/* device IO registers */
 		interrupt-parent = <&crossbar_mpu>;
 		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		ready-gpio = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <16>;
diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
index 245f5f9..a11a646 100644
--- a/arch/arm/boot/dts/dra72-evm.dts
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -405,6 +405,7 @@
 		reg = <0 0 4>;		/* device IO registers */
 		interrupt-parent = <&crossbar_mpu>;
 		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		ready-gpio = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <16>;
-- 
2.1.4


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

* [PATCH v3 22/27] ARM: dts: am437x: Fix NAND device nodes
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (20 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 21/27] ARM: dts: dra7x-evm: Provide NAND ready pin Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 23/27] ARM: dts: am437x-gp-evm: Provide NAND ready pin Roger Quadros
                   ` (8 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Add compatible id, GPMC register resource and interrupt
resource to NAND controller nodes.

The GPMC driver now implements gpiochip and irqchip so
enable gpio-controller and interrupt-controller properties.

With this the interrupt parent of NAND node changes so fix it
accordingly.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/am4372.dtsi        | 4 ++++
 arch/arm/boot/dts/am437x-gp-evm.dts  | 5 ++++-
 arch/arm/boot/dts/am43x-epos-evm.dts | 5 ++++-
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 0447c04a..ec8b7a3 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -849,6 +849,10 @@
 			gpmc,num-waitpins = <2>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts
index 22038f2..aa96c99 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -794,9 +794,12 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_flash_x8>;
-	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
+	ranges = <0 0 0x08000000 0x01000000>;	/* CS0 space. Min partition = 16MB */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;		/* device IO registers */
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
 		ti,nand-ecc-opt = "bch16";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index 86c2dfb..9a7786d 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -561,9 +561,12 @@
 	status = "okay";	/* Disable QSPI when enabling GPMC (NAND) */
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_flash_x8>;
-	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x08000000 0x01000000>;	/* CS0 space. Min partition = 16MB */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
 		ti,nand-ecc-opt = "bch16";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
-- 
2.1.4


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

* [PATCH v3 23/27] ARM: dts: am437x-gp-evm: Provide NAND ready pin
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (21 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 22/27] ARM: dts: am437x: Fix NAND device nodes Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 24/27] ARM: dts: am335x: Fix NAND device nodes Roger Quadros
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

On these boards NAND ready pin status is avilable over
GPMC_WAIT0 pin.

For NAND we don't use GPMC wait pin monitoring but
get the NAND Ready/Busy# status using GPIOlib.
GPMC driver provides the WAIT0 pin status over GPIOlib.

Read speed increases from 16516 KiB/ to 18813 KiB/s
and write speed was unchanged at 9941 KiB/s.

Measured using mtd_speedtest.ko.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/am437x-gp-evm.dts  | 3 +--
 arch/arm/boot/dts/am43x-epos-evm.dts | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts
index aa96c99..d7bfe9f 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -800,6 +800,7 @@
 		reg = <0 0 4>;		/* device IO registers */
 		interrupt-parent = <&gic>;
 		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+		ready-gpio = <&gpmc 0 GPIO_ACTIVE_HIGH>;	/* gpmc_wait0 */
 		ti,nand-ecc-opt = "bch16";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
@@ -818,11 +819,9 @@
 		gpmc,access-ns = <30>;
 		gpmc,rd-cycle-ns = <40>;
 		gpmc,wr-cycle-ns = <40>;
-		gpmc,wait-pin = <0>;
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		/* MTD partition table */
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index 9a7786d..4b26762 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -567,6 +567,7 @@
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
 		interrupt-parent = <&gic>;
 		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+		ready-gpio = <&gpmc 0 GPIO_ACTIVE_HIGH>;	/* gpmc_wait0 */
 		ti,nand-ecc-opt = "bch16";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
@@ -585,11 +586,9 @@
 		gpmc,access-ns = <30>; /* tCEA + 4*/
 		gpmc,rd-cycle-ns = <40>;
 		gpmc,wr-cycle-ns = <40>;
-		gpmc,wait-pin = <0>;
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		/* MTD partition table */
-- 
2.1.4


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

* [PATCH v3 24/27] ARM: dts: am335x: Fix NAND device nodes
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (22 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 23/27] ARM: dts: am437x-gp-evm: Provide NAND ready pin Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 25/27] ARM: dts: am335x: Provide NAND ready pin Roger Quadros
                   ` (6 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Add compatible id, GPMC register resource and interrupt
resource to NAND controller nodes.

The GPMC driver now implements gpiochip and irqchip so
enable gpio-controller and interrupt-controller properties.

With this the interrupt parent of NAND node changes so fix it
accordingly.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/am335x-chilisom.dtsi | 3 +++
 arch/arm/boot/dts/am335x-evm.dts       | 3 +++
 arch/arm/boot/dts/am335x-igep0033.dtsi | 3 +++
 arch/arm/boot/dts/am33xx.dtsi          | 4 ++++
 4 files changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-chilisom.dtsi b/arch/arm/boot/dts/am335x-chilisom.dtsi
index 7e9a34d..e2b5e22 100644
--- a/arch/arm/boot/dts/am335x-chilisom.dtsi
+++ b/arch/arm/boot/dts/am335x-chilisom.dtsi
@@ -208,7 +208,10 @@
 	pinctrl-0 = <&nandflash_pins>;
 	ranges = <0 0 0x08000000 0x01000000>; /* CS0 0 @addr 0x08000000, size 0x01000000 */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <100>;
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index 1942a5c..bea36e1 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -519,7 +519,10 @@
 	pinctrl-0 = <&nandflash_pins_s0>;
 	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <100>;
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi
index c0e1135..9252ff1 100644
--- a/arch/arm/boot/dts/am335x-igep0033.dtsi
+++ b/arch/arm/boot/dts/am335x-igep0033.dtsi
@@ -129,7 +129,10 @@
 	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <100>;
 		nand-bus-width = <8>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,device-width = <1>;
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index d23e252..e065f21 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -823,6 +823,10 @@
 			gpmc,num-waitpins = <2>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 			status = "disabled";
 		};
 
-- 
2.1.4


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

* [PATCH v3 25/27] ARM: dts: am335x: Provide NAND ready pin
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (23 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 24/27] ARM: dts: am335x: Fix NAND device nodes Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 26/27] ARM: dts: dm816x: Fix gpmc and NAND node Roger Quadros
                   ` (5 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

On these boards NAND ready pin status is avilable over
GPMC_WAIT0 pin.

For NAND we don't use GPMC wait pin monitoring but
get the NAND Ready/Busy# status using GPIOlib.
GPMC driver provides the WAIT0 pin status over GPIOlib.

Read speed increases from 7869 KiB/ to 8875 KiB/s
and write speed was unchanged at 5100 KiB/s.

Measured using mtd_speedtest.ko.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/am335x-chilisom.dtsi | 4 +---
 arch/arm/boot/dts/am335x-evm.dts       | 4 +---
 arch/arm/boot/dts/am335x-igep0033.dtsi | 4 +---
 3 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-chilisom.dtsi b/arch/arm/boot/dts/am335x-chilisom.dtsi
index e2b5e22..3c71c5d 100644
--- a/arch/arm/boot/dts/am335x-chilisom.dtsi
+++ b/arch/arm/boot/dts/am335x-chilisom.dtsi
@@ -212,6 +212,7 @@
 		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		interrupt-parent = <&intc>;
 		interrupts = <100>;
+		ready-gpio = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
@@ -230,12 +231,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 	};
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index bea36e1..c7dfc21 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -523,6 +523,7 @@
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
 		interrupt-parent = <&intc>;
 		interrupts = <100>;
+		ready-gpio = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
@@ -541,12 +542,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		/* MTD partition table */
diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi
index 9252ff1..84d4d50 100644
--- a/arch/arm/boot/dts/am335x-igep0033.dtsi
+++ b/arch/arm/boot/dts/am335x-igep0033.dtsi
@@ -133,6 +133,7 @@
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
 		interrupt-parent = <&intc>;
 		interrupts = <100>;
+		ready-gpio = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		nand-bus-width = <8>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,device-width = <1>;
@@ -150,12 +151,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 
-- 
2.1.4


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

* [PATCH v3 26/27] ARM: dts: dm816x: Fix gpmc and NAND node
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (24 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 25/27] ARM: dts: am335x: Provide NAND ready pin Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-09-18 14:53 ` [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes Roger Quadros
                   ` (4 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Make gpmc node gpio+interrupt capable.

Add compatible id, interrupt and wait pin to NAND node.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/dm8168-evm.dts | 7 ++++---
 arch/arm/boot/dts/dm816x.dtsi    | 4 ++++
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts
index 169a855..faa7abe 100644
--- a/arch/arm/boot/dts/dm8168-evm.dts
+++ b/arch/arm/boot/dts/dm8168-evm.dts
@@ -85,8 +85,12 @@
 	ranges = <0 0 0x04000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		linux,mtd-name= "micron,mt29f2g16aadwp";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <100>;
+		ready-gpio = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ti,nand-ecc-opt = "bch8";
@@ -106,12 +110,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		partition@0 {
diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi
index 3c99cfa..68fb444 100644
--- a/arch/arm/boot/dts/dm816x.dtsi
+++ b/arch/arm/boot/dts/dm816x.dtsi
@@ -182,6 +182,10 @@
 			interrupts = <100>;
 			gpmc,num-cs = <6>;
 			gpmc,num-waitpins = <2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 		};
 
 		i2c1: i2c@48028000 {
-- 
2.1.4


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

* [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (25 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 26/27] ARM: dts: dm816x: Fix gpmc and NAND node Roger Quadros
@ 2015-09-18 14:53 ` Roger Quadros
  2015-10-13  0:43   ` Tony Lindgren
  2015-10-14  8:55   ` [PATCH v4 " Roger Quadros
  2015-09-30  7:39 ` [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (3 subsequent siblings)
  30 siblings, 2 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-18 14:53 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Roger Quadros

Add compatible id, GPMC register resource and interrupt
resource to NAND controller nodes.

The GPMC driver now implements gpiochip and irqchip so
enable gpio-controller and interrupt-controller properties.

With this the interrupt parent of NAND node changes so fix it
accordingly.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/logicpd-torpedo-som.dtsi     | 7 +++++--
 arch/arm/boot/dts/omap3-beagle.dts             | 2 ++
 arch/arm/boot/dts/omap3-cm-t3x.dtsi            | 5 ++++-
 arch/arm/boot/dts/omap3-devkit8000-common.dtsi | 3 +++
 arch/arm/boot/dts/omap3-evm-37xx.dts           | 7 +++++--
 arch/arm/boot/dts/omap3-gta04.dtsi             | 3 +++
 arch/arm/boot/dts/omap3-igep.dtsi              | 5 ++++-
 arch/arm/boot/dts/omap3-igep0020-common.dtsi   | 4 ++--
 arch/arm/boot/dts/omap3-igep0030-common.dtsi   | 4 ++++
 arch/arm/boot/dts/omap3-ldp.dts                | 9 ++++++---
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi        | 5 ++++-
 arch/arm/boot/dts/omap3-pandora-common.dtsi    | 3 +++
 arch/arm/boot/dts/omap3-tao3530.dtsi           | 5 ++++-
 arch/arm/boot/dts/omap3.dtsi                   | 4 ++++
 arch/arm/boot/dts/omap3430-sdp.dts             | 5 ++++-
 15 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
index 36387b1..4ba73c9 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
@@ -35,11 +35,14 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
-		linux,mtd-name = "micron,mt29f4g16abbda3w";
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
+		linux,mtd-name = "micron,mt29f4g16abbda3w";
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,sync-clk-ps = <0>;
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index a547411..bb4df5d 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -384,7 +384,9 @@
 
 	/* Chip select 0 */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;		/* NAND I/O window, 4 bytes */
+		interrupt-parent = <&intc>;
 		interrupts = <20>;
 		ti,nand-ecc-opt = "ham1";
 		nand-bus-width = <16>;
diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
index 4d091ca..e9d7e28 100644
--- a/arch/arm/boot/dts/omap3-cm-t3x.dtsi
+++ b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
@@ -261,10 +261,13 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <8>;
 		gpmc,device-width = <1>;
 		ti,nand-ecc-opt = "sw";
diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
index 9ca2865..e7b46ad 100644
--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
@@ -204,7 +204,10 @@
 	ranges = <0 0 0x30000000 0x1000000>;       /* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "sw";
diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts
index 16e8ce3..7081e07 100644
--- a/arch/arm/boot/dts/omap3-evm-37xx.dts
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -154,12 +154,15 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>,	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x30000000 0x1000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		linux,mtd-name= "hynix,h8kds0un0mer-4em";
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi
index 7166d88..4c48b31 100644
--- a/arch/arm/boot/dts/omap3-gta04.dtsi
+++ b/arch/arm/boot/dts/omap3-gta04.dtsi
@@ -492,7 +492,10 @@
 	ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 
diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
index d5e5cd4..1324f51 100644
--- a/arch/arm/boot/dts/omap3-igep.dtsi
+++ b/arch/arm/boot/dts/omap3-igep.dtsi
@@ -101,8 +101,11 @@
 
 &gpmc {
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		linux,mtd-name= "micron,mt29c4g96maz";
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
diff --git a/arch/arm/boot/dts/omap3-igep0020-common.dtsi b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
index e458c21..8b7b7c7 100644
--- a/arch/arm/boot/dts/omap3-igep0020-common.dtsi
+++ b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
@@ -204,8 +204,8 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x20000000>,
-		 <5 0 0x2c000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x01000000>,	/* CS0: 16MB for NAND */
+		 <5 0 0x2c000000 0x01000000>;	/* CS5: 16MB for ethernet */
 
 	ethernet@gpmc {
 		pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/omap3-igep0030-common.dtsi b/arch/arm/boot/dts/omap3-igep0030-common.dtsi
index 0cb1527..c5d8210 100644
--- a/arch/arm/boot/dts/omap3-igep0030-common.dtsi
+++ b/arch/arm/boot/dts/omap3-igep0030-common.dtsi
@@ -58,3 +58,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart2_pins>;
 };
+
+&gpmc {
+	ranges = <0 0 0x30000000 0x01000000>;   /* CS0: 16MB for NAND */
+};
diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts
index bd6e676..fb86131 100644
--- a/arch/arm/boot/dts/omap3-ldp.dts
+++ b/arch/arm/boot/dts/omap3-ldp.dts
@@ -97,12 +97,15 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x01000000>,
-		 <1 0 0x08000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x1000000>,	/* CS0 space, 16MB */
+		 <1 0 0x08000000 0x1000000>;	/* CS1 space, 16MB */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		linux,mtd-name= "micron,nand";
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
diff --git a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
index d0dd036..abc39f4 100644
--- a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
+++ b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
@@ -362,7 +362,10 @@
 		<7 0 0x15000000 0x01000000>;
 
 	nand@0,0 {
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 		/* no elm on omap3 */
diff --git a/arch/arm/boot/dts/omap3-pandora-common.dtsi b/arch/arm/boot/dts/omap3-pandora-common.dtsi
index f2084e6..11ada97 100644
--- a/arch/arm/boot/dts/omap3-pandora-common.dtsi
+++ b/arch/arm/boot/dts/omap3-pandora-common.dtsi
@@ -546,7 +546,10 @@
 	ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "sw";
 
diff --git a/arch/arm/boot/dts/omap3-tao3530.dtsi b/arch/arm/boot/dts/omap3-tao3530.dtsi
index 7bd8d9a..838e0da 100644
--- a/arch/arm/boot/dts/omap3-tao3530.dtsi
+++ b/arch/arm/boot/dts/omap3-tao3530.dtsi
@@ -275,10 +275,13 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;	/* GPMC_DEVWIDTH_16BIT */
 		ti,nand-ecc-opt = "sw";
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 69a40cf..f802bcf 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -720,6 +720,10 @@
 			gpmc,num-waitpins = <4>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 		};
 
 		usb_otg_hs: usb_otg_hs@480ab000 {
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index 16b0cdf..3f113c5 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -103,10 +103,13 @@
 	};
 
 	nand@1,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		linux,mtd-name= "micron,mt29f1g08abb";
 		#address-cells = <1>;
 		#size-cells = <1>;
-		reg = <1 0 4>;	/* CS1, offset 0, IO size 4 */
 		ti,nand-ecc-opt = "sw";
 		nand-bus-width = <8>;
 		gpmc,cs-on-ns = <0>;
-- 
2.1.4


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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (26 preceding siblings ...)
  2015-09-18 14:53 ` [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes Roger Quadros
@ 2015-09-30  7:39 ` Roger Quadros
  2015-09-30 11:00 ` Roger Quadros
                   ` (2 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-09-30  7:39 UTC (permalink / raw)
  To: dwmw2, computersforpeace
  Cc: tony, ezequiel, javier, fcooper, nsekhar, linux-mtd, linux-omap,
	devicetree, linux-kernel

Brian/David,

On 18/09/15 17:53, Roger Quadros wrote:
> Hi,
> 
> We do a couple of things in this series which result in
> cleaner device tree implementation, faster perfomance and
> multi-platform support. As an added bonus we get new GPI/Interrupt pins
> for use in the system.
> 
> - Establish a custom interface between NAND and GPMC driver. This is
> needed because all of the NAND registers sit in the GPMC register space.
> Some bits like NAND IRQ are even shared with GPMC.
> 
> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
> This causes performance increase when using prefetch-irq mode.
> 30% increase in read, 17% increase in write in prefetch-irq mode.
> 
> - Clean up device tree support so that omap-gpmc IP and the omap2 NAND
> driver can be used on non-OMAP platforms. e.g. Keystone.
> 
> - Implement GPIOCHIP + IRQCHIP for the GPMC WAITPINS. SoCs can contain
> 2 to 4 of these and most of them would be unused otherwise. It also
> allows a cleaner implementation of NAND Ready pin status for the NAND driver.
> 
> - Implement GPIOlib based NAND ready pin checking for OMAP NAND driver.
> 
> This series is available at
> git@github.com:rogerq/linux.git
> in branch
> for-v4.4/gpmc-v3

Could you please ack the patches affecting the omap2 nand driver?
These would be patches 4, 6, 9, 10, 11, 12, 18. Thanks.

cheers,
-roger

> 
> Changelog:
> v3:
> -Fixed and tested NAND using legacy boot on omap3-beagle.
> -Support rising and falling edge interrupts on WAITpins.
> -Update DT node of all gpmc users.
> 
> Roger Quadros (27):
>   ARM: OMAP2+: gpmc: Add platform data
>   ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data
>   memory: omap-gpmc: Introduce GPMC to NAND interface
>   mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers
>   memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status
>   mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty
>     check
>   memory: omap-gpmc: Remove NAND IRQ code
>   memory: omap-gpmc: Add IRQ ops for GPMC-NAND interface
>   mtd: nand: omap2: manage NAND interrupts
>   mtd: nand: omap: Copy platform data parameters to omap_nand_info data
>   mtd: nand: omap: Clean up device tree support
>   mtd: nand: omap: Update DT binding documentation
>   memory: omap-gpmc: Prevent mapping into 1st 16MB
>   memory: omap-gpmc: Move device tree binding to correct location
>   memory: omap-gpmc: Support general purpose input for WAITPINs
>   memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring
>   memory: omap-gpmc: Add irqchip support to the gpiochip
>   mtd: nand: omap2: Implement NAND ready using gpiolib
>   memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via
>     gpmc_regs
>   ARM: dts: dra7: Fix NAND device nodes.
>   ARM: dts: dra7x-evm: Provide NAND ready pin
>   ARM: dts: am437x: Fix NAND device nodes
>   ARM: dts: am437x-gp-evm: Provide NAND ready pin
>   ARM: dts: am335x: Fix NAND device nodes
>   ARM: dts: am335x: Provide NAND ready pin
>   ARM: dts: dm816x: Fix gpmc and NAND node
>   ARM: dts: omap3: Fix gpmc and NAND nodes
> 
>  Documentation/devicetree/bindings/bus/ti-gpmc.txt  | 130 -----
>  .../bindings/memory-controllers/omap-gpmc.txt      | 130 +++++
>  .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
>  arch/arm/boot/dts/am335x-chilisom.dtsi             |   7 +-
>  arch/arm/boot/dts/am335x-evm.dts                   |   7 +-
>  arch/arm/boot/dts/am335x-igep0033.dtsi             |   7 +-
>  arch/arm/boot/dts/am33xx.dtsi                      |   4 +
>  arch/arm/boot/dts/am4372.dtsi                      |   4 +
>  arch/arm/boot/dts/am437x-gp-evm.dts                |   8 +-
>  arch/arm/boot/dts/am43x-epos-evm.dts               |   8 +-
>  arch/arm/boot/dts/dm8168-evm.dts                   |   7 +-
>  arch/arm/boot/dts/dm816x.dtsi                      |   4 +
>  arch/arm/boot/dts/dra7-evm.dts                     |   6 +-
>  arch/arm/boot/dts/dra7.dtsi                        |   4 +
>  arch/arm/boot/dts/dra72-evm.dts                    |   6 +-
>  arch/arm/boot/dts/logicpd-torpedo-som.dtsi         |   7 +-
>  arch/arm/boot/dts/omap3-beagle.dts                 |   2 +
>  arch/arm/boot/dts/omap3-cm-t3x.dtsi                |   5 +-
>  arch/arm/boot/dts/omap3-devkit8000-common.dtsi     |   3 +
>  arch/arm/boot/dts/omap3-evm-37xx.dts               |   7 +-
>  arch/arm/boot/dts/omap3-gta04.dtsi                 |   3 +
>  arch/arm/boot/dts/omap3-igep.dtsi                  |   5 +-
>  arch/arm/boot/dts/omap3-igep0020-common.dtsi       |   4 +-
>  arch/arm/boot/dts/omap3-igep0030-common.dtsi       |   4 +
>  arch/arm/boot/dts/omap3-ldp.dts                    |   9 +-
>  arch/arm/boot/dts/omap3-lilly-a83x.dtsi            |   5 +-
>  arch/arm/boot/dts/omap3-pandora-common.dtsi        |   3 +
>  arch/arm/boot/dts/omap3-tao3530.dtsi               |   5 +-
>  arch/arm/boot/dts/omap3.dtsi                       |   4 +
>  arch/arm/boot/dts/omap3430-sdp.dts                 |   5 +-
>  arch/arm/mach-omap2/gpmc-nand.c                    |  11 +-
>  drivers/memory/omap-gpmc.c                         | 640 ++++++++++++---------
>  drivers/mtd/nand/omap2.c                           | 261 ++++++---
>  include/linux/omap-gpmc.h                          | 183 ++----
>  include/linux/platform_data/gpmc-omap.h            | 167 ++++++
>  include/linux/platform_data/mtd-nand-omap2.h       |  12 +-
>  36 files changed, 1045 insertions(+), 648 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>  create mode 100644 include/linux/platform_data/gpmc-omap.h
> 

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (27 preceding siblings ...)
  2015-09-30  7:39 ` [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
@ 2015-09-30 11:00 ` Roger Quadros
  2015-10-06  8:33   ` Tony Lindgren
  2015-10-26 21:23 ` Brian Norris
  2015-12-03  5:09 ` Brian Norris
  30 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-09-30 11:00 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

Tony,

On 18/09/15 17:53, Roger Quadros wrote:
> Hi,
> 
> We do a couple of things in this series which result in
> cleaner device tree implementation, faster perfomance and
> multi-platform support. As an added bonus we get new GPI/Interrupt pins
> for use in the system.
> 
> - Establish a custom interface between NAND and GPMC driver. This is
> needed because all of the NAND registers sit in the GPMC register space.
> Some bits like NAND IRQ are even shared with GPMC.
> 
> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
> This causes performance increase when using prefetch-irq mode.
> 30% increase in read, 17% increase in write in prefetch-irq mode.
> 
> - Clean up device tree support so that omap-gpmc IP and the omap2 NAND
> driver can be used on non-OMAP platforms. e.g. Keystone.
> 
> - Implement GPIOCHIP + IRQCHIP for the GPMC WAITPINS. SoCs can contain
> 2 to 4 of these and most of them would be unused otherwise. It also
> allows a cleaner implementation of NAND Ready pin status for the NAND driver.
> 
> - Implement GPIOlib based NAND ready pin checking for OMAP NAND driver.
> 
> This series is available at
> git@github.com:rogerq/linux.git
> in branch
> for-v4.4/gpmc-v3

I've verified this series with the following boards
-dra7-evm
-am437x-gp-evm
-am335x-evm
-beagleboard-c4

For legacy boot I've checked only on beagleboard-c4.

Test procedure was to read an existing ubifs partition,
create a new one and read it back.

Need you to Ack if it looks good.
Do you mind taking it via omap-soc once MTD maintainers ack their relevant parts?

cheers,
-roger

> 
> Changelog:
> v3:
> -Fixed and tested NAND using legacy boot on omap3-beagle.
> -Support rising and falling edge interrupts on WAITpins.
> -Update DT node of all gpmc users.
> 
> Roger Quadros (27):
>   ARM: OMAP2+: gpmc: Add platform data
>   ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data
>   memory: omap-gpmc: Introduce GPMC to NAND interface
>   mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers
>   memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status
>   mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty
>     check
>   memory: omap-gpmc: Remove NAND IRQ code
>   memory: omap-gpmc: Add IRQ ops for GPMC-NAND interface
>   mtd: nand: omap2: manage NAND interrupts
>   mtd: nand: omap: Copy platform data parameters to omap_nand_info data
>   mtd: nand: omap: Clean up device tree support
>   mtd: nand: omap: Update DT binding documentation
>   memory: omap-gpmc: Prevent mapping into 1st 16MB
>   memory: omap-gpmc: Move device tree binding to correct location
>   memory: omap-gpmc: Support general purpose input for WAITPINs
>   memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring
>   memory: omap-gpmc: Add irqchip support to the gpiochip
>   mtd: nand: omap2: Implement NAND ready using gpiolib
>   memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via
>     gpmc_regs
>   ARM: dts: dra7: Fix NAND device nodes.
>   ARM: dts: dra7x-evm: Provide NAND ready pin
>   ARM: dts: am437x: Fix NAND device nodes
>   ARM: dts: am437x-gp-evm: Provide NAND ready pin
>   ARM: dts: am335x: Fix NAND device nodes
>   ARM: dts: am335x: Provide NAND ready pin
>   ARM: dts: dm816x: Fix gpmc and NAND node
>   ARM: dts: omap3: Fix gpmc and NAND nodes
> 
>  Documentation/devicetree/bindings/bus/ti-gpmc.txt  | 130 -----
>  .../bindings/memory-controllers/omap-gpmc.txt      | 130 +++++
>  .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
>  arch/arm/boot/dts/am335x-chilisom.dtsi             |   7 +-
>  arch/arm/boot/dts/am335x-evm.dts                   |   7 +-
>  arch/arm/boot/dts/am335x-igep0033.dtsi             |   7 +-
>  arch/arm/boot/dts/am33xx.dtsi                      |   4 +
>  arch/arm/boot/dts/am4372.dtsi                      |   4 +
>  arch/arm/boot/dts/am437x-gp-evm.dts                |   8 +-
>  arch/arm/boot/dts/am43x-epos-evm.dts               |   8 +-
>  arch/arm/boot/dts/dm8168-evm.dts                   |   7 +-
>  arch/arm/boot/dts/dm816x.dtsi                      |   4 +
>  arch/arm/boot/dts/dra7-evm.dts                     |   6 +-
>  arch/arm/boot/dts/dra7.dtsi                        |   4 +
>  arch/arm/boot/dts/dra72-evm.dts                    |   6 +-
>  arch/arm/boot/dts/logicpd-torpedo-som.dtsi         |   7 +-
>  arch/arm/boot/dts/omap3-beagle.dts                 |   2 +
>  arch/arm/boot/dts/omap3-cm-t3x.dtsi                |   5 +-
>  arch/arm/boot/dts/omap3-devkit8000-common.dtsi     |   3 +
>  arch/arm/boot/dts/omap3-evm-37xx.dts               |   7 +-
>  arch/arm/boot/dts/omap3-gta04.dtsi                 |   3 +
>  arch/arm/boot/dts/omap3-igep.dtsi                  |   5 +-
>  arch/arm/boot/dts/omap3-igep0020-common.dtsi       |   4 +-
>  arch/arm/boot/dts/omap3-igep0030-common.dtsi       |   4 +
>  arch/arm/boot/dts/omap3-ldp.dts                    |   9 +-
>  arch/arm/boot/dts/omap3-lilly-a83x.dtsi            |   5 +-
>  arch/arm/boot/dts/omap3-pandora-common.dtsi        |   3 +
>  arch/arm/boot/dts/omap3-tao3530.dtsi               |   5 +-
>  arch/arm/boot/dts/omap3.dtsi                       |   4 +
>  arch/arm/boot/dts/omap3430-sdp.dts                 |   5 +-
>  arch/arm/mach-omap2/gpmc-nand.c                    |  11 +-
>  drivers/memory/omap-gpmc.c                         | 640 ++++++++++++---------
>  drivers/mtd/nand/omap2.c                           | 261 ++++++---
>  include/linux/omap-gpmc.h                          | 183 ++----
>  include/linux/platform_data/gpmc-omap.h            | 167 ++++++
>  include/linux/platform_data/mtd-nand-omap2.h       |  12 +-
>  36 files changed, 1045 insertions(+), 648 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>  create mode 100644 include/linux/platform_data/gpmc-omap.h
> 

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-09-30 11:00 ` Roger Quadros
@ 2015-10-06  8:33   ` Tony Lindgren
  2015-10-06  9:54     ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Tony Lindgren @ 2015-10-06  8:33 UTC (permalink / raw)
  To: Roger Quadros
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

* Roger Quadros <rogerq@ti.com> [150930 04:04]:
> Tony,
> 
> On 18/09/15 17:53, Roger Quadros wrote:
> > Hi,
> > 
> > We do a couple of things in this series which result in
> > cleaner device tree implementation, faster perfomance and
> > multi-platform support. As an added bonus we get new GPI/Interrupt pins
> > for use in the system.
> > 
> > - Establish a custom interface between NAND and GPMC driver. This is
> > needed because all of the NAND registers sit in the GPMC register space.
> > Some bits like NAND IRQ are even shared with GPMC.
> > 
> > - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
> > with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
> > This causes performance increase when using prefetch-irq mode.
> > 30% increase in read, 17% increase in write in prefetch-irq mode.
> > 
> > - Clean up device tree support so that omap-gpmc IP and the omap2 NAND
> > driver can be used on non-OMAP platforms. e.g. Keystone.
> > 
> > - Implement GPIOCHIP + IRQCHIP for the GPMC WAITPINS. SoCs can contain
> > 2 to 4 of these and most of them would be unused otherwise. It also
> > allows a cleaner implementation of NAND Ready pin status for the NAND driver.
> > 
> > - Implement GPIOlib based NAND ready pin checking for OMAP NAND driver.
> > 
> > This series is available at
> > git@github.com:rogerq/linux.git
> > in branch
> > for-v4.4/gpmc-v3

In general, very nice work :)

> I've verified this series with the following boards
> -dra7-evm
> -am437x-gp-evm
> -am335x-evm
> -beagleboard-c4
> 
> For legacy boot I've checked only on beagleboard-c4.

Great.

Does build and boot and use NAND work throughtout the series?
Otherwise we'll have hard time bisecting anything..

> Test procedure was to read an existing ubifs partition,
> create a new one and read it back.
> 
> Need you to Ack if it looks good.
> Do you mind taking it via omap-soc once MTD maintainers ack their relevant parts?

Sure. I'll try to do some testing on the series first too.

Can the dts changes be merged separtely? Otherwise we'll have
a dependency between dts branch and the GPMC/NAND changes.

Regards,

Tony

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-06  8:33   ` Tony Lindgren
@ 2015-10-06  9:54     ` Roger Quadros
  2015-10-06 10:00       ` Tony Lindgren
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-06  9:54 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

On 06/10/15 11:33, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [150930 04:04]:
>> Tony,
>>
>> On 18/09/15 17:53, Roger Quadros wrote:
>>> Hi,
>>>
>>> We do a couple of things in this series which result in
>>> cleaner device tree implementation, faster perfomance and
>>> multi-platform support. As an added bonus we get new GPI/Interrupt pins
>>> for use in the system.
>>>
>>> - Establish a custom interface between NAND and GPMC driver. This is
>>> needed because all of the NAND registers sit in the GPMC register space.
>>> Some bits like NAND IRQ are even shared with GPMC.
>>>
>>> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
>>> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
>>> This causes performance increase when using prefetch-irq mode.
>>> 30% increase in read, 17% increase in write in prefetch-irq mode.
>>>
>>> - Clean up device tree support so that omap-gpmc IP and the omap2 NAND
>>> driver can be used on non-OMAP platforms. e.g. Keystone.
>>>
>>> - Implement GPIOCHIP + IRQCHIP for the GPMC WAITPINS. SoCs can contain
>>> 2 to 4 of these and most of them would be unused otherwise. It also
>>> allows a cleaner implementation of NAND Ready pin status for the NAND driver.
>>>
>>> - Implement GPIOlib based NAND ready pin checking for OMAP NAND driver.
>>>
>>> This series is available at
>>> git@github.com:rogerq/linux.git
>>> in branch
>>> for-v4.4/gpmc-v3
> 
> In general, very nice work :)

Thanks :)

> 
>> I've verified this series with the following boards
>> -dra7-evm
>> -am437x-gp-evm
>> -am335x-evm
>> -beagleboard-c4
>>
>> For legacy boot I've checked only on beagleboard-c4.
> 
> Great.
> 
> Does build and boot and use NAND work throughtout the series?
> Otherwise we'll have hard time bisecting anything..

Yes it does with the following exceptions.

- Patch 7 "memory: omap-gpmc: Remove NAND IRQ code" breaks prefetch-irq mode
but none of the boards seem to be using it so it shouldn't break NAND on existing boards.
At patch 9 "mtd: nand: omap2: manage NAND interrupts" prefetch-irq mode is working again.
Do you want me to squash patches 7,8,9 so that pre-fetch irq is not broken at any point?

- Then at patch 11 "mtd: nand: omap: Clean up device tree support" we break NAND on all DT
boards as we expect NAND to be a real child node with compatible id. Simply applying the
DT patch at this point makes it work again.

> 
>> Test procedure was to read an existing ubifs partition,
>> create a new one and read it back.
>>
>> Need you to Ack if it looks good.
>> Do you mind taking it via omap-soc once MTD maintainers ack their relevant parts?
> 
> Sure. I'll try to do some testing on the series first too.
> 
Thanks.

> Can the dts changes be merged separtely? Otherwise we'll have
> a dependency between dts branch and the GPMC/NAND changes.

I'm afraid no. Patch 11 makes us incompatible with the old DT.

cheers,
-roger

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-06  9:54     ` Roger Quadros
@ 2015-10-06 10:00       ` Tony Lindgren
  2015-10-06 10:05         ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Tony Lindgren @ 2015-10-06 10:00 UTC (permalink / raw)
  To: Roger Quadros
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

* Roger Quadros <rogerq@ti.com> [151006 02:59]:
> On 06/10/15 11:33, Tony Lindgren wrote:
> > Does build and boot and use NAND work throughtout the series?
> > Otherwise we'll have hard time bisecting anything..
> 
> Yes it does with the following exceptions.
> 
> - Patch 7 "memory: omap-gpmc: Remove NAND IRQ code" breaks prefetch-irq mode
> but none of the boards seem to be using it so it shouldn't break NAND on existing boards.
> At patch 9 "mtd: nand: omap2: manage NAND interrupts" prefetch-irq mode is working again.
> Do you want me to squash patches 7,8,9 so that pre-fetch irq is not broken at any point?

OK, no that's fine, no need to squash them together then.

> - Then at patch 11 "mtd: nand: omap: Clean up device tree support" we break NAND on all DT
> boards as we expect NAND to be a real child node with compatible id. Simply applying the
> DT patch at this point makes it work again.

Hmm can we at least warn about incompatible DT entry when somebody boots
with an older dtb?

> >> Test procedure was to read an existing ubifs partition,
> >> create a new one and read it back.
> >>
> >> Need you to Ack if it looks good.
> >> Do you mind taking it via omap-soc once MTD maintainers ack their relevant parts?
> > 
> > Sure. I'll try to do some testing on the series first too.
> > 
> Thanks.
> 
> > Can the dts changes be merged separtely? Otherwise we'll have
> > a dependency between dts branch and the GPMC/NAND changes.
> 
> I'm afraid no. Patch 11 makes us incompatible with the old DT.

OK. If we can warn about that, then the out of tree users will
have easier time to update their dts file.

Regards,

Tony

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-06 10:00       ` Tony Lindgren
@ 2015-10-06 10:05         ` Roger Quadros
  2015-10-06 10:28           ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-06 10:05 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

On 06/10/15 13:00, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [151006 02:59]:
>> On 06/10/15 11:33, Tony Lindgren wrote:
>>> Does build and boot and use NAND work throughtout the series?
>>> Otherwise we'll have hard time bisecting anything..
>>
>> Yes it does with the following exceptions.
>>
>> - Patch 7 "memory: omap-gpmc: Remove NAND IRQ code" breaks prefetch-irq mode
>> but none of the boards seem to be using it so it shouldn't break NAND on existing boards.
>> At patch 9 "mtd: nand: omap2: manage NAND interrupts" prefetch-irq mode is working again.
>> Do you want me to squash patches 7,8,9 so that pre-fetch irq is not broken at any point?
> 
> OK, no that's fine, no need to squash them together then.
> 
>> - Then at patch 11 "mtd: nand: omap: Clean up device tree support" we break NAND on all DT
>> boards as we expect NAND to be a real child node with compatible id. Simply applying the
>> DT patch at this point makes it work again.
> 
> Hmm can we at least warn about incompatible DT entry when somebody boots
> with an older dtb?

Yes that could be done. It looks like we can use the missing compatible property to identify
that it is and old DT entry.

I'll send a v4 of patch 11.

cheers,
-roger


> 
>>>> Test procedure was to read an existing ubifs partition,
>>>> create a new one and read it back.
>>>>
>>>> Need you to Ack if it looks good.
>>>> Do you mind taking it via omap-soc once MTD maintainers ack their relevant parts?
>>>
>>> Sure. I'll try to do some testing on the series first too.
>>>
>> Thanks.
>>
>>> Can the dts changes be merged separtely? Otherwise we'll have
>>> a dependency between dts branch and the GPMC/NAND changes.
>>
>> I'm afraid no. Patch 11 makes us incompatible with the old DT.
> 
> OK. If we can warn about that, then the out of tree users will
> have easier time to update their dts file.
> 
> Regards,
> 
> Tony
> 

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-06 10:05         ` Roger Quadros
@ 2015-10-06 10:28           ` Roger Quadros
  2015-10-06 11:01             ` Tony Lindgren
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-06 10:28 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree, linux-omap, nsekhar, linux-kernel, linux-mtd,
	ezequiel, javier, computersforpeace, dwmw2, fcooper

On 06/10/15 13:05, Roger Quadros wrote:
> On 06/10/15 13:00, Tony Lindgren wrote:
>> * Roger Quadros <rogerq@ti.com> [151006 02:59]:
>>> On 06/10/15 11:33, Tony Lindgren wrote:
>>>> Does build and boot and use NAND work throughtout the series?
>>>> Otherwise we'll have hard time bisecting anything..
>>>
>>> Yes it does with the following exceptions.
>>>
>>> - Patch 7 "memory: omap-gpmc: Remove NAND IRQ code" breaks prefetch-irq mode
>>> but none of the boards seem to be using it so it shouldn't break NAND on existing boards.
>>> At patch 9 "mtd: nand: omap2: manage NAND interrupts" prefetch-irq mode is working again.
>>> Do you want me to squash patches 7,8,9 so that pre-fetch irq is not broken at any point?
>>
>> OK, no that's fine, no need to squash them together then.
>>
>>> - Then at patch 11 "mtd: nand: omap: Clean up device tree support" we break NAND on all DT
>>> boards as we expect NAND to be a real child node with compatible id. Simply applying the
>>> DT patch at this point makes it work again.
>>
>> Hmm can we at least warn about incompatible DT entry when somebody boots
>> with an older dtb?
> 
> Yes that could be done. It looks like we can use the missing compatible property to identify
> that it is and old DT entry.
> 
> I'll send a v4 of patch 11.

There is another issue. Some of the old DT nodes set the NAND IO address to 0.
As we prevent mapping into first 16MB we see the following message for those nodes. e.g. dra7-evm

[    1.727598] omap-gpmc 50000000.gpmc: cannot remap GPMC CS 0 to 0x00000000
[    1.727605] omap-gpmc 50000000.gpmc: GPMC CS 0 start cannot be lesser than 0x1000000
[    1.727611] omap-gpmc 50000000.gpmc: failed to probe DT children

Hope this is good enough information that DT needs to be updated?

cheers,
-roger

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

* [PATCH v4 11/27] mtd: nand: omap: Clean up device tree support
  2015-09-18 14:53 ` [PATCH v3 11/27] mtd: nand: omap: Clean up device tree support Roger Quadros
@ 2015-10-06 10:35   ` Roger Quadros
  2015-12-03  4:29     ` Brian Norris
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-06 10:35 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, rogerq

Move NAND specific device tree parsing to NAND driver.

The NAND controller node must have a compatible id, register space
resource and interrupt resource.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
v4: Warn if using older incompatible DT i.e. compatible property not present
in nand node.

 arch/arm/mach-omap2/gpmc-nand.c              |   5 +-
 drivers/memory/omap-gpmc.c                   | 143 +++++++--------------------
 drivers/mtd/nand/omap2.c                     | 136 +++++++++++++++++++++----
 include/linux/platform_data/mtd-nand-omap2.h |   3 +-
 4 files changed, 155 insertions(+), 132 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index ffe646a..e07ca27 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -95,10 +95,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 	gpmc_nand_res[1].start = gpmc_get_irq();
 
 	memset(&s, 0, sizeof(struct gpmc_settings));
-	if (gpmc_nand_data->of_node)
-		gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
-	else
-		gpmc_set_legacy(gpmc_nand_data, &s);
+	gpmc_set_legacy(gpmc_nand_data, &s);
 
 	s.device_nand = true;
 
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index e75226d..318c187 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -29,7 +29,6 @@
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 #include <linux/omap-gpmc.h>
-#include <linux/mtd/nand.h>
 #include <linux/pm_runtime.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
@@ -1716,105 +1715,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 		of_property_read_bool(np, "gpmc,time-para-granularity");
 }
 
-#if IS_ENABLED(CONFIG_MTD_NAND)
-
-static const char * const nand_xfer_types[] = {
-	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
-	[NAND_OMAP_POLLED]			= "polled",
-	[NAND_OMAP_PREFETCH_DMA]		= "prefetch-dma",
-	[NAND_OMAP_PREFETCH_IRQ]		= "prefetch-irq",
-};
-
-static int gpmc_probe_nand_child(struct platform_device *pdev,
-				 struct device_node *child)
-{
-	u32 val;
-	const char *s;
-	struct gpmc_timings gpmc_t;
-	struct omap_nand_platform_data *gpmc_nand_data;
-
-	if (of_property_read_u32(child, "reg", &val) < 0) {
-		dev_err(&pdev->dev, "%s has no 'reg' property\n",
-			child->full_name);
-		return -ENODEV;
-	}
-
-	gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data),
-				      GFP_KERNEL);
-	if (!gpmc_nand_data)
-		return -ENOMEM;
-
-	gpmc_nand_data->cs = val;
-	gpmc_nand_data->of_node = child;
-
-	/* Detect availability of ELM module */
-	gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
-	if (gpmc_nand_data->elm_of_node == NULL)
-		gpmc_nand_data->elm_of_node =
-					of_parse_phandle(child, "elm_id", 0);
-
-	/* select ecc-scheme for NAND */
-	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
-		pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
-		return -ENODEV;
-	}
-
-	if (!strcmp(s, "sw"))
-		gpmc_nand_data->ecc_opt = OMAP_ECC_HAM1_CODE_SW;
-	else if (!strcmp(s, "ham1") ||
-		 !strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
-		gpmc_nand_data->ecc_opt =
-				OMAP_ECC_HAM1_CODE_HW;
-	else if (!strcmp(s, "bch4"))
-		if (gpmc_nand_data->elm_of_node)
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH4_CODE_HW;
-		else
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
-	else if (!strcmp(s, "bch8"))
-		if (gpmc_nand_data->elm_of_node)
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH8_CODE_HW;
-		else
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
-	else if (!strcmp(s, "bch16"))
-		if (gpmc_nand_data->elm_of_node)
-			gpmc_nand_data->ecc_opt =
-				OMAP_ECC_BCH16_CODE_HW;
-		else
-			pr_err("%s: BCH16 requires ELM support\n", __func__);
-	else
-		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
-
-	/* select data transfer mode for NAND controller */
-	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
-		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
-			if (!strcasecmp(s, nand_xfer_types[val])) {
-				gpmc_nand_data->xfer_type = val;
-				break;
-			}
-
-	gpmc_nand_data->flash_bbt = of_get_nand_on_flash_bbt(child);
-
-	val = of_get_nand_bus_width(child);
-	if (val == 16)
-		gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
-
-	gpmc_read_timings_dt(child, &gpmc_t);
-	gpmc_nand_init(gpmc_nand_data, &gpmc_t);
-
-	return 0;
-}
-#else
-static int gpmc_probe_nand_child(struct platform_device *pdev,
-				 struct device_node *child)
-{
-	return 0;
-}
-#endif
-
 #if IS_ENABLED(CONFIG_MTD_ONENAND)
 static int gpmc_probe_onenand_child(struct platform_device *pdev,
 				 struct device_node *child)
@@ -1933,9 +1833,42 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		goto err;
 	}
 
-	ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
-	if (ret < 0)
-		goto err;
+	if (of_node_cmp(child->name, "nand") == 0) {
+		/* NAND specific setup */
+		u32 val;
+
+		/* Warn about older DT blobs with no compatible property */
+		if (!of_property_read_bool(child, "compatible")) {
+			dev_warn(&pdev->dev,
+				 "Incompatible NAND node: missing compatible");
+			ret = -EINVAL;
+			goto err;
+		}
+
+		val = of_get_nand_bus_width(child);
+		switch (val) {
+		case 8:
+			gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
+			break;
+		case 16:
+			gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
+			break;
+		default:
+			dev_err(&pdev->dev, "%s: invalid 'nand-bus-width'\n",
+				child->name);
+			ret = -EINVAL;
+			goto err;
+		}
+
+		/* disable write protect */
+		gpmc_configure(GPMC_CONFIG_WP, 0);
+		gpmc_s.device_nand = true;
+	} else {
+		ret = of_property_read_u32(child, "bank-width",
+					   &gpmc_s.device_width);
+		if (ret < 0)
+			goto err;
+	}
 
 	ret = gpmc_cs_program_settings(cs, &gpmc_s);
 	if (ret < 0)
@@ -2018,9 +1951,7 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 		if (!child->name)
 			continue;
 
-		if (of_node_cmp(child->name, "nand") == 0)
-			ret = gpmc_probe_nand_child(pdev, child);
-		else if (of_node_cmp(child->name, "onenand") == 0)
+		if (of_node_cmp(child->name, "onenand") == 0)
 			ret = gpmc_probe_onenand_child(pdev, child);
 		else
 			ret = gpmc_probe_generic_child(pdev, child);
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index c35405c..228f498 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_mtd.h>
 
 #include <linux/mtd/nand_bch.h>
 #include <linux/platform_data/elm.h>
@@ -177,6 +178,8 @@ struct omap_nand_info {
 	struct gpmc_nand_regs		reg;
 	struct gpmc_nand_ops		*ops;
 	/* generated at runtime depending on ECC algorithm and layout selected */
+	bool				flash_bbt;
+	/* generated at runtime depending on ECC algorithm and layout */
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct device			*elm_dev;
@@ -1668,10 +1671,84 @@ static bool omap2_nand_ecc_check(struct omap_nand_info *info,
 	return true;
 }
 
+static const char * const nand_xfer_types[] = {
+	[NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled",
+	[NAND_OMAP_POLLED] = "polled",
+	[NAND_OMAP_PREFETCH_DMA] = "prefetch-dma",
+	[NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq",
+};
+
+static int omap_get_dt_info(struct device *dev, struct omap_nand_info *info)
+{
+	struct device_node *child = dev->of_node;
+	int i;
+	const char *s;
+
+	/* In old bindings, CS num is embedded in reg property */
+	if (of_property_read_u32(child, "reg", &info->gpmc_cs) < 0) {
+		dev_err(dev, "reg not found in DT\n");
+		return -EINVAL;
+	}
+
+	/* detect availability of ELM module. Won't be present pre-OMAP4 */
+	info->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
+	if (!info->elm_of_node)
+		dev_dbg(dev, "ti,elm-id not in DT\n");
+
+	/* select ecc-scheme for NAND */
+	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
+		dev_err(dev, "ti,nand-ecc-opt not found\n");
+		return -EINVAL;
+	}
+
+	if (!strcmp(s, "sw")) {
+		info->ecc_opt = OMAP_ECC_HAM1_CODE_SW;
+	} else if (!strcmp(s, "ham1") ||
+		   !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) {
+		info->ecc_opt =	OMAP_ECC_HAM1_CODE_HW;
+	} else if (!strcmp(s, "bch4")) {
+		if (info->elm_of_node)
+			info->ecc_opt = OMAP_ECC_BCH4_CODE_HW;
+		else
+			info->ecc_opt = OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
+	} else if (!strcmp(s, "bch8")) {
+		if (info->elm_of_node)
+			info->ecc_opt = OMAP_ECC_BCH8_CODE_HW;
+		else
+			info->ecc_opt = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+	} else if (!strcmp(s, "bch16")) {
+		info->ecc_opt =	OMAP_ECC_BCH16_CODE_HW;
+	} else {
+		dev_err(dev, "unrecognized value for ti,nand-ecc-opt\n");
+		return -EINVAL;
+	}
+
+	/* select data transfer mode */
+	if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) {
+		for (i = 0; i < ARRAY_SIZE(nand_xfer_types); i++) {
+			if (!strcasecmp(s, nand_xfer_types[i])) {
+				info->xfer_type = i;
+				goto next;
+			}
+		}
+
+		dev_err(dev, "unrecognized value for ti,nand-xfer-type\n");
+		return -EINVAL;
+	}
+
+next:
+	of_get_nand_on_flash_bbt(child);
+
+	if (of_get_nand_bus_width(child) == 16)
+		info->devsize = NAND_BUSWIDTH_16;
+
+	return 0;
+}
+
 static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
-	struct omap_nand_platform_data	*pdata;
+	struct omap_nand_platform_data	*pdata = NULL;
 	struct mtd_info			*mtd;
 	struct nand_chip		*nand_chip;
 	struct nand_ecclayout		*ecclayout;
@@ -1682,33 +1759,42 @@ static int omap_nand_probe(struct platform_device *pdev)
 	unsigned			oob_index;
 	struct resource			*res;
 	struct mtd_part_parser_data	ppdata = {};
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "platform data missing\n");
-		return -ENODEV;
-	}
+	struct device			*dev = &pdev->dev;
 
 	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
 				GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, info);
+	info->pdev = pdev;
 
+	if (dev->of_node) {
+		if (omap_get_dt_info(dev, info))
+			return -EINVAL;
+	} else {
+		pdata = dev_get_platdata(&pdev->dev);
+		if (!pdata) {
+			dev_err(&pdev->dev, "platform data missing\n");
+			return -EINVAL;
+		}
+
+		info->gpmc_cs = pdata->cs;
+		info->reg = pdata->reg;
+		info->of_node = pdata->of_node;
+		info->ecc_opt = pdata->ecc_opt;
+		info->dev_ready	= pdata->dev_ready;
+		info->xfer_type = pdata->xfer_type;
+		info->devsize = pdata->devsize;
+		info->elm_of_node = pdata->elm_of_node;
+		info->flash_bbt = pdata->flash_bbt;
+	}
+
+	platform_set_drvdata(pdev, info);
 	info->ops = gpmc_omap_get_nand_ops(&info->reg, info->gpmc_cs);
 	if (!info->ops) {
 		dev_err(&pdev->dev, "Failed to get GPMC->NAND interface\n");
 		return -ENODEV;
 	}
-	info->pdev		= pdev;
-	info->gpmc_cs		= pdata->cs;
-	info->of_node		= pdata->of_node;
-	info->ecc_opt		= pdata->ecc_opt;
-	info->dev_ready	= pdata->dev_ready;
-	info->xfer_type = pdata->xfer_type;
-	info->devsize = pdata->devsize;
-	info->elm_of_node = pdata->elm_of_node;
 
 	mtd			= &info->mtd;
 	mtd->priv		= &info->nand;
@@ -1744,7 +1830,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->chip_delay = 50;
 	}
 
-	if (pdata->flash_bbt)
+	if (info->flash_bbt)
 		nand_chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
 	else
 		nand_chip->options |= NAND_SKIP_BBTSCAN;
@@ -2049,9 +2135,13 @@ scan_tail:
 		goto return_error;
 	}
 
-	ppdata.of_node = pdata->of_node;
-	mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts,
-				  pdata->nr_parts);
+	if (dev->of_node) {
+		ppdata.of_node = dev->of_node;
+		mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+
+	} else {
+		mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
+	}
 
 	platform_set_drvdata(pdev, mtd);
 
@@ -2083,11 +2173,17 @@ static int omap_nand_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id omap_nand_ids[] = {
+	{ .compatible = "ti,omap2-nand", },
+	{},
+};
+
 static struct platform_driver omap_nand_driver = {
 	.probe		= omap_nand_probe,
 	.remove		= omap_nand_remove,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.of_match_table = of_match_ptr(omap_nand_ids),
 	},
 };
 
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index a067f58..ff27e5a 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -76,11 +76,10 @@ struct omap_nand_platform_data {
 	int			devsize;
 	enum omap_ecc           ecc_opt;
 
-	/* for passing the partitions */
-	struct device_node	*of_node;
 	struct device_node	*elm_of_node;
 
 	/* deprecated */
 	struct gpmc_nand_regs	reg;
+	struct device_node	*of_node;
 };
 #endif
-- 
2.1.4



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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-06 10:28           ` Roger Quadros
@ 2015-10-06 11:01             ` Tony Lindgren
  2015-10-06 11:09               ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Tony Lindgren @ 2015-10-06 11:01 UTC (permalink / raw)
  To: Roger Quadros
  Cc: devicetree, linux-omap, nsekhar, linux-kernel, linux-mtd,
	ezequiel, javier, computersforpeace, dwmw2, fcooper

* Roger Quadros <rogerq@ti.com> [151006 03:32]:
> On 06/10/15 13:05, Roger Quadros wrote:
> > On 06/10/15 13:00, Tony Lindgren wrote:
> >> * Roger Quadros <rogerq@ti.com> [151006 02:59]:
> >>> On 06/10/15 11:33, Tony Lindgren wrote:
> >>>> Does build and boot and use NAND work throughtout the series?
> >>>> Otherwise we'll have hard time bisecting anything..
> >>>
> >>> Yes it does with the following exceptions.
> >>>
> >>> - Patch 7 "memory: omap-gpmc: Remove NAND IRQ code" breaks prefetch-irq mode
> >>> but none of the boards seem to be using it so it shouldn't break NAND on existing boards.
> >>> At patch 9 "mtd: nand: omap2: manage NAND interrupts" prefetch-irq mode is working again.
> >>> Do you want me to squash patches 7,8,9 so that pre-fetch irq is not broken at any point?
> >>
> >> OK, no that's fine, no need to squash them together then.
> >>
> >>> - Then at patch 11 "mtd: nand: omap: Clean up device tree support" we break NAND on all DT
> >>> boards as we expect NAND to be a real child node with compatible id. Simply applying the
> >>> DT patch at this point makes it work again.
> >>
> >> Hmm can we at least warn about incompatible DT entry when somebody boots
> >> with an older dtb?
> > 
> > Yes that could be done. It looks like we can use the missing compatible property to identify
> > that it is and old DT entry.
> > 
> > I'll send a v4 of patch 11.
> 
> There is another issue. Some of the old DT nodes set the NAND IO address to 0.
> As we prevent mapping into first 16MB we see the following message for those nodes. e.g. dra7-evm
> 
> [    1.727598] omap-gpmc 50000000.gpmc: cannot remap GPMC CS 0 to 0x00000000
> [    1.727605] omap-gpmc 50000000.gpmc: GPMC CS 0 start cannot be lesser than 0x1000000
> [    1.727611] omap-gpmc 50000000.gpmc: failed to probe DT children
> 
> Hope this is good enough information that DT needs to be updated?

Yes I think that should allow users update the out of tree dts file
easily.

Regards,

Tony

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-06 11:01             ` Tony Lindgren
@ 2015-10-06 11:09               ` Roger Quadros
  2015-10-16 21:25                 ` Tony Lindgren
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-06 11:09 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree, linux-omap, nsekhar, linux-kernel, linux-mtd,
	ezequiel, javier, computersforpeace, dwmw2, fcooper

On 06/10/15 14:01, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [151006 03:32]:
>> On 06/10/15 13:05, Roger Quadros wrote:
>>> On 06/10/15 13:00, Tony Lindgren wrote:
>>>> * Roger Quadros <rogerq@ti.com> [151006 02:59]:
>>>>> On 06/10/15 11:33, Tony Lindgren wrote:
>>>>>> Does build and boot and use NAND work throughtout the series?
>>>>>> Otherwise we'll have hard time bisecting anything..
>>>>>
>>>>> Yes it does with the following exceptions.
>>>>>
>>>>> - Patch 7 "memory: omap-gpmc: Remove NAND IRQ code" breaks prefetch-irq mode
>>>>> but none of the boards seem to be using it so it shouldn't break NAND on existing boards.
>>>>> At patch 9 "mtd: nand: omap2: manage NAND interrupts" prefetch-irq mode is working again.
>>>>> Do you want me to squash patches 7,8,9 so that pre-fetch irq is not broken at any point?
>>>>
>>>> OK, no that's fine, no need to squash them together then.
>>>>
>>>>> - Then at patch 11 "mtd: nand: omap: Clean up device tree support" we break NAND on all DT
>>>>> boards as we expect NAND to be a real child node with compatible id. Simply applying the
>>>>> DT patch at this point makes it work again.
>>>>
>>>> Hmm can we at least warn about incompatible DT entry when somebody boots
>>>> with an older dtb?
>>>
>>> Yes that could be done. It looks like we can use the missing compatible property to identify
>>> that it is and old DT entry.
>>>
>>> I'll send a v4 of patch 11.
>>
>> There is another issue. Some of the old DT nodes set the NAND IO address to 0.
>> As we prevent mapping into first 16MB we see the following message for those nodes. e.g. dra7-evm
>>
>> [    1.727598] omap-gpmc 50000000.gpmc: cannot remap GPMC CS 0 to 0x00000000
>> [    1.727605] omap-gpmc 50000000.gpmc: GPMC CS 0 start cannot be lesser than 0x1000000
>> [    1.727611] omap-gpmc 50000000.gpmc: failed to probe DT children
>>
>> Hope this is good enough information that DT needs to be updated?
> 
> Yes I think that should allow users update the out of tree dts file
> easily.

Fine. The updated series is now at

git@github.com:rogerq/linux.git
 * [new branch]      for-v4.4/gpmc-v4

cheers,
-roger

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

* Re: [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes
  2015-09-18 14:53 ` [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes Roger Quadros
@ 2015-10-13  0:43   ` Tony Lindgren
  2015-10-13  6:29     ` Roger Quadros
  2015-10-14  8:55   ` [PATCH v4 " Roger Quadros
  1 sibling, 1 reply; 79+ messages in thread
From: Tony Lindgren @ 2015-10-13  0:43 UTC (permalink / raw)
  To: Roger Quadros
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

* Roger Quadros <rogerq@ti.com> [150918 08:00]:
> Add compatible id, GPMC register resource and interrupt
> resource to NAND controller nodes.
> 
> The GPMC driver now implements gpiochip and irqchip so
> enable gpio-controller and interrupt-controller properties.
> 
> With this the interrupt parent of NAND node changes so fix it
> accordingly.
...
> --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
> +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
> @@ -35,11 +35,14 @@
>  };
>  
>  &gpmc {
> -	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
> +	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
>  
>  	nand@0,0 {
> -		linux,mtd-name = "micron,mt29f4g16abbda3w";
> +		compatible = "ti,omap2-nand";
>  		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
> +		interrupt-parent = <&intc>;
> +		interrupts = <20>;
> +		linux,mtd-name = "micron,mt29f4g16abbda3w";
>  		nand-bus-width = <16>;
>  		ti,nand-ecc-opt = "bch8";
>  		gpmc,sync-clk-ps = <0>;

At least torpedo breaks for NFSroot as NAND now overlaps with
Ethernet.. What's the policy you have for moving the addresses
around?

There may be other similar cases to check too.

Regards,

Tony

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

* Re: [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes
  2015-10-13  0:43   ` Tony Lindgren
@ 2015-10-13  6:29     ` Roger Quadros
  2015-10-13 15:18       ` Tony Lindgren
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-13  6:29 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

On 13/10/15 03:43, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [150918 08:00]:
>> Add compatible id, GPMC register resource and interrupt
>> resource to NAND controller nodes.
>>
>> The GPMC driver now implements gpiochip and irqchip so
>> enable gpio-controller and interrupt-controller properties.
>>
>> With this the interrupt parent of NAND node changes so fix it
>> accordingly.
> ...
>> --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
>> +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
>> @@ -35,11 +35,14 @@
>>  };
>>  
>>  &gpmc {
>> -	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
>> +	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
>>  
>>  	nand@0,0 {
>> -		linux,mtd-name = "micron,mt29f4g16abbda3w";
>> +		compatible = "ti,omap2-nand";
>>  		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
>> +		interrupt-parent = <&intc>;
>> +		interrupts = <20>;
>> +		linux,mtd-name = "micron,mt29f4g16abbda3w";
>>  		nand-bus-width = <16>;
>>  		ti,nand-ecc-opt = "bch8";
>>  		gpmc,sync-clk-ps = <0>;
> 
> At least torpedo breaks for NFSroot as NAND now overlaps with
> Ethernet.. What's the policy you have for moving the addresses
> around?

For OMAP3 I intended to use 0x30000000 for NAND but incorrectly
used 0x08000000 for the torpedo.

Does setting it to 0x30000000 work? If not what is the original
NAND address for this board?

> 
> There may be other similar cases to check too.

Just checked that all other OMAP3 boards I've set to 0x30000000
if they were 0x0.

cheers,
-roger

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

* Re: [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes
  2015-10-13  6:29     ` Roger Quadros
@ 2015-10-13 15:18       ` Tony Lindgren
  2015-10-14  7:39         ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Tony Lindgren @ 2015-10-13 15:18 UTC (permalink / raw)
  To: Roger Quadros
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

* Roger Quadros <rogerq@ti.com> [151012 23:33]:
> On 13/10/15 03:43, Tony Lindgren wrote:
> > * Roger Quadros <rogerq@ti.com> [150918 08:00]:
> >> Add compatible id, GPMC register resource and interrupt
> >> resource to NAND controller nodes.
> >>
> >> The GPMC driver now implements gpiochip and irqchip so
> >> enable gpio-controller and interrupt-controller properties.
> >>
> >> With this the interrupt parent of NAND node changes so fix it
> >> accordingly.
> > ...
> >> --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
> >> +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
> >> @@ -35,11 +35,14 @@
> >>  };
> >>  
> >>  &gpmc {
> >> -	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
> >> +	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
> >>  
> >>  	nand@0,0 {
> >> -		linux,mtd-name = "micron,mt29f4g16abbda3w";
> >> +		compatible = "ti,omap2-nand";
> >>  		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
> >> +		interrupt-parent = <&intc>;
> >> +		interrupts = <20>;
> >> +		linux,mtd-name = "micron,mt29f4g16abbda3w";
> >>  		nand-bus-width = <16>;
> >>  		ti,nand-ecc-opt = "bch8";
> >>  		gpmc,sync-clk-ps = <0>;
> > 
> > At least torpedo breaks for NFSroot as NAND now overlaps with
> > Ethernet.. What's the policy you have for moving the addresses
> > around?
> 
> For OMAP3 I intended to use 0x30000000 for NAND but incorrectly
> used 0x08000000 for the torpedo.

Might be worth adding some documentation of suggested standardized
mappings.. For most of theme we could just add them as 16MB chunks,
then reserve some larger area for NOR?

> Does setting it to 0x30000000 work? If not what is the original
> NAND address for this board?

The u-boot addresses are probably what were used in the .dts* files.
Setting NAND to 0x30000000 is not enough though, looks like there's
a bug where the logicpd-torpedo-37xx-devkit.dts ranges is missing
the NAND range in logicpd-torpedo-som.dtsi. Something like the
patch below seems to make things work again, might be worth
checking what ranges make sense to standardize on though. Please
feel free to fold it into your patches.

> > There may be other similar cases to check too.
> 
> Just checked that all other OMAP3 boards I've set to 0x30000000
> if they were 0x0.

Do you want to reserve a large chunk for NOR at cs0 or what's
the reason for picking 0x30000000 for NAND?

I guess NOR can be also on other chipselects.. Not sure we can
standardize on any specific partition scheme?

Regards,

Tony

8< --------------------
--- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
+++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
@@ -73,7 +73,8 @@
 };
 
 &gpmc {
-	ranges = <1 0 0x08000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
+	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
+		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
 
 	ethernet@gpmc {
 		pinctrl-names = "default";
--- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
@@ -35,7 +35,7 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x30000000 0x1000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
 		compatible = "ti,omap2-nand";

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

* Re: [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes
  2015-10-13 15:18       ` Tony Lindgren
@ 2015-10-14  7:39         ` Roger Quadros
  0 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-10-14  7:39 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

Tony,

On 13/10/15 18:18, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [151012 23:33]:
>> On 13/10/15 03:43, Tony Lindgren wrote:
>>> * Roger Quadros <rogerq@ti.com> [150918 08:00]:
>>>> Add compatible id, GPMC register resource and interrupt
>>>> resource to NAND controller nodes.
>>>>
>>>> The GPMC driver now implements gpiochip and irqchip so
>>>> enable gpio-controller and interrupt-controller properties.
>>>>
>>>> With this the interrupt parent of NAND node changes so fix it
>>>> accordingly.
>>> ...
>>>> --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
>>>> +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
>>>> @@ -35,11 +35,14 @@
>>>>  };
>>>>  
>>>>  &gpmc {
>>>> -	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
>>>> +	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
>>>>  
>>>>  	nand@0,0 {
>>>> -		linux,mtd-name = "micron,mt29f4g16abbda3w";
>>>> +		compatible = "ti,omap2-nand";
>>>>  		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
>>>> +		interrupt-parent = <&intc>;
>>>> +		interrupts = <20>;
>>>> +		linux,mtd-name = "micron,mt29f4g16abbda3w";
>>>>  		nand-bus-width = <16>;
>>>>  		ti,nand-ecc-opt = "bch8";
>>>>  		gpmc,sync-clk-ps = <0>;
>>>
>>> At least torpedo breaks for NFSroot as NAND now overlaps with
>>> Ethernet.. What's the policy you have for moving the addresses
>>> around?
>>
>> For OMAP3 I intended to use 0x30000000 for NAND but incorrectly
>> used 0x08000000 for the torpedo.
> 
> Might be worth adding some documentation of suggested standardized
> mappings.. For most of theme we could just add them as 16MB chunks,
> then reserve some larger area for NOR?

As GPMC peripherals are not plug and play the GPMC map is specific to
the board and need not necessarily apply to all boards.
So I don't think we need to have any standardized mappings.

> 
>> Does setting it to 0x30000000 work? If not what is the original
>> NAND address for this board?
> 
> The u-boot addresses are probably what were used in the .dts* files.
> Setting NAND to 0x30000000 is not enough though, looks like there's
> a bug where the logicpd-torpedo-37xx-devkit.dts ranges is missing
> the NAND range in logicpd-torpedo-som.dtsi. Something like the
> patch below seems to make things work again, might be worth
> checking what ranges make sense to standardize on though. Please
> feel free to fold it into your patches.

Thanks. I'll post a revised patch.

> 
>>> There may be other similar cases to check too.
>>
>> Just checked that all other OMAP3 boards I've set to 0x30000000
>> if they were 0x0.
> 
> Do you want to reserve a large chunk for NOR at cs0 or what's
> the reason for picking 0x30000000 for NAND?

All of the OMAP3 boards were using 0x30000000. Probably copy paste effect? :)
What's the point of reserving anything for NOR. If the board doesn't already
have NOR it never will. Future board having NOR can have its own GPMC map.
> 
> I guess NOR can be also on other chipselects.. Not sure we can
> standardize on any specific partition scheme?

Exactly.

cheers,
-roger

> 
> Regards,
> 
> Tony
> 
> 8< --------------------
> --- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
> +++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
> @@ -73,7 +73,8 @@
>  };
>  
>  &gpmc {
> -	ranges = <1 0 0x08000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
> +	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
> +		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
>  
>  	ethernet@gpmc {
>  		pinctrl-names = "default";
> --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
> +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
> @@ -35,7 +35,7 @@
>  };
>  
>  &gpmc {
> -	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
> +	ranges = <0 0 0x30000000 0x1000000>;	/* CS0: 16MB for NAND */
>  
>  	nand@0,0 {
>  		compatible = "ti,omap2-nand";
> 

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

* [PATCH v4 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes
  2015-09-18 14:53 ` [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes Roger Quadros
  2015-10-13  0:43   ` Tony Lindgren
@ 2015-10-14  8:55   ` Roger Quadros
  1 sibling, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-10-14  8:55 UTC (permalink / raw)
  To: tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, rogerq

Add compatible id, GPMC register resource and interrupt
resource to NAND controller nodes.

The GPMC driver now implements gpiochip and irqchip so
enable gpio-controller and interrupt-controller properties.

With this the interrupt parent of NAND node changes so fix it
accordingly.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---

v4: Applied Tony's patch to fix broken ethernet on torpedo.

updated v4 series available at

git@github.com:rogerq/linux.git
 * [branch]      for-v4.4/gpmc-v4

 arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts | 3 ++-
 arch/arm/boot/dts/logicpd-torpedo-som.dtsi        | 7 +++++--
 arch/arm/boot/dts/omap3-beagle.dts                | 2 ++
 arch/arm/boot/dts/omap3-cm-t3x.dtsi               | 5 ++++-
 arch/arm/boot/dts/omap3-devkit8000-common.dtsi    | 3 +++
 arch/arm/boot/dts/omap3-evm-37xx.dts              | 7 +++++--
 arch/arm/boot/dts/omap3-gta04.dtsi                | 3 +++
 arch/arm/boot/dts/omap3-igep.dtsi                 | 5 ++++-
 arch/arm/boot/dts/omap3-igep0020-common.dtsi      | 4 ++--
 arch/arm/boot/dts/omap3-igep0030-common.dtsi      | 4 ++++
 arch/arm/boot/dts/omap3-ldp.dts                   | 9 ++++++---
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi           | 5 ++++-
 arch/arm/boot/dts/omap3-pandora-common.dtsi       | 3 +++
 arch/arm/boot/dts/omap3-tao3530.dtsi              | 5 ++++-
 arch/arm/boot/dts/omap3.dtsi                      | 4 ++++
 arch/arm/boot/dts/omap3430-sdp.dts                | 5 ++++-
 16 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
index 91146c3..20e157d 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
+++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
@@ -73,7 +73,8 @@
 };
 
 &gpmc {
-	ranges = <1 0 0x08000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
+	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
+		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
 
 	ethernet@gpmc {
 		pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
index 36387b1..f108e55 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
@@ -35,11 +35,14 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x30000000 0x1000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
-		linux,mtd-name = "micron,mt29f4g16abbda3w";
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
+		linux,mtd-name = "micron,mt29f4g16abbda3w";
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,sync-clk-ps = <0>;
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index 67659a0..9b145dd 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -384,7 +384,9 @@
 
 	/* Chip select 0 */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;		/* NAND I/O window, 4 bytes */
+		interrupt-parent = <&intc>;
 		interrupts = <20>;
 		ti,nand-ecc-opt = "ham1";
 		nand-bus-width = <16>;
diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
index 4d091ca..e9d7e28 100644
--- a/arch/arm/boot/dts/omap3-cm-t3x.dtsi
+++ b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
@@ -261,10 +261,13 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <8>;
 		gpmc,device-width = <1>;
 		ti,nand-ecc-opt = "sw";
diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
index 9ca2865..e7b46ad 100644
--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
@@ -204,7 +204,10 @@
 	ranges = <0 0 0x30000000 0x1000000>;       /* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "sw";
diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts
index 16e8ce3..7081e07 100644
--- a/arch/arm/boot/dts/omap3-evm-37xx.dts
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -154,12 +154,15 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>,	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x30000000 0x1000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		linux,mtd-name= "hynix,h8kds0un0mer-4em";
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi
index 7166d88..4c48b31 100644
--- a/arch/arm/boot/dts/omap3-gta04.dtsi
+++ b/arch/arm/boot/dts/omap3-gta04.dtsi
@@ -492,7 +492,10 @@
 	ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 
diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
index 2230e1c..d4dff72 100644
--- a/arch/arm/boot/dts/omap3-igep.dtsi
+++ b/arch/arm/boot/dts/omap3-igep.dtsi
@@ -95,8 +95,11 @@
 
 &gpmc {
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		linux,mtd-name= "micron,mt29c4g96maz";
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
diff --git a/arch/arm/boot/dts/omap3-igep0020-common.dtsi b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
index 5ad688c..eecd7a8 100644
--- a/arch/arm/boot/dts/omap3-igep0020-common.dtsi
+++ b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
@@ -210,8 +210,8 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x20000000>,
-		 <5 0 0x2c000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x01000000>,	/* CS0: 16MB for NAND */
+		 <5 0 0x2c000000 0x01000000>;	/* CS5: 16MB for ethernet */
 
 	ethernet@gpmc {
 		pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/omap3-igep0030-common.dtsi b/arch/arm/boot/dts/omap3-igep0030-common.dtsi
index 0cb1527..c5d8210 100644
--- a/arch/arm/boot/dts/omap3-igep0030-common.dtsi
+++ b/arch/arm/boot/dts/omap3-igep0030-common.dtsi
@@ -58,3 +58,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart2_pins>;
 };
+
+&gpmc {
+	ranges = <0 0 0x30000000 0x01000000>;   /* CS0: 16MB for NAND */
+};
diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts
index bd6e676..fb86131 100644
--- a/arch/arm/boot/dts/omap3-ldp.dts
+++ b/arch/arm/boot/dts/omap3-ldp.dts
@@ -97,12 +97,15 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x01000000>,
-		 <1 0 0x08000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x1000000>,	/* CS0 space, 16MB */
+		 <1 0 0x08000000 0x1000000>;	/* CS1 space, 16MB */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		linux,mtd-name= "micron,nand";
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
diff --git a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
index d0dd036..abc39f4 100644
--- a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
+++ b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
@@ -362,7 +362,10 @@
 		<7 0 0x15000000 0x01000000>;
 
 	nand@0,0 {
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 		/* no elm on omap3 */
diff --git a/arch/arm/boot/dts/omap3-pandora-common.dtsi b/arch/arm/boot/dts/omap3-pandora-common.dtsi
index f2084e6..11ada97 100644
--- a/arch/arm/boot/dts/omap3-pandora-common.dtsi
+++ b/arch/arm/boot/dts/omap3-pandora-common.dtsi
@@ -546,7 +546,10 @@
 	ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "sw";
 
diff --git a/arch/arm/boot/dts/omap3-tao3530.dtsi b/arch/arm/boot/dts/omap3-tao3530.dtsi
index 7bd8d9a..838e0da 100644
--- a/arch/arm/boot/dts/omap3-tao3530.dtsi
+++ b/arch/arm/boot/dts/omap3-tao3530.dtsi
@@ -275,10 +275,13 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;	/* GPMC_DEVWIDTH_16BIT */
 		ti,nand-ecc-opt = "sw";
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 8a2b253..7f212b6 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -721,6 +721,10 @@
 			gpmc,num-waitpins = <4>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 		};
 
 		usb_otg_hs: usb_otg_hs@480ab000 {
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index 16b0cdf..3f113c5 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -103,10 +103,13 @@
 	};
 
 	nand@1,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
 		linux,mtd-name= "micron,mt29f1g08abb";
 		#address-cells = <1>;
 		#size-cells = <1>;
-		reg = <1 0 4>;	/* CS1, offset 0, IO size 4 */
 		ti,nand-ecc-opt = "sw";
 		nand-bus-width = <8>;
 		gpmc,cs-on-ns = <0>;
-- 
2.1.4



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

* Re: [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes.
  2015-09-18 14:53 ` [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes Roger Quadros
@ 2015-10-14 13:34   ` Franklin S Cooper Jr.
  2015-10-14 14:17     ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Franklin S Cooper Jr. @ 2015-10-14 13:34 UTC (permalink / raw)
  To: Roger Quadros, tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel



On 09/18/2015 09:53 AM, Roger Quadros wrote:
> Add compatible id, GPMC register resource and interrupt
> resource to NAND controller nodes.
>
> The GPMC driver now implements gpiochip and irqchip so
> enable gpio-controller and interrupt-controller properties.
>
> With this the interrupt parent of NAND node changes so fix it
> accordingly.
>
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  arch/arm/boot/dts/dra7-evm.dts  | 5 ++++-
>  arch/arm/boot/dts/dra7.dtsi     | 4 ++++
>  arch/arm/boot/dts/dra72-evm.dts | 5 ++++-
>  3 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
> index a6c82e5..8a31161 100644
> --- a/arch/arm/boot/dts/dra7-evm.dts
> +++ b/arch/arm/boot/dts/dra7-evm.dts
> @@ -585,9 +585,12 @@
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&nand_flash_x16>;
> -	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
> +	ranges = <0 0 0x08000000 0x01000000>;	/* minimum GPMC partition = 16MB */
>  	nand@0,0 {
> +		compatible = "ti,omap2-nand";
>  		reg = <0 0 4>;		/* device IO registers */
> +		interrupt-parent = <&crossbar_mpu>;
> +		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>  		ti,nand-ecc-opt = "bch8";
>  		ti,elm-id = <&elm>;
>  		nand-bus-width = <16>;
> diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
> index 5d65db9..f0a3616 100644
> --- a/arch/arm/boot/dts/dra7.dtsi
> +++ b/arch/arm/boot/dts/dra7.dtsi
> @@ -1389,6 +1389,10 @@
>  			gpmc,num-waitpins = <2>;
>  			#address-cells = <2>;
>  			#size-cells = <1>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
>  			status = "disabled";
>  		};
Based on the discussion on my patchset I noticed that the nand node defines the
interrupt but it is also defined in the parent node. Similar to the dma channel we
should conclude where the best place for it to be defined.  But to me it seems at
least it should only be defined once.

This is true for your other patches making similar changes to the dt.
>  
> diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
> index 6f6bd98..245f5f9 100644
> --- a/arch/arm/boot/dts/dra72-evm.dts
> +++ b/arch/arm/boot/dts/dra72-evm.dts
> @@ -395,13 +395,16 @@
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&nand_default>;
> -	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
> +	ranges = <0 0 0x08000000 0x01000000>;	/* minimum GPMC partition = 16MB */
>  	nand@0,0 {
>  		/* To use NAND, DIP switch SW5 must be set like so:
>  		 * SW5.1 (NAND_SELn) = ON (LOW)
>  		 * SW5.9 (GPMC_WPN) = OFF (HIGH)
>  		 */
> +		compatible = "ti,omap2-nand";
>  		reg = <0 0 4>;		/* device IO registers */
> +		interrupt-parent = <&crossbar_mpu>;
> +		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>  		ti,nand-ecc-opt = "bch8";
>  		ti,elm-id = <&elm>;
>  		nand-bus-width = <16>;


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

* Re: [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes.
  2015-10-14 13:34   ` Franklin S Cooper Jr.
@ 2015-10-14 14:17     ` Roger Quadros
  2015-10-14 14:37       ` Franklin S Cooper Jr.
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-14 14:17 UTC (permalink / raw)
  To: Franklin S Cooper Jr., tony
  Cc: dwmw2, computersforpeace, ezequiel, javier, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

On 14/10/15 16:34, Franklin S Cooper Jr. wrote:
> 
> 
> On 09/18/2015 09:53 AM, Roger Quadros wrote:
>> Add compatible id, GPMC register resource and interrupt
>> resource to NAND controller nodes.
>>
>> The GPMC driver now implements gpiochip and irqchip so
>> enable gpio-controller and interrupt-controller properties.
>>
>> With this the interrupt parent of NAND node changes so fix it
>> accordingly.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  arch/arm/boot/dts/dra7-evm.dts  | 5 ++++-
>>  arch/arm/boot/dts/dra7.dtsi     | 4 ++++
>>  arch/arm/boot/dts/dra72-evm.dts | 5 ++++-
>>  3 files changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
>> index a6c82e5..8a31161 100644
>> --- a/arch/arm/boot/dts/dra7-evm.dts
>> +++ b/arch/arm/boot/dts/dra7-evm.dts
>> @@ -585,9 +585,12 @@
>>  	status = "okay";
>>  	pinctrl-names = "default";
>>  	pinctrl-0 = <&nand_flash_x16>;
>> -	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
>> +	ranges = <0 0 0x08000000 0x01000000>;	/* minimum GPMC partition = 16MB */
>>  	nand@0,0 {
>> +		compatible = "ti,omap2-nand";
>>  		reg = <0 0 4>;		/* device IO registers */
>> +		interrupt-parent = <&crossbar_mpu>;
>> +		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>>  		ti,nand-ecc-opt = "bch8";
>>  		ti,elm-id = <&elm>;
>>  		nand-bus-width = <16>;
>> diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
>> index 5d65db9..f0a3616 100644
>> --- a/arch/arm/boot/dts/dra7.dtsi
>> +++ b/arch/arm/boot/dts/dra7.dtsi
>> @@ -1389,6 +1389,10 @@
>>  			gpmc,num-waitpins = <2>;
>>  			#address-cells = <2>;
>>  			#size-cells = <1>;
>> +			gpio-controller;
>> +			#gpio-cells = <2>;
>> +			interrupt-controller;
>> +			#interrupt-cells = <2>;
>>  			status = "disabled";
>>  		};
> Based on the discussion on my patchset I noticed that the nand node defines the
> interrupt but it is also defined in the parent node. Similar to the dma channel we
> should conclude where the best place for it to be defined.  But to me it seems at
> least it should only be defined once.

The interrupt is defined at both places because it is used at both places.
It is used as a shared interrupt. Wait_pin interrupts are managed by the
gpmc driver and NAND specific interrupts are managed by the NAND driver.

If GPMC dma channel is going to be used only by the NAND driver then
we should define the channel in the NAND node.

> 
> This is true for your other patches making similar changes to the dt.

Yes, GPMC IRQ is defined in both GPMC and NAND nodes.

--
cheers,
-roger

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

* Re: [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes.
  2015-10-14 14:17     ` Roger Quadros
@ 2015-10-14 14:37       ` Franklin S Cooper Jr.
  0 siblings, 0 replies; 79+ messages in thread
From: Franklin S Cooper Jr. @ 2015-10-14 14:37 UTC (permalink / raw)
  To: Roger Quadros
  Cc: dwmw2, computersforpeace, ezequiel, javier, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel, tony



On 10/14/2015 09:17 AM, Roger Quadros wrote:
> On 14/10/15 16:34, Franklin S Cooper Jr. wrote:
>>
>> On 09/18/2015 09:53 AM, Roger Quadros wrote:
>>> Add compatible id, GPMC register resource and interrupt
>>> resource to NAND controller nodes.
>>>
>>> The GPMC driver now implements gpiochip and irqchip so
>>> enable gpio-controller and interrupt-controller properties.
>>>
>>> With this the interrupt parent of NAND node changes so fix it
>>> accordingly.
>>>
>>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>>> ---
>>>  arch/arm/boot/dts/dra7-evm.dts  | 5 ++++-
>>>  arch/arm/boot/dts/dra7.dtsi     | 4 ++++
>>>  arch/arm/boot/dts/dra72-evm.dts | 5 ++++-
>>>  3 files changed, 12 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
>>> index a6c82e5..8a31161 100644
>>> --- a/arch/arm/boot/dts/dra7-evm.dts
>>> +++ b/arch/arm/boot/dts/dra7-evm.dts
>>> @@ -585,9 +585,12 @@
>>>  	status = "okay";
>>>  	pinctrl-names = "default";
>>>  	pinctrl-0 = <&nand_flash_x16>;
>>> -	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
>>> +	ranges = <0 0 0x08000000 0x01000000>;	/* minimum GPMC partition = 16MB */
>>>  	nand@0,0 {
>>> +		compatible = "ti,omap2-nand";
>>>  		reg = <0 0 4>;		/* device IO registers */
>>> +		interrupt-parent = <&crossbar_mpu>;
>>> +		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>>>  		ti,nand-ecc-opt = "bch8";
>>>  		ti,elm-id = <&elm>;
>>>  		nand-bus-width = <16>;
>>> diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
>>> index 5d65db9..f0a3616 100644
>>> --- a/arch/arm/boot/dts/dra7.dtsi
>>> +++ b/arch/arm/boot/dts/dra7.dtsi
>>> @@ -1389,6 +1389,10 @@
>>>  			gpmc,num-waitpins = <2>;
>>>  			#address-cells = <2>;
>>>  			#size-cells = <1>;
>>> +			gpio-controller;
>>> +			#gpio-cells = <2>;
>>> +			interrupt-controller;
>>> +			#interrupt-cells = <2>;
>>>  			status = "disabled";
>>>  		};
>> Based on the discussion on my patchset I noticed that the nand node defines the
>> interrupt but it is also defined in the parent node. Similar to the dma channel we
>> should conclude where the best place for it to be defined.  But to me it seems at
>> least it should only be defined once.
> The interrupt is defined at both places because it is used at both places.
> It is used as a shared interrupt. Wait_pin interrupts are managed by the
> gpmc driver and NAND specific interrupts are managed by the NAND driver.
>
> If GPMC dma channel is going to be used only by the NAND driver then
> we should define the channel in the NAND node.
>
>> This is true for your other patches making similar changes to the dt.
> Yes, GPMC IRQ is defined in both GPMC and NAND nodes.
Ok. I would still think you would just reuse the entry from the
parent since you know it will always be the same. But we can
go with what Tony thinks is best.
>
> --
> cheers,
> -roger


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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-06 11:09               ` Roger Quadros
@ 2015-10-16 21:25                 ` Tony Lindgren
  2015-10-19  7:08                   ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Tony Lindgren @ 2015-10-16 21:25 UTC (permalink / raw)
  To: Roger Quadros
  Cc: devicetree, linux-omap, nsekhar, linux-kernel, linux-mtd,
	ezequiel, javier, computersforpeace, dwmw2, fcooper

* Roger Quadros <rogerq@ti.com> [151006 04:13]:
> 
> Fine. The updated series is now at
> 
> git@github.com:rogerq/linux.git
>  * [new branch]      for-v4.4/gpmc-v4

Looks like it produces some build errors, this with RMKs 3430 and 4430
only .configs:

drivers/memory/omap-gpmc.c:2035:43: error: ‘struct gpio_chip’ has no
member named ‘irqdomain’
drivers/memory/omap-gpmc.c:2116:8: error: implicit declaration of
function ‘gpiochip_irqchip_add’ [-Werror=implicit-function-declaration]

Maybe run randconfig builds on it for overnight?

Other than that your series seems to behave for me now, so feel
free to add:

Acked-by: Tony Lindgren <tony@atomide.com>

Regards,

Tony

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-16 21:25                 ` Tony Lindgren
@ 2015-10-19  7:08                   ` Roger Quadros
  2015-10-21  8:31                     ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-19  7:08 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree, linux-omap, nsekhar, linux-kernel, linux-mtd,
	ezequiel, javier, computersforpeace, dwmw2, fcooper

On 17/10/15 00:25, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [151006 04:13]:
>>
>> Fine. The updated series is now at
>>
>> git@github.com:rogerq/linux.git
>>  * [new branch]      for-v4.4/gpmc-v4
> 
> Looks like it produces some build errors, this with RMKs 3430 and 4430
> only .configs:
> 
> drivers/memory/omap-gpmc.c:2035:43: error: ‘struct gpio_chip’ has no
> member named ‘irqdomain’
> drivers/memory/omap-gpmc.c:2116:8: error: implicit declaration of
> function ‘gpiochip_irqchip_add’ [-Werror=implicit-function-declaration]
> 

Good catch. We'll have to select GPIOLIB_IRQCHIP for this driver.

> Maybe run randconfig builds on it for overnight?

OK. I'll do that.

> 
> Other than that your series seems to behave for me now, so feel
> free to add:
> 
> Acked-by: Tony Lindgren <tony@atomide.com>

Thanks for the tests :)

cheers,
-roger

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-19  7:08                   ` Roger Quadros
@ 2015-10-21  8:31                     ` Roger Quadros
  2015-10-21 15:20                       ` Tony Lindgren
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-21  8:31 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree, linux-omap, nsekhar, linux-kernel, linux-mtd,
	ezequiel, javier, computersforpeace, dwmw2, fcooper

On 19/10/15 10:08, Roger Quadros wrote:
> On 17/10/15 00:25, Tony Lindgren wrote:
>> * Roger Quadros <rogerq@ti.com> [151006 04:13]:
>>>
>>> Fine. The updated series is now at
>>>
>>> git@github.com:rogerq/linux.git
>>>  * [new branch]      for-v4.4/gpmc-v4
>>
>> Looks like it produces some build errors, this with RMKs 3430 and 4430
>> only .configs:
>>
>> drivers/memory/omap-gpmc.c:2035:43: error: ‘struct gpio_chip’ has no
>> member named ‘irqdomain’
>> drivers/memory/omap-gpmc.c:2116:8: error: implicit declaration of
>> function ‘gpiochip_irqchip_add’ [-Werror=implicit-function-declaration]
>>
> 
> Good catch. We'll have to select GPIOLIB_IRQCHIP for this driver.
> 
>> Maybe run randconfig builds on it for overnight?
> 
> OK. I'll do that.

I couldn't run randconfig beyond few iterations as it keeps failing
everywhere. How do we limit the randconfig options to OMAP only
platforms?

cheers,
-roger

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-21  8:31                     ` Roger Quadros
@ 2015-10-21 15:20                       ` Tony Lindgren
  2015-10-23  7:09                         ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Tony Lindgren @ 2015-10-21 15:20 UTC (permalink / raw)
  To: Roger Quadros
  Cc: devicetree, linux-omap, nsekhar, linux-kernel, linux-mtd,
	ezequiel, javier, computersforpeace, dwmw2, fcooper

* Roger Quadros <rogerq@ti.com> [151021 01:31]:
> On 19/10/15 10:08, Roger Quadros wrote:
> > On 17/10/15 00:25, Tony Lindgren wrote:
> >> * Roger Quadros <rogerq@ti.com> [151006 04:13]:
> >>>
> >>> Fine. The updated series is now at
> >>>
> >>> git@github.com:rogerq/linux.git
> >>>  * [new branch]      for-v4.4/gpmc-v4
> >>
> >> Looks like it produces some build errors, this with RMKs 3430 and 4430
> >> only .configs:
> >>
> >> drivers/memory/omap-gpmc.c:2035:43: error: ‘struct gpio_chip’ has no
> >> member named ‘irqdomain’
> >> drivers/memory/omap-gpmc.c:2116:8: error: implicit declaration of
> >> function ‘gpiochip_irqchip_add’ [-Werror=implicit-function-declaration]
> >>
> > 
> > Good catch. We'll have to select GPIOLIB_IRQCHIP for this driver.
> > 
> >> Maybe run randconfig builds on it for overnight?
> > 
> > OK. I'll do that.
> 
> I couldn't run randconfig beyond few iterations as it keeps failing
> everywhere. How do we limit the randconfig options to OMAP only
> platforms?

You can use Felipe's scripts from github.

Regards,

Tony

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-21 15:20                       ` Tony Lindgren
@ 2015-10-23  7:09                         ` Roger Quadros
  2015-11-30 17:26                           ` Tony Lindgren
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-23  7:09 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree, linux-omap, nsekhar, linux-kernel, linux-mtd,
	ezequiel, javier, computersforpeace, dwmw2, fcooper

On 21/10/15 18:20, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [151021 01:31]:
>> On 19/10/15 10:08, Roger Quadros wrote:
>>> On 17/10/15 00:25, Tony Lindgren wrote:
>>>> * Roger Quadros <rogerq@ti.com> [151006 04:13]:
>>>>>
>>>>> Fine. The updated series is now at
>>>>>
>>>>> git@github.com:rogerq/linux.git
>>>>>  * [new branch]      for-v4.4/gpmc-v4
>>>>
>>>> Looks like it produces some build errors, this with RMKs 3430 and 4430
>>>> only .configs:
>>>>
>>>> drivers/memory/omap-gpmc.c:2035:43: error: ‘struct gpio_chip’ has no
>>>> member named ‘irqdomain’
>>>> drivers/memory/omap-gpmc.c:2116:8: error: implicit declaration of
>>>> function ‘gpiochip_irqchip_add’ [-Werror=implicit-function-declaration]
>>>>
>>>
>>> Good catch. We'll have to select GPIOLIB_IRQCHIP for this driver.
>>>
>>>> Maybe run randconfig builds on it for overnight?
>>>
>>> OK. I'll do that.
>>
>> I couldn't run randconfig beyond few iterations as it keeps failing
>> everywhere. How do we limit the randconfig options to OMAP only
>> platforms?
> 
> You can use Felipe's scripts from github.

Thanks. I used his scripts and ran 10 randconfigs per platform.
Didn't find any issues with this series.

How can we proceed?
Patches are on https://github.com/rogerq/linux/commits/for-v4.4/gpmc-v4

cheers,
-roger

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

* Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib
  2015-09-18 14:53 ` [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib Roger Quadros
@ 2015-10-26 20:49   ` Brian Norris
  2015-10-27  8:03     ` Roger Quadros
  2015-10-27  8:28     ` Boris Brezillon
  0 siblings, 2 replies; 79+ messages in thread
From: Brian Norris @ 2015-10-26 20:49 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel, Boris Brezillon,
	Alex Smith, Harvey Hunt

+ others

A few comments below.

On Fri, Sep 18, 2015 at 05:53:40PM +0300, Roger Quadros wrote:
> The GPMC WAIT pin status are now available over gpiolib.
> Update the omap_dev_ready() function to use gpio instead of
> directly accessing GPMC register space.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  drivers/mtd/nand/omap2.c                     | 29 +++++++++++++++++-----------
>  include/linux/platform_data/mtd-nand-omap2.h |  2 +-
>  2 files changed, 19 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 228f498..d0f2620 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -12,6 +12,7 @@
>  #include <linux/dmaengine.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/module.h>
>  #include <linux/interrupt.h>
>  #include <linux/jiffies.h>
> @@ -184,6 +185,8 @@ struct omap_nand_info {
>  	/* fields specific for BCHx_HW ECC scheme */
>  	struct device			*elm_dev;
>  	struct device_node		*of_node;
> +	/* NAND ready gpio */
> +	struct gpio_desc		*ready_gpiod;
>  };
>  
>  /**
> @@ -1047,22 +1050,17 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
>  }
>  
>  /**
> - * omap_dev_ready - calls the platform specific dev_ready function
> + * omap_dev_ready - checks the NAND Ready GPIO line
>   * @mtd: MTD device structure
> + *
> + * Returns true if ready and false if busy.
>   */
>  static int omap_dev_ready(struct mtd_info *mtd)
>  {
> -	unsigned int val = 0;
>  	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
>  							mtd);
>  
> -	val = readl(info->reg.gpmc_status);
> -
> -	if ((val & 0x100) == 0x100) {
> -		return 1;
> -	} else {
> -		return 0;
> -	}
> +	return gpiod_get_value(info->ready_gpiod);
>  }
>  
>  /**
> @@ -1782,7 +1780,9 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		info->reg = pdata->reg;
>  		info->of_node = pdata->of_node;
>  		info->ecc_opt = pdata->ecc_opt;
> -		info->dev_ready	= pdata->dev_ready;
> +		if (pdata->dev_ready)
> +			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
> +
>  		info->xfer_type = pdata->xfer_type;
>  		info->devsize = pdata->devsize;
>  		info->elm_of_node = pdata->elm_of_node;
> @@ -1815,6 +1815,13 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
>  	nand_chip->cmd_ctrl  = omap_hwcontrol;
>  
> +	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "ready",
> +						    GPIOD_IN);

Others have been looking at using GPIOs for the ready/busy pin too. At a
minimum, we need an updated DT binding doc for this, since I see you're
adding this via device tree in a later patch (I don't see any DT binding
patch for this; but I could just be overlooking it). It'd also be great
if this support was moved to nand_dt_init() so other platforms can
benefit, but I won't require that.

Also, previous [0] proposers had suggested 'rb-gpios', not 'ready-gpio'
(the hardware docs typically call it 'rb' for ready/busy, FWIW). I don't
really care, but the name should be going into a doc, so we can choose
the same one everywhere.

EDIT: looks like the discussion was partly here [1] and it seems we're
landing on "rb-gpios" in the latest version [2]. Can we stick with that?

Regards,
Brian

[0] "Previous" may be subject to debate, as both series have been going
    for several revisions.
[1] http://patchwork.ozlabs.org/patch/515327/
[2] http://patchwork.ozlabs.org/patch/526819/

> +	if (IS_ERR(info->ready_gpiod)) {
> +		dev_err(dev, "failed to get ready gpio\n");
> +		return PTR_ERR(info->ready_gpiod);
> +	}
> +
>  	/*
>  	 * If RDY/BSY line is connected to OMAP then use the omap ready
>  	 * function and the generic nand_wait function which reads the status
> @@ -1822,7 +1829,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	 * chip delay which is slightly more than tR (AC Timing) of the NAND
>  	 * device and read status register until you get a failure or success
>  	 */
> -	if (info->dev_ready) {
> +	if (info->ready_gpiod) {
>  		nand_chip->dev_ready = omap_dev_ready;
>  		nand_chip->chip_delay = 0;
>  	} else {
> diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
> index ff27e5a..19e509d 100644
> --- a/include/linux/platform_data/mtd-nand-omap2.h
> +++ b/include/linux/platform_data/mtd-nand-omap2.h
> @@ -70,7 +70,6 @@ struct omap_nand_platform_data {
>  	int			cs;
>  	struct mtd_partition	*parts;
>  	int			nr_parts;
> -	bool			dev_ready;
>  	bool			flash_bbt;
>  	enum nand_io		xfer_type;
>  	int			devsize;
> @@ -81,5 +80,6 @@ struct omap_nand_platform_data {
>  	/* deprecated */
>  	struct gpmc_nand_regs	reg;
>  	struct device_node	*of_node;
> +	bool			dev_ready;
>  };
>  #endif
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (28 preceding siblings ...)
  2015-09-30 11:00 ` Roger Quadros
@ 2015-10-26 21:23 ` Brian Norris
  2015-10-27  9:37   ` Roger Quadros
  2015-12-03  5:09 ` Brian Norris
  30 siblings, 1 reply; 79+ messages in thread
From: Brian Norris @ 2015-10-26 21:23 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Hi Roger,

I'm not too familiar with OMAP platforms, and I might have missed out on
prior discussions/context, so please forgive if I'm asking silly or old
questions here.

On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
> This causes performance increase when using prefetch-irq mode.
> 30% increase in read, 17% increase in write in prefetch-irq mode.

Have you pinpointed the exact causes for the performance increase, or
can you give an educated guess? AIUI, you're reducing the number of
interrupts needed for NAND prefetch mode, but you're also removing a bit
of abstraction and implementing hooks that look awfully like the
existing abstractions:

+       int (*nand_irq_enable)(enum gpmc_nand_irq irq);
+       int (*nand_irq_disable)(enum gpmc_nand_irq irq);
+       void (*nand_irq_clear)(enum gpmc_nand_irq irq);
+       u32 (*nand_irq_status)(void);

That's not really a problem if there's a good reason for them (brcmnand
implements similar hooks because of quirks in the implementation of
interrupts across various BRCM SoCs, and it's not worth writing irqchip
drivers for those cases). I'm mainly curious for an explanation.

Regards,
Brian

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

* Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib
  2015-10-26 20:49   ` Brian Norris
@ 2015-10-27  8:03     ` Roger Quadros
  2015-10-27  8:12       ` Boris Brezillon
  2015-10-27  8:28     ` Boris Brezillon
  1 sibling, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-10-27  8:03 UTC (permalink / raw)
  To: Brian Norris
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel, Boris Brezillon,
	Alex Smith, Harvey Hunt

On 26/10/15 22:49, Brian Norris wrote:
> + others
> 
> A few comments below.
> 
> On Fri, Sep 18, 2015 at 05:53:40PM +0300, Roger Quadros wrote:
>> The GPMC WAIT pin status are now available over gpiolib.
>> Update the omap_dev_ready() function to use gpio instead of
>> directly accessing GPMC register space.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  drivers/mtd/nand/omap2.c                     | 29 +++++++++++++++++-----------
>>  include/linux/platform_data/mtd-nand-omap2.h |  2 +-
>>  2 files changed, 19 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
>> index 228f498..d0f2620 100644
>> --- a/drivers/mtd/nand/omap2.c
>> +++ b/drivers/mtd/nand/omap2.c
>> @@ -12,6 +12,7 @@
>>  #include <linux/dmaengine.h>
>>  #include <linux/dma-mapping.h>
>>  #include <linux/delay.h>
>> +#include <linux/gpio/consumer.h>
>>  #include <linux/module.h>
>>  #include <linux/interrupt.h>
>>  #include <linux/jiffies.h>
>> @@ -184,6 +185,8 @@ struct omap_nand_info {
>>  	/* fields specific for BCHx_HW ECC scheme */
>>  	struct device			*elm_dev;
>>  	struct device_node		*of_node;
>> +	/* NAND ready gpio */
>> +	struct gpio_desc		*ready_gpiod;
>>  };
>>  
>>  /**
>> @@ -1047,22 +1050,17 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
>>  }
>>  
>>  /**
>> - * omap_dev_ready - calls the platform specific dev_ready function
>> + * omap_dev_ready - checks the NAND Ready GPIO line
>>   * @mtd: MTD device structure
>> + *
>> + * Returns true if ready and false if busy.
>>   */
>>  static int omap_dev_ready(struct mtd_info *mtd)
>>  {
>> -	unsigned int val = 0;
>>  	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
>>  							mtd);
>>  
>> -	val = readl(info->reg.gpmc_status);
>> -
>> -	if ((val & 0x100) == 0x100) {
>> -		return 1;
>> -	} else {
>> -		return 0;
>> -	}
>> +	return gpiod_get_value(info->ready_gpiod);
>>  }
>>  
>>  /**
>> @@ -1782,7 +1780,9 @@ static int omap_nand_probe(struct platform_device *pdev)
>>  		info->reg = pdata->reg;
>>  		info->of_node = pdata->of_node;
>>  		info->ecc_opt = pdata->ecc_opt;
>> -		info->dev_ready	= pdata->dev_ready;
>> +		if (pdata->dev_ready)
>> +			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
>> +
>>  		info->xfer_type = pdata->xfer_type;
>>  		info->devsize = pdata->devsize;
>>  		info->elm_of_node = pdata->elm_of_node;
>> @@ -1815,6 +1815,13 @@ static int omap_nand_probe(struct platform_device *pdev)
>>  	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
>>  	nand_chip->cmd_ctrl  = omap_hwcontrol;
>>  
>> +	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "ready",
>> +						    GPIOD_IN);
> 
> Others have been looking at using GPIOs for the ready/busy pin too. At a
> minimum, we need an updated DT binding doc for this, since I see you're
> adding this via device tree in a later patch (I don't see any DT binding
> patch for this; but I could just be overlooking it). It'd also be great
> if this support was moved to nand_dt_init() so other platforms can
> benefit, but I won't require that.
> 
> Also, previous [0] proposers had suggested 'rb-gpios', not 'ready-gpio'
> (the hardware docs typically call it 'rb' for ready/busy, FWIW). I don't
> really care, but the name should be going into a doc, so we can choose
> the same one everywhere.
> 
> EDIT: looks like the discussion was partly here [1] and it seems we're
> landing on "rb-gpios" in the latest version [2]. Can we stick with that?

Why should it be "rb-gpios" and not "rb-gpio"?
I don't think there are multiple gpios for r/b# function.

cheers,
-roger

> 
> Regards,
> Brian
> 
> [0] "Previous" may be subject to debate, as both series have been going
>     for several revisions.
> [1] http://patchwork.ozlabs.org/patch/515327/
> [2] http://patchwork.ozlabs.org/patch/526819/
> 
>> +	if (IS_ERR(info->ready_gpiod)) {
>> +		dev_err(dev, "failed to get ready gpio\n");
>> +		return PTR_ERR(info->ready_gpiod);
>> +	}
>> +
>>  	/*
>>  	 * If RDY/BSY line is connected to OMAP then use the omap ready
>>  	 * function and the generic nand_wait function which reads the status
>> @@ -1822,7 +1829,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>>  	 * chip delay which is slightly more than tR (AC Timing) of the NAND
>>  	 * device and read status register until you get a failure or success
>>  	 */
>> -	if (info->dev_ready) {
>> +	if (info->ready_gpiod) {
>>  		nand_chip->dev_ready = omap_dev_ready;
>>  		nand_chip->chip_delay = 0;
>>  	} else {
>> diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
>> index ff27e5a..19e509d 100644
>> --- a/include/linux/platform_data/mtd-nand-omap2.h
>> +++ b/include/linux/platform_data/mtd-nand-omap2.h
>> @@ -70,7 +70,6 @@ struct omap_nand_platform_data {
>>  	int			cs;
>>  	struct mtd_partition	*parts;
>>  	int			nr_parts;
>> -	bool			dev_ready;
>>  	bool			flash_bbt;
>>  	enum nand_io		xfer_type;
>>  	int			devsize;
>> @@ -81,5 +80,6 @@ struct omap_nand_platform_data {
>>  	/* deprecated */
>>  	struct gpmc_nand_regs	reg;
>>  	struct device_node	*of_node;
>> +	bool			dev_ready;
>>  };
>>  #endif
>> -- 
>> 2.1.4
>>

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

* Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib
  2015-10-27  8:03     ` Roger Quadros
@ 2015-10-27  8:12       ` Boris Brezillon
  2015-10-27  8:43         ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Boris Brezillon @ 2015-10-27  8:12 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Brian Norris, tony, dwmw2, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Alex Smith,
	Harvey Hunt

Hi Roger,

On Tue, 27 Oct 2015 10:03:02 +0200
Roger Quadros <rogerq@ti.com> wrote:

> On 26/10/15 22:49, Brian Norris wrote:
> > 
> > Others have been looking at using GPIOs for the ready/busy pin too. At a
> > minimum, we need an updated DT binding doc for this, since I see you're
> > adding this via device tree in a later patch (I don't see any DT binding
> > patch for this; but I could just be overlooking it). It'd also be great
> > if this support was moved to nand_dt_init() so other platforms can
> > benefit, but I won't require that.
> > 
> > Also, previous [0] proposers had suggested 'rb-gpios', not 'ready-gpio'
> > (the hardware docs typically call it 'rb' for ready/busy, FWIW). I don't
> > really care, but the name should be going into a doc, so we can choose
> > the same one everywhere.
> > 
> > EDIT: looks like the discussion was partly here [1] and it seems we're
> > landing on "rb-gpios" in the latest version [2]. Can we stick with that?
> 
> Why should it be "rb-gpios" and not "rb-gpio"?
> I don't think there are multiple gpios for r/b# function.

Because it's supposed to be a generic binding, and some NAND chips
embed several dies, thus exposing several CS and RB pins, hence the
rb-gpios name.
Also, as described here [1], the convention is to name your property
<name>-gpios even if you only need one gpio.

Best Regards,

Boris

[1]http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/gpio/gpio.txt#L16



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib
  2015-10-26 20:49   ` Brian Norris
  2015-10-27  8:03     ` Roger Quadros
@ 2015-10-27  8:28     ` Boris Brezillon
  2015-12-03  4:45       ` Brian Norris
  1 sibling, 1 reply; 79+ messages in thread
From: Boris Brezillon @ 2015-10-27  8:28 UTC (permalink / raw)
  To: Brian Norris
  Cc: Roger Quadros, tony, dwmw2, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Alex Smith,
	Harvey Hunt

Hi Brian,

On Mon, 26 Oct 2015 13:49:00 -0700
Brian Norris <computersforpeace@gmail.com> wrote:

> + others
> 
> A few comments below.
> 
> On Fri, Sep 18, 2015 at 05:53:40PM +0300, Roger Quadros wrote:
> > The GPMC WAIT pin status are now available over gpiolib.
> > Update the omap_dev_ready() function to use gpio instead of
> > directly accessing GPMC register space.
> > 
> > Signed-off-by: Roger Quadros <rogerq@ti.com>
> > ---
> >  drivers/mtd/nand/omap2.c                     | 29 +++++++++++++++++-----------
> >  include/linux/platform_data/mtd-nand-omap2.h |  2 +-
> >  2 files changed, 19 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> > index 228f498..d0f2620 100644
> > --- a/drivers/mtd/nand/omap2.c
> > +++ b/drivers/mtd/nand/omap2.c
> > @@ -12,6 +12,7 @@
> >  #include <linux/dmaengine.h>
> >  #include <linux/dma-mapping.h>
> >  #include <linux/delay.h>
> > +#include <linux/gpio/consumer.h>
> >  #include <linux/module.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/jiffies.h>
> > @@ -184,6 +185,8 @@ struct omap_nand_info {
> >  	/* fields specific for BCHx_HW ECC scheme */
> >  	struct device			*elm_dev;
> >  	struct device_node		*of_node;
> > +	/* NAND ready gpio */
> > +	struct gpio_desc		*ready_gpiod;
> >  };
> >  
> >  /**
> > @@ -1047,22 +1050,17 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
> >  }
> >  
> >  /**
> > - * omap_dev_ready - calls the platform specific dev_ready function
> > + * omap_dev_ready - checks the NAND Ready GPIO line
> >   * @mtd: MTD device structure
> > + *
> > + * Returns true if ready and false if busy.
> >   */
> >  static int omap_dev_ready(struct mtd_info *mtd)
> >  {
> > -	unsigned int val = 0;
> >  	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> >  							mtd);
> >  
> > -	val = readl(info->reg.gpmc_status);
> > -
> > -	if ((val & 0x100) == 0x100) {
> > -		return 1;
> > -	} else {
> > -		return 0;
> > -	}
> > +	return gpiod_get_value(info->ready_gpiod);
> >  }
> >  
> >  /**
> > @@ -1782,7 +1780,9 @@ static int omap_nand_probe(struct platform_device *pdev)
> >  		info->reg = pdata->reg;
> >  		info->of_node = pdata->of_node;
> >  		info->ecc_opt = pdata->ecc_opt;
> > -		info->dev_ready	= pdata->dev_ready;
> > +		if (pdata->dev_ready)
> > +			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
> > +
> >  		info->xfer_type = pdata->xfer_type;
> >  		info->devsize = pdata->devsize;
> >  		info->elm_of_node = pdata->elm_of_node;
> > @@ -1815,6 +1815,13 @@ static int omap_nand_probe(struct platform_device *pdev)
> >  	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
> >  	nand_chip->cmd_ctrl  = omap_hwcontrol;
> >  
> > +	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "ready",
> > +						    GPIOD_IN);
> 
> Others have been looking at using GPIOs for the ready/busy pin too. At a
> minimum, we need an updated DT binding doc for this, since I see you're
> adding this via device tree in a later patch (I don't see any DT binding
> patch for this; but I could just be overlooking it). It'd also be great
> if this support was moved to nand_dt_init() so other platforms can
> benefit, but I won't require that.

Actually I started to work on a generic solution parsing the DT and
creating CS, WP and RB gpios when they are provided, but I think it's a
bit more complicated than just moving the rb-gpios parsing into
nand_dt_init().
First you'll need something to store your gpio_desc pointers, which
means you'll have to allocate a table of gpio_desc pointers (or a table
of struct embedding a gpio_desc pointer).
The other blocking point is that when nand_scan_ident() is called, the
caller is supposed to have filled the ->dev_ready() or ->waitfunc()
fields, and to choose how to implement it he may need to know
which kind of RB handler should be used (this is the case in the sunxi
driver, where the user can either use a GPIO or native R/B pin directly
connected to the controller).

All this makes me think that maybe nand_dt_init() should be called
separately or in a different helper (nand_init() ?) taking care of the
basic nand_chip initializations/allocations without interacting with
the NAND itself.

Another solution would be to add an ->init() function to nand_chip
and call it after the generic initialization has been done (but before
NAND chip detection). This way the NAND controller driver could adapt
some fields and parse controller specific properties.

What do you think?

Best Regards,

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib
  2015-10-27  8:12       ` Boris Brezillon
@ 2015-10-27  8:43         ` Roger Quadros
  0 siblings, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-10-27  8:43 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, tony, dwmw2, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Alex Smith,
	Harvey Hunt

Boris,

On 27/10/15 10:12, Boris Brezillon wrote:
> Hi Roger,
> 
> On Tue, 27 Oct 2015 10:03:02 +0200
> Roger Quadros <rogerq@ti.com> wrote:
> 
>> On 26/10/15 22:49, Brian Norris wrote:
>>>
>>> Others have been looking at using GPIOs for the ready/busy pin too. At a
>>> minimum, we need an updated DT binding doc for this, since I see you're
>>> adding this via device tree in a later patch (I don't see any DT binding
>>> patch for this; but I could just be overlooking it). It'd also be great
>>> if this support was moved to nand_dt_init() so other platforms can
>>> benefit, but I won't require that.
>>>
>>> Also, previous [0] proposers had suggested 'rb-gpios', not 'ready-gpio'
>>> (the hardware docs typically call it 'rb' for ready/busy, FWIW). I don't
>>> really care, but the name should be going into a doc, so we can choose
>>> the same one everywhere.
>>>
>>> EDIT: looks like the discussion was partly here [1] and it seems we're
>>> landing on "rb-gpios" in the latest version [2]. Can we stick with that?
>>
>> Why should it be "rb-gpios" and not "rb-gpio"?
>> I don't think there are multiple gpios for r/b# function.
> 
> Because it's supposed to be a generic binding, and some NAND chips
> embed several dies, thus exposing several CS and RB pins, hence the
> rb-gpios name.
> Also, as described here [1], the convention is to name your property
> <name>-gpios even if you only need one gpio.

Makes sense now. Thanks for the explanation.
I'll update this patch to use rb-gpios and update the binding doc as well.

--
cheers,
-roger

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-26 21:23 ` Brian Norris
@ 2015-10-27  9:37   ` Roger Quadros
  2015-11-25 10:42     ` Roger Quadros
  2015-11-30 19:54     ` Brian Norris
  0 siblings, 2 replies; 79+ messages in thread
From: Roger Quadros @ 2015-10-27  9:37 UTC (permalink / raw)
  To: Brian Norris
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Hi Brian,

On 26/10/15 23:23, Brian Norris wrote:
> Hi Roger,
> 
> I'm not too familiar with OMAP platforms, and I might have missed out on
> prior discussions/context, so please forgive if I'm asking silly or old
> questions here.

No worries at all.

> 
> On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
>> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
>> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
>> This causes performance increase when using prefetch-irq mode.
>> 30% increase in read, 17% increase in write in prefetch-irq mode.
> 
> Have you pinpointed the exact causes for the performance increase, or
> can you give an educated guess? AIUI, you're reducing the number of
> interrupts needed for NAND prefetch mode, but you're also removing a bit
> of abstraction and implementing hooks that look awfully like the
> existing abstractions:
> 
> +       int (*nand_irq_enable)(enum gpmc_nand_irq irq);
> +       int (*nand_irq_disable)(enum gpmc_nand_irq irq);
> +       void (*nand_irq_clear)(enum gpmc_nand_irq irq);
> +       u32 (*nand_irq_status)(void);
> 
> That's not really a problem if there's a good reason for them (brcmnand
> implements similar hooks because of quirks in the implementation of
> interrupts across various BRCM SoCs, and it's not worth writing irqchip
> drivers for those cases). I'm mainly curious for an explanation.

I have both implementations with me. My guess is that the 20% performance
gain is due to absence of irqchip/irqdomain translation code.
I haven't investigated further though.

Another concern I have is that I'm not using any locking around
gpmc_nand_irq_enable/disable(). Could this pose problems in multiple NAND
use cases? My understanding is that it should not as the controller access
is serialized between multiple NAND chips.

However I do need to add some locking as the GPMC_IRQENABLE register is shared
between NAND and GPMC driver.

NOTE: We are not using prefetch-irq mode for any of the OMAP boards because
of lesser performance than prefetch-polled mode. So if the less performance
for an unused mode is a lesser concern compared to cleaner code then
I can resend this with the irqdomain implementation.

Below are performance logs of irqdomain vs hooks.

--
cheers,
-roger

test logs.

for-v4.4/gpmc-v2 - irqdomain with prefetch-irq. No ready pin.
================

[   67.696631] 
[   67.698201] =================================================
[   67.704254] mtd_speedtest: MTD device: 8
[   67.708373] mtd_speedtest: MTD device size 8388608, eraseblock size 131072, page size 2048, count of eraseblocks 64, pages per eraseblock 64, OOB size 64
[   67.723701] mtd_test: scanning for bad eraseblocks
[   67.735468] mtd_test: scanned 64 eraseblocks, 0 are bad
[   67.772861] mtd_speedtest: testing eraseblock write speed
[   70.372903] mtd_speedtest: eraseblock write speed is 3156 KiB/s
[   70.379104] mtd_speedtest: testing eraseblock read speed
[   72.594169] mtd_speedtest: eraseblock read speed is 3708 KiB/s
[   72.656375] mtd_speedtest: testing page write speed
[   75.213646] mtd_speedtest: page write speed is 3208 KiB/s
[   75.219311] mtd_speedtest: testing page read speed
[   77.343639] mtd_speedtest: page read speed is 3865 KiB/s
[   77.405236] mtd_speedtest: testing 2 page write speed
[   80.039702] mtd_speedtest: 2 page write speed is 3114 KiB/s
[   80.045561] mtd_speedtest: testing 2 page read speed
[   82.175098] mtd_speedtest: 2 page read speed is 3856 KiB/s
[   82.180849] mtd_speedtest: Testing erase speed
[   82.241548] mtd_speedtest: erase speed is 146285 KiB/s
[   82.246920] mtd_speedtest: Testing 2x multi-block erase speed
[   82.284789] mtd_speedtest: 2x multi-block erase speed is 264258 KiB/s
[   82.291551] mtd_speedtest: Testing 4x multi-block erase speed
[   82.329358] mtd_speedtest: 4x multi-block erase speed is 264258 KiB/s
[   82.336116] mtd_speedtest: Testing 8x multi-block erase speed
[   82.373903] mtd_speedtest: 8x multi-block erase speed is 264258 KiB/s
[   82.380648] mtd_speedtest: Testing 16x multi-block erase speed
[   82.418503] mtd_speedtest: 16x multi-block erase speed is 264258 KiB/s
[   82.425356] mtd_speedtest: Testing 32x multi-block erase speed
[   82.463227] mtd_speedtest: 32x multi-block erase speed is 264258 KiB/s
[   82.470066] mtd_speedtest: Testing 64x multi-block erase speed
[   82.507908] mtd_speedtest: 64x multi-block erase speed is 264258 KiB/s
[   82.514758] mtd_speedtest: finished
[   82.518417] =================================================

root@rockdesk:~# cat /proc/interrupts 
           CPU0       CPU1       
324:     798720          0      CBAR  15 Level     gpmc
397:     798720          0      gpmc   0 Edge      gpmc-nand-fifo
398:      24576          0      gpmc   1 Edge      gpmc-nand-count


root@rockdesk:~# ./nandthroughput.sh 
Test file blobs/50M.bin found
mounting NAND partition 9
== attaching ubi to mtd9
[  133.102184] ubi0: attaching mtd9
[  133.801162] ubi0: scanning is finished
[  133.818853] ubi0: attached mtd9 (name "NAND.file-system", size 246 MiB)
[  133.825805] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[  133.833036] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[  133.840065] ubi0: VID header offset: 512 (aligned 512), data offset: 2048
[  133.847198] ubi0: good PEBs: 1968, bad PEBs: 0, corrupted PEBs: 0
[  133.853598] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
[  133.861178] ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 673614122
[  133.870682] ubi0: available PEBs: 0, total reserved PEBs: 1968, PEBs reserved for bad PEB handling: 40
[  133.880817] ubi0: background thread "ubi_bgt0d" started, PID 2304
UBI device number 0, total 1968 LEBs (253919232 bytes, 242.2 MiB), available 0 LEBs (0 bytes), LEB size 129024 bytes (126.0 KiB)
== mounting volume
[  133.921377] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 2306
[  133.987100] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "rootfs"
[  133.994882] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[  134.005314] UBIFS (ubi0:0): FS size: 246564864 bytes (235 MiB, 1911 LEBs), journal size 12386304 bytes (11 MiB, 96 LEBs)
[  134.016737] UBIFS (ubi0:0): reserved for root: 4952683 bytes (4836 KiB)
[  134.023691] UBIFS (ubi0:0): media format: w4/r0 (latest is w4/r0), UUID CE1A60B9-55D7-42D8-BC23-13997CF7F130, small LPT model
write test
[  134.159501] nandthroughput. (2301): drop_caches: 3
5+0 records in
5+0 records out
52428800 bytes (52 MB) copied, 12.0334 s, 4.4 MB/s
read test
[  146.782569] nandthroughput. (2301): drop_caches: 3
5+0 records in
5+0 records out
52428800 bytes (52 MB) copied, 7.61057 s, 6.9 MB/s
b34b1f703d54d577fe78564226d5a6d6 /tmp/nandtest
b34b1f703d54d577fe78564226d5a6d6  /tmp/nandtestread
== unmounting volume
[  155.122917] UBIFS (ubi0:0): un-mount UBI device 0
[  155.128142] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" stops
== detaching ubi
[  155.175075] ubi0: detaching mtd9
[  155.184543] ubi0: mtd9 is detached
done


for-v4.4/gpmc-v4-prefetch-irq-noready - prefetch-irq with no irqdomain, no ready pin.
=====================================

[   28.472795] 
[   28.474361] =================================================
[   28.480376] mtd_speedtest: MTD device: 8
[   28.484546] mtd_speedtest: MTD device size 8388608, eraseblock size 131072, page size 2048, count of eraseblocks 64, pages per eraseblock 64, OOB size 64
[   28.499856] mtd_test: scanning for bad eraseblocks
[   28.512001] mtd_test: scanned 64 eraseblocks, 0 are bad
[   28.549375] mtd_speedtest: testing eraseblock write speed
[   30.886014] mtd_speedtest: eraseblock write speed is 3515 KiB/s
[   30.892246] mtd_speedtest: testing eraseblock read speed
[   32.727323] mtd_speedtest: eraseblock read speed is 4476 KiB/s
[   32.789452] mtd_speedtest: testing page write speed
[   35.124514] mtd_speedtest: page write speed is 3515 KiB/s
[   35.130181] mtd_speedtest: testing page read speed
[   37.006367] mtd_speedtest: page read speed is 4378 KiB/s
[   37.067976] mtd_speedtest: testing 2 page write speed
[   39.386324] mtd_speedtest: 2 page write speed is 3541 KiB/s
[   39.392191] mtd_speedtest: testing 2 page read speed
[   41.289049] mtd_speedtest: 2 page read speed is 4329 KiB/s
[   41.294820] mtd_speedtest: Testing erase speed
[   41.355468] mtd_speedtest: erase speed is 148945 KiB/s
[   41.360856] mtd_speedtest: Testing 2x multi-block erase speed
[   41.398737] mtd_speedtest: 2x multi-block erase speed is 264258 KiB/s
[   41.405506] mtd_speedtest: Testing 4x multi-block erase speed
[   41.443567] mtd_speedtest: 4x multi-block erase speed is 256000 KiB/s
[   41.450319] mtd_speedtest: Testing 8x multi-block erase speed
[   41.488075] mtd_speedtest: 8x multi-block erase speed is 264258 KiB/s
[   41.494843] mtd_speedtest: Testing 16x multi-block erase speed
[   41.532670] mtd_speedtest: 16x multi-block erase speed is 264258 KiB/s
[   41.539512] mtd_speedtest: Testing 32x multi-block erase speed
[   41.577328] mtd_speedtest: 32x multi-block erase speed is 264258 KiB/s
[   41.584183] mtd_speedtest: Testing 64x multi-block erase speed
[   41.621973] mtd_speedtest: 64x multi-block erase speed is 264258 KiB/s
[   41.628817] mtd_speedtest: finished
[   41.632486] =================================================
root@rockdesk:~# 
root@rockdesk:~# cat /proc/interrupts 
           CPU0       CPU1       
324:     798737          0      CBAR  15 Level     omap-gpmc, omap2-nand


./nandthroughput.sh 
Test file blobs/50M.bin found
mounting NAND partition 9
== attaching ubi to mtd9
[  371.605283] ubi0: attaching mtd9
[  372.661433] ubi0: scanning is finished
[  372.682827] ubi0: attached mtd9 (name "NAND.file-system", size 246 MiB)
[  372.689759] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[  372.696989] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[  372.704021] ubi0: VID header offset: 512 (aligned 512), data offset: 2048
[  372.711136] ubi0: good PEBs: 1968, bad PEBs: 0, corrupted PEBs: 0
[  372.717530] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
[  372.725104] ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 673614122
[  372.734594] ubi0: available PEBs: 0, total reserved PEBs: 1968, PEBs reserved for bad PEB handling: 40
[  372.744779] ubi0: background thread "ubi_bgt0d" started, PID 2320
UBI device number 0, total 1968 LEBs (253919232 bytes, 242.2 MiB), available 0 LEBs (0 bytes), LEB size 129024 bytes (126.0 KiB)
== mounting volume
[  372.786473] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 2322
[  372.835870] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "rootfs"
[  372.843648] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[  372.854082] UBIFS (ubi0:0): FS size: 246564864 bytes (235 MiB, 1911 LEBs), journal size 12386304 bytes (11 MiB, 96 LEBs)
[  372.865505] UBIFS (ubi0:0): reserved for root: 4952683 bytes (4836 KiB)
[  372.872467] UBIFS (ubi0:0): media format: w4/r0 (latest is w4/r0), UUID CE1A60B9-55D7-42D8-BC23-13997CF7F130, small LPT model
write test
[  373.019723] nandthroughput. (2317): drop_caches: 3
5+0 records in
5+0 records out
52428800 bytes (52 MB) copied, 10.8034 s, 4.9 MB/s
read test
[  384.393642] nandthroughput. (2317): drop_caches: 3
5+0 records in
5+0 records out
52428800 bytes (52 MB) copied, 6.30402 s, 8.3 MB/s
b34b1f703d54d577fe78564226d5a6d6 /tmp/nandtest
b34b1f703d54d577fe78564226d5a6d6  /tmp/nandtestread
== unmounting volume
[  391.420866] UBIFS (ubi0:0): un-mount UBI device 0
[  391.426108] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" stops
== detaching ubi
[  391.456007] ubi0: detaching mtd9
[  391.464569] ubi0: mtd9 is detached
done





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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-27  9:37   ` Roger Quadros
@ 2015-11-25 10:42     ` Roger Quadros
  2015-11-30 19:54     ` Brian Norris
  1 sibling, 0 replies; 79+ messages in thread
From: Roger Quadros @ 2015-11-25 10:42 UTC (permalink / raw)
  To: Brian Norris
  Cc: devicetree, tony, nsekhar, linux-kernel, linux-mtd, ezequiel,
	javier, linux-omap, dwmw2, fcooper

Brian,

On 27/10/15 11:37, Roger Quadros wrote:
> Hi Brian,
> 
> On 26/10/15 23:23, Brian Norris wrote:
>> Hi Roger,
>>
>> I'm not too familiar with OMAP platforms, and I might have missed out on
>> prior discussions/context, so please forgive if I'm asking silly or old
>> questions here.
> 
> No worries at all.
> 
>>
>> On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
>>> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
>>> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
>>> This causes performance increase when using prefetch-irq mode.
>>> 30% increase in read, 17% increase in write in prefetch-irq mode.
>>
>> Have you pinpointed the exact causes for the performance increase, or
>> can you give an educated guess? AIUI, you're reducing the number of
>> interrupts needed for NAND prefetch mode, but you're also removing a bit
>> of abstraction and implementing hooks that look awfully like the
>> existing abstractions:
>>
>> +       int (*nand_irq_enable)(enum gpmc_nand_irq irq);
>> +       int (*nand_irq_disable)(enum gpmc_nand_irq irq);
>> +       void (*nand_irq_clear)(enum gpmc_nand_irq irq);
>> +       u32 (*nand_irq_status)(void);
>>
>> That's not really a problem if there's a good reason for them (brcmnand
>> implements similar hooks because of quirks in the implementation of
>> interrupts across various BRCM SoCs, and it's not worth writing irqchip
>> drivers for those cases). I'm mainly curious for an explanation.
> 
> I have both implementations with me. My guess is that the 20% performance
> gain is due to absence of irqchip/irqdomain translation code.
> I haven't investigated further though.
> 
> Another concern I have is that I'm not using any locking around
> gpmc_nand_irq_enable/disable(). Could this pose problems in multiple NAND
> use cases? My understanding is that it should not as the controller access
> is serialized between multiple NAND chips.
> 
> However I do need to add some locking as the GPMC_IRQENABLE register is shared
> between NAND and GPMC driver.
> 
> NOTE: We are not using prefetch-irq mode for any of the OMAP boards because
> of lesser performance than prefetch-polled mode. So if the less performance
> for an unused mode is a lesser concern compared to cleaner code then
> I can resend this with the irqdomain implementation.
> 
> Below are performance logs of irqdomain vs hooks.

Any further comments?

cheers,
-roger

> 
> --
> cheers,
> -roger
> 
> test logs.
> 
> for-v4.4/gpmc-v2 - irqdomain with prefetch-irq. No ready pin.
> ================
> 
> [   67.696631] 
> [   67.698201] =================================================
> [   67.704254] mtd_speedtest: MTD device: 8
> [   67.708373] mtd_speedtest: MTD device size 8388608, eraseblock size 131072, page size 2048, count of eraseblocks 64, pages per eraseblock 64, OOB size 64
> [   67.723701] mtd_test: scanning for bad eraseblocks
> [   67.735468] mtd_test: scanned 64 eraseblocks, 0 are bad
> [   67.772861] mtd_speedtest: testing eraseblock write speed
> [   70.372903] mtd_speedtest: eraseblock write speed is 3156 KiB/s
> [   70.379104] mtd_speedtest: testing eraseblock read speed
> [   72.594169] mtd_speedtest: eraseblock read speed is 3708 KiB/s
> [   72.656375] mtd_speedtest: testing page write speed
> [   75.213646] mtd_speedtest: page write speed is 3208 KiB/s
> [   75.219311] mtd_speedtest: testing page read speed
> [   77.343639] mtd_speedtest: page read speed is 3865 KiB/s
> [   77.405236] mtd_speedtest: testing 2 page write speed
> [   80.039702] mtd_speedtest: 2 page write speed is 3114 KiB/s
> [   80.045561] mtd_speedtest: testing 2 page read speed
> [   82.175098] mtd_speedtest: 2 page read speed is 3856 KiB/s
> [   82.180849] mtd_speedtest: Testing erase speed
> [   82.241548] mtd_speedtest: erase speed is 146285 KiB/s
> [   82.246920] mtd_speedtest: Testing 2x multi-block erase speed
> [   82.284789] mtd_speedtest: 2x multi-block erase speed is 264258 KiB/s
> [   82.291551] mtd_speedtest: Testing 4x multi-block erase speed
> [   82.329358] mtd_speedtest: 4x multi-block erase speed is 264258 KiB/s
> [   82.336116] mtd_speedtest: Testing 8x multi-block erase speed
> [   82.373903] mtd_speedtest: 8x multi-block erase speed is 264258 KiB/s
> [   82.380648] mtd_speedtest: Testing 16x multi-block erase speed
> [   82.418503] mtd_speedtest: 16x multi-block erase speed is 264258 KiB/s
> [   82.425356] mtd_speedtest: Testing 32x multi-block erase speed
> [   82.463227] mtd_speedtest: 32x multi-block erase speed is 264258 KiB/s
> [   82.470066] mtd_speedtest: Testing 64x multi-block erase speed
> [   82.507908] mtd_speedtest: 64x multi-block erase speed is 264258 KiB/s
> [   82.514758] mtd_speedtest: finished
> [   82.518417] =================================================
> 
> root@rockdesk:~# cat /proc/interrupts 
>            CPU0       CPU1       
> 324:     798720          0      CBAR  15 Level     gpmc
> 397:     798720          0      gpmc   0 Edge      gpmc-nand-fifo
> 398:      24576          0      gpmc   1 Edge      gpmc-nand-count
> 
> 
> root@rockdesk:~# ./nandthroughput.sh 
> Test file blobs/50M.bin found
> mounting NAND partition 9
> == attaching ubi to mtd9
> [  133.102184] ubi0: attaching mtd9
> [  133.801162] ubi0: scanning is finished
> [  133.818853] ubi0: attached mtd9 (name "NAND.file-system", size 246 MiB)
> [  133.825805] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
> [  133.833036] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
> [  133.840065] ubi0: VID header offset: 512 (aligned 512), data offset: 2048
> [  133.847198] ubi0: good PEBs: 1968, bad PEBs: 0, corrupted PEBs: 0
> [  133.853598] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
> [  133.861178] ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 673614122
> [  133.870682] ubi0: available PEBs: 0, total reserved PEBs: 1968, PEBs reserved for bad PEB handling: 40
> [  133.880817] ubi0: background thread "ubi_bgt0d" started, PID 2304
> UBI device number 0, total 1968 LEBs (253919232 bytes, 242.2 MiB), available 0 LEBs (0 bytes), LEB size 129024 bytes (126.0 KiB)
> == mounting volume
> [  133.921377] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 2306
> [  133.987100] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "rootfs"
> [  133.994882] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
> [  134.005314] UBIFS (ubi0:0): FS size: 246564864 bytes (235 MiB, 1911 LEBs), journal size 12386304 bytes (11 MiB, 96 LEBs)
> [  134.016737] UBIFS (ubi0:0): reserved for root: 4952683 bytes (4836 KiB)
> [  134.023691] UBIFS (ubi0:0): media format: w4/r0 (latest is w4/r0), UUID CE1A60B9-55D7-42D8-BC23-13997CF7F130, small LPT model
> write test
> [  134.159501] nandthroughput. (2301): drop_caches: 3
> 5+0 records in
> 5+0 records out
> 52428800 bytes (52 MB) copied, 12.0334 s, 4.4 MB/s
> read test
> [  146.782569] nandthroughput. (2301): drop_caches: 3
> 5+0 records in
> 5+0 records out
> 52428800 bytes (52 MB) copied, 7.61057 s, 6.9 MB/s
> b34b1f703d54d577fe78564226d5a6d6 /tmp/nandtest
> b34b1f703d54d577fe78564226d5a6d6  /tmp/nandtestread
> == unmounting volume
> [  155.122917] UBIFS (ubi0:0): un-mount UBI device 0
> [  155.128142] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" stops
> == detaching ubi
> [  155.175075] ubi0: detaching mtd9
> [  155.184543] ubi0: mtd9 is detached
> done
> 
> 
> for-v4.4/gpmc-v4-prefetch-irq-noready - prefetch-irq with no irqdomain, no ready pin.
> =====================================
> 
> [   28.472795] 
> [   28.474361] =================================================
> [   28.480376] mtd_speedtest: MTD device: 8
> [   28.484546] mtd_speedtest: MTD device size 8388608, eraseblock size 131072, page size 2048, count of eraseblocks 64, pages per eraseblock 64, OOB size 64
> [   28.499856] mtd_test: scanning for bad eraseblocks
> [   28.512001] mtd_test: scanned 64 eraseblocks, 0 are bad
> [   28.549375] mtd_speedtest: testing eraseblock write speed
> [   30.886014] mtd_speedtest: eraseblock write speed is 3515 KiB/s
> [   30.892246] mtd_speedtest: testing eraseblock read speed
> [   32.727323] mtd_speedtest: eraseblock read speed is 4476 KiB/s
> [   32.789452] mtd_speedtest: testing page write speed
> [   35.124514] mtd_speedtest: page write speed is 3515 KiB/s
> [   35.130181] mtd_speedtest: testing page read speed
> [   37.006367] mtd_speedtest: page read speed is 4378 KiB/s
> [   37.067976] mtd_speedtest: testing 2 page write speed
> [   39.386324] mtd_speedtest: 2 page write speed is 3541 KiB/s
> [   39.392191] mtd_speedtest: testing 2 page read speed
> [   41.289049] mtd_speedtest: 2 page read speed is 4329 KiB/s
> [   41.294820] mtd_speedtest: Testing erase speed
> [   41.355468] mtd_speedtest: erase speed is 148945 KiB/s
> [   41.360856] mtd_speedtest: Testing 2x multi-block erase speed
> [   41.398737] mtd_speedtest: 2x multi-block erase speed is 264258 KiB/s
> [   41.405506] mtd_speedtest: Testing 4x multi-block erase speed
> [   41.443567] mtd_speedtest: 4x multi-block erase speed is 256000 KiB/s
> [   41.450319] mtd_speedtest: Testing 8x multi-block erase speed
> [   41.488075] mtd_speedtest: 8x multi-block erase speed is 264258 KiB/s
> [   41.494843] mtd_speedtest: Testing 16x multi-block erase speed
> [   41.532670] mtd_speedtest: 16x multi-block erase speed is 264258 KiB/s
> [   41.539512] mtd_speedtest: Testing 32x multi-block erase speed
> [   41.577328] mtd_speedtest: 32x multi-block erase speed is 264258 KiB/s
> [   41.584183] mtd_speedtest: Testing 64x multi-block erase speed
> [   41.621973] mtd_speedtest: 64x multi-block erase speed is 264258 KiB/s
> [   41.628817] mtd_speedtest: finished
> [   41.632486] =================================================
> root@rockdesk:~# 
> root@rockdesk:~# cat /proc/interrupts 
>            CPU0       CPU1       
> 324:     798737          0      CBAR  15 Level     omap-gpmc, omap2-nand
> 
> 
> ./nandthroughput.sh 
> Test file blobs/50M.bin found
> mounting NAND partition 9
> == attaching ubi to mtd9
> [  371.605283] ubi0: attaching mtd9
> [  372.661433] ubi0: scanning is finished
> [  372.682827] ubi0: attached mtd9 (name "NAND.file-system", size 246 MiB)
> [  372.689759] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
> [  372.696989] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
> [  372.704021] ubi0: VID header offset: 512 (aligned 512), data offset: 2048
> [  372.711136] ubi0: good PEBs: 1968, bad PEBs: 0, corrupted PEBs: 0
> [  372.717530] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
> [  372.725104] ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 673614122
> [  372.734594] ubi0: available PEBs: 0, total reserved PEBs: 1968, PEBs reserved for bad PEB handling: 40
> [  372.744779] ubi0: background thread "ubi_bgt0d" started, PID 2320
> UBI device number 0, total 1968 LEBs (253919232 bytes, 242.2 MiB), available 0 LEBs (0 bytes), LEB size 129024 bytes (126.0 KiB)
> == mounting volume
> [  372.786473] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 2322
> [  372.835870] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "rootfs"
> [  372.843648] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
> [  372.854082] UBIFS (ubi0:0): FS size: 246564864 bytes (235 MiB, 1911 LEBs), journal size 12386304 bytes (11 MiB, 96 LEBs)
> [  372.865505] UBIFS (ubi0:0): reserved for root: 4952683 bytes (4836 KiB)
> [  372.872467] UBIFS (ubi0:0): media format: w4/r0 (latest is w4/r0), UUID CE1A60B9-55D7-42D8-BC23-13997CF7F130, small LPT model
> write test
> [  373.019723] nandthroughput. (2317): drop_caches: 3
> 5+0 records in
> 5+0 records out
> 52428800 bytes (52 MB) copied, 10.8034 s, 4.9 MB/s
> read test
> [  384.393642] nandthroughput. (2317): drop_caches: 3
> 5+0 records in
> 5+0 records out
> 52428800 bytes (52 MB) copied, 6.30402 s, 8.3 MB/s
> b34b1f703d54d577fe78564226d5a6d6 /tmp/nandtest
> b34b1f703d54d577fe78564226d5a6d6  /tmp/nandtestread
> == unmounting volume
> [  391.420866] UBIFS (ubi0:0): un-mount UBI device 0
> [  391.426108] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" stops
> == detaching ubi
> [  391.456007] ubi0: detaching mtd9
> [  391.464569] ubi0: mtd9 is detached
> done
> 
> 
> 
> 
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
> 

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-23  7:09                         ` Roger Quadros
@ 2015-11-30 17:26                           ` Tony Lindgren
  0 siblings, 0 replies; 79+ messages in thread
From: Tony Lindgren @ 2015-11-30 17:26 UTC (permalink / raw)
  To: Roger Quadros
  Cc: devicetree, linux-omap, nsekhar, linux-kernel, linux-mtd,
	ezequiel, javier, computersforpeace, dwmw2, fcooper

* Roger Quadros <rogerq@ti.com> [151023 00:09]:
> On 21/10/15 18:20, Tony Lindgren wrote:
> > * Roger Quadros <rogerq@ti.com> [151021 01:31]:
> >>
> >> I couldn't run randconfig beyond few iterations as it keeps failing
> >> everywhere. How do we limit the randconfig options to OMAP only
> >> platforms?
> > 
> > You can use Felipe's scripts from github.
> 
> Thanks. I used his scripts and ran 10 randconfigs per platform.
> Didn't find any issues with this series.
> 
> How can we proceed?
> Patches are on https://github.com/rogerq/linux/commits/for-v4.4/gpmc-v4

Sorry for the delay on this one. I suggest you get this series into
linux next and then we can merge it for v4.5 via arm-soc as long as
the pending comments are addressed. As far as I'm concerned, feel free
to add for the whole series:

Acked-by: Tony Lindgren <tony@atomide.com>

Regards,

Tony

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-10-27  9:37   ` Roger Quadros
  2015-11-25 10:42     ` Roger Quadros
@ 2015-11-30 19:54     ` Brian Norris
  2015-12-01 14:41       ` Roger Quadros
  1 sibling, 1 reply; 79+ messages in thread
From: Brian Norris @ 2015-11-30 19:54 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Hi Roger,

On Tue, Oct 27, 2015 at 11:37:03AM +0200, Roger Quadros wrote:
> On 26/10/15 23:23, Brian Norris wrote:
> > I'm not too familiar with OMAP platforms, and I might have missed out on
> > prior discussions/context, so please forgive if I'm asking silly or old
> > questions here.
> 
> No worries at all.
> 
> > 
> > On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
> >> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
> >> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
> >> This causes performance increase when using prefetch-irq mode.
> >> 30% increase in read, 17% increase in write in prefetch-irq mode.
> > 
> > Have you pinpointed the exact causes for the performance increase, or
> > can you give an educated guess? AIUI, you're reducing the number of
> > interrupts needed for NAND prefetch mode, but you're also removing a bit
> > of abstraction and implementing hooks that look awfully like the
> > existing abstractions:
> > 
> > +       int (*nand_irq_enable)(enum gpmc_nand_irq irq);
> > +       int (*nand_irq_disable)(enum gpmc_nand_irq irq);
> > +       void (*nand_irq_clear)(enum gpmc_nand_irq irq);
> > +       u32 (*nand_irq_status)(void);
> > 
> > That's not really a problem if there's a good reason for them (brcmnand
> > implements similar hooks because of quirks in the implementation of
> > interrupts across various BRCM SoCs, and it's not worth writing irqchip
> > drivers for those cases). I'm mainly curious for an explanation.
> 
> I have both implementations with me. My guess is that the 20% performance
> gain is due to absence of irqchip/irqdomain translation code.
> I haven't investigated further though.

I don't have much context for whether this makes sense or not. According
to your tests, you're getting ~800K interrupts over ~15 seconds. So
should you start noticing performance hits due to abstraction at 53K
interrupts per second?

But anyway, I'm not sure that completely answered my question. My
question was whether you were removing the irqchip code solely for
performance reasons, or are there others?

> Another concern I have is that I'm not using any locking around
> gpmc_nand_irq_enable/disable(). Could this pose problems in multiple NAND
> use cases? My understanding is that it should not as the controller access
> is serialized between multiple NAND chips.

Right, if you're touching just a NAND interrupt, and it's only used by a
single instance of this NAND controller, then the NAND controller
serialization code will handle this for you.

> However I do need to add some locking as the GPMC_IRQENABLE register is shared
> between NAND and GPMC driver.
> 
> NOTE: We are not using prefetch-irq mode for any of the OMAP boards because
> of lesser performance than prefetch-polled mode. So if the less performance
> for an unused mode is a lesser concern compared to cleaner code then
> I can resend this with the irqdomain implementation.
> 
> Below are performance logs of irqdomain vs hooks.
> 
> --
> cheers,
> -roger
> 
> test logs.

[snip]

Brian

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-11-30 19:54     ` Brian Norris
@ 2015-12-01 14:41       ` Roger Quadros
  2015-12-02  3:26         ` Brian Norris
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-12-01 14:41 UTC (permalink / raw)
  To: Brian Norris
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Hi Brian,

On 30/11/15 21:54, Brian Norris wrote:
> Hi Roger,
> 
> On Tue, Oct 27, 2015 at 11:37:03AM +0200, Roger Quadros wrote:
>> On 26/10/15 23:23, Brian Norris wrote:
>>> I'm not too familiar with OMAP platforms, and I might have missed out on
>>> prior discussions/context, so please forgive if I'm asking silly or old
>>> questions here.
>>
>> No worries at all.
>>
>>>
>>> On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
>>>> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
>>>> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
>>>> This causes performance increase when using prefetch-irq mode.
>>>> 30% increase in read, 17% increase in write in prefetch-irq mode.
>>>
>>> Have you pinpointed the exact causes for the performance increase, or
>>> can you give an educated guess? AIUI, you're reducing the number of
>>> interrupts needed for NAND prefetch mode, but you're also removing a bit
>>> of abstraction and implementing hooks that look awfully like the
>>> existing abstractions:
>>>
>>> +       int (*nand_irq_enable)(enum gpmc_nand_irq irq);
>>> +       int (*nand_irq_disable)(enum gpmc_nand_irq irq);
>>> +       void (*nand_irq_clear)(enum gpmc_nand_irq irq);
>>> +       u32 (*nand_irq_status)(void);
>>>
>>> That's not really a problem if there's a good reason for them (brcmnand
>>> implements similar hooks because of quirks in the implementation of
>>> interrupts across various BRCM SoCs, and it's not worth writing irqchip
>>> drivers for those cases). I'm mainly curious for an explanation.
>>
>> I have both implementations with me. My guess is that the 20% performance
>> gain is due to absence of irqchip/irqdomain translation code.
>> I haven't investigated further though.
> 
> I don't have much context for whether this makes sense or not. According
> to your tests, you're getting ~800K interrupts over ~15 seconds. So
> should you start noticing performance hits due to abstraction at 53K
> interrupts per second?

Yes, this was my understanding.

> 
> But anyway, I'm not sure that completely answered my question. My
> question was whether you were removing the irqchip code solely for
> performance reasons, or are there others?

Yes. Only for performance reasons.

> 
>> Another concern I have is that I'm not using any locking around
>> gpmc_nand_irq_enable/disable(). Could this pose problems in multiple NAND
>> use cases? My understanding is that it should not as the controller access
>> is serialized between multiple NAND chips.
> 
> Right, if you're touching just a NAND interrupt, and it's only used by a
> single instance of this NAND controller, then the NAND controller
> serialization code will handle this for you.

OK.

cheers,
-roger

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-01 14:41       ` Roger Quadros
@ 2015-12-02  3:26         ` Brian Norris
  2015-12-02  5:12           ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Brian Norris @ 2015-12-02  3:26 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Hi Roger,

On Tue, Dec 01, 2015 at 04:41:16PM +0200, Roger Quadros wrote:
> On 30/11/15 21:54, Brian Norris wrote:
> > On Tue, Oct 27, 2015 at 11:37:03AM +0200, Roger Quadros wrote:
> >> On 26/10/15 23:23, Brian Norris wrote:
> >>> On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
> >>>> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
> >>>> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
> >>>> This causes performance increase when using prefetch-irq mode.
> >>>> 30% increase in read, 17% increase in write in prefetch-irq mode.
> >>>
> >>> Have you pinpointed the exact causes for the performance increase, or
> >>> can you give an educated guess? AIUI, you're reducing the number of
> >>> interrupts needed for NAND prefetch mode, but you're also removing a bit
> >>> of abstraction and implementing hooks that look awfully like the
> >>> existing abstractions:
> >>>
> >>> +       int (*nand_irq_enable)(enum gpmc_nand_irq irq);
> >>> +       int (*nand_irq_disable)(enum gpmc_nand_irq irq);
> >>> +       void (*nand_irq_clear)(enum gpmc_nand_irq irq);
> >>> +       u32 (*nand_irq_status)(void);
> >>>
> >>> That's not really a problem if there's a good reason for them (brcmnand
> >>> implements similar hooks because of quirks in the implementation of
> >>> interrupts across various BRCM SoCs, and it's not worth writing irqchip
> >>> drivers for those cases). I'm mainly curious for an explanation.
> >>
> >> I have both implementations with me. My guess is that the 20% performance
> >> gain is due to absence of irqchip/irqdomain translation code.
> >> I haven't investigated further though.
> > 
> > I don't have much context for whether this makes sense or not. According
> > to your tests, you're getting ~800K interrupts over ~15 seconds. So
> > should you start noticing performance hits due to abstraction at 53K
> > interrupts per second?
> 
> Yes, this was my understanding.

Am I computing wrong, or is that a pretty insane rate of interrupts?

> > But anyway, I'm not sure that completely answered my question. My
> > question was whether you were removing the irqchip code solely for
> > performance reasons, or are there others?
> 
> Yes. Only for performance reasons.

Hmm, that's not my favorite answer. I'd prefer that more analysis was
done here before scrapping irqchip...

But maybe that's not too bad. It seems like your patch set overall is a
net positive for disentangling some of arch/ and drivers/.

I'll take another pass over your patch set, but if things are looking
better, how do you expect to merge this? There are significant portions
that touch at least 2 or 3 different subsystem trees, AFAICT.

Brian

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-02  3:26         ` Brian Norris
@ 2015-12-02  5:12           ` Roger Quadros
  2015-12-02 15:03             ` Tony Lindgren
  2015-12-02 18:43             ` Brian Norris
  0 siblings, 2 replies; 79+ messages in thread
From: Roger Quadros @ 2015-12-02  5:12 UTC (permalink / raw)
  To: Brian Norris
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Brian,

On 02/12/15 08:56, Brian Norris wrote:
> Hi Roger,
> 
> On Tue, Dec 01, 2015 at 04:41:16PM +0200, Roger Quadros wrote:
>> On 30/11/15 21:54, Brian Norris wrote:
>>> On Tue, Oct 27, 2015 at 11:37:03AM +0200, Roger Quadros wrote:
>>>> On 26/10/15 23:23, Brian Norris wrote:
>>>>> On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
>>>>>> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
>>>>>> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
>>>>>> This causes performance increase when using prefetch-irq mode.
>>>>>> 30% increase in read, 17% increase in write in prefetch-irq mode.
>>>>>
>>>>> Have you pinpointed the exact causes for the performance increase, or
>>>>> can you give an educated guess? AIUI, you're reducing the number of
>>>>> interrupts needed for NAND prefetch mode, but you're also removing a bit
>>>>> of abstraction and implementing hooks that look awfully like the
>>>>> existing abstractions:
>>>>>
>>>>> +       int (*nand_irq_enable)(enum gpmc_nand_irq irq);
>>>>> +       int (*nand_irq_disable)(enum gpmc_nand_irq irq);
>>>>> +       void (*nand_irq_clear)(enum gpmc_nand_irq irq);
>>>>> +       u32 (*nand_irq_status)(void);
>>>>>
>>>>> That's not really a problem if there's a good reason for them (brcmnand
>>>>> implements similar hooks because of quirks in the implementation of
>>>>> interrupts across various BRCM SoCs, and it's not worth writing irqchip
>>>>> drivers for those cases). I'm mainly curious for an explanation.
>>>>
>>>> I have both implementations with me. My guess is that the 20% performance
>>>> gain is due to absence of irqchip/irqdomain translation code.
>>>> I haven't investigated further though.
>>>
>>> I don't have much context for whether this makes sense or not. According
>>> to your tests, you're getting ~800K interrupts over ~15 seconds. So
>>> should you start noticing performance hits due to abstraction at 53K
>>> interrupts per second?
>>
>> Yes, this was my understanding.
> 
> Am I computing wrong, or is that a pretty insane rate of interrupts?

I don't have the test board with me right now and so can't tell you
for sure if the mtd tests took 15 seconds or more.

I can try it out on a different board that I have and let you know
for sure about how many interrupts we get per second.
> 
>>> But anyway, I'm not sure that completely answered my question. My
>>> question was whether you were removing the irqchip code solely for
>>> performance reasons, or are there others?
>>
>> Yes. Only for performance reasons.
> 
> Hmm, that's not my favorite answer. I'd prefer that more analysis was
> done here before scrapping irqchip...

I agree. We could retain the irqchip model till we have more satisfying
analysis.

> 
> But maybe that's not too bad. It seems like your patch set overall is a
> net positive for disentangling some of arch/ and drivers/.

:)

> 
> I'll take another pass over your patch set, but if things are looking
> better, how do you expect to merge this? There are significant portions
> that touch at least 2 or 3 different subsystem trees, AFAICT.

Tony could create an immutable branch with all the dts and memory changes.
You could base the mtd changes on top of that?

cheers,
-roger

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-02  5:12           ` Roger Quadros
@ 2015-12-02 15:03             ` Tony Lindgren
  2015-12-02 18:13               ` Brian Norris
  2015-12-02 18:43             ` Brian Norris
  1 sibling, 1 reply; 79+ messages in thread
From: Tony Lindgren @ 2015-12-02 15:03 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Brian Norris, dwmw2, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

* Roger Quadros <rogerq@ti.com> [151201 21:13]:
> On 02/12/15 08:56, Brian Norris wrote:
> > 
> > I'll take another pass over your patch set, but if things are looking
> > better, how do you expect to merge this? There are significant portions
> > that touch at least 2 or 3 different subsystem trees, AFAICT.
> 
> Tony could create an immutable branch with all the dts and memory changes.
> You could base the mtd changes on top of that?

If we all agree on that it will be immutable Roger can set up the branch
with our acks and we can all merge it in as needed. I believe v4.4-rc1
should work as a base for us all?

Regards,

Tony

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-02 15:03             ` Tony Lindgren
@ 2015-12-02 18:13               ` Brian Norris
  2015-12-02 20:05                 ` Tony Lindgren
  0 siblings, 1 reply; 79+ messages in thread
From: Brian Norris @ 2015-12-02 18:13 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Roger Quadros, dwmw2, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Boris Brezillon

On Wed, Dec 02, 2015 at 07:03:17AM -0800, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [151201 21:13]:
> > On 02/12/15 08:56, Brian Norris wrote:
> > > 
> > > I'll take another pass over your patch set, but if things are looking
> > > better, how do you expect to merge this? There are significant portions
> > > that touch at least 2 or 3 different subsystem trees, AFAICT.
> > 
> > Tony could create an immutable branch with all the dts and memory changes.
> > You could base the mtd changes on top of that?
> 
> If we all agree on that it will be immutable Roger can set up the branch
> with our acks and we can all merge it in as needed. I believe v4.4-rc1
> should work as a base for us all?

There are oustanding comments about the NAND ready/busy GPIO naming in
patch 18, which I'd like addressed. I'll re-review the rest before the
end of the day (West Coast U.S.A.). I'm not sure my acks are worth much
beyond the MTD stuff.

Regarding branches, 4.4-rc1 is fine with me.

Regards,
Brian

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-02  5:12           ` Roger Quadros
  2015-12-02 15:03             ` Tony Lindgren
@ 2015-12-02 18:43             ` Brian Norris
  1 sibling, 0 replies; 79+ messages in thread
From: Brian Norris @ 2015-12-02 18:43 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Hi Roger,

On Wed, Dec 02, 2015 at 10:42:12AM +0530, Roger Quadros wrote:
> On 02/12/15 08:56, Brian Norris wrote:
> > On Tue, Dec 01, 2015 at 04:41:16PM +0200, Roger Quadros wrote:
> >> On 30/11/15 21:54, Brian Norris wrote:
> >>> But anyway, I'm not sure that completely answered my question. My
> >>> question was whether you were removing the irqchip code solely for
> >>> performance reasons, or are there others?
> >>
> >> Yes. Only for performance reasons.
> > 
> > Hmm, that's not my favorite answer. I'd prefer that more analysis was
> > done here before scrapping irqchip...
> 
> I agree. We could retain the irqchip model till we have more satisfying
> analysis.

I won't insist, though if it's not too ugly/horrible to do so, I think
that would make sense. I'll leave it as your call.

Brian

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-02 18:13               ` Brian Norris
@ 2015-12-02 20:05                 ` Tony Lindgren
  0 siblings, 0 replies; 79+ messages in thread
From: Tony Lindgren @ 2015-12-02 20:05 UTC (permalink / raw)
  To: Brian Norris
  Cc: Roger Quadros, dwmw2, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Boris Brezillon

* Brian Norris <computersforpeace@gmail.com> [151202 10:14]:
> On Wed, Dec 02, 2015 at 07:03:17AM -0800, Tony Lindgren wrote:
> > * Roger Quadros <rogerq@ti.com> [151201 21:13]:
> > > On 02/12/15 08:56, Brian Norris wrote:
> > > > 
> > > > I'll take another pass over your patch set, but if things are looking
> > > > better, how do you expect to merge this? There are significant portions
> > > > that touch at least 2 or 3 different subsystem trees, AFAICT.
> > > 
> > > Tony could create an immutable branch with all the dts and memory changes.
> > > You could base the mtd changes on top of that?
> > 
> > If we all agree on that it will be immutable Roger can set up the branch
> > with our acks and we can all merge it in as needed. I believe v4.4-rc1
> > should work as a base for us all?
> 
> There are oustanding comments about the NAND ready/busy GPIO naming in
> patch 18, which I'd like addressed. I'll re-review the rest before the
> end of the day (West Coast U.S.A.). I'm not sure my acks are worth much
> beyond the MTD stuff.

OK, I'm happy with the gpmc related parts.

> Regarding branches, 4.4-rc1 is fine with me.

OK

Thanks,

Tony

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

* Re: [PATCH v4 11/27] mtd: nand: omap: Clean up device tree support
  2015-10-06 10:35   ` [PATCH v4 " Roger Quadros
@ 2015-12-03  4:29     ` Brian Norris
  2015-12-03  5:57       ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Brian Norris @ 2015-12-03  4:29 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Hi Roger,

On Tue, Oct 06, 2015 at 01:35:48PM +0300, Roger Quadros wrote:
> Move NAND specific device tree parsing to NAND driver.
> 
> The NAND controller node must have a compatible id, register space
> resource and interrupt resource.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>

This one's going to need rebased, as there are some conflicting of_node
changes in l2-mtd.git.

> ---
> v4: Warn if using older incompatible DT i.e. compatible property not present
> in nand node.
> 
>  arch/arm/mach-omap2/gpmc-nand.c              |   5 +-
>  drivers/memory/omap-gpmc.c                   | 143 +++++++--------------------
>  drivers/mtd/nand/omap2.c                     | 136 +++++++++++++++++++++----
>  include/linux/platform_data/mtd-nand-omap2.h |   3 +-
>  4 files changed, 155 insertions(+), 132 deletions(-)

Also, this is going to be hard to manage across trees, as you touch
three drivers all at once. Is it not possible to split any of this apart
better?

> 
> diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
> index ffe646a..e07ca27 100644
> --- a/arch/arm/mach-omap2/gpmc-nand.c
> +++ b/arch/arm/mach-omap2/gpmc-nand.c
> @@ -95,10 +95,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
>  	gpmc_nand_res[1].start = gpmc_get_irq();
>  
>  	memset(&s, 0, sizeof(struct gpmc_settings));
> -	if (gpmc_nand_data->of_node)
> -		gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
> -	else
> -		gpmc_set_legacy(gpmc_nand_data, &s);
> +	gpmc_set_legacy(gpmc_nand_data, &s);
>  
>  	s.device_nand = true;
>  
> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
> index e75226d..318c187 100644
> --- a/drivers/memory/omap-gpmc.c
> +++ b/drivers/memory/omap-gpmc.c
> @@ -29,7 +29,6 @@
>  #include <linux/of_device.h>
>  #include <linux/of_platform.h>
>  #include <linux/omap-gpmc.h>
> -#include <linux/mtd/nand.h>
>  #include <linux/pm_runtime.h>
>  
>  #include <linux/platform_data/mtd-nand-omap2.h>
> @@ -1716,105 +1715,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>  		of_property_read_bool(np, "gpmc,time-para-granularity");
>  }
>  
> -#if IS_ENABLED(CONFIG_MTD_NAND)
> -
> -static const char * const nand_xfer_types[] = {
> -	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
> -	[NAND_OMAP_POLLED]			= "polled",
> -	[NAND_OMAP_PREFETCH_DMA]		= "prefetch-dma",
> -	[NAND_OMAP_PREFETCH_IRQ]		= "prefetch-irq",
> -};
> -
> -static int gpmc_probe_nand_child(struct platform_device *pdev,
> -				 struct device_node *child)
> -{
> -	u32 val;
> -	const char *s;
> -	struct gpmc_timings gpmc_t;
> -	struct omap_nand_platform_data *gpmc_nand_data;
> -
> -	if (of_property_read_u32(child, "reg", &val) < 0) {
> -		dev_err(&pdev->dev, "%s has no 'reg' property\n",
> -			child->full_name);
> -		return -ENODEV;
> -	}
> -
> -	gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data),
> -				      GFP_KERNEL);
> -	if (!gpmc_nand_data)
> -		return -ENOMEM;
> -
> -	gpmc_nand_data->cs = val;
> -	gpmc_nand_data->of_node = child;
> -
> -	/* Detect availability of ELM module */
> -	gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
> -	if (gpmc_nand_data->elm_of_node == NULL)
> -		gpmc_nand_data->elm_of_node =
> -					of_parse_phandle(child, "elm_id", 0);
> -
> -	/* select ecc-scheme for NAND */
> -	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
> -		pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
> -		return -ENODEV;
> -	}
> -
> -	if (!strcmp(s, "sw"))
> -		gpmc_nand_data->ecc_opt = OMAP_ECC_HAM1_CODE_SW;
> -	else if (!strcmp(s, "ham1") ||
> -		 !strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
> -		gpmc_nand_data->ecc_opt =
> -				OMAP_ECC_HAM1_CODE_HW;
> -	else if (!strcmp(s, "bch4"))
> -		if (gpmc_nand_data->elm_of_node)
> -			gpmc_nand_data->ecc_opt =
> -				OMAP_ECC_BCH4_CODE_HW;
> -		else
> -			gpmc_nand_data->ecc_opt =
> -				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
> -	else if (!strcmp(s, "bch8"))
> -		if (gpmc_nand_data->elm_of_node)
> -			gpmc_nand_data->ecc_opt =
> -				OMAP_ECC_BCH8_CODE_HW;
> -		else
> -			gpmc_nand_data->ecc_opt =
> -				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
> -	else if (!strcmp(s, "bch16"))
> -		if (gpmc_nand_data->elm_of_node)
> -			gpmc_nand_data->ecc_opt =
> -				OMAP_ECC_BCH16_CODE_HW;
> -		else
> -			pr_err("%s: BCH16 requires ELM support\n", __func__);
> -	else
> -		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
> -
> -	/* select data transfer mode for NAND controller */
> -	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
> -		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
> -			if (!strcasecmp(s, nand_xfer_types[val])) {
> -				gpmc_nand_data->xfer_type = val;
> -				break;
> -			}
> -
> -	gpmc_nand_data->flash_bbt = of_get_nand_on_flash_bbt(child);
> -
> -	val = of_get_nand_bus_width(child);
> -	if (val == 16)
> -		gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
> -
> -	gpmc_read_timings_dt(child, &gpmc_t);
> -	gpmc_nand_init(gpmc_nand_data, &gpmc_t);
> -
> -	return 0;
> -}
> -#else
> -static int gpmc_probe_nand_child(struct platform_device *pdev,
> -				 struct device_node *child)
> -{
> -	return 0;
> -}
> -#endif
> -
>  #if IS_ENABLED(CONFIG_MTD_ONENAND)
>  static int gpmc_probe_onenand_child(struct platform_device *pdev,
>  				 struct device_node *child)
> @@ -1933,9 +1833,42 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
>  		goto err;
>  	}
>  
> -	ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
> -	if (ret < 0)
> -		goto err;
> +	if (of_node_cmp(child->name, "nand") == 0) {
> +		/* NAND specific setup */
> +		u32 val;
> +
> +		/* Warn about older DT blobs with no compatible property */
> +		if (!of_property_read_bool(child, "compatible")) {
> +			dev_warn(&pdev->dev,
> +				 "Incompatible NAND node: missing compatible");
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +
> +		val = of_get_nand_bus_width(child);
> +		switch (val) {
> +		case 8:
> +			gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
> +			break;
> +		case 16:
> +			gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
> +			break;
> +		default:
> +			dev_err(&pdev->dev, "%s: invalid 'nand-bus-width'\n",
> +				child->name);
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +
> +		/* disable write protect */
> +		gpmc_configure(GPMC_CONFIG_WP, 0);
> +		gpmc_s.device_nand = true;
> +	} else {
> +		ret = of_property_read_u32(child, "bank-width",
> +					   &gpmc_s.device_width);
> +		if (ret < 0)
> +			goto err;
> +	}
>  
>  	ret = gpmc_cs_program_settings(cs, &gpmc_s);
>  	if (ret < 0)
> @@ -2018,9 +1951,7 @@ static int gpmc_probe_dt(struct platform_device *pdev)
>  		if (!child->name)
>  			continue;
>  
> -		if (of_node_cmp(child->name, "nand") == 0)
> -			ret = gpmc_probe_nand_child(pdev, child);
> -		else if (of_node_cmp(child->name, "onenand") == 0)
> +		if (of_node_cmp(child->name, "onenand") == 0)
>  			ret = gpmc_probe_onenand_child(pdev, child);
>  		else
>  			ret = gpmc_probe_generic_child(pdev, child);
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index c35405c..228f498 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -24,6 +24,7 @@
>  #include <linux/slab.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/of_mtd.h>
>  
>  #include <linux/mtd/nand_bch.h>
>  #include <linux/platform_data/elm.h>
> @@ -177,6 +178,8 @@ struct omap_nand_info {
>  	struct gpmc_nand_regs		reg;
>  	struct gpmc_nand_ops		*ops;
>  	/* generated at runtime depending on ECC algorithm and layout selected */
> +	bool				flash_bbt;
> +	/* generated at runtime depending on ECC algorithm and layout */
>  	struct nand_ecclayout		oobinfo;
>  	/* fields specific for BCHx_HW ECC scheme */
>  	struct device			*elm_dev;
> @@ -1668,10 +1671,84 @@ static bool omap2_nand_ecc_check(struct omap_nand_info *info,
>  	return true;
>  }
>  
> +static const char * const nand_xfer_types[] = {
> +	[NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled",
> +	[NAND_OMAP_POLLED] = "polled",
> +	[NAND_OMAP_PREFETCH_DMA] = "prefetch-dma",
> +	[NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq",
> +};
> +
> +static int omap_get_dt_info(struct device *dev, struct omap_nand_info *info)
> +{
> +	struct device_node *child = dev->of_node;
> +	int i;
> +	const char *s;
> +
> +	/* In old bindings, CS num is embedded in reg property */
> +	if (of_property_read_u32(child, "reg", &info->gpmc_cs) < 0) {
> +		dev_err(dev, "reg not found in DT\n");
> +		return -EINVAL;
> +	}
> +
> +	/* detect availability of ELM module. Won't be present pre-OMAP4 */
> +	info->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
> +	if (!info->elm_of_node)
> +		dev_dbg(dev, "ti,elm-id not in DT\n");
> +
> +	/* select ecc-scheme for NAND */
> +	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
> +		dev_err(dev, "ti,nand-ecc-opt not found\n");
> +		return -EINVAL;
> +	}
> +
> +	if (!strcmp(s, "sw")) {
> +		info->ecc_opt = OMAP_ECC_HAM1_CODE_SW;
> +	} else if (!strcmp(s, "ham1") ||
> +		   !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) {
> +		info->ecc_opt =	OMAP_ECC_HAM1_CODE_HW;
> +	} else if (!strcmp(s, "bch4")) {
> +		if (info->elm_of_node)
> +			info->ecc_opt = OMAP_ECC_BCH4_CODE_HW;
> +		else
> +			info->ecc_opt = OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
> +	} else if (!strcmp(s, "bch8")) {
> +		if (info->elm_of_node)
> +			info->ecc_opt = OMAP_ECC_BCH8_CODE_HW;
> +		else
> +			info->ecc_opt = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
> +	} else if (!strcmp(s, "bch16")) {
> +		info->ecc_opt =	OMAP_ECC_BCH16_CODE_HW;
> +	} else {
> +		dev_err(dev, "unrecognized value for ti,nand-ecc-opt\n");
> +		return -EINVAL;
> +	}
> +
> +	/* select data transfer mode */
> +	if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) {
> +		for (i = 0; i < ARRAY_SIZE(nand_xfer_types); i++) {
> +			if (!strcasecmp(s, nand_xfer_types[i])) {
> +				info->xfer_type = i;
> +				goto next;
> +			}
> +		}
> +
> +		dev_err(dev, "unrecognized value for ti,nand-xfer-type\n");
> +		return -EINVAL;
> +	}
> +
> +next:
> +	of_get_nand_on_flash_bbt(child);
> +
> +	if (of_get_nand_bus_width(child) == 16)
> +		info->devsize = NAND_BUSWIDTH_16;
> +
> +	return 0;
> +}
> +
>  static int omap_nand_probe(struct platform_device *pdev)
>  {
>  	struct omap_nand_info		*info;
> -	struct omap_nand_platform_data	*pdata;
> +	struct omap_nand_platform_data	*pdata = NULL;
>  	struct mtd_info			*mtd;
>  	struct nand_chip		*nand_chip;
>  	struct nand_ecclayout		*ecclayout;
> @@ -1682,33 +1759,42 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	unsigned			oob_index;
>  	struct resource			*res;
>  	struct mtd_part_parser_data	ppdata = {};
> -
> -	pdata = dev_get_platdata(&pdev->dev);
> -	if (pdata == NULL) {
> -		dev_err(&pdev->dev, "platform data missing\n");
> -		return -ENODEV;
> -	}
> +	struct device			*dev = &pdev->dev;
>  
>  	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
>  				GFP_KERNEL);
>  	if (!info)
>  		return -ENOMEM;
>  
> -	platform_set_drvdata(pdev, info);
> +	info->pdev = pdev;
>  
> +	if (dev->of_node) {
> +		if (omap_get_dt_info(dev, info))
> +			return -EINVAL;
> +	} else {
> +		pdata = dev_get_platdata(&pdev->dev);
> +		if (!pdata) {
> +			dev_err(&pdev->dev, "platform data missing\n");
> +			return -EINVAL;
> +		}
> +
> +		info->gpmc_cs = pdata->cs;
> +		info->reg = pdata->reg;
> +		info->of_node = pdata->of_node;
> +		info->ecc_opt = pdata->ecc_opt;
> +		info->dev_ready	= pdata->dev_ready;
> +		info->xfer_type = pdata->xfer_type;
> +		info->devsize = pdata->devsize;
> +		info->elm_of_node = pdata->elm_of_node;
> +		info->flash_bbt = pdata->flash_bbt;
> +	}
> +
> +	platform_set_drvdata(pdev, info);
>  	info->ops = gpmc_omap_get_nand_ops(&info->reg, info->gpmc_cs);
>  	if (!info->ops) {
>  		dev_err(&pdev->dev, "Failed to get GPMC->NAND interface\n");
>  		return -ENODEV;
>  	}
> -	info->pdev		= pdev;
> -	info->gpmc_cs		= pdata->cs;
> -	info->of_node		= pdata->of_node;
> -	info->ecc_opt		= pdata->ecc_opt;
> -	info->dev_ready	= pdata->dev_ready;
> -	info->xfer_type = pdata->xfer_type;
> -	info->devsize = pdata->devsize;
> -	info->elm_of_node = pdata->elm_of_node;
>  
>  	mtd			= &info->mtd;
>  	mtd->priv		= &info->nand;
> @@ -1744,7 +1830,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		nand_chip->chip_delay = 50;
>  	}
>  
> -	if (pdata->flash_bbt)
> +	if (info->flash_bbt)
>  		nand_chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
>  	else
>  		nand_chip->options |= NAND_SKIP_BBTSCAN;
> @@ -2049,9 +2135,13 @@ scan_tail:
>  		goto return_error;
>  	}
>  
> -	ppdata.of_node = pdata->of_node;
> -	mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts,
> -				  pdata->nr_parts);
> +	if (dev->of_node) {
> +		ppdata.of_node = dev->of_node;

The latest l2-mtd.git changed how the partitions' of_node is passed. Now
this is handled by nand_set_flash_node().

> +		mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
> +
> +	} else {
> +		mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
> +	}
>  
>  	platform_set_drvdata(pdev, mtd);
>  
> @@ -2083,11 +2173,17 @@ static int omap_nand_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +static const struct of_device_id omap_nand_ids[] = {
> +	{ .compatible = "ti,omap2-nand", },
> +	{},
> +};
> +
>  static struct platform_driver omap_nand_driver = {
>  	.probe		= omap_nand_probe,
>  	.remove		= omap_nand_remove,
>  	.driver		= {
>  		.name	= DRIVER_NAME,
> +		.of_match_table = of_match_ptr(omap_nand_ids),
>  	},
>  };
>  
> diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
> index a067f58..ff27e5a 100644
> --- a/include/linux/platform_data/mtd-nand-omap2.h
> +++ b/include/linux/platform_data/mtd-nand-omap2.h
> @@ -76,11 +76,10 @@ struct omap_nand_platform_data {
>  	int			devsize;
>  	enum omap_ecc           ecc_opt;
>  
> -	/* for passing the partitions */
> -	struct device_node	*of_node;
>  	struct device_node	*elm_of_node;
>  
>  	/* deprecated */
>  	struct gpmc_nand_regs	reg;
> +	struct device_node	*of_node;

I'm a little confused here. Do you have a mixed platform data / device
tree setup here? That's odd. (It also seems if that was really
necessary, you could have the board file set pdev->dev.of_node before
registering it, then you don't need this field.) But really, if you're
partly using device tree, can't you just convert completely? Or is this
a two-phase process, and you're planning to convert omap2 to full device
tree?

>  };
>  #endif

Brian

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

* Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib
  2015-10-27  8:28     ` Boris Brezillon
@ 2015-12-03  4:45       ` Brian Norris
  2015-12-03  8:41         ` Boris Brezillon
  0 siblings, 1 reply; 79+ messages in thread
From: Brian Norris @ 2015-12-03  4:45 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Roger Quadros, tony, dwmw2, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Alex Smith,
	Harvey Hunt

(to be clear, this branch of discussion isn't directly regarding the TI
changes; we can handle any generic handling afterward, as long as we get
the DT binding right now)

On Tue, Oct 27, 2015 at 09:28:32AM +0100, Boris Brezillon wrote:
> On Mon, 26 Oct 2015 13:49:00 -0700
> Brian Norris <computersforpeace@gmail.com> wrote:
> > On Fri, Sep 18, 2015 at 05:53:40PM +0300, Roger Quadros wrote:
> > > @@ -1782,7 +1780,9 @@ static int omap_nand_probe(struct platform_device *pdev)
> > >  		info->reg = pdata->reg;
> > >  		info->of_node = pdata->of_node;
> > >  		info->ecc_opt = pdata->ecc_opt;
> > > -		info->dev_ready	= pdata->dev_ready;
> > > +		if (pdata->dev_ready)
> > > +			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
> > > +
> > >  		info->xfer_type = pdata->xfer_type;
> > >  		info->devsize = pdata->devsize;
> > >  		info->elm_of_node = pdata->elm_of_node;
> > > @@ -1815,6 +1815,13 @@ static int omap_nand_probe(struct platform_device *pdev)
> > >  	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
> > >  	nand_chip->cmd_ctrl  = omap_hwcontrol;
> > >  
> > > +	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "ready",
> > > +						    GPIOD_IN);
> > 
> > Others have been looking at using GPIOs for the ready/busy pin too. At a
> > minimum, we need an updated DT binding doc for this, since I see you're
> > adding this via device tree in a later patch (I don't see any DT binding
> > patch for this; but I could just be overlooking it). It'd also be great
> > if this support was moved to nand_dt_init() so other platforms can
> > benefit, but I won't require that.
> 
> Actually I started to work on a generic solution parsing the DT and
> creating CS, WP and RB gpios when they are provided, but I think it's a
> bit more complicated than just moving the rb-gpios parsing into
> nand_dt_init().
> First you'll need something to store your gpio_desc pointers, which
> means you'll have to allocate a table of gpio_desc pointers (or a table
> of struct embedding a gpio_desc pointer).

I'm not sure what you mean by table. It seems like we would just have a
few gpio_desc pointers in struct nand_chip, no?

> The other blocking point is that when nand_scan_ident() is called, the
> caller is supposed to have filled the ->dev_ready() or ->waitfunc()
> fields, and to choose how to implement it he may need to know
> which kind of RB handler should be used (this is the case in the sunxi
> driver, where the user can either use a GPIO or native R/B pin directly
> connected to the controller).

Right, I was thinking about this one.

> All this makes me think that maybe nand_dt_init() should be called
> separately or in a different helper (nand_init() ?) taking care of the
> basic nand_chip initializations/allocations without interacting with
> the NAND itself.

Yeah, I feel like there have been other good reasons for something like
this before, and we just have worked around them so far. Maybe something
more like the alloc/add split in many other subsystems? e.g.,
platform_device_{alloc,add}, spi_{alloc,add}_device. Now we might want
nand_alloc()?

On a slight tangent, it seems silly that nand_scan_tail() doesn't
register the MTD, but nand_release() unregisters it. That shouldn't be.

> Another solution would be to add an ->init() function to nand_chip
> and call it after the generic initialization has been done (but before
> NAND chip detection). This way the NAND controller driver could adapt
> some fields and parse controller specific properties.

That could work too, I guess.

> What do you think?

Brian

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

* Re: [PATCH v3 04/27] mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers
  2015-09-18 14:53 ` [PATCH v3 04/27] mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers Roger Quadros
@ 2015-12-03  5:00   ` Brian Norris
  0 siblings, 0 replies; 79+ messages in thread
From: Brian Norris @ 2015-12-03  5:00 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

On Fri, Sep 18, 2015 at 05:53:26PM +0300, Roger Quadros wrote:
> Deprecate nand register passing via platform data and use
> gpmc_omap_get_nand_ops() instead.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  arch/arm/mach-omap2/gpmc-nand.c              | 2 --
>  drivers/mtd/nand/omap2.c                     | 9 ++++++++-
>  include/linux/platform_data/mtd-nand-omap2.h | 4 +++-
>  3 files changed, 11 insertions(+), 4 deletions(-)

This one also seems a bit oddly-split, if you're trying to allow
bringing these into different trees. The nand/omap2.c changes seem like
they can be done completely on their own (after the previous patches),
and the arch/arm/mach-omap2/gpmc-nand.c and
include/linux/platform_data/mtd-nand-omap2.h changes can come in their
own patch afterward.

That does still make things a little complicated for applying to
different trees, though, as we have some arch/arm -> drivers/mtd ->
arch/arm dependencies.

If it helps, I can try to provide Tony with a stable v4.4-rc1-based
piece of the MTD tree, and just take everything through there (with
acks). (FWIW, everything in l2-mtd.git can be considered stable,
git-wise. I've been keeping a clean history. But it'd be best to
coordinate what points to cross-merge.)

Then if we do that, we'd have to keep a close eye to make sure I don't
take any more conflicting changes to drivers/mtd/nand/omap2.c, or else
do another cross-merge...

Any better suggestions?

Brian

> 
> diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
> index 72918c4..04e6998 100644
> --- a/arch/arm/mach-omap2/gpmc-nand.c
> +++ b/arch/arm/mach-omap2/gpmc-nand.c
> @@ -121,8 +121,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
>  	if (err < 0)
>  		goto out_free_cs;
>  
> -	gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
> -
>  	if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
>  		pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
>  		err = -EINVAL;
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 60fa899..f214fe2 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -28,6 +28,7 @@
>  #include <linux/mtd/nand_bch.h>
>  #include <linux/platform_data/elm.h>
>  
> +#include <linux/omap-gpmc.h>
>  #include <linux/platform_data/mtd-nand-omap2.h>
>  
>  #define	DRIVER_NAME	"omap2-nand"
> @@ -169,7 +170,9 @@ struct omap_nand_info {
>  	} iomode;
>  	u_char				*buf;
>  	int					buf_len;
> +	/* Interface to GPMC */
>  	struct gpmc_nand_regs		reg;
> +	struct gpmc_nand_ops		*ops;
>  	/* generated at runtime depending on ECC algorithm and layout selected */
>  	struct nand_ecclayout		oobinfo;
>  	/* fields specific for BCHx_HW ECC scheme */
> @@ -1677,9 +1680,13 @@ static int omap_nand_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, info);
>  
> +	info->ops = gpmc_omap_get_nand_ops(&info->reg, info->gpmc_cs);
> +	if (!info->ops) {
> +		dev_err(&pdev->dev, "Failed to get GPMC->NAND interface\n");
> +		return -ENODEV;
> +	}
>  	info->pdev		= pdev;
>  	info->gpmc_cs		= pdata->cs;
> -	info->reg		= pdata->reg;
>  	info->of_node		= pdata->of_node;
>  	info->ecc_opt		= pdata->ecc_opt;
>  	mtd			= &info->mtd;
> diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
> index 090bbab..a067f58 100644
> --- a/include/linux/platform_data/mtd-nand-omap2.h
> +++ b/include/linux/platform_data/mtd-nand-omap2.h
> @@ -75,10 +75,12 @@ struct omap_nand_platform_data {
>  	enum nand_io		xfer_type;
>  	int			devsize;
>  	enum omap_ecc           ecc_opt;
> -	struct gpmc_nand_regs	reg;
>  
>  	/* for passing the partitions */
>  	struct device_node	*of_node;
>  	struct device_node	*elm_of_node;
> +
> +	/* deprecated */
> +	struct gpmc_nand_regs	reg;
>  };
>  #endif
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
                   ` (29 preceding siblings ...)
  2015-10-26 21:23 ` Brian Norris
@ 2015-12-03  5:09 ` Brian Norris
  2015-12-03  6:08   ` Roger Quadros
  30 siblings, 1 reply; 79+ messages in thread
From: Brian Norris @ 2015-12-03  5:09 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Hi,

On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
> Hi,
> 
> We do a couple of things in this series which result in
> cleaner device tree implementation, faster perfomance and
> multi-platform support. As an added bonus we get new GPI/Interrupt pins
> for use in the system.
> 
> - Establish a custom interface between NAND and GPMC driver. This is
> needed because all of the NAND registers sit in the GPMC register space.
> Some bits like NAND IRQ are even shared with GPMC.
> 
> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
> This causes performance increase when using prefetch-irq mode.
> 30% increase in read, 17% increase in write in prefetch-irq mode.
> 
> - Clean up device tree support so that omap-gpmc IP and the omap2 NAND
> driver can be used on non-OMAP platforms. e.g. Keystone.
> 
> - Implement GPIOCHIP + IRQCHIP for the GPMC WAITPINS. SoCs can contain
> 2 to 4 of these and most of them would be unused otherwise. It also
> allows a cleaner implementation of NAND Ready pin status for the NAND driver.
> 
> - Implement GPIOlib based NAND ready pin checking for OMAP NAND driver.
> 
> This series is available at
> git@github.com:rogerq/linux.git
> in branch
> for-v4.4/gpmc-v3
> 
> cheers,
> -roger
> 
> Changelog:
> v3:
> -Fixed and tested NAND using legacy boot on omap3-beagle.
> -Support rising and falling edge interrupts on WAITpins.
> -Update DT node of all gpmc users.

The MTD stuff looks mostly good to me know. I've made all my comments
for now, but I'm not sure how you're going to end up rebasing/splitting
and what you're going to do with the irqchip removal, so I'll refrain
from ack's for now. Hopefully I can either ack or merge v4.

I brought it up on one other patch, but it's not really clear to me what
the split is on board file vs. device tree handling, since you seem to
have a combination of both (i.e., platform data that passes along device
nodes). What's the plan on that?

And of course, there's the question of how exactly to merge this, given
the:
(1) conflicts already existing in the MTD dev tree
(2) this touches several trees, often in the same patch and
(3) even if the patches were split out a little better into MTD and
    non-MTD stuff, I think there would still be dependencies such that
    we'd need at least 1 (probably 2) cross merges to get it all
    straight

I'd be happy to hear your thoughts.

Brian

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

* Re: [PATCH v4 11/27] mtd: nand: omap: Clean up device tree support
  2015-12-03  4:29     ` Brian Norris
@ 2015-12-03  5:57       ` Roger Quadros
  2015-12-03  6:09         ` Brian Norris
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-12-03  5:57 UTC (permalink / raw)
  To: Brian Norris
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Brian,

On 03/12/15 09:59, Brian Norris wrote:
> Hi Roger,
> 
> On Tue, Oct 06, 2015 at 01:35:48PM +0300, Roger Quadros wrote:
>> Move NAND specific device tree parsing to NAND driver.
>>
>> The NAND controller node must have a compatible id, register space
>> resource and interrupt resource.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
> 
> This one's going to need rebased, as there are some conflicting of_node
> changes in l2-mtd.git.

Al right. I'll rebase on top of l2-mtd.git
> 
>> ---
>> v4: Warn if using older incompatible DT i.e. compatible property not present
>> in nand node.
>>
>>  arch/arm/mach-omap2/gpmc-nand.c              |   5 +-
>>  drivers/memory/omap-gpmc.c                   | 143 +++++++--------------------
>>  drivers/mtd/nand/omap2.c                     | 136 +++++++++++++++++++++----
>>  include/linux/platform_data/mtd-nand-omap2.h |   3 +-
>>  4 files changed, 155 insertions(+), 132 deletions(-)
> 
> Also, this is going to be hard to manage across trees, as you touch
> three drivers all at once. Is it not possible to split any of this apart
> better?

Will need some more effort and I can do it. Butm if we're going to start
an with immutable branch with everything in, is it worth the effort?
> 
>>
>> diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
>> index ffe646a..e07ca27 100644
>> --- a/arch/arm/mach-omap2/gpmc-nand.c
>> +++ b/arch/arm/mach-omap2/gpmc-nand.c
>> @@ -95,10 +95,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
>>  	gpmc_nand_res[1].start = gpmc_get_irq();
>>  
>>  	memset(&s, 0, sizeof(struct gpmc_settings));
>> -	if (gpmc_nand_data->of_node)
>> -		gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
>> -	else
>> -		gpmc_set_legacy(gpmc_nand_data, &s);
>> +	gpmc_set_legacy(gpmc_nand_data, &s);
>>  
>>  	s.device_nand = true;
>>  
>> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
>> index e75226d..318c187 100644
>> --- a/drivers/memory/omap-gpmc.c
>> +++ b/drivers/memory/omap-gpmc.c
>> @@ -29,7 +29,6 @@
>>  #include <linux/of_device.h>
>>  #include <linux/of_platform.h>
>>  #include <linux/omap-gpmc.h>
>> -#include <linux/mtd/nand.h>
>>  #include <linux/pm_runtime.h>
>>  

<snip>

>>  
>> -	ppdata.of_node = pdata->of_node;
>> -	mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts,
>> -				  pdata->nr_parts);
>> +	if (dev->of_node) {
>> +		ppdata.of_node = dev->of_node;
> 
> The latest l2-mtd.git changed how the partitions' of_node is passed. Now
> this is handled by nand_set_flash_node().

OK.
> 
>> +		mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
>> +
>> +	} else {
>> +		mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
>> +	}
>>  
>>  	platform_set_drvdata(pdev, mtd);
>>  
>> @@ -2083,11 +2173,17 @@ static int omap_nand_remove(struct platform_device *pdev)
>>  	return 0;
>>  }
>>  
>> +static const struct of_device_id omap_nand_ids[] = {
>> +	{ .compatible = "ti,omap2-nand", },
>> +	{},
>> +};
>> +
>>  static struct platform_driver omap_nand_driver = {
>>  	.probe		= omap_nand_probe,
>>  	.remove		= omap_nand_remove,
>>  	.driver		= {
>>  		.name	= DRIVER_NAME,
>> +		.of_match_table = of_match_ptr(omap_nand_ids),
>>  	},
>>  };
>>  
>> diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
>> index a067f58..ff27e5a 100644
>> --- a/include/linux/platform_data/mtd-nand-omap2.h
>> +++ b/include/linux/platform_data/mtd-nand-omap2.h
>> @@ -76,11 +76,10 @@ struct omap_nand_platform_data {
>>  	int			devsize;
>>  	enum omap_ecc           ecc_opt;
>>  
>> -	/* for passing the partitions */
>> -	struct device_node	*of_node;
>>  	struct device_node	*elm_of_node;
>>  
>>  	/* deprecated */
>>  	struct gpmc_nand_regs	reg;
>> +	struct device_node	*of_node;
> 
> I'm a little confused here. Do you have a mixed platform data / device
> tree setup here? That's odd. (It also seems if that was really
> necessary, you could have the board file set pdev->dev.of_node before
> registering it, then you don't need this field.) But really, if you're
> partly using device tree, can't you just convert completely? Or is this
> a two-phase process, and you're planning to convert omap2 to full device
> tree?

The existing device tree implementation for omap2-nand was like this:
omap-gpmc.c driver was creating a platform device for the nand device and
passing the device node via platform data.

After this series we no longer do this and that's why of_node is marked
deprecated in platform data. I might as well could just get rid of it
but wasn't sure of how we're going to integrate the changes into the
subsystem trees so just marked it deprecated.

cheers,
-roger

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-03  5:09 ` Brian Norris
@ 2015-12-03  6:08   ` Roger Quadros
  2015-12-03  6:22     ` Brian Norris
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-12-03  6:08 UTC (permalink / raw)
  To: Brian Norris
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Brian,

On 03/12/15 10:39, Brian Norris wrote:
> Hi,
> 
> On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
>> Hi,
>>
>> We do a couple of things in this series which result in
>> cleaner device tree implementation, faster perfomance and
>> multi-platform support. As an added bonus we get new GPI/Interrupt pins
>> for use in the system.
>>
>> - Establish a custom interface between NAND and GPMC driver. This is
>> needed because all of the NAND registers sit in the GPMC register space.
>> Some bits like NAND IRQ are even shared with GPMC.
>>
>> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
>> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
>> This causes performance increase when using prefetch-irq mode.
>> 30% increase in read, 17% increase in write in prefetch-irq mode.
>>
>> - Clean up device tree support so that omap-gpmc IP and the omap2 NAND
>> driver can be used on non-OMAP platforms. e.g. Keystone.
>>
>> - Implement GPIOCHIP + IRQCHIP for the GPMC WAITPINS. SoCs can contain
>> 2 to 4 of these and most of them would be unused otherwise. It also
>> allows a cleaner implementation of NAND Ready pin status for the NAND driver.
>>
>> - Implement GPIOlib based NAND ready pin checking for OMAP NAND driver.
>>
>> This series is available at
>> git@github.com:rogerq/linux.git
>> in branch
>> for-v4.4/gpmc-v3
>>
>> cheers,
>> -roger
>>
>> Changelog:
>> v3:
>> -Fixed and tested NAND using legacy boot on omap3-beagle.
>> -Support rising and falling edge interrupts on WAITpins.
>> -Update DT node of all gpmc users.
> 
> The MTD stuff looks mostly good to me know. I've made all my comments
> for now, but I'm not sure how you're going to end up rebasing/splitting
> and what you're going to do with the irqchip removal, so I'll refrain
> from ack's for now. Hopefully I can either ack or merge v4.

I'll retain the irqchip model for now and send a v4 with all comments
addressed and better subsystem wise patch split.

> 
> I brought it up on one other patch, but it's not really clear to me what
> the split is on board file vs. device tree handling, since you seem to
> have a combination of both (i.e., platform data that passes along device
> nodes). What's the plan on that?

Platform data no longer passes device nodes. We're either true device tree
or plain legacy. The deprecated fields are no longer used once the series is
applied.

> 
> And of course, there's the question of how exactly to merge this, given
> the:
> (1) conflicts already existing in the MTD dev tree

I'll rebase the series on top of MTD dev tree.

> (2) this touches several trees, often in the same patch and

I'll try my best to split the patches but not sure if this could be 100%
clean split without functional breakage.

> (3) even if the patches were split out a little better into MTD and
>     non-MTD stuff, I think there would still be dependencies such that
>     we'd need at least 1 (probably 2) cross merges to get it all
>     straight

That is correct.
Is it OK if functionality breaks if for example only MTD changes are considered?

cheers,
-roger

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

* Re: [PATCH v4 11/27] mtd: nand: omap: Clean up device tree support
  2015-12-03  5:57       ` Roger Quadros
@ 2015-12-03  6:09         ` Brian Norris
  0 siblings, 0 replies; 79+ messages in thread
From: Brian Norris @ 2015-12-03  6:09 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

On Thu, Dec 03, 2015 at 11:27:13AM +0530, Roger Quadros wrote:
> On 03/12/15 09:59, Brian Norris wrote:
> > On Tue, Oct 06, 2015 at 01:35:48PM +0300, Roger Quadros wrote:
> >>  arch/arm/mach-omap2/gpmc-nand.c              |   5 +-
> >>  drivers/memory/omap-gpmc.c                   | 143 +++++++--------------------
> >>  drivers/mtd/nand/omap2.c                     | 136 +++++++++++++++++++++----
> >>  include/linux/platform_data/mtd-nand-omap2.h |   3 +-
> >>  4 files changed, 155 insertions(+), 132 deletions(-)
> > 
> > Also, this is going to be hard to manage across trees, as you touch
> > three drivers all at once. Is it not possible to split any of this apart
> > better?
> 
> Will need some more effort and I can do it. Butm if we're going to start
> an with immutable branch with everything in, is it worth the effort?

I don't think I noticed the "everything in it" part. I was assuming
you'd have non-MTD changes in the immutable branch, and MTD stuff on
top. But that is indeed more difficult. I'm fine with everything going
in one branch, and pulling that all into MTD.

Then the hangup is that you'll need to have some of l2-mtd.git in that
branch as a prerequisite, if you're going to rebase. Or else I have to
fix it up when merging back into l2-mtd.git...

...

> >> diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
> >> index a067f58..ff27e5a 100644
> >> --- a/include/linux/platform_data/mtd-nand-omap2.h
> >> +++ b/include/linux/platform_data/mtd-nand-omap2.h
> >> @@ -76,11 +76,10 @@ struct omap_nand_platform_data {
> >>  	int			devsize;
> >>  	enum omap_ecc           ecc_opt;
> >>  
> >> -	/* for passing the partitions */
> >> -	struct device_node	*of_node;
> >>  	struct device_node	*elm_of_node;
> >>  
> >>  	/* deprecated */
> >>  	struct gpmc_nand_regs	reg;
> >> +	struct device_node	*of_node;
> > 
> > I'm a little confused here. Do you have a mixed platform data / device
> > tree setup here? That's odd. (It also seems if that was really
> > necessary, you could have the board file set pdev->dev.of_node before
> > registering it, then you don't need this field.) But really, if you're
> > partly using device tree, can't you just convert completely? Or is this
> > a two-phase process, and you're planning to convert omap2 to full device
> > tree?
> 
> The existing device tree implementation for omap2-nand was like this:
> omap-gpmc.c driver was creating a platform device for the nand device and
> passing the device node via platform data.
> 
> After this series we no longer do this and that's why of_node is marked
> deprecated in platform data. I might as well could just get rid of it
> but wasn't sure of how we're going to integrate the changes into the
> subsystem trees so just marked it deprecated.

Whoops, sorry I didn't read the "deprecated" header there this time. I
thought the movement was odd. *facepalm*

But yes, especially if we're putting everything in one branch, it'd be
more clear to simply kill off things instead of marking things
deprecated. It's especially confusing, since you're actually still using
the field.

Brian

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-03  6:08   ` Roger Quadros
@ 2015-12-03  6:22     ` Brian Norris
  2015-12-03  9:01       ` Roger Quadros
  0 siblings, 1 reply; 79+ messages in thread
From: Brian Norris @ 2015-12-03  6:22 UTC (permalink / raw)
  To: Roger Quadros
  Cc: tony, dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd,
	linux-omap, devicetree, linux-kernel

Hi,

On Thu, Dec 03, 2015 at 11:38:14AM +0530, Roger Quadros wrote:
> On 03/12/15 10:39, Brian Norris wrote:
> > On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
> >> We do a couple of things in this series which result in
> >> cleaner device tree implementation, faster perfomance and
> >> multi-platform support. As an added bonus we get new GPI/Interrupt pins
> >> for use in the system.
> >>
> >> - Establish a custom interface between NAND and GPMC driver. This is
> >> needed because all of the NAND registers sit in the GPMC register space.
> >> Some bits like NAND IRQ are even shared with GPMC.
> >>
> >> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
> >> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
> >> This causes performance increase when using prefetch-irq mode.
> >> 30% increase in read, 17% increase in write in prefetch-irq mode.
> >>
> >> - Clean up device tree support so that omap-gpmc IP and the omap2 NAND
> >> driver can be used on non-OMAP platforms. e.g. Keystone.
> >>
> >> - Implement GPIOCHIP + IRQCHIP for the GPMC WAITPINS. SoCs can contain
> >> 2 to 4 of these and most of them would be unused otherwise. It also
> >> allows a cleaner implementation of NAND Ready pin status for the NAND driver.
> >>
> >> - Implement GPIOlib based NAND ready pin checking for OMAP NAND driver.
> >>
> >> This series is available at
> >> git@github.com:rogerq/linux.git
> >> in branch
> >> for-v4.4/gpmc-v3
> >>
> >> cheers,
> >> -roger
> >>
> >> Changelog:
> >> v3:
> >> -Fixed and tested NAND using legacy boot on omap3-beagle.
> >> -Support rising and falling edge interrupts on WAITpins.
> >> -Update DT node of all gpmc users.
> > 
> > The MTD stuff looks mostly good to me know. I've made all my comments
> > for now, but I'm not sure how you're going to end up rebasing/splitting
> > and what you're going to do with the irqchip removal, so I'll refrain
> > from ack's for now. Hopefully I can either ack or merge v4.
> 
> I'll retain the irqchip model for now and send a v4 with all comments
> addressed and better subsystem wise patch split.
> 
> > 
> > I brought it up on one other patch, but it's not really clear to me what
> > the split is on board file vs. device tree handling, since you seem to
> > have a combination of both (i.e., platform data that passes along device
> > nodes). What's the plan on that?
> 
> Platform data no longer passes device nodes. We're either true device tree
> or plain legacy. The deprecated fields are no longer used once the series is
> applied.

Well, they're still sorta used (you assign info->of_node =
pdata->of_node, for instance). As dicussed in the other thread, I think
we can avoid the deprecation part and just kill the fields though, and
that would make things clearer.

> > And of course, there's the question of how exactly to merge this, given
> > the:
> > (1) conflicts already existing in the MTD dev tree
> 
> I'll rebase the series on top of MTD dev tree.

OK. FWIW, we so far only need to base them on commit a61ae81a1907 ("mtd:
nand: drop unnecessary partition parser data"). Maybe when queueing up a
branch, that'd be the best starting point for Tony, so he doesn't need
to have all of MTD's stuff in his tree too? I can set up a signed tag or
something, if that would be helpful.

But for sending patches, the latest l2-mtd.git is fine too.

> > (2) this touches several trees, often in the same patch and
> 
> I'll try my best to split the patches but not sure if this could be 100%
> clean split without functional breakage.
> 
> > (3) even if the patches were split out a little better into MTD and
> >     non-MTD stuff, I think there would still be dependencies such that
> >     we'd need at least 1 (probably 2) cross merges to get it all
> >     straight
> 
> That is correct.
> Is it OK if functionality breaks if for example only MTD changes are considered?

I think I may have misunderstood the branch proposal. If Tony queues up:

  l2-mtd.git (or just up to commit a61ae81a1907)
  +
  your patches

and I pull that back into l2-mtd.git as well, then we don't need to
worry about patches that touch multiple "trees". Just do whatever makes
things clearest, including disregarding some of my comments along the
line of (3).

Sorry for any confusion.

Brian

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

* Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib
  2015-12-03  4:45       ` Brian Norris
@ 2015-12-03  8:41         ` Boris Brezillon
  0 siblings, 0 replies; 79+ messages in thread
From: Boris Brezillon @ 2015-12-03  8:41 UTC (permalink / raw)
  To: Brian Norris
  Cc: Roger Quadros, tony, dwmw2, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel, Alex Smith,
	Harvey Hunt

Hi Brian,

On Wed, 2 Dec 2015 20:45:44 -0800
Brian Norris <computersforpeace@gmail.com> wrote:

> (to be clear, this branch of discussion isn't directly regarding the TI
> changes; we can handle any generic handling afterward, as long as we get
> the DT binding right now)
> 
> On Tue, Oct 27, 2015 at 09:28:32AM +0100, Boris Brezillon wrote:
> > On Mon, 26 Oct 2015 13:49:00 -0700
> > Brian Norris <computersforpeace@gmail.com> wrote:
> > > On Fri, Sep 18, 2015 at 05:53:40PM +0300, Roger Quadros wrote:
> > > > @@ -1782,7 +1780,9 @@ static int omap_nand_probe(struct platform_device *pdev)
> > > >  		info->reg = pdata->reg;
> > > >  		info->of_node = pdata->of_node;
> > > >  		info->ecc_opt = pdata->ecc_opt;
> > > > -		info->dev_ready	= pdata->dev_ready;
> > > > +		if (pdata->dev_ready)
> > > > +			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
> > > > +
> > > >  		info->xfer_type = pdata->xfer_type;
> > > >  		info->devsize = pdata->devsize;
> > > >  		info->elm_of_node = pdata->elm_of_node;
> > > > @@ -1815,6 +1815,13 @@ static int omap_nand_probe(struct platform_device *pdev)
> > > >  	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
> > > >  	nand_chip->cmd_ctrl  = omap_hwcontrol;
> > > >  
> > > > +	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "ready",
> > > > +						    GPIOD_IN);
> > > 
> > > Others have been looking at using GPIOs for the ready/busy pin too. At a
> > > minimum, we need an updated DT binding doc for this, since I see you're
> > > adding this via device tree in a later patch (I don't see any DT binding
> > > patch for this; but I could just be overlooking it). It'd also be great
> > > if this support was moved to nand_dt_init() so other platforms can
> > > benefit, but I won't require that.
> > 
> > Actually I started to work on a generic solution parsing the DT and
> > creating CS, WP and RB gpios when they are provided, but I think it's a
> > bit more complicated than just moving the rb-gpios parsing into
> > nand_dt_init().
> > First you'll need something to store your gpio_desc pointers, which
> > means you'll have to allocate a table of gpio_desc pointers (or a table
> > of struct embedding a gpio_desc pointer).
> 
> I'm not sure what you mean by table. It seems like we would just have a
> few gpio_desc pointers in struct nand_chip, no?

Nope, because a single nand_chip can use several CS and R/B lines,
hence the gpio_desc array.

> 
> > The other blocking point is that when nand_scan_ident() is called, the
> > caller is supposed to have filled the ->dev_ready() or ->waitfunc()
> > fields, and to choose how to implement it he may need to know
> > which kind of RB handler should be used (this is the case in the sunxi
> > driver, where the user can either use a GPIO or native R/B pin directly
> > connected to the controller).
> 
> Right, I was thinking about this one.
> 
> > All this makes me think that maybe nand_dt_init() should be called
> > separately or in a different helper (nand_init() ?) taking care of the
> > basic nand_chip initializations/allocations without interacting with
> > the NAND itself.
> 
> Yeah, I feel like there have been other good reasons for something like
> this before, and we just have worked around them so far. Maybe something
> more like the alloc/add split in many other subsystems? e.g.,
> platform_device_{alloc,add}, spi_{alloc,add}_device. Now we might want
> nand_alloc()?
> 
> On a slight tangent, it seems silly that nand_scan_tail() doesn't
> register the MTD, but nand_release() unregisters it. That shouldn't be.

Yep, that's one of the things we should address too.

> 
> > Another solution would be to add an ->init() function to nand_chip
> > and call it after the generic initialization has been done (but before
> > NAND chip detection). This way the NAND controller driver could adapt
> > some fields and parse controller specific properties.
> 
> That could work too, I guess.

Hm, all these suggestions have been made before I started my
nand_controller/nand_chip separation work, and I think we can get
something way simpler if we switch to a model where the core
implements most of the initialization steps (including parsing of
generic DT properties) and ask the controller to do its specific
initialization (as is done in the SPI subsystem for example).

If you want to have an idea of where I'm heading to, you can have a
look at the last commits in this branch [1]. The generic DT parsing is
not yet automated but it could easily be places here [2], so that when
controller->ops->add() is called everything is in place and the driver
can overload the default behavior with its own implementation.

Any objection to this approach?

Best Regards,

Boris

[1]https://github.com/bbrezillon/linux-sunxi/commits/nand/layering-rework
[2]https://github.com/bbrezillon/linux-sunxi/blob/nand/layering-rework/drivers/mtd/nand/nand_base.c#L4025

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-03  6:22     ` Brian Norris
@ 2015-12-03  9:01       ` Roger Quadros
  2015-12-03 15:17         ` Tony Lindgren
  0 siblings, 1 reply; 79+ messages in thread
From: Roger Quadros @ 2015-12-03  9:01 UTC (permalink / raw)
  To: Brian Norris, tony
  Cc: dwmw2, ezequiel, javier, fcooper, nsekhar, linux-mtd, linux-omap,
	devicetree, linux-kernel

On 03/12/15 11:52, Brian Norris wrote:
> Hi,
> 
> On Thu, Dec 03, 2015 at 11:38:14AM +0530, Roger Quadros wrote:
>> On 03/12/15 10:39, Brian Norris wrote:
>>> On Fri, Sep 18, 2015 at 05:53:22PM +0300, Roger Quadros wrote:
>>>> We do a couple of things in this series which result in
>>>> cleaner device tree implementation, faster perfomance and
>>>> multi-platform support. As an added bonus we get new GPI/Interrupt pins
>>>> for use in the system.
>>>>
>>>> - Establish a custom interface between NAND and GPMC driver. This is
>>>> needed because all of the NAND registers sit in the GPMC register space.
>>>> Some bits like NAND IRQ are even shared with GPMC.
>>>>
>>>> - Remove NAND IRQ handling from omap-gpmc driver, share the GPMC IRQ
>>>> with the omap2-nand driver and handle NAND IRQ events in the NAND driver.
>>>> This causes performance increase when using prefetch-irq mode.
>>>> 30% increase in read, 17% increase in write in prefetch-irq mode.
>>>>
>>>> - Clean up device tree support so that omap-gpmc IP and the omap2 NAND
>>>> driver can be used on non-OMAP platforms. e.g. Keystone.
>>>>
>>>> - Implement GPIOCHIP + IRQCHIP for the GPMC WAITPINS. SoCs can contain
>>>> 2 to 4 of these and most of them would be unused otherwise. It also
>>>> allows a cleaner implementation of NAND Ready pin status for the NAND driver.
>>>>
>>>> - Implement GPIOlib based NAND ready pin checking for OMAP NAND driver.
>>>>
>>>> This series is available at
>>>> git@github.com:rogerq/linux.git
>>>> in branch
>>>> for-v4.4/gpmc-v3
>>>>
>>>> cheers,
>>>> -roger
>>>>
>>>> Changelog:
>>>> v3:
>>>> -Fixed and tested NAND using legacy boot on omap3-beagle.
>>>> -Support rising and falling edge interrupts on WAITpins.
>>>> -Update DT node of all gpmc users.
>>>
>>> The MTD stuff looks mostly good to me know. I've made all my comments
>>> for now, but I'm not sure how you're going to end up rebasing/splitting
>>> and what you're going to do with the irqchip removal, so I'll refrain
>>> from ack's for now. Hopefully I can either ack or merge v4.
>>
>> I'll retain the irqchip model for now and send a v4 with all comments
>> addressed and better subsystem wise patch split.
>>
>>>
>>> I brought it up on one other patch, but it's not really clear to me what
>>> the split is on board file vs. device tree handling, since you seem to
>>> have a combination of both (i.e., platform data that passes along device
>>> nodes). What's the plan on that?
>>
>> Platform data no longer passes device nodes. We're either true device tree
>> or plain legacy. The deprecated fields are no longer used once the series is
>> applied.
> 
> Well, they're still sorta used (you assign info->of_node =
> pdata->of_node, for instance). As dicussed in the other thread, I think
> we can avoid the deprecation part and just kill the fields though, and
> that would make things clearer.
> 
>>> And of course, there's the question of how exactly to merge this, given
>>> the:
>>> (1) conflicts already existing in the MTD dev tree
>>
>> I'll rebase the series on top of MTD dev tree.
> 
> OK. FWIW, we so far only need to base them on commit a61ae81a1907 ("mtd:
> nand: drop unnecessary partition parser data"). Maybe when queueing up a
> branch, that'd be the best starting point for Tony, so he doesn't need
> to have all of MTD's stuff in his tree too? I can set up a signed tag or
> something, if that would be helpful.
> 
> But for sending patches, the latest l2-mtd.git is fine too.
> 
>>> (2) this touches several trees, often in the same patch and
>>
>> I'll try my best to split the patches but not sure if this could be 100%
>> clean split without functional breakage.
>>
>>> (3) even if the patches were split out a little better into MTD and
>>>     non-MTD stuff, I think there would still be dependencies such that
>>>     we'd need at least 1 (probably 2) cross merges to get it all
>>>     straight
>>
>> That is correct.
>> Is it OK if functionality breaks if for example only MTD changes are considered?
> 
> I think I may have misunderstood the branch proposal. If Tony queues up:
> 
>   l2-mtd.git (or just up to commit a61ae81a1907)
>   +
>   your patches
> 
> and I pull that back into l2-mtd.git as well, then we don't need to
> worry about patches that touch multiple "trees". Just do whatever makes
> things clearest, including disregarding some of my comments along the
> line of (3).

Tony,

Are you fine with this?

cheers,
-roger

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

* Re: [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms
  2015-12-03  9:01       ` Roger Quadros
@ 2015-12-03 15:17         ` Tony Lindgren
  0 siblings, 0 replies; 79+ messages in thread
From: Tony Lindgren @ 2015-12-03 15:17 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Brian Norris, dwmw2, ezequiel, javier, fcooper, nsekhar,
	linux-mtd, linux-omap, devicetree, linux-kernel

* Roger Quadros <rogerq@ti.com> [151203 01:02]:
> On 03/12/15 11:52, Brian Norris wrote:
> > On Thu, Dec 03, 2015 at 11:38:14AM +0530, Roger Quadros wrote:
> > 
> > I think I may have misunderstood the branch proposal. If Tony queues up:
> > 
> >   l2-mtd.git (or just up to commit a61ae81a1907)
> >   +
> >   your patches
> > 
> > and I pull that back into l2-mtd.git as well, then we don't need to
> > worry about patches that touch multiple "trees". Just do whatever makes
> > things clearest, including disregarding some of my comments along the
> > line of (3).
> 
> Tony,
> 
> Are you fine with this?

I'm fine with what you guys prefer as long as I have some immutable branch
I can merge in too in case of conflicts :)

Regards,

Tony

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

end of thread, other threads:[~2015-12-03 15:17 UTC | newest]

Thread overview: 79+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-18 14:53 [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
2015-09-18 14:53 ` [PATCH v3 01/27] ARM: OMAP2+: gpmc: Add platform data Roger Quadros
2015-09-18 14:53 ` [PATCH v3 02/27] ARM: OMAP2+: gpmc: Add gpmc timings and settings to " Roger Quadros
2015-09-18 14:53 ` [PATCH v3 03/27] memory: omap-gpmc: Introduce GPMC to NAND interface Roger Quadros
2015-09-18 14:53 ` [PATCH v3 04/27] mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers Roger Quadros
2015-12-03  5:00   ` Brian Norris
2015-09-18 14:53 ` [PATCH v3 05/27] memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status Roger Quadros
2015-09-18 14:53 ` [PATCH v3 06/27] mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty check Roger Quadros
2015-09-18 14:53 ` [PATCH v3 07/27] memory: omap-gpmc: Remove NAND IRQ code Roger Quadros
2015-09-18 14:53 ` [PATCH v3 08/27] memory: omap-gpmc: Add IRQ ops for GPMC-NAND interface Roger Quadros
2015-09-18 14:53 ` [PATCH v3 09/27] mtd: nand: omap2: manage NAND interrupts Roger Quadros
2015-09-18 14:53 ` [PATCH v3 10/27] mtd: nand: omap: Copy platform data parameters to omap_nand_info data Roger Quadros
2015-09-18 14:53 ` [PATCH v3 11/27] mtd: nand: omap: Clean up device tree support Roger Quadros
2015-10-06 10:35   ` [PATCH v4 " Roger Quadros
2015-12-03  4:29     ` Brian Norris
2015-12-03  5:57       ` Roger Quadros
2015-12-03  6:09         ` Brian Norris
2015-09-18 14:53 ` [PATCH v3 12/27] mtd: nand: omap: Update DT binding documentation Roger Quadros
2015-09-18 14:53 ` [PATCH v3 13/27] memory: omap-gpmc: Prevent mapping into 1st 16MB Roger Quadros
2015-09-18 14:53 ` [PATCH v3 14/27] memory: omap-gpmc: Move device tree binding to correct location Roger Quadros
2015-09-18 14:53 ` [PATCH v3 15/27] memory: omap-gpmc: Support general purpose input for WAITPINs Roger Quadros
2015-09-18 14:53 ` [PATCH v3 16/27] memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring Roger Quadros
2015-09-18 14:53 ` [PATCH v3 17/27] memory: omap-gpmc: Add irqchip support to the gpiochip Roger Quadros
2015-09-18 14:53 ` [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib Roger Quadros
2015-10-26 20:49   ` Brian Norris
2015-10-27  8:03     ` Roger Quadros
2015-10-27  8:12       ` Boris Brezillon
2015-10-27  8:43         ` Roger Quadros
2015-10-27  8:28     ` Boris Brezillon
2015-12-03  4:45       ` Brian Norris
2015-12-03  8:41         ` Boris Brezillon
2015-09-18 14:53 ` [PATCH v3 19/27] memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via gpmc_regs Roger Quadros
2015-09-18 14:53 ` [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes Roger Quadros
2015-10-14 13:34   ` Franklin S Cooper Jr.
2015-10-14 14:17     ` Roger Quadros
2015-10-14 14:37       ` Franklin S Cooper Jr.
2015-09-18 14:53 ` [PATCH v3 21/27] ARM: dts: dra7x-evm: Provide NAND ready pin Roger Quadros
2015-09-18 14:53 ` [PATCH v3 22/27] ARM: dts: am437x: Fix NAND device nodes Roger Quadros
2015-09-18 14:53 ` [PATCH v3 23/27] ARM: dts: am437x-gp-evm: Provide NAND ready pin Roger Quadros
2015-09-18 14:53 ` [PATCH v3 24/27] ARM: dts: am335x: Fix NAND device nodes Roger Quadros
2015-09-18 14:53 ` [PATCH v3 25/27] ARM: dts: am335x: Provide NAND ready pin Roger Quadros
2015-09-18 14:53 ` [PATCH v3 26/27] ARM: dts: dm816x: Fix gpmc and NAND node Roger Quadros
2015-09-18 14:53 ` [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes Roger Quadros
2015-10-13  0:43   ` Tony Lindgren
2015-10-13  6:29     ` Roger Quadros
2015-10-13 15:18       ` Tony Lindgren
2015-10-14  7:39         ` Roger Quadros
2015-10-14  8:55   ` [PATCH v4 " Roger Quadros
2015-09-30  7:39 ` [PATCH v3 00/27] memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms Roger Quadros
2015-09-30 11:00 ` Roger Quadros
2015-10-06  8:33   ` Tony Lindgren
2015-10-06  9:54     ` Roger Quadros
2015-10-06 10:00       ` Tony Lindgren
2015-10-06 10:05         ` Roger Quadros
2015-10-06 10:28           ` Roger Quadros
2015-10-06 11:01             ` Tony Lindgren
2015-10-06 11:09               ` Roger Quadros
2015-10-16 21:25                 ` Tony Lindgren
2015-10-19  7:08                   ` Roger Quadros
2015-10-21  8:31                     ` Roger Quadros
2015-10-21 15:20                       ` Tony Lindgren
2015-10-23  7:09                         ` Roger Quadros
2015-11-30 17:26                           ` Tony Lindgren
2015-10-26 21:23 ` Brian Norris
2015-10-27  9:37   ` Roger Quadros
2015-11-25 10:42     ` Roger Quadros
2015-11-30 19:54     ` Brian Norris
2015-12-01 14:41       ` Roger Quadros
2015-12-02  3:26         ` Brian Norris
2015-12-02  5:12           ` Roger Quadros
2015-12-02 15:03             ` Tony Lindgren
2015-12-02 18:13               ` Brian Norris
2015-12-02 20:05                 ` Tony Lindgren
2015-12-02 18:43             ` Brian Norris
2015-12-03  5:09 ` Brian Norris
2015-12-03  6:08   ` Roger Quadros
2015-12-03  6:22     ` Brian Norris
2015-12-03  9:01       ` Roger Quadros
2015-12-03 15:17         ` Tony Lindgren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).