Skip to contentSkip to conversation

omap gpmc and board clean-up for v3.19 merge window

PATCH New Tony Lindgren 2 participants 27 messages Oct 30, 2014 – Nov 4, 2014

Subsystems (6)
lore
Share & tools
lore

Tony Lindgren

author maintainer
#0 lore raw

cover omap gpmc and board clean-up for v3.19 merge window

Here are few patches to fix and clean up some GPMC issues and remove two board files that are no longer needed.

Regards,

Tony

Tony Lindgren (10):
ARM: dts: Fix bootloader version dependencies by muxing n900 smc91x
pins
ARM: dts: Fix wrong GPMC size mappings for omaps
ARM: dts: Add smc91x GPMC configuration for 2430sdp
ARM: dts: Add GPMC timings for omap zoom serial port
ARM: OMAP2+: Fix support for multiple devices on a GPMC chip select
ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the
.dts file
ARM: OMAP2+: Require proper GPMC timings for devices
ARM: OMAP2+: Drop legacy code for gpmc-smc91x.c
ARM: OMAP2+: Drop board file for ti8168evm
ARM: omap2plus: Drop board file for 3430sdp

 arch/arm/boot/dts/am335x-evm.dts             |   4 +-
 arch/arm/boot/dts/am335x-igep0033.dtsi       |   4 +-
 arch/arm/boot/dts/am43x-epos-evm.dts         |   4 +-
 arch/arm/boot/dts/omap-zoom-common.dtsi      |  62 ++-
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi  |   4 +-
 arch/arm/boot/dts/omap2430-sdp.dts           |  28 +-
 arch/arm/boot/dts/omap3-devkit8000.dts       |   4 +-
 arch/arm/boot/dts/omap3-evm-37xx.dts         |   4 +-
 arch/arm/boot/dts/omap3-gta04.dtsi           |   4 +-
 arch/arm/boot/dts/omap3-igep0020.dts         |   4 +-
 arch/arm/boot/dts/omap3-igep0030.dts         |   4 +-
 arch/arm/boot/dts/omap3-ldp.dts              |   2 +-
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi      |   2 +-
 arch/arm/boot/dts/omap3-n900.dts             |  35 +-
 arch/arm/boot/dts/omap3-n950-n9.dtsi         |   4 +-
 arch/arm/boot/dts/omap3-tao3530.dtsi         |   2 +-
 arch/arm/boot/dts/omap3430-sdp.dts           |   8 +-
 arch/arm/mach-omap2/Kconfig                  |  16 -
 arch/arm/mach-omap2/Makefile                 |   6 -
 arch/arm/mach-omap2/board-3430sdp.c          | 632 ---------------------------
 arch/arm/mach-omap2/board-rx51-peripherals.c |  29 --
 arch/arm/mach-omap2/board-ti8168evm.c        |  62 ---
 arch/arm/mach-omap2/gpmc-smc91x.c            | 186 --------
 arch/arm/mach-omap2/gpmc-smc91x.h            |  42 --
 arch/arm/mach-omap2/gpmc.c                   | 206 +++++++--
 25 files changed, 324 insertions(+), 1034 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/board-3430sdp.c
 delete mode 100644 arch/arm/mach-omap2/board-ti8168evm.c
 delete mode 100644 arch/arm/mach-omap2/gpmc-smc91x.c
 delete mode 100644 arch/arm/mach-omap2/gpmc-smc91x.h
Signature · 1 line
2.1.1
author maintainer
#1 lore raw

PATCH 1/10 ARM: dts: Fix bootloader version dependencies by muxing n900 smc91x pins

Apparently some versions of nolo don't mux the necessary GPMC pins for the smc91x probe to work properly. Let's fix this issue by adding mux support for GPMC to the kernel.

Note that it's unclear why the GPMC clk pin has input enabled, but let's not touch that as in general the mux settings in nolo are correct.

Cc Kevin Hilman <[email protected]>
Cc Roger Quadros <[email protected]>
---
 arch/arm/boot/dts/omap3-n900.dts | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
arch/arm/boot/dts/omap3-n900.dts +29 -0
index 739fcf2..e7210d1 100644
@@ -142,6 +142,33 @@
 		>;
 	};
 
+	gpmc_pins: pinmux_gpmc_pins {
+		pinctrl-single,pins = <
+
+			/* address lines */
+                        OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a1.gpmc_a1 */
+                        OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a2.gpmc_a2 */
+                        OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a3.gpmc_a3 */
+
+			/* data lines, gpmc_d0..d7 not muxable according to TRM */
+                        OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0)        /* gpmc_d8.gpmc_d8 */
+                        OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0)        /* gpmc_d9.gpmc_d9 */
+                        OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0)        /* gpmc_d10.gpmc_d10 */
+                        OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0)        /* gpmc_d11.gpmc_d11 */
+                        OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0)        /* gpmc_d12.gpmc_d12 */
+                        OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0)        /* gpmc_d13.gpmc_d13 */
+                        OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0)        /* gpmc_d14.gpmc_d14 */
+                        OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0)        /* gpmc_d15.gpmc_d15 */
+
+			/*
+			 * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable
+			 * according to TRM. REVISIT: why does nolo set input for gpmc_clk?
+			 */
+                        OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs1.gpmc_ncs1 */
+                        OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0)        /* gpmc_clk.gpmc_clk */
+		>;
+	};
+
 	i2c1_pins: pinmux_i2c1_pins {
 		pinctrl-single,pins = <
 			0x18a (PIN_INPUT | MUX_MODE0)		/* i2c1_scl */
@@ -588,6 +615,8 @@
 	ranges = <0 0 0x04000000 0x10000000>; /* 256MB */
 	ranges = <0 0 0x01000000 0x01000000>,	/* 16 MB for OneNAND */
 		 <1 0 0x02000000 0x01000000>;	/* 16 MB for smc91c96 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpmc_pins>;
 
 	/* gpio-irq for dma: 65 */
 
Signature · 1 line
2.1.1
#2 lore raw

PATCH 1/10 ARM: dts: Fix bootloader version dependencies by muxing n900 smc91x pins

Quoted 37 lines · Tony Lindgren

Apparently some versions of nolo don't mux the necessary GPMC pins for the smc91x probe to work properly. Let's fix this issue by adding mux support for GPMC to the kernel.

Note that it's unclear why the GPMC clk pin has input enabled, but let's not touch that as in general the mux settings in nolo are correct.

Cc Kevin Hilman <[email protected]>
Cc Roger Quadros <[email protected]>
---
 arch/arm/boot/dts/omap3-n900.dts | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
arch/arm/boot/dts/omap3-n900.dts +14 -0
index 739fcf2..e7210d1 100644
@@ -142,6 +142,33 @@
 		>;
 	};
 
+	gpmc_pins: pinmux_gpmc_pins {
+		pinctrl-single,pins = <
+
+			/* address lines */
+                        OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a1.gpmc_a1 */
+                        OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a2.gpmc_a2 */
+                        OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a3.gpmc_a3 */
+
+			/* data lines, gpmc_d0..d7 not muxable according to TRM */
+                        OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0)        /* gpmc_d8.gpmc_d8 */
+                        OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0)        /* gpmc_d9.gpmc_d9 */
+                        OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0)        /* gpmc_d10.gpmc_d10 */
+                        OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0)        /* gpmc_d11.gpmc_d11 */
+                        OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0)        /* gpmc_d12.gpmc_d12 */

arch/arm/boot/dts/omap3-n900.dts line 168

Quoted 10 lines
arch/arm/boot/dts/omap3-n900.dts +10 -0
+                        OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0)        /* gpmc_d13.gpmc_d13 */
+                        OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0)        /* gpmc_d14.gpmc_d14 */
+                        OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0)        /* gpmc_d15.gpmc_d15 */
+
+			/*
+			 * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable
+			 * according to TRM. REVISIT: why does nolo set input for gpmc_clk?
+			 */
+                        OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs1.gpmc_ncs1 */
+                        OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0)        /* gpmc_clk.gpmc_clk */

Right about the comment. GPMC_CLK should feed the CLK input of the OneNAND. This needs to be an OUTPUT pin.

Does OneNAND work when this pin is configured as output?

cheers,
-roger

Quoted 16 lines
arch/arm/boot/dts/omap3-n900.dts +5 -0
+		>;
+	};
+
 	i2c1_pins: pinmux_i2c1_pins {
 		pinctrl-single,pins = <
 			0x18a (PIN_INPUT | MUX_MODE0)		/* i2c1_scl */
@@ -588,6 +615,8 @@
 	ranges = <0 0 0x04000000 0x10000000>; /* 256MB */
 	ranges = <0 0 0x01000000 0x01000000>,	/* 16 MB for OneNAND */
 		 <1 0 0x02000000 0x01000000>;	/* 16 MB for smc91c96 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpmc_pins>;
 
 	/* gpio-irq for dma: 65 */
 
author maintainer
#3 lore raw

PATCH 1/10 ARM: dts: Fix bootloader version dependencies by muxing n900 smc91x pins

Quoted 12 lines · Roger Quadros

Review

Quoted 7 lines · Tony Lindgren
(quoted diff) +7 -0
+
+			/*
+			 * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable
+			 * according to TRM. REVISIT: why does nolo set input for gpmc_clk?
+			 */
+                        OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs1.gpmc_ncs1 */
+                        OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0)        /* gpmc_clk.gpmc_clk */

Right about the comment. GPMC_CLK should feed the CLK input of the OneNAND. This needs to be an OUTPUT pin.

Quoted 1 line

Does OneNAND work when this pin is configured as output?

Does not seem to work, it produces onenand_wait: ECC error = 0xffff.

It seems the clock needs to be copied to GPMC too in some cases. For MMC, there's the MMCSDIO2ADPCLKISEL option to copy the clock to account for level shifter latencies [1]. But in the OneNAND case I don't think there are any level shifters, and I don't think we have "copy clock" option for GPMC either in SCM so it somehow is automatic in GPMC.

Anyways, updated patch below with wrong guessing removed.

Regards,

Tony

[1] http://processors.wiki.ti.com/index.php/SD-MMC_Usage_Notes_on_OMAP35x_and_AM37x

8< --------------------
From: Tony Lindgren <[email protected]>
Date: Wed, 29 Oct 2014 17:16:47 -0700
Subject: [PATCH] ARM: dts: Fix bootloader version dependencies by muxing n900 smc91x pins

Apparently some versions of nolo don't mux the all the necessary GPMC pins for the smc91x probe to work properly. Let's fix this issue by adding mux support for GPMC to the kernel.

Note that GPMC clk needs input enabled for OnenNAND to work.

Cc Kevin Hilman <[email protected]>
Cc Roger Quadros <[email protected]>
arch/arm/boot/dts/omap3-n900.dts +29 -0
@@ -142,6 +142,33 @@
 		>;
 	};
 
+	gpmc_pins: pinmux_gpmc_pins {
+		pinctrl-single,pins = <
+
+			/* address lines */
+                        OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a1.gpmc_a1 */
+                        OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a2.gpmc_a2 */
+                        OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a3.gpmc_a3 */
+
+			/* data lines, gpmc_d0..d7 not muxable according to TRM */
+                        OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0)        /* gpmc_d8.gpmc_d8 */
+                        OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0)        /* gpmc_d9.gpmc_d9 */
+                        OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0)        /* gpmc_d10.gpmc_d10 */
+                        OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0)        /* gpmc_d11.gpmc_d11 */
+                        OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0)        /* gpmc_d12.gpmc_d12 */
+                        OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0)        /* gpmc_d13.gpmc_d13 */
+                        OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0)        /* gpmc_d14.gpmc_d14 */
+                        OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0)        /* gpmc_d15.gpmc_d15 */
+
+			/*
+			 * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable
+			 * according to TRM. OneNAND seems to require PIN_INPUT on clock.
+			 */
+                        OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs1.gpmc_ncs1 */
+                        OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0)        /* gpmc_clk.gpmc_clk */
+		>;
+	};
+
 	i2c1_pins: pinmux_i2c1_pins {
 		pinctrl-single,pins = <
 			0x18a (PIN_INPUT | MUX_MODE0)		/* i2c1_scl */
@@ -588,6 +615,8 @@
 	ranges = <0 0 0x04000000 0x10000000>; /* 256MB */
 	ranges = <0 0 0x01000000 0x01000000>,	/* 16 MB for OneNAND */
 		 <1 0 0x02000000 0x01000000>;	/* 16 MB for smc91c96 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpmc_pins>;
 
 	/* gpio-irq for dma: 65 */
 
#4 lore raw

PATCH 1/10 ARM: dts: Fix bootloader version dependencies by muxing n900 smc91x pins

Quoted 42 lines · Tony Lindgren
Quoted 12 lines · Roger Quadros

arch/arm/boot/dts/omap3-n900.dts line 168

Quoted 7 lines · Tony Lindgren
arch/arm/boot/dts/omap3-n900.dts +7 -0
+
+			/*
+			 * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable
+			 * according to TRM. REVISIT: why does nolo set input for gpmc_clk?
+			 */
+                        OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs1.gpmc_ncs1 */
+                        OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0)        /* gpmc_clk.gpmc_clk */

Right about the comment. GPMC_CLK should feed the CLK input of the OneNAND. This needs to be an OUTPUT pin.

Quoted 1 line

Does OneNAND work when this pin is configured as output?

Does not seem to work, it produces onenand_wait: ECC error = 0xffff.

It seems the clock needs to be copied to GPMC too in some cases. For MMC, there's the MMCSDIO2ADPCLKISEL option to copy the clock to account for level shifter latencies [1]. But in the OneNAND case I don't think there are any level shifters, and I don't think we have "copy clock" option for GPMC either in SCM so it somehow is automatic in GPMC.

Anyways, updated patch below with wrong guessing removed.

Regards,

Tony

[1] http://processors.wiki.ti.com/index.php/SD-MMC_Usage_Notes_on_OMAP35x_and_AM37x

8< --------------------
From: Tony Lindgren <[email protected]>
Date: Wed, 29 Oct 2014 17:16:47 -0700
Subject: [PATCH] ARM: dts: Fix bootloader version dependencies by muxing n900 smc91x pins

Apparently some versions of nolo don't mux the all the necessary GPMC pins for the smc91x probe to work properly. Let's fix this issue by adding mux support for GPMC to the kernel.

Quoted 5 lines

Note that GPMC clk needs input enabled for OnenNAND to work.

Cc Kevin Hilman <[email protected]>
Cc Roger Quadros <[email protected]>

cheers,
-roger

author maintainer
#5 lore raw

PATCH 2/10 ARM: dts: Fix wrong GPMC size mappings for omaps

In reply to Tony Lindgren

The GPMC binding is obviously very confusing as the values are all over the place. People seem to confuse the GPMC partition size for the chip select, and the device IO size within the GPMC partition easily.

The ranges entry contains the GPMC partition size. And the reg entry contains the size of the IO registers of the device connected to the GPMC.

Let's fix the issue according to the following table:

Device          GPMC partition size     Device IO size
connected       in the ranges entry     in the reg entry
NAND            0x01000000 (16MB)       4
16550           0x01000000 (16MB)       8
smc91x          0x01000000 (16MB)       0xf
smc911x         0x01000000 (16MB)       0xff
OneNAND         0x01000000 (16MB)       0x20000 (128KB)
16MB NOR        0x01000000 (16MB)       0x01000000 (16MB)
32MB NOR        0x02000000 (32MB)       0x02000000 (32MB)
64MB NOR        0x04000000 (64MB)       0x04000000 (64MB)
128MB NOR       0x08000000 (128MB)      0x08000000 (128MB)
256MB NOR       0x10000000 (256MB)      0x10000000 (256MB)

Let's also add comments to the fixed entries while at it.

---
 arch/arm/boot/dts/am335x-evm.dts            | 4 ++--
 arch/arm/boot/dts/am335x-igep0033.dtsi      | 4 ++--
 arch/arm/boot/dts/am43x-epos-evm.dts        | 4 ++--
 arch/arm/boot/dts/omap-zoom-common.dtsi     | 4 ++--
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 4 ++--
 arch/arm/boot/dts/omap3-devkit8000.dts      | 4 ++--
 arch/arm/boot/dts/omap3-evm-37xx.dts        | 4 ++--
 arch/arm/boot/dts/omap3-gta04.dtsi          | 4 ++--
 arch/arm/boot/dts/omap3-igep0020.dts        | 4 ++--
 arch/arm/boot/dts/omap3-igep0030.dts        | 4 ++--
 arch/arm/boot/dts/omap3-ldp.dts             | 2 +-
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi     | 2 +-
 arch/arm/boot/dts/omap3-n900.dts            | 6 ++----
 arch/arm/boot/dts/omap3-n950-n9.dtsi        | 4 ++--
 arch/arm/boot/dts/omap3-tao3530.dtsi        | 2 +-
 arch/arm/boot/dts/omap3430-sdp.dts          | 8 ++++----
 16 files changed, 31 insertions(+), 33 deletions(-)
arch/arm/boot/dts/am335x-evm.dts +2 -2
index e2156a5..43a536c 100644
@@ -437,9 +437,9 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&nandflash_pins_s0>;
-	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 	nand at 0,0 {
-		reg = <0 0 0>; /* CS0, offset 0 */
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
arch/arm/boot/dts/am335x-igep0033.dtsi +2 -2
index a1a0cc5..c0e1135 100644
@@ -126,10 +126,10 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&nandflash_pins>;
 
-	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 
 	nand at 0,0 {
-		reg = <0 0 0>; /* CS0, offset 0 */
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
 		nand-bus-width = <8>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,device-width = <1>;
arch/arm/boot/dts/am43x-epos-evm.dts +2 -2
index ac3e485..bb4cb85 100644
@@ -438,9 +438,9 @@
 	status = "okay";	/* Disable QSPI when enabling GPMC (NAND) */
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_flash_x8>;
-	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 	nand at 0,0 {
-		reg = <0 0 0>; /* CS0, offset 0 */
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
 		ti,nand-ecc-opt = "bch16";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
arch/arm/boot/dts/omap-zoom-common.dtsi +2 -2
index 68221fa..2889b50 100644
@@ -5,7 +5,7 @@
 #include "omap-gpmc-smsc911x.dtsi"
 
 &gpmc {
-	ranges = <3 0 0x10000000 0x00000400>,
+	ranges = <3 0 0x10000000 0x1000000>,	/* CS3: 16MB for UART */
 		 <7 0 0x2c000000 0x01000000>;
 
 	/*
@@ -15,7 +15,7 @@
 	 */
 	uart at 3,0 {
 		compatible = "ns16550a";
-		reg = <3 0 0x100>;
+		reg = <3 0 8>;	/* CS3, offset 0, IO size 8 */
 		bank-width = <2>;
 		reg-shift = <1>;
 		reg-io-width = <1>;
arch/arm/boot/dts/omap2420-n8x0-common.dtsi +2 -2
index 24c50db..c9f1e93 100644
@@ -40,14 +40,14 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x04000000 0x10000000>;
+	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
 
 	/* gpio-irq for dma: 26 */
 
 	onenand at 0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		reg = <0 0 0x10000000>;
+		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
 		gpmc,burst-length = <16>;
arch/arm/boot/dts/omap3-devkit8000.dts +2 -2
index da402f0..169037e 100644
@@ -106,10 +106,10 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x30000000 0x04>;       /* CS0: NAND */
+	ranges = <0 0 0x30000000 0x1000000>;       /* CS0: 16MB for NAND */
 
 	nand at 0,0 {
-		reg = <0 0 0>; /* CS0, offset 0 */
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 
 		gpmc,sync-clk-ps = <0>;
arch/arm/boot/dts/omap3-evm-37xx.dts +2 -2
index a8bd434..f73385b 100644
@@ -154,12 +154,12 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x20000000>,
+	ranges = <0 0 0x00000000 0x1000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;
 
 	nand at 0,0 {
 		linux,mtd-name= "hynix,h8kds0un0mer-4em";
-		reg = <0 0 0>;
+		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 
arch/arm/boot/dts/omap3-gta04.dtsi +2 -2
index fd34f91..91bba85 100644
@@ -397,10 +397,10 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x30000000 0x04>; /* CS0: NAND */
+	ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
 
 	nand at 0,0 {
-		reg = <0 0 0>; /* CS0, offset 0 */
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 
arch/arm/boot/dts/omap3-igep0020.dts +2 -2
index b22caaa..ff0b11d 100644
@@ -197,12 +197,12 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x20000000>,
+	ranges = <0 0 0x00000000 0x1000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;
 
 	nand at 0,0 {
 		linux,mtd-name= "micron,mt29c4g96maz";
-		reg = <0 0 0>;
+		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 
arch/arm/boot/dts/omap3-igep0030.dts +2 -2
index 2793749..fd7ed71 100644
@@ -55,11 +55,11 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x20000000>;
+	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
 
 	nand at 0,0 {
 		linux,mtd-name= "micron,mt29c4g96maz";
-		reg = <0 0 0>;
+		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 
arch/arm/boot/dts/omap3-ldp.dts +1 -1
index 72dca0b..37d305a 100644
@@ -101,7 +101,7 @@
 
 	nand at 0,0 {
 		linux,mtd-name= "micron,nand";
-		reg = <0 0 0>;
+		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 
arch/arm/boot/dts/omap3-lilly-a83x.dtsi +1 -1
index d973088..e81fb65 100644
@@ -363,7 +363,7 @@
 		<7 0 0x15000000 0x01000000>;
 
 	nand at 0,0 {
-		reg = <0 0 0x1000000>;
+		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 		/* no elm on omap3 */
arch/arm/boot/dts/omap3-n900.dts +2 -4
index e7210d1..7cfc777 100644
@@ -612,18 +612,16 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x04000000 0x10000000>; /* 256MB */
 	ranges = <0 0 0x01000000 0x01000000>,	/* 16 MB for OneNAND */
 		 <1 0 0x02000000 0x01000000>;	/* 16 MB for smc91c96 */
 	pinctrl-names = "default";
 	pinctrl-0 = <&gpmc_pins>;
 
-	/* gpio-irq for dma: 65 */
-
+	/* sys_ndmareq1 could be used by the driver, not as gpio65 though */
 	onenand at 0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		reg = <0 0 0x10000000>;
+		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
 		gpmc,sync-write;
arch/arm/boot/dts/omap3-n950-n9.dtsi +2 -2
index 70addcb..1e49dfe 100644
@@ -115,12 +115,12 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x04000000 0x20000000>;
+	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
 
 	onenand at 0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		reg = <0 0 0x20000000>;
+		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
 		gpmc,sync-write;
arch/arm/boot/dts/omap3-tao3530.dtsi +1 -1
index b30f387..e89820a 100644
@@ -270,7 +270,7 @@
 	ranges = <0 0 0x00000000 0x01000000>;
 
 	nand at 0,0 {
-		reg = <0 0 0>; /* CS0, offset 0 */
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;	/* GPMC_DEVWIDTH_16BIT */
 		ti,nand-ecc-opt = "sw";
arch/arm/boot/dts/omap3430-sdp.dts +4 -4
index 9bad94e..16b0cdf 100644
@@ -51,8 +51,8 @@
 
 &gpmc {
 	ranges = <0 0 0x10000000 0x08000000>,
-		 <1 0 0x28000000 0x08000000>,
-		 <2 0 0x20000000 0x10000000>;
+		 <1 0 0x28000000 0x1000000>,	/* CS1: 16MB for NAND */
+		 <2 0 0x20000000 0x1000000>;	/* CS2: 16MB for OneNAND */
 
 	nor at 0,0 {
 		compatible = "cfi-flash";
@@ -106,7 +106,7 @@
 		linux,mtd-name= "micron,mt29f1g08abb";
 		#address-cells = <1>;
 		#size-cells = <1>;
-		reg = <1 0 0x08000000>;
+		reg = <1 0 4>;	/* CS1, offset 0, IO size 4 */
 		ti,nand-ecc-opt = "sw";
 		nand-bus-width = <8>;
 		gpmc,cs-on-ns = <0>;
@@ -150,7 +150,7 @@
 		linux,mtd-name= "samsung,kfm2g16q2m-deb8";
 		#address-cells = <1>;
 		#size-cells = <1>;
-		reg = <2 0 0x10000000>;
+		reg = <2 0 0x20000>;	/* CS2, offset 0, IO size 4 */
 
 		gpmc,device-width = <2>;
 		gpmc,mux-add-data = <2>;
Signature · 1 line
2.1.1
#6 lore raw

PATCH 2/10 ARM: dts: Fix wrong GPMC size mappings for omaps

Quoted 25 lines · Tony Lindgren

The GPMC binding is obviously very confusing as the values are all over the place. People seem to confuse the GPMC partition size for the chip select, and the device IO size within the GPMC partition easily.

The ranges entry contains the GPMC partition size. And the reg entry contains the size of the IO registers of the device connected to the GPMC.

Let's fix the issue according to the following table:

Device          GPMC partition size     Device IO size
connected       in the ranges entry     in the reg entry
NAND            0x01000000 (16MB)       4
16550           0x01000000 (16MB)       8
smc91x          0x01000000 (16MB)       0xf
smc911x         0x01000000 (16MB)       0xff
OneNAND         0x01000000 (16MB)       0x20000 (128KB)
16MB NOR        0x01000000 (16MB)       0x01000000 (16MB)
32MB NOR        0x02000000 (32MB)       0x02000000 (32MB)
64MB NOR        0x04000000 (64MB)       0x04000000 (64MB)
128MB NOR       0x08000000 (128MB)      0x08000000 (128MB)
256MB NOR       0x10000000 (256MB)      0x10000000 (256MB)
Quoted 4 lines

Let's also add comments to the fixed entries while at it.

cheers,
-roger

author maintainer
#7 lore raw

PATCH 3/10 ARM: dts: Add smc91x GPMC configuration for 2430sdp

In reply to Tony Lindgren

Let's use the bootloader values except for the partially configured wait-pin that does not seem to work.

---
 arch/arm/boot/dts/omap2430-sdp.dts | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)
arch/arm/boot/dts/omap2430-sdp.dts +26 -2
index 2c90d29..05eca2e 100644
@@ -43,7 +43,31 @@
 		interrupts = <21 IRQ_TYPE_LEVEL_LOW>;	/* gpio149 */
 		reg = <5 0x300 0xf>;
 		bank-width = <2>;
-		gpmc,mux-add-data;
-        };
+		gpmc,sync-clk-ps = <0>;
+		gpmc,mux-add-data = <2>;
+		gpmc,device-width = <1>;
+		gpmc,cycle2cycle-samecsen = <1>;
+		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cs-on-ns = <7>;
+		gpmc,cs-rd-off-ns = <233>;
+		gpmc,cs-wr-off-ns = <233>;
+		gpmc,adv-on-ns = <22>;
+		gpmc,adv-rd-off-ns = <60>;
+		gpmc,adv-wr-off-ns = <60>;
+		gpmc,oe-on-ns = <67>;
+		gpmc,oe-off-ns = <210>;
+		gpmc,we-on-ns = <67>;
+		gpmc,we-off-ns = <210>;
+		gpmc,rd-cycle-ns = <233>;
+		gpmc,wr-cycle-ns = <233>;
+		gpmc,access-ns = <233>;
+		gpmc,page-burst-access-ns = <30>;
+		gpmc,bus-turnaround-ns = <30>;
+		gpmc,cycle2cycle-delay-ns = <30>;
+		gpmc,wait-monitoring-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+		gpmc,wr-access-ns = <0>;
+	};
 };
 
Signature · 1 line
2.1.1
author maintainer
#8 lore raw

PATCH 4/10 ARM: dts: Add GPMC timings for omap zoom serial port

In reply to Tony Lindgren

The four port serial port on the zoom debug board uses a TL16CP754C with a single interrupt and GPMC chip select. The serial ports each use a 8 bytes for IO registers, and are 256 bytes apart on the GPMC line.

Let's add timings for all four ports so we can remove the GPMC workarounds for using bootloader timings.

Not caused by this patch, but looks like u-boot only properly initializes the fifo on the first serial port. Currently the other ports produce garbage at least with my version of u-boot. I suspect that TL16CP754C needs non-standard initialization added to 8250 driver to properly fix this issue.

---
 arch/arm/boot/dts/omap-zoom-common.dtsi | 58 +++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
arch/arm/boot/dts/omap-zoom-common.dtsi +58 -0
index 2889b50..46ef3e4 100644
@@ -23,6 +23,64 @@
 		interrupts = <6 IRQ_TYPE_EDGE_RISING>;	/* gpio102 */
 		clock-frequency = <1843200>;
 		current-speed = <115200>;
+		gpmc,mux-add-data = <0>;
+		gpmc,device-width = <1>;
+		gpmc,wait-pin = <1>;
+		gpmc,cycle2cycle-samecsen = <1>;
+		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cs-on-ns = <5>;
+		gpmc,cs-rd-off-ns = <155>;
+		gpmc,cs-wr-off-ns = <155>;
+		gpmc,adv-on-ns = <15>;
+		gpmc,adv-rd-off-ns = <40>;
+		gpmc,adv-wr-off-ns = <40>;
+		gpmc,oe-on-ns = <45>;
+		gpmc,oe-off-ns = <145>;
+		gpmc,we-on-ns = <45>;
+		gpmc,we-off-ns = <145>;
+		gpmc,rd-cycle-ns = <155>;
+		gpmc,wr-cycle-ns = <155>;
+		gpmc,access-ns = <145>;
+		gpmc,page-burst-access-ns = <20>;
+		gpmc,bus-turnaround-ns = <20>;
+		gpmc,cycle2cycle-delay-ns = <20>;
+		gpmc,wait-monitoring-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wr-data-mux-bus-ns = <45>;
+		gpmc,wr-access-ns = <145>;
+	};
+	uart at 3,1 {
+		compatible = "ns16550a";
+		reg = <3 0x100 8>;	/* CS3, offset 0x100, IO size 8 */
+		bank-width = <2>;
+		reg-shift = <1>;
+		reg-io-width = <1>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <6 IRQ_TYPE_EDGE_RISING>;	/* gpio102 */
+		clock-frequency = <1843200>;
+		current-speed = <115200>;
+	};
+	uart at 3,2 {
+		compatible = "ns16550a";
+		reg = <3 0x200 8>;	/* CS3, offset 0x200, IO size 8 */
+		bank-width = <2>;
+		reg-shift = <1>;
+		reg-io-width = <1>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <6 IRQ_TYPE_EDGE_RISING>;	/* gpio102 */
+		clock-frequency = <1843200>;
+		current-speed = <115200>;
+	};
+	uart at 3,3 {
+		compatible = "ns16550a";
+		reg = <3 0x300 8>;	/* CS3, offset 0x300, IO size 8 */
+		bank-width = <2>;
+		reg-shift = <1>;
+		reg-io-width = <1>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <6 IRQ_TYPE_EDGE_RISING>;	/* gpio102 */
+		clock-frequency = <1843200>;
+		current-speed = <115200>;
 	};
 
 	ethernet at gpmc {
Signature · 1 line
2.1.1
#9 lore raw

PATCH 4/10 ARM: dts: Add GPMC timings for omap zoom serial port

Quoted 8 lines · Tony Lindgren

The four port serial port on the zoom debug board uses a TL16CP754C with a single interrupt and GPMC chip select. The serial ports each use a 8 bytes for IO registers, and are 256 bytes apart on the GPMC line.

Let's add timings for all four ports so we can remove the GPMC workarounds for using bootloader timings.

Quoted 8 lines

Not caused by this patch, but looks like u-boot only properly initializes the fifo on the first serial port. Currently the other ports produce garbage at least with my version of u-boot. I suspect that TL16CP754C needs non-standard initialization added to 8250 driver to properly fix this issue.

I haven't cross checked the timings, but otherwise it looks good to me.

cheers,
-roger

Quoted 74 lines
---
 arch/arm/boot/dts/omap-zoom-common.dtsi | 58 +++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
arch/arm/boot/dts/omap-zoom-common.dtsi +58 -0
index 2889b50..46ef3e4 100644
@@ -23,6 +23,64 @@
 		interrupts = <6 IRQ_TYPE_EDGE_RISING>;	/* gpio102 */
 		clock-frequency = <1843200>;
 		current-speed = <115200>;
+		gpmc,mux-add-data = <0>;
+		gpmc,device-width = <1>;
+		gpmc,wait-pin = <1>;
+		gpmc,cycle2cycle-samecsen = <1>;
+		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cs-on-ns = <5>;
+		gpmc,cs-rd-off-ns = <155>;
+		gpmc,cs-wr-off-ns = <155>;
+		gpmc,adv-on-ns = <15>;
+		gpmc,adv-rd-off-ns = <40>;
+		gpmc,adv-wr-off-ns = <40>;
+		gpmc,oe-on-ns = <45>;
+		gpmc,oe-off-ns = <145>;
+		gpmc,we-on-ns = <45>;
+		gpmc,we-off-ns = <145>;
+		gpmc,rd-cycle-ns = <155>;
+		gpmc,wr-cycle-ns = <155>;
+		gpmc,access-ns = <145>;
+		gpmc,page-burst-access-ns = <20>;
+		gpmc,bus-turnaround-ns = <20>;
+		gpmc,cycle2cycle-delay-ns = <20>;
+		gpmc,wait-monitoring-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wr-data-mux-bus-ns = <45>;
+		gpmc,wr-access-ns = <145>;
+	};
+	uart at 3,1 {
+		compatible = "ns16550a";
+		reg = <3 0x100 8>;	/* CS3, offset 0x100, IO size 8 */
+		bank-width = <2>;
+		reg-shift = <1>;
+		reg-io-width = <1>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <6 IRQ_TYPE_EDGE_RISING>;	/* gpio102 */
+		clock-frequency = <1843200>;
+		current-speed = <115200>;
+	};
+	uart at 3,2 {
+		compatible = "ns16550a";
+		reg = <3 0x200 8>;	/* CS3, offset 0x200, IO size 8 */
+		bank-width = <2>;
+		reg-shift = <1>;
+		reg-io-width = <1>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <6 IRQ_TYPE_EDGE_RISING>;	/* gpio102 */
+		clock-frequency = <1843200>;
+		current-speed = <115200>;
+	};
+	uart at 3,3 {
+		compatible = "ns16550a";
+		reg = <3 0x300 8>;	/* CS3, offset 0x300, IO size 8 */
+		bank-width = <2>;
+		reg-shift = <1>;
+		reg-io-width = <1>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <6 IRQ_TYPE_EDGE_RISING>;	/* gpio102 */
+		clock-frequency = <1843200>;
+		current-speed = <115200>;
 	};
 
 	ethernet at gpmc {
author maintainer
#10 lore raw

PATCH 5/10 ARM: OMAP2+: Fix support for multiple devices on a GPMC chip select

In reply to Tony Lindgren

There are cases where we have multiple device instances connected to a single GPMC chip select. For example, there are four UARTs on the Zoom debug boards that all share a single chip select and a GPIO interrupt.

We do have support for this already in theory, but it's broken because we're bailing out if the chip select is already taken.

To be able to provide checks on the chip select usage, let's add new struct gpmc_cs_data so we can start using already registered device names for checks.

Later on we probably want to start using struct gpmc_cs_data as a wrapper for all the GPMC chipselect related data.

---
 arch/arm/mach-omap2/gpmc.c | 61 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 49 insertions(+), 12 deletions(-)
arch/arm/mach-omap2/gpmc.c +49 -12
index 5fa3755..2c5f348 100644
@@ -118,6 +118,15 @@
  */
 #define	GPMC_NR_IRQ		2
 
+struct gpmc_cs_data {
+	const char *name;
+
+#define GPMC_CS_RESERVED	(1 << 0)
+	u32 flags;
+
+	struct resource mem;
+};
+
 struct gpmc_client_irq	{
 	unsigned		irq;
 	u32			bitmask;
@@ -155,10 +164,9 @@ static struct irq_chip gpmc_irq_chip;
 static int gpmc_irq_start;
 
 static struct resource	gpmc_mem_root;
-static struct resource	gpmc_cs_mem[GPMC_CS_NUM];
+static struct gpmc_cs_data gpmc_cs[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
 /* Define chip-selects as reserved by default until probe completes */
-static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
 static unsigned int gpmc_cs_num = GPMC_CS_NUM;
 static unsigned int gpmc_nr_waitpins;
 static struct device *gpmc_dev;
@@ -460,13 +468,30 @@ static int gpmc_cs_mem_enabled(int cs)
 
 static void gpmc_cs_set_reserved(int cs, int reserved)
 {
-	gpmc_cs_map &= ~(1 << cs);
-	gpmc_cs_map |= (reserved ? 1 : 0) << cs;
+	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
+
+	gpmc->flags |= GPMC_CS_RESERVED;
 }
 
 static bool gpmc_cs_reserved(int cs)
 {
-	return gpmc_cs_map & (1 << cs);
+	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
+
+	return gpmc->flags & GPMC_CS_RESERVED;
+}
+
+static void gpmc_cs_set_name(int cs, const char *name)
+{
+	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
+
+	gpmc->name = name;
+}
+
+const char *gpmc_cs_get_name(int cs)
+{
+	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
+
+	return gpmc->name;
 }
 
 static unsigned long gpmc_mem_align(unsigned long size)
@@ -485,7 +510,8 @@ static unsigned long gpmc_mem_align(unsigned long size)
 
 static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
 {
-	struct resource	*res = &gpmc_cs_mem[cs];
+	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
+	struct resource *res = &gpmc->mem;
 	int r;
 
 	size = gpmc_mem_align(size);
@@ -500,7 +526,8 @@ static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
 
 static int gpmc_cs_delete_mem(int cs)
 {
-	struct resource	*res = &gpmc_cs_mem[cs];
+	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
+	struct resource *res = &gpmc->mem;
 	int r;
 
 	spin_lock(&gpmc_mem_lock);
@@ -557,7 +584,8 @@ static int gpmc_cs_remap(int cs, u32 base)
 
 int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
 {
-	struct resource *res = &gpmc_cs_mem[cs];
+	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
+	struct resource *res = &gpmc->mem;
 	int r = -1;
 
 	if (cs > gpmc_cs_num) {
@@ -597,7 +625,8 @@ EXPORT_SYMBOL(gpmc_cs_request);
 
 void gpmc_cs_free(int cs)
 {
-	struct resource	*res = &gpmc_cs_mem[cs];
+	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
+	struct resource *res = &gpmc->mem;
 
 	spin_lock(&gpmc_mem_lock);
 	if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
@@ -1511,6 +1540,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	struct gpmc_timings gpmc_t;
 	struct resource res;
 	unsigned long base;
+	const char *name;
 	int ret, cs;
 
 	if (of_property_read_u32(child, "reg", &cs) < 0) {
@@ -1525,11 +1555,21 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		return -ENODEV;
 	}
 
+	/*
+	 * Check if we have multiple instances of the same device
+	 * on a single chip select. If so, use the already initialized
+	 * timings.
+	 */
+	name = gpmc_cs_get_name(cs);
+	if (name && child->name && of_node_cmp(child->name, name) == 0)
+			goto no_timings;
+
 	ret = gpmc_cs_request(cs, resource_size(&res), &base);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
 		return ret;
 	}
+	gpmc_cs_set_name(cs, child->name);
 
 	/*
 	 * For some GPMC devices we still need to rely on the bootloader
@@ -1708,9 +1748,6 @@ static int gpmc_probe(struct platform_device *pdev)
 	if (gpmc_setup_irq() < 0)
 		dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
 
-	/* Now the GPMC is initialised, unreserve the chip-selects */
-	gpmc_cs_map = 0;
-
 	if (!pdev->dev.of_node) {
 		gpmc_cs_num	 = GPMC_CS_NUM;
 		gpmc_nr_waitpins = GPMC_NR_WAITPINS;
Signature · 1 line
2.1.1
#11 lore raw

PATCH 5/10 ARM: OMAP2+: Fix support for multiple devices on a GPMC chip select

Quoted 12 lines · Tony Lindgren

There are cases where we have multiple device instances connected to a single GPMC chip select. For example, there are four UARTs on the Zoom debug boards that all share a single chip select and a GPIO interrupt.

We do have support for this already in theory, but it's broken because we're bailing out if the chip select is already taken.

To be able to provide checks on the chip select usage, let's add new struct gpmc_cs_data so we can start using already registered device names for checks.

Quoted 5 lines

Later on we probably want to start using struct gpmc_cs_data as a wrapper for all the GPMC chipselect related data.

cheers,
-roger

author maintainer
#12 lore raw

PATCH 6/10 ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

In reply to Tony Lindgren

As we still have some devices with GPMC timings missing from the .dts files, let's make it a bit easier to use the bootloader values and print them out.

Note that we now need to move the parsing of the device tree provided configuration a bit earlier so we can use that for checking if anything was configured.

---
 arch/arm/mach-omap2/gpmc.c | 141 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 137 insertions(+), 4 deletions(-)
arch/arm/mach-omap2/gpmc.c +137 -4
index 2c5f348..0999923 100644
@@ -291,6 +291,123 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
 			   p->cycle2cyclediffcsen);
 }
 
+static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+			       bool raw, bool noval, int shift,
+			       const char *name)
+{
+	u32 l;
+	int nr_bits, max_value, mask;
+
+	l = gpmc_cs_read_reg(cs, reg);
+	nr_bits = end_bit - st_bit + 1;
+	max_value = (1 << nr_bits) - 1;
+	mask = max_value << st_bit;
+	l = (l & mask) >> st_bit;
+	if (shift)
+		l <<= shift;
+	if (noval && (l == 0))
+		return 0;
+	if (!raw) {
+		unsigned int time_ns_min, time_ns, time_ns_max;
+
+		time_ns_min = gpmc_ticks_to_ns(l ? l - 1 : 0);
+		time_ns = gpmc_ticks_to_ns(l);
+		time_ns_max = gpmc_ticks_to_ns(l + 1 > max_value ?
+					       max_value : l + 1);
+		pr_info("gpmc,%s = <%u> (%u - %u ns, %i ticks)\n",
+			name, time_ns, time_ns_min, time_ns_max, l);
+	} else {
+		pr_info("gpmc,%s = <%u>\n", name, l);
+	}
+
+	return l;
+}
+
+#define GPMC_PRINT_CONFIG(cs, config) \
+	pr_info("cs%i %s: 0x%08x\n", cs, #config, \
+		gpmc_cs_read_reg(cs, config))
+#define GPMC_GET_RAW(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 0, 0, field)
+#define GPMC_GET_RAW_BOOL(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, 0, field)
+#define GPMC_GET_RAW_SHIFT(reg, st, end, shift, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, (shift), field)
+#define GPMC_GET_TICKS(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 0, 0, 0, field)
+
+static void gpmc_show_regs(int cs, const char *desc)
+{
+	pr_info("gpmc cs%i %s:\n", cs, desc);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG1);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG2);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG3);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG4);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG5);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG6);
+}
+
+/*
+ * Note that gpmc,wait-pin handing wrongly assumes bit 8 is available,
+ * see commit c9fb809.
+ */
+static void gpmc_cs_show_timings(int cs, const char *desc)
+{
+	gpmc_show_regs(cs, desc);
+
+	pr_info("gpmc cs%i access configuration:\n", cs);
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
+	GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 3, "burst-length");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 27, 27, "sync-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 28, 28, "burst-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 29, 29, "gpmc,sync-read");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 30, 30, "burst-read");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 31, 31, "burst-wrap");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG2,  7,  7, "cs-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG3,  7,  7, "adv-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4, 23, 23, "we-extra-delay");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4,  7,  7, "oe-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6,  7,  7, "cycle2cycle-samecsen");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6,  6,  6, "cycle2cycle-diffcsen");
+
+	pr_info("gpmc cs%i timings configuration:\n", cs);
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2,  0,  3, "cs-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2,  8, 12, "cs-rd-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2, 16, 20, "cs-wr-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3,  0,  3, "adv-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3,  8, 12, "adv-rd-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3, 16, 20, "adv-wr-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4,  0,  3, "oe-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4,  8, 12, "oe-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4, 16, 19, "we-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4, 24, 28, "we-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5,  0,  4, "rd-cycle-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5,  8, 12, "wr-cycle-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5, 16, 20, "access-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5, 24, 27, "page-burst-access-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 0, 3, "bus-turnaround-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 8, 11, "cycle2cycle-delay-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG1, 18, 19, "wait-monitoring-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG1, 25, 26, "clk-activation-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 16, 19, "wr-data-mux-bus-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 24, 28, "wr-access-ns");
+}
+
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 			       int time, const char *name)
@@ -361,6 +478,9 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	int div;
 	u32 l;
 
+#ifdef DEBUG
+	gpmc_cs_show_timings(cs, "before gpmc_cs_set_timings");
+#endif
 	div = gpmc_calc_divider(t->sync_clk);
 	if (div < 0)
 		return div;
@@ -410,7 +530,9 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	}
 
 	gpmc_cs_bool_timings(cs, &t->bool_timings);
-
+#ifdef DEBUG
+	gpmc_cs_show_timings(cs, "after gpmc_cs_set_timings");
+#endif
 	return 0;
 }
 
@@ -1571,6 +1693,20 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	}
 	gpmc_cs_set_name(cs, child->name);
 
+	gpmc_read_settings_dt(child, &gpmc_s);
+	gpmc_read_timings_dt(child, &gpmc_t);
+
+	/*
+	 * For some GPMC devices we still need to rely on the bootloader
+	 * timings because the devices can be connected via FPGA.
+	 * REVISIT: Add timing support from slls644g.pdf.
+	 */
+	if (!gpmc_t.cs_rd_off) {
+		gpmc_cs_show_timings(cs,
+				     "please add GPMC bootloader timings to .dts");
+		goto no_timings;
+	}
+
 	/*
 	 * For some GPMC devices we still need to rely on the bootloader
 	 * timings because the devices can be connected via FPGA. So far
@@ -1602,8 +1738,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		goto err;
 	}
 
-	gpmc_read_settings_dt(child, &gpmc_s);
-
 	ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
 	if (ret < 0)
 		goto err;
@@ -1612,7 +1746,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	if (ret < 0)
 		goto err;
 
-	gpmc_read_timings_dt(child, &gpmc_t);
 	gpmc_cs_set_timings(cs, &gpmc_t);
 
 no_timings:
Signature · 1 line
2.1.1
#13 lore raw

PATCH 6/10 ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

Quoted 83 lines · Tony Lindgren

As we still have some devices with GPMC timings missing from the .dts files, let's make it a bit easier to use the bootloader values and print them out.

Note that we now need to move the parsing of the device tree provided configuration a bit earlier so we can use that for checking if anything was configured.

---
 arch/arm/mach-omap2/gpmc.c | 141 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 137 insertions(+), 4 deletions(-)
arch/arm/mach-omap2/gpmc.c +61 -0
index 2c5f348..0999923 100644
@@ -291,6 +291,123 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
 			   p->cycle2cyclediffcsen);
 }
 
+static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+			       bool raw, bool noval, int shift,
+			       const char *name)
+{
+	u32 l;
+	int nr_bits, max_value, mask;
+
+	l = gpmc_cs_read_reg(cs, reg);
+	nr_bits = end_bit - st_bit + 1;
+	max_value = (1 << nr_bits) - 1;
+	mask = max_value << st_bit;
+	l = (l & mask) >> st_bit;
+	if (shift)
+		l <<= shift;
+	if (noval && (l == 0))
+		return 0;
+	if (!raw) {
+		unsigned int time_ns_min, time_ns, time_ns_max;
+
+		time_ns_min = gpmc_ticks_to_ns(l ? l - 1 : 0);
+		time_ns = gpmc_ticks_to_ns(l);
+		time_ns_max = gpmc_ticks_to_ns(l + 1 > max_value ?
+					       max_value : l + 1);
+		pr_info("gpmc,%s = <%u> (%u - %u ns, %i ticks)\n",
+			name, time_ns, time_ns_min, time_ns_max, l);
+	} else {
+		pr_info("gpmc,%s = <%u>\n", name, l);
+	}
+
+	return l;
+}
+
+#define GPMC_PRINT_CONFIG(cs, config) \
+	pr_info("cs%i %s: 0x%08x\n", cs, #config, \
+		gpmc_cs_read_reg(cs, config))
+#define GPMC_GET_RAW(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 0, 0, field)
+#define GPMC_GET_RAW_BOOL(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, 0, field)
+#define GPMC_GET_RAW_SHIFT(reg, st, end, shift, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, (shift), field)
+#define GPMC_GET_TICKS(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 0, 0, 0, field)
+
+static void gpmc_show_regs(int cs, const char *desc)
+{
+	pr_info("gpmc cs%i %s:\n", cs, desc);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG1);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG2);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG3);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG4);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG5);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG6);
+}
+
+/*
+ * Note that gpmc,wait-pin handing wrongly assumes bit 8 is available,
+ * see commit c9fb809.
+ */
+static void gpmc_cs_show_timings(int cs, const char *desc)
+{

arch/arm/mach-omap2/gpmc.c static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) · line 364

Quoted 10 lines
arch/arm/mach-omap2/gpmc.c +10 -0
+	gpmc_show_regs(cs, desc);
+
+	pr_info("gpmc cs%i access configuration:\n", cs);
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
+	GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 3, "burst-length");

how does this work with shift = 3?
Possible values of burst length are
0 -> 4
1 -> 8
2 -> 16

Quoted 36 lines
arch/arm/mach-omap2/gpmc.c +36 -0
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 27, 27, "sync-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 28, 28, "burst-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 29, 29, "gpmc,sync-read");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 30, 30, "burst-read");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 31, 31, "burst-wrap");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG2,  7,  7, "cs-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG3,  7,  7, "adv-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4, 23, 23, "we-extra-delay");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4,  7,  7, "oe-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6,  7,  7, "cycle2cycle-samecsen");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6,  6,  6, "cycle2cycle-diffcsen");
+
+	pr_info("gpmc cs%i timings configuration:\n", cs);
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2,  0,  3, "cs-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2,  8, 12, "cs-rd-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2, 16, 20, "cs-wr-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3,  0,  3, "adv-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3,  8, 12, "adv-rd-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3, 16, 20, "adv-wr-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4,  0,  3, "oe-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4,  8, 12, "oe-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4, 16, 19, "we-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4, 24, 28, "we-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5,  0,  4, "rd-cycle-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5,  8, 12, "wr-cycle-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5, 16, 20, "access-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5, 24, 27, "page-burst-access-ns");
+

arch/arm/mach-omap2/gpmc.c static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) · line 410

Quoted 10 lines
arch/arm/mach-omap2/gpmc.c +10 -0
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 0, 3, "bus-turnaround-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 8, 11, "cycle2cycle-delay-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG1, 18, 19, "wait-monitoring-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG1, 25, 26, "clk-activation-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 16, 19, "wr-data-mux-bus-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 24, 28, "wr-access-ns");
+}
+

Shouldn't all the above functions except gpmc_show_regs() be defined within #ifdef DEBUG?

Quoted 56 lines
arch/arm/mach-omap2/gpmc.c +20 -3
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 			       int time, const char *name)
@@ -361,6 +478,9 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	int div;
 	u32 l;
 
+#ifdef DEBUG
+	gpmc_cs_show_timings(cs, "before gpmc_cs_set_timings");
+#endif
 	div = gpmc_calc_divider(t->sync_clk);
 	if (div < 0)
 		return div;
@@ -410,7 +530,9 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	}
 
 	gpmc_cs_bool_timings(cs, &t->bool_timings);
-
+#ifdef DEBUG
+	gpmc_cs_show_timings(cs, "after gpmc_cs_set_timings");
+#endif
 	return 0;
 }
 
@@ -1571,6 +1693,20 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	}
 	gpmc_cs_set_name(cs, child->name);
 
+	gpmc_read_settings_dt(child, &gpmc_s);
+	gpmc_read_timings_dt(child, &gpmc_t);
+
+	/*
+	 * For some GPMC devices we still need to rely on the bootloader
+	 * timings because the devices can be connected via FPGA.
+	 * REVISIT: Add timing support from slls644g.pdf.
+	 */
+	if (!gpmc_t.cs_rd_off) {
+		gpmc_cs_show_timings(cs,
+				     "please add GPMC bootloader timings to .dts");
+		goto no_timings;
+	}
+
 	/*
 	 * For some GPMC devices we still need to rely on the bootloader
 	 * timings because the devices can be connected via FPGA. So far
@@ -1602,8 +1738,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		goto err;
 	}
 
-	gpmc_read_settings_dt(child, &gpmc_s);
-
 	ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
 	if (ret < 0)
 		goto err;

arch/arm/mach-omap2/gpmc.c static int gpmc_probe_generic_child(struct platform_device *pdev, · line 1751

Quoted 7 lines
arch/arm/mach-omap2/gpmc.c +0 -1
@@ -1612,7 +1746,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	if (ret < 0)
 		goto err;
 
-	gpmc_read_timings_dt(child, &gpmc_t);
 	gpmc_cs_set_timings(cs, &gpmc_t);
 
 no_timings:

cheers,
-roger

author maintainer
#14 lore raw

PATCH 6/10 ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

Quoted 11 lines · Roger Quadros
Quoted 10 lines · Tony Lindgren
arch/arm/mach-omap2/gpmc.c +10 -0
+static void gpmc_cs_show_timings(int cs, const char *desc)
+{
+	gpmc_show_regs(cs, desc);
+
+	pr_info("gpmc cs%i access configuration:\n", cs);
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
Quoted 8 lines

arch/arm/mach-omap2/gpmc.c static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) · line 364

Quoted 2 lines
arch/arm/mach-omap2/gpmc.c +2 -0
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
+	GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 3, "burst-length");

how does this work with shift = 3?
Possible values of burst length are
0 -> 4
1 -> 8
2 -> 16

Hmm sounds like a bug..

In general, if you a chance to test this patch with a few devices that would be great. Assuming you have working timings in the bootloader, just remove the gpmc,* entries temporarily from the .dts file for a device, and see if the values printed by this patch make sense. I've used this to generate the values for the 2430sdp smc91x and zoom 8250 but I don't think I've tried anything with a burst mode so far.

Quoted 1 line

Shouldn't all the above functions except gpmc_show_regs() be defined within #ifdef DEBUG?

Yes let's do that to avoid bloat. Let's do a warning if no timings are specified so people know to enable DEBUG.

BTW, I'm hoping we can start using gpmc_probe_generic_child() for all the devices and get rid of gpmc_probe_nand_child() and gpmc_probe_onenand_child(). We can now use gpmc_cs_get_name() to call helpers from gpmc_probe_generic_child() for NAND and OneNAND if really needed.

Regards,

Tony

#15 lore raw

PATCH 6/10 ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

Quoted 23 lines · Tony Lindgren
Quoted 11 lines · Roger Quadros
Quoted 10 lines · Tony Lindgren
arch/arm/mach-omap2/gpmc.c +10 -0
+static void gpmc_cs_show_timings(int cs, const char *desc)
+{
+	gpmc_show_regs(cs, desc);
+
+	pr_info("gpmc cs%i access configuration:\n", cs);
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
Quoted 8 lines

arch/arm/mach-omap2/gpmc.c static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) · line 364

Quoted 2 lines
arch/arm/mach-omap2/gpmc.c +2 -0
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
+	GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 3, "burst-length");

how does this work with shift = 3?
Possible values of burst length are
0 -> 4
1 -> 8
2 -> 16

Hmm sounds like a bug..

Quoted 7 lines

In general, if you a chance to test this patch with a few devices that would be great. Assuming you have working timings in the bootloader, just remove the gpmc,* entries temporarily from the .dts file for a device, and see if the values printed by this patch make sense. I've used this to generate the values for the 2430sdp smc91x and zoom 8250 but I don't think I've tried anything with a burst mode so far.

OK. I'll give it a spin with u-boot configured devices.

Quoted 11 lines
Quoted 2 lines

Shouldn't all the above functions except gpmc_show_regs() be defined within #ifdef DEBUG?

Yes let's do that to avoid bloat. Let's do a warning if no timings are specified so people know to enable DEBUG.

BTW, I'm hoping we can start using gpmc_probe_generic_child() for all the devices and get rid of gpmc_probe_nand_child() and gpmc_probe_onenand_child(). We can now use gpmc_cs_get_name() to call helpers from gpmc_probe_generic_child() for NAND and OneNAND if really needed.

I agree. I almost had this done in one of my RFC patches. Need to spend some more time to resurrect them. ;)

cheers,
-roger

author maintainer
#16 lore raw

PATCH 6/10 ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

Quoted 22 lines · Roger Quadros
Quoted 21 lines · Tony Lindgren
Quoted 19 lines · Roger Quadros

Review

Quoted 12 lines · Tony Lindgren
(quoted diff) +12 -0
+static void gpmc_cs_show_timings(int cs, const char *desc)
+{
+	gpmc_show_regs(cs, desc);
+
+	pr_info("gpmc cs%i access configuration:\n", cs);
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
+	GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 3, "burst-length");

how does this work with shift = 3?
Possible values of burst length are
0 -> 4
1 -> 8
2 -> 16

Quoted 1 line
Quoted 1 line

Hmm sounds like a bug..

The shift does not work here for 0 << 3 naturally :) I've changed it to l = (shift << l) where shift is 4 in this case.

Quoted 9 lines
Quoted 7 lines

In general, if you a chance to test this patch with a few devices that would be great. Assuming you have working timings in the bootloader, just remove the gpmc,* entries temporarily from the .dts file for a device, and see if the values printed by this patch make sense. I've used this to generate the values for the 2430sdp smc91x and zoom 8250 but I don't think I've tried anything with a burst mode so far.

OK. I'll give it a spin with u-boot configured devices.

Great thanks. Updated patch below.

Regards,

Tony

8< ----------------
From: Tony Lindgren <[email protected]>
Date: Wed, 29 Oct 2014 17:16:48 -0700
Subject: [PATCH] ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

As we still have some devices with GPMC timings missing from the .dts files, let's make it a bit easier to use the bootloader values and print them out.

Note that we now need to move the parsing of the device tree provided configuration a bit earlier so we can use that for checking if anything was configured.

arch/arm/mach-omap2/gpmc.c +141 -3
@@ -292,6 +292,129 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
 }
 
 #ifdef DEBUG
+static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+			       bool raw, bool noval, int shift,
+			       const char *name)
+{
+	u32 l;
+	int nr_bits, max_value, mask;
+
+	l = gpmc_cs_read_reg(cs, reg);
+	nr_bits = end_bit - st_bit + 1;
+	max_value = (1 << nr_bits) - 1;
+	mask = max_value << st_bit;
+	l = (l & mask) >> st_bit;
+	if (shift)
+		l = (shift << l);
+	if (noval && (l == 0))
+		return 0;
+	if (!raw) {
+		unsigned int time_ns_min, time_ns, time_ns_max;
+
+		time_ns_min = gpmc_ticks_to_ns(l ? l - 1 : 0);
+		time_ns = gpmc_ticks_to_ns(l);
+		time_ns_max = gpmc_ticks_to_ns(l + 1 > max_value ?
+					       max_value : l + 1);
+		pr_info("gpmc,%s = <%u> (%u - %u ns, %i ticks)\n",
+			name, time_ns, time_ns_min, time_ns_max, l);
+	} else {
+		pr_info("gpmc,%s = <%u>\n", name, l);
+	}
+
+	return l;
+}
+
+#define GPMC_PRINT_CONFIG(cs, config) \
+	pr_info("cs%i %s: 0x%08x\n", cs, #config, \
+		gpmc_cs_read_reg(cs, config))
+#define GPMC_GET_RAW(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 0, 0, field)
+#define GPMC_GET_RAW_BOOL(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, 0, field)
+#define GPMC_GET_RAW_SHIFT(reg, st, end, shift, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, (shift), field)
+#define GPMC_GET_TICKS(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 0, 0, 0, field)
+
+static void gpmc_show_regs(int cs, const char *desc)
+{
+	pr_info("gpmc cs%i %s:\n", cs, desc);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG1);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG2);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG3);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG4);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG5);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG6);
+}
+
+/*
+ * Note that gpmc,wait-pin handing wrongly assumes bit 8 is available,
+ * see commit c9fb809.
+ */
+static void gpmc_cs_show_timings(int cs, const char *desc)
+{
+	gpmc_show_regs(cs, desc);
+
+	pr_info("gpmc cs%i access configuration:\n", cs);
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
+	GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 4, "burst-length");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 27, 27, "sync-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 28, 28, "burst-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 29, 29, "gpmc,sync-read");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 30, 30, "burst-read");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 31, 31, "burst-wrap");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG2,  7,  7, "cs-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG3,  7,  7, "adv-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4, 23, 23, "we-extra-delay");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4,  7,  7, "oe-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6,  7,  7, "cycle2cycle-samecsen");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6,  6,  6, "cycle2cycle-diffcsen");
+
+	pr_info("gpmc cs%i timings configuration:\n", cs);
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2,  0,  3, "cs-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2,  8, 12, "cs-rd-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2, 16, 20, "cs-wr-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3,  0,  3, "adv-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3,  8, 12, "adv-rd-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3, 16, 20, "adv-wr-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4,  0,  3, "oe-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4,  8, 12, "oe-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4, 16, 19, "we-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4, 24, 28, "we-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5,  0,  4, "rd-cycle-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5,  8, 12, "wr-cycle-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5, 16, 20, "access-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5, 24, 27, "page-burst-access-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 0, 3, "bus-turnaround-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 8, 11, "cycle2cycle-delay-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG1, 18, 19, "wait-monitoring-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG1, 25, 26, "clk-activation-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 16, 19, "wr-data-mux-bus-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 24, 28, "wr-access-ns");
+}
+#else
+static inline void gpmc_cs_show_timings(int cs, const char *desc)
+{
+}
+#endif
+
+#ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 			       int time, const char *name)
 #else
@@ -361,6 +484,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	int div;
 	u32 l;
 
+	gpmc_cs_show_timings(cs, "before gpmc_cs_set_timings");
 	div = gpmc_calc_divider(t->sync_clk);
 	if (div < 0)
 		return div;
@@ -410,6 +534,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	}
 
 	gpmc_cs_bool_timings(cs, &t->bool_timings);
+	gpmc_cs_show_timings(cs, "after gpmc_cs_set_timings");
 
 	return 0;
 }
@@ -1571,6 +1696,22 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	}
 	gpmc_cs_set_name(cs, child->name);
 
+	gpmc_read_settings_dt(child, &gpmc_s);
+	gpmc_read_timings_dt(child, &gpmc_t);
+
+	/*
+	 * For some GPMC devices we still need to rely on the bootloader
+	 * timings because the devices can be connected via FPGA.
+	 * REVISIT: Add timing support from slls644g.pdf.
+	 */
+	if (!gpmc_t.cs_rd_off) {
+		WARN(1, "enable GPMC debug to configure .dts timings for CS%i\n",
+			cs);
+		gpmc_cs_show_timings(cs,
+				     "please add GPMC bootloader timings to .dts");
+		goto no_timings;
+	}
+
 	/*
 	 * For some GPMC devices we still need to rely on the bootloader
 	 * timings because the devices can be connected via FPGA. So far
@@ -1602,8 +1743,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		goto err;
 	}
 
-	gpmc_read_settings_dt(child, &gpmc_s);
-
 	ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
 	if (ret < 0)
 		goto err;
@@ -1612,7 +1751,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	if (ret < 0)
 		goto err;
 
-	gpmc_read_timings_dt(child, &gpmc_t);
 	gpmc_cs_set_timings(cs, &gpmc_t);
 
 no_timings:
#17 lore raw

PATCH 6/10 ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

Quoted 54 lines · Tony Lindgren
Quoted 22 lines · Roger Quadros
Quoted 21 lines · Tony Lindgren
Quoted 19 lines · Roger Quadros

arch/arm/mach-omap2/gpmc.c static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)

Quoted 12 lines · Tony Lindgren
arch/arm/mach-omap2/gpmc.c +12 -0
+static void gpmc_cs_show_timings(int cs, const char *desc)
+{
+	gpmc_show_regs(cs, desc);
+
+	pr_info("gpmc cs%i access configuration:\n", cs);
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
+	GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 3, "burst-length");

how does this work with shift = 3?
Possible values of burst length are
0 -> 4
1 -> 8
2 -> 16

Quoted 1 line
Quoted 1 line

Hmm sounds like a bug..

The shift does not work here for 0 << 3 naturally :) I've changed it to l = (shift << l) where shift is 4 in this case.

Quoted 9 lines
Quoted 7 lines

In general, if you a chance to test this patch with a few devices that would be great. Assuming you have working timings in the bootloader, just remove the gpmc,* entries temporarily from the .dts file for a device, and see if the values printed by this patch make sense. I've used this to generate the values for the 2430sdp smc91x and zoom 8250 but I don't think I've tried anything with a burst mode so far.

OK. I'll give it a spin with u-boot configured devices.

Great thanks. Updated patch below.

Regards,

Tony

8< ----------------
From: Tony Lindgren <[email protected]>
Date: Wed, 29 Oct 2014 17:16:48 -0700
Subject: [PATCH] ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

As we still have some devices with GPMC timings missing from the .dts files, let's make it a bit easier to use the bootloader values and print them out.

Quoted 6 lines

Note that we now need to move the parsing of the device tree provided configuration a bit earlier so we can use that for checking if anything was configured.

I won't be able to test this series this week, but will get back by the next.

cheers,
-roger

#18 lore raw

PATCH 6/10 ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

In reply to Tony Lindgren
Quoted 54 lines · Tony Lindgren
Quoted 22 lines · Roger Quadros
Quoted 21 lines · Tony Lindgren
Quoted 19 lines · Roger Quadros

arch/arm/mach-omap2/gpmc.c static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)

Quoted 12 lines · Tony Lindgren
arch/arm/mach-omap2/gpmc.c +12 -0
+static void gpmc_cs_show_timings(int cs, const char *desc)
+{
+	gpmc_show_regs(cs, desc);
+
+	pr_info("gpmc cs%i access configuration:\n", cs);
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
+	GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 3, "burst-length");

how does this work with shift = 3?
Possible values of burst length are
0 -> 4
1 -> 8
2 -> 16

Quoted 1 line
Quoted 1 line

Hmm sounds like a bug..

The shift does not work here for 0 << 3 naturally :) I've changed it to l = (shift << l) where shift is 4 in this case.

Quoted 9 lines
Quoted 7 lines

In general, if you a chance to test this patch with a few devices that would be great. Assuming you have working timings in the bootloader, just remove the gpmc,* entries temporarily from the .dts file for a device, and see if the values printed by this patch make sense. I've used this to generate the values for the 2430sdp smc91x and zoom 8250 but I don't think I've tried anything with a burst mode so far.

OK. I'll give it a spin with u-boot configured devices.

Great thanks. Updated patch below.

Regards,

Tony

8< ----------------
From: Tony Lindgren <[email protected]>
Date: Wed, 29 Oct 2014 17:16:48 -0700
Subject: [PATCH] ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

As we still have some devices with GPMC timings missing from the .dts files, let's make it a bit easier to use the bootloader values and print them out.

Quoted 7 lines

Note that we now need to move the parsing of the device tree provided configuration a bit earlier so we can use that for checking if anything was configured.

I don't have any board with smsc or working NOR so I called gpmc_cs_show_timings() after NAND was setup.

The printed values match closely to the configured values in the DTS.

cheers,
-roger

author maintainer
#19 lore raw

PATCH 6/10 ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

Quoted 5 lines · Roger Quadros

I don't have any board with smsc or working NOR so I called gpmc_cs_show_timings() after NAND was setup.

The printed values match closely to the configured values in the DTS.

OK thanks for checking. I've checked with smsc91x, smsc911x and 8250 so far so I think we're good to go.

Regards,

Tony

#20 lore raw

PATCH 6/10 ARM: OMAP2+: Show bootloader GPMC timings to allow configuring the .dts file

In reply to Tony Lindgren

Sorry if you get this twice. I wasn't sure if my last reply went through.

Quoted 83 lines · Tony Lindgren

As we still have some devices with GPMC timings missing from the .dts files, let's make it a bit easier to use the bootloader values and print them out.

Note that we now need to move the parsing of the device tree provided configuration a bit earlier so we can use that for checking if anything was configured.

---
 arch/arm/mach-omap2/gpmc.c | 141 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 137 insertions(+), 4 deletions(-)
arch/arm/mach-omap2/gpmc.c +61 -0
index 2c5f348..0999923 100644
@@ -291,6 +291,123 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
 			   p->cycle2cyclediffcsen);
 }
 
+static int get_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+			       bool raw, bool noval, int shift,
+			       const char *name)
+{
+	u32 l;
+	int nr_bits, max_value, mask;
+
+	l = gpmc_cs_read_reg(cs, reg);
+	nr_bits = end_bit - st_bit + 1;
+	max_value = (1 << nr_bits) - 1;
+	mask = max_value << st_bit;
+	l = (l & mask) >> st_bit;
+	if (shift)
+		l <<= shift;
+	if (noval && (l == 0))
+		return 0;
+	if (!raw) {
+		unsigned int time_ns_min, time_ns, time_ns_max;
+
+		time_ns_min = gpmc_ticks_to_ns(l ? l - 1 : 0);
+		time_ns = gpmc_ticks_to_ns(l);
+		time_ns_max = gpmc_ticks_to_ns(l + 1 > max_value ?
+					       max_value : l + 1);
+		pr_info("gpmc,%s = <%u> (%u - %u ns, %i ticks)\n",
+			name, time_ns, time_ns_min, time_ns_max, l);
+	} else {
+		pr_info("gpmc,%s = <%u>\n", name, l);
+	}
+
+	return l;
+}
+
+#define GPMC_PRINT_CONFIG(cs, config) \
+	pr_info("cs%i %s: 0x%08x\n", cs, #config, \
+		gpmc_cs_read_reg(cs, config))
+#define GPMC_GET_RAW(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 0, 0, field)
+#define GPMC_GET_RAW_BOOL(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, 0, field)
+#define GPMC_GET_RAW_SHIFT(reg, st, end, shift, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 1, 1, (shift), field)
+#define GPMC_GET_TICKS(reg, st, end, field) \
+	get_gpmc_timing_reg(cs, (reg), (st), (end), 0, 0, 0, field)
+
+static void gpmc_show_regs(int cs, const char *desc)
+{
+	pr_info("gpmc cs%i %s:\n", cs, desc);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG1);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG2);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG3);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG4);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG5);
+	GPMC_PRINT_CONFIG(cs, GPMC_CS_CONFIG6);
+}
+
+/*
+ * Note that gpmc,wait-pin handing wrongly assumes bit 8 is available,
+ * see commit c9fb809.
+ */
+static void gpmc_cs_show_timings(int cs, const char *desc)
+{

arch/arm/mach-omap2/gpmc.c static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) · line 364

Quoted 10 lines
arch/arm/mach-omap2/gpmc.c +10 -0
+	gpmc_show_regs(cs, desc);
+
+	pr_info("gpmc cs%i access configuration:\n", cs);
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 12, 13, "device-width");
+	GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 22, 22, "wait-on-read");
+	GPMC_GET_RAW_SHIFT(GPMC_CS_CONFIG1, 23, 24, 3, "burst-length");

how does this work with shift = 3?
Possible values of burst length are
0 -> 4
1 -> 8
2 -> 16

Quoted 36 lines
arch/arm/mach-omap2/gpmc.c +36 -0
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 27, 27, "sync-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 28, 28, "burst-write");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 29, 29, "gpmc,sync-read");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 30, 30, "burst-read");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 31, 31, "burst-wrap");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG2,  7,  7, "cs-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG3,  7,  7, "adv-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4, 23, 23, "we-extra-delay");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG4,  7,  7, "oe-extra-delay");
+
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6,  7,  7, "cycle2cycle-samecsen");
+	GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG6,  6,  6, "cycle2cycle-diffcsen");
+
+	pr_info("gpmc cs%i timings configuration:\n", cs);
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2,  0,  3, "cs-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2,  8, 12, "cs-rd-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG2, 16, 20, "cs-wr-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3,  0,  3, "adv-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3,  8, 12, "adv-rd-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG3, 16, 20, "adv-wr-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4,  0,  3, "oe-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4,  8, 12, "oe-off-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4, 16, 19, "we-on-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG4, 24, 28, "we-off-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5,  0,  4, "rd-cycle-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5,  8, 12, "wr-cycle-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5, 16, 20, "access-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG5, 24, 27, "page-burst-access-ns");
+

arch/arm/mach-omap2/gpmc.c static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) · line 410

Quoted 10 lines
arch/arm/mach-omap2/gpmc.c +10 -0
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 0, 3, "bus-turnaround-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 8, 11, "cycle2cycle-delay-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG1, 18, 19, "wait-monitoring-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG1, 25, 26, "clk-activation-ns");
+
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 16, 19, "wr-data-mux-bus-ns");
+	GPMC_GET_TICKS(GPMC_CS_CONFIG6, 24, 28, "wr-access-ns");
+}
+

Shouldn't all the above functions except gpmc_show_regs() be defined within #ifdef DEBUG?

Quoted 56 lines
arch/arm/mach-omap2/gpmc.c +20 -3
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 			       int time, const char *name)
@@ -361,6 +478,9 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	int div;
 	u32 l;
 
+#ifdef DEBUG
+	gpmc_cs_show_timings(cs, "before gpmc_cs_set_timings");
+#endif
 	div = gpmc_calc_divider(t->sync_clk);
 	if (div < 0)
 		return div;
@@ -410,7 +530,9 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	}
 
 	gpmc_cs_bool_timings(cs, &t->bool_timings);
-
+#ifdef DEBUG
+	gpmc_cs_show_timings(cs, "after gpmc_cs_set_timings");
+#endif
 	return 0;
 }
 
@@ -1571,6 +1693,20 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	}
 	gpmc_cs_set_name(cs, child->name);
 
+	gpmc_read_settings_dt(child, &gpmc_s);
+	gpmc_read_timings_dt(child, &gpmc_t);
+
+	/*
+	 * For some GPMC devices we still need to rely on the bootloader
+	 * timings because the devices can be connected via FPGA.
+	 * REVISIT: Add timing support from slls644g.pdf.
+	 */
+	if (!gpmc_t.cs_rd_off) {
+		gpmc_cs_show_timings(cs,
+				     "please add GPMC bootloader timings to .dts");
+		goto no_timings;
+	}
+
 	/*
 	 * For some GPMC devices we still need to rely on the bootloader
 	 * timings because the devices can be connected via FPGA. So far
@@ -1602,8 +1738,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		goto err;
 	}
 
-	gpmc_read_settings_dt(child, &gpmc_s);
-
 	ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
 	if (ret < 0)
 		goto err;

arch/arm/mach-omap2/gpmc.c static int gpmc_probe_generic_child(struct platform_device *pdev, · line 1751

Quoted 7 lines
arch/arm/mach-omap2/gpmc.c +0 -1
@@ -1612,7 +1746,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	if (ret < 0)
 		goto err;
 
-	gpmc_read_timings_dt(child, &gpmc_t);
 	gpmc_cs_set_timings(cs, &gpmc_t);
 
 no_timings:

cheers,
-roger

author maintainer
#21 lore raw

PATCH 7/10 ARM: OMAP2+: Require proper GPMC timings for devices

In reply to Tony Lindgren

Now that we have timings in the .dts files for smc91x and 8250, we can remove the device specific checks and just print out the bootloader timings for devices that may not have timings in the .dts files.

---
 arch/arm/mach-omap2/gpmc.c | 16 ----------------
 1 file changed, 16 deletions(-)
arch/arm/mach-omap2/gpmc.c +0 -16
index 0999923..0e74d1d 100644
@@ -1708,22 +1708,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	}
 
 	/*
-	 * For some GPMC devices we still need to rely on the bootloader
-	 * timings because the devices can be connected via FPGA. So far
-	 * the list is smc91x on the omap2 SDP boards, and 8250 on zooms.
-	 * REVISIT: Add timing support from slls644g.pdf and from the
-	 * lan91c96 manual.
-	 */
-	if (of_device_is_compatible(child, "ns16550a") ||
-	    of_device_is_compatible(child, "smsc,lan91c94") ||
-	    of_device_is_compatible(child, "smsc,lan91c111")) {
-		dev_warn(&pdev->dev,
-			 "%s using bootloader timings on CS%d\n",
-			 child->name, cs);
-		goto no_timings;
-	}
-
-	/*
 	 * FIXME: gpmc_cs_request() will map the CS to an arbitary
 	 * location in the gpmc address space. When booting with
 	 * device-tree we want the NOR flash to be mapped to the
Signature · 1 line
2.1.1
author maintainer
#23 lore raw

PATCH 8/10 ARM: OMAP2+: Drop legacy code for gpmc-smc91x.c

In reply to Tony Lindgren

This code was only used by 2430sdp, 3430sdp, and n900 development boards.

The 2430sdp is already device tree only, and all the users of the 3430sdp and n900 development boards are already booting in device tree mode, so we can drop the legacy smc91x support.

---
 arch/arm/mach-omap2/Makefile                 |   3 -
 arch/arm/mach-omap2/board-3430sdp.c          |  28 ----
 arch/arm/mach-omap2/board-rx51-peripherals.c |  29 -----
 arch/arm/mach-omap2/gpmc-smc91x.c            | 186 ---------------------------
 arch/arm/mach-omap2/gpmc-smc91x.h            |  42 ------
 5 files changed, 288 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/gpmc-smc91x.c
 delete mode 100644 arch/arm/mach-omap2/gpmc-smc91x.h
arch/arm/mach-omap2/Makefile +0 -3
index d9e9412..3e824f8 100644
@@ -284,9 +284,6 @@ obj-y					+= $(onenand-m) $(onenand-y)
 nand-$(CONFIG_MTD_NAND_OMAP2)		:= gpmc-nand.o
 obj-y					+= $(nand-m) $(nand-y)
 
-smc91x-$(CONFIG_SMC91X)			:= gpmc-smc91x.o
-obj-y					+= $(smc91x-m) $(smc91x-y)
-
 smsc911x-$(CONFIG_SMSC911X)		:= gpmc-smsc911x.o
 obj-y					+= $(smsc911x-m) $(smsc911x-y)
 ifneq ($(CONFIG_HWSPINLOCK_OMAP),)
arch/arm/mach-omap2/board-3430sdp.c +0 -28
index d21a304..9857882 100644
@@ -38,7 +38,6 @@
 #include <video/omap-panel-data.h>
 
 #include "gpmc.h"
-#include "gpmc-smc91x.h"
 
 #include "soc.h"
 #include "board-flash.h"
@@ -407,32 +406,6 @@ static int __init omap3430_i2c_init(void)
 	return 0;
 }
 
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
-
-static struct omap_smc91x_platform_data board_smc91x_data = {
-	.cs		= 3,
-	.flags		= GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
-				IORESOURCE_IRQ_LOWLEVEL,
-};
-
-static void __init board_smc91x_init(void)
-{
-	if (omap_rev() > OMAP3430_REV_ES1_0)
-		board_smc91x_data.gpio_irq = 6;
-	else
-		board_smc91x_data.gpio_irq = 29;
-
-	gpmc_smc91x_init(&board_smc91x_data);
-}
-
-#else
-
-static inline void board_smc91x_init(void)
-{
-}
-
-#endif
-
 static void enable_board_wakeup_source(void)
 {
 	/* T2 interrupt line (keypad) */
@@ -609,7 +582,6 @@ static void __init omap_3430sdp_init(void)
 	omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL);
 	usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
 	usb_musb_init(NULL);
-	board_smc91x_init();
 	board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
 	sdp3430_display_init();
 	enable_board_wakeup_source();
arch/arm/mach-omap2/board-rx51-peripherals.c +0 -29
index ddfc8df..30e7d4c 100644
@@ -32,7 +32,6 @@
 
 #include "common.h"
 #include <linux/omap-dma.h>
-#include "gpmc-smc91x.h"
 
 #include "board-rx51.h"
 
@@ -1146,33 +1145,6 @@ static struct omap_onenand_platform_data board_onenand_data[] = {
 };
 #endif
 
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
-
-static struct omap_smc91x_platform_data board_smc91x_data = {
-	.cs		= 1,
-	.gpio_irq	= 54,
-	.gpio_pwrdwn	= 86,
-	.gpio_reset	= 164,
-	.flags		= GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHLEVEL,
-};
-
-static void __init board_smc91x_init(void)
-{
-	omap_mux_init_gpio(54, OMAP_PIN_INPUT_PULLDOWN);
-	omap_mux_init_gpio(86, OMAP_PIN_OUTPUT);
-	omap_mux_init_gpio(164, OMAP_PIN_OUTPUT);
-
-	gpmc_smc91x_init(&board_smc91x_data);
-}
-
-#else
-
-static inline void board_smc91x_init(void)
-{
-}
-
-#endif
-
 static struct gpio rx51_wl1251_gpios[] __initdata = {
 	{ RX51_WL1251_IRQ_GPIO,	  GPIOF_IN,		"wl1251 irq"	},
 };
@@ -1303,7 +1275,6 @@ void __init rx51_peripherals_init(void)
 	rx51_i2c_init();
 	regulator_has_full_constraints();
 	gpmc_onenand_init(board_onenand_data);
-	board_smc91x_init();
 	rx51_add_gpio_keys();
 	rx51_init_wl1251();
 	rx51_init_tsc2005();
arch/arm/mach-omap2/gpmc-smc91x.c deleted +0 -186

186 lines not on this page · raw message

arch/arm/mach-omap2/gpmc-smc91x.h deleted +0 -42

42 lines not on this page · raw message

Signature · 1 line
2.1.1
#24 lore raw

PATCH 8/10 ARM: OMAP2+: Drop legacy code for gpmc-smc91x.c

Quoted 9 lines · Tony Lindgren

This code was only used by 2430sdp, 3430sdp, and n900 development boards.

The 2430sdp is already device tree only, and all the users of the 3430sdp and n900 development boards are already booting in device tree mode, so we can drop the legacy smc91x support.

cheers,
-roger

author maintainer
#25 lore raw

PATCH 9/10 ARM: OMAP2+: Drop board file for ti8168evm

In reply to Tony Lindgren

The 81xx support is known to be broken for quite some time now because of missing patches. And it should be using device tree based booting now anyways.

So let's just drop the board file for it.

---
 arch/arm/mach-omap2/Kconfig           | 10 ------
 arch/arm/mach-omap2/Makefile          |  2 --
 arch/arm/mach-omap2/board-ti8168evm.c | 62 -----------------------------------
 3 files changed, 74 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/board-ti8168evm.c
arch/arm/mach-omap2/Kconfig +0 -10
index f4d06ae..7adc4f7 100644
@@ -282,16 +282,6 @@ config MACH_SBC3530
 	default y
 	select OMAP_PACKAGE_CUS
 
-config MACH_TI8168EVM
-	bool "TI8168 Evaluation Module"
-	depends on SOC_TI81XX
-	default y
-
-config MACH_TI8148EVM
-	bool "TI8148 Evaluation Module"
-	depends on SOC_TI81XX
-	default y
-
 config OMAP3_EMU
 	bool "OMAP3 debugging peripherals"
 	depends on ARCH_OMAP3
arch/arm/mach-omap2/Makefile +0 -2
index 3e824f8..3a54671 100644
@@ -260,8 +260,6 @@ obj-$(CONFIG_MACH_OMAP3517EVM)		+= board-am3517evm.o
 obj-$(CONFIG_MACH_CRANEBOARD)		+= board-am3517crane.o
 
 obj-$(CONFIG_MACH_SBC3530)		+= board-omap3stalker.o
-obj-$(CONFIG_MACH_TI8168EVM)		+= board-ti8168evm.o
-obj-$(CONFIG_MACH_TI8148EVM)		+= board-ti8168evm.o
 
 # Platform specific device init code
 
arch/arm/mach-omap2/board-ti8168evm.c deleted +0 -62

62 lines not on this page · raw message

Signature · 1 line
2.1.1
author maintainer
#26 lore raw

PATCH 10/10 ARM: omap2plus: Drop board file for 3430sdp

In reply to Tony Lindgren

This board seems to be in use only for few automated boot test system and has been booting in device tree only mode for quite some time now.

So let's drop the board file for it.

---
 arch/arm/mach-omap2/Kconfig         |   6 -
 arch/arm/mach-omap2/Makefile        |   1 -
 arch/arm/mach-omap2/board-3430sdp.c | 604 ------------------------------------
 3 files changed, 611 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/Kconfig +0 -6
index 7adc4f7..27ec892 100644
@@ -235,12 +235,6 @@ config MACH_TOUCHBOOK
 	default y
 	select OMAP_PACKAGE_CBB
 
-config MACH_OMAP_3430SDP
-	bool "OMAP 3430 SDP board"
-	depends on ARCH_OMAP3
-	default y
-	select OMAP_PACKAGE_CBB
-
 config MACH_NOKIA_N810
        bool
 
arch/arm/mach-omap2/Makefile +0 -1
index 3a54671..00b35a3 100644
@@ -246,7 +246,6 @@ obj-$(CONFIG_MACH_OMAP3530_LV_SOM)      += board-omap3logic.o
 obj-$(CONFIG_MACH_OMAP3_TORPEDO)        += board-omap3logic.o
 obj-$(CONFIG_MACH_OVERO)		+= board-overo.o
 obj-$(CONFIG_MACH_OMAP3_PANDORA)	+= board-omap3pandora.o
-obj-$(CONFIG_MACH_OMAP_3430SDP)		+= board-3430sdp.o
 obj-$(CONFIG_MACH_NOKIA_N8X0)		+= board-n8x0.o
 obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o sdram-nokia.o
 obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51-peripherals.o
arch/arm/mach-omap2/board-3430sdp.c deleted +0 -604

604 lines not on this page · raw message

Signature · 1 line
2.1.1