Skip to contentSkip to conversation

memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms

PATCH Superseded Roger Quadros 5 participants 79 messages Sep 18, 2015 – Dec 3, 2015

Subsystems (9)

v3 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v3 cover memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms

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
[email protected]: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
Signature · 1 line
2.1.4
#1 lore raw

PATCH v3 1/27 ARM: OMAP2+: gpmc: Add platform data

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.

---
 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
include/linux/omap-gpmc.h +1 -2
index 7dee0014..5c79190 100644
@@ -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
 
include/linux/platform_data/gpmc-omap.h new file +30 -0
new file mode 100644
index 0000000..d32d9de
@@ -0,0 +1,30 @@
+/*
+ * OMAP GPMC Platform data
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc. - http://www.ti.com
+ *	Roger Quadros <[email protected]>
+ *
+ * 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 */
Signature · 6 lines
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#2 lore raw

PATCH v3 2/27 ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data

In reply to Roger Quadros

Add device_timings, gpmc_timings and gpmc_setting to gpmc platform data.

---
 include/linux/omap-gpmc.h               | 134 -------------------------------
 include/linux/platform_data/gpmc-omap.h | 137 ++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+), 134 deletions(-)
include/linux/omap-gpmc.h +0 -134
index 5c79190..2dcef1c 100644
@@ -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);
include/linux/platform_data/gpmc-omap.h +137 -0

147 lines not on this page · raw message

Signature · 6 lines
2.1.4


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

PATCH v3 3/27 memory: omap-gpmc: Introduce GPMC to NAND interface

In reply to 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.

---
 drivers/memory/omap-gpmc.c | 21 ++++++++++++++++++++
 include/linux/omap-gpmc.h  | 49 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 2 deletions(-)
drivers/memory/omap-gpmc.c +21 -0
index 32ac049..a80c53e 100644
@@ -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;
include/linux/omap-gpmc.h +47 -2

61 lines not on this page · raw message

Signature · 6 lines
2.1.4


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

PATCH v3 4/27 mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers

In reply to Roger Quadros

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

---
 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(-)
arch/arm/mach-omap2/gpmc-nand.c +0 -2
index 72918c4..04e6998 100644
@@ -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;
drivers/mtd/nand/omap2.c +8 -1
index 60fa899..f214fe2 100644
@@ -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;
include/linux/platform_data/mtd-nand-omap2.h +3 -1
index 090bbab..a067f58 100644
@@ -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
Signature · 6 lines
2.1.4


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

Re: [PATCH v3 04/27] mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers

Quoted 9 lines · Roger Quadros

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

---
 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

Quoted 72 lines
arch/arm/mach-omap2/gpmc-nand.c +0 -2
index 72918c4..04e6998 100644
@@ -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;
drivers/mtd/nand/omap2.c +8 -1
index 60fa899..f214fe2 100644
@@ -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;
include/linux/platform_data/mtd-nand-omap2.h +3 -1
index 090bbab..a067f58 100644
@@ -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
Signature · 1 line
2.1.4
#6 lore raw

PATCH v3 5/27 memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status

In reply to Roger Quadros

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

---
 drivers/memory/omap-gpmc.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/memory/omap-gpmc.c +13 -1
index a80c53e..174c45b 100644
@@ -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
Signature · 1 line
2.1.4
#7 lore raw

PATCH v3 6/27 mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty check

In reply to 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.

---
 drivers/mtd/nand/omap2.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/mtd/nand/omap2.c +4 -6
index f214fe2..0eb0b8c 100644
@@ -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);
 	}
 }
Signature · 6 lines
2.1.4


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

PATCH v3 7/27 memory: omap-gpmc: Remove NAND IRQ code

In reply to 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.

---
 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(-)
arch/arm/mach-omap2/gpmc-nand.c +1 -3
index 04e6998..ffe646a 100644
@@ -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)
drivers/memory/omap-gpmc.c +3 -160

235 lines not on this page · raw message

include/linux/omap-gpmc.h +6 -5
index 7de9f9b..58f6bd2 100644
@@ -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);
Signature · 6 lines
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#9 lore raw

PATCH v3 8/27 memory: omap-gpmc: Add IRQ ops for GPMC-NAND interface

In reply to 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.

---
 drivers/memory/omap-gpmc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/omap-gpmc.h  |  4 ++++
 2 files changed, 54 insertions(+)
drivers/memory/omap-gpmc.c +50 -0
index a9071bb..e75226d 100644
@@ -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,
 };
 
 /**
include/linux/omap-gpmc.h +4 -0
index 58f6bd2..b76cec3 100644
@@ -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,
Signature · 6 lines
2.1.4


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

PATCH v3 9/27 mtd: nand: omap2: manage NAND interrupts

In reply to 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

---
 drivers/mtd/nand/omap2.c | 65 +++++++++++++++++++++++-------------------------
 1 file changed, 31 insertions(+), 34 deletions(-)
drivers/mtd/nand/omap2.c +31 -34
index 0eb0b8c..267bcdd 100644
@@ -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;
 		}
 
Signature · 6 lines
2.1.4


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

PATCH v3 10/27 mtd: nand: omap: Copy platform data parameters to omap_nand_info data

In reply to 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.

---
 drivers/mtd/nand/omap2.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)
drivers/mtd/nand/omap2.c +18 -8
index 267bcdd..c35405c 100644
@@ -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;
 	}
Signature · 1 line
2.1.4
#12 lore raw

PATCH v3 11/27 mtd: nand: omap: Clean up device tree support

In reply to 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.

---
 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(-)
arch/arm/mach-omap2/gpmc-nand.c +1 -4
index ffe646a..e07ca27 100644
@@ -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;
 
drivers/memory/omap-gpmc.c +29 -106

159 lines not on this page · raw message

drivers/mtd/nand/omap2.c +116 -20

198 lines not on this page · raw message

include/linux/platform_data/mtd-nand-omap2.h +1 -2
index a067f58..ff27e5a 100644
@@ -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
Signature · 1 line
2.1.4
#13 lore raw

PATCH v4 11/27 mtd: nand: omap: Clean up device tree support

Move NAND specific device tree parsing to NAND driver.

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

---
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(-)
arch/arm/mach-omap2/gpmc-nand.c +1 -4
index ffe646a..e07ca27 100644
@@ -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;
 
drivers/memory/omap-gpmc.c +37 -106

167 lines not on this page · raw message

drivers/mtd/nand/omap2.c +116 -20

198 lines not on this page · raw message

include/linux/platform_data/mtd-nand-omap2.h +1 -2
index a067f58..ff27e5a 100644
@@ -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
Signature · 7 lines
2.1.4


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#14 lore raw

Re: [PATCH v4 11/27] mtd: nand: omap: Clean up device tree support

Hi Roger,

Quoted 6 lines · 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.

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

Quoted 9 lines

---
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?

Quoted 367 lines
arch/arm/mach-omap2/gpmc-nand.c +1 -4
index ffe646a..e07ca27 100644
@@ -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;
 
drivers/memory/omap-gpmc.c +37 -106
index e75226d..318c187 100644
@@ -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);
drivers/mtd/nand/omap2.c +103 -17
index c35405c..228f498 100644
@@ -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;

drivers/mtd/nand/omap2.c scan_tail: · line 2139

Quoted 8 lines
drivers/mtd/nand/omap2.c +2 -3
@@ -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().

Quoted 31 lines
drivers/mtd/nand/omap2.c +11 -0
+		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),
 	},
 };
 
include/linux/platform_data/mtd-nand-omap2.h +0 -0
index a067f58..ff27e5a 100644

include/linux/platform_data/mtd-nand-omap2.h struct omap_nand_platform_data { · line 83

Quoted 10 lines
include/linux/platform_data/mtd-nand-omap2.h +1 -2
@@ -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?

include/linux/platform_data/mtd-nand-omap2.h struct omap_nand_platform_data { · line 85

Quoted 2 lines
include/linux/platform_data/mtd-nand-omap2.h +0 -0
 };
 #endif

Brian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#15 lore raw

Re: [PATCH v4 11/27] mtd: nand: omap: Clean up device tree support

Brian,

Quoted 5 lines · Brian Norris

Hi Roger,

Quoted 2 lines · Roger Quadros

Move NAND specific device tree parsing to NAND driver.

Quoted 7 lines
Quoted 4 lines

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

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

Quoted 11 lines
Quoted 10 lines

---
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(-)
Quoted 3 lines

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?

Quoted 29 lines
Quoted 29 lines
arch/arm/mach-omap2/gpmc-nand.c +1 -4
index ffe646a..e07ca27 100644
@@ -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;
 
drivers/memory/omap-gpmc.c +0 -1
index e75226d..318c187 100644
@@ -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>

Quoted 9 lines

drivers/memory/omap-gpmc.c

Quoted 6 lines
drivers/memory/omap-gpmc.c +2 -3
-	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.

Quoted 39 lines
Quoted 39 lines
drivers/memory/omap-gpmc.c +11 -0
+		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),
 	},
 };
 
include/linux/platform_data/mtd-nand-omap2.h +0 -2
index a067f58..ff27e5a 100644
@@ -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;
 
Quoted 11 lines

include/linux/platform_data/mtd-nand-omap2.h struct omap_nand_platform_data { · line 83

Quoted 3 lines
include/linux/platform_data/mtd-nand-omap2.h +1 -0
 	/* 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

#16 lore raw

Re: [PATCH v4 11/27] mtd: nand: omap: Clean up device tree support

Quoted 8 lines · Roger Quadros
Quoted 7 lines · Brian Norris
Quoted 5 lines · Roger Quadros
 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(-)
Quoted 6 lines
Quoted 3 lines

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...

...

Quoted 24 lines
Quoted 12 lines
Quoted 12 lines
include/linux/platform_data/mtd-nand-omap2.h +0 -2
index a067f58..ff27e5a 100644
@@ -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;
 
Quoted 11 lines

include/linux/platform_data/mtd-nand-omap2.h struct omap_nand_platform_data { · line 83

Quoted 3 lines
include/linux/platform_data/mtd-nand-omap2.h +1 -0
 	/* 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?

Quoted 8 lines

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

#17 lore raw

PATCH v3 12/27 mtd: nand: omap: Update DT binding documentation

In reply to Roger Quadros

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

---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +12 -4
index fb733c4..253e6de 100644
@@ -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>;
Signature · 6 lines
2.1.4


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

PATCH v3 13/27 memory: omap-gpmc: Prevent mapping into 1st 16MB

In reply to 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.

---
 drivers/memory/omap-gpmc.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)
drivers/memory/omap-gpmc.c +18 -6
index b09e1bc..bcf4b05 100644
@@ -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;
 	}
 
Signature · 1 line
2.1.4
#19 lore raw

PATCH v3 14/27 memory: omap-gpmc: Move device tree binding to correct location

In reply to Roger Quadros

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

---
 .../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%)
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt renamed from Documentation/devicetree/bindings/bus/ti-gpmc.txt +0 -0
similarity index 100%
rename from Documentation/devicetree/bindings/bus/ti-gpmc.txt
rename to Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
Signature · 1 line
2.1.4
#20 lore raw

PATCH v3 15/27 memory: omap-gpmc: Support general purpose input for WAITPINs

In reply to 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.

---
 drivers/memory/omap-gpmc.c | 130 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 120 insertions(+), 10 deletions(-)
drivers/memory/omap-gpmc.c +120 -10
index bcf4b05..518b418 100644
@@ -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);
Signature · 1 line
2.1.4
#21 lore raw

PATCH v3 16/27 memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring

In reply to 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.

---
 drivers/memory/omap-gpmc.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/memory/omap-gpmc.c +21 -2
index 518b418..fdf19eeb 100644
@@ -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);
 
Signature · 6 lines
2.1.4


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

PATCH v3 17/27 memory: omap-gpmc: Add irqchip support to the gpiochip

In reply to Roger Quadros

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

---
 drivers/memory/omap-gpmc.c | 132 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)
drivers/memory/omap-gpmc.c +132 -0
index fdf19eeb..764e24a 100644
@@ -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)
Signature · 1 line
2.1.4
#23 lore raw

PATCH v3 18/27 mtd: nand: omap2: Implement NAND ready using gpiolib

In reply to 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.

---
 drivers/mtd/nand/omap2.c                     | 29 +++++++++++++++++-----------
 include/linux/platform_data/mtd-nand-omap2.h |  2 +-
 2 files changed, 19 insertions(+), 12 deletions(-)
drivers/mtd/nand/omap2.c +18 -11
index 228f498..d0f2620 100644
@@ -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 {
include/linux/platform_data/mtd-nand-omap2.h +1 -1
index ff27e5a..19e509d 100644
@@ -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
Signature · 6 lines
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#24 lore raw

Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib

+ others

A few comments below.

Quoted 70 lines · 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.

---
 drivers/mtd/nand/omap2.c                     | 29 +++++++++++++++++-----------
 include/linux/platform_data/mtd-nand-omap2.h |  2 +-
 2 files changed, 19 insertions(+), 12 deletions(-)
drivers/mtd/nand/omap2.c +10 -10
index 228f498..d0f2620 100644
@@ -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;

drivers/mtd/nand/omap2.c static int omap_nand_probe(struct platform_device *pdev) · line 1819

Quoted 5 lines
drivers/mtd/nand/omap2.c +2 -0
@@ -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/

Quoted 39 lines
drivers/mtd/nand/omap2.c +6 -1
+	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 {
include/linux/platform_data/mtd-nand-omap2.h +1 -1
index ff27e5a..19e509d 100644
@@ -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
Signature · 1 line
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#25 lore raw

Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib

Quoted 88 lines · Brian Norris

+ others

A few comments below.

Quoted 70 lines · 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.

---
 drivers/mtd/nand/omap2.c                     | 29 +++++++++++++++++-----------
 include/linux/platform_data/mtd-nand-omap2.h |  2 +-
 2 files changed, 19 insertions(+), 12 deletions(-)
drivers/mtd/nand/omap2.c +10 -10
index 228f498..d0f2620 100644
@@ -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;

drivers/mtd/nand/omap2.c static int omap_nand_probe(struct platform_device *pdev) · line 1819

Quoted 5 lines
drivers/mtd/nand/omap2.c +2 -0
@@ -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.

Quoted 7 lines

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

Quoted 40 lines

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/

Quoted 31 lines
drivers/mtd/nand/omap2.c +6 -1
+	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 {
include/linux/platform_data/mtd-nand-omap2.h +0 -1
index ff27e5a..19e509d 100644
@@ -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 */
Quoted 8 lines
Quoted 8 lines
include/linux/platform_data/mtd-nand-omap2.h +1 -0
 	struct gpmc_nand_regs	reg;
 	struct device_node	*of_node;
+	bool			dev_ready;
 };
 #endif
Signature · 1 line
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#26 lore raw

Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib

Hi Roger,

Quoted 14 lines · On Tue, 27 Oct 2015 10:03:02 +0200 Roger Quadros <[email protected]> wrote:
Quoted 13 lines · Brian Norris

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.

Quoted 5 lines
Quoted 2 lines

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

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#27 lore raw

Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib

Boris,

Quoted 22 lines · Boris Brezillon

Hi Roger,

Quoted 17 lines · On Tue, 27 Oct 2015 10:03:02 +0200 Roger Quadros…
Quoted 15 lines · Brian Norris

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?

Quoted 8 lines
Quoted 2 lines

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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#28 lore raw

Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib

In reply to Brian Norris

Hi Brian,

Quoted 78 lines · On Mon, 26 Oct 2015 13:49:00 -0700 Brian Norris <[email protected]>…

+ others

A few comments below.

Quoted 73 lines · 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.

---
 drivers/mtd/nand/omap2.c                     | 29 +++++++++++++++++-----------
 include/linux/platform_data/mtd-nand-omap2.h |  2 +-
 2 files changed, 19 insertions(+), 12 deletions(-)
drivers/mtd/nand/omap2.c +10 -10
index 228f498..d0f2620 100644
@@ -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;
 
Quoted 9 lines

drivers/mtd/nand/omap2.c static int omap_nand_probe(struct platform_device *pdev) · line 1819

Quoted 2 lines
drivers/mtd/nand/omap2.c +2 -0
+	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

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#29 lore raw

Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib

(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)

Quoted 28 lines · Boris Brezillon
Quoted 16 lines · On Mon, 26 Oct 2015 13:49:00 -0700 Brian Norris <[email protected]>…
Quoted 15 lines · Roger Quadros
drivers/mtd/nand/omap2.c +3 -1
@@ -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;
 
Quoted 9 lines

drivers/mtd/nand/omap2.c static int omap_nand_probe(struct platform_device *pdev) · line 1819

Quoted 2 lines
drivers/mtd/nand/omap2.c +2 -0
+	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.

Quoted 7 lines

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?

Quoted 6 lines

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.

Quoted 4 lines

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.

Quoted 4 lines

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.

Quoted 1 line

What do you think?

Brian

#30 lore raw

Re: [PATCH v3 18/27] mtd: nand: omap2: Implement NAND ready using gpiolib

Hi Brian,

Quoted 41 lines · On Wed, 2 Dec 2015 20:45:44 -0800 Brian Norris <[email protected]>…

(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)

Quoted 28 lines · Boris Brezillon
Quoted 16 lines · On Mon, 26 Oct 2015 13:49:00 -0700 Brian Norris <[email protected]>…
Quoted 15 lines · Roger Quadros
drivers/mtd/nand/omap2.c +3 -1
@@ -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;
 
Quoted 9 lines

drivers/mtd/nand/omap2.c static int omap_nand_probe(struct platform_device *pdev) · line 1819

Quoted 2 lines
drivers/mtd/nand/omap2.c +2 -0
+	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.

Quoted 7 lines

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).

Quoted 2 lines

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.

Quoted 15 lines
Quoted 7 lines

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.

Quoted 4 lines

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.

Quoted 8 lines

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.

Quoted 7 lines
Quoted 5 lines

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

Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#31 lore raw

PATCH v3 19/27 memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via gpmc_regs

In reply to 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.

---
 drivers/memory/omap-gpmc.c                   | 2 +-
 include/linux/platform_data/mtd-nand-omap2.h | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)
drivers/memory/omap-gpmc.c +1 -1
index 764e24a..4c630ad 100644
@@ -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 +
include/linux/platform_data/mtd-nand-omap2.h +2 -1
index 19e509d..17d57a1 100644
@@ -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 {
Signature · 1 line
2.1.4
#32 lore raw

PATCH v3 20/27 ARM: dts: dra7: Fix NAND device nodes.

In reply to 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.

---
 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(-)
arch/arm/boot/dts/dra7-evm.dts +4 -1
index a6c82e5..8a31161 100644
@@ -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>;
arch/arm/boot/dts/dra7.dtsi +4 -0
index 5d65db9..f0a3616 100644
@@ -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";
 		};
 
arch/arm/boot/dts/dra72-evm.dts +4 -1
index 6f6bd98..245f5f9 100644
@@ -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>;
Signature · 6 lines
2.1.4


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

Re: [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes.

Quoted 39 lines · 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.

---
 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(-)
arch/arm/boot/dts/dra7-evm.dts +4 -1
index a6c82e5..8a31161 100644
@@ -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>;
arch/arm/boot/dts/dra7.dtsi +0 -0
index 5d65db9..f0a3616 100644

arch/arm/boot/dts/dra7.dtsi line 1397

Quoted 9 lines
arch/arm/boot/dts/dra7.dtsi +4 -0
@@ -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.

Quoted 13 lines
arch/arm/boot/dts/dra72-evm.dts +1 -1
index 6f6bd98..245f5f9 100644
@@ -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:

arch/arm/boot/dts/dra72-evm.dts line 410

Quoted 10 lines
arch/arm/boot/dts/dra72-evm.dts +3 -0
 		 * 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>;

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#34 lore raw

Re: [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes.

Quoted 47 lines · Franklin S Cooper Jr.
Quoted 44 lines · 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.

---
 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(-)
arch/arm/boot/dts/dra7-evm.dts +4 -1
index a6c82e5..8a31161 100644
@@ -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>;
arch/arm/boot/dts/dra7.dtsi +2 -0
index 5d65db9..f0a3616 100644
@@ -1389,6 +1389,10 @@
 			gpmc,num-waitpins = <2>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
Quoted 8 lines

arch/arm/boot/dts/dra7.dtsi line 1397

Quoted 4 lines
arch/arm/boot/dts/dra7.dtsi +2 -0
+			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.

Quoted 2 lines

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

#35 lore raw

Re: [PATCH v3 20/27] ARM: dts: dra7: Fix NAND device nodes.

Quoted 59 lines · Roger Quadros
Quoted 46 lines · Franklin S Cooper Jr.
Quoted 44 lines · 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.

---
 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(-)
arch/arm/boot/dts/dra7-evm.dts +4 -1
index a6c82e5..8a31161 100644
@@ -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>;
arch/arm/boot/dts/dra7.dtsi +2 -0
index 5d65db9..f0a3616 100644
@@ -1389,6 +1389,10 @@
 			gpmc,num-waitpins = <2>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
Quoted 8 lines

arch/arm/boot/dts/dra7.dtsi line 1397

Quoted 4 lines
arch/arm/boot/dts/dra7.dtsi +2 -0
+			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.

Quoted 5 lines

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

Quoted 1 line

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.

Quoted 4 lines

--
cheers,
-roger

#36 lore raw

PATCH v3 21/27 ARM: dts: dra7x-evm: Provide NAND ready pin

In reply to 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.

---
 arch/arm/boot/dts/dra7-evm.dts  | 1 +
 arch/arm/boot/dts/dra72-evm.dts | 1 +
 2 files changed, 2 insertions(+)
arch/arm/boot/dts/dra7-evm.dts +1 -0
index 8a31161..4760562 100644
@@ -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>;
arch/arm/boot/dts/dra72-evm.dts +1 -0
index 245f5f9..a11a646 100644
@@ -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>;
Signature · 1 line
2.1.4
#37 lore raw

PATCH v3 22/27 ARM: dts: am437x: Fix NAND device nodes

In reply to 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.

---
 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(-)
arch/arm/boot/dts/am4372.dtsi +4 -0
index 0447c04a..ec8b7a3 100644
@@ -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";
 		};
 
arch/arm/boot/dts/am437x-gp-evm.dts +4 -1
index 22038f2..aa96c99 100644
@@ -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>;
arch/arm/boot/dts/am43x-epos-evm.dts +4 -1
index 86c2dfb..9a7786d 100644
@@ -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>;
Signature · 1 line
2.1.4
#38 lore raw

PATCH v3 23/27 ARM: dts: am437x-gp-evm: Provide NAND ready pin

In reply to 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.

---
 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(-)
arch/arm/boot/dts/am437x-gp-evm.dts +1 -2
index aa96c99..d7bfe9f 100644
@@ -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 */
arch/arm/boot/dts/am43x-epos-evm.dts +1 -2
index 9a7786d..4b26762 100644
@@ -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 */
Signature · 1 line
2.1.4
#39 lore raw

PATCH v3 24/27 ARM: dts: am335x: Fix NAND device nodes

In reply to 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.

---
 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(+)
arch/arm/boot/dts/am335x-chilisom.dtsi +3 -0
index 7e9a34d..e2b5e22 100644
@@ -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>;
arch/arm/boot/dts/am335x-evm.dts +3 -0
index 1942a5c..bea36e1 100644
@@ -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>;
arch/arm/boot/dts/am335x-igep0033.dtsi +3 -0
index c0e1135..9252ff1 100644
@@ -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>;
arch/arm/boot/dts/am33xx.dtsi +4 -0
index d23e252..e065f21 100644
@@ -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";
 		};
 
Signature · 1 line
2.1.4
#40 lore raw

PATCH v3 25/27 ARM: dts: am335x: Provide NAND ready pin

In reply to 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.

---
 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(-)
arch/arm/boot/dts/am335x-chilisom.dtsi +1 -3
index e2b5e22..3c71c5d 100644
@@ -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>;
 	};
arch/arm/boot/dts/am335x-evm.dts +1 -3
index bea36e1..c7dfc21 100644
@@ -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 */
arch/arm/boot/dts/am335x-igep0033.dtsi +1 -3
index 9252ff1..84d4d50 100644
@@ -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>;
 
Signature · 1 line
2.1.4
#41 lore raw

PATCH v3 26/27 ARM: dts: dm816x: Fix gpmc and NAND node

In reply to Roger Quadros

Make gpmc node gpio+interrupt capable.

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

---
 arch/arm/boot/dts/dm8168-evm.dts | 7 ++++---
 arch/arm/boot/dts/dm816x.dtsi    | 4 ++++
 2 files changed, 8 insertions(+), 3 deletions(-)
arch/arm/boot/dts/dm8168-evm.dts +4 -3
index 169a855..faa7abe 100644
@@ -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 {
arch/arm/boot/dts/dm816x.dtsi +4 -0
index 3c99cfa..68fb444 100644
@@ -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 {
Signature · 1 line
2.1.4
#42 lore raw

PATCH v3 27/27 ARM: dts: omap3: Fix gpmc and NAND nodes

In reply to 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.

---
 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(-)
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +5 -2
index 36387b1..4ba73c9 100644
@@ -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>;
arch/arm/boot/dts/omap3-beagle.dts +2 -0
index a547411..bb4df5d 100644
@@ -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>;
arch/arm/boot/dts/omap3-cm-t3x.dtsi +4 -1
index 4d091ca..e9d7e28 100644
@@ -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";
arch/arm/boot/dts/omap3-devkit8000-common.dtsi +3 -0
index 9ca2865..e7b46ad 100644
@@ -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";
arch/arm/boot/dts/omap3-evm-37xx.dts +5 -2
index 16e8ce3..7081e07 100644
@@ -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";
arch/arm/boot/dts/omap3-gta04.dtsi +3 -0
index 7166d88..4c48b31 100644
@@ -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";
 
arch/arm/boot/dts/omap3-igep.dtsi +4 -1
index d5e5cd4..1324f51 100644
@@ -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";
arch/arm/boot/dts/omap3-igep0020-common.dtsi +2 -2
index e458c21..8b7b7c7 100644
@@ -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";
arch/arm/boot/dts/omap3-igep0030-common.dtsi +4 -0
index 0cb1527..c5d8210 100644
@@ -58,3 +58,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart2_pins>;
 };
+
+&gpmc {
+	ranges = <0 0 0x30000000 0x01000000>;   /* CS0: 16MB for NAND */
+};
arch/arm/boot/dts/omap3-ldp.dts +6 -3
index bd6e676..fb86131 100644
@@ -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";
arch/arm/boot/dts/omap3-lilly-a83x.dtsi +4 -1
index d0dd036..abc39f4 100644
@@ -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 */
arch/arm/boot/dts/omap3-pandora-common.dtsi +3 -0
index f2084e6..11ada97 100644
@@ -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";
 
arch/arm/boot/dts/omap3-tao3530.dtsi +4 -1
index 7bd8d9a..838e0da 100644
@@ -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";
arch/arm/boot/dts/omap3.dtsi +4 -0
index 69a40cf..f802bcf 100644
@@ -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 {
arch/arm/boot/dts/omap3430-sdp.dts +4 -1
index 16b0cdf..3f113c5 100644
@@ -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>;
Signature · 1 line
2.1.4
maintainer
#43 lore raw

Re: [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes

Quoted 8 lines · 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.

...

Quoted 9 lines
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +1 -1
@@ -35,11 +35,14 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 

arch/arm/boot/dts/logicpd-torpedo-som.dtsi line 48

Quoted 10 lines
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +4 -1
 	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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#44 lore raw

Re: [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes

Quoted 19 lines · Tony Lindgren
Quoted 8 lines · 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.

...

Quoted 9 lines
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +1 -1
@@ -35,11 +35,14 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 
Quoted 14 lines

arch/arm/boot/dts/logicpd-torpedo-som.dtsi line 48

Quoted 10 lines
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +4 -1
 	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?

Quoted 2 lines

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

maintainer
#45 lore raw

Re: [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes

Quoted 35 lines · Roger Quadros
Quoted 19 lines · Tony Lindgren
Quoted 8 lines · 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.

...

Quoted 9 lines
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +1 -1
@@ -35,11 +35,14 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 
Quoted 14 lines

arch/arm/boot/dts/logicpd-torpedo-som.dtsi line 48

Quoted 10 lines
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +4 -1
 	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?

Quoted 2 lines

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?

Quoted 2 lines

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.

Quoted 4 lines
Quoted 1 line

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< --------------------

arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts +2 -1
@@ -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";
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +1 -1
@@ -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";

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#46 lore raw

Re: [PATCH v3 27/27] ARM: dts: omap3: Fix gpmc and NAND nodes

Tony,

Quoted 36 lines · Tony Lindgren
Quoted 35 lines · Roger Quadros
Quoted 33 lines · Tony Lindgren
Quoted 8 lines · 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.

...

Quoted 9 lines
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +1 -1
@@ -35,11 +35,14 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 

arch/arm/boot/dts/logicpd-torpedo-som.dtsi line 48

Quoted 10 lines
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +4 -1
 	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?

Quoted 6 lines
Quoted 2 lines

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.

Quoted 11 lines
Quoted 3 lines

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.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

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.

Quoted 3 lines

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

Exactly.

cheers,
-roger

Quoted 30 lines

Regards,

Tony

8< --------------------

arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts +2 -1
@@ -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";
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +1 -1
@@ -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";
#47 lore raw

PATCH v4 27/27 ARM: dts: omap3: Fix gpmc and NAND nodes

In reply to 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.

---

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

updated v4 series available at

[email protected]: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(-)
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts +2 -1
index 91146c3..20e157d 100644
@@ -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";
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +5 -2
index 36387b1..f108e55 100644
@@ -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>;
arch/arm/boot/dts/omap3-beagle.dts +2 -0
index 67659a0..9b145dd 100644
@@ -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>;
arch/arm/boot/dts/omap3-cm-t3x.dtsi +4 -1
index 4d091ca..e9d7e28 100644
@@ -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";
arch/arm/boot/dts/omap3-devkit8000-common.dtsi +3 -0
index 9ca2865..e7b46ad 100644
@@ -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";
arch/arm/boot/dts/omap3-evm-37xx.dts +5 -2
index 16e8ce3..7081e07 100644
@@ -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";
arch/arm/boot/dts/omap3-gta04.dtsi +3 -0
index 7166d88..4c48b31 100644
@@ -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";
 
arch/arm/boot/dts/omap3-igep.dtsi +4 -1
index 2230e1c..d4dff72 100644
@@ -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";
arch/arm/boot/dts/omap3-igep0020-common.dtsi +2 -2
index 5ad688c..eecd7a8 100644
@@ -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";
arch/arm/boot/dts/omap3-igep0030-common.dtsi +4 -0
index 0cb1527..c5d8210 100644
@@ -58,3 +58,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart2_pins>;
 };
+
+&gpmc {
+	ranges = <0 0 0x30000000 0x01000000>;   /* CS0: 16MB for NAND */
+};
arch/arm/boot/dts/omap3-ldp.dts +6 -3
index bd6e676..fb86131 100644
@@ -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";
arch/arm/boot/dts/omap3-lilly-a83x.dtsi +4 -1
index d0dd036..abc39f4 100644
@@ -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 */
arch/arm/boot/dts/omap3-pandora-common.dtsi +3 -0
index f2084e6..11ada97 100644
@@ -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";
 
arch/arm/boot/dts/omap3-tao3530.dtsi +4 -1
index 7bd8d9a..838e0da 100644
@@ -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";
arch/arm/boot/dts/omap3.dtsi +4 -0
index 8a2b253..7f212b6 100644
@@ -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 {
arch/arm/boot/dts/omap3430-sdp.dts +4 -1
index 16b0cdf..3f113c5 100644
@@ -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>;
Signature · 1 line
2.1.4
#48 lore raw
In reply to Roger Quadros

Brian/David,

Quoted 23 lines · 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.

Quoted 6 lines

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

This series is available at
[email protected]: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

Quoted 79 lines

Changelog:
v3:

(quoted diff) +0 -3
-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
#49 lore raw
In reply to Roger Quadros

Tony,

Quoted 23 lines · 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.

Quoted 6 lines

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

This series is available at
[email protected]: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

Quoted 79 lines

Changelog:
v3:

(quoted diff) +0 -3
-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
maintainer
#50 lore raw
Quoted 32 lines · Roger Quadros

Tony,

Quoted 29 lines · 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
[email protected]:rogerq/linux.git
in branch
for-v4.4/gpmc-v3

In general, very nice work :)

Quoted 7 lines

I've verified this series with the following boards

(quoted diff) +0 -4
-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..

Quoted 5 lines

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

#51 lore raw
Quoted 27 lines · Tony Lindgren
Quoted 26 lines · Roger Quadros

Tony,

Quoted 23 lines · 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.

Quoted 8 lines
Quoted 6 lines
Quoted 6 lines

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

This series is available at git-9UaJU3cA/F/[email protected]:rogerq/linux.git in branch
for-v4.4/gpmc-v3

In general, very nice work :)

Thanks :)

Quoted 7 lines
Quoted 7 lines

I've verified this series with the following boards

(quoted diff) +0 -4
-dra7-evm
-am437x-gp-evm
-am335x-evm
-beagleboard-c4
Quoted 6 lines
Quoted 1 line

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.

Quoted 9 lines
Quoted 6 lines

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.

Quoted 2 lines

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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

maintainer
#52 lore raw
Quoted 10 lines · Roger Quadros
Quoted 2 lines · Tony Lindgren

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.

Quoted 3 lines

- 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?

Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

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?

Quoted 8 lines
Quoted 2 lines

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

Thanks.

Quoted 2 lines

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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#53 lore raw
Quoted 12 lines · Tony Lindgren
Quoted 10 lines · Roger Quadros
Quoted 2 lines · Tony Lindgren

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?

Quoted 8 lines

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

Quoted 3 lines

- 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

Quoted 23 lines
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines

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?

Quoted 8 lines
Quoted 2 lines

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

Thanks.

Quoted 2 lines

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

#54 lore raw
Quoted 19 lines · Roger Quadros
Quoted 18 lines · Tony Lindgren
Quoted 10 lines · Roger Quadros
Quoted 2 lines · Tony Lindgren

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.

Quoted 3 lines

- 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.

Quoted 7 lines
Quoted 2 lines

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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

maintainer
#55 lore raw
Quoted 28 lines · Roger Quadros
Quoted 19 lines · Roger Quadros
Quoted 18 lines · Tony Lindgren
Quoted 10 lines · Roger Quadros
Quoted 2 lines · Tony Lindgren

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.

Quoted 3 lines

- 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.

Quoted 7 lines
Quoted 2 lines

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.

Quoted 8 lines

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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#56 lore raw
Quoted 32 lines · Tony Lindgren
Quoted 31 lines · Roger Quadros
Quoted 19 lines · Roger Quadros
Quoted 18 lines · Tony Lindgren
Quoted 10 lines · Roger Quadros
Quoted 2 lines · Tony Lindgren

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.

Quoted 3 lines

- 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.

Quoted 7 lines
Quoted 2 lines

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

Quoted 8 lines
Quoted 5 lines
[    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

[email protected]:rogerq/linux.git
* [new branch] for-v4.4/gpmc-v4

cheers,
-roger

maintainer Acked-by
#57 lore raw
Quoted 5 lines · Roger Quadros

Fine. The updated series is now at

[email protected]: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:

Regards,

Tony

#58 lore raw
Quoted 7 lines · Tony Lindgren
Quoted 5 lines · Roger Quadros

Fine. The updated series is now at

git-9UaJU3cA/F/[email protected]:rogerq/linux.git
* [new branch] for-v4.4/gpmc-v4

Quoted 8 lines

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.

Quoted 1 line

Maybe run randconfig builds on it for overnight?

OK. I'll do that.

Quoted 5 lines

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

Thanks for the tests :)

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#59 lore raw
Quoted 17 lines · Roger Quadros
Quoted 7 lines · Tony Lindgren
Quoted 5 lines · Roger Quadros

Fine. The updated series is now at

[email protected]:rogerq/linux.git
* [new branch] for-v4.4/gpmc-v4

Quoted 8 lines

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]

Quoted 5 lines

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

Quoted 1 line

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

maintainer
#60 lore raw
Quoted 20 lines · Roger Quadros
Quoted 19 lines · Roger Quadros
Quoted 7 lines · Tony Lindgren
Quoted 5 lines · Roger Quadros

Fine. The updated series is now at

git-9UaJU3cA/F/[email protected]:rogerq/linux.git
* [new branch] for-v4.4/gpmc-v4

Quoted 8 lines

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.

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#61 lore raw
Quoted 23 lines · Tony Lindgren
Quoted 22 lines · Roger Quadros
Quoted 21 lines · Roger Quadros
Quoted 7 lines · Tony Lindgren
Quoted 5 lines · Roger Quadros

Fine. The updated series is now at

[email protected]:rogerq/linux.git
* [new branch] for-v4.4/gpmc-v4

Quoted 8 lines

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.

Quoted 1 line

Maybe run randconfig builds on it for overnight?

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

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

maintainer Acked-by
#62 lore raw
Quoted 7 lines · Roger Quadros
Quoted 6 lines · Tony Lindgren
Quoted 4 lines · Roger Quadros

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

Quoted 7 lines
Quoted 1 line

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:

Regards,

Tony

#63 lore raw
In reply to Roger Quadros

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.

Quoted 4 lines · Roger Quadros

- 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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#64 lore raw

Hi Brian,

Quoted 5 lines · Brian Norris

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.

Quoted 18 lines · Roger Quadros
Quoted 4 lines

- 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:

(quoted diff) +4 -0
+       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);
Quoted 4 lines

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

#65 lore raw

Brian,

Quoted 46 lines · Roger Quadros

Hi Brian,

Quoted 5 lines · Brian Norris

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.

Quoted 18 lines · Roger Quadros
Quoted 4 lines

- 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:

(quoted diff) +4 -0
+       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);
Quoted 4 lines

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.

Quoted 6 lines

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

Quoted 190 lines

--
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/

#66 lore raw
In reply to Roger Quadros

Hi Roger,

Quoted 25 lines · Roger Quadros
Quoted 3 lines · Brian Norris

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.

Quoted 18 lines · Roger Quadros
Quoted 4 lines

- 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:

(quoted diff) +4 -0
+       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);
Quoted 8 lines
Quoted 4 lines

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?

Quoted 4 lines

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.

Quoted 8 lines

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.

Quoted 7 lines

Below are performance logs of irqdomain vs hooks.

--
cheers,
-roger

test logs.

[snip]

Brian

#67 lore raw

Hi Brian,

Quoted 33 lines · Brian Norris

Hi Roger,

Quoted 30 lines · Roger Quadros
Quoted 3 lines · Brian Norris

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.

Quoted 22 lines · Roger Quadros
Quoted 4 lines

- 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:

(quoted diff) +4 -0
+       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.

Quoted 8 lines
Quoted 3 lines

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.

Quoted 4 lines

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.

Quoted 9 lines
Quoted 5 lines

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

#68 lore raw

Hi Roger,

Quoted 29 lines · Roger Quadros
Quoted 28 lines · Brian Norris
Quoted 26 lines · Roger Quadros
Quoted 17 lines · Brian Norris
Quoted 4 lines · Roger Quadros

- 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:

(quoted diff) +4 -0
+       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);
Quoted 4 lines

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.

Quoted 6 lines
Quoted 4 lines

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?

Quoted 5 lines
Quoted 3 lines

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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#69 lore raw

Brian,

Quoted 32 lines · Brian Norris

Hi Roger,

Quoted 29 lines · Roger Quadros
Quoted 28 lines · Brian Norris
Quoted 26 lines · Roger Quadros
Quoted 17 lines · Brian Norris
Quoted 4 lines · Roger Quadros

- 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:

(quoted diff) +4 -0
+       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);
Quoted 4 lines

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.

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

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.

Quoted 9 lines
Quoted 6 lines
Quoted 4 lines

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.

Quoted 3 lines

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/.

:)

Quoted 4 lines

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

maintainer
#70 lore raw
Quoted 8 lines · Roger Quadros
Quoted 4 lines · Brian Norris

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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#71 lore raw
Quoted 7 lines · Tony Lindgren
Quoted 6 lines · Roger Quadros
Quoted 4 lines · Brian Norris

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.

Quoted 6 lines
Quoted 2 lines

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

maintainer
#72 lore raw
Quoted 11 lines · Brian Norris
Quoted 10 lines · Tony Lindgren
Quoted 8 lines · Roger Quadros
Quoted 4 lines · Brian Norris

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?

Quoted 8 lines
Quoted 3 lines

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.

Quoted 1 line

Regarding branches, 4.4-rc1 is fine with me.

OK

Thanks,

Tony

#73 lore raw
In reply to Roger Quadros

Hi Roger,

Quoted 7 lines · Roger Quadros
Quoted 6 lines · Brian Norris
Quoted 5 lines · Roger Quadros
Quoted 3 lines · Brian Norris

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?

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

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

#74 lore raw
In reply to Roger Quadros

Hi,

Quoted 35 lines · 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-9UaJU3cA/F/[email protected]:rogerq/linux.git in branch
for-v4.4/gpmc-v3

cheers,
-roger

Changelog:
v3:

Review

Quoted 3 lines
(quoted diff) +0 -3
-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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#75 lore raw

Brian,

Quoted 36 lines · Brian Norris

Hi,

Quoted 33 lines · 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
[email protected]:rogerq/linux.git
in branch
for-v4.4/gpmc-v3

cheers,
-roger

Quoted 10 lines

Review

Quoted 5 lines

Changelog:
v3:

(quoted diff) +0 -3
-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.

Quoted 5 lines

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.

Quoted 4 lines

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.

Quoted 1 line

(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.

Quoted 4 lines

(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

#76 lore raw

Hi,

Quoted 48 lines · Roger Quadros
Quoted 32 lines · Brian Norris
Quoted 31 lines · Roger Quadros

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
[email protected]:rogerq/linux.git
in branch
for-v4.4/gpmc-v3

cheers,
-roger

Quoted 10 lines

Review

Quoted 5 lines

Changelog:
v3:

(quoted diff) +0 -3
-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.

Quoted 1 line
Quoted 8 lines
Quoted 4 lines

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.

Quoted 5 lines
Quoted 3 lines

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.

Quoted 5 lines
Quoted 1 line

(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.

Quoted 7 lines
Quoted 4 lines

(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

#77 lore raw
Quoted 94 lines · Brian Norris

Hi,

Quoted 48 lines · Roger Quadros
Quoted 32 lines · Brian Norris
Quoted 31 lines · Roger Quadros

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
[email protected]:rogerq/linux.git
in branch
for-v4.4/gpmc-v3

cheers,
-roger

Quoted 10 lines

Review

Quoted 5 lines

Changelog:
v3:

(quoted diff) +0 -3
-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.

Quoted 1 line
Quoted 8 lines
Quoted 4 lines

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.

Quoted 5 lines
Quoted 3 lines

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.

Quoted 5 lines
Quoted 1 line

(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.

Quoted 7 lines
Quoted 4 lines

(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:

Quoted 8 lines

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

maintainer
#78 lore raw
Quoted 9 lines · Roger Quadros
Quoted 8 lines · Brian Norris

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

Quoted 8 lines
Quoted 4 lines

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