[v3,1/7] memory: omap-gpmc: Refactor OneNAND support

Message ID 20171109091253.lvrzi5kbaykkxlcb@lenoch
State Superseded
Delegated to: Boris Brezillon
Headers show
Series
  • OMAP2+ OneNAND driver update
Related show

Commit Message

Ladislav Michl Nov. 9, 2017, 9:12 a.m.
Use generic probe function to deal with OneNAND node and remove now useless
gpmc_probe_onenand_child function.
Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
and prepare for MTD driver DTfication.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: add gpmc_omap_onenand_set_timings description
 -v3: none

 drivers/memory/omap-gpmc.c | 158 +++++++++++++++++++++++++++++++++------------
 include/linux/omap-gpmc.h  |  25 +++++++
 2 files changed, 142 insertions(+), 41 deletions(-)

Comments

Tony Lindgren Nov. 9, 2017, 5:56 p.m. | #1
Hi,

* Ladislav Michl <ladis@linux-mips.org> [171109 09:14]:
> Use generic probe function to deal with OneNAND node and remove now useless
> gpmc_probe_onenand_child function.
> Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
> and prepare for MTD driver DTfication.

I tried giving this series a try on n900, but looks like onenand is no longer
seen on n900 after this first patch.

Regards,

Tony
Ladislav Michl Nov. 9, 2017, 6:10 p.m. | #2
On Thu, Nov 09, 2017 at 09:56:26AM -0800, Tony Lindgren wrote:
> Hi,
> 
> * Ladislav Michl <ladis@linux-mips.org> [171109 09:14]:
> > Use generic probe function to deal with OneNAND node and remove now useless
> > gpmc_probe_onenand_child function.
> > Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
> > and prepare for MTD driver DTfication.
> 
> I tried giving this series a try on n900, but looks like onenand is no longer
> seen on n900 after this first patch.

This first patch makes original driver stop working as it removes special
OneNAND handling. If it doesn't work even after applying whole serie, then:
- verify onenand node has compatible 'ti,omap2-onenand' property
- verify timings

On IGEPv2 bootlog shows:
[    1.544464] omap-gpmc 6e000000.gpmc: GPMC revision 5.0
[    1.550415] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
[    1.560485] omap2-onenand 30000000.onenand: initializing on CS0, phys base 0x30000000, virtual base e0080000
[    1.571014] Muxed OneNAND(DDP) 512MB 1.8V 16-bit (0x58)
[    1.576507] OneNAND version = 0x0031
[    1.583435] Scanning device for bad blocks
[    1.620971] OneNAND eraseblock 597 is an initial bad block
[    1.657470] OneNAND eraseblock 1159 is an initial bad block
[    1.754577] OneNAND eraseblock 2812 is an initial bad block
[    1.832214] omap2-onenand 30000000.onenand: optimized timings for 83 MHz
[    1.842620] 2 ofpart partitions found on MTD device 30000000.onenand
[    1.849426] Creating 2 MTD partitions on "30000000.onenand":
[    1.855651] 0x000000000000-0x000000080000 : "SPL"
[    1.863464] 0x000000080000-0x000020000000 : "UBI"

For a start:

diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 4acd32a1c4ef..aa5b1a439564 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -838,6 +838,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
Tony Lindgren Nov. 9, 2017, 6:26 p.m. | #3
* Ladislav Michl <ladis@linux-mips.org> [171109 18:11]:
> On Thu, Nov 09, 2017 at 09:56:26AM -0800, Tony Lindgren wrote:
> > Hi,
> > 
> > * Ladislav Michl <ladis@linux-mips.org> [171109 09:14]:
> > > Use generic probe function to deal with OneNAND node and remove now useless
> > > gpmc_probe_onenand_child function.
> > > Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
> > > and prepare for MTD driver DTfication.
> > 
> > I tried giving this series a try on n900, but looks like onenand is no longer
> > seen on n900 after this first patch.
> 
> This first patch makes original driver stop working as it removes special
> OneNAND handling. If it doesn't work even after applying whole serie, then:
> - verify onenand node has compatible 'ti,omap2-onenand' property
> - verify timings
> 
> On IGEPv2 bootlog shows:
> [    1.544464] omap-gpmc 6e000000.gpmc: GPMC revision 5.0
> [    1.550415] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> [    1.560485] omap2-onenand 30000000.onenand: initializing on CS0, phys base 0x30000000, virtual base e0080000
> [    1.571014] Muxed OneNAND(DDP) 512MB 1.8V 16-bit (0x58)
> [    1.576507] OneNAND version = 0x0031
> [    1.583435] Scanning device for bad blocks
> [    1.620971] OneNAND eraseblock 597 is an initial bad block
> [    1.657470] OneNAND eraseblock 1159 is an initial bad block
> [    1.754577] OneNAND eraseblock 2812 is an initial bad block
> [    1.832214] omap2-onenand 30000000.onenand: optimized timings for 83 MHz
> [    1.842620] 2 ofpart partitions found on MTD device 30000000.onenand
> [    1.849426] Creating 2 MTD partitions on "30000000.onenand":
> [    1.855651] 0x000000000000-0x000000080000 : "SPL"
> [    1.863464] 0x000000080000-0x000020000000 : "UBI"
> 
> For a start:
> 
> diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
> index 4acd32a1c4ef..aa5b1a439564 100644
> --- a/arch/arm/boot/dts/omap3-n900.dts
> +++ b/arch/arm/boot/dts/omap3-n900.dts
> @@ -838,6 +838,7 @@
>  	onenand@0,0 {
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> +		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
>  
>  		gpmc,sync-read;

Well we should have the dependencies merged first to avoid breaking
git bisect. After applying this and the first patch I see:

omap-gpmc 6e000000.gpmc: /ocp@68000000/gpmc@6e000000/onenand@0,0 has no 'bank-width' property
omap-gpmc 6e000000.gpmc: failed to probe DT child 'onenand': -22

So seems like more dts changes are needed to test this.

Regards,

Tony
Ladislav Michl Nov. 9, 2017, 6:34 p.m. | #4
On Thu, Nov 09, 2017 at 10:26:45AM -0800, Tony Lindgren wrote:
> * Ladislav Michl <ladis@linux-mips.org> [171109 18:11]:
> > On Thu, Nov 09, 2017 at 09:56:26AM -0800, Tony Lindgren wrote:
> > > Hi,
> > > 
> > > * Ladislav Michl <ladis@linux-mips.org> [171109 09:14]:
> > > > Use generic probe function to deal with OneNAND node and remove now useless
> > > > gpmc_probe_onenand_child function.
> > > > Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
> > > > and prepare for MTD driver DTfication.
> > > 
> > > I tried giving this series a try on n900, but looks like onenand is no longer
> > > seen on n900 after this first patch.
> > 
> > This first patch makes original driver stop working as it removes special
> > OneNAND handling. If it doesn't work even after applying whole serie, then:
> > - verify onenand node has compatible 'ti,omap2-onenand' property
> > - verify timings
> > 
> > On IGEPv2 bootlog shows:
> > [    1.544464] omap-gpmc 6e000000.gpmc: GPMC revision 5.0
> > [    1.550415] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
> > [    1.560485] omap2-onenand 30000000.onenand: initializing on CS0, phys base 0x30000000, virtual base e0080000
> > [    1.571014] Muxed OneNAND(DDP) 512MB 1.8V 16-bit (0x58)
> > [    1.576507] OneNAND version = 0x0031
> > [    1.583435] Scanning device for bad blocks
> > [    1.620971] OneNAND eraseblock 597 is an initial bad block
> > [    1.657470] OneNAND eraseblock 1159 is an initial bad block
> > [    1.754577] OneNAND eraseblock 2812 is an initial bad block
> > [    1.832214] omap2-onenand 30000000.onenand: optimized timings for 83 MHz
> > [    1.842620] 2 ofpart partitions found on MTD device 30000000.onenand
> > [    1.849426] Creating 2 MTD partitions on "30000000.onenand":
> > [    1.855651] 0x000000000000-0x000000080000 : "SPL"
> > [    1.863464] 0x000000080000-0x000020000000 : "UBI"
> > 
> > For a start:
> > 
> > diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
> > index 4acd32a1c4ef..aa5b1a439564 100644
> > --- a/arch/arm/boot/dts/omap3-n900.dts
> > +++ b/arch/arm/boot/dts/omap3-n900.dts
> > @@ -838,6 +838,7 @@
> >  	onenand@0,0 {
> >  		#address-cells = <1>;
> >  		#size-cells = <1>;
> > +		compatible = "ti,omap2-onenand";
> >  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
> >  
> >  		gpmc,sync-read;
> 
> Well we should have the dependencies merged first to avoid breaking

Yes, that's what cover letter says :-)
Also, I still count on your suggestion to merge it via mtd tree.

> git bisect. After applying this and the first patch I see:
> 
> omap-gpmc 6e000000.gpmc: /ocp@68000000/gpmc@6e000000/onenand@0,0 has no 'bank-width' property
> omap-gpmc 6e000000.gpmc: failed to probe DT child 'onenand': -22
> 
> So seems like more dts changes are needed to test this.

Argh... You are right, I should add this into serie:
https://patchwork.kernel.org/patch/10043259/

> Regards,
> 
> Tony
Tony Lindgren Nov. 9, 2017, 6:48 p.m. | #5
* Ladislav Michl <ladis@linux-mips.org> [171109 18:35]:
> On Thu, Nov 09, 2017 at 10:26:45AM -0800, Tony Lindgren wrote:
> > Well we should have the dependencies merged first to avoid breaking
> 
> Yes, that's what cover letter says :-)
> Also, I still count on your suggestion to merge it via mtd tree.

Well only after it has been tested :) At this point I'd say
we're best off waiting for v4.16 merge window on the clean
up too as the merge window is about to open.

> > git bisect. After applying this and the first patch I see:
> > 
> > omap-gpmc 6e000000.gpmc: /ocp@68000000/gpmc@6e000000/onenand@0,0 has no 'bank-width' property
> > omap-gpmc 6e000000.gpmc: failed to probe DT child 'onenand': -22
> > 
> > So seems like more dts changes are needed to test this.
> 
> Argh... You are right, I should add this into serie:
> https://patchwork.kernel.org/patch/10043259/

Well don't we still need the related dts changes posted
and merged first?

Regards,

Tony
Ladislav Michl Nov. 9, 2017, 7:10 p.m. | #6
On Thu, Nov 09, 2017 at 10:48:28AM -0800, Tony Lindgren wrote:
> * Ladislav Michl <ladis@linux-mips.org> [171109 18:35]:
> > On Thu, Nov 09, 2017 at 10:26:45AM -0800, Tony Lindgren wrote:
> > > Well we should have the dependencies merged first to avoid breaking
> > 
> > Yes, that's what cover letter says :-)
> > Also, I still count on your suggestion to merge it via mtd tree.
> 
> Well only after it has been tested :) At this point I'd say
> we're best off waiting for v4.16 merge window on the clean
> up too as the merge window is about to open.
> 
> > > git bisect. After applying this and the first patch I see:
> > > 
> > > omap-gpmc 6e000000.gpmc: /ocp@68000000/gpmc@6e000000/onenand@0,0 has no 'bank-width' property
> > > omap-gpmc 6e000000.gpmc: failed to probe DT child 'onenand': -22
> > > 
> > > So seems like more dts changes are needed to test this.
> > 
> > Argh... You are right, I should add this into serie:
> > https://patchwork.kernel.org/patch/10043259/
> 
> Well don't we still need the related dts changes posted
> and merged first?

Well, except Roger's feedback, there were complete silence so far.
Note that simple fix was posted in February, this was rejected as
we should aim towards clean DT only driver. And here we are with
some doubts.

As I have no hardware nor any special knowledge going prior
initial driver commit it is rather hard to send "related dts changes"
given simple fact, that I'm unsure whenever we need to distinguish
between OMAP2 and OMAP3. Based on that we need either one or
two compatible strings.

Having two is safe, but u-boot will be unable to bring onenand equipped
igep up.

	ladis

> Regards,
> 
> Tony
Tony Lindgren Nov. 9, 2017, 9:59 p.m. | #7
* Ladislav Michl <ladis@linux-mips.org> [171109 19:12]:
> On Thu, Nov 09, 2017 at 10:48:28AM -0800, Tony Lindgren wrote:
> > Well don't we still need the related dts changes posted
> > and merged first?
> 
> Well, except Roger's feedback, there were complete silence so far.
> Note that simple fix was posted in February, this was rejected as
> we should aim towards clean DT only driver. And here we are with
> some doubts.
> 
> As I have no hardware nor any special knowledge going prior
> initial driver commit it is rather hard to send "related dts changes"
> given simple fact, that I'm unsure whenever we need to distinguish
> between OMAP2 and OMAP3. Based on that we need either one or
> two compatible strings.
> 
> Having two is safe, but u-boot will be unable to bring onenand equipped
> igep up.

Well if you have a complete series with proposed dts changes for
n8x0 and n900, I can try to test those. My n800 seems to have stopped
booting today.. Maybe I need to reflash it after playing with onenand.

Regards,

Tony
Ladislav Michl Nov. 9, 2017, 10:26 p.m. | #8
On Thu, Nov 09, 2017 at 01:59:53PM -0800, Tony Lindgren wrote:
> * Ladislav Michl <ladis@linux-mips.org> [171109 19:12]:
> > On Thu, Nov 09, 2017 at 10:48:28AM -0800, Tony Lindgren wrote:
> > > Well don't we still need the related dts changes posted
> > > and merged first?
> > 
> > Well, except Roger's feedback, there were complete silence so far.
> > Note that simple fix was posted in February, this was rejected as
> > we should aim towards clean DT only driver. And here we are with
> > some doubts.
> > 
> > As I have no hardware nor any special knowledge going prior
> > initial driver commit it is rather hard to send "related dts changes"
> > given simple fact, that I'm unsure whenever we need to distinguish
> > between OMAP2 and OMAP3. Based on that we need either one or
> > two compatible strings.
> > 
> > Having two is safe, but u-boot will be unable to bring onenand equipped
> > igep up.
> 
> Well if you have a complete series with proposed dts changes for
> n8x0 and n900, I can try to test those. My n800 seems to have stopped
> booting today.. Maybe I need to reflash it after playing with onenand.

Okay, here's quick dts patch. Other than that you need:
https://patchwork.kernel.org/patch/10043259/

If you possibly get it working, we can try enable DMA, which is where
things start to be interesting. Once we get DMA working on both
OMAP2 and OMAP3, we are safe to provide only one compatible string.
But that seems to be very long run as even original driver author
left DMA disabled for OMAP2 :-(

Another option is to just ignore OMAP2 DMA which is rather easy:
just omit gpio in dts.

diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 1de80c7886ab..843f6a2f5e29 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -48,6 +48,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 4acd32a1c4ef..aa5b1a439564 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -838,6 +838,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index 1b0bd72945f2..cb3c7b2fce52 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -367,6 +367,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index d50a105c9dc6..ed65795ccc62 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -155,6 +155,7 @@
 		linux,mtd-name= "samsung,kfm2g16q2m-deb8";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <2 0 0x20000>;	/* CS2, offset 0, IO size 4 */
 
 		gpmc,device-width = <2>;
Roger Quadros Nov. 10, 2017, 8:12 a.m. | #9
On 09/11/17 20:48, Tony Lindgren wrote:
> * Ladislav Michl <ladis@linux-mips.org> [171109 18:35]:
>> On Thu, Nov 09, 2017 at 10:26:45AM -0800, Tony Lindgren wrote:
>>> Well we should have the dependencies merged first to avoid breaking
>>
>> Yes, that's what cover letter says :-)
>> Also, I still count on your suggestion to merge it via mtd tree.
> 
> Well only after it has been tested :) At this point I'd say
> we're best off waiting for v4.16 merge window on the clean
> up too as the merge window is about to open.
> 
>>> git bisect. After applying this and the first patch I see:
>>>
>>> omap-gpmc 6e000000.gpmc: /ocp@68000000/gpmc@6e000000/onenand@0,0 has no 'bank-width' property
>>> omap-gpmc 6e000000.gpmc: failed to probe DT child 'onenand': -22
>>>
>>> So seems like more dts changes are needed to test this.
>>
>> Argh... You are right, I should add this into serie:
>> https://patchwork.kernel.org/patch/10043259/

You don't need to resend that patch as it has been already
reviewed and in my v4.16 queue. Just indicate in the cover letter that this
series depends on that patch.

> 
> Well don't we still need the related dts changes posted
> and merged first> 
> Regards,
> 
> Tony
>

Patch

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 0e30ee1c8677..90a66b3f7ae1 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -32,7 +32,6 @@ 
 #include <linux/pm_runtime.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
 
 #include <asm/mach-types.h>
 
@@ -1138,6 +1137,112 @@  struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
 }
 EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
 
+static void gpmc_omap_onenand_calc_sync_timings(struct gpmc_timings *t,
+						struct gpmc_settings *s,
+						int freq, int latency)
+{
+	struct gpmc_device_timings dev_t;
+	const int t_cer  = 15;
+	const int t_avdp = 12;
+	const int t_cez  = 20; /* max of t_cez, t_oez */
+	const int t_wpl  = 40;
+	const int t_wph  = 30;
+	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
+
+	switch (freq) {
+	case 104:
+		min_gpmc_clk_period = 9600; /* 104 MHz */
+		t_ces   = 3;
+		t_avds  = 4;
+		t_avdh  = 2;
+		t_ach   = 3;
+		t_aavdh = 6;
+		t_rdyo  = 6;
+		break;
+	case 83:
+		min_gpmc_clk_period = 12000; /* 83 MHz */
+		t_ces   = 5;
+		t_avds  = 4;
+		t_avdh  = 2;
+		t_ach   = 6;
+		t_aavdh = 6;
+		t_rdyo  = 9;
+		break;
+	case 66:
+		min_gpmc_clk_period = 15000; /* 66 MHz */
+		t_ces   = 6;
+		t_avds  = 5;
+		t_avdh  = 2;
+		t_ach   = 6;
+		t_aavdh = 6;
+		t_rdyo  = 11;
+		break;
+	default:
+		min_gpmc_clk_period = 18500; /* 54 MHz */
+		t_ces   = 7;
+		t_avds  = 7;
+		t_avdh  = 7;
+		t_ach   = 9;
+		t_aavdh = 7;
+		t_rdyo  = 15;
+		break;
+	}
+
+	/* Set synchronous read timings */
+	memset(&dev_t, 0, sizeof(dev_t));
+
+	if (!s->sync_write) {
+		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+		dev_t.t_wpl = t_wpl * 1000;
+		dev_t.t_wph = t_wph * 1000;
+		dev_t.t_aavdh = t_aavdh * 1000;
+	}
+	dev_t.ce_xdelay = true;
+	dev_t.avd_xdelay = true;
+	dev_t.oe_xdelay = true;
+	dev_t.we_xdelay = true;
+	dev_t.clk = min_gpmc_clk_period;
+	dev_t.t_bacc = dev_t.clk;
+	dev_t.t_ces = t_ces * 1000;
+	dev_t.t_avds = t_avds * 1000;
+	dev_t.t_avdh = t_avdh * 1000;
+	dev_t.t_ach = t_ach * 1000;
+	dev_t.cyc_iaa = (latency + 1);
+	dev_t.t_cez_r = t_cez * 1000;
+	dev_t.t_cez_w = dev_t.t_cez_r;
+	dev_t.cyc_aavdh_oe = 1;
+	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
+
+	gpmc_calc_timings(t, s, &dev_t);
+}
+
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info)
+{
+	int ret;
+	struct gpmc_timings gpmc_t;
+	struct gpmc_settings gpmc_s;
+
+	gpmc_read_settings_dt(dev->of_node, &gpmc_s);
+
+	info->sync_read = gpmc_s.sync_read;
+	info->sync_write = gpmc_s.sync_write;
+	info->burst_len = gpmc_s.burst_len;
+
+	if (!gpmc_s.sync_read && !gpmc_s.sync_write)
+		return 0;
+
+	gpmc_omap_onenand_calc_sync_timings(&gpmc_t, &gpmc_s, freq, latency);
+
+	ret = gpmc_cs_program_settings(cs, &gpmc_s);
+	if (ret < 0)
+		return ret;
+
+	return gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
+}
+EXPORT_SYMBOL_GPL(gpmc_omap_onenand_set_timings);
+
 int gpmc_get_client_irq(unsigned irq_config)
 {
 	if (!gpmc_irq_domain) {
@@ -1916,41 +2021,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_ONENAND)
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-				 struct device_node *child)
-{
-	u32 val;
-	struct omap_onenand_platform_data *gpmc_onenand_data;
-
-	if (of_property_read_u32(child, "reg", &val) < 0) {
-		dev_err(&pdev->dev, "%pOF has no 'reg' property\n",
-			child);
-		return -ENODEV;
-	}
-
-	gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
-					 GFP_KERNEL);
-	if (!gpmc_onenand_data)
-		return -ENOMEM;
-
-	gpmc_onenand_data->cs = val;
-	gpmc_onenand_data->of_node = child;
-	gpmc_onenand_data->dma_channel = -1;
-
-	if (!of_property_read_u32(child, "dma-channel", &val))
-		gpmc_onenand_data->dma_channel = val;
-
-	return gpmc_onenand_init(gpmc_onenand_data);
-}
-#else
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-				    struct device_node *child)
-{
-	return 0;
-}
-#endif
-
 /**
  * gpmc_probe_generic_child - configures the gpmc for a child device
  * @pdev:	pointer to gpmc platform device
@@ -2053,6 +2123,16 @@  static int gpmc_probe_generic_child(struct platform_device *pdev,
 		}
 	}
 
+	if (of_node_cmp(child->name, "onenand") == 0) {
+		/* Warn about older DT blobs with no compatible property */
+		if (!of_property_read_bool(child, "compatible")) {
+			dev_warn(&pdev->dev,
+				 "Incompatible OneNAND node: missing compatible");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
 	if (of_device_is_compatible(child, "ti,omap2-nand")) {
 		/* NAND specific setup */
 		val = 8;
@@ -2189,11 +2269,7 @@  static void gpmc_probe_dt_children(struct platform_device *pdev)
 		if (!child->name)
 			continue;
 
-		if (of_node_cmp(child->name, "onenand") == 0)
-			ret = gpmc_probe_onenand_child(pdev, child);
-		else
-			ret = gpmc_probe_generic_child(pdev, child);
-
+		ret = gpmc_probe_generic_child(pdev, child);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n",
 				child->name, ret);
diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index edfa280c3d56..067bea5e98c4 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -25,15 +25,40 @@  struct gpmc_nand_ops {
 
 struct gpmc_nand_regs;
 
+struct gpmc_onenand_info {
+	bool sync_read;
+	bool sync_write;
+	int burst_len;
+};
+
 #if IS_ENABLED(CONFIG_OMAP_GPMC)
 struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
 					     int cs);
+/**
+ * gpmc_omap_onenand_set_timings - set optimized sync timings.
+ * @cs:      Chip Select Region
+ * @freq:    Chip frequency
+ * @latency: Burst latency cycle count
+ * @info:    Structure describing parameters used
+ */
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info);
+
 #else
 static inline struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
 							   int cs)
 {
 	return NULL;
 }
+
+static inline
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info)
+{
+	return -EINVAL;
+}
 #endif /* CONFIG_OMAP_GPMC */
 
 extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,