linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update
@ 2013-03-15 15:20 Jon Hunter
  2013-03-15 15:20 ` [PATCH V3 01/18] ARM: OMAP2+: Simplify code configuring ONENAND devices Jon Hunter
                   ` (18 more replies)
  0 siblings, 19 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:20 UTC (permalink / raw)
  To: linux-arm-kernel

While adding device-tree support for NOR memories, it became apparent
that there is no common way for configuring various GPMC settings for
devices that interface to the GPMC. These settings include bus-width,
synchronous/asynchronous mode, burst settings, wait monitoring etc.
Therefore, to simplify the GPMC code and add device-tree support for
NOR, it was first necessary to consolidate how these settings are
programmed.

Series based upon Mark Jackson's patch [1] and Ezequiel Garcia GPMC
clean-up series [2]. Entire series available here [3].

V3 changes:
- Rebased on RMK's IS_ERR_VALUE() patch and removed usage of
  IS_ERR_VALUE() from series.
- Fixed BUG in NAND code introduced in V2 by making gpmc_settings
  structure a local variable (I forgot to initialise structure to zero).
- Added fix from Javier to correct return value from gpmc_probe_nor().

V2 changes:
- Made gpmc_settings structure local in gpmc_nand_init().
- Use resource_size() API in probe_nor().
- Add kernel-doc for gpmc_cs_program_settings() function.
- Use of_platform_device_create() to register NOR devices in probe_nor().
- Add support for GPMC address-address-data multiplexing which required
  changing GPMC DT property "gpmc,mux-add-data" to store a 32-bit value
  and changing mux_add_data member of gpmc_settings to be a 32-bit type
  instead of bool.
- Add detection for incorrect GPMC chip-select base addresses.
- Cleaned-up code in gpmc_mem_init() and changed gpmc_mem_init() so that
  it would not return an error when the GPMC driver is being probed.

V1 changes:
- Clean-up/simplification of ONENAND initialisation code.
- Add a new GPMC structure to unify storage of various GPMC settings
  (that are non-timing related) for client devices and add a new
  function to program these settings in a common way.
- Migrate initialisation code for existing flash, usb and networking
  devices to use the new structure and function for GPMC settings.
- Add device-tree support for NOR flash memories.
- Add additional GPMC timing parameters to GPMC device-tree binding.
- Update GPMC NAND and ONENAND device-tree support to retrieve GPMC
  settings from device-tree.

Testing includes:
- Boot testing on OMAP2420 H4, OMAP3430 SDP and OMAP4430 SDP with
  and without device-tree present.
- OMAP2420 H4 board has NOR flash and OMAP3430 SDP has NOR, NAND
  and ONENAND flash. So verified that flash is detected on boot
  as expected. Note additional patches [4] are required for OMAP2420
  H4 and OMAP3430 SDP dts files in order to enable flash memory
  support.
- All of the above boards use GPMC for interfacing to a networking
  chip and so verified that networking is working wit this series.
  However, please note that networking is not currently supported
  on these boards when booting with DT and so networking is only
  tested without DT.

[1] http://permalink.gmane.org/gmane.linux.ports.arm.omap/94765
[2] http://comments.gmane.org/gmane.linux.ports.arm.omap/93784
[3] https://github.com/jonhunter/linux/tree/omap-gpmc-for-v3.10
[4] https://github.com/jonhunter/linux/tree/omap-dt-for-v3.10

Javier Martinez Canillas (1):
  ARM: OMAP2+: return -ENODEV if GPMC child device creation fails

Jon Hunter (17):
  ARM: OMAP2+: Simplify code configuring ONENAND devices
  ARM: OMAP2+: Add variable to store number of GPMC waitpins
  ARM: OMAP2+: Add structure for storing GPMC settings
  ARM: OMAP2+: Add function for configuring GPMC settings
  ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings()
  ARM: OMAP2+: Convert NAND to use gpmc_cs_program_settings()
  ARM: OMAP2+: Convert SMC91x to use gpmc_cs_program_settings()
  ARM: OMAP2+: Convert TUSB to use gpmc_cs_program_settings()
  ARM: OMAP2+: Don't configure of chip-select options in
    gpmc_cs_configure()
  ARM: OMAP2+: Add function to read GPMC settings from device-tree
  ARM: OMAP2+: Add device-tree support for NOR flash
  ARM: OMAP2+: Add additional GPMC timing parameters
  ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT
  ARM: OMAP2+: Convert ONENAND to retrieve GPMC settings from DT
  ARM: OMAP2+: Detect incorrectly aligned GPMC base address
  ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable
  ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails

 Documentation/devicetree/bindings/bus/ti-gpmc.txt  |   48 +-
 Documentation/devicetree/bindings/mtd/gpmc-nor.txt |   98 ++++
 .../devicetree/bindings/mtd/gpmc-onenand.txt       |    3 +
 arch/arm/mach-omap2/gpmc-nand.c                    |   39 +-
 arch/arm/mach-omap2/gpmc-onenand.c                 |  110 ++--
 arch/arm/mach-omap2/gpmc-smc91x.c                  |   30 +-
 arch/arm/mach-omap2/gpmc.c                         |  524 +++++++++++++++-----
 arch/arm/mach-omap2/gpmc.h                         |   37 +-
 arch/arm/mach-omap2/usb-tusb6010.c                 |   62 ++-
 9 files changed, 691 insertions(+), 260 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt

-- 
1.7.10.4

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

* [PATCH V3 01/18] ARM: OMAP2+: Simplify code configuring ONENAND devices
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
@ 2013-03-15 15:20 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins Jon Hunter
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:20 UTC (permalink / raw)
  To: linux-arm-kernel

The OMAP2+ code that configures the GPMC for ONENAND devices is copying
structures between functions unnecessarily. Avoid this by passing
pointers instead and simplify the code.

A pointer to structure "omap_onenand_platform_data" is passed to the
function omap2_onenand_calc_sync_timings(), but only the flags member
of the structure is used. Simplify the code by only passing the flags
member and not the entire structure.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c |   26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 4c91752..db52c4b 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -47,10 +47,9 @@ static struct platform_device gpmc_onenand_device = {
 	.resource	= &gpmc_onenand_resource,
 };
 
-static struct gpmc_timings omap2_onenand_calc_async_timings(void)
+static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
 {
 	struct gpmc_device_timings dev_t;
-	struct gpmc_timings t;
 
 	const int t_cer = 15;
 	const int t_avdp = 12;
@@ -76,9 +75,7 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 	dev_t.t_wpl = t_wpl * 1000;
 	dev_t.t_wph = t_wph * 1000;
 
-	gpmc_calc_timings(&t, &dev_t);
-
-	return t;
+	gpmc_calc_timings(t, &dev_t);
 }
 
 static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
@@ -158,12 +155,11 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
 	return freq;
 }
 
-static struct gpmc_timings
-omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
-				int freq)
+static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
+					    unsigned int flags,
+					    int freq)
 {
 	struct gpmc_device_timings dev_t;
-	struct gpmc_timings t;
 	const int t_cer  = 15;
 	const int t_avdp = 12;
 	const int t_cez  = 20; /* max of t_cez, t_oez */
@@ -172,9 +168,9 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
 	int div, gpmc_clk_ns;
 
-	if (cfg->flags & ONENAND_SYNC_READ)
+	if (flags & ONENAND_SYNC_READ)
 		onenand_flags = ONENAND_FLAG_SYNCREAD;
-	else if (cfg->flags & ONENAND_SYNC_READWRITE)
+	else if (flags & ONENAND_SYNC_READWRITE)
 		onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
 
 	switch (freq) {
@@ -265,9 +261,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 	dev_t.cyc_aavdh_oe = 1;
 	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
 
-	gpmc_calc_timings(&t, &dev_t);
-
-	return t;
+	gpmc_calc_timings(t, &dev_t);
 }
 
 static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
@@ -300,7 +294,7 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
 
 	omap2_onenand_set_async_mode(onenand_base);
 
-	t = omap2_onenand_calc_async_timings();
+	omap2_onenand_calc_async_timings(&t);
 
 	ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
 	if (ret < 0)
@@ -322,7 +316,7 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
 		set_onenand_cfg(onenand_base);
 	}
 
-	t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq);
+	omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
 
 	ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
 	if (ret < 0)
-- 
1.7.10.4

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

* [PATCH V3 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
  2013-03-15 15:20 ` [PATCH V3 01/18] ARM: OMAP2+: Simplify code configuring ONENAND devices Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-16 20:59   ` Ezequiel Garcia
  2013-03-15 15:21 ` [PATCH V3 03/18] ARM: OMAP2+: Add structure for storing GPMC settings Jon Hunter
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

The GPMC has wait-pin signals that can be assigned to a chip-select
to monitor the ready signal of an external device. Add a variable to
indicate the total number of wait-pins for a given device. This will
allow us to detect if the wait-pin being selected is valid or not.

When booting with device-tree read the number of wait-pins from the
device-tree blob. When device-tree is not used set the number of
wait-pins to 4 which is valid for OMAP2-5 devices. Newer devices
that have less wait-pins (such as AM335x) only support booting with
device-tree and so hard-coding the wait-pin number when not using
device-tree is fine.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index ef655d9..88a261c 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -108,6 +108,8 @@
 #define	GPMC_HAS_WR_ACCESS		0x1
 #define	GPMC_HAS_WR_DATA_MUX_BUS	0x2
 
+#define GPMC_NR_WAITPINS		4
+
 /* XXX: Only NAND irq has been considered,currently these are the only ones used
  */
 #define	GPMC_NR_IRQ		2
@@ -153,6 +155,7 @@ static struct resource	gpmc_cs_mem[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_nr_waitpins;
 static struct device *gpmc_dev;
 static int gpmc_irq;
 static resource_size_t phys_base, mem_size;
@@ -1297,6 +1300,13 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 	if (!of_id)
 		return 0;
 
+	ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
+				   &gpmc_nr_waitpins);
+	if (ret < 0) {
+		pr_err("%s: number of wait pins not found!\n", __func__);
+		return ret;
+	}
+
 	for_each_node_by_name(child, "nand") {
 		ret = gpmc_probe_nand_child(pdev, child);
 		if (ret < 0) {
@@ -1372,6 +1382,12 @@ 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_nr_waitpins = GPMC_NR_WAITPINS;
+
 	rc = gpmc_probe_dt(pdev);
 	if (rc < 0) {
 		clk_disable_unprepare(gpmc_l3_clk);
-- 
1.7.10.4

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

* [PATCH V3 03/18] ARM: OMAP2+: Add structure for storing GPMC settings
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
  2013-03-15 15:20 ` [PATCH V3 01/18] ARM: OMAP2+: Simplify code configuring ONENAND devices Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 04/18] ARM: OMAP2+: Add function for configuring " Jon Hunter
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

The GPMC has various different configuration options such as bus-width,
synchronous or asychronous mode selection, burst mode options etc.
Currently, there is no central structure for storing all these options
when configuring the GPMC for a given device. Some of the options are
stored in the GPMC timing structure and some are directly programmed
into the GPMC configuration register. Add a new structure to store
these options and convert code to use this structure. Adding this
structure will allow us to create a common function for configuring
these options.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c |   18 ++++++++++-----
 arch/arm/mach-omap2/gpmc-smc91x.c  |    2 +-
 arch/arm/mach-omap2/gpmc.c         |   45 +++++++++++++++++++++---------------
 arch/arm/mach-omap2/gpmc.h         |   28 ++++++++++++++++------
 arch/arm/mach-omap2/usb-tusb6010.c |   19 ++++++++-------
 5 files changed, 72 insertions(+), 40 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index db52c4b..e175ceb 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -47,6 +47,15 @@ static struct platform_device gpmc_onenand_device = {
 	.resource	= &gpmc_onenand_resource,
 };
 
+static struct gpmc_settings onenand_async = {
+	.mux_add_data	= GPMC_MUX_AD,
+};
+
+static struct gpmc_settings onenand_sync = {
+	.burst_read	= true,
+	.mux_add_data	= GPMC_MUX_AD,
+};
+
 static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
 {
 	struct gpmc_device_timings dev_t;
@@ -63,7 +72,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
 
 	memset(&dev_t, 0, sizeof(dev_t));
 
-	dev_t.mux = true;
 	dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
 	dev_t.t_avdp_w = dev_t.t_avdp_r;
 	dev_t.t_aavdh = t_aavdh * 1000;
@@ -75,7 +83,7 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
 	dev_t.t_wpl = t_wpl * 1000;
 	dev_t.t_wph = t_wph * 1000;
 
-	gpmc_calc_timings(t, &dev_t);
+	gpmc_calc_timings(t, &onenand_async, &dev_t);
 }
 
 static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
@@ -235,10 +243,8 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
 	/* Set synchronous read timings */
 	memset(&dev_t, 0, sizeof(dev_t));
 
-	dev_t.mux = true;
-	dev_t.sync_read = true;
 	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
-		dev_t.sync_write = true;
+		onenand_sync.sync_write = true;
 	} else {
 		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
 		dev_t.t_wpl = t_wpl * 1000;
@@ -261,7 +267,7 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
 	dev_t.cyc_aavdh_oe = 1;
 	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
 
-	gpmc_calc_timings(t, &dev_t);
+	gpmc_calc_timings(t, &onenand_sync, &dev_t);
 }
 
 static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index 11d0b75..4b78338 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -104,7 +104,7 @@ static int smc91c96_gpmc_retime(void)
 	dev_t.t_cez_w = t4_w * 1000;
 	dev_t.t_wr_cycle = (t20 - t3) * 1000;
 
-	gpmc_calc_timings(&t, &dev_t);
+	gpmc_calc_timings(&t, NULL, &dev_t);
 
 	return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
 }
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 88a261c..7cc07b5 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -817,9 +817,9 @@ static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
 
 /* XXX: can the cycles be avoided ? */
 static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
-				struct gpmc_device_timings *dev_t)
+				       struct gpmc_device_timings *dev_t,
+				       bool mux)
 {
-	bool mux = dev_t->mux;
 	u32 temp;
 
 	/* adv_rd_off */
@@ -872,9 +872,9 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
 }
 
 static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
-				struct gpmc_device_timings *dev_t)
+					struct gpmc_device_timings *dev_t,
+					bool mux)
 {
-	bool mux = dev_t->mux;
 	u32 temp;
 
 	/* adv_wr_off */
@@ -934,9 +934,9 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
 }
 
 static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
-				struct gpmc_device_timings *dev_t)
+					struct gpmc_device_timings *dev_t,
+					bool mux)
 {
-	bool mux = dev_t->mux;
 	u32 temp;
 
 	/* adv_rd_off */
@@ -974,9 +974,9 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
 }
 
 static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
-				struct gpmc_device_timings *dev_t)
+					 struct gpmc_device_timings *dev_t,
+					 bool mux)
 {
-	bool mux = dev_t->mux;
 	u32 temp;
 
 	/* adv_wr_off */
@@ -1046,7 +1046,8 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
 }
 
 static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
-			struct gpmc_device_timings *dev_t)
+				    struct gpmc_device_timings *dev_t,
+				    bool sync)
 {
 	u32 temp;
 
@@ -1060,7 +1061,7 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
 				gpmc_t->cs_on + dev_t->t_ce_avd);
 	gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
 
-	if (dev_t->sync_write || dev_t->sync_read)
+	if (sync)
 		gpmc_calc_sync_common_timings(gpmc_t, dev_t);
 
 	return 0;
@@ -1095,21 +1096,29 @@ static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
 }
 
 int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
-			struct gpmc_device_timings *dev_t)
+		      struct gpmc_settings *gpmc_s,
+		      struct gpmc_device_timings *dev_t)
 {
+	bool mux = false, sync = false;
+
+	if (gpmc_s) {
+		mux = gpmc_s->mux_add_data ? true : false;
+		sync = (gpmc_s->sync_read || gpmc_s->sync_write);
+	}
+
 	memset(gpmc_t, 0, sizeof(*gpmc_t));
 
-	gpmc_calc_common_timings(gpmc_t, dev_t);
+	gpmc_calc_common_timings(gpmc_t, dev_t, sync);
 
-	if (dev_t->sync_read)
-		gpmc_calc_sync_read_timings(gpmc_t, dev_t);
+	if (gpmc_s && gpmc_s->sync_read)
+		gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux);
 	else
-		gpmc_calc_async_read_timings(gpmc_t, dev_t);
+		gpmc_calc_async_read_timings(gpmc_t, dev_t, mux);
 
-	if (dev_t->sync_write)
-		gpmc_calc_sync_write_timings(gpmc_t, dev_t);
+	if (gpmc_s && gpmc_s->sync_write)
+		gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux);
 	else
-		gpmc_calc_async_write_timings(gpmc_t, dev_t);
+		gpmc_calc_async_write_timings(gpmc_t, dev_t, mux);
 
 	/* TODO: remove, see function definition */
 	gpmc_convert_ps_to_ns(gpmc_t);
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 697ff42..39e4e04 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -60,8 +60,8 @@
 #define GPMC_CONFIG1_DEVICETYPE_NOR     GPMC_CONFIG1_DEVICETYPE(0)
 #define GPMC_CONFIG1_MUXTYPE(val)       ((val & 3) << 8)
 #define GPMC_CONFIG1_MUXNONMUX          GPMC_CONFIG1_MUXTYPE(0)
-#define GPMC_CONFIG1_MUXAAD             GPMC_CONFIG1_MUXTYPE(1)
-#define GPMC_CONFIG1_MUXADDDATA         GPMC_CONFIG1_MUXTYPE(2)
+#define GPMC_CONFIG1_MUXAAD             GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AAD)
+#define GPMC_CONFIG1_MUXADDDATA         GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AD)
 #define GPMC_CONFIG1_TIME_PARA_GRAN     (1 << 4)
 #define GPMC_CONFIG1_FCLK_DIV(val)      (val & 3)
 #define GPMC_CONFIG1_FCLK_DIV2          (GPMC_CONFIG1_FCLK_DIV(1))
@@ -76,6 +76,8 @@
 #define GPMC_IRQ_FIFOEVENTENABLE	0x01
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
+#define GPMC_MUX_AAD			1	/* Addr-Addr-Data multiplex */
+#define GPMC_MUX_AD			2	/* Addr-Data multiplex */
 
 /* bool type time settings */
 struct gpmc_bool_timings {
@@ -181,10 +183,6 @@ struct gpmc_device_timings {
 	u8 cyc_wpl;	/* write deassertion time in cycles */
 	u32 cyc_iaa;	/* initial access time in cycles */
 
-	bool mux;	/* address & data muxed */
-	bool sync_write;/* synchronous write */
-	bool sync_read;	/* synchronous read */
-
 	/* extra delays */
 	bool ce_xdelay;
 	bool avd_xdelay;
@@ -192,8 +190,24 @@ struct gpmc_device_timings {
 	bool we_xdelay;
 };
 
+struct gpmc_settings {
+	bool burst_wrap;	/* enables wrap bursting */
+	bool burst_read;	/* enables read page/burst mode */
+	bool burst_write;	/* enables write page/burst mode */
+	bool device_nand;	/* device is NAND */
+	bool sync_read;		/* enables synchronous reads */
+	bool sync_write;	/* enables synchronous writes */
+	bool wait_on_read;	/* monitor wait on reads */
+	bool wait_on_write;	/* monitor wait on writes */
+	u32 burst_len;		/* page/burst length */
+	u32 device_width;	/* device bus width (8 or 16 bit) */
+	u32 mux_add_data;	/* multiplex address & data */
+	u32 wait_pin;		/* wait-pin to be used */
+};
+
 extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
-				struct gpmc_device_timings *dev_t);
+			     struct gpmc_settings *gpmc_s,
+			     struct gpmc_device_timings *dev_t);
 
 extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
 extern int gpmc_get_client_irq(unsigned irq_config);
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index c5a3c6f..faaf96d 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -26,6 +26,15 @@
 static u8		async_cs, sync_cs;
 static unsigned		refclk_psec;
 
+static struct gpmc_settings tusb_async = {
+	.mux_add_data	= GPMC_MUX_AD,
+};
+
+static struct gpmc_settings tusb_sync = {
+	.sync_read	= true,
+	.sync_write	= true,
+	.mux_add_data	= GPMC_MUX_AD,
+};
 
 /* NOTE:  timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
 
@@ -37,8 +46,6 @@ static int tusb_set_async_mode(unsigned sysclk_ps)
 
 	memset(&dev_t, 0, sizeof(dev_t));
 
-	dev_t.mux = true;
-
 	dev_t.t_ceasu = 8 * 1000;
 	dev_t.t_avdasu = t_acsnh_advnh - 7000;
 	dev_t.t_ce_avd = 1000;
@@ -52,7 +59,7 @@ static int tusb_set_async_mode(unsigned sysclk_ps)
 	dev_t.t_wpl = 300;
 	dev_t.cyc_aavdh_we = 1;
 
-	gpmc_calc_timings(&t, &dev_t);
+	gpmc_calc_timings(&t, &tusb_async, &dev_t);
 
 	return gpmc_cs_set_timings(async_cs, &t);
 }
@@ -65,10 +72,6 @@ static int tusb_set_sync_mode(unsigned sysclk_ps)
 
 	memset(&dev_t, 0, sizeof(dev_t));
 
-	dev_t.mux = true;
-	dev_t.sync_read = true;
-	dev_t.sync_write = true;
-
 	dev_t.clk = 11100;
 	dev_t.t_bacc = 1000;
 	dev_t.t_ces = 1000;
@@ -84,7 +87,7 @@ static int tusb_set_sync_mode(unsigned sysclk_ps)
 	dev_t.cyc_wpl = 6;
 	dev_t.t_ce_rdyz = 7000;
 
-	gpmc_calc_timings(&t, &dev_t);
+	gpmc_calc_timings(&t, &tusb_sync, &dev_t);
 
 	return gpmc_cs_set_timings(sync_cs, &t);
 }
-- 
1.7.10.4

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

* [PATCH V3 04/18] ARM: OMAP2+: Add function for configuring GPMC settings
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (2 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 03/18] ARM: OMAP2+: Add structure for storing GPMC settings Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 05/18] ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings() Jon Hunter
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

The GPMC has various different configuration options such as bus-width,
synchronous or asychronous mode selection, burst mode options etc.
Currently, there is no common function for configuring these options and
various devices set these options by either programming the GPMC CONFIG1
register directly or by calling gpmc_cs_configure() to set some of the
options.

Add a new function for configuring all of the GPMC options. Having a common
function for configuring this options will simplify code and ease the
migration to device-tree.

Also add a new capability flag to detect devices that support the
address-address-data multiplexing mode.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |  100 ++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/gpmc.h |    6 +++
 2 files changed, 106 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 7cc07b5..760c26d 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -107,6 +107,7 @@
 
 #define	GPMC_HAS_WR_ACCESS		0x1
 #define	GPMC_HAS_WR_DATA_MUX_BUS	0x2
+#define	GPMC_HAS_MUX_AAD		0x4
 
 #define GPMC_NR_WAITPINS		4
 
@@ -1129,6 +1130,90 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
 	return 0;
 }
 
+/**
+ * gpmc_cs_program_settings - programs non-timing related settings
+ * @cs:		GPMC chip-select to program
+ * @p:		pointer to GPMC settings structure
+ *
+ * Programs non-timing related settings for a GPMC chip-select, such as
+ * bus-width, burst configuration, etc. Function should be called once
+ * for each chip-select that is being used and must be called before
+ * calling gpmc_cs_set_timings() as timing parameters in the CONFIG1
+ * register will be initialised to zero by this function. Returns 0 on
+ * success and appropriate negative error code on failure.
+ */
+int gpmc_cs_program_settings(int cs, struct gpmc_settings *p)
+{
+	u32 config1;
+
+	if ((!p->device_width) || (p->device_width > GPMC_DEVWIDTH_16BIT)) {
+		pr_err("%s: invalid width %d!", __func__, p->device_width);
+		return -EINVAL;
+	}
+
+	/* Address-data multiplexing not supported for NAND devices */
+	if (p->device_nand && p->mux_add_data) {
+		pr_err("%s: invalid configuration!\n", __func__);
+		return -EINVAL;
+	}
+
+	if ((p->mux_add_data > GPMC_MUX_AD) ||
+	    ((p->mux_add_data == GPMC_MUX_AAD) &&
+	     !(gpmc_capability & GPMC_HAS_MUX_AAD))) {
+		pr_err("%s: invalid multiplex configuration!\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Page/burst mode supports lengths of 4, 8 and 16 bytes */
+	if (p->burst_read || p->burst_write) {
+		switch (p->burst_len) {
+		case GPMC_BURST_4:
+		case GPMC_BURST_8:
+		case GPMC_BURST_16:
+			break;
+		default:
+			pr_err("%s: invalid page/burst-length (%d)\n",
+			       __func__, p->burst_len);
+			return -EINVAL;
+		}
+	}
+
+	if ((p->wait_on_read || p->wait_on_write) &&
+	    (p->wait_pin > gpmc_nr_waitpins)) {
+		pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin);
+		return -EINVAL;
+	}
+
+	config1 = GPMC_CONFIG1_DEVICESIZE((p->device_width - 1));
+
+	if (p->sync_read)
+		config1 |= GPMC_CONFIG1_READTYPE_SYNC;
+	if (p->sync_write)
+		config1 |= GPMC_CONFIG1_WRITETYPE_SYNC;
+	if (p->wait_on_read)
+		config1 |= GPMC_CONFIG1_WAIT_READ_MON;
+	if (p->wait_on_write)
+		config1 |= GPMC_CONFIG1_WAIT_WRITE_MON;
+	if (p->wait_on_read || p->wait_on_write)
+		config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p->wait_pin);
+	if (p->device_nand)
+		config1	|= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND);
+	if (p->mux_add_data)
+		config1	|= GPMC_CONFIG1_MUXTYPE(p->mux_add_data);
+	if (p->burst_read)
+		config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP;
+	if (p->burst_write)
+		config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP;
+	if (p->burst_read || p->burst_write) {
+		config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3);
+		config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0;
+	}
+
+	gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1);
+
+	return 0;
+}
+
 #ifdef CONFIG_OF
 static struct of_device_id gpmc_dt_ids[] = {
 	{ .compatible = "ti,omap2420-gpmc" },
@@ -1375,8 +1460,23 @@ static int gpmc_probe(struct platform_device *pdev)
 	gpmc_dev = &pdev->dev;
 
 	l = gpmc_read_reg(GPMC_REVISION);
+
+	/*
+	 * FIXME: Once device-tree migration is complete the below flags
+	 * should be populated based upon the device-tree compatible
+	 * string. For now just use the IP revision. OMAP3+ devices have
+	 * the wr_access and wr_data_mux_bus register fields. OMAP4+
+	 * devices support the addr-addr-data multiplex protocol.
+	 *
+	 * GPMC IP revisions:
+	 * - OMAP24xx			= 2.0
+	 * - OMAP3xxx			= 5.0
+	 * - OMAP44xx/54xx/AM335x	= 6.0
+	 */
 	if (GPMC_REVISION_MAJOR(l) > 0x4)
 		gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
+	if (GPMC_REVISION_MAJOR(l) > 0x5)
+		gpmc_capability |= GPMC_HAS_MUX_AAD;
 	dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
 		 GPMC_REVISION_MINOR(l));
 
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 39e4e04..ce6ae21 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -76,6 +76,11 @@
 #define GPMC_IRQ_FIFOEVENTENABLE	0x01
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
+#define GPMC_BURST_4			4	/* 4 word burst */
+#define GPMC_BURST_8			8	/* 8 word burst */
+#define GPMC_BURST_16			16	/* 16 word burst */
+#define GPMC_DEVWIDTH_8BIT		1	/* 8-bit device width */
+#define GPMC_DEVWIDTH_16BIT		2	/* 16-bit device width */
 #define GPMC_MUX_AAD			1	/* Addr-Addr-Data multiplex */
 #define GPMC_MUX_AD			2	/* Addr-Data multiplex */
 
@@ -217,6 +222,7 @@ extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
 extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
 extern int gpmc_calc_divider(unsigned int sync_clk);
 extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
+extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p);
 extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
 extern void gpmc_cs_free(int cs);
 extern void omap3_gpmc_save_context(void);
-- 
1.7.10.4

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

* [PATCH V3 05/18] ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings()
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (3 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 04/18] ARM: OMAP2+: Add function for configuring " Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 06/18] ARM: OMAP2+: Convert NAND " Jon Hunter
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the OMAP2+ ONENAND code to use the gpmc_cs_program_settings()
function for configuring the various GPMC options instead of directly
programming the CONFIG1 register.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c |   61 +++++++++++++++---------------------
 1 file changed, 25 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index e175ceb..46aac83 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -48,18 +48,22 @@ static struct platform_device gpmc_onenand_device = {
 };
 
 static struct gpmc_settings onenand_async = {
+	.device_width	= GPMC_DEVWIDTH_16BIT,
 	.mux_add_data	= GPMC_MUX_AD,
 };
 
 static struct gpmc_settings onenand_sync = {
 	.burst_read	= true,
+	.burst_wrap	= true,
+	.burst_len	= GPMC_BURST_16,
+	.device_width	= GPMC_DEVWIDTH_16BIT,
 	.mux_add_data	= GPMC_MUX_AD,
+	.wait_pin	= 0,
 };
 
 static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
 {
 	struct gpmc_device_timings dev_t;
-
 	const int t_cer = 15;
 	const int t_avdp = 12;
 	const int t_aavdh = 7;
@@ -86,16 +90,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
 	gpmc_calc_timings(t, &onenand_async, &dev_t);
 }
 
-static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
-{
-	/* Configure GPMC for asynchronous read */
-	gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
-			  GPMC_CONFIG1_DEVICESIZE_16 |
-			  GPMC_CONFIG1_MUXADDDATA);
-
-	return gpmc_cs_set_timings(cs, t);
-}
-
 static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
 {
 	u32 reg;
@@ -243,8 +237,11 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
 	/* Set synchronous read timings */
 	memset(&dev_t, 0, sizeof(dev_t));
 
+	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
+		onenand_sync.sync_read = true;
 	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
 		onenand_sync.sync_write = true;
+		onenand_sync.burst_write = true;
 	} else {
 		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
 		dev_t.t_wpl = t_wpl * 1000;
@@ -270,29 +267,6 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
 	gpmc_calc_timings(t, &onenand_sync, &dev_t);
 }
 
-static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
-{
-	unsigned sync_read = onenand_flags & ONENAND_FLAG_SYNCREAD;
-	unsigned sync_write = onenand_flags & ONENAND_FLAG_SYNCWRITE;
-
-	/* Configure GPMC for synchronous read */
-	gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
-			  GPMC_CONFIG1_WRAPBURST_SUPP |
-			  GPMC_CONFIG1_READMULTIPLE_SUPP |
-			  (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
-			  (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
-			  (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
-			  GPMC_CONFIG1_PAGE_LEN(2) |
-			  (cpu_is_omap34xx() ? 0 :
-				(GPMC_CONFIG1_WAIT_READ_MON |
-				 GPMC_CONFIG1_WAIT_PIN_SEL(0))) |
-			  GPMC_CONFIG1_DEVICESIZE_16 |
-			  GPMC_CONFIG1_DEVICETYPE_NOR |
-			  GPMC_CONFIG1_MUXADDDATA);
-
-	return gpmc_cs_set_timings(cs, t);
-}
-
 static int omap2_onenand_setup_async(void __iomem *onenand_base)
 {
 	struct gpmc_timings t;
@@ -302,7 +276,11 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
 
 	omap2_onenand_calc_async_timings(&t);
 
-	ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
+	ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
+	if (ret < 0)
+		return ret;
+
+	ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t);
 	if (ret < 0)
 		return ret;
 
@@ -322,9 +300,20 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
 		set_onenand_cfg(onenand_base);
 	}
 
+	/*
+	 * FIXME: Appears to be legacy code from initial ONENAND commit.
+	 * Unclear what boards this is for and if this can be removed.
+	 */
+	if (!cpu_is_omap34xx())
+		onenand_sync.wait_on_read = true;
+
 	omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
 
-	ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
+	ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync);
+	if (ret < 0)
+		return ret;
+
+	ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t);
 	if (ret < 0)
 		return ret;
 
-- 
1.7.10.4

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

* [PATCH V3 06/18] ARM: OMAP2+: Convert NAND to use gpmc_cs_program_settings()
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (4 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 05/18] ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings() Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 07/18] ARM: OMAP2+: Convert SMC91x " Jon Hunter
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the OMAP2+ NAND code to use the gpmc_cs_program_settings()
function for configuring the various GPMC options instead of directly
programming the CONFIG1 register.

This moves the configuration of some GPMC options outside the
nand_gpmc_retime() because these options should only need to be set once
regardless of whether the gpmc timing is changing dynamically at runtime.
The programming of where the wait-pin is also moved slightly, but this
will not have any impact to existing devices as no boards are currently
setting the dev_ready variable.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc-nand.c |   35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index e50e438..75feb95 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -74,14 +74,6 @@ static int omap2_nand_gpmc_retime(
 	t.cs_wr_off = gpmc_t->cs_wr_off;
 	t.wr_cycle = gpmc_t->wr_cycle;
 
-	/* Configure GPMC */
-	if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
-		gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 1);
-	else
-		gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 0);
-	gpmc_cs_configure(gpmc_nand_data->cs,
-			GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
-	gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0);
 	err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t);
 	if (err)
 		return err;
@@ -115,8 +107,11 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 		   struct gpmc_timings *gpmc_t)
 {
 	int err	= 0;
+	struct gpmc_settings s;
 	struct device *dev = &gpmc_nand_device.dev;
 
+	memset(&s, 0, sizeof(struct gpmc_settings));
+
 	gpmc_nand_device.dev.platform_data = gpmc_nand_data;
 
 	err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
@@ -141,11 +136,27 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 			dev_err(dev, "Unable to set gpmc timings: %d\n", err);
 			return err;
 		}
-	}
 
-	/* Enable RD PIN Monitoring Reg */
-	if (gpmc_nand_data->dev_ready) {
-		gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1);
+		s.device_nand = true;
+
+		/* Enable RD PIN Monitoring Reg */
+		if (gpmc_nand_data->dev_ready) {
+			s.wait_on_read = true;
+			s.wait_on_write = true;
+		}
+
+		if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
+			s.device_width = GPMC_DEVWIDTH_16BIT;
+		else
+			s.device_width = GPMC_DEVWIDTH_8BIT;
+
+		err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
+		if (err < 0)
+			goto out_free_cs;
+
+		err = gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0);
+		if (err < 0)
+			goto out_free_cs;
 	}
 
 	gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
-- 
1.7.10.4

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

* [PATCH V3 07/18] ARM: OMAP2+: Convert SMC91x to use gpmc_cs_program_settings()
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (5 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 06/18] ARM: OMAP2+: Convert NAND " Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 08/18] ARM: OMAP2+: Convert TUSB " Jon Hunter
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the OMAP2+ SMC91x code to use the gpmc_cs_program_settings()
function for configuring the various GPMC options instead of directly
programming the CONFIG1 register.

Move configuration of the GPMC settings outside retime function and
this does not need to be done if the timings are changed dynamically
at runtime.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc-smc91x.c |   30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index 4b78338..61a0635 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -49,6 +49,10 @@ static struct platform_device gpmc_smc91x_device = {
 	.resource	= gpmc_smc91x_resources,
 };
 
+static struct gpmc_settings smc91x_settings = {
+	.device_width = GPMC_DEVWIDTH_16BIT,
+};
+
 /*
  * Set the gpmc timings for smc91c96. The timings are taken
  * from the data sheet available at:
@@ -67,18 +71,6 @@ static int smc91c96_gpmc_retime(void)
 	const int t7 = 5;	/* Figure 12.4 write */
 	const int t8 = 5;	/* Figure 12.4 write */
 	const int t20 = 185;	/* Figure 12.2 read and 12.4 write */
-	u32 l;
-
-	l = GPMC_CONFIG1_DEVICESIZE_16;
-	if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
-		l |= GPMC_CONFIG1_MUXADDDATA;
-	if (gpmc_cfg->flags & GPMC_READ_MON)
-		l |= GPMC_CONFIG1_WAIT_READ_MON;
-	if (gpmc_cfg->flags & GPMC_WRITE_MON)
-		l |= GPMC_CONFIG1_WAIT_WRITE_MON;
-	if (gpmc_cfg->wait_pin)
-		l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg->wait_pin);
-	gpmc_cs_write_reg(gpmc_cfg->cs, GPMC_CS_CONFIG1, l);
 
 	/*
 	 * FIXME: Calculate the address and data bus muxed timings.
@@ -104,7 +96,7 @@ static int smc91c96_gpmc_retime(void)
 	dev_t.t_cez_w = t4_w * 1000;
 	dev_t.t_wr_cycle = (t20 - t3) * 1000;
 
-	gpmc_calc_timings(&t, NULL, &dev_t);
+	gpmc_calc_timings(&t, &smc91x_settings, &dev_t);
 
 	return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
 }
@@ -133,6 +125,18 @@ void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data)
 	gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f;
 	gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK);
 
+	if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
+		smc91x_settings.mux_add_data = GPMC_MUX_AD;
+	if (gpmc_cfg->flags & GPMC_READ_MON)
+		smc91x_settings.wait_on_read = true;
+	if (gpmc_cfg->flags & GPMC_WRITE_MON)
+		smc91x_settings.wait_on_write = true;
+	if (gpmc_cfg->wait_pin)
+		smc91x_settings.wait_pin = gpmc_cfg->wait_pin;
+	ret = gpmc_cs_program_settings(gpmc_cfg->cs, &smc91x_settings);
+	if (ret < 0)
+		goto free1;
+
 	if (gpmc_cfg->retime) {
 		ret = gpmc_cfg->retime();
 		if (ret != 0)
-- 
1.7.10.4

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

* [PATCH V3 08/18] ARM: OMAP2+: Convert TUSB to use gpmc_cs_program_settings()
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (6 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 07/18] ARM: OMAP2+: Convert SMC91x " Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 09/18] ARM: OMAP2+: Don't configure of chip-select options in gpmc_cs_configure() Jon Hunter
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the OMAP2+ TUSB code to use the gpmc_cs_program_settings()
function for configuring the various GPMC options instead of directly
programming the CONFIG1 register.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/usb-tusb6010.c |   43 ++++++++++++++++--------------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index faaf96d..e832bc7 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/err.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -27,12 +28,21 @@ static u8		async_cs, sync_cs;
 static unsigned		refclk_psec;
 
 static struct gpmc_settings tusb_async = {
+	.wait_on_read	= true,
+	.wait_on_write	= true,
+	.device_width	= GPMC_DEVWIDTH_16BIT,
 	.mux_add_data	= GPMC_MUX_AD,
 };
 
 static struct gpmc_settings tusb_sync = {
+	.burst_read	= true,
+	.burst_write	= true,
 	.sync_read	= true,
 	.sync_write	= true,
+	.wait_on_read	= true,
+	.wait_on_write	= true,
+	.burst_len	= GPMC_BURST_16,
+	.device_width	= GPMC_DEVWIDTH_16BIT,
 	.mux_add_data	= GPMC_MUX_AD,
 };
 
@@ -168,18 +178,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
 		return status;
 	}
 	tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
+	tusb_async.wait_pin = waitpin;
 	async_cs = async;
-	gpmc_cs_write_reg(async, GPMC_CS_CONFIG1,
-			  GPMC_CONFIG1_PAGE_LEN(2)
-			| GPMC_CONFIG1_WAIT_READ_MON
-			| GPMC_CONFIG1_WAIT_WRITE_MON
-			| GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
-			| GPMC_CONFIG1_READTYPE_ASYNC
-			| GPMC_CONFIG1_WRITETYPE_ASYNC
-			| GPMC_CONFIG1_DEVICESIZE_16
-			| GPMC_CONFIG1_DEVICETYPE_NOR
-			| GPMC_CONFIG1_MUXADDDATA);
 
+	status = gpmc_cs_program_settings(async_cs, &tusb_async);
+	if (status < 0)
+		return status;
 
 	/* SYNC region, primarily for DMA */
 	status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
@@ -189,21 +193,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
 		return status;
 	}
 	tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
+	tusb_sync.wait_pin = waitpin;
 	sync_cs = sync;
-	gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1,
-			  GPMC_CONFIG1_READMULTIPLE_SUPP
-			| GPMC_CONFIG1_READTYPE_SYNC
-			| GPMC_CONFIG1_WRITEMULTIPLE_SUPP
-			| GPMC_CONFIG1_WRITETYPE_SYNC
-			| GPMC_CONFIG1_PAGE_LEN(2)
-			| GPMC_CONFIG1_WAIT_READ_MON
-			| GPMC_CONFIG1_WAIT_WRITE_MON
-			| GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
-			| GPMC_CONFIG1_DEVICESIZE_16
-			| GPMC_CONFIG1_DEVICETYPE_NOR
-			| GPMC_CONFIG1_MUXADDDATA
-			/* fclk divider gets set later */
-			);
+
+	status = gpmc_cs_program_settings(sync_cs, &tusb_sync);
+	if (status < 0)
+		return status;
 
 	/* IRQ */
 	status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
-- 
1.7.10.4

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

* [PATCH V3 09/18] ARM: OMAP2+: Don't configure of chip-select options in gpmc_cs_configure()
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (7 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 08/18] ARM: OMAP2+: Convert TUSB " Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree Jon Hunter
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

With the addition of the gpmc_cs_program_settings(), we no longer need
or use gpmc_cs_configure() to configure some of the GPMC chip-select
options. So rename the function to gpmc_configure() and remove code that
modifies options in the CONFIG1 register.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc-nand.c |    2 +-
 arch/arm/mach-omap2/gpmc.c      |   49 ++++++---------------------------------
 arch/arm/mach-omap2/gpmc.h      |    5 +---
 3 files changed, 9 insertions(+), 47 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 75feb95..12e9753 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -154,7 +154,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 		if (err < 0)
 			goto out_free_cs;
 
-		err = gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0);
+		err = gpmc_configure(GPMC_CONFIG_WP, 0);
 		if (err < 0)
 			goto out_free_cs;
 	}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 760c26d..3ec1937 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -550,16 +550,14 @@ void gpmc_cs_free(int cs)
 EXPORT_SYMBOL(gpmc_cs_free);
 
 /**
- * gpmc_cs_configure - write request to configure gpmc
- * @cs: chip select number
+ * gpmc_configure - write request to configure gpmc
  * @cmd: command type
  * @wval: value to write
  * @return status of the operation
  */
-int gpmc_cs_configure(int cs, int cmd, int wval)
+int gpmc_configure(int cmd, int wval)
 {
-	int err = 0;
-	u32 regval = 0;
+	u32 regval;
 
 	switch (cmd) {
 	case GPMC_ENABLE_IRQ:
@@ -579,47 +577,14 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
 		gpmc_write_reg(GPMC_CONFIG, regval);
 		break;
 
-	case GPMC_CONFIG_RDY_BSY:
-		regval  = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-		if (wval)
-			regval |= WR_RD_PIN_MONITORING;
-		else
-			regval &= ~WR_RD_PIN_MONITORING;
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
-		break;
-
-	case GPMC_CONFIG_DEV_SIZE:
-		regval  = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-
-		/* clear 2 target bits */
-		regval &= ~GPMC_CONFIG1_DEVICESIZE(3);
-
-		/* set the proper value */
-		regval |= GPMC_CONFIG1_DEVICESIZE(wval);
-
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
-		break;
-
-	case GPMC_CONFIG_DEV_TYPE:
-		regval  = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-		/* clear 4 target bits */
-		regval &= ~(GPMC_CONFIG1_DEVICETYPE(3) |
-			    GPMC_CONFIG1_MUXTYPE(3));
-		/* set the proper value */
-		regval |= GPMC_CONFIG1_DEVICETYPE(wval);
-		if (wval == GPMC_DEVICETYPE_NOR)
-			regval |= GPMC_CONFIG1_MUXADDDATA;
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
-		break;
-
 	default:
-		printk(KERN_ERR "gpmc_configure_cs: Not supported\n");
-		err = -EINVAL;
+		pr_err("%s: command not supported\n", __func__);
+		return -EINVAL;
 	}
 
-	return err;
+	return 0;
 }
-EXPORT_SYMBOL(gpmc_cs_configure);
+EXPORT_SYMBOL(gpmc_configure);
 
 void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 {
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index ce6ae21..87d2a22 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -59,9 +59,6 @@
 #define GPMC_CONFIG1_DEVICETYPE(val)    ((val & 3) << 10)
 #define GPMC_CONFIG1_DEVICETYPE_NOR     GPMC_CONFIG1_DEVICETYPE(0)
 #define GPMC_CONFIG1_MUXTYPE(val)       ((val & 3) << 8)
-#define GPMC_CONFIG1_MUXNONMUX          GPMC_CONFIG1_MUXTYPE(0)
-#define GPMC_CONFIG1_MUXAAD             GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AAD)
-#define GPMC_CONFIG1_MUXADDDATA         GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AD)
 #define GPMC_CONFIG1_TIME_PARA_GRAN     (1 << 4)
 #define GPMC_CONFIG1_FCLK_DIV(val)      (val & 3)
 #define GPMC_CONFIG1_FCLK_DIV2          (GPMC_CONFIG1_FCLK_DIV(1))
@@ -227,6 +224,6 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
 extern void gpmc_cs_free(int cs);
 extern void omap3_gpmc_save_context(void);
 extern void omap3_gpmc_restore_context(void);
-extern int gpmc_cs_configure(int cs, int cmd, int wval);
+extern int gpmc_configure(int cmd, int wval);
 
 #endif
-- 
1.7.10.4

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

* [PATCH V3 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (8 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 09/18] ARM: OMAP2+: Don't configure of chip-select options in gpmc_cs_configure() Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-17  5:24   ` Ezequiel Garcia
  2013-03-15 15:21 ` [PATCH V3 11/18] ARM: OMAP2+: Add device-tree support for NOR flash Jon Hunter
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

Adds a function to read the various GPMC chip-select settings from
device-tree and store them in the gpmc_settings structure.

Update the GPMC device-tree binding documentation to describe these
options.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 Documentation/devicetree/bindings/bus/ti-gpmc.txt |   23 ++++++++++
 arch/arm/mach-omap2/gpmc.c                        |   49 +++++++++++++++++++++
 arch/arm/mach-omap2/gpmc.h                        |    2 +
 3 files changed, 74 insertions(+)

diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
index 5ddb2e9..6fde1cf 100644
--- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt
+++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
@@ -65,6 +65,29 @@ The following are only applicable to OMAP3+ and AM335x:
  - gpmc,wr-access
  - gpmc,wr-data-mux-bus
 
+GPMC chip-select settings properties for child nodes. All are optional.
+
+- gpmc,burst-length	Page/burst length. Must be 4, 8 or 16.
+- gpmc,burst-wrap	Enables wrap bursting
+- gpmc,burst-read	Enables read page/burst mode
+- gpmc,burst-write	Enables write page/burst mode
+- gpmc,device-nand	Device is NAND
+- gpmc,device-width	Total width of device(s) connected to a GPMC
+			chip-select in bytes. The GPMC supports 8-bit
+			and 16-bit devices and so this property must be
+			1 or 2.
+- gpmc,mux-add-data	Address and data multiplexing configuration.
+			Valid values are 1 for address-address-data
+			multiplexing mode and 2 for address-data
+			multiplexing mode.
+- gpmc,sync-read	Enables synchronous read. Defaults to asynchronous
+			is this is not set.
+- gpmc,sync-write	Enables synchronous writes. Defaults to asynchronous
+			is this is not set.
+- gpmc,wait-pin		Wait-pin used by client. Must be less than
+			"gpmc,num-waitpins".
+- gpmc,wait-on-read	Enables wait monitoring on reads.
+- gpmc,wait-on-write	Enables wait monitoring on writes.
 
 Example for an AM33xx board:
 
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 3ec1937..1e7eef3 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1190,6 +1190,55 @@ static struct of_device_id gpmc_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
 
+/**
+ * gpmc_read_settings_dt - read gpmc settings from device-tree
+ * @np:		pointer to device-tree node for a gpmc child device
+ * @p:		pointer to gpmc settings structure
+ *
+ * Reads the GPMC settings for a GPMC child device from device-tree and
+ * stores them in the GPMC settings structure passed. The GPMC settings
+ * structure is initialise to zero by this function and so any previously
+ * stored settings will be clearer.
+ */
+void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
+{
+	memset(p, 0, sizeof(struct gpmc_settings));
+
+	if (of_find_property(np, "gpmc,sync-read", NULL))
+		p->sync_read = true;
+	if (of_find_property(np, "gpmc,sync-write", NULL))
+		p->sync_write = true;
+
+	if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) {
+		if (of_find_property(np, "gpmc,burst-wrap", NULL))
+			p->burst_wrap = true;
+		if (of_find_property(np, "gpmc,burst-read", NULL))
+			p->burst_read = true;
+		if (of_find_property(np, "gpmc,burst-write", NULL))
+			p->burst_write = true;
+		if (!p->burst_read && !p->burst_write)
+			pr_warn("%s: page/burst-length set but not used!\n",
+				__func__);
+	}
+
+	if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) {
+		if (of_find_property(np, "gpmc,wait-on-read", NULL))
+			p->wait_on_read = true;
+		if (of_find_property(np, "gpmc,wait-on-write", NULL))
+			p->wait_on_write = true;
+		if (!p->wait_on_read && !p->wait_on_write)
+			pr_warn("%s: read/write wait monitoring not enabled!\n",
+				__func__);
+	}
+
+	of_property_read_u32(np, "gpmc,device-width", &p->device_width);
+
+	if (of_find_property(np, "gpmc,device-nand", NULL))
+		p->device_nand = true;
+
+	of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data);
+}
+
 static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 						struct gpmc_timings *gpmc_t)
 {
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 87d2a22..707f6d5 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -225,5 +225,7 @@ extern void gpmc_cs_free(int cs);
 extern void omap3_gpmc_save_context(void);
 extern void omap3_gpmc_restore_context(void);
 extern int gpmc_configure(int cmd, int wval);
+extern void gpmc_read_settings_dt(struct device_node *np,
+				  struct gpmc_settings *p);
 
 #endif
-- 
1.7.10.4

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

* [PATCH V3 11/18] ARM: OMAP2+: Add device-tree support for NOR flash
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (9 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters Jon Hunter
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

NOR flash is not currently supported when booting with device-tree
on OMAP2+ devices. Add support to detect and configure NOR devices
when booting with device-tree.

Add documentation for the TI GPMC NOR binding.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 Documentation/devicetree/bindings/mtd/gpmc-nor.txt |   98 +++++++++++++++++
 arch/arm/mach-omap2/gpmc.c                         |  115 ++++++++++++++++++++
 2 files changed, 213 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
new file mode 100644
index 0000000..8c638fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
@@ -0,0 +1,98 @@
+Device tree bindings for NOR flash connect to TI GPMC
+
+NOR flash connected to the TI GPMC (found on OMAP boards) are represented as
+child nodes of the GPMC controller with a name of "nor".
+
+All timing relevant properties as well as generic GPMC child properties are
+explained in a separate documents. Please refer to
+Documentation/devicetree/bindings/bus/ti-gpmc.txt
+
+Required properties:
+- bank-width: 		Width of NOR flash in bytes. GPMC supports 8-bit and
+			16-bit devices and so must be either 1 or 2 bytes.
+- compatible:		Documentation/devicetree/bindings/mtd/mtd-physmap.txt
+- gpmc,cs-on:		Chip-select assertion time
+- gpmc,cs-rd-off:	Chip-select de-assertion time for reads
+- gpmc,cs-wr-off:	Chip-select de-assertion time for writes
+- gpmc,oe-on:		Output-enable assertion time
+- gpmc,oe-off		Output-enable de-assertion time
+- gpmc,we-on:		Write-enable assertion time
+- gpmc,we-off:		Write-enable de-assertion time
+- gpmc,access:		Start cycle to first data capture (read access)
+- gpmc,rd-cycle:	Total read cycle time
+- gpmc,wr-cycle:	Total write cycle time
+- linux,mtd-name:	Documentation/devicetree/bindings/mtd/mtd-physmap.txt
+- reg:			Chip-select, base address (relative to chip-select)
+			and size of NOR flash. Note that base address will be
+			typically 0 as this is the start of the chip-select.
+
+Optional properties:
+- gpmc,XXX		Additional GPMC timings and settings parameters. See
+			Documentation/devicetree/bindings/bus/ti-gpmc.txt
+
+Optional properties for partiton table parsing:
+- #address-cells: should be set to 1
+- #size-cells: should be set to 1
+
+Example:
+
+gpmc: gpmc at 6e000000 {
+	compatible = "ti,omap3430-gpmc", "simple-bus";
+	ti,hwmods = "gpmc";
+	reg = <0x6e000000 0x1000>;
+	interrupts = <20>;
+	gpmc,num-cs = <8>;
+	gpmc,num-waitpins = <4>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	ranges = <0 0 0x10000000 0x08000000>;
+
+	nor at 0,0 {
+		compatible = "cfi-flash";
+		linux,mtd-name= "intel,pf48f6000m0y1be";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0 0 0x08000000>;
+		bank-width = <2>;
+
+		gpmc,mux-add-data;
+		gpmc,cs-on = <0>;
+		gpmc,cs-rd-off = <186>;
+		gpmc,cs-wr-off = <186>;
+		gpmc,adv-on = <12>;
+		gpmc,adv-rd-off = <48>;
+		gpmc,adv-wr-off = <48>;
+		gpmc,oe-on = <54>;
+		gpmc,oe-off = <168>;
+		gpmc,we-on = <54>;
+		gpmc,we-off = <168>;
+		gpmc,rd-cycle = <186>;
+		gpmc,wr-cycle = <186>;
+		gpmc,access = <114>;
+		gpmc,page-burst-access = <6>;
+		gpmc,bus-turnaround = <12>;
+		gpmc,cycle2cycle-delay = <18>;
+		gpmc,wr-data-mux-bus = <90>;
+		gpmc,wr-access = <186>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
+
+		partition at 0 {
+			label = "bootloader-nor";
+			reg = <0 0x40000>;
+		};
+		partition at 0x40000 {
+			label = "params-nor";
+			reg = <0x40000 0x40000>;
+		};
+		partition at 0x80000 {
+			label = "kernel-nor";
+			reg = <0x80000 0x200000>;
+		};
+		partition at 0x280000 {
+			label = "filesystem-nor";
+			reg = <0x240000 0x7d80000>;
+		};
+	};
+};
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 1e7eef3..85b1a35 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_mtd.h>
 #include <linux/of_device.h>
 #include <linux/mtd/nand.h>
@@ -499,6 +500,37 @@ static int gpmc_cs_delete_mem(int cs)
 	return r;
 }
 
+/**
+ * gpmc_cs_remap - remaps a chip-select physical base address
+ * @cs:		chip-select to remap
+ * @base:	physical base address to re-map chip-select to
+ *
+ * Re-maps a chip-select to a new physical base address specified by
+ * "base". Returns 0 on success and appropriate negative error code
+ * on failure.
+ */
+static int gpmc_cs_remap(int cs, u32 base)
+{
+	int ret;
+	u32 old_base, size;
+
+	if (cs > GPMC_CS_NUM)
+		return -ENODEV;
+	gpmc_cs_get_memconf(cs, &old_base, &size);
+	if (base == old_base)
+		return 0;
+	gpmc_cs_disable_mem(cs);
+	ret = gpmc_cs_delete_mem(cs);
+	if (ret < 0)
+		return ret;
+	ret = gpmc_cs_insert_mem(cs, base, size);
+	if (ret < 0)
+		return ret;
+	gpmc_cs_enable_mem(cs, base, size);
+
+	return 0;
+}
+
 int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
 {
 	struct resource *res = &gpmc_cs_mem[cs];
@@ -1398,6 +1430,80 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev,
 }
 #endif
 
+/**
+ * gpmc_probe_nor_child - configures the gpmc for a nor device
+ * @pdev:	pointer to gpmc platform device
+ * @child:	pointer to device-tree node for nor device
+ *
+ * Allocates and configures a GPMC chip-select for a NOR flash device.
+ * Returns 0 on success and appropriate negative error code on failure.
+ */
+static int gpmc_probe_nor_child(struct platform_device *pdev,
+				struct device_node *child)
+{
+	struct gpmc_settings gpmc_s;
+	struct gpmc_timings gpmc_t;
+	struct resource res;
+	unsigned long base;
+	int ret, cs;
+
+	if (of_property_read_u32(child, "reg", &cs) < 0) {
+		dev_err(&pdev->dev, "%s has no 'reg' property\n",
+			child->full_name);
+		return -ENODEV;
+	}
+
+	if (of_address_to_resource(child, 0, &res) < 0) {
+		dev_err(&pdev->dev, "%s has malformed 'reg' property\n",
+			child->full_name);
+		return -ENODEV;
+	}
+
+	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;
+	}
+
+	/*
+	 * 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
+	 * location specified in the device-tree blob. So remap the
+	 * CS to this location. Once DT migration is complete should
+	 * just make gpmc_cs_request() map a specific address.
+	 */
+	ret = gpmc_cs_remap(cs, res.start);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "cannot remap GPMC CS %d to 0x%x\n",
+			cs, res.start);
+		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;
+
+	ret = gpmc_cs_program_settings(cs, &gpmc_s);
+	if (ret < 0)
+		goto err;
+
+	gpmc_read_timings_dt(child, &gpmc_t);
+	gpmc_cs_set_timings(cs, &gpmc_t);
+
+	if (of_platform_device_create(child, NULL, &pdev->dev))
+		return 0;
+
+	dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
+
+err:
+	gpmc_cs_free(cs);
+
+	return ret;
+}
+
 static int gpmc_probe_dt(struct platform_device *pdev)
 {
 	int ret;
@@ -1430,6 +1536,15 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 			return ret;
 		}
 	}
+
+	for_each_node_by_name(child, "nor") {
+		ret = gpmc_probe_nor_child(pdev, child);
+		if (ret < 0) {
+			of_node_put(child);
+			return ret;
+		}
+	}
+
 	return 0;
 }
 #else
-- 
1.7.10.4

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

* [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (10 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 11/18] ARM: OMAP2+: Add device-tree support for NOR flash Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-18 14:07   ` Rob Herring
  2013-03-15 15:21 ` [PATCH V3 13/18] ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT Jon Hunter
                   ` (6 subsequent siblings)
  18 siblings, 1 reply; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

Some of the GPMC timings parameters are currently missing from the GPMC
device-tree binding. Add these parameters to the binding documentation
as well as code to read them.

The existing code in gpmc_read_timings_dt() is checking the value of
of_property_read_u32() and only is successful storing the value read
in the gpmc_timings structure. Checking the return value in this case
is not necessary and we can simply read the value, if present, and
store directly in the gpmc_timings structure. Therefore, simplify the
code by removing these checks.

The comment in the gpmc_read_timings_dt() function, "only for OMAP3430"
is also incorrect as it is applicable to all OMAP3+ devices. So correct
this too.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 Documentation/devicetree/bindings/bus/ti-gpmc.txt |   25 +++++-
 arch/arm/mach-omap2/gpmc.c                        |   93 ++++++++++-----------
 2 files changed, 66 insertions(+), 52 deletions(-)

diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
index 6fde1cf..a63bd93 100644
--- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt
+++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
@@ -56,10 +56,27 @@ Timing properties for child nodes. All are optional and default to 0.
  - gpmc,oe-off:		Deassertion time
 
  Access time and cycle time timings corresponding to GPMC_CONFIG5:
- - gpmc,page-burst-access: Multiple access word delay
- - gpmc,access:		Start-cycle to first data valid delay
- - gpmc,rd-cycle:	Total read cycle time
- - gpmc,wr-cycle:	Total write cycle time
+ - gpmc,page-burst-access: 	Multiple access word delay
+ - gpmc,access:			Start-cycle to first data valid delay
+ - gpmc,rd-cycle:		Total read cycle time
+ - gpmc,wr-cycle:		Total write cycle time
+ - gpmc,bus-turnaround:		Turn-around time between successive accesses
+ - gpmc,cycle2cycle-delay:	Delay between chip-select pulses
+ - gpmc,clk-activation: 	GPMC clock activation time
+ - gpmc,wait-monitoring:	Start of wait monitoring with regard to valid
+				data
+
+Boolean timing parameters. If property is present parameter enabled and
+disabled if omitted:
+ - gpmc,adv-extra-delay:	ADV signal is delayed by half GPMC clock
+ - gpmc,cs-extra-delay:		CS signal is delayed by half GPMC clock
+ - gpmc,cycle2cycle-diffcsen:	Add "cycle2cycle-delay" between successive
+				accesses to a different CS
+ - gpmc,cycle2cycle-samecsen:	Add "cycle2cycle-delay" between successive
+				accesses to the same CS
+ - gpmc,oe-extra-delay:		OE signal is delayed by half GPMC clock
+ - gpmc,we-extra-delay:		WE signal is delayed by half GPMC clock
+ - gpmc,time-para-granularity:	Multiply all access times by 2
 
 The following are only applicable to OMAP3+ and AM335x:
  - gpmc,wr-access
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 85b1a35..c928a8c 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1274,67 +1274,64 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
 static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 						struct gpmc_timings *gpmc_t)
 {
-	u32 val;
-
 	memset(gpmc_t, 0, sizeof(*gpmc_t));
 
 	/* minimum clock period for syncronous mode */
-	if (!of_property_read_u32(np, "gpmc,sync-clk", &val))
-		gpmc_t->sync_clk = val;
+	of_property_read_u32(np, "gpmc,sync-clk", &gpmc_t->sync_clk);
 
 	/* chip select timtings */
-	if (!of_property_read_u32(np, "gpmc,cs-on", &val))
-		gpmc_t->cs_on = val;
-
-	if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val))
-		gpmc_t->cs_rd_off = val;
-
-	if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val))
-		gpmc_t->cs_wr_off = val;
+	of_property_read_u32(np, "gpmc,cs-on", &gpmc_t->cs_on);
+	of_property_read_u32(np, "gpmc,cs-rd-off", &gpmc_t->cs_rd_off);
+	of_property_read_u32(np, "gpmc,cs-wr-off", &gpmc_t->cs_wr_off);
 
 	/* ADV signal timings */
-	if (!of_property_read_u32(np, "gpmc,adv-on", &val))
-		gpmc_t->adv_on = val;
-
-	if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val))
-		gpmc_t->adv_rd_off = val;
-
-	if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val))
-		gpmc_t->adv_wr_off = val;
+	of_property_read_u32(np, "gpmc,adv-on", &gpmc_t->adv_on);
+	of_property_read_u32(np, "gpmc,adv-rd-off", &gpmc_t->adv_rd_off);
+	of_property_read_u32(np, "gpmc,adv-wr-off", &gpmc_t->adv_wr_off);
 
 	/* WE signal timings */
-	if (!of_property_read_u32(np, "gpmc,we-on", &val))
-		gpmc_t->we_on = val;
-
-	if (!of_property_read_u32(np, "gpmc,we-off", &val))
-		gpmc_t->we_off = val;
+	of_property_read_u32(np, "gpmc,we-on", &gpmc_t->we_on);
+	of_property_read_u32(np, "gpmc,we-off", &gpmc_t->we_off);
 
 	/* OE signal timings */
-	if (!of_property_read_u32(np, "gpmc,oe-on", &val))
-		gpmc_t->oe_on = val;
-
-	if (!of_property_read_u32(np, "gpmc,oe-off", &val))
-		gpmc_t->oe_off = val;
+	of_property_read_u32(np, "gpmc,oe-on", &gpmc_t->oe_on);
+	of_property_read_u32(np, "gpmc,oe-off", &gpmc_t->oe_off);
 
 	/* access and cycle timings */
-	if (!of_property_read_u32(np, "gpmc,page-burst-access", &val))
-		gpmc_t->page_burst_access = val;
-
-	if (!of_property_read_u32(np, "gpmc,access", &val))
-		gpmc_t->access = val;
-
-	if (!of_property_read_u32(np, "gpmc,rd-cycle", &val))
-		gpmc_t->rd_cycle = val;
-
-	if (!of_property_read_u32(np, "gpmc,wr-cycle", &val))
-		gpmc_t->wr_cycle = val;
-
-	/* only for OMAP3430 */
-	if (!of_property_read_u32(np, "gpmc,wr-access", &val))
-		gpmc_t->wr_access = val;
-
-	if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val))
-		gpmc_t->wr_data_mux_bus = val;
+	of_property_read_u32(np, "gpmc,page-burst-access",
+			     &gpmc_t->page_burst_access);
+	of_property_read_u32(np, "gpmc,access", &gpmc_t->access);
+	of_property_read_u32(np, "gpmc,rd-cycle", &gpmc_t->rd_cycle);
+	of_property_read_u32(np, "gpmc,wr-cycle", &gpmc_t->wr_cycle);
+	of_property_read_u32(np, "gpmc,bus-turnaround",
+			     &gpmc_t->bus_turnaround);
+	of_property_read_u32(np, "gpmc,cycle2cycle-delay",
+			     &gpmc_t->cycle2cycle_delay);
+	of_property_read_u32(np, "gpmc,wait-monitoring",
+			     &gpmc_t->wait_monitoring);
+	of_property_read_u32(np, "gpmc,clk-activation",
+			     &gpmc_t->clk_activation);
+
+	/* only applicable to OMAP3+ */
+	of_property_read_u32(np, "gpmc,wr-access", &gpmc_t->wr_access);
+	of_property_read_u32(np, "gpmc,wr-data-mux-bus",
+			     &gpmc_t->wr_data_mux_bus);
+
+	/* bool timing parameters */
+	if (of_find_property(np, "gpmc,cycle2cycle-diffcsen", NULL))
+		gpmc_t->bool_timings.cycle2cyclediffcsen = true;
+	if (of_find_property(np, "gpmc,cycle2cycle-samecsen", NULL))
+		gpmc_t->bool_timings.cycle2cyclesamecsen = true;
+	if (of_find_property(np, "gpmc,we-extra-delay", NULL))
+		gpmc_t->bool_timings.we_extra_delay = true;
+	if (of_find_property(np, "gpmc,oe-extra-delay", NULL))
+		gpmc_t->bool_timings.oe_extra_delay = true;
+	if (of_find_property(np, "gpmc,adv-extra-delay", NULL))
+		gpmc_t->bool_timings.adv_extra_delay = true;
+	if (of_find_property(np, "gpmc,cs-extra-delay", NULL))
+		gpmc_t->bool_timings.cs_extra_delay = true;
+	if (of_find_property(np, "gpmc,time-para-granularity", NULL))
+		gpmc_t->bool_timings.time_para_granularity = true;
 }
 
 #ifdef CONFIG_MTD_NAND
-- 
1.7.10.4

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

* [PATCH V3 13/18] ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (11 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 14/18] ARM: OMAP2+: Convert ONENAND " Jon Hunter
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

When booting with device-tree, retrieve GPMC settings for NAND from
the device-tree blob. This will allow us to remove all static settings
stored in the gpmc-nand.c in the future once the migration to
device-tree is complete.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc-nand.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 12e9753..d9c2719 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -137,12 +137,16 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 			return err;
 		}
 
-		s.device_nand = true;
-
-		/* Enable RD PIN Monitoring Reg */
-		if (gpmc_nand_data->dev_ready) {
-			s.wait_on_read = true;
-			s.wait_on_write = true;
+		if (gpmc_nand_data->of_node) {
+			gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
+		} else {
+			s.device_nand = true;
+
+			/* Enable RD PIN Monitoring Reg */
+			if (gpmc_nand_data->dev_ready) {
+				s.wait_on_read = true;
+				s.wait_on_write = true;
+			}
 		}
 
 		if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
-- 
1.7.10.4

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

* [PATCH V3 14/18] ARM: OMAP2+: Convert ONENAND to retrieve GPMC settings from DT
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (12 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 13/18] ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 15/18] ARM: OMAP2+: Detect incorrectly aligned GPMC base address Jon Hunter
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

When booting with device-tree, retrieve GPMC settings for ONENAND from
the device-tree blob. This will allow us to remove all static settings
stored in the gpmc-nand.c in the future once the migration to
device-tree is complete.

The user must now specify the ONENAND device width in the device-tree
binding so that the GPMC can be programmed correctly. Therefore, update
the device-tree binding documentation for ONENAND devices connected to
the GPMC to reflect this.

Please note that this does not include GPMC timings for ONENAND. The
timings are being calculated at runtime.

There is some legacy code that only enables read wait monitoring for
non-OMAP3 devices. There are no known OMAP3 device issues that prevent
this feature being enabled and so when booting with device-tree use the
wait-monitoring settings described in the device-tree blob.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 .../devicetree/bindings/mtd/gpmc-onenand.txt       |    3 +++
 arch/arm/mach-omap2/gpmc-onenand.c                 |   21 ++++++++++++++------
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
index deec9da..b752942 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
@@ -10,6 +10,8 @@ Documentation/devicetree/bindings/bus/ti-gpmc.txt
 Required properties:
 
  - reg:			The CS line the peripheral is connected to
+ - gpmc,device-width	Width of the ONENAND device connected to the GPMC
+			in bytes. Must be 1 or 2.
 
 Optional properties:
 
@@ -34,6 +36,7 @@ Example for an OMAP3430 board:
 
 		onenand at 0 {
 			reg = <0 0 0>; /* CS0, offset 0 */
+			gpmc,device-width = <2>;
 
 			#address-cells = <1>;
 			#size-cells = <1>;
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 46aac83..64b5a83 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -272,6 +272,10 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
 	struct gpmc_timings t;
 	int ret;
 
+	if (gpmc_onenand_data->of_node)
+		gpmc_read_settings_dt(gpmc_onenand_data->of_node,
+				      &onenand_async);
+
 	omap2_onenand_set_async_mode(onenand_base);
 
 	omap2_onenand_calc_async_timings(&t);
@@ -300,12 +304,17 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
 		set_onenand_cfg(onenand_base);
 	}
 
-	/*
-	 * FIXME: Appears to be legacy code from initial ONENAND commit.
-	 * Unclear what boards this is for and if this can be removed.
-	 */
-	if (!cpu_is_omap34xx())
-		onenand_sync.wait_on_read = true;
+	if (gpmc_onenand_data->of_node) {
+		gpmc_read_settings_dt(gpmc_onenand_data->of_node,
+				      &onenand_sync);
+	} else {
+		/*
+		 * FIXME: Appears to be legacy code from initial ONENAND commit.
+		 * Unclear what boards this is for and if this can be removed.
+		 */
+		if (!cpu_is_omap34xx())
+			onenand_sync.wait_on_read = true;
+	}
 
 	omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
 
-- 
1.7.10.4

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

* [PATCH V3 15/18] ARM: OMAP2+: Detect incorrectly aligned GPMC base address
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (13 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 14/18] ARM: OMAP2+: Convert ONENAND " Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 16/18] ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable Jon Hunter
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

Each GPMC chip-select can be configured to map 16MB, 32MB, 64MB or 128MB
of address space. The physical base address where a chip-select starts
is also configurable and must be aligned on a boundary that is equal to
or greater than the size of the address space mapped bt the chip-select.
When enabling a GPMC chip-select, ensure that the base address is aligned
to the appropriate boundary.

Reported-by: Mark Jackson <mpfj-list@mimc.co.uk>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |   22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index c928a8c..a6f2b71 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -403,11 +403,18 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	return 0;
 }
 
-static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
+static int gpmc_cs_enable_mem(int cs, u32 base, u32 size)
 {
 	u32 l;
 	u32 mask;
 
+	/*
+	 * Ensure that base address is aligned on a
+	 * boundary equal to or greater than size.
+	 */
+	if (base & (size - 1))
+		return -EINVAL;
+
 	mask = (1 << GPMC_SECTION_SHIFT) - size;
 	l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
 	l &= ~0x3f;
@@ -416,6 +423,8 @@ static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
 	l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
 	l |= GPMC_CONFIG7_CSVALID;
 	gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
+
+	return 0;
 }
 
 static void gpmc_cs_disable_mem(int cs)
@@ -526,7 +535,9 @@ static int gpmc_cs_remap(int cs, u32 base)
 	ret = gpmc_cs_insert_mem(cs, base, size);
 	if (ret < 0)
 		return ret;
-	gpmc_cs_enable_mem(cs, base, size);
+	ret = gpmc_cs_enable_mem(cs, base, size);
+	if (ret < 0)
+		return ret;
 
 	return 0;
 }
@@ -556,7 +567,12 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
 	if (r < 0)
 		goto out;
 
-	gpmc_cs_enable_mem(cs, res->start, resource_size(res));
+	r = gpmc_cs_enable_mem(cs, res->start, resource_size(res));
+	if (r < 0) {
+		release_resource(res);
+		goto out;
+	}
+
 	*base = res->start;
 	gpmc_cs_set_reserved(cs, 1);
 out:
-- 
1.7.10.4

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

* [PATCH V3 16/18] ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (14 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 15/18] ARM: OMAP2+: Detect incorrectly aligned GPMC base address Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 17/18] ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails Jon Hunter
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

With commit 21cc2bd (ARM: OMAP2+: Remove apollon board support) the
variable "boot_rom_space" is now not needed and the code surrounding
this variable can be cleaned up and simplified. Remove unnecessary
definitions and clean-up the comment as well.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index a6f2b71..5239d47 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -92,9 +92,7 @@
 #define GPMC_CS_SIZE		0x30
 #define	GPMC_BCH_SIZE		0x10
 
-#define GPMC_MEM_START		0x00000000
 #define GPMC_MEM_END		0x3FFFFFFF
-#define BOOT_ROM_SPACE		0x100000	/* 1MB */
 
 #define GPMC_CHUNK_SHIFT	24		/* 16 MB */
 #define GPMC_SECTION_SHIFT	28		/* 128 MB */
@@ -790,13 +788,13 @@ static void gpmc_mem_exit(void)
 static int gpmc_mem_init(void)
 {
 	int cs, rc;
-	unsigned long boot_rom_space = 0;
 
-	/* never allocate the first page, to facilitate bug detection;
-	 * even if we didn't boot from ROM.
+	/*
+	 * The first 1MB of GPMC address space is typically mapped to
+	 * the internal ROM. Never allocate the first page, to
+	 * facilitate bug detection; even if we didn't boot from ROM.
 	 */
-	boot_rom_space = BOOT_ROM_SPACE;
-	gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
+	gpmc_mem_root.start = SZ_1M;
 	gpmc_mem_root.end = GPMC_MEM_END;
 
 	/* Reserve all regions that has been set up by bootloader */
-- 
1.7.10.4

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

* [PATCH V3 17/18] ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (15 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 16/18] ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-15 15:21 ` [PATCH V3 18/18] ARM: OMAP2+: return -ENODEV if GPMC child device creation fails Jon Hunter
  2013-03-17  5:34 ` [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Ezequiel Garcia
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

When the GPMC driver is probed, we call gpmc_mem_init() to see which
chip-selects have already been configured and enabled by the boot-loader
and allocate space for them. If we fail to allocate space for one
chip-select, then we return failure from the probe and the GPMC driver
will not be available.

Rather than render the GPMC useless for all GPMC devices, if we fail to
allocate space for one chip-select print a warning and disable the
chip-select. This way other GPMC clients can still be used.

There is no downside to this approach, because all GPMC clients need to
request a chip-select before they can use the GPMC and on requesting a
chip-select, if memory has not already been reserved for the chip-select
then it will be.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |   24 +++++++-----------------
 1 file changed, 7 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 5239d47..ee6601c 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -785,9 +785,9 @@ static void gpmc_mem_exit(void)
 
 }
 
-static int gpmc_mem_init(void)
+static void gpmc_mem_init(void)
 {
-	int cs, rc;
+	int cs;
 
 	/*
 	 * The first 1MB of GPMC address space is typically mapped to
@@ -804,16 +804,12 @@ static int gpmc_mem_init(void)
 		if (!gpmc_cs_mem_enabled(cs))
 			continue;
 		gpmc_cs_get_memconf(cs, &base, &size);
-		rc = gpmc_cs_insert_mem(cs, base, size);
-		if (rc < 0) {
-			while (--cs >= 0)
-				if (gpmc_cs_mem_enabled(cs))
-					gpmc_cs_delete_mem(cs);
-			return rc;
+		if (gpmc_cs_insert_mem(cs, base, size)) {
+			pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n",
+				__func__, cs, base, base + size);
+			gpmc_cs_disable_mem(cs);
 		}
 	}
-
-	return 0;
 }
 
 static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
@@ -1620,13 +1616,7 @@ static int gpmc_probe(struct platform_device *pdev)
 	dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
 		 GPMC_REVISION_MINOR(l));
 
-	rc = gpmc_mem_init();
-	if (rc < 0) {
-		clk_disable_unprepare(gpmc_l3_clk);
-		clk_put(gpmc_l3_clk);
-		dev_err(gpmc_dev, "failed to reserve memory\n");
-		return rc;
-	}
+	gpmc_mem_init();
 
 	if (gpmc_setup_irq() < 0)
 		dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
-- 
1.7.10.4

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

* [PATCH V3 18/18] ARM: OMAP2+: return -ENODEV if GPMC child device creation fails
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (16 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 17/18] ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails Jon Hunter
@ 2013-03-15 15:21 ` Jon Hunter
  2013-03-17  5:34 ` [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Ezequiel Garcia
  18 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-15 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Javier Martinez Canillas <javier.martinez@collabora.co.uk>

gpmc_probe_nor_child() calls of_platform_device_create() to create a
platform device for the NOR child. If this function fails the value
of ret is returned to the caller but this value is zero since it was
assigned the return of a previous call to gpmc_cs_program_settings()
that had to succeed or otherwise gpmc_probe_nor_child() would have
returned before.

This means that if of_platform_device_create() fails, 0 will be returned
to the caller instead of an appropriate error code.

Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index ee6601c..d4ec5bb 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1504,6 +1504,7 @@ static int gpmc_probe_nor_child(struct platform_device *pdev,
 		return 0;
 
 	dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
+	ret = -ENODEV;
 
 err:
 	gpmc_cs_free(cs);
-- 
1.7.10.4

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

* [PATCH V3 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins
  2013-03-15 15:21 ` [PATCH V3 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins Jon Hunter
@ 2013-03-16 20:59   ` Ezequiel Garcia
  2013-03-18 13:43     ` Jon Hunter
  0 siblings, 1 reply; 27+ messages in thread
From: Ezequiel Garcia @ 2013-03-16 20:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

On Fri, Mar 15, 2013 at 10:21:00AM -0500, Jon Hunter wrote:
> The GPMC has wait-pin signals that can be assigned to a chip-select
> to monitor the ready signal of an external device. Add a variable to
> indicate the total number of wait-pins for a given device. This will
> allow us to detect if the wait-pin being selected is valid or not.
> 
> When booting with device-tree read the number of wait-pins from the
> device-tree blob. When device-tree is not used set the number of
> wait-pins to 4 which is valid for OMAP2-5 devices. Newer devices
> that have less wait-pins (such as AM335x) only support booting with
> device-tree and so hard-coding the wait-pin number when not using
> device-tree is fine.
> 
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---
>  arch/arm/mach-omap2/gpmc.c |   16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index ef655d9..88a261c 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -108,6 +108,8 @@
>  #define	GPMC_HAS_WR_ACCESS		0x1
>  #define	GPMC_HAS_WR_DATA_MUX_BUS	0x2
>  
> +#define GPMC_NR_WAITPINS		4
> +
>  /* XXX: Only NAND irq has been considered,currently these are the only ones used
>   */
>  #define	GPMC_NR_IRQ		2
> @@ -153,6 +155,7 @@ static struct resource	gpmc_cs_mem[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_nr_waitpins;
>  static struct device *gpmc_dev;
>  static int gpmc_irq;
>  static resource_size_t phys_base, mem_size;
> @@ -1297,6 +1300,13 @@ static int gpmc_probe_dt(struct platform_device *pdev)
>  	if (!of_id)
>  		return 0;
>  
> +	ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
> +				   &gpmc_nr_waitpins);
> +	if (ret < 0) {
> +		pr_err("%s: number of wait pins not found!\n", __func__);
> +		return ret;
> +	}
> +
>  	for_each_node_by_name(child, "nand") {
>  		ret = gpmc_probe_nand_child(pdev, child);
>  		if (ret < 0) {
> @@ -1372,6 +1382,12 @@ 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;

The above seems to be a remanent of another patch.
I think you already sent that one, right?

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

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

* [PATCH V3 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree
  2013-03-15 15:21 ` [PATCH V3 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree Jon Hunter
@ 2013-03-17  5:24   ` Ezequiel Garcia
  2013-03-18 13:43     ` Jon Hunter
  0 siblings, 1 reply; 27+ messages in thread
From: Ezequiel Garcia @ 2013-03-17  5:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

I have some tiny nitpicks...

On Fri, Mar 15, 2013 at 10:21:08AM -0500, Jon Hunter wrote:
> Adds a function to read the various GPMC chip-select settings from
> device-tree and store them in the gpmc_settings structure.
> 
> Update the GPMC device-tree binding documentation to describe these
> options.
> 
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---
>  Documentation/devicetree/bindings/bus/ti-gpmc.txt |   23 ++++++++++
>  arch/arm/mach-omap2/gpmc.c                        |   49 +++++++++++++++++++++
>  arch/arm/mach-omap2/gpmc.h                        |    2 +
>  3 files changed, 74 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
> index 5ddb2e9..6fde1cf 100644
> --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt
> +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
> @@ -65,6 +65,29 @@ The following are only applicable to OMAP3+ and AM335x:
>   - gpmc,wr-access
>   - gpmc,wr-data-mux-bus
>  
> +GPMC chip-select settings properties for child nodes. All are optional.
> +
> +- gpmc,burst-length	Page/burst length. Must be 4, 8 or 16.
> +- gpmc,burst-wrap	Enables wrap bursting
> +- gpmc,burst-read	Enables read page/burst mode
> +- gpmc,burst-write	Enables write page/burst mode
> +- gpmc,device-nand	Device is NAND
> +- gpmc,device-width	Total width of device(s) connected to a GPMC
> +			chip-select in bytes. The GPMC supports 8-bit
> +			and 16-bit devices and so this property must be
> +			1 or 2.
> +- gpmc,mux-add-data	Address and data multiplexing configuration.
> +			Valid values are 1 for address-address-data
> +			multiplexing mode and 2 for address-data
> +			multiplexing mode.
> +- gpmc,sync-read	Enables synchronous read. Defaults to asynchronous
> +			is this is not set.
> +- gpmc,sync-write	Enables synchronous writes. Defaults to asynchronous
> +			is this is not set.
> +- gpmc,wait-pin		Wait-pin used by client. Must be less than
> +			"gpmc,num-waitpins".
> +- gpmc,wait-on-read	Enables wait monitoring on reads.
> +- gpmc,wait-on-write	Enables wait monitoring on writes.
>  
>  Example for an AM33xx board:
>  
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 3ec1937..1e7eef3 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -1190,6 +1190,55 @@ static struct of_device_id gpmc_dt_ids[] = {
>  };
>  MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
>  
> +/**
> + * gpmc_read_settings_dt - read gpmc settings from device-tree
> + * @np:		pointer to device-tree node for a gpmc child device
> + * @p:		pointer to gpmc settings structure
> + *
> + * Reads the GPMC settings for a GPMC child device from device-tree and
> + * stores them in the GPMC settings structure passed. The GPMC settings
> + * structure is initialise to zero by this function and so any previously

s/initialise/initialized ?

> + * stored settings will be clearer.

s/clearer/cleared ?

I'm not an english native speaker,
so please bare with me if I'm wrong on these...

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

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

* [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update
  2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
                   ` (17 preceding siblings ...)
  2013-03-15 15:21 ` [PATCH V3 18/18] ARM: OMAP2+: return -ENODEV if GPMC child device creation fails Jon Hunter
@ 2013-03-17  5:34 ` Ezequiel Garcia
  18 siblings, 0 replies; 27+ messages in thread
From: Ezequiel Garcia @ 2013-03-17  5:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 15, 2013 at 10:20:58AM -0500, Jon Hunter wrote:
> While adding device-tree support for NOR memories, it became apparent
> that there is no common way for configuring various GPMC settings for
> devices that interface to the GPMC. These settings include bus-width,
> synchronous/asynchronous mode, burst settings, wait monitoring etc.
> Therefore, to simplify the GPMC code and add device-tree support for
> NOR, it was first necessary to consolidate how these settings are
> programmed.
> 
> Series based upon Mark Jackson's patch [1] and Ezequiel Garcia GPMC
> clean-up series [2]. Entire series available here [3].
> 
> V3 changes:
> - Rebased on RMK's IS_ERR_VALUE() patch and removed usage of
>   IS_ERR_VALUE() from series.
> - Fixed BUG in NAND code introduced in V2 by making gpmc_settings
>   structure a local variable (I forgot to initialise structure to zero).
> - Added fix from Javier to correct return value from gpmc_probe_nor().
> 
> V2 changes:
> - Made gpmc_settings structure local in gpmc_nand_init().
> - Use resource_size() API in probe_nor().
> - Add kernel-doc for gpmc_cs_program_settings() function.
> - Use of_platform_device_create() to register NOR devices in probe_nor().
> - Add support for GPMC address-address-data multiplexing which required
>   changing GPMC DT property "gpmc,mux-add-data" to store a 32-bit value
>   and changing mux_add_data member of gpmc_settings to be a 32-bit type
>   instead of bool.
> - Add detection for incorrect GPMC chip-select base addresses.
> - Cleaned-up code in gpmc_mem_init() and changed gpmc_mem_init() so that
>   it would not return an error when the GPMC driver is being probed.
> 
> V1 changes:
> - Clean-up/simplification of ONENAND initialisation code.
> - Add a new GPMC structure to unify storage of various GPMC settings
>   (that are non-timing related) for client devices and add a new
>   function to program these settings in a common way.
> - Migrate initialisation code for existing flash, usb and networking
>   devices to use the new structure and function for GPMC settings.
> - Add device-tree support for NOR flash memories.
> - Add additional GPMC timing parameters to GPMC device-tree binding.
> - Update GPMC NAND and ONENAND device-tree support to retrieve GPMC
>   settings from device-tree.
> 
> Testing includes:
> - Boot testing on OMAP2420 H4, OMAP3430 SDP and OMAP4430 SDP with
>   and without device-tree present.
> - OMAP2420 H4 board has NOR flash and OMAP3430 SDP has NOR, NAND
>   and ONENAND flash. So verified that flash is detected on boot
>   as expected. Note additional patches [4] are required for OMAP2420
>   H4 and OMAP3430 SDP dts files in order to enable flash memory
>   support.
> - All of the above boards use GPMC for interfacing to a networking
>   chip and so verified that networking is working wit this series.
>   However, please note that networking is not currently supported
>   on these boards when booting with DT and so networking is only
>   tested without DT.
> 
> [1] http://permalink.gmane.org/gmane.linux.ports.arm.omap/94765
> [2] http://comments.gmane.org/gmane.linux.ports.arm.omap/93784
> [3] https://github.com/jonhunter/linux/tree/omap-gpmc-for-v3.10
> [4] https://github.com/jonhunter/linux/tree/omap-dt-for-v3.10
> 
> Javier Martinez Canillas (1):
>   ARM: OMAP2+: return -ENODEV if GPMC child device creation fails
> 
> Jon Hunter (17):
>   ARM: OMAP2+: Simplify code configuring ONENAND devices
>   ARM: OMAP2+: Add variable to store number of GPMC waitpins
>   ARM: OMAP2+: Add structure for storing GPMC settings
>   ARM: OMAP2+: Add function for configuring GPMC settings
>   ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings()
>   ARM: OMAP2+: Convert NAND to use gpmc_cs_program_settings()
>   ARM: OMAP2+: Convert SMC91x to use gpmc_cs_program_settings()
>   ARM: OMAP2+: Convert TUSB to use gpmc_cs_program_settings()
>   ARM: OMAP2+: Don't configure of chip-select options in
>     gpmc_cs_configure()
>   ARM: OMAP2+: Add function to read GPMC settings from device-tree
>   ARM: OMAP2+: Add device-tree support for NOR flash
>   ARM: OMAP2+: Add additional GPMC timing parameters
>   ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT
>   ARM: OMAP2+: Convert ONENAND to retrieve GPMC settings from DT
>   ARM: OMAP2+: Detect incorrectly aligned GPMC base address
>   ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable
>   ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails
> 
>  Documentation/devicetree/bindings/bus/ti-gpmc.txt  |   48 +-
>  Documentation/devicetree/bindings/mtd/gpmc-nor.txt |   98 ++++
>  .../devicetree/bindings/mtd/gpmc-onenand.txt       |    3 +
>  arch/arm/mach-omap2/gpmc-nand.c                    |   39 +-
>  arch/arm/mach-omap2/gpmc-onenand.c                 |  110 ++--
>  arch/arm/mach-omap2/gpmc-smc91x.c                  |   30 +-
>  arch/arm/mach-omap2/gpmc.c                         |  524 +++++++++++++++-----
>  arch/arm/mach-omap2/gpmc.h                         |   37 +-
>  arch/arm/mach-omap2/usb-tusb6010.c                 |   62 ++-
>  9 files changed, 691 insertions(+), 260 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt
> 
> -- 
> 1.7.10.4
> 

Looks really good!

FWIW, On my OMAP3630 (IGEPv2) board, both DT and non-DT
booted and read the OneNAND device.

Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>

Thanks,
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

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

* [PATCH V3 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree
  2013-03-17  5:24   ` Ezequiel Garcia
@ 2013-03-18 13:43     ` Jon Hunter
  0 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-18 13:43 UTC (permalink / raw)
  To: linux-arm-kernel


On 03/17/2013 12:24 AM, Ezequiel Garcia wrote:
> Hi Jon,
> 
> I have some tiny nitpicks...
> 
> On Fri, Mar 15, 2013 at 10:21:08AM -0500, Jon Hunter wrote:
>> Adds a function to read the various GPMC chip-select settings from
>> device-tree and store them in the gpmc_settings structure.
>>
>> Update the GPMC device-tree binding documentation to describe these
>> options.
>>
>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>> ---
>>  Documentation/devicetree/bindings/bus/ti-gpmc.txt |   23 ++++++++++
>>  arch/arm/mach-omap2/gpmc.c                        |   49 +++++++++++++++++++++
>>  arch/arm/mach-omap2/gpmc.h                        |    2 +
>>  3 files changed, 74 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
>> index 5ddb2e9..6fde1cf 100644
>> --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt
>> +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
>> @@ -65,6 +65,29 @@ The following are only applicable to OMAP3+ and AM335x:
>>   - gpmc,wr-access
>>   - gpmc,wr-data-mux-bus
>>  
>> +GPMC chip-select settings properties for child nodes. All are optional.
>> +
>> +- gpmc,burst-length	Page/burst length. Must be 4, 8 or 16.
>> +- gpmc,burst-wrap	Enables wrap bursting
>> +- gpmc,burst-read	Enables read page/burst mode
>> +- gpmc,burst-write	Enables write page/burst mode
>> +- gpmc,device-nand	Device is NAND
>> +- gpmc,device-width	Total width of device(s) connected to a GPMC
>> +			chip-select in bytes. The GPMC supports 8-bit
>> +			and 16-bit devices and so this property must be
>> +			1 or 2.
>> +- gpmc,mux-add-data	Address and data multiplexing configuration.
>> +			Valid values are 1 for address-address-data
>> +			multiplexing mode and 2 for address-data
>> +			multiplexing mode.
>> +- gpmc,sync-read	Enables synchronous read. Defaults to asynchronous
>> +			is this is not set.
>> +- gpmc,sync-write	Enables synchronous writes. Defaults to asynchronous
>> +			is this is not set.
>> +- gpmc,wait-pin		Wait-pin used by client. Must be less than
>> +			"gpmc,num-waitpins".
>> +- gpmc,wait-on-read	Enables wait monitoring on reads.
>> +- gpmc,wait-on-write	Enables wait monitoring on writes.
>>  
>>  Example for an AM33xx board:
>>  
>> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
>> index 3ec1937..1e7eef3 100644
>> --- a/arch/arm/mach-omap2/gpmc.c
>> +++ b/arch/arm/mach-omap2/gpmc.c
>> @@ -1190,6 +1190,55 @@ static struct of_device_id gpmc_dt_ids[] = {
>>  };
>>  MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
>>  
>> +/**
>> + * gpmc_read_settings_dt - read gpmc settings from device-tree
>> + * @np:		pointer to device-tree node for a gpmc child device
>> + * @p:		pointer to gpmc settings structure
>> + *
>> + * Reads the GPMC settings for a GPMC child device from device-tree and
>> + * stores them in the GPMC settings structure passed. The GPMC settings
>> + * structure is initialise to zero by this function and so any previously
> 
> s/initialise/initialized ?

Thanks will add the "d". However, "initialise" is correct British
English ;-)

>> + * stored settings will be clearer.
> 
> s/clearer/cleared ?
> 
> I'm not an english native speaker,
> so please bare with me if I'm wrong on these...

You are right here too. Will fix thanks!

Jon

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

* [PATCH V3 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins
  2013-03-16 20:59   ` Ezequiel Garcia
@ 2013-03-18 13:43     ` Jon Hunter
  0 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-18 13:43 UTC (permalink / raw)
  To: linux-arm-kernel



On 03/16/2013 03:59 PM, Ezequiel Garcia wrote:
> Hi Jon,
> 
> On Fri, Mar 15, 2013 at 10:21:00AM -0500, Jon Hunter wrote:
>> The GPMC has wait-pin signals that can be assigned to a chip-select
>> to monitor the ready signal of an external device. Add a variable to
>> indicate the total number of wait-pins for a given device. This will
>> allow us to detect if the wait-pin being selected is valid or not.
>>
>> When booting with device-tree read the number of wait-pins from the
>> device-tree blob. When device-tree is not used set the number of
>> wait-pins to 4 which is valid for OMAP2-5 devices. Newer devices
>> that have less wait-pins (such as AM335x) only support booting with
>> device-tree and so hard-coding the wait-pin number when not using
>> device-tree is fine.
>>
>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>> ---
>>  arch/arm/mach-omap2/gpmc.c |   16 ++++++++++++++++
>>  1 file changed, 16 insertions(+)
>>
>> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
>> index ef655d9..88a261c 100644
>> --- a/arch/arm/mach-omap2/gpmc.c
>> +++ b/arch/arm/mach-omap2/gpmc.c
>> @@ -108,6 +108,8 @@
>>  #define	GPMC_HAS_WR_ACCESS		0x1
>>  #define	GPMC_HAS_WR_DATA_MUX_BUS	0x2
>>  
>> +#define GPMC_NR_WAITPINS		4
>> +
>>  /* XXX: Only NAND irq has been considered,currently these are the only ones used
>>   */
>>  #define	GPMC_NR_IRQ		2
>> @@ -153,6 +155,7 @@ static struct resource	gpmc_cs_mem[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_nr_waitpins;
>>  static struct device *gpmc_dev;
>>  static int gpmc_irq;
>>  static resource_size_t phys_base, mem_size;
>> @@ -1297,6 +1300,13 @@ static int gpmc_probe_dt(struct platform_device *pdev)
>>  	if (!of_id)
>>  		return 0;
>>  
>> +	ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
>> +				   &gpmc_nr_waitpins);
>> +	if (ret < 0) {
>> +		pr_err("%s: number of wait pins not found!\n", __func__);
>> +		return ret;
>> +	}
>> +
>>  	for_each_node_by_name(child, "nand") {
>>  		ret = gpmc_probe_nand_child(pdev, child);
>>  		if (ret < 0) {
>> @@ -1372,6 +1382,12 @@ 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;
> 
> The above seems to be a remanent of another patch.
> I think you already sent that one, right?

Good catch. I will fix this up.

Jon

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

* [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters
  2013-03-15 15:21 ` [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters Jon Hunter
@ 2013-03-18 14:07   ` Rob Herring
  2013-03-18 14:32     ` Jon Hunter
  0 siblings, 1 reply; 27+ messages in thread
From: Rob Herring @ 2013-03-18 14:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/15/2013 10:21 AM, Jon Hunter wrote:
> Some of the GPMC timings parameters are currently missing from the GPMC
> device-tree binding. Add these parameters to the binding documentation
> as well as code to read them.
> 
> The existing code in gpmc_read_timings_dt() is checking the value of
> of_property_read_u32() and only is successful storing the value read
> in the gpmc_timings structure. Checking the return value in this case
> is not necessary and we can simply read the value, if present, and
> store directly in the gpmc_timings structure. Therefore, simplify the
> code by removing these checks.
> 
> The comment in the gpmc_read_timings_dt() function, "only for OMAP3430"
> is also incorrect as it is applicable to all OMAP3+ devices. So correct
> this too.
> 
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---
>  Documentation/devicetree/bindings/bus/ti-gpmc.txt |   25 +++++-
>  arch/arm/mach-omap2/gpmc.c                        |   93 ++++++++++-----------
>  2 files changed, 66 insertions(+), 52 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
> index 6fde1cf..a63bd93 100644
> --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt
> +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
> @@ -56,10 +56,27 @@ Timing properties for child nodes. All are optional and default to 0.
>   - gpmc,oe-off:		Deassertion time
>  
>   Access time and cycle time timings corresponding to GPMC_CONFIG5:
> - - gpmc,page-burst-access: Multiple access word delay
> - - gpmc,access:		Start-cycle to first data valid delay
> - - gpmc,rd-cycle:	Total read cycle time
> - - gpmc,wr-cycle:	Total write cycle time
> + - gpmc,page-burst-access: 	Multiple access word delay
> + - gpmc,access:			Start-cycle to first data valid delay
> + - gpmc,rd-cycle:		Total read cycle time
> + - gpmc,wr-cycle:		Total write cycle time
> + - gpmc,bus-turnaround:		Turn-around time between successive accesses
> + - gpmc,cycle2cycle-delay:	Delay between chip-select pulses
> + - gpmc,clk-activation: 	GPMC clock activation time
> + - gpmc,wait-monitoring:	Start of wait monitoring with regard to valid
> +				data

What units are these in? If in nanoseconds, can you append "-ns"

> +
> +Boolean timing parameters. If property is present parameter enabled and
> +disabled if omitted:
> + - gpmc,adv-extra-delay:	ADV signal is delayed by half GPMC clock
> + - gpmc,cs-extra-delay:		CS signal is delayed by half GPMC clock
> + - gpmc,cycle2cycle-diffcsen:	Add "cycle2cycle-delay" between successive
> +				accesses to a different CS
> + - gpmc,cycle2cycle-samecsen:	Add "cycle2cycle-delay" between successive
> +				accesses to the same CS
> + - gpmc,oe-extra-delay:		OE signal is delayed by half GPMC clock
> + - gpmc,we-extra-delay:		WE signal is delayed by half GPMC clock
> + - gpmc,time-para-granularity:	Multiply all access times by 2
>  
>  The following are only applicable to OMAP3+ and AM335x:
>   - gpmc,wr-access
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 85b1a35..c928a8c 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -1274,67 +1274,64 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
>  static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>  						struct gpmc_timings *gpmc_t)
>  {
> -	u32 val;
> -
>  	memset(gpmc_t, 0, sizeof(*gpmc_t));
>  
>  	/* minimum clock period for syncronous mode */
> -	if (!of_property_read_u32(np, "gpmc,sync-clk", &val))
> -		gpmc_t->sync_clk = val;
> +	of_property_read_u32(np, "gpmc,sync-clk", &gpmc_t->sync_clk);
>  
>  	/* chip select timtings */
> -	if (!of_property_read_u32(np, "gpmc,cs-on", &val))
> -		gpmc_t->cs_on = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val))
> -		gpmc_t->cs_rd_off = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val))
> -		gpmc_t->cs_wr_off = val;
> +	of_property_read_u32(np, "gpmc,cs-on", &gpmc_t->cs_on);
> +	of_property_read_u32(np, "gpmc,cs-rd-off", &gpmc_t->cs_rd_off);
> +	of_property_read_u32(np, "gpmc,cs-wr-off", &gpmc_t->cs_wr_off);
>  
>  	/* ADV signal timings */
> -	if (!of_property_read_u32(np, "gpmc,adv-on", &val))
> -		gpmc_t->adv_on = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val))
> -		gpmc_t->adv_rd_off = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val))
> -		gpmc_t->adv_wr_off = val;
> +	of_property_read_u32(np, "gpmc,adv-on", &gpmc_t->adv_on);
> +	of_property_read_u32(np, "gpmc,adv-rd-off", &gpmc_t->adv_rd_off);
> +	of_property_read_u32(np, "gpmc,adv-wr-off", &gpmc_t->adv_wr_off);
>  
>  	/* WE signal timings */
> -	if (!of_property_read_u32(np, "gpmc,we-on", &val))
> -		gpmc_t->we_on = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,we-off", &val))
> -		gpmc_t->we_off = val;
> +	of_property_read_u32(np, "gpmc,we-on", &gpmc_t->we_on);
> +	of_property_read_u32(np, "gpmc,we-off", &gpmc_t->we_off);
>  
>  	/* OE signal timings */
> -	if (!of_property_read_u32(np, "gpmc,oe-on", &val))
> -		gpmc_t->oe_on = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,oe-off", &val))
> -		gpmc_t->oe_off = val;
> +	of_property_read_u32(np, "gpmc,oe-on", &gpmc_t->oe_on);
> +	of_property_read_u32(np, "gpmc,oe-off", &gpmc_t->oe_off);
>  
>  	/* access and cycle timings */
> -	if (!of_property_read_u32(np, "gpmc,page-burst-access", &val))
> -		gpmc_t->page_burst_access = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,access", &val))
> -		gpmc_t->access = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,rd-cycle", &val))
> -		gpmc_t->rd_cycle = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,wr-cycle", &val))
> -		gpmc_t->wr_cycle = val;
> -
> -	/* only for OMAP3430 */
> -	if (!of_property_read_u32(np, "gpmc,wr-access", &val))
> -		gpmc_t->wr_access = val;
> -
> -	if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val))
> -		gpmc_t->wr_data_mux_bus = val;
> +	of_property_read_u32(np, "gpmc,page-burst-access",
> +			     &gpmc_t->page_burst_access);
> +	of_property_read_u32(np, "gpmc,access", &gpmc_t->access);
> +	of_property_read_u32(np, "gpmc,rd-cycle", &gpmc_t->rd_cycle);
> +	of_property_read_u32(np, "gpmc,wr-cycle", &gpmc_t->wr_cycle);
> +	of_property_read_u32(np, "gpmc,bus-turnaround",
> +			     &gpmc_t->bus_turnaround);
> +	of_property_read_u32(np, "gpmc,cycle2cycle-delay",
> +			     &gpmc_t->cycle2cycle_delay);
> +	of_property_read_u32(np, "gpmc,wait-monitoring",
> +			     &gpmc_t->wait_monitoring);
> +	of_property_read_u32(np, "gpmc,clk-activation",
> +			     &gpmc_t->clk_activation);
> +
> +	/* only applicable to OMAP3+ */
> +	of_property_read_u32(np, "gpmc,wr-access", &gpmc_t->wr_access);
> +	of_property_read_u32(np, "gpmc,wr-data-mux-bus",
> +			     &gpmc_t->wr_data_mux_bus);
> +
> +	/* bool timing parameters */
> +	if (of_find_property(np, "gpmc,cycle2cycle-diffcsen", NULL))
> +		gpmc_t->bool_timings.cycle2cyclediffcsen = true;
> +	if (of_find_property(np, "gpmc,cycle2cycle-samecsen", NULL))
> +		gpmc_t->bool_timings.cycle2cyclesamecsen = true;
> +	if (of_find_property(np, "gpmc,we-extra-delay", NULL))
> +		gpmc_t->bool_timings.we_extra_delay = true;
> +	if (of_find_property(np, "gpmc,oe-extra-delay", NULL))
> +		gpmc_t->bool_timings.oe_extra_delay = true;
> +	if (of_find_property(np, "gpmc,adv-extra-delay", NULL))
> +		gpmc_t->bool_timings.adv_extra_delay = true;
> +	if (of_find_property(np, "gpmc,cs-extra-delay", NULL))
> +		gpmc_t->bool_timings.cs_extra_delay = true;
> +	if (of_find_property(np, "gpmc,time-para-granularity", NULL))
> +		gpmc_t->bool_timings.time_para_granularity = true;

of_property_read_bool doesn't work for these?

Rob

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

* [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters
  2013-03-18 14:07   ` Rob Herring
@ 2013-03-18 14:32     ` Jon Hunter
  2013-03-18 15:59       ` Jon Hunter
  0 siblings, 1 reply; 27+ messages in thread
From: Jon Hunter @ 2013-03-18 14:32 UTC (permalink / raw)
  To: linux-arm-kernel


On 03/18/2013 09:07 AM, Rob Herring wrote:
> On 03/15/2013 10:21 AM, Jon Hunter wrote:
>> Some of the GPMC timings parameters are currently missing from the GPMC
>> device-tree binding. Add these parameters to the binding documentation
>> as well as code to read them.
>>
>> The existing code in gpmc_read_timings_dt() is checking the value of
>> of_property_read_u32() and only is successful storing the value read
>> in the gpmc_timings structure. Checking the return value in this case
>> is not necessary and we can simply read the value, if present, and
>> store directly in the gpmc_timings structure. Therefore, simplify the
>> code by removing these checks.
>>
>> The comment in the gpmc_read_timings_dt() function, "only for OMAP3430"
>> is also incorrect as it is applicable to all OMAP3+ devices. So correct
>> this too.
>>
>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>> ---
>>  Documentation/devicetree/bindings/bus/ti-gpmc.txt |   25 +++++-
>>  arch/arm/mach-omap2/gpmc.c                        |   93 ++++++++++-----------
>>  2 files changed, 66 insertions(+), 52 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
>> index 6fde1cf..a63bd93 100644
>> --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt
>> +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
>> @@ -56,10 +56,27 @@ Timing properties for child nodes. All are optional and default to 0.
>>   - gpmc,oe-off:		Deassertion time
>>  
>>   Access time and cycle time timings corresponding to GPMC_CONFIG5:
>> - - gpmc,page-burst-access: Multiple access word delay
>> - - gpmc,access:		Start-cycle to first data valid delay
>> - - gpmc,rd-cycle:	Total read cycle time
>> - - gpmc,wr-cycle:	Total write cycle time
>> + - gpmc,page-burst-access: 	Multiple access word delay
>> + - gpmc,access:			Start-cycle to first data valid delay
>> + - gpmc,rd-cycle:		Total read cycle time
>> + - gpmc,wr-cycle:		Total write cycle time
>> + - gpmc,bus-turnaround:		Turn-around time between successive accesses
>> + - gpmc,cycle2cycle-delay:	Delay between chip-select pulses
>> + - gpmc,clk-activation: 	GPMC clock activation time
>> + - gpmc,wait-monitoring:	Start of wait monitoring with regard to valid
>> +				data
> 
> What units are these in? If in nanoseconds, can you append "-ns"

These are cycles. I can update the comment to reflect that.

>> +
>> +Boolean timing parameters. If property is present parameter enabled and
>> +disabled if omitted:
>> + - gpmc,adv-extra-delay:	ADV signal is delayed by half GPMC clock
>> + - gpmc,cs-extra-delay:		CS signal is delayed by half GPMC clock
>> + - gpmc,cycle2cycle-diffcsen:	Add "cycle2cycle-delay" between successive
>> +				accesses to a different CS
>> + - gpmc,cycle2cycle-samecsen:	Add "cycle2cycle-delay" between successive
>> +				accesses to the same CS
>> + - gpmc,oe-extra-delay:		OE signal is delayed by half GPMC clock
>> + - gpmc,we-extra-delay:		WE signal is delayed by half GPMC clock
>> + - gpmc,time-para-granularity:	Multiply all access times by 2
>>  
>>  The following are only applicable to OMAP3+ and AM335x:
>>   - gpmc,wr-access
>> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
>> index 85b1a35..c928a8c 100644
>> --- a/arch/arm/mach-omap2/gpmc.c
>> +++ b/arch/arm/mach-omap2/gpmc.c
>> @@ -1274,67 +1274,64 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
>>  static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>>  						struct gpmc_timings *gpmc_t)
>>  {
>> -	u32 val;
>> -
>>  	memset(gpmc_t, 0, sizeof(*gpmc_t));
>>  
>>  	/* minimum clock period for syncronous mode */
>> -	if (!of_property_read_u32(np, "gpmc,sync-clk", &val))
>> -		gpmc_t->sync_clk = val;
>> +	of_property_read_u32(np, "gpmc,sync-clk", &gpmc_t->sync_clk);
>>  
>>  	/* chip select timtings */
>> -	if (!of_property_read_u32(np, "gpmc,cs-on", &val))
>> -		gpmc_t->cs_on = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val))
>> -		gpmc_t->cs_rd_off = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val))
>> -		gpmc_t->cs_wr_off = val;
>> +	of_property_read_u32(np, "gpmc,cs-on", &gpmc_t->cs_on);
>> +	of_property_read_u32(np, "gpmc,cs-rd-off", &gpmc_t->cs_rd_off);
>> +	of_property_read_u32(np, "gpmc,cs-wr-off", &gpmc_t->cs_wr_off);
>>  
>>  	/* ADV signal timings */
>> -	if (!of_property_read_u32(np, "gpmc,adv-on", &val))
>> -		gpmc_t->adv_on = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val))
>> -		gpmc_t->adv_rd_off = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val))
>> -		gpmc_t->adv_wr_off = val;
>> +	of_property_read_u32(np, "gpmc,adv-on", &gpmc_t->adv_on);
>> +	of_property_read_u32(np, "gpmc,adv-rd-off", &gpmc_t->adv_rd_off);
>> +	of_property_read_u32(np, "gpmc,adv-wr-off", &gpmc_t->adv_wr_off);
>>  
>>  	/* WE signal timings */
>> -	if (!of_property_read_u32(np, "gpmc,we-on", &val))
>> -		gpmc_t->we_on = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,we-off", &val))
>> -		gpmc_t->we_off = val;
>> +	of_property_read_u32(np, "gpmc,we-on", &gpmc_t->we_on);
>> +	of_property_read_u32(np, "gpmc,we-off", &gpmc_t->we_off);
>>  
>>  	/* OE signal timings */
>> -	if (!of_property_read_u32(np, "gpmc,oe-on", &val))
>> -		gpmc_t->oe_on = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,oe-off", &val))
>> -		gpmc_t->oe_off = val;
>> +	of_property_read_u32(np, "gpmc,oe-on", &gpmc_t->oe_on);
>> +	of_property_read_u32(np, "gpmc,oe-off", &gpmc_t->oe_off);
>>  
>>  	/* access and cycle timings */
>> -	if (!of_property_read_u32(np, "gpmc,page-burst-access", &val))
>> -		gpmc_t->page_burst_access = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,access", &val))
>> -		gpmc_t->access = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,rd-cycle", &val))
>> -		gpmc_t->rd_cycle = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,wr-cycle", &val))
>> -		gpmc_t->wr_cycle = val;
>> -
>> -	/* only for OMAP3430 */
>> -	if (!of_property_read_u32(np, "gpmc,wr-access", &val))
>> -		gpmc_t->wr_access = val;
>> -
>> -	if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val))
>> -		gpmc_t->wr_data_mux_bus = val;
>> +	of_property_read_u32(np, "gpmc,page-burst-access",
>> +			     &gpmc_t->page_burst_access);
>> +	of_property_read_u32(np, "gpmc,access", &gpmc_t->access);
>> +	of_property_read_u32(np, "gpmc,rd-cycle", &gpmc_t->rd_cycle);
>> +	of_property_read_u32(np, "gpmc,wr-cycle", &gpmc_t->wr_cycle);
>> +	of_property_read_u32(np, "gpmc,bus-turnaround",
>> +			     &gpmc_t->bus_turnaround);
>> +	of_property_read_u32(np, "gpmc,cycle2cycle-delay",
>> +			     &gpmc_t->cycle2cycle_delay);
>> +	of_property_read_u32(np, "gpmc,wait-monitoring",
>> +			     &gpmc_t->wait_monitoring);
>> +	of_property_read_u32(np, "gpmc,clk-activation",
>> +			     &gpmc_t->clk_activation);
>> +
>> +	/* only applicable to OMAP3+ */
>> +	of_property_read_u32(np, "gpmc,wr-access", &gpmc_t->wr_access);
>> +	of_property_read_u32(np, "gpmc,wr-data-mux-bus",
>> +			     &gpmc_t->wr_data_mux_bus);
>> +
>> +	/* bool timing parameters */
>> +	if (of_find_property(np, "gpmc,cycle2cycle-diffcsen", NULL))
>> +		gpmc_t->bool_timings.cycle2cyclediffcsen = true;
>> +	if (of_find_property(np, "gpmc,cycle2cycle-samecsen", NULL))
>> +		gpmc_t->bool_timings.cycle2cyclesamecsen = true;
>> +	if (of_find_property(np, "gpmc,we-extra-delay", NULL))
>> +		gpmc_t->bool_timings.we_extra_delay = true;
>> +	if (of_find_property(np, "gpmc,oe-extra-delay", NULL))
>> +		gpmc_t->bool_timings.oe_extra_delay = true;
>> +	if (of_find_property(np, "gpmc,adv-extra-delay", NULL))
>> +		gpmc_t->bool_timings.adv_extra_delay = true;
>> +	if (of_find_property(np, "gpmc,cs-extra-delay", NULL))
>> +		gpmc_t->bool_timings.cs_extra_delay = true;
>> +	if (of_find_property(np, "gpmc,time-para-granularity", NULL))
>> +		gpmc_t->bool_timings.time_para_granularity = true;
> 
> of_property_read_bool doesn't work for these?

It should work fine, I wasn't aware of that. Will change.

Cheers
Jon

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

* [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters
  2013-03-18 14:32     ` Jon Hunter
@ 2013-03-18 15:59       ` Jon Hunter
  0 siblings, 0 replies; 27+ messages in thread
From: Jon Hunter @ 2013-03-18 15:59 UTC (permalink / raw)
  To: linux-arm-kernel


On 03/18/2013 09:32 AM, Jon Hunter wrote:
> 
> On 03/18/2013 09:07 AM, Rob Herring wrote:
>> On 03/15/2013 10:21 AM, Jon Hunter wrote:
>>> Some of the GPMC timings parameters are currently missing from the GPMC
>>> device-tree binding. Add these parameters to the binding documentation
>>> as well as code to read them.
>>>
>>> The existing code in gpmc_read_timings_dt() is checking the value of
>>> of_property_read_u32() and only is successful storing the value read
>>> in the gpmc_timings structure. Checking the return value in this case
>>> is not necessary and we can simply read the value, if present, and
>>> store directly in the gpmc_timings structure. Therefore, simplify the
>>> code by removing these checks.
>>>
>>> The comment in the gpmc_read_timings_dt() function, "only for OMAP3430"
>>> is also incorrect as it is applicable to all OMAP3+ devices. So correct
>>> this too.
>>>
>>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>>> ---
>>>  Documentation/devicetree/bindings/bus/ti-gpmc.txt |   25 +++++-
>>>  arch/arm/mach-omap2/gpmc.c                        |   93 ++++++++++-----------
>>>  2 files changed, 66 insertions(+), 52 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
>>> index 6fde1cf..a63bd93 100644
>>> --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt
>>> +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
>>> @@ -56,10 +56,27 @@ Timing properties for child nodes. All are optional and default to 0.
>>>   - gpmc,oe-off:		Deassertion time
>>>  
>>>   Access time and cycle time timings corresponding to GPMC_CONFIG5:
>>> - - gpmc,page-burst-access: Multiple access word delay
>>> - - gpmc,access:		Start-cycle to first data valid delay
>>> - - gpmc,rd-cycle:	Total read cycle time
>>> - - gpmc,wr-cycle:	Total write cycle time
>>> + - gpmc,page-burst-access: 	Multiple access word delay
>>> + - gpmc,access:			Start-cycle to first data valid delay
>>> + - gpmc,rd-cycle:		Total read cycle time
>>> + - gpmc,wr-cycle:		Total write cycle time
>>> + - gpmc,bus-turnaround:		Turn-around time between successive accesses
>>> + - gpmc,cycle2cycle-delay:	Delay between chip-select pulses
>>> + - gpmc,clk-activation: 	GPMC clock activation time
>>> + - gpmc,wait-monitoring:	Start of wait monitoring with regard to valid
>>> +				data
>>
>> What units are these in? If in nanoseconds, can you append "-ns"
> 
> These are cycles. I can update the comment to reflect that.

Sorry these are nanoseconds. I will update the properties to reflect that.

Jon

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

end of thread, other threads:[~2013-03-18 15:59 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-15 15:20 [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Jon Hunter
2013-03-15 15:20 ` [PATCH V3 01/18] ARM: OMAP2+: Simplify code configuring ONENAND devices Jon Hunter
2013-03-15 15:21 ` [PATCH V3 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins Jon Hunter
2013-03-16 20:59   ` Ezequiel Garcia
2013-03-18 13:43     ` Jon Hunter
2013-03-15 15:21 ` [PATCH V3 03/18] ARM: OMAP2+: Add structure for storing GPMC settings Jon Hunter
2013-03-15 15:21 ` [PATCH V3 04/18] ARM: OMAP2+: Add function for configuring " Jon Hunter
2013-03-15 15:21 ` [PATCH V3 05/18] ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings() Jon Hunter
2013-03-15 15:21 ` [PATCH V3 06/18] ARM: OMAP2+: Convert NAND " Jon Hunter
2013-03-15 15:21 ` [PATCH V3 07/18] ARM: OMAP2+: Convert SMC91x " Jon Hunter
2013-03-15 15:21 ` [PATCH V3 08/18] ARM: OMAP2+: Convert TUSB " Jon Hunter
2013-03-15 15:21 ` [PATCH V3 09/18] ARM: OMAP2+: Don't configure of chip-select options in gpmc_cs_configure() Jon Hunter
2013-03-15 15:21 ` [PATCH V3 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree Jon Hunter
2013-03-17  5:24   ` Ezequiel Garcia
2013-03-18 13:43     ` Jon Hunter
2013-03-15 15:21 ` [PATCH V3 11/18] ARM: OMAP2+: Add device-tree support for NOR flash Jon Hunter
2013-03-15 15:21 ` [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters Jon Hunter
2013-03-18 14:07   ` Rob Herring
2013-03-18 14:32     ` Jon Hunter
2013-03-18 15:59       ` Jon Hunter
2013-03-15 15:21 ` [PATCH V3 13/18] ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT Jon Hunter
2013-03-15 15:21 ` [PATCH V3 14/18] ARM: OMAP2+: Convert ONENAND " Jon Hunter
2013-03-15 15:21 ` [PATCH V3 15/18] ARM: OMAP2+: Detect incorrectly aligned GPMC base address Jon Hunter
2013-03-15 15:21 ` [PATCH V3 16/18] ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable Jon Hunter
2013-03-15 15:21 ` [PATCH V3 17/18] ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails Jon Hunter
2013-03-15 15:21 ` [PATCH V3 18/18] ARM: OMAP2+: return -ENODEV if GPMC child device creation fails Jon Hunter
2013-03-17  5:34 ` [PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update Ezequiel Garcia

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