All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
@ 2012-08-21 10:41 ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:41 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Hi,

This series provides a generic gpmc timing calculation routine. There
were three peripherals (OneNAND, tusb6010, smc91x) using custom timing
calculations, they are migrated to use the generic timing calculation.

Such a generic routine would help create a driver out of gpmc platform
code, which would be peripheral agnostic and thus lead to DT finally.
Input to generic timing calculation routine would be gpmc peripheral
timings, output - translated timings that gpmc can understand. Later,
to DT'ify, gpmc peripheral timings could be passed through DT. Input
timings that has been used here are selected such that it represents
those that are present in peripheral timing datasheets.

Proposed generic routine has been tested on OneNAND (async) on
OMAP3EVM rev C (as mainline does not have the OneNAND support for this,
local patch were used to test). For other cases of custom timing
calculation (tusb6010, smc91x non-muxed, OneNAND sync), generic timing
calculation routine was verified by simulating on OMAP3EVM. Codebase
for such a testing is available
@ git://gitorious.org/x0148406-public/linux-kernel.git gpmc-prep-v6-verify

Regarding "we_on" for onenand async, it was found that even for muxed
address/data, it need not be greater than "adv_wr_off", but rather
could be derived from write setup time for peripheral from start of
access, hence would more be in line with peripheral timings. With
"we_on" calculated this way, it was working fine. If it is required in
some cases to have "we_on" same as "wr_data_mux_bus" (i.e. greater
than "adv_wr_off") other than for IP's not having "wr_data_mux_bus",
another variable could be added to indicate it, but such a
requirement is not expected though.

It has been observed that "adv_rd_off" & "adv_wr_off" are currently
calculated by adding an offset over "oe_on" & "we_on" respectively
in the case of smc91x. But peripheral datasheet does not specify
so and so "adv_rd(wr)_off" has been derived (to be specific, made
ignorant of "oe_on" & "we_on") observing datasheet rather than adding
an offset. Hence this generic routine is expected to work for smc91x
(91C96 RX51 board). This was verified on smsc911x (9220 on OMAP3EVM)
- a similar ethernet controller.

Also this series contains, patches 1-3 of v5 in addition to
minor cleanups that were low hanging fruits came across upon
implementing generic timing routine. One such is credited to
Jon Hunter, relevant patch is 1/2 of his series
@ http://marc.info/?l=linux-omap&m=134090910321284&w=2

This series has been tested on OMAP3EVM. As mentioned above, generic
timing could be tested on OneNAND hardware working in async mode.
Also generic timing calculation for other cases was validated by
comparing output values of existing custom timing calculation routine
& the new generic one, these conditions were simulated on OMAP3EVM


This series is available
	@ git://gitorious.org/x0148406-public/linux-kernel.git gpmc-prep-v6

and is made on top of
	http://marc.info/?l=linux-omap&m=134554192102899&w=2

which is based over 3.6-rc1.

Regards
Afzal

v6:
	1. Generic timing calculation, move existing users of custom
	 calculation to use the new generic one
	2. Set OneNAND part to async mode before gpmc configuration
	3. Move extra delay time user handling to proper patch
	 (3/10 -> 2/10)
	4. Modify nand init for OMAP3EVM too as support got added
v5:
	Use flags for sync_read/write, hv, vhf
v4:
	Reorganize OneNAND set_sync/async functions in a better way
v3:
	1. Refactor OneNAND set_sync/async functions to separate out
	 timing and configurations
	2. Handle bool type timings too
	3. Swap patches 2 & 3 due to dependency of OneNAND change on
	 newly added bool type timings
v2:
	1. Make use of timing api for setting clock activation time,
	 and remove direct writing to register for clock activation.
	2. Move ensuring that async mode in OneNAND has been setup from
	 set_sync to setup function, improve commit message

Afzal Mohammed (9):
  ARM: OMAP2+: nand: unify init functions
  ARM: OMAP2+: gpmc: handle additional timings
  ARM: OMAP2+: onenand: refactor for clarity
  ARM: OMAP2+: gpmc: find features by ip rev check
  ARM: OMAP2+: gpmc: remove cs# in sync clk div calc
  ARM: OMAP2+: gpmc: generic timing calculation
  ARM: OMAP2+: onenand: generic timing calculation
  ARM: OMAP2+: smc91x: generic timing calculation
  ARM: OMAP2+: tusb6010: generic timing calculation

Jon Hunter (1):
  ARM: OMAP2+: GPMC: Remove unused OneNAND get_freq() platform function

 arch/arm/mach-omap2/board-devkit8000.c     |    8 +-
 arch/arm/mach-omap2/board-flash.c          |   45 ++--
 arch/arm/mach-omap2/board-flash.h          |    6 +-
 arch/arm/mach-omap2/board-igep0020.c       |    2 +-
 arch/arm/mach-omap2/board-ldp.c            |    4 +-
 arch/arm/mach-omap2/board-omap3beagle.c    |    8 +-
 arch/arm/mach-omap2/board-omap3evm.c       |    8 +-
 arch/arm/mach-omap2/board-omap3touchbook.c |    8 +-
 arch/arm/mach-omap2/board-overo.c          |    7 +-
 arch/arm/mach-omap2/board-zoom.c           |    5 +-
 arch/arm/mach-omap2/common-board-devices.c |   46 ----
 arch/arm/mach-omap2/common-board-devices.h |    1 -
 arch/arm/mach-omap2/gpmc-onenand.c         |  334 +++++++++++---------------
 arch/arm/mach-omap2/gpmc-smc91x.c          |   43 ++--
 arch/arm/mach-omap2/gpmc.c                 |  363 +++++++++++++++++++++++++++-
 arch/arm/mach-omap2/usb-tusb6010.c         |  180 ++++-----------
 arch/arm/plat-omap/include/plat/gpmc.h     |   82 ++++++-
 arch/arm/plat-omap/include/plat/onenand.h  |    8 -
 18 files changed, 707 insertions(+), 451 deletions(-)


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

* [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
@ 2012-08-21 10:41 ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This series provides a generic gpmc timing calculation routine. There
were three peripherals (OneNAND, tusb6010, smc91x) using custom timing
calculations, they are migrated to use the generic timing calculation.

Such a generic routine would help create a driver out of gpmc platform
code, which would be peripheral agnostic and thus lead to DT finally.
Input to generic timing calculation routine would be gpmc peripheral
timings, output - translated timings that gpmc can understand. Later,
to DT'ify, gpmc peripheral timings could be passed through DT. Input
timings that has been used here are selected such that it represents
those that are present in peripheral timing datasheets.

Proposed generic routine has been tested on OneNAND (async) on
OMAP3EVM rev C (as mainline does not have the OneNAND support for this,
local patch were used to test). For other cases of custom timing
calculation (tusb6010, smc91x non-muxed, OneNAND sync), generic timing
calculation routine was verified by simulating on OMAP3EVM. Codebase
for such a testing is available
@ git://gitorious.org/x0148406-public/linux-kernel.git gpmc-prep-v6-verify

Regarding "we_on" for onenand async, it was found that even for muxed
address/data, it need not be greater than "adv_wr_off", but rather
could be derived from write setup time for peripheral from start of
access, hence would more be in line with peripheral timings. With
"we_on" calculated this way, it was working fine. If it is required in
some cases to have "we_on" same as "wr_data_mux_bus" (i.e. greater
than "adv_wr_off") other than for IP's not having "wr_data_mux_bus",
another variable could be added to indicate it, but such a
requirement is not expected though.

It has been observed that "adv_rd_off" & "adv_wr_off" are currently
calculated by adding an offset over "oe_on" & "we_on" respectively
in the case of smc91x. But peripheral datasheet does not specify
so and so "adv_rd(wr)_off" has been derived (to be specific, made
ignorant of "oe_on" & "we_on") observing datasheet rather than adding
an offset. Hence this generic routine is expected to work for smc91x
(91C96 RX51 board). This was verified on smsc911x (9220 on OMAP3EVM)
- a similar ethernet controller.

Also this series contains, patches 1-3 of v5 in addition to
minor cleanups that were low hanging fruits came across upon
implementing generic timing routine. One such is credited to
Jon Hunter, relevant patch is 1/2 of his series
@ http://marc.info/?l=linux-omap&m=134090910321284&w=2

This series has been tested on OMAP3EVM. As mentioned above, generic
timing could be tested on OneNAND hardware working in async mode.
Also generic timing calculation for other cases was validated by
comparing output values of existing custom timing calculation routine
& the new generic one, these conditions were simulated on OMAP3EVM


This series is available
	@ git://gitorious.org/x0148406-public/linux-kernel.git gpmc-prep-v6

and is made on top of
	http://marc.info/?l=linux-omap&m=134554192102899&w=2

which is based over 3.6-rc1.

Regards
Afzal

v6:
	1. Generic timing calculation, move existing users of custom
	 calculation to use the new generic one
	2. Set OneNAND part to async mode before gpmc configuration
	3. Move extra delay time user handling to proper patch
	 (3/10 -> 2/10)
	4. Modify nand init for OMAP3EVM too as support got added
v5:
	Use flags for sync_read/write, hv, vhf
v4:
	Reorganize OneNAND set_sync/async functions in a better way
v3:
	1. Refactor OneNAND set_sync/async functions to separate out
	 timing and configurations
	2. Handle bool type timings too
	3. Swap patches 2 & 3 due to dependency of OneNAND change on
	 newly added bool type timings
v2:
	1. Make use of timing api for setting clock activation time,
	 and remove direct writing to register for clock activation.
	2. Move ensuring that async mode in OneNAND has been setup from
	 set_sync to setup function, improve commit message

Afzal Mohammed (9):
  ARM: OMAP2+: nand: unify init functions
  ARM: OMAP2+: gpmc: handle additional timings
  ARM: OMAP2+: onenand: refactor for clarity
  ARM: OMAP2+: gpmc: find features by ip rev check
  ARM: OMAP2+: gpmc: remove cs# in sync clk div calc
  ARM: OMAP2+: gpmc: generic timing calculation
  ARM: OMAP2+: onenand: generic timing calculation
  ARM: OMAP2+: smc91x: generic timing calculation
  ARM: OMAP2+: tusb6010: generic timing calculation

Jon Hunter (1):
  ARM: OMAP2+: GPMC: Remove unused OneNAND get_freq() platform function

 arch/arm/mach-omap2/board-devkit8000.c     |    8 +-
 arch/arm/mach-omap2/board-flash.c          |   45 ++--
 arch/arm/mach-omap2/board-flash.h          |    6 +-
 arch/arm/mach-omap2/board-igep0020.c       |    2 +-
 arch/arm/mach-omap2/board-ldp.c            |    4 +-
 arch/arm/mach-omap2/board-omap3beagle.c    |    8 +-
 arch/arm/mach-omap2/board-omap3evm.c       |    8 +-
 arch/arm/mach-omap2/board-omap3touchbook.c |    8 +-
 arch/arm/mach-omap2/board-overo.c          |    7 +-
 arch/arm/mach-omap2/board-zoom.c           |    5 +-
 arch/arm/mach-omap2/common-board-devices.c |   46 ----
 arch/arm/mach-omap2/common-board-devices.h |    1 -
 arch/arm/mach-omap2/gpmc-onenand.c         |  334 +++++++++++---------------
 arch/arm/mach-omap2/gpmc-smc91x.c          |   43 ++--
 arch/arm/mach-omap2/gpmc.c                 |  363 +++++++++++++++++++++++++++-
 arch/arm/mach-omap2/usb-tusb6010.c         |  180 ++++-----------
 arch/arm/plat-omap/include/plat/gpmc.h     |   82 ++++++-
 arch/arm/plat-omap/include/plat/onenand.h  |    8 -
 18 files changed, 707 insertions(+), 451 deletions(-)

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

* [PATCH v6 01/10] ARM: OMAP2+: nand: unify init functions
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:45   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Helper function for updating nand platform data has been
added the capability to take timing structure arguement.
Usage of omap_nand_flash_init() has been replaced by modifed
one, omap_nand_flash_init was doing things similar to
board_nand_init except that NAND CS# were being acquired
based on bootloader setting. As CS# is hardwired for a given
board, acquiring gpmc CS# has been removed, and updated with
the value on board.

NAND CS# used in beagle board & omap3evm was found to be CS0.
Thomas Weber <thomas.weber.linux@googlemail.com> reported
that value of devkit8000 to be CS0. Overo board was found
to be using CS0 based on u-boot, while google grep says
omap3touchbook too has CS0.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
Reviewed-by: Jon Hunter <jon-hunter@ti.com>
---

v6:	Modify nand init for OMAP3EVM too as support got added

 arch/arm/mach-omap2/board-devkit8000.c     |    8 ++++-
 arch/arm/mach-omap2/board-flash.c          |   45 ++++++++++++++-------------
 arch/arm/mach-omap2/board-flash.h          |    6 ++-
 arch/arm/mach-omap2/board-igep0020.c       |    2 +-
 arch/arm/mach-omap2/board-ldp.c            |    4 +-
 arch/arm/mach-omap2/board-omap3beagle.c    |    8 ++++-
 arch/arm/mach-omap2/board-omap3evm.c       |    8 ++++-
 arch/arm/mach-omap2/board-omap3touchbook.c |    8 ++++-
 arch/arm/mach-omap2/board-overo.c          |    7 +++-
 arch/arm/mach-omap2/board-zoom.c           |    5 ++-
 arch/arm/mach-omap2/common-board-devices.c |   46 ----------------------------
 arch/arm/mach-omap2/common-board-devices.h |    1 -
 12 files changed, 62 insertions(+), 86 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 6567c1c..6ee429a 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,8 +59,11 @@
 
 #include "mux.h"
 #include "hsmmc.h"
+#include "board-flash.h"
 #include "common-board-devices.h"
 
+#define	NAND_CS			0
+
 #define OMAP_DM9000_GPIO_IRQ	25
 #define OMAP3_DEVKIT_TS_GPIO	27
 
@@ -628,8 +631,9 @@ static void __init devkit8000_init(void)
 
 	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-			     ARRAY_SIZE(devkit8000_nand_partitions));
+	board_nand_init(devkit8000_nand_partitions,
+		ARRAY_SIZE(devkit8000_nand_partitions), NAND_CS,
+		NAND_BUSWIDTH_16, NULL);
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index 53c39d2..47fb903 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -103,41 +103,41 @@ __init board_onenand_init(struct mtd_partition *onenand_parts,
 		defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+	{
+		.sync_clk = 0,
 
-	.sync_clk = 0,
+		.cs_on = 0,
+		.cs_rd_off = 36,
+		.cs_wr_off = 36,
 
-	.cs_on = 0,
-	.cs_rd_off = 36,
-	.cs_wr_off = 36,
+		.adv_on = 6,
+		.adv_rd_off = 24,
+		.adv_wr_off = 36,
 
-	.adv_on = 6,
-	.adv_rd_off = 24,
-	.adv_wr_off = 36,
+		.we_off = 30,
+		.oe_off = 48,
 
-	.we_off = 30,
-	.oe_off = 48,
+		.access = 54,
+		.rd_cycle = 72,
+		.wr_cycle = 72,
 
-	.access = 54,
-	.rd_cycle = 72,
-	.wr_cycle = 72,
-
-	.wr_access = 30,
-	.wr_data_mux_bus = 0,
+		.wr_access = 30,
+		.wr_data_mux_bus = 0,
+	},
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-	.gpmc_t		= &nand_timings,
-};
+static struct omap_nand_platform_data board_nand_data;
 
 void
-__init board_nand_init(struct mtd_partition *nand_parts,
-			u8 nr_parts, u8 cs, int nand_type)
+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+				int nand_type, struct gpmc_timings *gpmc_t)
 {
 	board_nand_data.cs		= cs;
 	board_nand_data.parts		= nand_parts;
 	board_nand_data.nr_parts	= nr_parts;
 	board_nand_data.devsize		= nand_type;
+	board_nand_data.gpmc_t		= gpmc_t;
 
 	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
 	board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
@@ -238,5 +238,6 @@ void __init board_flash_init(struct flash_partitions partition_info[],
 		pr_err("NAND: Unable to find configuration in GPMC\n");
 	else
 		board_nand_init(partition_info[2].parts,
-			partition_info[2].nr_parts, nandcs, nand_type);
+			partition_info[2].nr_parts, nandcs,
+			nand_type, nand_default_timings);
 }
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
index c44b70d..a3aa5fc 100644
--- a/arch/arm/mach-omap2/board-flash.h
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -40,12 +40,14 @@ static inline void board_flash_init(struct flash_partitions part[],
 #if defined(CONFIG_MTD_NAND_OMAP2) || \
 		defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 extern void board_nand_init(struct mtd_partition *nand_parts,
-					u8 nr_parts, u8 cs, int nand_type);
+		u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t);
+extern struct gpmc_timings nand_default_timings[];
 #else
 static inline void board_nand_init(struct mtd_partition *nand_parts,
-					u8 nr_parts, u8 cs, int nand_type)
+		u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t)
 {
 }
+#define	nand_default_timings	NULL
 #endif
 
 #if defined(CONFIG_MTD_ONENAND_OMAP2) || \
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 2821448..b7401f7 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -175,7 +175,7 @@ static void __init igep_flash_init(void)
 		pr_info("IGEP: initializing NAND memory device\n");
 		board_nand_init(igep_flash_partitions,
 				ARRAY_SIZE(igep_flash_partitions),
-				0, NAND_BUSWIDTH_16);
+				0, NAND_BUSWIDTH_16, nand_default_timings);
 	} else if (mux == IGEP_SYSBOOT_ONENAND) {
 		pr_info("IGEP: initializing OneNAND memory device\n");
 		board_onenand_init(igep_flash_partitions,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index ef9e829..5d8fa99 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -427,8 +427,8 @@ static void __init omap_ldp_init(void)
 	omap_serial_init();
 	omap_sdrc_init(NULL, NULL);
 	usb_musb_init(NULL);
-	board_nand_init(ldp_nand_partitions,
-		ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
+	board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions),
+				ZOOM_NAND_CS, 0, nand_default_timings);
 
 	omap_hsmmc_init(mmc);
 	ldp_display_init();
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 6202fc7..940ab49 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -51,8 +51,11 @@
 #include "mux.h"
 #include "hsmmc.h"
 #include "pm.h"
+#include "board-flash.h"
 #include "common-board-devices.h"
 
+#define	NAND_CS	0
+
 /*
  * OMAP3 Beagle revision
  * Run time detection of Beagle revision is done by reading GPIO.
@@ -517,8 +520,9 @@ static void __init omap3_beagle_init(void)
 
 	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
-			     ARRAY_SIZE(omap3beagle_nand_partitions));
+	board_nand_init(omap3beagle_nand_partitions,
+		ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS,
+		NAND_BUSWIDTH_16, NULL);
 
 	/* Ensure msecure is mux'd to be able to set the RTC. */
 	omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 0d362e9..833c42c 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -57,6 +57,9 @@
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
 #include "common-board-devices.h"
+#include "board-flash.h"
+
+#define	NAND_CS			0
 
 #define OMAP3_EVM_TS_GPIO	175
 #define OMAP3_EVM_EHCI_VBUS	22
@@ -730,8 +733,9 @@ static void __init omap3_evm_init(void)
 	}
 	usb_musb_init(&musb_board_data);
 	usbhs_init(&usbhs_bdata);
-	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3evm_nand_partitions,
-			     ARRAY_SIZE(omap3evm_nand_partitions));
+	board_nand_init(omap3evm_nand_partitions,
+		ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS,
+		NAND_BUSWIDTH_16, NULL);
 
 	omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
 	omap3evm_init_smsc911x();
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 485d14d..75e07f6 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -52,6 +52,7 @@
 
 #include "mux.h"
 #include "hsmmc.h"
+#include "board-flash.h"
 #include "common-board-devices.h"
 
 #include <asm/setup.h>
@@ -61,6 +62,8 @@
 #define TB_BL_PWM_TIMER		9
 #define TB_KILL_POWER_GPIO	168
 
+#define	NAND_CS			0
+
 static unsigned long touchbook_revision;
 
 static struct mtd_partition omap3touchbook_nand_partitions[] = {
@@ -370,8 +373,9 @@ static void __init omap3_touchbook_init(void)
 	omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata);
 	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3touchbook_nand_partitions,
-			     ARRAY_SIZE(omap3touchbook_nand_partitions));
+	board_nand_init(omap3touchbook_nand_partitions,
+		ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS,
+		NAND_BUSWIDTH_16, NULL);
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 779734d..56d5b9e 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -57,8 +57,11 @@
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
+#include "board-flash.h"
 #include "common-board-devices.h"
 
+#define	NAND_CS			0
+
 #define OVERO_GPIO_BT_XGATE	15
 #define OVERO_GPIO_W2W_NRESET	16
 #define OVERO_GPIO_PENDOWN	114
@@ -500,8 +503,8 @@ static void __init overo_init(void)
 	omap_serial_init();
 	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
 				  mt46h32m32lf6_sdrc_params);
-	omap_nand_flash_init(0, overo_nand_partitions,
-			     ARRAY_SIZE(overo_nand_partitions));
+	board_nand_init(overo_nand_partitions,
+		ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL);
 	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
 	overo_spi_init();
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
index 4e7e561..a04dd85 100644
--- a/arch/arm/mach-omap2/board-zoom.c
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -114,8 +114,9 @@ static void __init omap_zoom_init(void)
 		usbhs_init(&usbhs_bdata);
 	}
 
-	board_nand_init(zoom_nand_partitions, ARRAY_SIZE(zoom_nand_partitions),
-						ZOOM_NAND_CS, NAND_BUSWIDTH_16);
+	board_nand_init(zoom_nand_partitions,
+			ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS,
+			NAND_BUSWIDTH_16, nand_default_timings);
 	zoom_debugboard_init();
 	zoom_peripherals_init();
 
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
index c187586..3aef3a9 100644
--- a/arch/arm/mach-omap2/common-board-devices.c
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -95,49 +95,3 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
 {
 }
 #endif
-
-#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-static struct omap_nand_platform_data nand_data;
-
-void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
-				 int nr_parts)
-{
-	u8 cs = 0;
-	u8 nandcs = GPMC_CS_NUM + 1;
-
-	/* find out the chip-select on which NAND exists */
-	while (cs < GPMC_CS_NUM) {
-		u32 ret = 0;
-		ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-
-		if ((ret & 0xC00) == 0x800) {
-			printk(KERN_INFO "Found NAND on CS%d\n", cs);
-			if (nandcs > GPMC_CS_NUM)
-				nandcs = cs;
-		}
-		cs++;
-	}
-
-	if (nandcs > GPMC_CS_NUM) {
-		printk(KERN_INFO "NAND: Unable to find configuration "
-				 "in GPMC\n ");
-		return;
-	}
-
-	if (nandcs < GPMC_CS_NUM) {
-		nand_data.cs = nandcs;
-		nand_data.parts = parts;
-		nand_data.nr_parts = nr_parts;
-		nand_data.devsize = options;
-
-		printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
-		if (gpmc_nand_init(&nand_data) < 0)
-			printk(KERN_ERR "Unable to register NAND device\n");
-	}
-}
-#else
-void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
-				 int nr_parts)
-{
-}
-#endif
diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h
index a0b4a42..72bb41b 100644
--- a/arch/arm/mach-omap2/common-board-devices.h
+++ b/arch/arm/mach-omap2/common-board-devices.h
@@ -10,6 +10,5 @@ struct ads7846_platform_data;
 
 void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
 		       struct ads7846_platform_data *board_pdata);
-void omap_nand_flash_init(int opts, struct mtd_partition *parts, int n_parts);
 
 #endif /* __OMAP_COMMON_BOARD_DEVICES__ */
-- 
1.7.1


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

* [PATCH v6 01/10] ARM: OMAP2+: nand: unify init functions
@ 2012-08-21 10:45   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

Helper function for updating nand platform data has been
added the capability to take timing structure arguement.
Usage of omap_nand_flash_init() has been replaced by modifed
one, omap_nand_flash_init was doing things similar to
board_nand_init except that NAND CS# were being acquired
based on bootloader setting. As CS# is hardwired for a given
board, acquiring gpmc CS# has been removed, and updated with
the value on board.

NAND CS# used in beagle board & omap3evm was found to be CS0.
Thomas Weber <thomas.weber.linux@googlemail.com> reported
that value of devkit8000 to be CS0. Overo board was found
to be using CS0 based on u-boot, while google grep says
omap3touchbook too has CS0.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
Reviewed-by: Jon Hunter <jon-hunter@ti.com>
---

v6:	Modify nand init for OMAP3EVM too as support got added

 arch/arm/mach-omap2/board-devkit8000.c     |    8 ++++-
 arch/arm/mach-omap2/board-flash.c          |   45 ++++++++++++++-------------
 arch/arm/mach-omap2/board-flash.h          |    6 ++-
 arch/arm/mach-omap2/board-igep0020.c       |    2 +-
 arch/arm/mach-omap2/board-ldp.c            |    4 +-
 arch/arm/mach-omap2/board-omap3beagle.c    |    8 ++++-
 arch/arm/mach-omap2/board-omap3evm.c       |    8 ++++-
 arch/arm/mach-omap2/board-omap3touchbook.c |    8 ++++-
 arch/arm/mach-omap2/board-overo.c          |    7 +++-
 arch/arm/mach-omap2/board-zoom.c           |    5 ++-
 arch/arm/mach-omap2/common-board-devices.c |   46 ----------------------------
 arch/arm/mach-omap2/common-board-devices.h |    1 -
 12 files changed, 62 insertions(+), 86 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 6567c1c..6ee429a 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,8 +59,11 @@
 
 #include "mux.h"
 #include "hsmmc.h"
+#include "board-flash.h"
 #include "common-board-devices.h"
 
+#define	NAND_CS			0
+
 #define OMAP_DM9000_GPIO_IRQ	25
 #define OMAP3_DEVKIT_TS_GPIO	27
 
@@ -628,8 +631,9 @@ static void __init devkit8000_init(void)
 
 	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-			     ARRAY_SIZE(devkit8000_nand_partitions));
+	board_nand_init(devkit8000_nand_partitions,
+		ARRAY_SIZE(devkit8000_nand_partitions), NAND_CS,
+		NAND_BUSWIDTH_16, NULL);
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index 53c39d2..47fb903 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -103,41 +103,41 @@ __init board_onenand_init(struct mtd_partition *onenand_parts,
 		defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+	{
+		.sync_clk = 0,
 
-	.sync_clk = 0,
+		.cs_on = 0,
+		.cs_rd_off = 36,
+		.cs_wr_off = 36,
 
-	.cs_on = 0,
-	.cs_rd_off = 36,
-	.cs_wr_off = 36,
+		.adv_on = 6,
+		.adv_rd_off = 24,
+		.adv_wr_off = 36,
 
-	.adv_on = 6,
-	.adv_rd_off = 24,
-	.adv_wr_off = 36,
+		.we_off = 30,
+		.oe_off = 48,
 
-	.we_off = 30,
-	.oe_off = 48,
+		.access = 54,
+		.rd_cycle = 72,
+		.wr_cycle = 72,
 
-	.access = 54,
-	.rd_cycle = 72,
-	.wr_cycle = 72,
-
-	.wr_access = 30,
-	.wr_data_mux_bus = 0,
+		.wr_access = 30,
+		.wr_data_mux_bus = 0,
+	},
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-	.gpmc_t		= &nand_timings,
-};
+static struct omap_nand_platform_data board_nand_data;
 
 void
-__init board_nand_init(struct mtd_partition *nand_parts,
-			u8 nr_parts, u8 cs, int nand_type)
+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+				int nand_type, struct gpmc_timings *gpmc_t)
 {
 	board_nand_data.cs		= cs;
 	board_nand_data.parts		= nand_parts;
 	board_nand_data.nr_parts	= nr_parts;
 	board_nand_data.devsize		= nand_type;
+	board_nand_data.gpmc_t		= gpmc_t;
 
 	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
 	board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
@@ -238,5 +238,6 @@ void __init board_flash_init(struct flash_partitions partition_info[],
 		pr_err("NAND: Unable to find configuration in GPMC\n");
 	else
 		board_nand_init(partition_info[2].parts,
-			partition_info[2].nr_parts, nandcs, nand_type);
+			partition_info[2].nr_parts, nandcs,
+			nand_type, nand_default_timings);
 }
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
index c44b70d..a3aa5fc 100644
--- a/arch/arm/mach-omap2/board-flash.h
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -40,12 +40,14 @@ static inline void board_flash_init(struct flash_partitions part[],
 #if defined(CONFIG_MTD_NAND_OMAP2) || \
 		defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 extern void board_nand_init(struct mtd_partition *nand_parts,
-					u8 nr_parts, u8 cs, int nand_type);
+		u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t);
+extern struct gpmc_timings nand_default_timings[];
 #else
 static inline void board_nand_init(struct mtd_partition *nand_parts,
-					u8 nr_parts, u8 cs, int nand_type)
+		u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t)
 {
 }
+#define	nand_default_timings	NULL
 #endif
 
 #if defined(CONFIG_MTD_ONENAND_OMAP2) || \
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 2821448..b7401f7 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -175,7 +175,7 @@ static void __init igep_flash_init(void)
 		pr_info("IGEP: initializing NAND memory device\n");
 		board_nand_init(igep_flash_partitions,
 				ARRAY_SIZE(igep_flash_partitions),
-				0, NAND_BUSWIDTH_16);
+				0, NAND_BUSWIDTH_16, nand_default_timings);
 	} else if (mux == IGEP_SYSBOOT_ONENAND) {
 		pr_info("IGEP: initializing OneNAND memory device\n");
 		board_onenand_init(igep_flash_partitions,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index ef9e829..5d8fa99 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -427,8 +427,8 @@ static void __init omap_ldp_init(void)
 	omap_serial_init();
 	omap_sdrc_init(NULL, NULL);
 	usb_musb_init(NULL);
-	board_nand_init(ldp_nand_partitions,
-		ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
+	board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions),
+				ZOOM_NAND_CS, 0, nand_default_timings);
 
 	omap_hsmmc_init(mmc);
 	ldp_display_init();
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 6202fc7..940ab49 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -51,8 +51,11 @@
 #include "mux.h"
 #include "hsmmc.h"
 #include "pm.h"
+#include "board-flash.h"
 #include "common-board-devices.h"
 
+#define	NAND_CS	0
+
 /*
  * OMAP3 Beagle revision
  * Run time detection of Beagle revision is done by reading GPIO.
@@ -517,8 +520,9 @@ static void __init omap3_beagle_init(void)
 
 	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
-			     ARRAY_SIZE(omap3beagle_nand_partitions));
+	board_nand_init(omap3beagle_nand_partitions,
+		ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS,
+		NAND_BUSWIDTH_16, NULL);
 
 	/* Ensure msecure is mux'd to be able to set the RTC. */
 	omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 0d362e9..833c42c 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -57,6 +57,9 @@
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
 #include "common-board-devices.h"
+#include "board-flash.h"
+
+#define	NAND_CS			0
 
 #define OMAP3_EVM_TS_GPIO	175
 #define OMAP3_EVM_EHCI_VBUS	22
@@ -730,8 +733,9 @@ static void __init omap3_evm_init(void)
 	}
 	usb_musb_init(&musb_board_data);
 	usbhs_init(&usbhs_bdata);
-	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3evm_nand_partitions,
-			     ARRAY_SIZE(omap3evm_nand_partitions));
+	board_nand_init(omap3evm_nand_partitions,
+		ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS,
+		NAND_BUSWIDTH_16, NULL);
 
 	omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
 	omap3evm_init_smsc911x();
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 485d14d..75e07f6 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -52,6 +52,7 @@
 
 #include "mux.h"
 #include "hsmmc.h"
+#include "board-flash.h"
 #include "common-board-devices.h"
 
 #include <asm/setup.h>
@@ -61,6 +62,8 @@
 #define TB_BL_PWM_TIMER		9
 #define TB_KILL_POWER_GPIO	168
 
+#define	NAND_CS			0
+
 static unsigned long touchbook_revision;
 
 static struct mtd_partition omap3touchbook_nand_partitions[] = {
@@ -370,8 +373,9 @@ static void __init omap3_touchbook_init(void)
 	omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata);
 	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3touchbook_nand_partitions,
-			     ARRAY_SIZE(omap3touchbook_nand_partitions));
+	board_nand_init(omap3touchbook_nand_partitions,
+		ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS,
+		NAND_BUSWIDTH_16, NULL);
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 779734d..56d5b9e 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -57,8 +57,11 @@
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
+#include "board-flash.h"
 #include "common-board-devices.h"
 
+#define	NAND_CS			0
+
 #define OVERO_GPIO_BT_XGATE	15
 #define OVERO_GPIO_W2W_NRESET	16
 #define OVERO_GPIO_PENDOWN	114
@@ -500,8 +503,8 @@ static void __init overo_init(void)
 	omap_serial_init();
 	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
 				  mt46h32m32lf6_sdrc_params);
-	omap_nand_flash_init(0, overo_nand_partitions,
-			     ARRAY_SIZE(overo_nand_partitions));
+	board_nand_init(overo_nand_partitions,
+		ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL);
 	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
 	overo_spi_init();
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
index 4e7e561..a04dd85 100644
--- a/arch/arm/mach-omap2/board-zoom.c
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -114,8 +114,9 @@ static void __init omap_zoom_init(void)
 		usbhs_init(&usbhs_bdata);
 	}
 
-	board_nand_init(zoom_nand_partitions, ARRAY_SIZE(zoom_nand_partitions),
-						ZOOM_NAND_CS, NAND_BUSWIDTH_16);
+	board_nand_init(zoom_nand_partitions,
+			ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS,
+			NAND_BUSWIDTH_16, nand_default_timings);
 	zoom_debugboard_init();
 	zoom_peripherals_init();
 
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
index c187586..3aef3a9 100644
--- a/arch/arm/mach-omap2/common-board-devices.c
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -95,49 +95,3 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
 {
 }
 #endif
-
-#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-static struct omap_nand_platform_data nand_data;
-
-void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
-				 int nr_parts)
-{
-	u8 cs = 0;
-	u8 nandcs = GPMC_CS_NUM + 1;
-
-	/* find out the chip-select on which NAND exists */
-	while (cs < GPMC_CS_NUM) {
-		u32 ret = 0;
-		ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-
-		if ((ret & 0xC00) == 0x800) {
-			printk(KERN_INFO "Found NAND on CS%d\n", cs);
-			if (nandcs > GPMC_CS_NUM)
-				nandcs = cs;
-		}
-		cs++;
-	}
-
-	if (nandcs > GPMC_CS_NUM) {
-		printk(KERN_INFO "NAND: Unable to find configuration "
-				 "in GPMC\n ");
-		return;
-	}
-
-	if (nandcs < GPMC_CS_NUM) {
-		nand_data.cs = nandcs;
-		nand_data.parts = parts;
-		nand_data.nr_parts = nr_parts;
-		nand_data.devsize = options;
-
-		printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
-		if (gpmc_nand_init(&nand_data) < 0)
-			printk(KERN_ERR "Unable to register NAND device\n");
-	}
-}
-#else
-void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
-				 int nr_parts)
-{
-}
-#endif
diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h
index a0b4a42..72bb41b 100644
--- a/arch/arm/mach-omap2/common-board-devices.h
+++ b/arch/arm/mach-omap2/common-board-devices.h
@@ -10,6 +10,5 @@ struct ads7846_platform_data;
 
 void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
 		       struct ads7846_platform_data *board_pdata);
-void omap_nand_flash_init(int opts, struct mtd_partition *parts, int n_parts);
 
 #endif /* __OMAP_COMMON_BOARD_DEVICES__ */
-- 
1.7.1

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

* [PATCH v6 02/10] ARM: OMAP2+: gpmc: handle additional timings
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:45   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Configure busturnaround, cycle2cycledelay, waitmonitoringtime,
clkactivationtime in gpmc_cs_set_timings(). This is done so
that boards can configure these parameters of gpmc in Kernel
instead of relying on bootloader. Also configure bool type
timings like extradelay.

This needed change to the existing users that were configuring
clk activation time and extra delay by directly writing to
registers. Thanks to Tony for making me aware of users of clk
activation and being kind enough to test the modified one.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---

v6:	Move extra delay time user handling to present one from 3/10
v3:	Handle bool type timings too
v2:	Make use of timing api for setting clock activation time,
	 and remove direct writing to register for clock activation.

 arch/arm/mach-omap2/gpmc-onenand.c     |   28 ++++---------------
 arch/arm/mach-omap2/gpmc.c             |   45 ++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/usb-tusb6010.c     |    3 +-
 arch/arm/plat-omap/include/plat/gpmc.h |   19 +++++++++++++
 4 files changed, 72 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 71d7c07..977b71d 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -284,27 +284,10 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 					sync_read, sync_write, hf, vhf);
 
 	if (div == 1) {
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
-		reg |= (1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
-		reg |= (1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
-		reg |= (1 << 7);
-		reg |= (1 << 23);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
-	} else {
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
-		reg &= ~(1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
-		reg &= ~(1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
-		reg &= ~(1 << 7);
-		reg &= ~(1 << 23);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
+		t.bool_timings.cs_extra_delay = true;
+		t.bool_timings.adv_extra_delay = true;
+		t.bool_timings.oe_extra_delay = true;
+		t.bool_timings.we_extra_delay = true;
 	}
 
 	/* Set synchronous read timings */
@@ -329,6 +312,8 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 	t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
 		     ticks_cez);
 
+	t.clk_activation = fclk_offset_ns;
+
 	/* Write */
 	if (sync_write) {
 		t.adv_wr_off = t.adv_rd_off;
@@ -362,7 +347,6 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 			  (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
 			  (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
 			  (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
-			  GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
 			  GPMC_CONFIG1_PAGE_LEN(2) |
 			  (cpu_is_omap34xx() ? 0 :
 				(GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 39c30d9..070fac5 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -64,6 +64,13 @@
 #define GPMC_ECC_CTRL_ECCREG8		0x008
 #define GPMC_ECC_CTRL_ECCREG9		0x009
 
+#define	GPMC_CONFIG2_CSEXTRADELAY		BIT(7)
+#define	GPMC_CONFIG3_ADVEXTRADELAY		BIT(7)
+#define	GPMC_CONFIG4_OEEXTRADELAY		BIT(7)
+#define	GPMC_CONFIG4_WEEXTRADELAY		BIT(23)
+#define	GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN	BIT(6)
+#define	GPMC_CONFIG6_CYCLE2CYCLESAMECSEN	BIT(7)
+
 #define GPMC_CS0_OFFSET		0x60
 #define GPMC_CS_SIZE		0x30
 
@@ -220,6 +227,36 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
 	return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
+{
+	u32 l;
+
+	l = gpmc_cs_read_reg(cs, reg);
+	if (value)
+		l |= mask;
+	else
+		l &= ~mask;
+	gpmc_cs_write_reg(cs, reg, l);
+}
+
+static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
+{
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
+		GPMC_CONFIG1_TIME_PARA_GRAN, p->time_para_granularity);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
+		GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
+		GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+		GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+		GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+		GPMC_CONFIG6_CYCLE2CYCLESAMECSEN, p->cycle2cyclesamecsen);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+		GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN, p->cycle2cyclediffcsen);
+}
+
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 			       int time, const char *name)
@@ -313,6 +350,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 
 	GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
 
+	GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
+	GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
+
+	GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
+	GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
+
 	if (cpu_is_omap34xx()) {
 		GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
 		GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
@@ -332,6 +375,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
 	}
 
+	gpmc_cs_bool_timings(cs, &t->bool_timings);
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 805bea6..7a85ebe 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -174,6 +174,8 @@ static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
 	tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
 	t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
 
+	t.clk_activation = gpmc_ticks_to_ns(1);
+
 	return gpmc_cs_set_timings(sync_cs, &t);
 }
 
@@ -283,7 +285,6 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
 			| GPMC_CONFIG1_READTYPE_SYNC
 			| GPMC_CONFIG1_WRITEMULTIPLE_SUPP
 			| GPMC_CONFIG1_WRITETYPE_SYNC
-			| GPMC_CONFIG1_CLKACTIVATIONTIME(1)
 			| GPMC_CONFIG1_PAGE_LEN(2)
 			| GPMC_CONFIG1_WAIT_READ_MON
 			| GPMC_CONFIG1_WAIT_WRITE_MON
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 2e6e259..b7c9ea6 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -96,6 +96,17 @@ enum omap_ecc {
 	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
 };
 
+/* bool type time settings */
+struct gpmc_bool_timings {
+	bool cycle2cyclediffcsen;
+	bool cycle2cyclesamecsen;
+	bool we_extra_delay;
+	bool oe_extra_delay;
+	bool adv_extra_delay;
+	bool cs_extra_delay;
+	bool time_para_granularity;
+};
+
 /*
  * Note that all values in this struct are in nanoseconds except sync_clk
  * (which is in picoseconds), while the register values are in gpmc_fck cycles.
@@ -128,9 +139,17 @@ struct gpmc_timings {
 	u16 rd_cycle;		/* Total read cycle time */
 	u16 wr_cycle;		/* Total write cycle time */
 
+	u16 bus_turnaround;
+	u16 cycle2cycle_delay;
+
+	u16 wait_monitoring;
+	u16 clk_activation;
+
 	/* The following are only on OMAP3430 */
 	u16 wr_access;		/* WRACCESSTIME */
 	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+
+	struct gpmc_bool_timings bool_timings;
 };
 
 struct gpmc_nand_regs {
-- 
1.7.1


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

* [PATCH v6 02/10] ARM: OMAP2+: gpmc: handle additional timings
@ 2012-08-21 10:45   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

Configure busturnaround, cycle2cycledelay, waitmonitoringtime,
clkactivationtime in gpmc_cs_set_timings(). This is done so
that boards can configure these parameters of gpmc in Kernel
instead of relying on bootloader. Also configure bool type
timings like extradelay.

This needed change to the existing users that were configuring
clk activation time and extra delay by directly writing to
registers. Thanks to Tony for making me aware of users of clk
activation and being kind enough to test the modified one.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---

v6:	Move extra delay time user handling to present one from 3/10
v3:	Handle bool type timings too
v2:	Make use of timing api for setting clock activation time,
	 and remove direct writing to register for clock activation.

 arch/arm/mach-omap2/gpmc-onenand.c     |   28 ++++---------------
 arch/arm/mach-omap2/gpmc.c             |   45 ++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/usb-tusb6010.c     |    3 +-
 arch/arm/plat-omap/include/plat/gpmc.h |   19 +++++++++++++
 4 files changed, 72 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 71d7c07..977b71d 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -284,27 +284,10 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 					sync_read, sync_write, hf, vhf);
 
 	if (div == 1) {
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
-		reg |= (1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
-		reg |= (1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
-		reg |= (1 << 7);
-		reg |= (1 << 23);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
-	} else {
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
-		reg &= ~(1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
-		reg &= ~(1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
-		reg &= ~(1 << 7);
-		reg &= ~(1 << 23);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
+		t.bool_timings.cs_extra_delay = true;
+		t.bool_timings.adv_extra_delay = true;
+		t.bool_timings.oe_extra_delay = true;
+		t.bool_timings.we_extra_delay = true;
 	}
 
 	/* Set synchronous read timings */
@@ -329,6 +312,8 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 	t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
 		     ticks_cez);
 
+	t.clk_activation = fclk_offset_ns;
+
 	/* Write */
 	if (sync_write) {
 		t.adv_wr_off = t.adv_rd_off;
@@ -362,7 +347,6 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 			  (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
 			  (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
 			  (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
-			  GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
 			  GPMC_CONFIG1_PAGE_LEN(2) |
 			  (cpu_is_omap34xx() ? 0 :
 				(GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 39c30d9..070fac5 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -64,6 +64,13 @@
 #define GPMC_ECC_CTRL_ECCREG8		0x008
 #define GPMC_ECC_CTRL_ECCREG9		0x009
 
+#define	GPMC_CONFIG2_CSEXTRADELAY		BIT(7)
+#define	GPMC_CONFIG3_ADVEXTRADELAY		BIT(7)
+#define	GPMC_CONFIG4_OEEXTRADELAY		BIT(7)
+#define	GPMC_CONFIG4_WEEXTRADELAY		BIT(23)
+#define	GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN	BIT(6)
+#define	GPMC_CONFIG6_CYCLE2CYCLESAMECSEN	BIT(7)
+
 #define GPMC_CS0_OFFSET		0x60
 #define GPMC_CS_SIZE		0x30
 
@@ -220,6 +227,36 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
 	return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
+{
+	u32 l;
+
+	l = gpmc_cs_read_reg(cs, reg);
+	if (value)
+		l |= mask;
+	else
+		l &= ~mask;
+	gpmc_cs_write_reg(cs, reg, l);
+}
+
+static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
+{
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
+		GPMC_CONFIG1_TIME_PARA_GRAN, p->time_para_granularity);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
+		GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
+		GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+		GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+		GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+		GPMC_CONFIG6_CYCLE2CYCLESAMECSEN, p->cycle2cyclesamecsen);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+		GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN, p->cycle2cyclediffcsen);
+}
+
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 			       int time, const char *name)
@@ -313,6 +350,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 
 	GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
 
+	GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
+	GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
+
+	GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
+	GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
+
 	if (cpu_is_omap34xx()) {
 		GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
 		GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
@@ -332,6 +375,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
 	}
 
+	gpmc_cs_bool_timings(cs, &t->bool_timings);
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 805bea6..7a85ebe 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -174,6 +174,8 @@ static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
 	tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
 	t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
 
+	t.clk_activation = gpmc_ticks_to_ns(1);
+
 	return gpmc_cs_set_timings(sync_cs, &t);
 }
 
@@ -283,7 +285,6 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
 			| GPMC_CONFIG1_READTYPE_SYNC
 			| GPMC_CONFIG1_WRITEMULTIPLE_SUPP
 			| GPMC_CONFIG1_WRITETYPE_SYNC
-			| GPMC_CONFIG1_CLKACTIVATIONTIME(1)
 			| GPMC_CONFIG1_PAGE_LEN(2)
 			| GPMC_CONFIG1_WAIT_READ_MON
 			| GPMC_CONFIG1_WAIT_WRITE_MON
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 2e6e259..b7c9ea6 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -96,6 +96,17 @@ enum omap_ecc {
 	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
 };
 
+/* bool type time settings */
+struct gpmc_bool_timings {
+	bool cycle2cyclediffcsen;
+	bool cycle2cyclesamecsen;
+	bool we_extra_delay;
+	bool oe_extra_delay;
+	bool adv_extra_delay;
+	bool cs_extra_delay;
+	bool time_para_granularity;
+};
+
 /*
  * Note that all values in this struct are in nanoseconds except sync_clk
  * (which is in picoseconds), while the register values are in gpmc_fck cycles.
@@ -128,9 +139,17 @@ struct gpmc_timings {
 	u16 rd_cycle;		/* Total read cycle time */
 	u16 wr_cycle;		/* Total write cycle time */
 
+	u16 bus_turnaround;
+	u16 cycle2cycle_delay;
+
+	u16 wait_monitoring;
+	u16 clk_activation;
+
 	/* The following are only on OMAP3430 */
 	u16 wr_access;		/* WRACCESSTIME */
 	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+
+	struct gpmc_bool_timings bool_timings;
 };
 
 struct gpmc_nand_regs {
-- 
1.7.1

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

* [PATCH v6 03/10] ARM: OMAP2+: onenand: refactor for clarity
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:45   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Refactor set_async_mode & set_sync_mode functions to
separate out timing calculation & actual configuration
(GPMC & OneNAND side).

Thanks to Jon for his suggestions.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
Reviewed-by: Jon Hunter <jon-hunter@ti.com>
---

v6:
	1. Set OneNAND part to async mode before gpmc configuration
	2. Move extra delay time user handling away from this patch
	 (3/10 -> 2/10)
v5:	Use flags for sync_read/write, hv, vhf
v4:	Reorganize OneNAND set_sync/async functions in a better way
v3:	Refactor OneNAND set_sync/async functions to separate out
	 timing and configurations
v2:	Move ensuring that async mode in OneNAND has been setup from
	 set_sync to setup function, improve commit message

 arch/arm/mach-omap2/gpmc-onenand.c |  174 ++++++++++++++++++++++-------------
 1 files changed, 109 insertions(+), 65 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 977b71d..bbae674 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/onenand_regs.h>
 #include <linux/io.h>
+#include <linux/err.h>
 
 #include <asm/mach/flash.h>
 
@@ -25,6 +26,14 @@
 
 #define	ONENAND_IO_SIZE	SZ_128K
 
+#define	ONENAND_FLAG_SYNCREAD	(1 << 0)
+#define	ONENAND_FLAG_SYNCWRITE	(1 << 1)
+#define	ONENAND_FLAG_HF		(1 << 2)
+#define	ONENAND_FLAG_VHF	(1 << 3)
+
+static unsigned onenand_flags;
+static unsigned latency;
+
 static struct omap_onenand_platform_data *gpmc_onenand_data;
 
 static struct resource gpmc_onenand_resource = {
@@ -38,11 +47,9 @@ static struct platform_device gpmc_onenand_device = {
 	.resource	= &gpmc_onenand_resource,
 };
 
-static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
+static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 {
 	struct gpmc_timings t;
-	u32 reg;
-	int err;
 
 	const int t_cer = 15;
 	const int t_avdp = 12;
@@ -55,11 +62,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
 	const int t_wpl = 40;
 	const int t_wph = 30;
 
-	/* Ensure sync read and sync write are disabled */
-	reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-	reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
 	memset(&t, 0, sizeof(t));
 	t.sync_clk = 0;
 	t.cs_on = 0;
@@ -86,25 +88,30 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
 	t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
 	t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
 
+	return 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);
 
-	err = gpmc_cs_set_timings(cs, &t);
-	if (err)
-		return err;
+	return gpmc_cs_set_timings(cs, t);
+}
+
+static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
+{
+	u32 reg;
 
 	/* Ensure sync read and sync write are disabled */
 	reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
 	reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
 	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
-	return 0;
 }
 
-static void set_onenand_cfg(void __iomem *onenand_base, int latency,
-				int sync_read, int sync_write, int hf, int vhf)
+static void set_onenand_cfg(void __iomem *onenand_base)
 {
 	u32 reg;
 
@@ -112,19 +119,19 @@ static void set_onenand_cfg(void __iomem *onenand_base, int latency,
 	reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9));
 	reg |=	(latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
 		ONENAND_SYS_CFG1_BL_16;
-	if (sync_read)
+	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
 		reg |= ONENAND_SYS_CFG1_SYNC_READ;
 	else
 		reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
-	if (sync_write)
+	if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
 		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
 	else
 		reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	if (hf)
+	if (onenand_flags & ONENAND_FLAG_HF)
 		reg |= ONENAND_SYS_CFG1_HF;
 	else
 		reg &= ~ONENAND_SYS_CFG1_HF;
-	if (vhf)
+	if (onenand_flags & ONENAND_FLAG_VHF)
 		reg |= ONENAND_SYS_CFG1_VHF;
 	else
 		reg &= ~ONENAND_SYS_CFG1_VHF;
@@ -172,9 +179,9 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
 	return freq;
 }
 
-static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
-					void __iomem *onenand_base,
-					int *freq_ptr)
+static struct gpmc_timings
+omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
+						int freq, bool clk_dep)
 {
 	struct gpmc_timings t;
 	const int t_cer  = 15;
@@ -184,29 +191,14 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 	const int t_wpl  = 40;
 	const int t_wph  = 30;
 	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-	int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency;
-	int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0;
-	int err, ticks_cez;
-	int cs = cfg->cs, freq = *freq_ptr;
-	u32 reg;
-	bool clk_dep = false;
-
-	if (cfg->flags & ONENAND_SYNC_READ) {
-		sync_read = 1;
-	} else if (cfg->flags & ONENAND_SYNC_READWRITE) {
-		sync_read = 1;
-		sync_write = 1;
-	} else
-		return omap2_onenand_set_async_mode(cs, onenand_base);
+	int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
+	int ticks_cez;
+	int cs = cfg->cs;
 
-	if (!freq) {
-		/* Very first call freq is not known */
-		err = omap2_onenand_set_async_mode(cs, onenand_base);
-		if (err)
-			return err;
-		freq = omap2_onenand_get_freq(cfg, onenand_base, &clk_dep);
-		first_time = 1;
-	}
+	if (cfg->flags & ONENAND_SYNC_READ)
+		onenand_flags = ONENAND_FLAG_SYNCREAD;
+	else if (cfg->flags & ONENAND_SYNC_READWRITE)
+		onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
 
 	switch (freq) {
 	case 104:
@@ -244,19 +236,23 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 		t_ach   = 9;
 		t_aavdh = 7;
 		t_rdyo  = 15;
-		sync_write = 0;
+		onenand_flags &= ~ONENAND_FLAG_SYNCWRITE;
 		break;
 	}
 
 	div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
 	gpmc_clk_ns = gpmc_ticks_to_ns(div);
 	if (gpmc_clk_ns < 15) /* >66Mhz */
-		hf = 1;
+		onenand_flags |= ONENAND_FLAG_HF;
+	else
+		onenand_flags &= ~ONENAND_FLAG_HF;
 	if (gpmc_clk_ns < 12) /* >83Mhz */
-		vhf = 1;
-	if (vhf)
+		onenand_flags |= ONENAND_FLAG_VHF;
+	else
+		onenand_flags &= ~ONENAND_FLAG_VHF;
+	if (onenand_flags & ONENAND_FLAG_VHF)
 		latency = 8;
-	else if (hf)
+	else if (onenand_flags & ONENAND_FLAG_HF)
 		latency = 6;
 	else if (gpmc_clk_ns >= 25) /* 40 MHz*/
 		latency = 3;
@@ -279,9 +275,8 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 		}
 	}
 
-	if (first_time)
-		set_onenand_cfg(onenand_base, latency,
-					sync_read, sync_write, hf, vhf);
+	/* Set synchronous read timings */
+	memset(&t, 0, sizeof(t));
 
 	if (div == 1) {
 		t.bool_timings.cs_extra_delay = true;
@@ -290,8 +285,6 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 		t.bool_timings.we_extra_delay = true;
 	}
 
-	/* Set synchronous read timings */
-	memset(&t, 0, sizeof(t));
 	t.sync_clk = min_gpmc_clk_period;
 	t.cs_on = 0;
 	t.adv_on = 0;
@@ -315,7 +308,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 	t.clk_activation = fclk_offset_ns;
 
 	/* Write */
-	if (sync_write) {
+	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
 		t.adv_wr_off = t.adv_rd_off;
 		t.we_on  = 0;
 		t.we_off = t.cs_rd_off;
@@ -340,6 +333,14 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 		}
 	}
 
+	return 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 |
@@ -355,11 +356,47 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 			  GPMC_CONFIG1_DEVICETYPE_NOR |
 			  GPMC_CONFIG1_MUXADDDATA);
 
-	err = gpmc_cs_set_timings(cs, &t);
-	if (err)
-		return err;
+	return gpmc_cs_set_timings(cs, t);
+}
+
+static int omap2_onenand_setup_async(void __iomem *onenand_base)
+{
+	struct gpmc_timings t;
+	int ret;
+
+	omap2_onenand_set_async_mode(onenand_base);
+
+	t = omap2_onenand_calc_async_timings();
+
+	ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
+	if (IS_ERR_VALUE(ret))
+		return ret;
+
+	omap2_onenand_set_async_mode(onenand_base);
+
+	return 0;
+}
+
+static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
+{
+	int ret, freq = *freq_ptr;
+	struct gpmc_timings t;
+	bool clk_dep = false;
+
+	if (!freq) {
+		/* Very first call freq is not known */
+		freq = omap2_onenand_get_freq(gpmc_onenand_data,
+						onenand_base, &clk_dep);
+		set_onenand_cfg(onenand_base);
+	}
+
+	t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq, clk_dep);
 
-	set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf, vhf);
+	ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
+	if (IS_ERR_VALUE(ret))
+		return ret;
+
+	set_onenand_cfg(onenand_base);
 
 	*freq_ptr = freq;
 
@@ -369,15 +406,22 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
 {
 	struct device *dev = &gpmc_onenand_device.dev;
+	unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE;
+	int ret;
 
-	/* Set sync timings in GPMC */
-	if (omap2_onenand_set_sync_mode(gpmc_onenand_data, onenand_base,
-			freq_ptr) < 0) {
-		dev_err(dev, "Unable to set synchronous mode\n");
-		return -EINVAL;
+	ret = omap2_onenand_setup_async(onenand_base);
+	if (ret) {
+		dev_err(dev, "unable to set to async mode\n");
+		return ret;
 	}
 
-	return 0;
+	if (!(gpmc_onenand_data->flags & l))
+		return 0;
+
+	ret = omap2_onenand_setup_sync(onenand_base, freq_ptr);
+	if (ret)
+		dev_err(dev, "unable to set to sync mode\n");
+	return ret;
 }
 
 void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
-- 
1.7.1


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

* [PATCH v6 03/10] ARM: OMAP2+: onenand: refactor for clarity
@ 2012-08-21 10:45   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

Refactor set_async_mode & set_sync_mode functions to
separate out timing calculation & actual configuration
(GPMC & OneNAND side).

Thanks to Jon for his suggestions.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
Reviewed-by: Jon Hunter <jon-hunter@ti.com>
---

v6:
	1. Set OneNAND part to async mode before gpmc configuration
	2. Move extra delay time user handling away from this patch
	 (3/10 -> 2/10)
v5:	Use flags for sync_read/write, hv, vhf
v4:	Reorganize OneNAND set_sync/async functions in a better way
v3:	Refactor OneNAND set_sync/async functions to separate out
	 timing and configurations
v2:	Move ensuring that async mode in OneNAND has been setup from
	 set_sync to setup function, improve commit message

 arch/arm/mach-omap2/gpmc-onenand.c |  174 ++++++++++++++++++++++-------------
 1 files changed, 109 insertions(+), 65 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 977b71d..bbae674 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/onenand_regs.h>
 #include <linux/io.h>
+#include <linux/err.h>
 
 #include <asm/mach/flash.h>
 
@@ -25,6 +26,14 @@
 
 #define	ONENAND_IO_SIZE	SZ_128K
 
+#define	ONENAND_FLAG_SYNCREAD	(1 << 0)
+#define	ONENAND_FLAG_SYNCWRITE	(1 << 1)
+#define	ONENAND_FLAG_HF		(1 << 2)
+#define	ONENAND_FLAG_VHF	(1 << 3)
+
+static unsigned onenand_flags;
+static unsigned latency;
+
 static struct omap_onenand_platform_data *gpmc_onenand_data;
 
 static struct resource gpmc_onenand_resource = {
@@ -38,11 +47,9 @@ static struct platform_device gpmc_onenand_device = {
 	.resource	= &gpmc_onenand_resource,
 };
 
-static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
+static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 {
 	struct gpmc_timings t;
-	u32 reg;
-	int err;
 
 	const int t_cer = 15;
 	const int t_avdp = 12;
@@ -55,11 +62,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
 	const int t_wpl = 40;
 	const int t_wph = 30;
 
-	/* Ensure sync read and sync write are disabled */
-	reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-	reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
 	memset(&t, 0, sizeof(t));
 	t.sync_clk = 0;
 	t.cs_on = 0;
@@ -86,25 +88,30 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
 	t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
 	t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
 
+	return 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);
 
-	err = gpmc_cs_set_timings(cs, &t);
-	if (err)
-		return err;
+	return gpmc_cs_set_timings(cs, t);
+}
+
+static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
+{
+	u32 reg;
 
 	/* Ensure sync read and sync write are disabled */
 	reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
 	reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
 	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
-	return 0;
 }
 
-static void set_onenand_cfg(void __iomem *onenand_base, int latency,
-				int sync_read, int sync_write, int hf, int vhf)
+static void set_onenand_cfg(void __iomem *onenand_base)
 {
 	u32 reg;
 
@@ -112,19 +119,19 @@ static void set_onenand_cfg(void __iomem *onenand_base, int latency,
 	reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9));
 	reg |=	(latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
 		ONENAND_SYS_CFG1_BL_16;
-	if (sync_read)
+	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
 		reg |= ONENAND_SYS_CFG1_SYNC_READ;
 	else
 		reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
-	if (sync_write)
+	if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
 		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
 	else
 		reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	if (hf)
+	if (onenand_flags & ONENAND_FLAG_HF)
 		reg |= ONENAND_SYS_CFG1_HF;
 	else
 		reg &= ~ONENAND_SYS_CFG1_HF;
-	if (vhf)
+	if (onenand_flags & ONENAND_FLAG_VHF)
 		reg |= ONENAND_SYS_CFG1_VHF;
 	else
 		reg &= ~ONENAND_SYS_CFG1_VHF;
@@ -172,9 +179,9 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
 	return freq;
 }
 
-static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
-					void __iomem *onenand_base,
-					int *freq_ptr)
+static struct gpmc_timings
+omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
+						int freq, bool clk_dep)
 {
 	struct gpmc_timings t;
 	const int t_cer  = 15;
@@ -184,29 +191,14 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 	const int t_wpl  = 40;
 	const int t_wph  = 30;
 	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-	int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency;
-	int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0;
-	int err, ticks_cez;
-	int cs = cfg->cs, freq = *freq_ptr;
-	u32 reg;
-	bool clk_dep = false;
-
-	if (cfg->flags & ONENAND_SYNC_READ) {
-		sync_read = 1;
-	} else if (cfg->flags & ONENAND_SYNC_READWRITE) {
-		sync_read = 1;
-		sync_write = 1;
-	} else
-		return omap2_onenand_set_async_mode(cs, onenand_base);
+	int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
+	int ticks_cez;
+	int cs = cfg->cs;
 
-	if (!freq) {
-		/* Very first call freq is not known */
-		err = omap2_onenand_set_async_mode(cs, onenand_base);
-		if (err)
-			return err;
-		freq = omap2_onenand_get_freq(cfg, onenand_base, &clk_dep);
-		first_time = 1;
-	}
+	if (cfg->flags & ONENAND_SYNC_READ)
+		onenand_flags = ONENAND_FLAG_SYNCREAD;
+	else if (cfg->flags & ONENAND_SYNC_READWRITE)
+		onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
 
 	switch (freq) {
 	case 104:
@@ -244,19 +236,23 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 		t_ach   = 9;
 		t_aavdh = 7;
 		t_rdyo  = 15;
-		sync_write = 0;
+		onenand_flags &= ~ONENAND_FLAG_SYNCWRITE;
 		break;
 	}
 
 	div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
 	gpmc_clk_ns = gpmc_ticks_to_ns(div);
 	if (gpmc_clk_ns < 15) /* >66Mhz */
-		hf = 1;
+		onenand_flags |= ONENAND_FLAG_HF;
+	else
+		onenand_flags &= ~ONENAND_FLAG_HF;
 	if (gpmc_clk_ns < 12) /* >83Mhz */
-		vhf = 1;
-	if (vhf)
+		onenand_flags |= ONENAND_FLAG_VHF;
+	else
+		onenand_flags &= ~ONENAND_FLAG_VHF;
+	if (onenand_flags & ONENAND_FLAG_VHF)
 		latency = 8;
-	else if (hf)
+	else if (onenand_flags & ONENAND_FLAG_HF)
 		latency = 6;
 	else if (gpmc_clk_ns >= 25) /* 40 MHz*/
 		latency = 3;
@@ -279,9 +275,8 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 		}
 	}
 
-	if (first_time)
-		set_onenand_cfg(onenand_base, latency,
-					sync_read, sync_write, hf, vhf);
+	/* Set synchronous read timings */
+	memset(&t, 0, sizeof(t));
 
 	if (div == 1) {
 		t.bool_timings.cs_extra_delay = true;
@@ -290,8 +285,6 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 		t.bool_timings.we_extra_delay = true;
 	}
 
-	/* Set synchronous read timings */
-	memset(&t, 0, sizeof(t));
 	t.sync_clk = min_gpmc_clk_period;
 	t.cs_on = 0;
 	t.adv_on = 0;
@@ -315,7 +308,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 	t.clk_activation = fclk_offset_ns;
 
 	/* Write */
-	if (sync_write) {
+	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
 		t.adv_wr_off = t.adv_rd_off;
 		t.we_on  = 0;
 		t.we_off = t.cs_rd_off;
@@ -340,6 +333,14 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 		}
 	}
 
+	return 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 |
@@ -355,11 +356,47 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 			  GPMC_CONFIG1_DEVICETYPE_NOR |
 			  GPMC_CONFIG1_MUXADDDATA);
 
-	err = gpmc_cs_set_timings(cs, &t);
-	if (err)
-		return err;
+	return gpmc_cs_set_timings(cs, t);
+}
+
+static int omap2_onenand_setup_async(void __iomem *onenand_base)
+{
+	struct gpmc_timings t;
+	int ret;
+
+	omap2_onenand_set_async_mode(onenand_base);
+
+	t = omap2_onenand_calc_async_timings();
+
+	ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
+	if (IS_ERR_VALUE(ret))
+		return ret;
+
+	omap2_onenand_set_async_mode(onenand_base);
+
+	return 0;
+}
+
+static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
+{
+	int ret, freq = *freq_ptr;
+	struct gpmc_timings t;
+	bool clk_dep = false;
+
+	if (!freq) {
+		/* Very first call freq is not known */
+		freq = omap2_onenand_get_freq(gpmc_onenand_data,
+						onenand_base, &clk_dep);
+		set_onenand_cfg(onenand_base);
+	}
+
+	t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq, clk_dep);
 
-	set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf, vhf);
+	ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
+	if (IS_ERR_VALUE(ret))
+		return ret;
+
+	set_onenand_cfg(onenand_base);
 
 	*freq_ptr = freq;
 
@@ -369,15 +406,22 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
 static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
 {
 	struct device *dev = &gpmc_onenand_device.dev;
+	unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE;
+	int ret;
 
-	/* Set sync timings in GPMC */
-	if (omap2_onenand_set_sync_mode(gpmc_onenand_data, onenand_base,
-			freq_ptr) < 0) {
-		dev_err(dev, "Unable to set synchronous mode\n");
-		return -EINVAL;
+	ret = omap2_onenand_setup_async(onenand_base);
+	if (ret) {
+		dev_err(dev, "unable to set to async mode\n");
+		return ret;
 	}
 
-	return 0;
+	if (!(gpmc_onenand_data->flags & l))
+		return 0;
+
+	ret = omap2_onenand_setup_sync(onenand_base, freq_ptr);
+	if (ret)
+		dev_err(dev, "unable to set to sync mode\n");
+	return ret;
 }
 
 void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
-- 
1.7.1

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

* [PATCH v6 04/10] ARM: OMAP2+: GPMC: Remove unused OneNAND get_freq() platform function
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:45   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

From: Jon Hunter <jon-hunter@ti.com>

A platform function pointer for getting the frequency of a OneNAND device
was added so that a platform could specify a custom function for returning
the frequency and not just rely on the OneNAND version to determine the
frequency. However, this platform function pointer is not currently being
used and I am not sure if it ever has.

OneNAND devices are not so common these days and as far as I know not being
used with new devices. Therefore, it is most likely that this get_freq()
function pointer will not be used and so remove it.

Given that the get_freq() function pointer is not used, neither is the
clk_dep variable and so all references to it can also be removed.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c        |   39 +++-------------------------
 arch/arm/plat-omap/include/plat/onenand.h |    8 ------
 2 files changed, 5 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index bbae674..8a301f3 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -139,21 +139,10 @@ static void set_onenand_cfg(void __iomem *onenand_base)
 }
 
 static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
-				  void __iomem *onenand_base, bool *clk_dep)
+				  void __iomem *onenand_base)
 {
 	u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
-	int freq = 0;
-
-	if (cfg->get_freq) {
-		struct onenand_freq_info fi;
-
-		fi.maf_id = readw(onenand_base + ONENAND_REG_MANUFACTURER_ID);
-		fi.dev_id = readw(onenand_base + ONENAND_REG_DEVICE_ID);
-		fi.ver_id = ver;
-		freq = cfg->get_freq(&fi, clk_dep);
-		if (freq)
-			return freq;
-	}
+	int freq;
 
 	switch ((ver >> 4) & 0xf) {
 	case 0:
@@ -181,7 +170,7 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
 
 static struct gpmc_timings
 omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
-						int freq, bool clk_dep)
+						int freq)
 {
 	struct gpmc_timings t;
 	const int t_cer  = 15;
@@ -259,22 +248,6 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 	else
 		latency = 4;
 
-	if (clk_dep) {
-		if (gpmc_clk_ns < 12) { /* >83Mhz */
-			t_ces   = 3;
-			t_avds  = 4;
-		} else if (gpmc_clk_ns < 15) { /* >66Mhz */
-			t_ces   = 5;
-			t_avds  = 4;
-		} else if (gpmc_clk_ns < 25) { /* >40Mhz */
-			t_ces   = 6;
-			t_avds  = 5;
-		} else {
-			t_ces   = 7;
-			t_avds  = 7;
-		}
-	}
-
 	/* Set synchronous read timings */
 	memset(&t, 0, sizeof(t));
 
@@ -381,16 +354,14 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
 {
 	int ret, freq = *freq_ptr;
 	struct gpmc_timings t;
-	bool clk_dep = false;
 
 	if (!freq) {
 		/* Very first call freq is not known */
-		freq = omap2_onenand_get_freq(gpmc_onenand_data,
-						onenand_base, &clk_dep);
+		freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
 		set_onenand_cfg(onenand_base);
 	}
 
-	t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq, clk_dep);
+	t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq);
 
 	ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
 	if (IS_ERR_VALUE(ret))
diff --git a/arch/arm/plat-omap/include/plat/onenand.h b/arch/arm/plat-omap/include/plat/onenand.h
index 2858667..21bb0ff 100644
--- a/arch/arm/plat-omap/include/plat/onenand.h
+++ b/arch/arm/plat-omap/include/plat/onenand.h
@@ -15,20 +15,12 @@
 #define ONENAND_SYNC_READ	(1 << 0)
 #define ONENAND_SYNC_READWRITE	(1 << 1)
 
-struct onenand_freq_info {
-	u16			maf_id;
-	u16			dev_id;
-	u16			ver_id;
-};
-
 struct omap_onenand_platform_data {
 	int			cs;
 	int			gpio_irq;
 	struct mtd_partition	*parts;
 	int			nr_parts;
 	int			(*onenand_setup)(void __iomem *, int *freq_ptr);
-	int		(*get_freq)(const struct onenand_freq_info *freq_info,
-				    bool *clk_dep);
 	int			dma_channel;
 	u8			flags;
 	u8			regulator_can_sleep;
-- 
1.7.1


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

* [PATCH v6 04/10] ARM: OMAP2+: GPMC: Remove unused OneNAND get_freq() platform function
@ 2012-08-21 10:45   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Hunter <jon-hunter@ti.com>

A platform function pointer for getting the frequency of a OneNAND device
was added so that a platform could specify a custom function for returning
the frequency and not just rely on the OneNAND version to determine the
frequency. However, this platform function pointer is not currently being
used and I am not sure if it ever has.

OneNAND devices are not so common these days and as far as I know not being
used with new devices. Therefore, it is most likely that this get_freq()
function pointer will not be used and so remove it.

Given that the get_freq() function pointer is not used, neither is the
clk_dep variable and so all references to it can also be removed.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c        |   39 +++-------------------------
 arch/arm/plat-omap/include/plat/onenand.h |    8 ------
 2 files changed, 5 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index bbae674..8a301f3 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -139,21 +139,10 @@ static void set_onenand_cfg(void __iomem *onenand_base)
 }
 
 static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
-				  void __iomem *onenand_base, bool *clk_dep)
+				  void __iomem *onenand_base)
 {
 	u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
-	int freq = 0;
-
-	if (cfg->get_freq) {
-		struct onenand_freq_info fi;
-
-		fi.maf_id = readw(onenand_base + ONENAND_REG_MANUFACTURER_ID);
-		fi.dev_id = readw(onenand_base + ONENAND_REG_DEVICE_ID);
-		fi.ver_id = ver;
-		freq = cfg->get_freq(&fi, clk_dep);
-		if (freq)
-			return freq;
-	}
+	int freq;
 
 	switch ((ver >> 4) & 0xf) {
 	case 0:
@@ -181,7 +170,7 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
 
 static struct gpmc_timings
 omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
-						int freq, bool clk_dep)
+						int freq)
 {
 	struct gpmc_timings t;
 	const int t_cer  = 15;
@@ -259,22 +248,6 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 	else
 		latency = 4;
 
-	if (clk_dep) {
-		if (gpmc_clk_ns < 12) { /* >83Mhz */
-			t_ces   = 3;
-			t_avds  = 4;
-		} else if (gpmc_clk_ns < 15) { /* >66Mhz */
-			t_ces   = 5;
-			t_avds  = 4;
-		} else if (gpmc_clk_ns < 25) { /* >40Mhz */
-			t_ces   = 6;
-			t_avds  = 5;
-		} else {
-			t_ces   = 7;
-			t_avds  = 7;
-		}
-	}
-
 	/* Set synchronous read timings */
 	memset(&t, 0, sizeof(t));
 
@@ -381,16 +354,14 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
 {
 	int ret, freq = *freq_ptr;
 	struct gpmc_timings t;
-	bool clk_dep = false;
 
 	if (!freq) {
 		/* Very first call freq is not known */
-		freq = omap2_onenand_get_freq(gpmc_onenand_data,
-						onenand_base, &clk_dep);
+		freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
 		set_onenand_cfg(onenand_base);
 	}
 
-	t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq, clk_dep);
+	t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq);
 
 	ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
 	if (IS_ERR_VALUE(ret))
diff --git a/arch/arm/plat-omap/include/plat/onenand.h b/arch/arm/plat-omap/include/plat/onenand.h
index 2858667..21bb0ff 100644
--- a/arch/arm/plat-omap/include/plat/onenand.h
+++ b/arch/arm/plat-omap/include/plat/onenand.h
@@ -15,20 +15,12 @@
 #define ONENAND_SYNC_READ	(1 << 0)
 #define ONENAND_SYNC_READWRITE	(1 << 1)
 
-struct onenand_freq_info {
-	u16			maf_id;
-	u16			dev_id;
-	u16			ver_id;
-};
-
 struct omap_onenand_platform_data {
 	int			cs;
 	int			gpio_irq;
 	struct mtd_partition	*parts;
 	int			nr_parts;
 	int			(*onenand_setup)(void __iomem *, int *freq_ptr);
-	int		(*get_freq)(const struct onenand_freq_info *freq_info,
-				    bool *clk_dep);
 	int			dma_channel;
 	u8			flags;
 	u8			regulator_can_sleep;
-- 
1.7.1

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

* [PATCH v6 05/10] ARM: OMAP2+: gpmc: find features by ip rev check
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:45   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Newer IP's have wr_access and wr_data_mux_bus fields. Use
IP revision values to determine availability of these
fields and hence decide on whether to configure them.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 070fac5..68123d0 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -85,6 +85,11 @@
 #define ENABLE_PREFETCH		(0x1 << 7)
 #define DMA_MPU_MODE		2
 
+#define	GPMC_REVISION_MAJOR(l)		((l >> 4) & 0xf)
+
+#define	GPMC_HAS_WR_ACCESS		0x1
+#define	GPMC_HAS_WR_DATA_MUX_BUS	0x2
+
 /* XXX: Only NAND irq has been considered,currently these are the only ones used
  */
 #define	GPMC_NR_IRQ		2
@@ -131,6 +136,7 @@ static DEFINE_SPINLOCK(gpmc_mem_lock);
 static unsigned int gpmc_cs_map;	/* flag for cs which are initialized */
 static int gpmc_ecc_used = -EINVAL;	/* cs using ecc engine */
 
+static unsigned gpmc_capability;
 static void __iomem *gpmc_base;
 
 static struct clk *gpmc_l3_clk;
@@ -356,10 +362,10 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
 	GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
 
-	if (cpu_is_omap34xx()) {
+	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
 		GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
+	if (gpmc_capability & GPMC_HAS_WR_ACCESS)
 		GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
-	}
 
 	/* caller is expected to have initialized CONFIG1 to cover
 	 * at least sync vs async
@@ -922,6 +928,8 @@ static int __init gpmc_init(void)
 	clk_enable(gpmc_l3_clk);
 
 	l = gpmc_read_reg(GPMC_REVISION);
+	if (GPMC_REVISION_MAJOR(l) > 0x4)
+		gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
 	printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
 	/* Set smart idle mode and automatic L3 clock gating */
 	l = gpmc_read_reg(GPMC_SYSCONFIG);
-- 
1.7.1


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

* [PATCH v6 05/10] ARM: OMAP2+: gpmc: find features by ip rev check
@ 2012-08-21 10:45   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

Newer IP's have wr_access and wr_data_mux_bus fields. Use
IP revision values to determine availability of these
fields and hence decide on whether to configure them.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 070fac5..68123d0 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -85,6 +85,11 @@
 #define ENABLE_PREFETCH		(0x1 << 7)
 #define DMA_MPU_MODE		2
 
+#define	GPMC_REVISION_MAJOR(l)		((l >> 4) & 0xf)
+
+#define	GPMC_HAS_WR_ACCESS		0x1
+#define	GPMC_HAS_WR_DATA_MUX_BUS	0x2
+
 /* XXX: Only NAND irq has been considered,currently these are the only ones used
  */
 #define	GPMC_NR_IRQ		2
@@ -131,6 +136,7 @@ static DEFINE_SPINLOCK(gpmc_mem_lock);
 static unsigned int gpmc_cs_map;	/* flag for cs which are initialized */
 static int gpmc_ecc_used = -EINVAL;	/* cs using ecc engine */
 
+static unsigned gpmc_capability;
 static void __iomem *gpmc_base;
 
 static struct clk *gpmc_l3_clk;
@@ -356,10 +362,10 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
 	GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
 
-	if (cpu_is_omap34xx()) {
+	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
 		GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
+	if (gpmc_capability & GPMC_HAS_WR_ACCESS)
 		GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
-	}
 
 	/* caller is expected to have initialized CONFIG1 to cover
 	 * at least sync vs async
@@ -922,6 +928,8 @@ static int __init gpmc_init(void)
 	clk_enable(gpmc_l3_clk);
 
 	l = gpmc_read_reg(GPMC_REVISION);
+	if (GPMC_REVISION_MAJOR(l) > 0x4)
+		gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
 	printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
 	/* Set smart idle mode and automatic L3 clock gating */
 	l = gpmc_read_reg(GPMC_SYSCONFIG);
-- 
1.7.1

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

* [PATCH v6 06/10] ARM: OMAP2+: gpmc: remove cs# in sync clk div calc
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:45   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Divider value for a certain sync clk is determined solely
based on gpmc fclk. CS# does not have any role here, thus
remove presence of CS# in clock divider calculation API.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c     |    3 +--
 arch/arm/mach-omap2/gpmc.c             |    4 ++--
 arch/arm/plat-omap/include/plat/gpmc.h |    2 +-
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 8a301f3..e139e3f 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -182,7 +182,6 @@ 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, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
 	int ticks_cez;
-	int cs = cfg->cs;
 
 	if (cfg->flags & ONENAND_SYNC_READ)
 		onenand_flags = ONENAND_FLAG_SYNCREAD;
@@ -229,7 +228,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 		break;
 	}
 
-	div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
+	div = gpmc_calc_divider(min_gpmc_clk_period);
 	gpmc_clk_ns = gpmc_ticks_to_ns(div);
 	if (gpmc_clk_ns < 15) /* >66Mhz */
 		onenand_flags |= ONENAND_FLAG_HF;
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 68123d0..d005b3a 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -313,7 +313,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 		return -1
 #endif
 
-int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
+int gpmc_calc_divider(unsigned int sync_clk)
 {
 	int div;
 	u32 l;
@@ -333,7 +333,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	int div;
 	u32 l;
 
-	div = gpmc_cs_calc_divider(cs, t->sync_clk);
+	div = gpmc_calc_divider(t->sync_clk);
 	if (div < 0)
 		return -1;
 
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index b7c9ea6..1cafbfd 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -179,7 +179,7 @@ extern unsigned long gpmc_get_fclk_period(void);
 
 extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
 extern u32 gpmc_cs_read_reg(int cs, int idx);
-extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
+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_request(int cs, unsigned long size, unsigned long *base);
 extern void gpmc_cs_free(int cs);
-- 
1.7.1


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

* [PATCH v6 06/10] ARM: OMAP2+: gpmc: remove cs# in sync clk div calc
@ 2012-08-21 10:45   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

Divider value for a certain sync clk is determined solely
based on gpmc fclk. CS# does not have any role here, thus
remove presence of CS# in clock divider calculation API.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c     |    3 +--
 arch/arm/mach-omap2/gpmc.c             |    4 ++--
 arch/arm/plat-omap/include/plat/gpmc.h |    2 +-
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 8a301f3..e139e3f 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -182,7 +182,6 @@ 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, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
 	int ticks_cez;
-	int cs = cfg->cs;
 
 	if (cfg->flags & ONENAND_SYNC_READ)
 		onenand_flags = ONENAND_FLAG_SYNCREAD;
@@ -229,7 +228,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 		break;
 	}
 
-	div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
+	div = gpmc_calc_divider(min_gpmc_clk_period);
 	gpmc_clk_ns = gpmc_ticks_to_ns(div);
 	if (gpmc_clk_ns < 15) /* >66Mhz */
 		onenand_flags |= ONENAND_FLAG_HF;
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 68123d0..d005b3a 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -313,7 +313,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 		return -1
 #endif
 
-int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
+int gpmc_calc_divider(unsigned int sync_clk)
 {
 	int div;
 	u32 l;
@@ -333,7 +333,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	int div;
 	u32 l;
 
-	div = gpmc_cs_calc_divider(cs, t->sync_clk);
+	div = gpmc_calc_divider(t->sync_clk);
 	if (div < 0)
 		return -1;
 
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index b7c9ea6..1cafbfd 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -179,7 +179,7 @@ extern unsigned long gpmc_get_fclk_period(void);
 
 extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
 extern u32 gpmc_cs_read_reg(int cs, int idx);
-extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
+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_request(int cs, unsigned long size, unsigned long *base);
 extern void gpmc_cs_free(int cs);
-- 
1.7.1

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

* [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:45   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Presently there are three peripherals that gets it timing
by runtime calculation. Those peripherals can work with
frequency scaling that affects gpmc clock. But timing
calculation for them are in different ways.

Here a generic runtime calculation method is proposed. Input
to this function were selected so that they represent timing
variables that are present in peripheral datasheets. Motive
behind this was to achieve DT bindings for the inputs as is.
Even though a few of the tusb6010 timings could not be made
directly related to timings normally found on peripherals,
expressions used were translated to those that could be
justified.

There are possibilities of improving the calculations, like
calculating timing for read & write operations in a more
similar way. Expressions derived here were tested for async
onenand on omap3evm (as vanilla Kernel does not have omap3evm
onenand support, local patch was used). Other peripherals,
tusb6010, smc91x calculations were validated by simulating
on omap3evm.

Regarding "we_on" for onenand async, it was found that even
for muxed address/data, it need not be greater than
"adv_wr_off", but rather could be derived from write setup
time for peripheral from start of access time, hence would
more be in line with peripheral timings. With this method
it was working fine. If it is required in some cases to
have "we_on" same as "wr_data_mux_bus" (i.e. greater than
"adv_wr_off"), another variable could be added to indicate
it. But such a requirement is not expected though.

Whole of this exercise is being done to achieve driver and
DT conversion. If timings could not be calculated in a
peripheral agnostic way, either gpmc driver would have to
be peripheral gnostic or a wrapper arrangement over gpmc
driver would be required.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc.c             |  302 ++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/gpmc.h |   61 +++++++
 2 files changed, 363 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index d005b3a..d8e5b08 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -233,6 +233,18 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
 	return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+unsigned int gpmc_ticks_to_ps(unsigned int ticks)
+{
+	return ticks * gpmc_get_fclk_period();
+}
+
+unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
+{
+	unsigned long ticks = gpmc_ps_to_ticks(time_ps);
+
+	return ticks * gpmc_get_fclk_period();
+}
+
 static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
 {
 	u32 l;
@@ -884,6 +896,296 @@ static void __init gpmc_mem_init(void)
 	}
 }
 
+static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
+{
+	u32 temp;
+	int div;
+
+	div = gpmc_calc_divider(sync_clk);
+	temp = gpmc_ps_to_ticks(time_ps);
+	temp = (temp + div - 1) / div;
+	return gpmc_ticks_to_ps(temp * div);
+}
+
+/* can the cycles be avoided ? */
+static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_rd_off */
+	temp = dev_t->t_avdp_r;
+	/* mux check required ? */
+	if (mux) {
+		/* t_avdp not to be required for sync, only added for tusb this
+		 * indirectly necessitates requirement of t_avdp_r & t_avdp_w
+		 * instead of having a single t_avdp
+		 */
+		temp = max_t(u32, temp,	gpmc_t->clk_activation * 1000 +
+							dev_t->t_avdh);
+		temp = max_t(u32,
+			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+	}
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* oe_on */
+	temp = dev_t->t_oeasu; /* remove this ? */
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->clk_activation * 1000 + dev_t->t_ach);
+		temp = max_t(u32, temp, (gpmc_t->adv_rd_off +
+				gpmc_ticks_to_ns(dev_t->cyc_aavdh_oe)) * 1000);
+	}
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* access */
+	/* any scope for improvement ?, by combining oe_on & clk_activation,
+	 * need to check whether access = clk_activation + round to sync clk ?
+	 */
+	temp = max_t(u32, dev_t->t_iaa,	dev_t->cyc_iaa * gpmc_t->sync_clk);
+	temp += gpmc_t->clk_activation * 1000;
+	if (dev_t->cyc_oe)
+		temp = max_t(u32, temp, (gpmc_t->oe_on +
+				gpmc_ticks_to_ns(dev_t->cyc_oe)) * 1000);
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+	/* rd_cycle */
+	temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
+	temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
+							gpmc_t->access * 1000;
+	/* barter t_ce_rdyz with t_cez_r ? */
+	if (dev_t->t_ce_rdyz)
+		temp = max_t(u32, temp,
+				gpmc_t->cs_rd_off * 1000 + dev_t->t_ce_rdyz);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	return 0;
+}
+
+static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_wr_off */
+	temp = dev_t->t_avdp_w;
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->clk_activation * 1000 + dev_t->t_avdh);
+		temp = max_t(u32,
+			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+	}
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* wr_data_mux_bus */
+	temp = max_t(u32, dev_t->t_weasu,
+			gpmc_t->clk_activation * 1000 + dev_t->t_rdyo);
+	/* shouldn't mux be kept as a whole for wr_data_mux_bus ?,
+	 * and in that case remember to handle we_on properly
+	 */
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
+		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+	}
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* we_on */
+	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+	else
+		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+	/* wr_access */
+	/* gpmc_capability check reqd ? , even if not, will not harm */
+	gpmc_t->wr_access = gpmc_t->access;
+
+	/* we_off */
+	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
+	temp = max_t(u32, temp,
+			(gpmc_t->wr_access + gpmc_ticks_to_ns(1)) * 1000);
+	temp = max_t(u32, temp,
+		(gpmc_t->we_on + gpmc_ticks_to_ns(dev_t->cyc_wpl)) * 1000);
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off * 1000 +
+							dev_t->t_wph) / 1000;
+
+	/* wr_cycle */
+	temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
+	temp += gpmc_t->wr_access * 1000;
+	/* barter t_ce_rdyz with t_cez_w ? */
+	if (dev_t->t_ce_rdyz)
+		temp = max_t(u32, temp,
+				 gpmc_t->cs_wr_off * 1000 + dev_t->t_ce_rdyz);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	return 0;
+}
+
+static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_rd_off */
+	temp = dev_t->t_avdp_r;
+	if (mux)
+		temp = max_t(u32,
+			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* oe_on */
+	temp = dev_t->t_oeasu;
+	if (mux)
+		temp = max_t(u32, temp,
+			gpmc_t->adv_rd_off * 1000 + dev_t->t_aavdh);
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* access */
+	temp = max_t(u32, dev_t->t_iaa, /* remove t_iaa in async ? */
+				gpmc_t->oe_on * 1000 + dev_t->t_oe);
+	temp = max_t(u32, temp,
+				gpmc_t->cs_on * 1000 + dev_t->t_ce);
+	temp = max_t(u32, temp,
+				gpmc_t->adv_on * 1000 + dev_t->t_aa);
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+	/* rd_cycle */
+	temp = max_t(u32, dev_t->t_rd_cycle,
+			gpmc_t->cs_rd_off * 1000 + dev_t->t_cez_r);
+	temp = max_t(u32, temp,
+			gpmc_t->oe_off * 1000 + dev_t->t_oez);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	return 0;
+}
+
+static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_wr_off */
+	temp = dev_t->t_avdp_w;
+	if (mux)
+		temp = max_t(u32,
+			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* wr_data_mux_bus */
+	temp = dev_t->t_weasu;
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
+		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+	}
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* we_on */
+	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+	else
+		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+	/* we_off */
+	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks((gpmc_t->we_off * 1000 +
+				dev_t->t_wph)) / 1000;
+
+	/* wr_cycle */
+	temp = max_t(u32, dev_t->t_wr_cycle,
+				gpmc_t->cs_wr_off * 1000 + dev_t->t_cez_w);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	return 0;
+}
+
+static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
+			struct gpmc_device_timings *dev_t)
+{
+	u32 temp;
+
+	gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) *
+						gpmc_get_fclk_period();
+
+	gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
+					dev_t->t_bacc,
+					gpmc_t->sync_clk) / 1000;
+
+	temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
+	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
+		return 0;
+
+	if (dev_t->ce_xdelay)
+		gpmc_t->bool_timings.cs_extra_delay = true;
+	if (dev_t->avd_xdelay)
+		gpmc_t->bool_timings.adv_extra_delay = true;
+	if (dev_t->oe_xdelay)
+		gpmc_t->bool_timings.oe_extra_delay = true;
+	if (dev_t->we_xdelay)
+		gpmc_t->bool_timings.we_extra_delay = true;
+
+	return 0;
+}
+
+static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
+			struct gpmc_device_timings *dev_t)
+{
+	u32 temp;
+
+	/* cs_on */
+	gpmc_t->cs_on = gpmc_round_ns_to_ticks(dev_t->t_ceasu / 1000);
+
+	/* adv_on */
+	temp = dev_t->t_avdasu;
+	if (dev_t->t_ce_avd)
+		temp = max_t(u32, temp,
+				gpmc_t->cs_on * 1000 + dev_t->t_ce_avd);
+	gpmc_t->adv_on = gpmc_round_ns_to_ticks(temp / 1000);
+
+	if (dev_t->sync_write || dev_t->sync_read)
+		gpmc_calc_sync_common_timings(gpmc_t, dev_t);
+
+	return 0;
+}
+
+int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+			struct gpmc_device_timings *dev_t)
+{
+	memset(gpmc_t, 0, sizeof(*gpmc_t));
+
+	gpmc_calc_common_timings(gpmc_t, dev_t);
+
+	if (dev_t->sync_read)
+		gpmc_calc_sync_read_timings(gpmc_t, dev_t);
+	else
+		gpmc_calc_async_read_timings(gpmc_t, dev_t);
+
+	if (dev_t->sync_write)
+		gpmc_calc_sync_write_timings(gpmc_t, dev_t);
+	else
+		gpmc_calc_async_write_timings(gpmc_t, dev_t);
+
+	return 0;
+}
+
 static int __init gpmc_init(void)
 {
 	u32 l;
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 1cafbfd..e59a932 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -152,6 +152,67 @@ struct gpmc_timings {
 	struct gpmc_bool_timings bool_timings;
 };
 
+/* Device timings in picoseconds */
+struct gpmc_device_timings {
+	u32     t_ceasu;	/* address setup to CS valid */
+	u32     t_avdasu;	/* address setup to ADV valid */
+	/* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
+	 * of tusb using these timings even for sync whilst
+	 * ideally for adv_rd/(wr)_off it should have considered
+	 * t_avdh instead. This indirectly necessitates r/w
+	 * variations of t_avdp as it is possible to have one
+	 * sync & other async
+	 */
+	u32	t_avdp_r;	/* ADV low time (what about t_cer ?) */
+	u32	t_avdp_w;
+	u32	t_aavdh;	/* address hold time */
+	u32     t_oeasu;	/* address setup to OE valid */
+	u32     t_aa;		/* access time from ADV assertion */
+	u32     t_iaa;		/* initial access time */
+	u32     t_oe;		/* access time from OE assertion */
+	u32     t_ce;		/* access time from CS asertion */
+	u32     t_rd_cycle;	/* read cycle time */
+	u32     t_cez_r;	/* read CS deassertion to high Z */
+	u32     t_cez_w;	/* write CS deassertion to high Z */
+	u32     t_oez;		/* OE deassertion to high Z */
+	u32     t_weasu;	/* address setup to WE valid */
+	u32     t_wpl;		/* write assertion time */
+	u32     t_wph;		/* write deassertion time */
+	u32     t_wr_cycle;	/* write cycle time */
+
+	u32	clk;
+	u32	t_bacc;		/* burst access valid clock to output delay */
+	u32	t_ces;		/* CS setup time to clk */
+	u32	t_avds;		/* ADV setup time to clk */
+	u32	t_avdh;		/* ADV hold time from clk */
+	u32     t_ach;		/* address hold time from clk */
+	u32	t_rdyo;		/* clk to ready valid */
+
+	u32	t_ce_rdyz;	/* XXX: description ?, or use t_cez instead */
+	u32	t_ce_avd;	/* CS on to ADV on delay */
+
+	/* XXX: check the possibility of combining
+	 * cyc_aavhd_oe & cyc_aavdh_we
+	 */
+	u8	cyc_aavdh_oe;
+	u8	cyc_aavdh_we;
+	u8	cyc_oe;
+	u8	cyc_wpl;
+	u32     cyc_iaa;
+
+	bool	mux;		/* address & data muxed */
+	bool	sync_write;	/* synchronous write */
+	bool	sync_read;	/* synchronous read */
+
+	bool	ce_xdelay;
+	bool	avd_xdelay;
+	bool	oe_xdelay;
+	bool	we_xdelay;
+};
+
+extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t);
+
 struct gpmc_nand_regs {
 	void __iomem	*gpmc_status;
 	void __iomem	*gpmc_nand_command;
-- 
1.7.1


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

* [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
@ 2012-08-21 10:45   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

Presently there are three peripherals that gets it timing
by runtime calculation. Those peripherals can work with
frequency scaling that affects gpmc clock. But timing
calculation for them are in different ways.

Here a generic runtime calculation method is proposed. Input
to this function were selected so that they represent timing
variables that are present in peripheral datasheets. Motive
behind this was to achieve DT bindings for the inputs as is.
Even though a few of the tusb6010 timings could not be made
directly related to timings normally found on peripherals,
expressions used were translated to those that could be
justified.

There are possibilities of improving the calculations, like
calculating timing for read & write operations in a more
similar way. Expressions derived here were tested for async
onenand on omap3evm (as vanilla Kernel does not have omap3evm
onenand support, local patch was used). Other peripherals,
tusb6010, smc91x calculations were validated by simulating
on omap3evm.

Regarding "we_on" for onenand async, it was found that even
for muxed address/data, it need not be greater than
"adv_wr_off", but rather could be derived from write setup
time for peripheral from start of access time, hence would
more be in line with peripheral timings. With this method
it was working fine. If it is required in some cases to
have "we_on" same as "wr_data_mux_bus" (i.e. greater than
"adv_wr_off"), another variable could be added to indicate
it. But such a requirement is not expected though.

Whole of this exercise is being done to achieve driver and
DT conversion. If timings could not be calculated in a
peripheral agnostic way, either gpmc driver would have to
be peripheral gnostic or a wrapper arrangement over gpmc
driver would be required.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc.c             |  302 ++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/gpmc.h |   61 +++++++
 2 files changed, 363 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index d005b3a..d8e5b08 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -233,6 +233,18 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
 	return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+unsigned int gpmc_ticks_to_ps(unsigned int ticks)
+{
+	return ticks * gpmc_get_fclk_period();
+}
+
+unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
+{
+	unsigned long ticks = gpmc_ps_to_ticks(time_ps);
+
+	return ticks * gpmc_get_fclk_period();
+}
+
 static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
 {
 	u32 l;
@@ -884,6 +896,296 @@ static void __init gpmc_mem_init(void)
 	}
 }
 
+static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
+{
+	u32 temp;
+	int div;
+
+	div = gpmc_calc_divider(sync_clk);
+	temp = gpmc_ps_to_ticks(time_ps);
+	temp = (temp + div - 1) / div;
+	return gpmc_ticks_to_ps(temp * div);
+}
+
+/* can the cycles be avoided ? */
+static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_rd_off */
+	temp = dev_t->t_avdp_r;
+	/* mux check required ? */
+	if (mux) {
+		/* t_avdp not to be required for sync, only added for tusb this
+		 * indirectly necessitates requirement of t_avdp_r & t_avdp_w
+		 * instead of having a single t_avdp
+		 */
+		temp = max_t(u32, temp,	gpmc_t->clk_activation * 1000 +
+							dev_t->t_avdh);
+		temp = max_t(u32,
+			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+	}
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* oe_on */
+	temp = dev_t->t_oeasu; /* remove this ? */
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->clk_activation * 1000 + dev_t->t_ach);
+		temp = max_t(u32, temp, (gpmc_t->adv_rd_off +
+				gpmc_ticks_to_ns(dev_t->cyc_aavdh_oe)) * 1000);
+	}
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* access */
+	/* any scope for improvement ?, by combining oe_on & clk_activation,
+	 * need to check whether access = clk_activation + round to sync clk ?
+	 */
+	temp = max_t(u32, dev_t->t_iaa,	dev_t->cyc_iaa * gpmc_t->sync_clk);
+	temp += gpmc_t->clk_activation * 1000;
+	if (dev_t->cyc_oe)
+		temp = max_t(u32, temp, (gpmc_t->oe_on +
+				gpmc_ticks_to_ns(dev_t->cyc_oe)) * 1000);
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+	/* rd_cycle */
+	temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
+	temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
+							gpmc_t->access * 1000;
+	/* barter t_ce_rdyz with t_cez_r ? */
+	if (dev_t->t_ce_rdyz)
+		temp = max_t(u32, temp,
+				gpmc_t->cs_rd_off * 1000 + dev_t->t_ce_rdyz);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	return 0;
+}
+
+static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_wr_off */
+	temp = dev_t->t_avdp_w;
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->clk_activation * 1000 + dev_t->t_avdh);
+		temp = max_t(u32,
+			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+	}
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* wr_data_mux_bus */
+	temp = max_t(u32, dev_t->t_weasu,
+			gpmc_t->clk_activation * 1000 + dev_t->t_rdyo);
+	/* shouldn't mux be kept as a whole for wr_data_mux_bus ?,
+	 * and in that case remember to handle we_on properly
+	 */
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
+		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+	}
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* we_on */
+	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+	else
+		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+	/* wr_access */
+	/* gpmc_capability check reqd ? , even if not, will not harm */
+	gpmc_t->wr_access = gpmc_t->access;
+
+	/* we_off */
+	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
+	temp = max_t(u32, temp,
+			(gpmc_t->wr_access + gpmc_ticks_to_ns(1)) * 1000);
+	temp = max_t(u32, temp,
+		(gpmc_t->we_on + gpmc_ticks_to_ns(dev_t->cyc_wpl)) * 1000);
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off * 1000 +
+							dev_t->t_wph) / 1000;
+
+	/* wr_cycle */
+	temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
+	temp += gpmc_t->wr_access * 1000;
+	/* barter t_ce_rdyz with t_cez_w ? */
+	if (dev_t->t_ce_rdyz)
+		temp = max_t(u32, temp,
+				 gpmc_t->cs_wr_off * 1000 + dev_t->t_ce_rdyz);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	return 0;
+}
+
+static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_rd_off */
+	temp = dev_t->t_avdp_r;
+	if (mux)
+		temp = max_t(u32,
+			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* oe_on */
+	temp = dev_t->t_oeasu;
+	if (mux)
+		temp = max_t(u32, temp,
+			gpmc_t->adv_rd_off * 1000 + dev_t->t_aavdh);
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* access */
+	temp = max_t(u32, dev_t->t_iaa, /* remove t_iaa in async ? */
+				gpmc_t->oe_on * 1000 + dev_t->t_oe);
+	temp = max_t(u32, temp,
+				gpmc_t->cs_on * 1000 + dev_t->t_ce);
+	temp = max_t(u32, temp,
+				gpmc_t->adv_on * 1000 + dev_t->t_aa);
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+	/* rd_cycle */
+	temp = max_t(u32, dev_t->t_rd_cycle,
+			gpmc_t->cs_rd_off * 1000 + dev_t->t_cez_r);
+	temp = max_t(u32, temp,
+			gpmc_t->oe_off * 1000 + dev_t->t_oez);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	return 0;
+}
+
+static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_wr_off */
+	temp = dev_t->t_avdp_w;
+	if (mux)
+		temp = max_t(u32,
+			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* wr_data_mux_bus */
+	temp = dev_t->t_weasu;
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
+		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+	}
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	/* we_on */
+	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+	else
+		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+	/* we_off */
+	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks((gpmc_t->we_off * 1000 +
+				dev_t->t_wph)) / 1000;
+
+	/* wr_cycle */
+	temp = max_t(u32, dev_t->t_wr_cycle,
+				gpmc_t->cs_wr_off * 1000 + dev_t->t_cez_w);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	return 0;
+}
+
+static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
+			struct gpmc_device_timings *dev_t)
+{
+	u32 temp;
+
+	gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) *
+						gpmc_get_fclk_period();
+
+	gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
+					dev_t->t_bacc,
+					gpmc_t->sync_clk) / 1000;
+
+	temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
+	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp) / 1000;
+
+	if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
+		return 0;
+
+	if (dev_t->ce_xdelay)
+		gpmc_t->bool_timings.cs_extra_delay = true;
+	if (dev_t->avd_xdelay)
+		gpmc_t->bool_timings.adv_extra_delay = true;
+	if (dev_t->oe_xdelay)
+		gpmc_t->bool_timings.oe_extra_delay = true;
+	if (dev_t->we_xdelay)
+		gpmc_t->bool_timings.we_extra_delay = true;
+
+	return 0;
+}
+
+static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
+			struct gpmc_device_timings *dev_t)
+{
+	u32 temp;
+
+	/* cs_on */
+	gpmc_t->cs_on = gpmc_round_ns_to_ticks(dev_t->t_ceasu / 1000);
+
+	/* adv_on */
+	temp = dev_t->t_avdasu;
+	if (dev_t->t_ce_avd)
+		temp = max_t(u32, temp,
+				gpmc_t->cs_on * 1000 + dev_t->t_ce_avd);
+	gpmc_t->adv_on = gpmc_round_ns_to_ticks(temp / 1000);
+
+	if (dev_t->sync_write || dev_t->sync_read)
+		gpmc_calc_sync_common_timings(gpmc_t, dev_t);
+
+	return 0;
+}
+
+int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+			struct gpmc_device_timings *dev_t)
+{
+	memset(gpmc_t, 0, sizeof(*gpmc_t));
+
+	gpmc_calc_common_timings(gpmc_t, dev_t);
+
+	if (dev_t->sync_read)
+		gpmc_calc_sync_read_timings(gpmc_t, dev_t);
+	else
+		gpmc_calc_async_read_timings(gpmc_t, dev_t);
+
+	if (dev_t->sync_write)
+		gpmc_calc_sync_write_timings(gpmc_t, dev_t);
+	else
+		gpmc_calc_async_write_timings(gpmc_t, dev_t);
+
+	return 0;
+}
+
 static int __init gpmc_init(void)
 {
 	u32 l;
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 1cafbfd..e59a932 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -152,6 +152,67 @@ struct gpmc_timings {
 	struct gpmc_bool_timings bool_timings;
 };
 
+/* Device timings in picoseconds */
+struct gpmc_device_timings {
+	u32     t_ceasu;	/* address setup to CS valid */
+	u32     t_avdasu;	/* address setup to ADV valid */
+	/* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
+	 * of tusb using these timings even for sync whilst
+	 * ideally for adv_rd/(wr)_off it should have considered
+	 * t_avdh instead. This indirectly necessitates r/w
+	 * variations of t_avdp as it is possible to have one
+	 * sync & other async
+	 */
+	u32	t_avdp_r;	/* ADV low time (what about t_cer ?) */
+	u32	t_avdp_w;
+	u32	t_aavdh;	/* address hold time */
+	u32     t_oeasu;	/* address setup to OE valid */
+	u32     t_aa;		/* access time from ADV assertion */
+	u32     t_iaa;		/* initial access time */
+	u32     t_oe;		/* access time from OE assertion */
+	u32     t_ce;		/* access time from CS asertion */
+	u32     t_rd_cycle;	/* read cycle time */
+	u32     t_cez_r;	/* read CS deassertion to high Z */
+	u32     t_cez_w;	/* write CS deassertion to high Z */
+	u32     t_oez;		/* OE deassertion to high Z */
+	u32     t_weasu;	/* address setup to WE valid */
+	u32     t_wpl;		/* write assertion time */
+	u32     t_wph;		/* write deassertion time */
+	u32     t_wr_cycle;	/* write cycle time */
+
+	u32	clk;
+	u32	t_bacc;		/* burst access valid clock to output delay */
+	u32	t_ces;		/* CS setup time to clk */
+	u32	t_avds;		/* ADV setup time to clk */
+	u32	t_avdh;		/* ADV hold time from clk */
+	u32     t_ach;		/* address hold time from clk */
+	u32	t_rdyo;		/* clk to ready valid */
+
+	u32	t_ce_rdyz;	/* XXX: description ?, or use t_cez instead */
+	u32	t_ce_avd;	/* CS on to ADV on delay */
+
+	/* XXX: check the possibility of combining
+	 * cyc_aavhd_oe & cyc_aavdh_we
+	 */
+	u8	cyc_aavdh_oe;
+	u8	cyc_aavdh_we;
+	u8	cyc_oe;
+	u8	cyc_wpl;
+	u32     cyc_iaa;
+
+	bool	mux;		/* address & data muxed */
+	bool	sync_write;	/* synchronous write */
+	bool	sync_read;	/* synchronous read */
+
+	bool	ce_xdelay;
+	bool	avd_xdelay;
+	bool	oe_xdelay;
+	bool	we_xdelay;
+};
+
+extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t);
+
 struct gpmc_nand_regs {
 	void __iomem	*gpmc_status;
 	void __iomem	*gpmc_nand_command;
-- 
1.7.1

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

* [PATCH v6 08/10] ARM: OMAP2+: onenand: generic timing calculation
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:45   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Generic gpmc timing calculation helper is available now, use
it instead of custom timing calculation.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c |  124 ++++++++++++------------------------
 1 files changed, 41 insertions(+), 83 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index e139e3f..700f9a6 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -49,6 +49,7 @@ static struct platform_device gpmc_onenand_device = {
 
 static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings t;
 
 	const int t_cer = 15;
@@ -58,35 +59,22 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 	const int t_aa = 76;
 	const int t_oe = 20;
 	const int t_cez = 20; /* max of t_cez, t_oez */
-	const int t_ds = 30;
 	const int t_wpl = 40;
 	const int t_wph = 30;
 
-	memset(&t, 0, sizeof(t));
-	t.sync_clk = 0;
-	t.cs_on = 0;
-	t.adv_on = 0;
-
-	/* Read */
-	t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
-	t.oe_on  = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh);
-	t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa);
-	t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce));
-	t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe));
-	t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
-	t.cs_rd_off = t.oe_off;
-	t.rd_cycle  = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez);
-
-	/* Write */
-	t.adv_wr_off = t.adv_rd_off;
-	t.we_on  = t.oe_on;
-	if (cpu_is_omap34xx()) {
-		t.wr_data_mux_bus = t.we_on;
-		t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
-	}
-	t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
-	t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
-	t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
+	memset(&dev_t, 0, sizeof(dev_t));
+
+	dev_t.mux = true;
+	dev_t.t_avdp_r = dev_t.t_avdp_w = max_t(int, t_avdp, t_cer) * 1000;
+	dev_t.t_aavdh = t_aavdh * 1000;
+	dev_t.t_aa = t_aa * 1000;
+	dev_t.t_ce = t_ce * 1000;
+	dev_t.t_oe = t_oe * 1000;
+	dev_t.t_cez_r = dev_t.t_cez_w = t_cez * 1000;
+	dev_t.t_wpl = t_wpl * 1000;
+	dev_t.t_wph = t_wph * 1000;
+
+	gpmc_calc_timings(&t, &dev_t);
 
 	return t;
 }
@@ -172,16 +160,15 @@ static struct gpmc_timings
 omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 						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 */
-	const int t_ds   = 30;
 	const int t_wpl  = 40;
 	const int t_wph  = 30;
 	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-	int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
-	int ticks_cez;
+	int div, gpmc_clk_ns;
 
 	if (cfg->flags & ONENAND_SYNC_READ)
 		onenand_flags = ONENAND_FLAG_SYNCREAD;
@@ -248,62 +235,33 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 		latency = 4;
 
 	/* Set synchronous read timings */
-	memset(&t, 0, sizeof(t));
+	memset(&dev_t, 0, sizeof(dev_t));
 
-	if (div == 1) {
-		t.bool_timings.cs_extra_delay = true;
-		t.bool_timings.adv_extra_delay = true;
-		t.bool_timings.oe_extra_delay = true;
-		t.bool_timings.we_extra_delay = true;
-	}
-
-	t.sync_clk = min_gpmc_clk_period;
-	t.cs_on = 0;
-	t.adv_on = 0;
-	fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
-	fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
-	t.page_burst_access = gpmc_clk_ns;
-
-	/* Read */
-	t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
-	t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
-	/* Force at least 1 clk between AVD High to OE Low */
-	if (t.oe_on <= t.adv_rd_off)
-		t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1);
-	t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
-	t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
-	t.cs_rd_off = t.oe_off;
-	ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
-	t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
-		     ticks_cez);
-
-	t.clk_activation = fclk_offset_ns;
-
-	/* Write */
-	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
-		t.adv_wr_off = t.adv_rd_off;
-		t.we_on  = 0;
-		t.we_off = t.cs_rd_off;
-		t.cs_wr_off = t.cs_rd_off;
-		t.wr_cycle  = t.rd_cycle;
-		if (cpu_is_omap34xx()) {
-			t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
-					gpmc_ps_to_ticks(min_gpmc_clk_period +
-					t_rdyo * 1000));
-			t.wr_access = t.access;
-		}
-	} else {
-		t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int,
-							t_avdp, t_cer));
-		t.we_on  = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh);
-		t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
-		t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
-		t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
-		if (cpu_is_omap34xx()) {
-			t.wr_data_mux_bus = t.we_on;
-			t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
-		}
+	dev_t.mux = true;
+	dev_t.sync_read = true;
+	if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
+		dev_t.sync_write = true;
+	else {
+		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+		dev_t.t_wpl = t_wpl * 1000;
+		dev_t.t_wph = t_wph * 1000;
+		dev_t.t_aavdh = t_aavdh * 1000;
 	}
+	dev_t.ce_xdelay = true;
+	dev_t.avd_xdelay = true;
+	dev_t.oe_xdelay = true;
+	dev_t.we_xdelay = true;
+	dev_t.clk = dev_t.t_bacc = min_gpmc_clk_period;
+	dev_t.t_ces = t_ces * 1000;
+	dev_t.t_avds = t_avds * 1000;
+	dev_t.t_avdh = t_avdh * 1000;
+	dev_t.t_ach = t_ach * 1000;
+	dev_t.cyc_iaa = (latency + 1);
+	dev_t.t_cez_r = dev_t.t_cez_w = t_cez * 1000;
+	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;
 }
-- 
1.7.1


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

* [PATCH v6 08/10] ARM: OMAP2+: onenand: generic timing calculation
@ 2012-08-21 10:45   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

Generic gpmc timing calculation helper is available now, use
it instead of custom timing calculation.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c |  124 ++++++++++++------------------------
 1 files changed, 41 insertions(+), 83 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index e139e3f..700f9a6 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -49,6 +49,7 @@ static struct platform_device gpmc_onenand_device = {
 
 static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings t;
 
 	const int t_cer = 15;
@@ -58,35 +59,22 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 	const int t_aa = 76;
 	const int t_oe = 20;
 	const int t_cez = 20; /* max of t_cez, t_oez */
-	const int t_ds = 30;
 	const int t_wpl = 40;
 	const int t_wph = 30;
 
-	memset(&t, 0, sizeof(t));
-	t.sync_clk = 0;
-	t.cs_on = 0;
-	t.adv_on = 0;
-
-	/* Read */
-	t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
-	t.oe_on  = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh);
-	t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa);
-	t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce));
-	t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe));
-	t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
-	t.cs_rd_off = t.oe_off;
-	t.rd_cycle  = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez);
-
-	/* Write */
-	t.adv_wr_off = t.adv_rd_off;
-	t.we_on  = t.oe_on;
-	if (cpu_is_omap34xx()) {
-		t.wr_data_mux_bus = t.we_on;
-		t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
-	}
-	t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
-	t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
-	t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
+	memset(&dev_t, 0, sizeof(dev_t));
+
+	dev_t.mux = true;
+	dev_t.t_avdp_r = dev_t.t_avdp_w = max_t(int, t_avdp, t_cer) * 1000;
+	dev_t.t_aavdh = t_aavdh * 1000;
+	dev_t.t_aa = t_aa * 1000;
+	dev_t.t_ce = t_ce * 1000;
+	dev_t.t_oe = t_oe * 1000;
+	dev_t.t_cez_r = dev_t.t_cez_w = t_cez * 1000;
+	dev_t.t_wpl = t_wpl * 1000;
+	dev_t.t_wph = t_wph * 1000;
+
+	gpmc_calc_timings(&t, &dev_t);
 
 	return t;
 }
@@ -172,16 +160,15 @@ static struct gpmc_timings
 omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 						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 */
-	const int t_ds   = 30;
 	const int t_wpl  = 40;
 	const int t_wph  = 30;
 	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-	int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
-	int ticks_cez;
+	int div, gpmc_clk_ns;
 
 	if (cfg->flags & ONENAND_SYNC_READ)
 		onenand_flags = ONENAND_FLAG_SYNCREAD;
@@ -248,62 +235,33 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 		latency = 4;
 
 	/* Set synchronous read timings */
-	memset(&t, 0, sizeof(t));
+	memset(&dev_t, 0, sizeof(dev_t));
 
-	if (div == 1) {
-		t.bool_timings.cs_extra_delay = true;
-		t.bool_timings.adv_extra_delay = true;
-		t.bool_timings.oe_extra_delay = true;
-		t.bool_timings.we_extra_delay = true;
-	}
-
-	t.sync_clk = min_gpmc_clk_period;
-	t.cs_on = 0;
-	t.adv_on = 0;
-	fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
-	fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
-	t.page_burst_access = gpmc_clk_ns;
-
-	/* Read */
-	t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
-	t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
-	/* Force at least 1 clk between AVD High to OE Low */
-	if (t.oe_on <= t.adv_rd_off)
-		t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1);
-	t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
-	t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
-	t.cs_rd_off = t.oe_off;
-	ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
-	t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
-		     ticks_cez);
-
-	t.clk_activation = fclk_offset_ns;
-
-	/* Write */
-	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
-		t.adv_wr_off = t.adv_rd_off;
-		t.we_on  = 0;
-		t.we_off = t.cs_rd_off;
-		t.cs_wr_off = t.cs_rd_off;
-		t.wr_cycle  = t.rd_cycle;
-		if (cpu_is_omap34xx()) {
-			t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
-					gpmc_ps_to_ticks(min_gpmc_clk_period +
-					t_rdyo * 1000));
-			t.wr_access = t.access;
-		}
-	} else {
-		t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int,
-							t_avdp, t_cer));
-		t.we_on  = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh);
-		t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
-		t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
-		t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
-		if (cpu_is_omap34xx()) {
-			t.wr_data_mux_bus = t.we_on;
-			t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
-		}
+	dev_t.mux = true;
+	dev_t.sync_read = true;
+	if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
+		dev_t.sync_write = true;
+	else {
+		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+		dev_t.t_wpl = t_wpl * 1000;
+		dev_t.t_wph = t_wph * 1000;
+		dev_t.t_aavdh = t_aavdh * 1000;
 	}
+	dev_t.ce_xdelay = true;
+	dev_t.avd_xdelay = true;
+	dev_t.oe_xdelay = true;
+	dev_t.we_xdelay = true;
+	dev_t.clk = dev_t.t_bacc = min_gpmc_clk_period;
+	dev_t.t_ces = t_ces * 1000;
+	dev_t.t_avds = t_avds * 1000;
+	dev_t.t_avdh = t_avdh * 1000;
+	dev_t.t_ach = t_ach * 1000;
+	dev_t.cyc_iaa = (latency + 1);
+	dev_t.t_cez_r = dev_t.t_cez_w = t_cez * 1000;
+	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;
 }
-- 
1.7.1

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

* [PATCH v6 09/10] ARM: OMAP2+: smc91x: generic timing calculation
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:46   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:46 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Generic gpmc timing calculation helper is available now, use
it instead of custom timing calculation.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc-smc91x.c |   43 ++++++++++++++----------------------
 1 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index ba10c24..43900f9 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -57,6 +57,7 @@ static struct platform_device gpmc_smc91x_device = {
 static int smc91c96_gpmc_retime(void)
 {
 	struct gpmc_timings t;
+	struct gpmc_device_timings dev_t;
 	const int t3 = 10;	/* Figure 12.2 read and 12.4 write */
 	const int t4_r = 20;	/* Figure 12.2 read */
 	const int t4_w = 5;	/* Figure 12.4 write */
@@ -67,32 +68,6 @@ static int smc91c96_gpmc_retime(void)
 	const int t20 = 185;	/* Figure 12.2 read and 12.4 write */
 	u32 l;
 
-	memset(&t, 0, sizeof(t));
-
-	/* Read timings */
-	t.cs_on = 0;
-	t.adv_on = t.cs_on;
-	t.oe_on = t.adv_on + t3;
-	t.access = t.oe_on + t5;
-	t.oe_off = t.access;
-	t.adv_rd_off = t.oe_off + max(t4_r, t6);
-	t.cs_rd_off = t.oe_off;
-	t.rd_cycle = t20 - t.oe_on;
-
-	/* Write timings */
-	t.we_on = t.adv_on + t3;
-
-	if (cpu_is_omap34xx() && (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)) {
-		t.wr_data_mux_bus = t.we_on;
-		t.we_off = t.wr_data_mux_bus + t7;
-	} else
-		t.we_off = t.we_on + t7;
-	if (cpu_is_omap34xx())
-		t.wr_access = t.we_off;
-	t.adv_wr_off = t.we_off + max(t4_w, t8);
-	t.cs_wr_off = t.we_off + t4_w;
-	t.wr_cycle = t20 - t.we_on;
-
 	l = GPMC_CONFIG1_DEVICESIZE_16;
 	if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
 		l |= GPMC_CONFIG1_MUXADDDATA;
@@ -114,6 +89,22 @@ static int smc91c96_gpmc_retime(void)
 	if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
 		return 0;
 
+	memset(&dev_t, 0, sizeof(dev_t));
+
+	dev_t.t_oeasu = t3 * 1000;
+	dev_t.t_oe = t5 * 1000;
+	dev_t.t_cez_r = t4_r * 1000;
+	dev_t.t_oez = t6 * 1000;
+	dev_t.t_rd_cycle = (t20 - t3) * 1000;
+
+	dev_t.t_weasu = t3 * 1000;
+	dev_t.t_wpl = t7 * 1000;
+	dev_t.t_wph = t8 * 1000;
+	dev_t.t_cez_w = t4_w * 1000;
+	dev_t.t_wr_cycle = (t20 - t3) * 1000;
+
+	gpmc_calc_timings(&t, &dev_t);
+
 	return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
 }
 
-- 
1.7.1


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

* [PATCH v6 09/10] ARM: OMAP2+: smc91x: generic timing calculation
@ 2012-08-21 10:46   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:46 UTC (permalink / raw)
  To: linux-arm-kernel

Generic gpmc timing calculation helper is available now, use
it instead of custom timing calculation.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc-smc91x.c |   43 ++++++++++++++----------------------
 1 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index ba10c24..43900f9 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -57,6 +57,7 @@ static struct platform_device gpmc_smc91x_device = {
 static int smc91c96_gpmc_retime(void)
 {
 	struct gpmc_timings t;
+	struct gpmc_device_timings dev_t;
 	const int t3 = 10;	/* Figure 12.2 read and 12.4 write */
 	const int t4_r = 20;	/* Figure 12.2 read */
 	const int t4_w = 5;	/* Figure 12.4 write */
@@ -67,32 +68,6 @@ static int smc91c96_gpmc_retime(void)
 	const int t20 = 185;	/* Figure 12.2 read and 12.4 write */
 	u32 l;
 
-	memset(&t, 0, sizeof(t));
-
-	/* Read timings */
-	t.cs_on = 0;
-	t.adv_on = t.cs_on;
-	t.oe_on = t.adv_on + t3;
-	t.access = t.oe_on + t5;
-	t.oe_off = t.access;
-	t.adv_rd_off = t.oe_off + max(t4_r, t6);
-	t.cs_rd_off = t.oe_off;
-	t.rd_cycle = t20 - t.oe_on;
-
-	/* Write timings */
-	t.we_on = t.adv_on + t3;
-
-	if (cpu_is_omap34xx() && (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)) {
-		t.wr_data_mux_bus = t.we_on;
-		t.we_off = t.wr_data_mux_bus + t7;
-	} else
-		t.we_off = t.we_on + t7;
-	if (cpu_is_omap34xx())
-		t.wr_access = t.we_off;
-	t.adv_wr_off = t.we_off + max(t4_w, t8);
-	t.cs_wr_off = t.we_off + t4_w;
-	t.wr_cycle = t20 - t.we_on;
-
 	l = GPMC_CONFIG1_DEVICESIZE_16;
 	if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
 		l |= GPMC_CONFIG1_MUXADDDATA;
@@ -114,6 +89,22 @@ static int smc91c96_gpmc_retime(void)
 	if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
 		return 0;
 
+	memset(&dev_t, 0, sizeof(dev_t));
+
+	dev_t.t_oeasu = t3 * 1000;
+	dev_t.t_oe = t5 * 1000;
+	dev_t.t_cez_r = t4_r * 1000;
+	dev_t.t_oez = t6 * 1000;
+	dev_t.t_rd_cycle = (t20 - t3) * 1000;
+
+	dev_t.t_weasu = t3 * 1000;
+	dev_t.t_wpl = t7 * 1000;
+	dev_t.t_wph = t8 * 1000;
+	dev_t.t_cez_w = t4_w * 1000;
+	dev_t.t_wr_cycle = (t20 - t3) * 1000;
+
+	gpmc_calc_timings(&t, &dev_t);
+
 	return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
 }
 
-- 
1.7.1

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-21 10:46   ` Afzal Mohammed
  -1 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:46 UTC (permalink / raw)
  To: tony, jon-hunter, paul, linux-omap, linux-arm-kernel; +Cc: Afzal Mohammed

Generic gpmc timing calculation helper is available now, use
it instead of custom timing calculation.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/usb-tusb6010.c |  181 +++++++++---------------------------
 1 files changed, 43 insertions(+), 138 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 7a85ebe..cce1f06 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -26,182 +26,87 @@ static u8		async_cs, sync_cs;
 static unsigned		refclk_psec;
 
 
-/* t2_ps, when quantized to fclk units, must happen no earlier than
- * the clock after after t1_NS.
- *
- * Return a possibly updated value of t2_ps, converted to nsec.
- */
-static unsigned
-next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
-{
-	unsigned	t1_ps = t1_NS * 1000;
-	unsigned	t1_f, t2_f;
-
-	if ((t1_ps + fclk_ps) < t2_ps)
-		return t2_ps / 1000;
-
-	t1_f = (t1_ps + fclk_ps - 1) / fclk_ps;
-	t2_f = (t2_ps + fclk_ps - 1) / fclk_ps;
-
-	if (t1_f >= t2_f)
-		t2_f = t1_f + 1;
-
-	return (t2_f * fclk_ps) / 1000;
-}
-
 /* NOTE:  timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
 
-static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps)
+static int tusb_set_async_mode(unsigned sysclk_ps)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings	t;
 	unsigned		t_acsnh_advnh = sysclk_ps + 3000;
-	unsigned		tmp;
-
-	memset(&t, 0, sizeof(t));
-
-	/* CS_ON = t_acsnh_acsnl */
-	t.cs_on = 8;
-	/* ADV_ON = t_acsnh_advnh - t_advn */
-	t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps);
-
-	/*
-	 * READ ... from omap2420 TRM fig 12-13
-	 */
-
-	/* ADV_RD_OFF = t_acsnh_advnh */
-	t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps);
-
-	/* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */
-	t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps);
-
-	/* ACCESS = counters continue only after nRDY */
-	tmp = t.oe_on * 1000 + 300;
-	t.access = next_clk(t.oe_on, tmp, fclk_ps);
-
-	/* OE_OFF = after data gets sampled */
-	tmp = t.access * 1000;
-	t.oe_off = next_clk(t.access, tmp, fclk_ps);
-
-	t.cs_rd_off = t.oe_off;
-
-	tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */;
-	t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
-
-	/*
-	 * WRITE ... from omap2420 TRM fig 12-15
-	 */
 
-	/* ADV_WR_OFF = t_acsnh_advnh */
-	t.adv_wr_off = t.adv_rd_off;
+	memset(&dev_t, 0, sizeof(dev_t));
 
-	/* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */
-	t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps);
+	dev_t.mux = true;
 
-	/* WE_OFF = after data gets sampled */
-	tmp = t.we_on * 1000 + 300;
-	t.we_off = next_clk(t.we_on, tmp, fclk_ps);
+	dev_t.t_ceasu = 8 * 1000;
+	dev_t.t_avdasu = t_acsnh_advnh - 7000;
+	dev_t.t_ce_avd = 1000;
+	dev_t.t_avdp_r = t_acsnh_advnh;
+	dev_t.t_oeasu = t_acsnh_advnh + 1000;
+	dev_t.t_oe = 300;
+	dev_t.t_cez_r = dev_t.t_cez_w = 7000;
+	dev_t.t_avdp_w = t_acsnh_advnh;
+	dev_t.t_weasu = t_acsnh_advnh + 1000;
+	dev_t.t_wpl = 300;
+	dev_t.cyc_aavdh_we = 1;
 
-	t.cs_wr_off = t.we_off;
-
-	tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */;
-	t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
+	gpmc_calc_timings(&t, &dev_t);
 
 	return gpmc_cs_set_timings(async_cs, &t);
 }
 
-static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
+static int tusb_set_sync_mode(unsigned sysclk_ps)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings	t;
 	unsigned		t_scsnh_advnh = sysclk_ps + 3000;
-	unsigned		tmp;
-
-	memset(&t, 0, sizeof(t));
-	t.cs_on = 8;
-
-	/* ADV_ON = t_acsnh_advnh - t_advn */
-	t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
-
-	/* GPMC_CLK rate = fclk rate / div */
-	t.sync_clk = 11100 /* 11.1 nsec */;
-	tmp = (t.sync_clk + fclk_ps - 1) / fclk_ps;
-	if (tmp > 4)
-		return -ERANGE;
-	if (tmp == 0)
-		tmp = 1;
-	t.page_burst_access = (fclk_ps * tmp) / 1000;
-
-	/*
-	 * READ ... based on omap2420 TRM fig 12-19, 12-20
-	 */
-
-	/* ADV_RD_OFF = t_scsnh_advnh */
-	t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps);
-
-	/* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */
-	tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps);
-	t.oe_on = next_clk(t.adv_on, tmp, fclk_ps);
-
-	/* ACCESS = number of clock cycles after t_adv_eon */
-	tmp = (t.oe_on * 1000) + (5 * fclk_ps);
-	t.access = next_clk(t.oe_on, tmp, fclk_ps);
-
-	/* OE_OFF = after data gets sampled */
-	tmp = (t.access * 1000) + (1 * fclk_ps);
-	t.oe_off = next_clk(t.access, tmp, fclk_ps);
 
-	t.cs_rd_off = t.oe_off;
-
-	tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */;
-	t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
-
-	/*
-	 * WRITE ... based on omap2420 TRM fig 12-21
-	 */
-
-	/* ADV_WR_OFF = t_scsnh_advnh */
-	t.adv_wr_off = t.adv_rd_off;
-
-	/* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */
-	tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps);
-	t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps);
-
-	/* WE_OFF = number of clock cycles after t_adv_wen */
-	tmp = (t.we_on * 1000) + (6 * fclk_ps);
-	t.we_off = next_clk(t.we_on, tmp, fclk_ps);
-
-	t.cs_wr_off = t.we_off;
-
-	tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
-	t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
-
-	t.clk_activation = gpmc_ticks_to_ns(1);
+	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;
+	dev_t.t_ceasu = 8 * 1000;
+	dev_t.t_avdasu = t_scsnh_advnh - 7000;
+	dev_t.t_ce_avd = 1000;
+	dev_t.t_avdp_r = t_scsnh_advnh;
+	dev_t.cyc_aavdh_oe = 3;
+	dev_t.cyc_oe = 5;
+	dev_t.t_ce_rdyz = 7000;
+	dev_t.t_avdp_w = t_scsnh_advnh;
+	dev_t.cyc_aavdh_we = 3;
+	dev_t.cyc_wpl = 6;
+	dev_t.t_ce_rdyz = 7000;
+
+	gpmc_calc_timings(&t, &dev_t);
 
 	return gpmc_cs_set_timings(sync_cs, &t);
 }
 
-extern unsigned long gpmc_get_fclk_period(void);
-
 /* tusb driver calls this when it changes the chip's clocking */
 int tusb6010_platform_retime(unsigned is_refclk)
 {
 	static const char	error[] =
 		KERN_ERR "tusb6010 %s retime error %d\n";
 
-	unsigned	fclk_ps = gpmc_get_fclk_period();
 	unsigned	sysclk_ps;
 	int		status;
 
-	if (!refclk_psec || fclk_ps == 0)
+	if (!refclk_psec)
 		return -ENODEV;
 
 	sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
 
-	status = tusb_set_async_mode(sysclk_ps, fclk_ps);
+	status = tusb_set_async_mode(sysclk_ps);
 	if (status < 0) {
 		printk(error, "async", status);
 		goto done;
 	}
-	status = tusb_set_sync_mode(sysclk_ps, fclk_ps);
+	status = tusb_set_sync_mode(sysclk_ps);
 	if (status < 0)
 		printk(error, "sync", status);
 done:
-- 
1.7.1


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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-08-21 10:46   ` Afzal Mohammed
  0 siblings, 0 replies; 74+ messages in thread
From: Afzal Mohammed @ 2012-08-21 10:46 UTC (permalink / raw)
  To: linux-arm-kernel

Generic gpmc timing calculation helper is available now, use
it instead of custom timing calculation.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/usb-tusb6010.c |  181 +++++++++---------------------------
 1 files changed, 43 insertions(+), 138 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 7a85ebe..cce1f06 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -26,182 +26,87 @@ static u8		async_cs, sync_cs;
 static unsigned		refclk_psec;
 
 
-/* t2_ps, when quantized to fclk units, must happen no earlier than
- * the clock after after t1_NS.
- *
- * Return a possibly updated value of t2_ps, converted to nsec.
- */
-static unsigned
-next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
-{
-	unsigned	t1_ps = t1_NS * 1000;
-	unsigned	t1_f, t2_f;
-
-	if ((t1_ps + fclk_ps) < t2_ps)
-		return t2_ps / 1000;
-
-	t1_f = (t1_ps + fclk_ps - 1) / fclk_ps;
-	t2_f = (t2_ps + fclk_ps - 1) / fclk_ps;
-
-	if (t1_f >= t2_f)
-		t2_f = t1_f + 1;
-
-	return (t2_f * fclk_ps) / 1000;
-}
-
 /* NOTE:  timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
 
-static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps)
+static int tusb_set_async_mode(unsigned sysclk_ps)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings	t;
 	unsigned		t_acsnh_advnh = sysclk_ps + 3000;
-	unsigned		tmp;
-
-	memset(&t, 0, sizeof(t));
-
-	/* CS_ON = t_acsnh_acsnl */
-	t.cs_on = 8;
-	/* ADV_ON = t_acsnh_advnh - t_advn */
-	t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps);
-
-	/*
-	 * READ ... from omap2420 TRM fig 12-13
-	 */
-
-	/* ADV_RD_OFF = t_acsnh_advnh */
-	t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps);
-
-	/* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */
-	t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps);
-
-	/* ACCESS = counters continue only after nRDY */
-	tmp = t.oe_on * 1000 + 300;
-	t.access = next_clk(t.oe_on, tmp, fclk_ps);
-
-	/* OE_OFF = after data gets sampled */
-	tmp = t.access * 1000;
-	t.oe_off = next_clk(t.access, tmp, fclk_ps);
-
-	t.cs_rd_off = t.oe_off;
-
-	tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */;
-	t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
-
-	/*
-	 * WRITE ... from omap2420 TRM fig 12-15
-	 */
 
-	/* ADV_WR_OFF = t_acsnh_advnh */
-	t.adv_wr_off = t.adv_rd_off;
+	memset(&dev_t, 0, sizeof(dev_t));
 
-	/* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */
-	t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps);
+	dev_t.mux = true;
 
-	/* WE_OFF = after data gets sampled */
-	tmp = t.we_on * 1000 + 300;
-	t.we_off = next_clk(t.we_on, tmp, fclk_ps);
+	dev_t.t_ceasu = 8 * 1000;
+	dev_t.t_avdasu = t_acsnh_advnh - 7000;
+	dev_t.t_ce_avd = 1000;
+	dev_t.t_avdp_r = t_acsnh_advnh;
+	dev_t.t_oeasu = t_acsnh_advnh + 1000;
+	dev_t.t_oe = 300;
+	dev_t.t_cez_r = dev_t.t_cez_w = 7000;
+	dev_t.t_avdp_w = t_acsnh_advnh;
+	dev_t.t_weasu = t_acsnh_advnh + 1000;
+	dev_t.t_wpl = 300;
+	dev_t.cyc_aavdh_we = 1;
 
-	t.cs_wr_off = t.we_off;
-
-	tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */;
-	t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
+	gpmc_calc_timings(&t, &dev_t);
 
 	return gpmc_cs_set_timings(async_cs, &t);
 }
 
-static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
+static int tusb_set_sync_mode(unsigned sysclk_ps)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings	t;
 	unsigned		t_scsnh_advnh = sysclk_ps + 3000;
-	unsigned		tmp;
-
-	memset(&t, 0, sizeof(t));
-	t.cs_on = 8;
-
-	/* ADV_ON = t_acsnh_advnh - t_advn */
-	t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
-
-	/* GPMC_CLK rate = fclk rate / div */
-	t.sync_clk = 11100 /* 11.1 nsec */;
-	tmp = (t.sync_clk + fclk_ps - 1) / fclk_ps;
-	if (tmp > 4)
-		return -ERANGE;
-	if (tmp == 0)
-		tmp = 1;
-	t.page_burst_access = (fclk_ps * tmp) / 1000;
-
-	/*
-	 * READ ... based on omap2420 TRM fig 12-19, 12-20
-	 */
-
-	/* ADV_RD_OFF = t_scsnh_advnh */
-	t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps);
-
-	/* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */
-	tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps);
-	t.oe_on = next_clk(t.adv_on, tmp, fclk_ps);
-
-	/* ACCESS = number of clock cycles after t_adv_eon */
-	tmp = (t.oe_on * 1000) + (5 * fclk_ps);
-	t.access = next_clk(t.oe_on, tmp, fclk_ps);
-
-	/* OE_OFF = after data gets sampled */
-	tmp = (t.access * 1000) + (1 * fclk_ps);
-	t.oe_off = next_clk(t.access, tmp, fclk_ps);
 
-	t.cs_rd_off = t.oe_off;
-
-	tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */;
-	t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
-
-	/*
-	 * WRITE ... based on omap2420 TRM fig 12-21
-	 */
-
-	/* ADV_WR_OFF = t_scsnh_advnh */
-	t.adv_wr_off = t.adv_rd_off;
-
-	/* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */
-	tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps);
-	t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps);
-
-	/* WE_OFF = number of clock cycles after t_adv_wen */
-	tmp = (t.we_on * 1000) + (6 * fclk_ps);
-	t.we_off = next_clk(t.we_on, tmp, fclk_ps);
-
-	t.cs_wr_off = t.we_off;
-
-	tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
-	t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
-
-	t.clk_activation = gpmc_ticks_to_ns(1);
+	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;
+	dev_t.t_ceasu = 8 * 1000;
+	dev_t.t_avdasu = t_scsnh_advnh - 7000;
+	dev_t.t_ce_avd = 1000;
+	dev_t.t_avdp_r = t_scsnh_advnh;
+	dev_t.cyc_aavdh_oe = 3;
+	dev_t.cyc_oe = 5;
+	dev_t.t_ce_rdyz = 7000;
+	dev_t.t_avdp_w = t_scsnh_advnh;
+	dev_t.cyc_aavdh_we = 3;
+	dev_t.cyc_wpl = 6;
+	dev_t.t_ce_rdyz = 7000;
+
+	gpmc_calc_timings(&t, &dev_t);
 
 	return gpmc_cs_set_timings(sync_cs, &t);
 }
 
-extern unsigned long gpmc_get_fclk_period(void);
-
 /* tusb driver calls this when it changes the chip's clocking */
 int tusb6010_platform_retime(unsigned is_refclk)
 {
 	static const char	error[] =
 		KERN_ERR "tusb6010 %s retime error %d\n";
 
-	unsigned	fclk_ps = gpmc_get_fclk_period();
 	unsigned	sysclk_ps;
 	int		status;
 
-	if (!refclk_psec || fclk_ps == 0)
+	if (!refclk_psec)
 		return -ENODEV;
 
 	sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
 
-	status = tusb_set_async_mode(sysclk_ps, fclk_ps);
+	status = tusb_set_async_mode(sysclk_ps);
 	if (status < 0) {
 		printk(error, "async", status);
 		goto done;
 	}
-	status = tusb_set_sync_mode(sysclk_ps, fclk_ps);
+	status = tusb_set_sync_mode(sysclk_ps);
 	if (status < 0)
 		printk(error, "sync", status);
 done:
-- 
1.7.1

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

* Re: [PATCH v6 01/10] ARM: OMAP2+: nand: unify init functions
  2012-08-21 10:45   ` Afzal Mohammed
@ 2012-08-21 11:37     ` Igor Grinberg
  -1 siblings, 0 replies; 74+ messages in thread
From: Igor Grinberg @ 2012-08-21 11:37 UTC (permalink / raw)
  To: Afzal Mohammed; +Cc: tony, jon-hunter, paul, linux-omap, linux-arm-kernel

Hi Afzal,

Thanks for the patches!

On 08/21/12 13:45, Afzal Mohammed wrote:
> Helper function for updating nand platform data has been
> added the capability to take timing structure arguement.
> Usage of omap_nand_flash_init() has been replaced by modifed
> one, omap_nand_flash_init was doing things similar to
> board_nand_init except that NAND CS# were being acquired
> based on bootloader setting. As CS# is hardwired for a given
> board, acquiring gpmc CS# has been removed, and updated with
> the value on board.
> 
> NAND CS# used in beagle board & omap3evm was found to be CS0.
> Thomas Weber <thomas.weber.linux@googlemail.com> reported
> that value of devkit8000 to be CS0. Overo board was found
> to be using CS0 based on u-boot, while google grep says
> omap3touchbook too has CS0.
> 
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> Reviewed-by: Jon Hunter <jon-hunter@ti.com>

Acked-by: Igor Grinberg <grinberg@compulab.co.il>


-- 
Regards,
Igor.

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

* [PATCH v6 01/10] ARM: OMAP2+: nand: unify init functions
@ 2012-08-21 11:37     ` Igor Grinberg
  0 siblings, 0 replies; 74+ messages in thread
From: Igor Grinberg @ 2012-08-21 11:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Afzal,

Thanks for the patches!

On 08/21/12 13:45, Afzal Mohammed wrote:
> Helper function for updating nand platform data has been
> added the capability to take timing structure arguement.
> Usage of omap_nand_flash_init() has been replaced by modifed
> one, omap_nand_flash_init was doing things similar to
> board_nand_init except that NAND CS# were being acquired
> based on bootloader setting. As CS# is hardwired for a given
> board, acquiring gpmc CS# has been removed, and updated with
> the value on board.
> 
> NAND CS# used in beagle board & omap3evm was found to be CS0.
> Thomas Weber <thomas.weber.linux@googlemail.com> reported
> that value of devkit8000 to be CS0. Overo board was found
> to be using CS0 based on u-boot, while google grep says
> omap3touchbook too has CS0.
> 
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> Reviewed-by: Jon Hunter <jon-hunter@ti.com>

Acked-by: Igor Grinberg <grinberg@compulab.co.il>


-- 
Regards,
Igor.

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

* Re: [PATCH v6 05/10] ARM: OMAP2+: gpmc: find features by ip rev check
  2012-08-21 10:45   ` Afzal Mohammed
@ 2012-08-22  2:08     ` Jon Hunter
  -1 siblings, 0 replies; 74+ messages in thread
From: Jon Hunter @ 2012-08-22  2:08 UTC (permalink / raw)
  To: Afzal Mohammed; +Cc: tony, paul, linux-omap, linux-arm-kernel


On 08/21/2012 05:45 AM, Afzal Mohammed wrote:
> Newer IP's have wr_access and wr_data_mux_bus fields. Use
> IP revision values to determine availability of these
> fields and hence decide on whether to configure them.
> 
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
>  arch/arm/mach-omap2/gpmc.c |   12 ++++++++++--
>  1 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 070fac5..68123d0 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -85,6 +85,11 @@
>  #define ENABLE_PREFETCH		(0x1 << 7)
>  #define DMA_MPU_MODE		2
>  
> +#define	GPMC_REVISION_MAJOR(l)		((l >> 4) & 0xf)
> +
> +#define	GPMC_HAS_WR_ACCESS		0x1
> +#define	GPMC_HAS_WR_DATA_MUX_BUS	0x2
> +
>  /* XXX: Only NAND irq has been considered,currently these are the only ones used
>   */
>  #define	GPMC_NR_IRQ		2
> @@ -131,6 +136,7 @@ static DEFINE_SPINLOCK(gpmc_mem_lock);
>  static unsigned int gpmc_cs_map;	/* flag for cs which are initialized */
>  static int gpmc_ecc_used = -EINVAL;	/* cs using ecc engine */
>  
> +static unsigned gpmc_capability;
>  static void __iomem *gpmc_base;
>  
>  static struct clk *gpmc_l3_clk;
> @@ -356,10 +362,10 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
>  	GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
>  	GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
>  
> -	if (cpu_is_omap34xx()) {
> +	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
>  		GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
> +	if (gpmc_capability & GPMC_HAS_WR_ACCESS)
>  		GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
> -	}
>  
>  	/* caller is expected to have initialized CONFIG1 to cover
>  	 * at least sync vs async
> @@ -922,6 +928,8 @@ static int __init gpmc_init(void)
>  	clk_enable(gpmc_l3_clk);
>  
>  	l = gpmc_read_reg(GPMC_REVISION);
> +	if (GPMC_REVISION_MAJOR(l) > 0x4)
> +		gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
>  	printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
>  	/* Set smart idle mode and automatic L3 clock gating */
>  	l = gpmc_read_reg(GPMC_SYSCONFIG);
> 

Reviewed-by: Jon Hunter <jon-hunter@ti.com>

Thanks!
Jon

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

* [PATCH v6 05/10] ARM: OMAP2+: gpmc: find features by ip rev check
@ 2012-08-22  2:08     ` Jon Hunter
  0 siblings, 0 replies; 74+ messages in thread
From: Jon Hunter @ 2012-08-22  2:08 UTC (permalink / raw)
  To: linux-arm-kernel


On 08/21/2012 05:45 AM, Afzal Mohammed wrote:
> Newer IP's have wr_access and wr_data_mux_bus fields. Use
> IP revision values to determine availability of these
> fields and hence decide on whether to configure them.
> 
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
>  arch/arm/mach-omap2/gpmc.c |   12 ++++++++++--
>  1 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 070fac5..68123d0 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -85,6 +85,11 @@
>  #define ENABLE_PREFETCH		(0x1 << 7)
>  #define DMA_MPU_MODE		2
>  
> +#define	GPMC_REVISION_MAJOR(l)		((l >> 4) & 0xf)
> +
> +#define	GPMC_HAS_WR_ACCESS		0x1
> +#define	GPMC_HAS_WR_DATA_MUX_BUS	0x2
> +
>  /* XXX: Only NAND irq has been considered,currently these are the only ones used
>   */
>  #define	GPMC_NR_IRQ		2
> @@ -131,6 +136,7 @@ static DEFINE_SPINLOCK(gpmc_mem_lock);
>  static unsigned int gpmc_cs_map;	/* flag for cs which are initialized */
>  static int gpmc_ecc_used = -EINVAL;	/* cs using ecc engine */
>  
> +static unsigned gpmc_capability;
>  static void __iomem *gpmc_base;
>  
>  static struct clk *gpmc_l3_clk;
> @@ -356,10 +362,10 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
>  	GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
>  	GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
>  
> -	if (cpu_is_omap34xx()) {
> +	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
>  		GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
> +	if (gpmc_capability & GPMC_HAS_WR_ACCESS)
>  		GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
> -	}
>  
>  	/* caller is expected to have initialized CONFIG1 to cover
>  	 * at least sync vs async
> @@ -922,6 +928,8 @@ static int __init gpmc_init(void)
>  	clk_enable(gpmc_l3_clk);
>  
>  	l = gpmc_read_reg(GPMC_REVISION);
> +	if (GPMC_REVISION_MAJOR(l) > 0x4)
> +		gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
>  	printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
>  	/* Set smart idle mode and automatic L3 clock gating */
>  	l = gpmc_read_reg(GPMC_SYSCONFIG);
> 

Reviewed-by: Jon Hunter <jon-hunter@ti.com>

Thanks!
Jon

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

* Re: [PATCH v6 06/10] ARM: OMAP2+: gpmc: remove cs# in sync clk div calc
  2012-08-21 10:45   ` Afzal Mohammed
@ 2012-08-22  2:11     ` Jon Hunter
  -1 siblings, 0 replies; 74+ messages in thread
From: Jon Hunter @ 2012-08-22  2:11 UTC (permalink / raw)
  To: Afzal Mohammed; +Cc: tony, paul, linux-omap, linux-arm-kernel


On 08/21/2012 05:45 AM, Afzal Mohammed wrote:
> Divider value for a certain sync clk is determined solely
> based on gpmc fclk. CS# does not have any role here, thus
> remove presence of CS# in clock divider calculation API.
> 
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
>  arch/arm/mach-omap2/gpmc-onenand.c     |    3 +--
>  arch/arm/mach-omap2/gpmc.c             |    4 ++--
>  arch/arm/plat-omap/include/plat/gpmc.h |    2 +-
>  3 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
> index 8a301f3..e139e3f 100644
> --- a/arch/arm/mach-omap2/gpmc-onenand.c
> +++ b/arch/arm/mach-omap2/gpmc-onenand.c
> @@ -182,7 +182,6 @@ 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, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
>  	int ticks_cez;
> -	int cs = cfg->cs;
>  
>  	if (cfg->flags & ONENAND_SYNC_READ)
>  		onenand_flags = ONENAND_FLAG_SYNCREAD;
> @@ -229,7 +228,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
>  		break;
>  	}
>  
> -	div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
> +	div = gpmc_calc_divider(min_gpmc_clk_period);
>  	gpmc_clk_ns = gpmc_ticks_to_ns(div);
>  	if (gpmc_clk_ns < 15) /* >66Mhz */
>  		onenand_flags |= ONENAND_FLAG_HF;
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 68123d0..d005b3a 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -313,7 +313,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
>  		return -1
>  #endif
>  
> -int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
> +int gpmc_calc_divider(unsigned int sync_clk)
>  {
>  	int div;
>  	u32 l;
> @@ -333,7 +333,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
>  	int div;
>  	u32 l;
>  
> -	div = gpmc_cs_calc_divider(cs, t->sync_clk);
> +	div = gpmc_calc_divider(t->sync_clk);
>  	if (div < 0)
>  		return -1;
>  
> diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
> index b7c9ea6..1cafbfd 100644
> --- a/arch/arm/plat-omap/include/plat/gpmc.h
> +++ b/arch/arm/plat-omap/include/plat/gpmc.h
> @@ -179,7 +179,7 @@ extern unsigned long gpmc_get_fclk_period(void);
>  
>  extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
>  extern u32 gpmc_cs_read_reg(int cs, int idx);
> -extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
> +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_request(int cs, unsigned long size, unsigned long *base);
>  extern void gpmc_cs_free(int cs);
> 

Reviewed-by: Jon Hunter <jon-hunter@ti.com>

Thanks!
Jon

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

* [PATCH v6 06/10] ARM: OMAP2+: gpmc: remove cs# in sync clk div calc
@ 2012-08-22  2:11     ` Jon Hunter
  0 siblings, 0 replies; 74+ messages in thread
From: Jon Hunter @ 2012-08-22  2:11 UTC (permalink / raw)
  To: linux-arm-kernel


On 08/21/2012 05:45 AM, Afzal Mohammed wrote:
> Divider value for a certain sync clk is determined solely
> based on gpmc fclk. CS# does not have any role here, thus
> remove presence of CS# in clock divider calculation API.
> 
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
>  arch/arm/mach-omap2/gpmc-onenand.c     |    3 +--
>  arch/arm/mach-omap2/gpmc.c             |    4 ++--
>  arch/arm/plat-omap/include/plat/gpmc.h |    2 +-
>  3 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
> index 8a301f3..e139e3f 100644
> --- a/arch/arm/mach-omap2/gpmc-onenand.c
> +++ b/arch/arm/mach-omap2/gpmc-onenand.c
> @@ -182,7 +182,6 @@ 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, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
>  	int ticks_cez;
> -	int cs = cfg->cs;
>  
>  	if (cfg->flags & ONENAND_SYNC_READ)
>  		onenand_flags = ONENAND_FLAG_SYNCREAD;
> @@ -229,7 +228,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
>  		break;
>  	}
>  
> -	div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
> +	div = gpmc_calc_divider(min_gpmc_clk_period);
>  	gpmc_clk_ns = gpmc_ticks_to_ns(div);
>  	if (gpmc_clk_ns < 15) /* >66Mhz */
>  		onenand_flags |= ONENAND_FLAG_HF;
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 68123d0..d005b3a 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -313,7 +313,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
>  		return -1
>  #endif
>  
> -int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
> +int gpmc_calc_divider(unsigned int sync_clk)
>  {
>  	int div;
>  	u32 l;
> @@ -333,7 +333,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
>  	int div;
>  	u32 l;
>  
> -	div = gpmc_cs_calc_divider(cs, t->sync_clk);
> +	div = gpmc_calc_divider(t->sync_clk);
>  	if (div < 0)
>  		return -1;
>  
> diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
> index b7c9ea6..1cafbfd 100644
> --- a/arch/arm/plat-omap/include/plat/gpmc.h
> +++ b/arch/arm/plat-omap/include/plat/gpmc.h
> @@ -179,7 +179,7 @@ extern unsigned long gpmc_get_fclk_period(void);
>  
>  extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
>  extern u32 gpmc_cs_read_reg(int cs, int idx);
> -extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
> +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_request(int cs, unsigned long size, unsigned long *base);
>  extern void gpmc_cs_free(int cs);
> 

Reviewed-by: Jon Hunter <jon-hunter@ti.com>

Thanks!
Jon

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

* Re: [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
  2012-08-21 10:45   ` Afzal Mohammed
@ 2012-08-23  2:58     ` Jon Hunter
  -1 siblings, 0 replies; 74+ messages in thread
From: Jon Hunter @ 2012-08-23  2:58 UTC (permalink / raw)
  To: Afzal Mohammed; +Cc: tony, paul, linux-omap, linux-arm-kernel

Hi Afzal,

On 08/21/2012 05:45 AM, Afzal Mohammed wrote:
> Presently there are three peripherals that gets it timing
> by runtime calculation. Those peripherals can work with
> frequency scaling that affects gpmc clock. But timing
> calculation for them are in different ways.
> 
> Here a generic runtime calculation method is proposed. Input
> to this function were selected so that they represent timing
> variables that are present in peripheral datasheets. Motive
> behind this was to achieve DT bindings for the inputs as is.
> Even though a few of the tusb6010 timings could not be made
> directly related to timings normally found on peripherals,
> expressions used were translated to those that could be
> justified.
> 
> There are possibilities of improving the calculations, like
> calculating timing for read & write operations in a more
> similar way. Expressions derived here were tested for async
> onenand on omap3evm (as vanilla Kernel does not have omap3evm
> onenand support, local patch was used). Other peripherals,
> tusb6010, smc91x calculations were validated by simulating
> on omap3evm.
> 
> Regarding "we_on" for onenand async, it was found that even
> for muxed address/data, it need not be greater than
> "adv_wr_off", but rather could be derived from write setup
> time for peripheral from start of access time, hence would
> more be in line with peripheral timings. With this method
> it was working fine. If it is required in some cases to
> have "we_on" same as "wr_data_mux_bus" (i.e. greater than
> "adv_wr_off"), another variable could be added to indicate
> it. But such a requirement is not expected though.
> 
> Whole of this exercise is being done to achieve driver and
> DT conversion. If timings could not be calculated in a
> peripheral agnostic way, either gpmc driver would have to
> be peripheral gnostic or a wrapper arrangement over gpmc
> driver would be required.
> 
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
>  arch/arm/mach-omap2/gpmc.c             |  302 ++++++++++++++++++++++++++++++++
>  arch/arm/plat-omap/include/plat/gpmc.h |   61 +++++++
>  2 files changed, 363 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index d005b3a..d8e5b08 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -233,6 +233,18 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
>  	return ticks * gpmc_get_fclk_period() / 1000;
>  }
>  
> +unsigned int gpmc_ticks_to_ps(unsigned int ticks)
> +{
> +	return ticks * gpmc_get_fclk_period();
> +}
> +
> +unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
> +{
> +	unsigned long ticks = gpmc_ps_to_ticks(time_ps);
> +
> +	return ticks * gpmc_get_fclk_period();
> +}
> +
>  static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
>  {
>  	u32 l;
> @@ -884,6 +896,296 @@ static void __init gpmc_mem_init(void)
>  	}
>  }
>  
> +static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
> +{
> +	u32 temp;
> +	int div;
> +
> +	div = gpmc_calc_divider(sync_clk);
> +	temp = gpmc_ps_to_ticks(time_ps);
> +	temp = (temp + div - 1) / div;
> +	return gpmc_ticks_to_ps(temp * div);
> +}
> +
> +/* can the cycles be avoided ? */

What is the above comment referring too?

> +static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
> +				struct gpmc_device_timings *dev_t)
> +{
> +	bool mux = dev_t->mux;
> +	u32 temp;
> +
> +	/* adv_rd_off */
> +	temp = dev_t->t_avdp_r;
> +	/* mux check required ? */
> +	if (mux) {
> +		/* t_avdp not to be required for sync, only added for tusb this
> +		 * indirectly necessitates requirement of t_avdp_r & t_avdp_w
> +		 * instead of having a single t_avdp
> +		 */
> +		temp = max_t(u32, temp,	gpmc_t->clk_activation * 1000 +
> +							dev_t->t_avdh);
> +		temp = max_t(u32,
> +			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
> +	}
> +	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> +	/* oe_on */
> +	temp = dev_t->t_oeasu; /* remove this ? */
> +	if (mux) {
> +		temp = max_t(u32, temp,
> +			gpmc_t->clk_activation * 1000 + dev_t->t_ach);
> +		temp = max_t(u32, temp, (gpmc_t->adv_rd_off +
> +				gpmc_ticks_to_ns(dev_t->cyc_aavdh_oe)) * 1000);
> +	}
> +	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> +	/* access */
> +	/* any scope for improvement ?, by combining oe_on & clk_activation,
> +	 * need to check whether access = clk_activation + round to sync clk ?
> +	 */
> +	temp = max_t(u32, dev_t->t_iaa,	dev_t->cyc_iaa * gpmc_t->sync_clk);
> +	temp += gpmc_t->clk_activation * 1000;
> +	if (dev_t->cyc_oe)
> +		temp = max_t(u32, temp, (gpmc_t->oe_on +
> +				gpmc_ticks_to_ns(dev_t->cyc_oe)) * 1000);
> +	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> +	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
> +	gpmc_t->cs_rd_off = gpmc_t->oe_off;
> +
> +	/* rd_cycle */
> +	temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
> +	temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
> +							gpmc_t->access * 1000;
> +	/* barter t_ce_rdyz with t_cez_r ? */
> +	if (dev_t->t_ce_rdyz)
> +		temp = max_t(u32, temp,
> +				gpmc_t->cs_rd_off * 1000 + dev_t->t_ce_rdyz);
> +	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> +	return 0;
> +}

[...]

> diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
> index 1cafbfd..e59a932 100644
> --- a/arch/arm/plat-omap/include/plat/gpmc.h
> +++ b/arch/arm/plat-omap/include/plat/gpmc.h
> @@ -152,6 +152,67 @@ struct gpmc_timings {
>  	struct gpmc_bool_timings bool_timings;
>  };
>  
> +/* Device timings in picoseconds */

Why pico seconds and not nanoseconds? I understand you may need to
temporarily convert to pico-secs for rounding, but when providing timing
it seems nano-secs is more suitable.

> +struct gpmc_device_timings {
> +	u32     t_ceasu;	/* address setup to CS valid */
> +	u32     t_avdasu;	/* address setup to ADV valid */
> +	/* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
> +	 * of tusb using these timings even for sync whilst
> +	 * ideally for adv_rd/(wr)_off it should have considered
> +	 * t_avdh instead. This indirectly necessitates r/w
> +	 * variations of t_avdp as it is possible to have one
> +	 * sync & other async
> +	 */
> +	u32	t_avdp_r;	/* ADV low time (what about t_cer ?) */
> +	u32	t_avdp_w;
> +	u32	t_aavdh;	/* address hold time */
> +	u32     t_oeasu;	/* address setup to OE valid */
> +	u32     t_aa;		/* access time from ADV assertion */
> +	u32     t_iaa;		/* initial access time */
> +	u32     t_oe;		/* access time from OE assertion */
> +	u32     t_ce;		/* access time from CS asertion */
> +	u32     t_rd_cycle;	/* read cycle time */
> +	u32     t_cez_r;	/* read CS deassertion to high Z */
> +	u32     t_cez_w;	/* write CS deassertion to high Z */
> +	u32     t_oez;		/* OE deassertion to high Z */
> +	u32     t_weasu;	/* address setup to WE valid */
> +	u32     t_wpl;		/* write assertion time */
> +	u32     t_wph;		/* write deassertion time */
> +	u32     t_wr_cycle;	/* write cycle time */
> +
> +	u32	clk;
> +	u32	t_bacc;		/* burst access valid clock to output delay */
> +	u32	t_ces;		/* CS setup time to clk */
> +	u32	t_avds;		/* ADV setup time to clk */
> +	u32	t_avdh;		/* ADV hold time from clk */
> +	u32     t_ach;		/* address hold time from clk */
> +	u32	t_rdyo;		/* clk to ready valid */
> +
> +	u32	t_ce_rdyz;	/* XXX: description ?, or use t_cez instead */
> +	u32	t_ce_avd;	/* CS on to ADV on delay */
> +
> +	/* XXX: check the possibility of combining
> +	 * cyc_aavhd_oe & cyc_aavdh_we
> +	 */
> +	u8	cyc_aavdh_oe;
> +	u8	cyc_aavdh_we;
> +	u8	cyc_oe;
> +	u8	cyc_wpl;
> +	u32     cyc_iaa;
> +
> +	bool	mux;		/* address & data muxed */
> +	bool	sync_write;	/* synchronous write */
> +	bool	sync_read;	/* synchronous read */
> +
> +	bool	ce_xdelay;
> +	bool	avd_xdelay;
> +	bool	oe_xdelay;
> +	bool	we_xdelay;
> +};

I am a little concerned about the above timings structure. For example,
if I am adding support for a new devices it is not clear ...

1. Which are required
2. Which are applicable for async, sync, address-data multiplexed etc.
3. Exactly how these relate to the fields in the gpmc registers.

I understand that this is based upon how timings for onenand and tusb
are being calculated today, but I am not sure that this is the way to go
for all devices. Personally, I would like to see us get away from how
those devices are calculating timings for any new device.

In general, I am concerned that we are abstracting the timings further
from the actual register fields. For example, the timings parameter
"t_ceasu" is described "address setup to CS valid" which is not
incorrect but this value is really just programming the CSONTIME field
and so why not call this cs_on?

So although this may consolidate how the timings are calculated today, I
am concerned it will be confusing to add timings for a new device. At
least if I am calculating timings, I am taking the timing information
for the device and translating that to the how I need to program the
gpmc register fields.

Cheers
Jon

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

* [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
@ 2012-08-23  2:58     ` Jon Hunter
  0 siblings, 0 replies; 74+ messages in thread
From: Jon Hunter @ 2012-08-23  2:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Afzal,

On 08/21/2012 05:45 AM, Afzal Mohammed wrote:
> Presently there are three peripherals that gets it timing
> by runtime calculation. Those peripherals can work with
> frequency scaling that affects gpmc clock. But timing
> calculation for them are in different ways.
> 
> Here a generic runtime calculation method is proposed. Input
> to this function were selected so that they represent timing
> variables that are present in peripheral datasheets. Motive
> behind this was to achieve DT bindings for the inputs as is.
> Even though a few of the tusb6010 timings could not be made
> directly related to timings normally found on peripherals,
> expressions used were translated to those that could be
> justified.
> 
> There are possibilities of improving the calculations, like
> calculating timing for read & write operations in a more
> similar way. Expressions derived here were tested for async
> onenand on omap3evm (as vanilla Kernel does not have omap3evm
> onenand support, local patch was used). Other peripherals,
> tusb6010, smc91x calculations were validated by simulating
> on omap3evm.
> 
> Regarding "we_on" for onenand async, it was found that even
> for muxed address/data, it need not be greater than
> "adv_wr_off", but rather could be derived from write setup
> time for peripheral from start of access time, hence would
> more be in line with peripheral timings. With this method
> it was working fine. If it is required in some cases to
> have "we_on" same as "wr_data_mux_bus" (i.e. greater than
> "adv_wr_off"), another variable could be added to indicate
> it. But such a requirement is not expected though.
> 
> Whole of this exercise is being done to achieve driver and
> DT conversion. If timings could not be calculated in a
> peripheral agnostic way, either gpmc driver would have to
> be peripheral gnostic or a wrapper arrangement over gpmc
> driver would be required.
> 
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
>  arch/arm/mach-omap2/gpmc.c             |  302 ++++++++++++++++++++++++++++++++
>  arch/arm/plat-omap/include/plat/gpmc.h |   61 +++++++
>  2 files changed, 363 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index d005b3a..d8e5b08 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -233,6 +233,18 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
>  	return ticks * gpmc_get_fclk_period() / 1000;
>  }
>  
> +unsigned int gpmc_ticks_to_ps(unsigned int ticks)
> +{
> +	return ticks * gpmc_get_fclk_period();
> +}
> +
> +unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
> +{
> +	unsigned long ticks = gpmc_ps_to_ticks(time_ps);
> +
> +	return ticks * gpmc_get_fclk_period();
> +}
> +
>  static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
>  {
>  	u32 l;
> @@ -884,6 +896,296 @@ static void __init gpmc_mem_init(void)
>  	}
>  }
>  
> +static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
> +{
> +	u32 temp;
> +	int div;
> +
> +	div = gpmc_calc_divider(sync_clk);
> +	temp = gpmc_ps_to_ticks(time_ps);
> +	temp = (temp + div - 1) / div;
> +	return gpmc_ticks_to_ps(temp * div);
> +}
> +
> +/* can the cycles be avoided ? */

What is the above comment referring too?

> +static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
> +				struct gpmc_device_timings *dev_t)
> +{
> +	bool mux = dev_t->mux;
> +	u32 temp;
> +
> +	/* adv_rd_off */
> +	temp = dev_t->t_avdp_r;
> +	/* mux check required ? */
> +	if (mux) {
> +		/* t_avdp not to be required for sync, only added for tusb this
> +		 * indirectly necessitates requirement of t_avdp_r & t_avdp_w
> +		 * instead of having a single t_avdp
> +		 */
> +		temp = max_t(u32, temp,	gpmc_t->clk_activation * 1000 +
> +							dev_t->t_avdh);
> +		temp = max_t(u32,
> +			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
> +	}
> +	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> +	/* oe_on */
> +	temp = dev_t->t_oeasu; /* remove this ? */
> +	if (mux) {
> +		temp = max_t(u32, temp,
> +			gpmc_t->clk_activation * 1000 + dev_t->t_ach);
> +		temp = max_t(u32, temp, (gpmc_t->adv_rd_off +
> +				gpmc_ticks_to_ns(dev_t->cyc_aavdh_oe)) * 1000);
> +	}
> +	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> +	/* access */
> +	/* any scope for improvement ?, by combining oe_on & clk_activation,
> +	 * need to check whether access = clk_activation + round to sync clk ?
> +	 */
> +	temp = max_t(u32, dev_t->t_iaa,	dev_t->cyc_iaa * gpmc_t->sync_clk);
> +	temp += gpmc_t->clk_activation * 1000;
> +	if (dev_t->cyc_oe)
> +		temp = max_t(u32, temp, (gpmc_t->oe_on +
> +				gpmc_ticks_to_ns(dev_t->cyc_oe)) * 1000);
> +	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> +	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
> +	gpmc_t->cs_rd_off = gpmc_t->oe_off;
> +
> +	/* rd_cycle */
> +	temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
> +	temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
> +							gpmc_t->access * 1000;
> +	/* barter t_ce_rdyz with t_cez_r ? */
> +	if (dev_t->t_ce_rdyz)
> +		temp = max_t(u32, temp,
> +				gpmc_t->cs_rd_off * 1000 + dev_t->t_ce_rdyz);
> +	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> +	return 0;
> +}

[...]

> diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
> index 1cafbfd..e59a932 100644
> --- a/arch/arm/plat-omap/include/plat/gpmc.h
> +++ b/arch/arm/plat-omap/include/plat/gpmc.h
> @@ -152,6 +152,67 @@ struct gpmc_timings {
>  	struct gpmc_bool_timings bool_timings;
>  };
>  
> +/* Device timings in picoseconds */

Why pico seconds and not nanoseconds? I understand you may need to
temporarily convert to pico-secs for rounding, but when providing timing
it seems nano-secs is more suitable.

> +struct gpmc_device_timings {
> +	u32     t_ceasu;	/* address setup to CS valid */
> +	u32     t_avdasu;	/* address setup to ADV valid */
> +	/* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
> +	 * of tusb using these timings even for sync whilst
> +	 * ideally for adv_rd/(wr)_off it should have considered
> +	 * t_avdh instead. This indirectly necessitates r/w
> +	 * variations of t_avdp as it is possible to have one
> +	 * sync & other async
> +	 */
> +	u32	t_avdp_r;	/* ADV low time (what about t_cer ?) */
> +	u32	t_avdp_w;
> +	u32	t_aavdh;	/* address hold time */
> +	u32     t_oeasu;	/* address setup to OE valid */
> +	u32     t_aa;		/* access time from ADV assertion */
> +	u32     t_iaa;		/* initial access time */
> +	u32     t_oe;		/* access time from OE assertion */
> +	u32     t_ce;		/* access time from CS asertion */
> +	u32     t_rd_cycle;	/* read cycle time */
> +	u32     t_cez_r;	/* read CS deassertion to high Z */
> +	u32     t_cez_w;	/* write CS deassertion to high Z */
> +	u32     t_oez;		/* OE deassertion to high Z */
> +	u32     t_weasu;	/* address setup to WE valid */
> +	u32     t_wpl;		/* write assertion time */
> +	u32     t_wph;		/* write deassertion time */
> +	u32     t_wr_cycle;	/* write cycle time */
> +
> +	u32	clk;
> +	u32	t_bacc;		/* burst access valid clock to output delay */
> +	u32	t_ces;		/* CS setup time to clk */
> +	u32	t_avds;		/* ADV setup time to clk */
> +	u32	t_avdh;		/* ADV hold time from clk */
> +	u32     t_ach;		/* address hold time from clk */
> +	u32	t_rdyo;		/* clk to ready valid */
> +
> +	u32	t_ce_rdyz;	/* XXX: description ?, or use t_cez instead */
> +	u32	t_ce_avd;	/* CS on to ADV on delay */
> +
> +	/* XXX: check the possibility of combining
> +	 * cyc_aavhd_oe & cyc_aavdh_we
> +	 */
> +	u8	cyc_aavdh_oe;
> +	u8	cyc_aavdh_we;
> +	u8	cyc_oe;
> +	u8	cyc_wpl;
> +	u32     cyc_iaa;
> +
> +	bool	mux;		/* address & data muxed */
> +	bool	sync_write;	/* synchronous write */
> +	bool	sync_read;	/* synchronous read */
> +
> +	bool	ce_xdelay;
> +	bool	avd_xdelay;
> +	bool	oe_xdelay;
> +	bool	we_xdelay;
> +};

I am a little concerned about the above timings structure. For example,
if I am adding support for a new devices it is not clear ...

1. Which are required
2. Which are applicable for async, sync, address-data multiplexed etc.
3. Exactly how these relate to the fields in the gpmc registers.

I understand that this is based upon how timings for onenand and tusb
are being calculated today, but I am not sure that this is the way to go
for all devices. Personally, I would like to see us get away from how
those devices are calculating timings for any new device.

In general, I am concerned that we are abstracting the timings further
from the actual register fields. For example, the timings parameter
"t_ceasu" is described "address setup to CS valid" which is not
incorrect but this value is really just programming the CSONTIME field
and so why not call this cs_on?

So although this may consolidate how the timings are calculated today, I
am concerned it will be confusing to add timings for a new device. At
least if I am calculating timings, I am taking the timing information
for the device and translating that to the how I need to program the
gpmc register fields.

Cheers
Jon

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

* Re: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-08-21 10:46   ` Afzal Mohammed
@ 2012-08-24 19:46     ` Tony Lindgren
  -1 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-08-24 19:46 UTC (permalink / raw)
  To: Afzal Mohammed; +Cc: jon-hunter, paul, linux-omap, linux-arm-kernel

* Afzal Mohammed <afzal@ti.com> [120821 03:46]:
> Generic gpmc timing calculation helper is available now, use
> it instead of custom timing calculation.

This hangs n800 during the boot.

Tony

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-08-24 19:46     ` Tony Lindgren
  0 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-08-24 19:46 UTC (permalink / raw)
  To: linux-arm-kernel

* Afzal Mohammed <afzal@ti.com> [120821 03:46]:
> Generic gpmc timing calculation helper is available now, use
> it instead of custom timing calculation.

This hangs n800 during the boot.

Tony

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

* Re: [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
  2012-08-23  2:58     ` Jon Hunter
@ 2012-08-24 19:54       ` Tony Lindgren
  -1 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-08-24 19:54 UTC (permalink / raw)
  To: Jon Hunter; +Cc: Afzal Mohammed, paul, linux-omap, linux-arm-kernel

* Jon Hunter <jon-hunter@TI.COM> [120822 19:58]:
> 
> So although this may consolidate how the timings are calculated today, I
> am concerned it will be confusing to add timings for a new device. At
> least if I am calculating timings, I am taking the timing information
> for the device and translating that to the how I need to program the
> gpmc register fields.

Yes agreed. Also as some values make sense only in cycles, converting them
back and forth to time is wrong. So at least some values should have an
option to specify them in cycles directly, and then ignore any time based
values.

Regards,

Tony

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

* [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
@ 2012-08-24 19:54       ` Tony Lindgren
  0 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-08-24 19:54 UTC (permalink / raw)
  To: linux-arm-kernel

* Jon Hunter <jon-hunter@TI.COM> [120822 19:58]:
> 
> So although this may consolidate how the timings are calculated today, I
> am concerned it will be confusing to add timings for a new device. At
> least if I am calculating timings, I am taking the timing information
> for the device and translating that to the how I need to program the
> gpmc register fields.

Yes agreed. Also as some values make sense only in cycles, converting them
back and forth to time is wrong. So at least some values should have an
option to specify them in cycles directly, and then ignore any time based
values.

Regards,

Tony

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

* RE: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-08-24 19:46     ` Tony Lindgren
@ 2012-08-27  8:34       ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27  8:34 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Hunter, Jon, paul, linux-omap, linux-arm-kernel

Hi Tony,

On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:

> This hangs n800 during the boot.

Shall I read the above as n800 boot without patch 10/10,
but with the other patches in this series ?

As per the board file, n800 has tusb6010 as well as
OneNAND in sync read & async write mode, was OneNAND
working without 10/10.

Do you have any idea, which timing could have gone wrong,
can you please sent me DEBUG enabled gpmc log with and
without 10/10.

Regards
Afzal

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-08-27  8:34       ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:

> This hangs n800 during the boot.

Shall I read the above as n800 boot without patch 10/10,
but with the other patches in this series ?

As per the board file, n800 has tusb6010 as well as
OneNAND in sync read & async write mode, was OneNAND
working without 10/10.

Do you have any idea, which timing could have gone wrong,
can you please sent me DEBUG enabled gpmc log with and
without 10/10.

Regards
Afzal

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

* RE: [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
  2012-08-23  2:58     ` Jon Hunter
@ 2012-08-27 10:37       ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27 10:37 UTC (permalink / raw)
  To: Hunter, Jon; +Cc: tony, paul, linux-omap, linux-arm-kernel

Hi Jon,

On Thu, Aug 23, 2012 at 08:28:44, Hunter, Jon wrote:
> On 08/21/2012 05:45 AM, Afzal Mohammed wrote:

> > +/* can the cycles be avoided ? */
> 
> What is the above comment referring too?

This was added in the initial stages and refers to the usage of
cycles in struct gpmc_device_timings. I wanted to avoid usage
of cycles, but it seems it is required logically as well. This
was mentioned as a note for future to find out whether at any
future point of time this can be removed.

> > +/* Device timings in picoseconds */
> 
> Why pico seconds and not nanoseconds? I understand you may need to
> temporarily convert to pico-secs for rounding, but when providing timing
> it seems nano-secs is more suitable.

For more accuracy, if you see some of the tusb6010 calculation
are in picoseconds, this can be true for any device although
only tusb does so. If we hold on to picoseconds till the last
moment, value would be more accurate. For eg. 300 ps has to be
used in the case of tusb, and with ns, it can't be accounted for

> I am a little concerned about the above timings structure. For example,
> if I am adding support for a new devices it is not clear ...
> 
> 1. Which are required
> 2. Which are applicable for async, sync, address-data multiplexed etc.
> 3. Exactly how these relate to the fields in the gpmc registers.

Please see at the end

> 
> I understand that this is based upon how timings for onenand and tusb
> are being calculated today, but I am not sure that this is the way to go
> for all devices. Personally, I would like to see us get away from how
> those devices are calculating timings for any new device.

You cannot do away with many of the those, as logically they
are right. Eg. read data should be available at access time,
assuming a zero data hold time, we can very well derive an
expression as,

read de-assertion time (oe_off) = access time plus 1 gpmc clock,

and this is what the existing calculations do, and also the
generic routine. There could be other constraints, but this
certainly should be one (I do realize that oe_off could be
optimized to be less than access time, by relying on read
hold time, then again effect of it would be in similar way
for different peripherals, but let's forget about
optimization in the beginning)

> In general, I am concerned that we are abstracting the timings further
> from the actual register fields. For example, the timings parameter
> "t_ceasu" is described "address setup to CS valid" which is not
> incorrect but this value is really just programming the CSONTIME field
> and so why not call this cs_on?

Timing fields of struct gpmc_device_timings are selected such
that they should be bindable by DT. At least one of the peripheral
datasheet has these fields. If user knows timings in terms of
gpmc values, he can directly use struct gpmc_timings, but
then all the values should be updated in struct gpmc_timings.
User should not update some of the values in terms of
peripheral timings, others in terms of gpmc timings, that
would make things complex and does not seem the right way
to me.

cs_on and other gpmc aware timings could be binded by DT, not as
peripheral timing, but as gpmc timing.

Bindings for peripheral DT timings should be something that
can be obtained from peripheral datasheet, here accidentally
it is same as gpmc timings, but not most timings are this way.
Also there could be other constraints that can come for cs_on,
even though I have not come across any till now.

> 
> So although this may consolidate how the timings are calculated today, I
> am concerned it will be confusing to add timings for a new device. At
> least if I am calculating timings, I am taking the timing information
> for the device and translating that to the how I need to program the
> gpmc register fields.

If I am not wrong, GPMC IP has been present for around a
decade, and so far I have not come across any generic time
calculation method that can be applied to all peripherals.
Getting to work same peripheral for a different gpmc
frequency is another problem.

Here we are trying to generalize based on the understanding of
gpmc & peripheral timings, as well as by a kind of reverse
engineering without most of the hardware or datasheet. Think of
this as an attempt to create one, let it evolve and become a
robust one. If a new user want to add a peripheral, let him add
support, input timings are selected such that it is found in
peripheral datasheet, if that does not work, let him try
to add any new timing field or alter existing expression
as he deems to be proper and verify that it does not break
others. And I can help provided I am not heavily loaded
with other works.

And at least for initial users, they are expected to have
some grasp on how to calculate timings, such a user will
not be much worried about your 3 concerns above, anyway as
of now they need to have a good grasp on it.

Meanwhile I will try to document more.

Regards
Afzal

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

* [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
@ 2012-08-27 10:37       ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27 10:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

On Thu, Aug 23, 2012 at 08:28:44, Hunter, Jon wrote:
> On 08/21/2012 05:45 AM, Afzal Mohammed wrote:

> > +/* can the cycles be avoided ? */
> 
> What is the above comment referring too?

This was added in the initial stages and refers to the usage of
cycles in struct gpmc_device_timings. I wanted to avoid usage
of cycles, but it seems it is required logically as well. This
was mentioned as a note for future to find out whether at any
future point of time this can be removed.

> > +/* Device timings in picoseconds */
> 
> Why pico seconds and not nanoseconds? I understand you may need to
> temporarily convert to pico-secs for rounding, but when providing timing
> it seems nano-secs is more suitable.

For more accuracy, if you see some of the tusb6010 calculation
are in picoseconds, this can be true for any device although
only tusb does so. If we hold on to picoseconds till the last
moment, value would be more accurate. For eg. 300 ps has to be
used in the case of tusb, and with ns, it can't be accounted for

> I am a little concerned about the above timings structure. For example,
> if I am adding support for a new devices it is not clear ...
> 
> 1. Which are required
> 2. Which are applicable for async, sync, address-data multiplexed etc.
> 3. Exactly how these relate to the fields in the gpmc registers.

Please see at the end

> 
> I understand that this is based upon how timings for onenand and tusb
> are being calculated today, but I am not sure that this is the way to go
> for all devices. Personally, I would like to see us get away from how
> those devices are calculating timings for any new device.

You cannot do away with many of the those, as logically they
are right. Eg. read data should be available at access time,
assuming a zero data hold time, we can very well derive an
expression as,

read de-assertion time (oe_off) = access time plus 1 gpmc clock,

and this is what the existing calculations do, and also the
generic routine. There could be other constraints, but this
certainly should be one (I do realize that oe_off could be
optimized to be less than access time, by relying on read
hold time, then again effect of it would be in similar way
for different peripherals, but let's forget about
optimization in the beginning)

> In general, I am concerned that we are abstracting the timings further
> from the actual register fields. For example, the timings parameter
> "t_ceasu" is described "address setup to CS valid" which is not
> incorrect but this value is really just programming the CSONTIME field
> and so why not call this cs_on?

Timing fields of struct gpmc_device_timings are selected such
that they should be bindable by DT. At least one of the peripheral
datasheet has these fields. If user knows timings in terms of
gpmc values, he can directly use struct gpmc_timings, but
then all the values should be updated in struct gpmc_timings.
User should not update some of the values in terms of
peripheral timings, others in terms of gpmc timings, that
would make things complex and does not seem the right way
to me.

cs_on and other gpmc aware timings could be binded by DT, not as
peripheral timing, but as gpmc timing.

Bindings for peripheral DT timings should be something that
can be obtained from peripheral datasheet, here accidentally
it is same as gpmc timings, but not most timings are this way.
Also there could be other constraints that can come for cs_on,
even though I have not come across any till now.

> 
> So although this may consolidate how the timings are calculated today, I
> am concerned it will be confusing to add timings for a new device. At
> least if I am calculating timings, I am taking the timing information
> for the device and translating that to the how I need to program the
> gpmc register fields.

If I am not wrong, GPMC IP has been present for around a
decade, and so far I have not come across any generic time
calculation method that can be applied to all peripherals.
Getting to work same peripheral for a different gpmc
frequency is another problem.

Here we are trying to generalize based on the understanding of
gpmc & peripheral timings, as well as by a kind of reverse
engineering without most of the hardware or datasheet. Think of
this as an attempt to create one, let it evolve and become a
robust one. If a new user want to add a peripheral, let him add
support, input timings are selected such that it is found in
peripheral datasheet, if that does not work, let him try
to add any new timing field or alter existing expression
as he deems to be proper and verify that it does not break
others. And I can help provided I am not heavily loaded
with other works.

And at least for initial users, they are expected to have
some grasp on how to calculate timings, such a user will
not be much worried about your 3 concerns above, anyway as
of now they need to have a good grasp on it.

Meanwhile I will try to document more.

Regards
Afzal

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

* RE: [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
  2012-08-24 19:54       ` Tony Lindgren
@ 2012-08-27 11:46         ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27 11:46 UTC (permalink / raw)
  To: Tony Lindgren, Hunter, Jon; +Cc: paul, linux-omap, linux-arm-kernel

Hi Tony,

On Sat, Aug 25, 2012 at 01:24:47, Tony Lindgren wrote:

> Yes agreed. Also as some values make sense only in cycles, converting them
> back and forth to time is wrong. So at least some values should have an
> option to specify them in cycles directly, and then ignore any time based
> values.

Which values in struct gpmc_device_timings are you referring to ?

Values that need to have an option to specify in cycles has been provided
such an option, while not updating time based field value, you can
achieve what you mentioned above. But if you want that to be handled in
in generic routine, I will do so.

Regards
Afzal

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

* [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
@ 2012-08-27 11:46         ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27 11:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

On Sat, Aug 25, 2012 at 01:24:47, Tony Lindgren wrote:

> Yes agreed. Also as some values make sense only in cycles, converting them
> back and forth to time is wrong. So at least some values should have an
> option to specify them in cycles directly, and then ignore any time based
> values.

Which values in struct gpmc_device_timings are you referring to ?

Values that need to have an option to specify in cycles has been provided
such an option, while not updating time based field value, you can
achieve what you mentioned above. But if you want that to be handled in
in generic routine, I will do so.

Regards
Afzal

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

* Re: [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
  2012-08-21 10:41 ` Afzal Mohammed
@ 2012-08-27 12:16   ` Daniel Mack
  -1 siblings, 0 replies; 74+ messages in thread
From: Daniel Mack @ 2012-08-27 12:16 UTC (permalink / raw)
  To: Afzal Mohammed; +Cc: tony, jon-hunter, paul, linux-omap, linux-arm-kernel

Hi Afzal,

On 21.08.2012 12:41, Afzal Mohammed wrote:
> This series provides a generic gpmc timing calculation routine. There
> were three peripherals (OneNAND, tusb6010, smc91x) using custom timing
> calculations, they are migrated to use the generic timing calculation.
> 
> Such a generic routine would help create a driver out of gpmc platform
> code, which would be peripheral agnostic and thus lead to DT finally.
> Input to generic timing calculation routine would be gpmc peripheral
> timings, output - translated timings that gpmc can understand. Later,
> to DT'ify, gpmc peripheral timings could be passed through DT. Input
> timings that has been used here are selected such that it represents
> those that are present in peripheral timing datasheets.

What I don't understand yet about this new approach is where the gpmc
client code should live in. In order to probe the drivers via DT, each
driver would need to call the gpmc support functions itself, right? Is
the plan to obsolete helper functions like gpmc_nand_init() and move
that functionality to the drivers?

I applied these patches locally and would like to help get the NAND
controller on my AX33xx DT-driven board going. Let me know if I can do
anything here.


Regards,
Daniel


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

* [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
@ 2012-08-27 12:16   ` Daniel Mack
  0 siblings, 0 replies; 74+ messages in thread
From: Daniel Mack @ 2012-08-27 12:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Afzal,

On 21.08.2012 12:41, Afzal Mohammed wrote:
> This series provides a generic gpmc timing calculation routine. There
> were three peripherals (OneNAND, tusb6010, smc91x) using custom timing
> calculations, they are migrated to use the generic timing calculation.
> 
> Such a generic routine would help create a driver out of gpmc platform
> code, which would be peripheral agnostic and thus lead to DT finally.
> Input to generic timing calculation routine would be gpmc peripheral
> timings, output - translated timings that gpmc can understand. Later,
> to DT'ify, gpmc peripheral timings could be passed through DT. Input
> timings that has been used here are selected such that it represents
> those that are present in peripheral timing datasheets.

What I don't understand yet about this new approach is where the gpmc
client code should live in. In order to probe the drivers via DT, each
driver would need to call the gpmc support functions itself, right? Is
the plan to obsolete helper functions like gpmc_nand_init() and move
that functionality to the drivers?

I applied these patches locally and would like to help get the NAND
controller on my AX33xx DT-driven board going. Let me know if I can do
anything here.


Regards,
Daniel

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

* RE: [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
  2012-08-27 12:16   ` Daniel Mack
@ 2012-08-27 12:38     ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27 12:38 UTC (permalink / raw)
  To: Daniel Mack; +Cc: tony, Hunter, Jon, paul, linux-omap, linux-arm-kernel

Hi Daniel,

On Mon, Aug 27, 2012 at 17:46:17, Daniel Mack wrote:

> > Such a generic routine would help create a driver out of gpmc platform
> > code, which would be peripheral agnostic and thus lead to DT finally.
> > Input to generic timing calculation routine would be gpmc peripheral
> > timings, output - translated timings that gpmc can understand. Later,
> > to DT'ify, gpmc peripheral timings could be passed through DT. Input
> > timings that has been used here are selected such that it represents
> > those that are present in peripheral timing datasheets.
> 
> What I don't understand yet about this new approach is where the gpmc
> client code should live in. In order to probe the drivers via DT, each
> driver would need to call the gpmc support functions itself, right? Is

By gpmc client code, if you are referring to helper functions in
mach-omap2/gpmc-*, if things go as per plan, with DT, they will go away
and gpmc driver would handle those based on the information from DT.

No change would be needed for client drivers like smc91x ethernet drivers,
but NAND driver may need some change to live with DT as it is tightly
coupled with GPMC.

> the plan to obsolete helper functions like gpmc_nand_init() and move
> that functionality to the drivers?

Yes, plan is to obsolete the functions like gpmc_nand_init, those tasks
would be handled by gpmc driver

> 
> I applied these patches locally and would like to help get the NAND
> controller on my AX33xx DT-driven board going. Let me know if I can do
> anything here.

Thanks for offering the help, will take liberty to ask you for help
when required. BTW, do you have any OMAP family boards ?

Regards
Afzal

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

* [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
@ 2012-08-27 12:38     ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27 12:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Daniel,

On Mon, Aug 27, 2012 at 17:46:17, Daniel Mack wrote:

> > Such a generic routine would help create a driver out of gpmc platform
> > code, which would be peripheral agnostic and thus lead to DT finally.
> > Input to generic timing calculation routine would be gpmc peripheral
> > timings, output - translated timings that gpmc can understand. Later,
> > to DT'ify, gpmc peripheral timings could be passed through DT. Input
> > timings that has been used here are selected such that it represents
> > those that are present in peripheral timing datasheets.
> 
> What I don't understand yet about this new approach is where the gpmc
> client code should live in. In order to probe the drivers via DT, each
> driver would need to call the gpmc support functions itself, right? Is

By gpmc client code, if you are referring to helper functions in
mach-omap2/gpmc-*, if things go as per plan, with DT, they will go away
and gpmc driver would handle those based on the information from DT.

No change would be needed for client drivers like smc91x ethernet drivers,
but NAND driver may need some change to live with DT as it is tightly
coupled with GPMC.

> the plan to obsolete helper functions like gpmc_nand_init() and move
> that functionality to the drivers?

Yes, plan is to obsolete the functions like gpmc_nand_init, those tasks
would be handled by gpmc driver

> 
> I applied these patches locally and would like to help get the NAND
> controller on my AX33xx DT-driven board going. Let me know if I can do
> anything here.

Thanks for offering the help, will take liberty to ask you for help
when required. BTW, do you have any OMAP family boards ?

Regards
Afzal

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

* Re: [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
  2012-08-27 12:38     ` Mohammed, Afzal
@ 2012-08-27 13:30       ` Daniel Mack
  -1 siblings, 0 replies; 74+ messages in thread
From: Daniel Mack @ 2012-08-27 13:30 UTC (permalink / raw)
  To: Mohammed, Afzal; +Cc: tony, Hunter, Jon, paul, linux-omap, linux-arm-kernel

On 27.08.2012 14:38, Mohammed, Afzal wrote:
> On Mon, Aug 27, 2012 at 17:46:17, Daniel Mack wrote:
> 
>>> Such a generic routine would help create a driver out of gpmc platform
>>> code, which would be peripheral agnostic and thus lead to DT finally.
>>> Input to generic timing calculation routine would be gpmc peripheral
>>> timings, output - translated timings that gpmc can understand. Later,
>>> to DT'ify, gpmc peripheral timings could be passed through DT. Input
>>> timings that has been used here are selected such that it represents
>>> those that are present in peripheral timing datasheets.
>>
>> What I don't understand yet about this new approach is where the gpmc
>> client code should live in. In order to probe the drivers via DT, each
>> driver would need to call the gpmc support functions itself, right? Is
> 
> By gpmc client code, if you are referring to helper functions in
> mach-omap2/gpmc-*, if things go as per plan, with DT, they will go away
> and gpmc driver would handle those based on the information from DT.

So the GPMC driver is the one that is matched from DT, and the NAND
driver will the be instanciated from the (generic) GPMC driver?

> No change would be needed for client drivers like smc91x ethernet drivers,
> but NAND driver may need some change to live with DT as it is tightly
> coupled with GPMC.

NAND drivers also typically parse partition entries that are children of
the DT node the are owning.

>> the plan to obsolete helper functions like gpmc_nand_init() and move
>> that functionality to the drivers?
> 
> Yes, plan is to obsolete the functions like gpmc_nand_init, those tasks
> would be handled by gpmc driver
> 
>>
>> I applied these patches locally and would like to help get the NAND
>> controller on my AX33xx DT-driven board going. Let me know if I can do
>> anything here.
> 
> Thanks for offering the help, will take liberty to ask you for help
> when required. BTW, do you have any OMAP family boards ?

I do have a beaglboard xM, but the board I'm currently working with is a
custom one based on an AM33xx.


Thanks,
Daniel


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

* [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
@ 2012-08-27 13:30       ` Daniel Mack
  0 siblings, 0 replies; 74+ messages in thread
From: Daniel Mack @ 2012-08-27 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

On 27.08.2012 14:38, Mohammed, Afzal wrote:
> On Mon, Aug 27, 2012 at 17:46:17, Daniel Mack wrote:
> 
>>> Such a generic routine would help create a driver out of gpmc platform
>>> code, which would be peripheral agnostic and thus lead to DT finally.
>>> Input to generic timing calculation routine would be gpmc peripheral
>>> timings, output - translated timings that gpmc can understand. Later,
>>> to DT'ify, gpmc peripheral timings could be passed through DT. Input
>>> timings that has been used here are selected such that it represents
>>> those that are present in peripheral timing datasheets.
>>
>> What I don't understand yet about this new approach is where the gpmc
>> client code should live in. In order to probe the drivers via DT, each
>> driver would need to call the gpmc support functions itself, right? Is
> 
> By gpmc client code, if you are referring to helper functions in
> mach-omap2/gpmc-*, if things go as per plan, with DT, they will go away
> and gpmc driver would handle those based on the information from DT.

So the GPMC driver is the one that is matched from DT, and the NAND
driver will the be instanciated from the (generic) GPMC driver?

> No change would be needed for client drivers like smc91x ethernet drivers,
> but NAND driver may need some change to live with DT as it is tightly
> coupled with GPMC.

NAND drivers also typically parse partition entries that are children of
the DT node the are owning.

>> the plan to obsolete helper functions like gpmc_nand_init() and move
>> that functionality to the drivers?
> 
> Yes, plan is to obsolete the functions like gpmc_nand_init, those tasks
> would be handled by gpmc driver
> 
>>
>> I applied these patches locally and would like to help get the NAND
>> controller on my AX33xx DT-driven board going. Let me know if I can do
>> anything here.
> 
> Thanks for offering the help, will take liberty to ask you for help
> when required. BTW, do you have any OMAP family boards ?

I do have a beaglboard xM, but the board I'm currently working with is a
custom one based on an AM33xx.


Thanks,
Daniel

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

* RE: [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
  2012-08-27 13:30       ` Daniel Mack
@ 2012-08-27 14:01         ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27 14:01 UTC (permalink / raw)
  To: Daniel Mack; +Cc: tony, Hunter, Jon, paul, linux-omap, linux-arm-kernel

Hi Daniel,

On Mon, Aug 27, 2012 at 19:00:32, Daniel Mack wrote:

> So the GPMC driver is the one that is matched from DT, and the NAND
> driver will the be instanciated from the (generic) GPMC driver?

I think you were referring to nand device being instantiated from
gpmc driver?, hence resulting in nand driver getting probed. What I
have in mind is to represent peripherals connected to gpmc as childs
of gpmc node. For devices like smsc911x, as they already have DT
bindings, creating an of device for childs by parsing DT hopefully
should relieve task of handling their platform data.

Similarly for nand, creating an of device is to be done by gpmc
driver.

Once the bigger issue of timing is resolved, I am planning to
implement DT as said above

Also for the existing boards on non-DT boot, plan is to keep the
existing interface as such, with no change needed in board files.

> 
> > No change would be needed for client drivers like smc91x ethernet drivers,
> > but NAND driver may need some change to live with DT as it is tightly
> > coupled with GPMC.
> 
> NAND drivers also typically parse partition entries that are children of
> the DT node the are owning.

Yes, in addition to the above, omap nand driver would need to determine a
few gpmc specific like transfer mode.

> I do have a beaglboard xM, but the board I'm currently working with is a
> custom one based on an AM33xx.

I was in need of a board like rx51, n800 that currently calculate gpmc
timings at runtime to test the generic timing function, np, thanks again

Regards
Afzal

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

* [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver
@ 2012-08-27 14:01         ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-27 14:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Daniel,

On Mon, Aug 27, 2012 at 19:00:32, Daniel Mack wrote:

> So the GPMC driver is the one that is matched from DT, and the NAND
> driver will the be instanciated from the (generic) GPMC driver?

I think you were referring to nand device being instantiated from
gpmc driver?, hence resulting in nand driver getting probed. What I
have in mind is to represent peripherals connected to gpmc as childs
of gpmc node. For devices like smsc911x, as they already have DT
bindings, creating an of device for childs by parsing DT hopefully
should relieve task of handling their platform data.

Similarly for nand, creating an of device is to be done by gpmc
driver.

Once the bigger issue of timing is resolved, I am planning to
implement DT as said above

Also for the existing boards on non-DT boot, plan is to keep the
existing interface as such, with no change needed in board files.

> 
> > No change would be needed for client drivers like smc91x ethernet drivers,
> > but NAND driver may need some change to live with DT as it is tightly
> > coupled with GPMC.
> 
> NAND drivers also typically parse partition entries that are children of
> the DT node the are owning.

Yes, in addition to the above, omap nand driver would need to determine a
few gpmc specific like transfer mode.

> I do have a beaglboard xM, but the board I'm currently working with is a
> custom one based on an AM33xx.

I was in need of a board like rx51, n800 that currently calculate gpmc
timings at runtime to test the generic timing function, np, thanks again

Regards
Afzal

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

* Re: [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
  2012-08-27 10:37       ` Mohammed, Afzal
@ 2012-08-27 20:30         ` Jon Hunter
  -1 siblings, 0 replies; 74+ messages in thread
From: Jon Hunter @ 2012-08-27 20:30 UTC (permalink / raw)
  To: Mohammed, Afzal; +Cc: tony, paul, linux-omap, linux-arm-kernel

Hi Afzal,

On 08/27/2012 05:37 AM, Mohammed, Afzal wrote:
> On Thu, Aug 23, 2012 at 08:28:44, Hunter, Jon wrote:

[snip]

>> I understand that this is based upon how timings for onenand and tusb
>> are being calculated today, but I am not sure that this is the way to go
>> for all devices. Personally, I would like to see us get away from how
>> those devices are calculating timings for any new device.
> 
> You cannot do away with many of the those, as logically they
> are right. Eg. read data should be available at access time,
> assuming a zero data hold time, we can very well derive an
> expression as,

I am not saying that we do away with them for current devices, just
maintain them as is.

> read de-assertion time (oe_off) = access time plus 1 gpmc clock,
> 
> and this is what the existing calculations do, and also the
> generic routine. There could be other constraints, but this
> certainly should be one (I do realize that oe_off could be
> optimized to be less than access time, by relying on read
> hold time, then again effect of it would be in similar way
> for different peripherals, but let's forget about
> optimization in the beginning)
> 
>> In general, I am concerned that we are abstracting the timings further
>> from the actual register fields. For example, the timings parameter
>> "t_ceasu" is described "address setup to CS valid" which is not
>> incorrect but this value is really just programming the CSONTIME field
>> and so why not call this cs_on?
> 
> Timing fields of struct gpmc_device_timings are selected such
> that they should be bindable by DT. At least one of the peripheral
> datasheet has these fields.

Right, but these are not applicable to every device and so I worry this
could be confusing. However, more documentation may help clear this up.

> If user knows timings in terms of
> gpmc values, he can directly use struct gpmc_timings, but
> then all the values should be updated in struct gpmc_timings.
> User should not update some of the values in terms of
> peripheral timings, others in terms of gpmc timings, that
> would make things complex and does not seem the right way
> to me.
> 
> cs_on and other gpmc aware timings could be binded by DT, not as
> peripheral timing, but as gpmc timing.
> 
> Bindings for peripheral DT timings should be something that
> can be obtained from peripheral datasheet, here accidentally
> it is same as gpmc timings, but not most timings are this way.
> Also there could be other constraints that can come for cs_on,
> even though I have not come across any till now.
> 
>>
>> So although this may consolidate how the timings are calculated today, I
>> am concerned it will be confusing to add timings for a new device. At
>> least if I am calculating timings, I am taking the timing information
>> for the device and translating that to the how I need to program the
>> gpmc register fields.
> 
> If I am not wrong, GPMC IP has been present for around a
> decade, and so far I have not come across any generic time
> calculation method that can be applied to all peripherals.

Yes not an easy problem to solve :-(

> Getting to work same peripheral for a different gpmc
> frequency is another problem.
> 
> Here we are trying to generalize based on the understanding of
> gpmc & peripheral timings, as well as by a kind of reverse
> engineering without most of the hardware or datasheet. Think of
> this as an attempt to create one, let it evolve and become a
> robust one. If a new user want to add a peripheral, let him add
> support, input timings are selected such that it is found in
> peripheral datasheet, if that does not work, let him try
> to add any new timing field or alter existing expression
> as he deems to be proper and verify that it does not break
> others. And I can help provided I am not heavily loaded
> with other works.

So long as it is maintainable ;-)

> And at least for initial users, they are expected to have
> some grasp on how to calculate timings, such a user will
> not be much worried about your 3 concerns above, anyway as
> of now they need to have a good grasp on it.

I would consider myself to be an initial user and I am concerned,
doesn't that count?

An example, would be the following where you have 4 timing parameters
for access time. You need to dig through the code to understand how
these are being used.

+	u32     t_aa;		/* access time from ADV assertion */
+	u32     t_iaa;		/* initial access time */
+	u32     t_oe;		/* access time from OE assertion */
+	u32     t_ce;		/* access time from CS asertion */

> Meanwhile I will try to document more.

Yes more documentation is definitely needed.

Cheers
Jon

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

* [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
@ 2012-08-27 20:30         ` Jon Hunter
  0 siblings, 0 replies; 74+ messages in thread
From: Jon Hunter @ 2012-08-27 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Afzal,

On 08/27/2012 05:37 AM, Mohammed, Afzal wrote:
> On Thu, Aug 23, 2012 at 08:28:44, Hunter, Jon wrote:

[snip]

>> I understand that this is based upon how timings for onenand and tusb
>> are being calculated today, but I am not sure that this is the way to go
>> for all devices. Personally, I would like to see us get away from how
>> those devices are calculating timings for any new device.
> 
> You cannot do away with many of the those, as logically they
> are right. Eg. read data should be available at access time,
> assuming a zero data hold time, we can very well derive an
> expression as,

I am not saying that we do away with them for current devices, just
maintain them as is.

> read de-assertion time (oe_off) = access time plus 1 gpmc clock,
> 
> and this is what the existing calculations do, and also the
> generic routine. There could be other constraints, but this
> certainly should be one (I do realize that oe_off could be
> optimized to be less than access time, by relying on read
> hold time, then again effect of it would be in similar way
> for different peripherals, but let's forget about
> optimization in the beginning)
> 
>> In general, I am concerned that we are abstracting the timings further
>> from the actual register fields. For example, the timings parameter
>> "t_ceasu" is described "address setup to CS valid" which is not
>> incorrect but this value is really just programming the CSONTIME field
>> and so why not call this cs_on?
> 
> Timing fields of struct gpmc_device_timings are selected such
> that they should be bindable by DT. At least one of the peripheral
> datasheet has these fields.

Right, but these are not applicable to every device and so I worry this
could be confusing. However, more documentation may help clear this up.

> If user knows timings in terms of
> gpmc values, he can directly use struct gpmc_timings, but
> then all the values should be updated in struct gpmc_timings.
> User should not update some of the values in terms of
> peripheral timings, others in terms of gpmc timings, that
> would make things complex and does not seem the right way
> to me.
> 
> cs_on and other gpmc aware timings could be binded by DT, not as
> peripheral timing, but as gpmc timing.
> 
> Bindings for peripheral DT timings should be something that
> can be obtained from peripheral datasheet, here accidentally
> it is same as gpmc timings, but not most timings are this way.
> Also there could be other constraints that can come for cs_on,
> even though I have not come across any till now.
> 
>>
>> So although this may consolidate how the timings are calculated today, I
>> am concerned it will be confusing to add timings for a new device. At
>> least if I am calculating timings, I am taking the timing information
>> for the device and translating that to the how I need to program the
>> gpmc register fields.
> 
> If I am not wrong, GPMC IP has been present for around a
> decade, and so far I have not come across any generic time
> calculation method that can be applied to all peripherals.

Yes not an easy problem to solve :-(

> Getting to work same peripheral for a different gpmc
> frequency is another problem.
> 
> Here we are trying to generalize based on the understanding of
> gpmc & peripheral timings, as well as by a kind of reverse
> engineering without most of the hardware or datasheet. Think of
> this as an attempt to create one, let it evolve and become a
> robust one. If a new user want to add a peripheral, let him add
> support, input timings are selected such that it is found in
> peripheral datasheet, if that does not work, let him try
> to add any new timing field or alter existing expression
> as he deems to be proper and verify that it does not break
> others. And I can help provided I am not heavily loaded
> with other works.

So long as it is maintainable ;-)

> And at least for initial users, they are expected to have
> some grasp on how to calculate timings, such a user will
> not be much worried about your 3 concerns above, anyway as
> of now they need to have a good grasp on it.

I would consider myself to be an initial user and I am concerned,
doesn't that count?

An example, would be the following where you have 4 timing parameters
for access time. You need to dig through the code to understand how
these are being used.

+	u32     t_aa;		/* access time from ADV assertion */
+	u32     t_iaa;		/* initial access time */
+	u32     t_oe;		/* access time from OE assertion */
+	u32     t_ce;		/* access time from CS asertion */

> Meanwhile I will try to document more.

Yes more documentation is definitely needed.

Cheers
Jon

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

* RE: [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
  2012-08-27 20:30         ` Jon Hunter
@ 2012-08-28 12:21           ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-28 12:21 UTC (permalink / raw)
  To: Hunter, Jon; +Cc: tony, paul, linux-omap, linux-arm-kernel

Hi Jon,

On Tue, Aug 28, 2012 at 02:00:13, Hunter, Jon wrote:
> On 08/27/2012 05:37 AM, Mohammed, Afzal wrote:

> > And at least for initial users, they are expected to have
> > some grasp on how to calculate timings, such a user will
> > not be much worried about your 3 concerns above, anyway as
> > of now they need to have a good grasp on it.
> 
> I would consider myself to be an initial user and I am concerned,
> doesn't that count?

Yes sir, what I meant was new users who want to have runtime
calculation using the generic timing routine. For the
peripherals already making use of custom timing routine,
I am into that role too, hence the patches 8-10.

And if you have any board that makes use of existing custom
timing calculation routines (OneNAND, tusb6010 or smc91x),
can you please give this series a try.

Regards
Afzal

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

* [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
@ 2012-08-28 12:21           ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-08-28 12:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

On Tue, Aug 28, 2012 at 02:00:13, Hunter, Jon wrote:
> On 08/27/2012 05:37 AM, Mohammed, Afzal wrote:

> > And at least for initial users, they are expected to have
> > some grasp on how to calculate timings, such a user will
> > not be much worried about your 3 concerns above, anyway as
> > of now they need to have a good grasp on it.
> 
> I would consider myself to be an initial user and I am concerned,
> doesn't that count?

Yes sir, what I meant was new users who want to have runtime
calculation using the generic timing routine. For the
peripherals already making use of custom timing routine,
I am into that role too, hence the patches 8-10.

And if you have any board that makes use of existing custom
timing calculation routines (OneNAND, tusb6010 or smc91x),
can you please give this series a try.

Regards
Afzal

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

* RE: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-08-27  8:34       ` Mohammed, Afzal
@ 2012-09-03  5:34         ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-03  5:34 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

Hi Tony,

On Mon, Aug 27, 2012 at 14:04:44, Mohammed, Afzal wrote:
> On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:

> > This hangs n800 during the boot.
> 
> Shall I read the above as n800 boot without patch 10/10,
> but with the other patches in this series ?
> 
> As per the board file, n800 has tusb6010 as well as
> OneNAND in sync read & async write mode, was OneNAND
> working without 10/10.
> 
> Do you have any idea, which timing could have gone wrong,
> can you please sent me DEBUG enabled gpmc log with and
> without 10/10.

Can you please sent me GPMC DEBUG enabled logs with and
without this series.

Regards
Afzal

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-03  5:34         ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-03  5:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

On Mon, Aug 27, 2012 at 14:04:44, Mohammed, Afzal wrote:
> On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:

> > This hangs n800 during the boot.
> 
> Shall I read the above as n800 boot without patch 10/10,
> but with the other patches in this series ?
> 
> As per the board file, n800 has tusb6010 as well as
> OneNAND in sync read & async write mode, was OneNAND
> working without 10/10.
> 
> Do you have any idea, which timing could have gone wrong,
> can you please sent me DEBUG enabled gpmc log with and
> without 10/10.

Can you please sent me GPMC DEBUG enabled logs with and
without this series.

Regards
Afzal

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

* RE: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-03  5:34         ` Mohammed, Afzal
@ 2012-09-06  7:39           ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-06  7:39 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

Hi Tony,

On Mon, Sep 03, 2012 at 11:04:10, Mohammed, Afzal wrote:
> On Mon, Aug 27, 2012 at 14:04:44, Mohammed, Afzal wrote:
> > On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:

> > > This hangs n800 during the boot.

Paul reported that n800 stopped booting on OMAP baseline [1]
due to an mmc issue and has posted a solution [2].

Are you facing the same issue ?, if so, then it is not
due to this series.

I tried to get an n800, but has been unsuccessful.

Regards
Afzal

[1] http://marc.info/?l=linux-omap&m=134685988517580&w=2
[2] http://www.spinics.net/lists/arm-kernel/msg190879.html


> > 
> > Shall I read the above as n800 boot without patch 10/10,
> > but with the other patches in this series ?
> > 
> > As per the board file, n800 has tusb6010 as well as
> > OneNAND in sync read & async write mode, was OneNAND
> > working without 10/10.
> > 
> > Do you have any idea, which timing could have gone wrong,
> > can you please sent me DEBUG enabled gpmc log with and
> > without 10/10.
> 
> Can you please sent me GPMC DEBUG enabled logs with and
> without this series.


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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-06  7:39           ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-06  7:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

On Mon, Sep 03, 2012 at 11:04:10, Mohammed, Afzal wrote:
> On Mon, Aug 27, 2012 at 14:04:44, Mohammed, Afzal wrote:
> > On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:

> > > This hangs n800 during the boot.

Paul reported that n800 stopped booting on OMAP baseline [1]
due to an mmc issue and has posted a solution [2].

Are you facing the same issue ?, if so, then it is not
due to this series.

I tried to get an n800, but has been unsuccessful.

Regards
Afzal

[1] http://marc.info/?l=linux-omap&m=134685988517580&w=2
[2] http://www.spinics.net/lists/arm-kernel/msg190879.html


> > 
> > Shall I read the above as n800 boot without patch 10/10,
> > but with the other patches in this series ?
> > 
> > As per the board file, n800 has tusb6010 as well as
> > OneNAND in sync read & async write mode, was OneNAND
> > working without 10/10.
> > 
> > Do you have any idea, which timing could have gone wrong,
> > can you please sent me DEBUG enabled gpmc log with and
> > without 10/10.
> 
> Can you please sent me GPMC DEBUG enabled logs with and
> without this series.

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

* Re: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-06  7:39           ` Mohammed, Afzal
@ 2012-09-06 20:43             ` Tony Lindgren
  -1 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-09-06 20:43 UTC (permalink / raw)
  To: Mohammed, Afzal; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

* Mohammed, Afzal <afzal@ti.com> [120906 00:40]:
> Hi Tony,
> 
> On Mon, Sep 03, 2012 at 11:04:10, Mohammed, Afzal wrote:
> > On Mon, Aug 27, 2012 at 14:04:44, Mohammed, Afzal wrote:
> > > On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:
> 
> > > > This hangs n800 during the boot.
> 
> Paul reported that n800 stopped booting on OMAP baseline [1]
> due to an mmc issue and has posted a solution [2].
> 
> Are you facing the same issue ?, if so, then it is not
> due to this series.

No that's a separate issue. Your series works except for
this patch makes thing hang.

Regards,

Tony
 
> I tried to get an n800, but has been unsuccessful.
> 
> Regards
> Afzal
> 
> [1] http://marc.info/?l=linux-omap&m=134685988517580&w=2
> [2] http://www.spinics.net/lists/arm-kernel/msg190879.html
> 
> 
> > > 
> > > Shall I read the above as n800 boot without patch 10/10,
> > > but with the other patches in this series ?
> > > 
> > > As per the board file, n800 has tusb6010 as well as
> > > OneNAND in sync read & async write mode, was OneNAND
> > > working without 10/10.
> > > 
> > > Do you have any idea, which timing could have gone wrong,
> > > can you please sent me DEBUG enabled gpmc log with and
> > > without 10/10.
> > 
> > Can you please sent me GPMC DEBUG enabled logs with and
> > without this series.
> 

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-06 20:43             ` Tony Lindgren
  0 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-09-06 20:43 UTC (permalink / raw)
  To: linux-arm-kernel

* Mohammed, Afzal <afzal@ti.com> [120906 00:40]:
> Hi Tony,
> 
> On Mon, Sep 03, 2012 at 11:04:10, Mohammed, Afzal wrote:
> > On Mon, Aug 27, 2012 at 14:04:44, Mohammed, Afzal wrote:
> > > On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:
> 
> > > > This hangs n800 during the boot.
> 
> Paul reported that n800 stopped booting on OMAP baseline [1]
> due to an mmc issue and has posted a solution [2].
> 
> Are you facing the same issue ?, if so, then it is not
> due to this series.

No that's a separate issue. Your series works except for
this patch makes thing hang.

Regards,

Tony
 
> I tried to get an n800, but has been unsuccessful.
> 
> Regards
> Afzal
> 
> [1] http://marc.info/?l=linux-omap&m=134685988517580&w=2
> [2] http://www.spinics.net/lists/arm-kernel/msg190879.html
> 
> 
> > > 
> > > Shall I read the above as n800 boot without patch 10/10,
> > > but with the other patches in this series ?
> > > 
> > > As per the board file, n800 has tusb6010 as well as
> > > OneNAND in sync read & async write mode, was OneNAND
> > > working without 10/10.
> > > 
> > > Do you have any idea, which timing could have gone wrong,
> > > can you please sent me DEBUG enabled gpmc log with and
> > > without 10/10.
> > 
> > Can you please sent me GPMC DEBUG enabled logs with and
> > without this series.
> 

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

* RE: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-06  7:39           ` Mohammed, Afzal
@ 2012-09-07  0:15             ` Paul Walmsley
  -1 siblings, 0 replies; 74+ messages in thread
From: Paul Walmsley @ 2012-09-07  0:15 UTC (permalink / raw)
  To: Mohammed, Afzal
  Cc: Tony Lindgren, rnayak, linux-omap, Hunter, Jon, linux-arm-kernel

+ Rajendra

Hi

On Thu, 6 Sep 2012, Mohammed, Afzal wrote:

> I tried to get an n800, but has been unsuccessful.

We took an n800 to TII a few years ago, hopefully you can find it.  Cc'ing 
Rajendra who might know where it is.


- Paul

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-07  0:15             ` Paul Walmsley
  0 siblings, 0 replies; 74+ messages in thread
From: Paul Walmsley @ 2012-09-07  0:15 UTC (permalink / raw)
  To: linux-arm-kernel

+ Rajendra

Hi

On Thu, 6 Sep 2012, Mohammed, Afzal wrote:

> I tried to get an n800, but has been unsuccessful.

We took an n800 to TII a few years ago, hopefully you can find it.  Cc'ing 
Rajendra who might know where it is.


- Paul

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

* Re: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-06 20:43             ` Tony Lindgren
@ 2012-09-11 18:46               ` Tony Lindgren
  -1 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-09-11 18:46 UTC (permalink / raw)
  To: Mohammed, Afzal; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 805 bytes --]

* Tony Lindgren <tony@atomide.com> [120906 13:45]:
> * Mohammed, Afzal <afzal@ti.com> [120906 00:40]:
> > Hi Tony,
> > 
> > On Mon, Sep 03, 2012 at 11:04:10, Mohammed, Afzal wrote:
> > > On Mon, Aug 27, 2012 at 14:04:44, Mohammed, Afzal wrote:
> > > > On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:
> > 
> > > > > This hangs n800 during the boot.
> > 
> > Paul reported that n800 stopped booting on OMAP baseline [1]
> > due to an mmc issue and has posted a solution [2].
> > 
> > Are you facing the same issue ?, if so, then it is not
> > due to this series.
> 
> No that's a separate issue. Your series works except for
> this patch makes thing hang.

Here are the timing changes with and without this patch from
my n800. You can just diff the two files to see some differences.

Regards,

Tony

[-- Attachment #2: n800-fails.txt --]
[-- Type: text/plain, Size: 5473 bytes --]

GPMC CS1: cs_on     :   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS1: cs_rd_off :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: cs_wr_off :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: adv_on    :   6 ticks,  54 ns (was   0 ticks)  54 ns
GPMC CS1: adv_rd_off:   7 ticks,  63 ns (was   3 ticks)  63 ns
GPMC CS1: adv_wr_off:   7 ticks,  63 ns (was   3 ticks)  63 ns
GPMC CS1: oe_on     :   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS1: oe_off    :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: we_on     :   8 ticks,  72 ns (was   4 ticks)  72 ns
GPMC CS1: we_off    :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: rd_cycle  :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: wr_cycle  :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: access    :   7 ticks,  63 ns (was   5 ticks)  63 ns
GPMC CS1: page_burst_access:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: clk_activation:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: cs_on     :   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS4: cs_rd_off :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: cs_wr_off :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: adv_on    :   6 ticks,  54 ns (was   2 ticks)  54 ns
GPMC CS4: adv_rd_off:   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS4: adv_wr_off:   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS4: oe_on     :  10 ticks,  91 ns (was   5 ticks)  91 ns
GPMC CS4: oe_off    :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: we_on     :  10 ticks,  91 ns (was   5 ticks)  91 ns
GPMC CS4: we_off    :  16 ticks, 145 ns (was   6 ticks) 145 ns
GPMC CS4: rd_cycle  :  17 ticks, 154 ns (was   8 ticks) 154 ns
GPMC CS4: wr_cycle  :  17 ticks, 154 ns (was   8 ticks) 154 ns
GPMC CS4: access    :  15 ticks, 136 ns (was   6 ticks) 136 ns
GPMC CS4: page_burst_access:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS4: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: clk_activation:   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS4 CLK period is 18 ns (div 2)
TUSB 6010
...
OneNAND driver initializing
GPMC CS0: cs_on     :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_rd_off :  10 ticks,  91 ns (was  12 ticks)  91 ns
GPMC CS0: cs_wr_off :  12 ticks, 109 ns (was   9 ticks) 109 ns
GPMC CS0: adv_on    :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: adv_rd_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: adv_wr_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: oe_on     :   3 ticks,  27 ns (was   2 ticks)  27 ns
GPMC CS0: oe_off    :  10 ticks,  91 ns (was  12 ticks)  91 ns
GPMC CS0: we_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: we_off    :   8 ticks,  72 ns (was   8 ticks)  72 ns
GPMC CS0: rd_cycle  :  13 ticks, 118 ns (was  13 ticks) 118 ns
GPMC CS0: wr_cycle  :  15 ticks, 136 ns (was  10 ticks) 136 ns
GPMC CS0: access    :   9 ticks,  82 ns (was  11 ticks)  82 ns
GPMC CS0: page_burst_access:   0 ticks,   0 ns (was   2 ticks)   0 ns
GPMC CS0: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: clk_activation:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_on     :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_rd_off :  14 ticks, 127 ns (was  10 ticks) 127 ns
GPMC CS0: cs_wr_off :  12 ticks, 109 ns (was  12 ticks) 109 ns
GPMC CS0: adv_on    :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: adv_rd_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: adv_wr_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: oe_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: oe_off    :  14 ticks, 127 ns (was  10 ticks) 127 ns
GPMC CS0: we_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: we_off    :   8 ticks,  72 ns (was   8 ticks)  72 ns
GPMC CS0: rd_cycle  :  16 ticks, 145 ns (was  13 ticks) 145 ns
GPMC CS0: wr_cycle  :  15 ticks, 136 ns (was  15 ticks) 136 ns
GPMC CS0: access    :  13 ticks, 118 ns (was   9 ticks) 118 ns
GPMC CS0: page_burst_access:   3 ticks,  27 ns (was   0 ticks)  27 ns
GPMC CS0: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: clk_activation:   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS0 CLK period is 27 ns (div 3)
omap2-onenand omap2-onenand: initializing on CS0, phys base 0x04000000, virtual base c88c0000, freq 54 MHz
OneNAND Manufacturer: Samsung (0xec)
Muxed OneNAND(DDP) 256MB 1.8V 16-bit (0x48)
OneNAND version = 0x0011
Chip support all block unlock
onenand_wait: controller error! state 15 ctrl 0x0400 intr 0x8000
Scanning device for bad blocks
Creating 5 MTD partitions on "omap2-onenand":
0x000000000000-0x000000020000 : "bootloader"
0x000000020000-0x000000080000 : "config"
0x000000080000-0x000000280000 : "kernel"
0x000000280000-0x000000680000 : "initfs"
0x000000680000-0x000010000000 : "rootfs"
omap-dma-engine omap-dma-engine: allocating channel for 44
omap-dma-engine omap-dma-engine: allocating channel for 43


[-- Attachment #3: n800-works.txt --]
[-- Type: text/plain, Size: 5473 bytes --]

GPMC CS1: cs_on     :   1 ticks,   9 ns (was   0 ticks)   8 ns
GPMC CS1: cs_rd_off :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: cs_wr_off :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: adv_on    :   6 ticks,  54 ns (was   0 ticks)  48 ns
GPMC CS1: adv_rd_off:   7 ticks,  63 ns (was   3 ticks)  63 ns
GPMC CS1: adv_wr_off:   7 ticks,  63 ns (was   3 ticks)  63 ns
GPMC CS1: oe_on     :   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS1: oe_off    :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: we_on     :   8 ticks,  72 ns (was   4 ticks)  72 ns
GPMC CS1: we_off    :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: rd_cycle  :  10 ticks,  91 ns (was   5 ticks)  91 ns
GPMC CS1: wr_cycle  :  10 ticks,  91 ns (was   5 ticks)  91 ns
GPMC CS1: access    :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: page_burst_access:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: clk_activation:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: cs_on     :   1 ticks,   9 ns (was   0 ticks)   8 ns
GPMC CS4: cs_rd_off :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: cs_wr_off :  16 ticks, 145 ns (was   7 ticks) 144 ns
GPMC CS4: adv_on    :   6 ticks,  54 ns (was   2 ticks)  48 ns
GPMC CS4: adv_rd_off:   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS4: adv_wr_off:   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS4: oe_on     :  10 ticks,  91 ns (was   5 ticks)  90 ns
GPMC CS4: oe_off    :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: we_on     :  10 ticks,  91 ns (was   5 ticks)  90 ns
GPMC CS4: we_off    :  16 ticks, 145 ns (was   6 ticks) 144 ns
GPMC CS4: rd_cycle  :  17 ticks, 154 ns (was   8 ticks) 154 ns
GPMC CS4: wr_cycle  :  17 ticks, 154 ns (was   8 ticks) 154 ns
GPMC CS4: access    :  15 ticks, 136 ns (was   6 ticks) 135 ns
GPMC CS4: page_burst_access:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS4: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: clk_activation:   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS4 CLK period is 18 ns (div 2)
TUSB 6010
...

OneNAND driver initializing
GPMC CS0: cs_on     :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_rd_off :  10 ticks,  91 ns (was  12 ticks)  91 ns
GPMC CS0: cs_wr_off :  12 ticks, 109 ns (was   9 ticks) 108 ns
GPMC CS0: adv_on    :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: adv_rd_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: adv_wr_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: oe_on     :   3 ticks,  27 ns (was   2 ticks)  27 ns
GPMC CS0: oe_off    :  10 ticks,  91 ns (was  12 ticks)  91 ns
GPMC CS0: we_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: we_off    :   8 ticks,  72 ns (was   8 ticks)  72 ns
GPMC CS0: rd_cycle  :  13 ticks, 118 ns (was  13 ticks) 118 ns
GPMC CS0: wr_cycle  :  15 ticks, 136 ns (was  10 ticks) 135 ns
GPMC CS0: access    :   9 ticks,  82 ns (was  11 ticks)  82 ns
GPMC CS0: page_burst_access:   0 ticks,   0 ns (was   2 ticks)   0 ns
GPMC CS0: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: clk_activation:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_on     :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_rd_off :  14 ticks, 127 ns (was  10 ticks) 127 ns
GPMC CS0: cs_wr_off :  12 ticks, 109 ns (was  12 ticks) 108 ns
GPMC CS0: adv_on    :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: adv_rd_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: adv_wr_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: oe_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: oe_off    :  14 ticks, 127 ns (was  10 ticks) 127 ns
GPMC CS0: we_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: we_off    :   8 ticks,  72 ns (was   8 ticks)  72 ns
GPMC CS0: rd_cycle  :  16 ticks, 145 ns (was  13 ticks) 145 ns
GPMC CS0: wr_cycle  :  15 ticks, 136 ns (was  15 ticks) 135 ns
GPMC CS0: access    :  13 ticks, 118 ns (was   9 ticks) 118 ns
GPMC CS0: page_burst_access:   3 ticks,  27 ns (was   0 ticks)  27 ns
GPMC CS0: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: clk_activation:   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS0 CLK period is 27 ns (div 3)
omap2-onenand omap2-onenand: initializing on CS0, phys base 0x04000000, virtual base c88c0000, freq 54 MHz
OneNAND Manufacturer: Samsung (0xec)
Muxed OneNAND(DDP) 256MB 1.8V 16-bit (0x48)
OneNAND version = 0x0011
Chip support all block unlock
onenand_wait: controller error! state 15 ctrl 0x0400 intr 0x8000
Scanning device for bad blocks
Creating 5 MTD partitions on "omap2-onenand":
0x000000000000-0x000000020000 : "bootloader"
0x000000020000-0x000000080000 : "config"
0x000000080000-0x000000280000 : "kernel"
0x000000280000-0x000000680000 : "initfs"
0x000000680000-0x000010000000 : "rootfs"
omap-dma-engine omap-dma-engine: allocating channel for 44
omap-dma-engine omap-dma-engine: allocating channel for 43

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-11 18:46               ` Tony Lindgren
  0 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-09-11 18:46 UTC (permalink / raw)
  To: linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [120906 13:45]:
> * Mohammed, Afzal <afzal@ti.com> [120906 00:40]:
> > Hi Tony,
> > 
> > On Mon, Sep 03, 2012 at 11:04:10, Mohammed, Afzal wrote:
> > > On Mon, Aug 27, 2012 at 14:04:44, Mohammed, Afzal wrote:
> > > > On Sat, Aug 25, 2012 at 01:16:30, Tony Lindgren wrote:
> > 
> > > > > This hangs n800 during the boot.
> > 
> > Paul reported that n800 stopped booting on OMAP baseline [1]
> > due to an mmc issue and has posted a solution [2].
> > 
> > Are you facing the same issue ?, if so, then it is not
> > due to this series.
> 
> No that's a separate issue. Your series works except for
> this patch makes thing hang.

Here are the timing changes with and without this patch from
my n800. You can just diff the two files to see some differences.

Regards,

Tony
-------------- next part --------------
GPMC CS1: cs_on     :   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS1: cs_rd_off :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: cs_wr_off :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: adv_on    :   6 ticks,  54 ns (was   0 ticks)  54 ns
GPMC CS1: adv_rd_off:   7 ticks,  63 ns (was   3 ticks)  63 ns
GPMC CS1: adv_wr_off:   7 ticks,  63 ns (was   3 ticks)  63 ns
GPMC CS1: oe_on     :   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS1: oe_off    :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: we_on     :   8 ticks,  72 ns (was   4 ticks)  72 ns
GPMC CS1: we_off    :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: rd_cycle  :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: wr_cycle  :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: access    :   7 ticks,  63 ns (was   5 ticks)  63 ns
GPMC CS1: page_burst_access:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: clk_activation:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: cs_on     :   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS4: cs_rd_off :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: cs_wr_off :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: adv_on    :   6 ticks,  54 ns (was   2 ticks)  54 ns
GPMC CS4: adv_rd_off:   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS4: adv_wr_off:   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS4: oe_on     :  10 ticks,  91 ns (was   5 ticks)  91 ns
GPMC CS4: oe_off    :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: we_on     :  10 ticks,  91 ns (was   5 ticks)  91 ns
GPMC CS4: we_off    :  16 ticks, 145 ns (was   6 ticks) 145 ns
GPMC CS4: rd_cycle  :  17 ticks, 154 ns (was   8 ticks) 154 ns
GPMC CS4: wr_cycle  :  17 ticks, 154 ns (was   8 ticks) 154 ns
GPMC CS4: access    :  15 ticks, 136 ns (was   6 ticks) 136 ns
GPMC CS4: page_burst_access:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS4: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: clk_activation:   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS4 CLK period is 18 ns (div 2)
TUSB 6010
...
OneNAND driver initializing
GPMC CS0: cs_on     :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_rd_off :  10 ticks,  91 ns (was  12 ticks)  91 ns
GPMC CS0: cs_wr_off :  12 ticks, 109 ns (was   9 ticks) 109 ns
GPMC CS0: adv_on    :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: adv_rd_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: adv_wr_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: oe_on     :   3 ticks,  27 ns (was   2 ticks)  27 ns
GPMC CS0: oe_off    :  10 ticks,  91 ns (was  12 ticks)  91 ns
GPMC CS0: we_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: we_off    :   8 ticks,  72 ns (was   8 ticks)  72 ns
GPMC CS0: rd_cycle  :  13 ticks, 118 ns (was  13 ticks) 118 ns
GPMC CS0: wr_cycle  :  15 ticks, 136 ns (was  10 ticks) 136 ns
GPMC CS0: access    :   9 ticks,  82 ns (was  11 ticks)  82 ns
GPMC CS0: page_burst_access:   0 ticks,   0 ns (was   2 ticks)   0 ns
GPMC CS0: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: clk_activation:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_on     :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_rd_off :  14 ticks, 127 ns (was  10 ticks) 127 ns
GPMC CS0: cs_wr_off :  12 ticks, 109 ns (was  12 ticks) 109 ns
GPMC CS0: adv_on    :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: adv_rd_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: adv_wr_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: oe_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: oe_off    :  14 ticks, 127 ns (was  10 ticks) 127 ns
GPMC CS0: we_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: we_off    :   8 ticks,  72 ns (was   8 ticks)  72 ns
GPMC CS0: rd_cycle  :  16 ticks, 145 ns (was  13 ticks) 145 ns
GPMC CS0: wr_cycle  :  15 ticks, 136 ns (was  15 ticks) 136 ns
GPMC CS0: access    :  13 ticks, 118 ns (was   9 ticks) 118 ns
GPMC CS0: page_burst_access:   3 ticks,  27 ns (was   0 ticks)  27 ns
GPMC CS0: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: clk_activation:   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS0 CLK period is 27 ns (div 3)
omap2-onenand omap2-onenand: initializing on CS0, phys base 0x04000000, virtual base c88c0000, freq 54 MHz
OneNAND Manufacturer: Samsung (0xec)
Muxed OneNAND(DDP) 256MB 1.8V 16-bit (0x48)
OneNAND version = 0x0011
Chip support all block unlock
onenand_wait: controller error! state 15 ctrl 0x0400 intr 0x8000
Scanning device for bad blocks
Creating 5 MTD partitions on "omap2-onenand":
0x000000000000-0x000000020000 : "bootloader"
0x000000020000-0x000000080000 : "config"
0x000000080000-0x000000280000 : "kernel"
0x000000280000-0x000000680000 : "initfs"
0x000000680000-0x000010000000 : "rootfs"
omap-dma-engine omap-dma-engine: allocating channel for 44
omap-dma-engine omap-dma-engine: allocating channel for 43

-------------- next part --------------
GPMC CS1: cs_on     :   1 ticks,   9 ns (was   0 ticks)   8 ns
GPMC CS1: cs_rd_off :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: cs_wr_off :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: adv_on    :   6 ticks,  54 ns (was   0 ticks)  48 ns
GPMC CS1: adv_rd_off:   7 ticks,  63 ns (was   3 ticks)  63 ns
GPMC CS1: adv_wr_off:   7 ticks,  63 ns (was   3 ticks)  63 ns
GPMC CS1: oe_on     :   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS1: oe_off    :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: we_on     :   8 ticks,  72 ns (was   4 ticks)  72 ns
GPMC CS1: we_off    :   9 ticks,  82 ns (was   5 ticks)  82 ns
GPMC CS1: rd_cycle  :  10 ticks,  91 ns (was   5 ticks)  91 ns
GPMC CS1: wr_cycle  :  10 ticks,  91 ns (was   5 ticks)  91 ns
GPMC CS1: access    :   8 ticks,  72 ns (was   5 ticks)  72 ns
GPMC CS1: page_burst_access:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS1: clk_activation:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: cs_on     :   1 ticks,   9 ns (was   0 ticks)   8 ns
GPMC CS4: cs_rd_off :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: cs_wr_off :  16 ticks, 145 ns (was   7 ticks) 144 ns
GPMC CS4: adv_on    :   6 ticks,  54 ns (was   2 ticks)  48 ns
GPMC CS4: adv_rd_off:   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS4: adv_wr_off:   7 ticks,  63 ns (was   4 ticks)  63 ns
GPMC CS4: oe_on     :  10 ticks,  91 ns (was   5 ticks)  90 ns
GPMC CS4: oe_off    :  16 ticks, 145 ns (was   7 ticks) 145 ns
GPMC CS4: we_on     :  10 ticks,  91 ns (was   5 ticks)  90 ns
GPMC CS4: we_off    :  16 ticks, 145 ns (was   6 ticks) 144 ns
GPMC CS4: rd_cycle  :  17 ticks, 154 ns (was   8 ticks) 154 ns
GPMC CS4: wr_cycle  :  17 ticks, 154 ns (was   8 ticks) 154 ns
GPMC CS4: access    :  15 ticks, 136 ns (was   6 ticks) 135 ns
GPMC CS4: page_burst_access:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS4: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS4: clk_activation:   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS4 CLK period is 18 ns (div 2)
TUSB 6010
...

OneNAND driver initializing
GPMC CS0: cs_on     :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_rd_off :  10 ticks,  91 ns (was  12 ticks)  91 ns
GPMC CS0: cs_wr_off :  12 ticks, 109 ns (was   9 ticks) 108 ns
GPMC CS0: adv_on    :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: adv_rd_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: adv_wr_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: oe_on     :   3 ticks,  27 ns (was   2 ticks)  27 ns
GPMC CS0: oe_off    :  10 ticks,  91 ns (was  12 ticks)  91 ns
GPMC CS0: we_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: we_off    :   8 ticks,  72 ns (was   8 ticks)  72 ns
GPMC CS0: rd_cycle  :  13 ticks, 118 ns (was  13 ticks) 118 ns
GPMC CS0: wr_cycle  :  15 ticks, 136 ns (was  10 ticks) 135 ns
GPMC CS0: access    :   9 ticks,  82 ns (was  11 ticks)  82 ns
GPMC CS0: page_burst_access:   0 ticks,   0 ns (was   2 ticks)   0 ns
GPMC CS0: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: clk_activation:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_on     :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cs_rd_off :  14 ticks, 127 ns (was  10 ticks) 127 ns
GPMC CS0: cs_wr_off :  12 ticks, 109 ns (was  12 ticks) 108 ns
GPMC CS0: adv_on    :   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: adv_rd_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: adv_wr_off:   2 ticks,  18 ns (was   2 ticks)  18 ns
GPMC CS0: oe_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: oe_off    :  14 ticks, 127 ns (was  10 ticks) 127 ns
GPMC CS0: we_on     :   3 ticks,  27 ns (was   3 ticks)  27 ns
GPMC CS0: we_off    :   8 ticks,  72 ns (was   8 ticks)  72 ns
GPMC CS0: rd_cycle  :  16 ticks, 145 ns (was  13 ticks) 145 ns
GPMC CS0: wr_cycle  :  15 ticks, 136 ns (was  15 ticks) 135 ns
GPMC CS0: access    :  13 ticks, 118 ns (was   9 ticks) 118 ns
GPMC CS0: page_burst_access:   3 ticks,  27 ns (was   0 ticks)  27 ns
GPMC CS0: bus_turnaround:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: cycle2cycle_delay:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: wait_monitoring:   0 ticks,   0 ns (was   0 ticks)   0 ns
GPMC CS0: clk_activation:   1 ticks,   9 ns (was   0 ticks)   9 ns
GPMC CS0 CLK period is 27 ns (div 3)
omap2-onenand omap2-onenand: initializing on CS0, phys base 0x04000000, virtual base c88c0000, freq 54 MHz
OneNAND Manufacturer: Samsung (0xec)
Muxed OneNAND(DDP) 256MB 1.8V 16-bit (0x48)
OneNAND version = 0x0011
Chip support all block unlock
onenand_wait: controller error! state 15 ctrl 0x0400 intr 0x8000
Scanning device for bad blocks
Creating 5 MTD partitions on "omap2-onenand":
0x000000000000-0x000000020000 : "bootloader"
0x000000020000-0x000000080000 : "config"
0x000000080000-0x000000280000 : "kernel"
0x000000280000-0x000000680000 : "initfs"
0x000000680000-0x000010000000 : "rootfs"
omap-dma-engine omap-dma-engine: allocating channel for 44
omap-dma-engine omap-dma-engine: allocating channel for 43

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

* RE: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-11 18:46               ` Tony Lindgren
@ 2012-09-12  9:50                 ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-12  9:50 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

Hi Tony,

On Wed, Sep 12, 2012 at 00:16:06, Tony Lindgren wrote:

> Here are the timing changes with and without this patch from
> my n800. You can just diff the two files to see some differences.

Hmm.. that was pretty close, OneNAND async,sync as well as
tusb sync values were same.

But some of the tusb async values is less by one. I need
to get it right.

And thanks for sending me the easily diff-able logs.

Regards
Afzal

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-12  9:50                 ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-12  9:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

On Wed, Sep 12, 2012 at 00:16:06, Tony Lindgren wrote:

> Here are the timing changes with and without this patch from
> my n800. You can just diff the two files to see some differences.

Hmm.. that was pretty close, OneNAND async,sync as well as
tusb sync values were same.

But some of the tusb async values is less by one. I need
to get it right.

And thanks for sending me the easily diff-able logs.

Regards
Afzal

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

* RE: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-12  9:50                 ` Mohammed, Afzal
@ 2012-09-14 10:20                   ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-14 10:20 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 596 bytes --]

* Mohammed, Afzal: Wednesday, September 12, 2012 3:20 PM

> But some of the tusb async values is less by one. I need
> to get it right.

Reason has been identified. It was due to rounding error,
no changes are required in the expressions. Moving
completely to picoseconds resolves the issue.

Can you please try with the attached patch ?

Once it is confirmed that issue is resolved, I will cleanup
gpmc-nand.c too (which would also take care of picoseconds)

Note: As this mail is sent via exchange, I am attaching the
patch so that it reaches you in proper way.

Regards
Afzal

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-gpmc-rounding-error-fix.patch --]
[-- Type: text/x-patch; name="0001-gpmc-rounding-error-fix.patch", Size: 14228 bytes --]

From 101b3d4c558bae420cbeba634f4deeae27c3b905 Mon Sep 17 00:00:00 2001
From: Afzal Mohammed <afzal@ti.com>
Date: Wed, 12 Sep 2012 19:30:27 +0530
Subject: [PATCH] gpmc: rounding error fix

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc.c             |  150 +++++++++++++++-----------------
 arch/arm/plat-omap/include/plat/gpmc.h |   40 ++++----
 2 files changed, 90 insertions(+), 100 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index d8e5b08..e9d57db 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -289,11 +289,11 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 	if (time == 0)
 		ticks = 0;
 	else
-		ticks = gpmc_ns_to_ticks(time);
+		ticks = gpmc_ps_to_ticks(time);
 	nr_bits = end_bit - st_bit + 1;
 	if (ticks >= 1 << nr_bits) {
 #ifdef DEBUG
-		printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
+		pr_info("GPMC CS%d: %-10s* %3d ps, %3d ticks >= %d\n",
 				cs, name, time, ticks, 1 << nr_bits);
 #endif
 		return -1;
@@ -302,10 +302,9 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 	mask = (1 << nr_bits) - 1;
 	l = gpmc_cs_read_reg(cs, reg);
 #ifdef DEBUG
-	printk(KERN_INFO
-		"GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
-	       cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
-			(l >> st_bit) & mask, time);
+	pr_info("GPMC CS%d: %-10s: %3d ticks, %3lu ps (was %3i ticks) %3d ps\n",
+		cs, name, ticks, gpmc_get_fclk_period() * ticks,
+		(l >> st_bit) & mask, time);
 #endif
 	l &= ~(mask << st_bit);
 	l |= ticks << st_bit;
@@ -385,8 +384,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
 	if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
 #ifdef DEBUG
-		printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
-				cs, (div * gpmc_get_fclk_period()) / 1000, div);
+		pr_info("GPMC CS%d CLK period is %lu ps (div %d)\n",
+				cs, div * gpmc_get_fclk_period(), div);
 #endif
 		l &= ~0x03;
 		l |= (div - 1);
@@ -922,46 +921,42 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
 		 * indirectly necessitates requirement of t_avdp_r & t_avdp_w
 		 * instead of having a single t_avdp
 		 */
-		temp = max_t(u32, temp,	gpmc_t->clk_activation * 1000 +
-							dev_t->t_avdh);
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
 	}
-	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
 
 	/* oe_on */
 	temp = dev_t->t_oeasu; /* remove this ? */
 	if (mux) {
-		temp = max_t(u32, temp,
-			gpmc_t->clk_activation * 1000 + dev_t->t_ach);
-		temp = max_t(u32, temp, (gpmc_t->adv_rd_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_oe)) * 1000);
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_ach);
+		temp = max_t(u32, temp, gpmc_t->adv_rd_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe));
 	}
-	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
 
 	/* access */
 	/* any scope for improvement ?, by combining oe_on & clk_activation,
 	 * need to check whether access = clk_activation + round to sync clk ?
 	 */
 	temp = max_t(u32, dev_t->t_iaa,	dev_t->cyc_iaa * gpmc_t->sync_clk);
-	temp += gpmc_t->clk_activation * 1000;
+	temp += gpmc_t->clk_activation;
 	if (dev_t->cyc_oe)
-		temp = max_t(u32, temp, (gpmc_t->oe_on +
-				gpmc_ticks_to_ns(dev_t->cyc_oe)) * 1000);
-	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, temp, gpmc_t->oe_on +
+				gpmc_ticks_to_ps(dev_t->cyc_oe));
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
 	gpmc_t->cs_rd_off = gpmc_t->oe_off;
 
 	/* rd_cycle */
 	temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
 	temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
-							gpmc_t->access * 1000;
+							gpmc_t->access;
 	/* barter t_ce_rdyz with t_cez_r ? */
 	if (dev_t->t_ce_rdyz)
-		temp = max_t(u32, temp,
-				gpmc_t->cs_rd_off * 1000 + dev_t->t_ce_rdyz);
-	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, temp,	gpmc_t->cs_rd_off + dev_t->t_ce_rdyz);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -976,29 +971,28 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
 	temp = dev_t->t_avdp_w;
 	if (mux) {
 		temp = max_t(u32, temp,
-			gpmc_t->clk_activation * 1000 + dev_t->t_avdh);
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+			gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
 	}
-	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
 
 	/* wr_data_mux_bus */
 	temp = max_t(u32, dev_t->t_weasu,
-			gpmc_t->clk_activation * 1000 + dev_t->t_rdyo);
+			gpmc_t->clk_activation + dev_t->t_rdyo);
 	/* shouldn't mux be kept as a whole for wr_data_mux_bus ?,
 	 * and in that case remember to handle we_on properly
 	 */
 	if (mux) {
 		temp = max_t(u32, temp,
-			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
-		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+			gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
 	}
-	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
 
 	/* we_on */
 	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
-		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
 	else
 		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
 
@@ -1007,24 +1001,24 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
 	gpmc_t->wr_access = gpmc_t->access;
 
 	/* we_off */
-	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
+	temp = gpmc_t->we_on + dev_t->t_wpl;
 	temp = max_t(u32, temp,
-			(gpmc_t->wr_access + gpmc_ticks_to_ns(1)) * 1000);
+			gpmc_t->wr_access + gpmc_ticks_to_ps(1));
 	temp = max_t(u32, temp,
-		(gpmc_t->we_on + gpmc_ticks_to_ns(dev_t->cyc_wpl)) * 1000);
-	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl));
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off * 1000 +
-							dev_t->t_wph) / 1000;
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
 
 	/* wr_cycle */
 	temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
-	temp += gpmc_t->wr_access * 1000;
+	temp += gpmc_t->wr_access;
 	/* barter t_ce_rdyz with t_cez_w ? */
 	if (dev_t->t_ce_rdyz)
 		temp = max_t(u32, temp,
-				 gpmc_t->cs_wr_off * 1000 + dev_t->t_ce_rdyz);
-	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+				 gpmc_t->cs_wr_off + dev_t->t_ce_rdyz);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1038,35 +1032,33 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
 	/* adv_rd_off */
 	temp = dev_t->t_avdp_r;
 	if (mux)
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
-	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
 
 	/* oe_on */
 	temp = dev_t->t_oeasu;
 	if (mux)
 		temp = max_t(u32, temp,
-			gpmc_t->adv_rd_off * 1000 + dev_t->t_aavdh);
-	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+			gpmc_t->adv_rd_off + dev_t->t_aavdh);
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
 
 	/* access */
 	temp = max_t(u32, dev_t->t_iaa, /* remove t_iaa in async ? */
-				gpmc_t->oe_on * 1000 + dev_t->t_oe);
+				gpmc_t->oe_on + dev_t->t_oe);
 	temp = max_t(u32, temp,
-				gpmc_t->cs_on * 1000 + dev_t->t_ce);
+				gpmc_t->cs_on + dev_t->t_ce);
 	temp = max_t(u32, temp,
-				gpmc_t->adv_on * 1000 + dev_t->t_aa);
-	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+				gpmc_t->adv_on + dev_t->t_aa);
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
 	gpmc_t->cs_rd_off = gpmc_t->oe_off;
 
 	/* rd_cycle */
 	temp = max_t(u32, dev_t->t_rd_cycle,
-			gpmc_t->cs_rd_off * 1000 + dev_t->t_cez_r);
-	temp = max_t(u32, temp,
-			gpmc_t->oe_off * 1000 + dev_t->t_oez);
-	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+			gpmc_t->cs_rd_off + dev_t->t_cez_r);
+	temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1080,37 +1072,35 @@ static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
 	/* adv_wr_off */
 	temp = dev_t->t_avdp_w;
 	if (mux)
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
-	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
 
 	/* wr_data_mux_bus */
 	temp = dev_t->t_weasu;
 	if (mux) {
-		temp = max_t(u32, temp,
-			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
-		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+		temp = max_t(u32, temp,	gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
 	}
-	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
 
 	/* we_on */
 	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
-		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
 	else
 		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
 
 	/* we_off */
-	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
-	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	temp = gpmc_t->we_on + dev_t->t_wpl;
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks((gpmc_t->we_off * 1000 +
-				dev_t->t_wph)) / 1000;
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
 
 	/* wr_cycle */
 	temp = max_t(u32, dev_t->t_wr_cycle,
-				gpmc_t->cs_wr_off * 1000 + dev_t->t_cez_w);
-	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+				gpmc_t->cs_wr_off + dev_t->t_cez_w);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1125,10 +1115,10 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
 
 	gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
 					dev_t->t_bacc,
-					gpmc_t->sync_clk) / 1000;
+					gpmc_t->sync_clk);
 
 	temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
-	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
 
 	if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
 		return 0;
@@ -1151,14 +1141,14 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
 	u32 temp;
 
 	/* cs_on */
-	gpmc_t->cs_on = gpmc_round_ns_to_ticks(dev_t->t_ceasu / 1000);
+	gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
 
 	/* adv_on */
 	temp = dev_t->t_avdasu;
 	if (dev_t->t_ce_avd)
 		temp = max_t(u32, temp,
-				gpmc_t->cs_on * 1000 + dev_t->t_ce_avd);
-	gpmc_t->adv_on = gpmc_round_ns_to_ticks(temp / 1000);
+				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)
 		gpmc_calc_sync_common_timings(gpmc_t, dev_t);
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index e59a932..f1d1d2e 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -116,38 +116,38 @@ struct gpmc_timings {
 	u32 sync_clk;
 
 	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
-	u16 cs_on;		/* Assertion time */
-	u16 cs_rd_off;		/* Read deassertion time */
-	u16 cs_wr_off;		/* Write deassertion time */
+	u32 cs_on;		/* Assertion time */
+	u32 cs_rd_off;		/* Read deassertion time */
+	u32 cs_wr_off;		/* Write deassertion time */
 
 	/* ADV signal timings corresponding to GPMC_CONFIG3 */
-	u16 adv_on;		/* Assertion time */
-	u16 adv_rd_off;		/* Read deassertion time */
-	u16 adv_wr_off;		/* Write deassertion time */
+	u32 adv_on;		/* Assertion time */
+	u32 adv_rd_off;		/* Read deassertion time */
+	u32 adv_wr_off;		/* Write deassertion time */
 
 	/* WE signals timings corresponding to GPMC_CONFIG4 */
-	u16 we_on;		/* WE assertion time */
-	u16 we_off;		/* WE deassertion time */
+	u32 we_on;		/* WE assertion time */
+	u32 we_off;		/* WE deassertion time */
 
 	/* OE signals timings corresponding to GPMC_CONFIG4 */
-	u16 oe_on;		/* OE assertion time */
-	u16 oe_off;		/* OE deassertion time */
+	u32 oe_on;		/* OE assertion time */
+	u32 oe_off;		/* OE deassertion time */
 
 	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
-	u16 page_burst_access;	/* Multiple access word delay */
-	u16 access;		/* Start-cycle to first data valid delay */
-	u16 rd_cycle;		/* Total read cycle time */
-	u16 wr_cycle;		/* Total write cycle time */
+	u32 page_burst_access;	/* Multiple access word delay */
+	u32 access;		/* Start-cycle to first data valid delay */
+	u32 rd_cycle;		/* Total read cycle time */
+	u32 wr_cycle;		/* Total write cycle time */
 
-	u16 bus_turnaround;
-	u16 cycle2cycle_delay;
+	u32 bus_turnaround;
+	u32 cycle2cycle_delay;
 
-	u16 wait_monitoring;
-	u16 clk_activation;
+	u32 wait_monitoring;
+	u32 clk_activation;
 
 	/* The following are only on OMAP3430 */
-	u16 wr_access;		/* WRACCESSTIME */
-	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+	u32 wr_access;		/* WRACCESSTIME */
+	u32 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
 
 	struct gpmc_bool_timings bool_timings;
 };
-- 
1.7.0.4


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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-14 10:20                   ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-14 10:20 UTC (permalink / raw)
  To: linux-arm-kernel

* Mohammed, Afzal: Wednesday, September 12, 2012 3:20 PM

> But some of the tusb async values is less by one. I need
> to get it right.

Reason has been identified. It was due to rounding error,
no changes are required in the expressions. Moving
completely to picoseconds resolves the issue.

Can you please try with the attached patch ?

Once it is confirmed that issue is resolved, I will cleanup
gpmc-nand.c too (which would also take care of picoseconds)

Note: As this mail is sent via exchange, I am attaching the
patch so that it reaches you in proper way.

Regards
Afzal
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-gpmc-rounding-error-fix.patch
Type: text/x-patch
Size: 14228 bytes
Desc: 0001-gpmc-rounding-error-fix.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120914/5b0b4601/attachment.bin>

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

* RE: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-14 10:20                   ` Mohammed, Afzal
@ 2012-09-17  8:39                     ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-17  8:39 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

Hi Tony,

On Fri, Sep 14, 2012 at 15:50:02, Mohammed, Afzal wrote:
> * Mohammed, Afzal: Wednesday, September 12, 2012 3:20 PM

> > But some of the tusb async values is less by one. I need
> > to get it right.
> 
> Reason has been identified. It was due to rounding error,
> no changes are required in the expressions. Moving
> completely to picoseconds resolves the issue.
> 
> Can you please try with the attached patch ?

Can you please try with patch attached in previous message
of this thread and check whether it makes n800 gpmc
peripherals work properly

Changes as in above mentioned patch has been pasted below again.

Regards
Afzal

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


diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index d8e5b08..e9d57db 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -289,11 +289,11 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 	if (time == 0)
 		ticks = 0;
 	else
-		ticks = gpmc_ns_to_ticks(time);
+		ticks = gpmc_ps_to_ticks(time);
 	nr_bits = end_bit - st_bit + 1;
 	if (ticks >= 1 << nr_bits) {
 #ifdef DEBUG
-		printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
+		pr_info("GPMC CS%d: %-10s* %3d ps, %3d ticks >= %d\n",
 				cs, name, time, ticks, 1 << nr_bits);
 #endif
 		return -1;
@@ -302,10 +302,9 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 	mask = (1 << nr_bits) - 1;
 	l = gpmc_cs_read_reg(cs, reg);
 #ifdef DEBUG
-	printk(KERN_INFO
-		"GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
-	       cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
-			(l >> st_bit) & mask, time);
+	pr_info("GPMC CS%d: %-10s: %3d ticks, %3lu ps (was %3i ticks) %3d ps\n",
+		cs, name, ticks, gpmc_get_fclk_period() * ticks,
+		(l >> st_bit) & mask, time);
 #endif
 	l &= ~(mask << st_bit);
 	l |= ticks << st_bit;
@@ -385,8 +384,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
 	if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
 #ifdef DEBUG
-		printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
-				cs, (div * gpmc_get_fclk_period()) / 1000, div);
+		pr_info("GPMC CS%d CLK period is %lu ps (div %d)\n",
+				cs, div * gpmc_get_fclk_period(), div);
 #endif
 		l &= ~0x03;
 		l |= (div - 1);
@@ -922,46 +921,42 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
 		 * indirectly necessitates requirement of t_avdp_r & t_avdp_w
 		 * instead of having a single t_avdp
 		 */
-		temp = max_t(u32, temp,	gpmc_t->clk_activation * 1000 +
-							dev_t->t_avdh);
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
 	}
-	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
 
 	/* oe_on */
 	temp = dev_t->t_oeasu; /* remove this ? */
 	if (mux) {
-		temp = max_t(u32, temp,
-			gpmc_t->clk_activation * 1000 + dev_t->t_ach);
-		temp = max_t(u32, temp, (gpmc_t->adv_rd_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_oe)) * 1000);
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_ach);
+		temp = max_t(u32, temp, gpmc_t->adv_rd_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe));
 	}
-	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
 
 	/* access */
 	/* any scope for improvement ?, by combining oe_on & clk_activation,
 	 * need to check whether access = clk_activation + round to sync clk ?
 	 */
 	temp = max_t(u32, dev_t->t_iaa,	dev_t->cyc_iaa * gpmc_t->sync_clk);
-	temp += gpmc_t->clk_activation * 1000;
+	temp += gpmc_t->clk_activation;
 	if (dev_t->cyc_oe)
-		temp = max_t(u32, temp, (gpmc_t->oe_on +
-				gpmc_ticks_to_ns(dev_t->cyc_oe)) * 1000);
-	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, temp, gpmc_t->oe_on +
+				gpmc_ticks_to_ps(dev_t->cyc_oe));
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
 	gpmc_t->cs_rd_off = gpmc_t->oe_off;
 
 	/* rd_cycle */
 	temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
 	temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
-							gpmc_t->access * 1000;
+							gpmc_t->access;
 	/* barter t_ce_rdyz with t_cez_r ? */
 	if (dev_t->t_ce_rdyz)
-		temp = max_t(u32, temp,
-				gpmc_t->cs_rd_off * 1000 + dev_t->t_ce_rdyz);
-	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, temp,	gpmc_t->cs_rd_off + dev_t->t_ce_rdyz);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -976,29 +971,28 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
 	temp = dev_t->t_avdp_w;
 	if (mux) {
 		temp = max_t(u32, temp,
-			gpmc_t->clk_activation * 1000 + dev_t->t_avdh);
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+			gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
 	}
-	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
 
 	/* wr_data_mux_bus */
 	temp = max_t(u32, dev_t->t_weasu,
-			gpmc_t->clk_activation * 1000 + dev_t->t_rdyo);
+			gpmc_t->clk_activation + dev_t->t_rdyo);
 	/* shouldn't mux be kept as a whole for wr_data_mux_bus ?,
 	 * and in that case remember to handle we_on properly
 	 */
 	if (mux) {
 		temp = max_t(u32, temp,
-			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
-		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+			gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
 	}
-	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
 
 	/* we_on */
 	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
-		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
 	else
 		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
 
@@ -1007,24 +1001,24 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
 	gpmc_t->wr_access = gpmc_t->access;
 
 	/* we_off */
-	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
+	temp = gpmc_t->we_on + dev_t->t_wpl;
 	temp = max_t(u32, temp,
-			(gpmc_t->wr_access + gpmc_ticks_to_ns(1)) * 1000);
+			gpmc_t->wr_access + gpmc_ticks_to_ps(1));
 	temp = max_t(u32, temp,
-		(gpmc_t->we_on + gpmc_ticks_to_ns(dev_t->cyc_wpl)) * 1000);
-	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl));
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off * 1000 +
-							dev_t->t_wph) / 1000;
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
 
 	/* wr_cycle */
 	temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
-	temp += gpmc_t->wr_access * 1000;
+	temp += gpmc_t->wr_access;
 	/* barter t_ce_rdyz with t_cez_w ? */
 	if (dev_t->t_ce_rdyz)
 		temp = max_t(u32, temp,
-				 gpmc_t->cs_wr_off * 1000 + dev_t->t_ce_rdyz);
-	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+				 gpmc_t->cs_wr_off + dev_t->t_ce_rdyz);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1038,35 +1032,33 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
 	/* adv_rd_off */
 	temp = dev_t->t_avdp_r;
 	if (mux)
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
-	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
 
 	/* oe_on */
 	temp = dev_t->t_oeasu;
 	if (mux)
 		temp = max_t(u32, temp,
-			gpmc_t->adv_rd_off * 1000 + dev_t->t_aavdh);
-	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+			gpmc_t->adv_rd_off + dev_t->t_aavdh);
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
 
 	/* access */
 	temp = max_t(u32, dev_t->t_iaa, /* remove t_iaa in async ? */
-				gpmc_t->oe_on * 1000 + dev_t->t_oe);
+				gpmc_t->oe_on + dev_t->t_oe);
 	temp = max_t(u32, temp,
-				gpmc_t->cs_on * 1000 + dev_t->t_ce);
+				gpmc_t->cs_on + dev_t->t_ce);
 	temp = max_t(u32, temp,
-				gpmc_t->adv_on * 1000 + dev_t->t_aa);
-	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+				gpmc_t->adv_on + dev_t->t_aa);
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
 	gpmc_t->cs_rd_off = gpmc_t->oe_off;
 
 	/* rd_cycle */
 	temp = max_t(u32, dev_t->t_rd_cycle,
-			gpmc_t->cs_rd_off * 1000 + dev_t->t_cez_r);
-	temp = max_t(u32, temp,
-			gpmc_t->oe_off * 1000 + dev_t->t_oez);
-	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+			gpmc_t->cs_rd_off + dev_t->t_cez_r);
+	temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1080,37 +1072,35 @@ static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
 	/* adv_wr_off */
 	temp = dev_t->t_avdp_w;
 	if (mux)
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
-	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
 
 	/* wr_data_mux_bus */
 	temp = dev_t->t_weasu;
 	if (mux) {
-		temp = max_t(u32, temp,
-			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
-		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+		temp = max_t(u32, temp,	gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
 	}
-	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
 
 	/* we_on */
 	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
-		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
 	else
 		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
 
 	/* we_off */
-	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
-	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	temp = gpmc_t->we_on + dev_t->t_wpl;
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks((gpmc_t->we_off * 1000 +
-				dev_t->t_wph)) / 1000;
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
 
 	/* wr_cycle */
 	temp = max_t(u32, dev_t->t_wr_cycle,
-				gpmc_t->cs_wr_off * 1000 + dev_t->t_cez_w);
-	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+				gpmc_t->cs_wr_off + dev_t->t_cez_w);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1125,10 +1115,10 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
 
 	gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
 					dev_t->t_bacc,
-					gpmc_t->sync_clk) / 1000;
+					gpmc_t->sync_clk);
 
 	temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
-	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
 
 	if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
 		return 0;
@@ -1151,14 +1141,14 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
 	u32 temp;
 
 	/* cs_on */
-	gpmc_t->cs_on = gpmc_round_ns_to_ticks(dev_t->t_ceasu / 1000);
+	gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
 
 	/* adv_on */
 	temp = dev_t->t_avdasu;
 	if (dev_t->t_ce_avd)
 		temp = max_t(u32, temp,
-				gpmc_t->cs_on * 1000 + dev_t->t_ce_avd);
-	gpmc_t->adv_on = gpmc_round_ns_to_ticks(temp / 1000);
+				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)
 		gpmc_calc_sync_common_timings(gpmc_t, dev_t);
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index e59a932..f1d1d2e 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -116,38 +116,38 @@ struct gpmc_timings {
 	u32 sync_clk;
 
 	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
-	u16 cs_on;		/* Assertion time */
-	u16 cs_rd_off;		/* Read deassertion time */
-	u16 cs_wr_off;		/* Write deassertion time */
+	u32 cs_on;		/* Assertion time */
+	u32 cs_rd_off;		/* Read deassertion time */
+	u32 cs_wr_off;		/* Write deassertion time */
 
 	/* ADV signal timings corresponding to GPMC_CONFIG3 */
-	u16 adv_on;		/* Assertion time */
-	u16 adv_rd_off;		/* Read deassertion time */
-	u16 adv_wr_off;		/* Write deassertion time */
+	u32 adv_on;		/* Assertion time */
+	u32 adv_rd_off;		/* Read deassertion time */
+	u32 adv_wr_off;		/* Write deassertion time */
 
 	/* WE signals timings corresponding to GPMC_CONFIG4 */
-	u16 we_on;		/* WE assertion time */
-	u16 we_off;		/* WE deassertion time */
+	u32 we_on;		/* WE assertion time */
+	u32 we_off;		/* WE deassertion time */
 
 	/* OE signals timings corresponding to GPMC_CONFIG4 */
-	u16 oe_on;		/* OE assertion time */
-	u16 oe_off;		/* OE deassertion time */
+	u32 oe_on;		/* OE assertion time */
+	u32 oe_off;		/* OE deassertion time */
 
 	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
-	u16 page_burst_access;	/* Multiple access word delay */
-	u16 access;		/* Start-cycle to first data valid delay */
-	u16 rd_cycle;		/* Total read cycle time */
-	u16 wr_cycle;		/* Total write cycle time */
+	u32 page_burst_access;	/* Multiple access word delay */
+	u32 access;		/* Start-cycle to first data valid delay */
+	u32 rd_cycle;		/* Total read cycle time */
+	u32 wr_cycle;		/* Total write cycle time */
 
-	u16 bus_turnaround;
-	u16 cycle2cycle_delay;
+	u32 bus_turnaround;
+	u32 cycle2cycle_delay;
 
-	u16 wait_monitoring;
-	u16 clk_activation;
+	u32 wait_monitoring;
+	u32 clk_activation;
 
 	/* The following are only on OMAP3430 */
-	u16 wr_access;		/* WRACCESSTIME */
-	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+	u32 wr_access;		/* WRACCESSTIME */
+	u32 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
 
 	struct gpmc_bool_timings bool_timings;
 };


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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-17  8:39                     ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-17  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

On Fri, Sep 14, 2012 at 15:50:02, Mohammed, Afzal wrote:
> * Mohammed, Afzal: Wednesday, September 12, 2012 3:20 PM

> > But some of the tusb async values is less by one. I need
> > to get it right.
> 
> Reason has been identified. It was due to rounding error,
> no changes are required in the expressions. Moving
> completely to picoseconds resolves the issue.
> 
> Can you please try with the attached patch ?

Can you please try with patch attached in previous message
of this thread and check whether it makes n800 gpmc
peripherals work properly

Changes as in above mentioned patch has been pasted below again.

Regards
Afzal

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


diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index d8e5b08..e9d57db 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -289,11 +289,11 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 	if (time == 0)
 		ticks = 0;
 	else
-		ticks = gpmc_ns_to_ticks(time);
+		ticks = gpmc_ps_to_ticks(time);
 	nr_bits = end_bit - st_bit + 1;
 	if (ticks >= 1 << nr_bits) {
 #ifdef DEBUG
-		printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
+		pr_info("GPMC CS%d: %-10s* %3d ps, %3d ticks >= %d\n",
 				cs, name, time, ticks, 1 << nr_bits);
 #endif
 		return -1;
@@ -302,10 +302,9 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 	mask = (1 << nr_bits) - 1;
 	l = gpmc_cs_read_reg(cs, reg);
 #ifdef DEBUG
-	printk(KERN_INFO
-		"GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
-	       cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
-			(l >> st_bit) & mask, time);
+	pr_info("GPMC CS%d: %-10s: %3d ticks, %3lu ps (was %3i ticks) %3d ps\n",
+		cs, name, ticks, gpmc_get_fclk_period() * ticks,
+		(l >> st_bit) & mask, time);
 #endif
 	l &= ~(mask << st_bit);
 	l |= ticks << st_bit;
@@ -385,8 +384,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
 	if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
 #ifdef DEBUG
-		printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
-				cs, (div * gpmc_get_fclk_period()) / 1000, div);
+		pr_info("GPMC CS%d CLK period is %lu ps (div %d)\n",
+				cs, div * gpmc_get_fclk_period(), div);
 #endif
 		l &= ~0x03;
 		l |= (div - 1);
@@ -922,46 +921,42 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
 		 * indirectly necessitates requirement of t_avdp_r & t_avdp_w
 		 * instead of having a single t_avdp
 		 */
-		temp = max_t(u32, temp,	gpmc_t->clk_activation * 1000 +
-							dev_t->t_avdh);
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
 	}
-	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
 
 	/* oe_on */
 	temp = dev_t->t_oeasu; /* remove this ? */
 	if (mux) {
-		temp = max_t(u32, temp,
-			gpmc_t->clk_activation * 1000 + dev_t->t_ach);
-		temp = max_t(u32, temp, (gpmc_t->adv_rd_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_oe)) * 1000);
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_ach);
+		temp = max_t(u32, temp, gpmc_t->adv_rd_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe));
 	}
-	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
 
 	/* access */
 	/* any scope for improvement ?, by combining oe_on & clk_activation,
 	 * need to check whether access = clk_activation + round to sync clk ?
 	 */
 	temp = max_t(u32, dev_t->t_iaa,	dev_t->cyc_iaa * gpmc_t->sync_clk);
-	temp += gpmc_t->clk_activation * 1000;
+	temp += gpmc_t->clk_activation;
 	if (dev_t->cyc_oe)
-		temp = max_t(u32, temp, (gpmc_t->oe_on +
-				gpmc_ticks_to_ns(dev_t->cyc_oe)) * 1000);
-	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, temp, gpmc_t->oe_on +
+				gpmc_ticks_to_ps(dev_t->cyc_oe));
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
 	gpmc_t->cs_rd_off = gpmc_t->oe_off;
 
 	/* rd_cycle */
 	temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
 	temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
-							gpmc_t->access * 1000;
+							gpmc_t->access;
 	/* barter t_ce_rdyz with t_cez_r ? */
 	if (dev_t->t_ce_rdyz)
-		temp = max_t(u32, temp,
-				gpmc_t->cs_rd_off * 1000 + dev_t->t_ce_rdyz);
-	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, temp,	gpmc_t->cs_rd_off + dev_t->t_ce_rdyz);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -976,29 +971,28 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
 	temp = dev_t->t_avdp_w;
 	if (mux) {
 		temp = max_t(u32, temp,
-			gpmc_t->clk_activation * 1000 + dev_t->t_avdh);
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+			gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
 	}
-	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
 
 	/* wr_data_mux_bus */
 	temp = max_t(u32, dev_t->t_weasu,
-			gpmc_t->clk_activation * 1000 + dev_t->t_rdyo);
+			gpmc_t->clk_activation + dev_t->t_rdyo);
 	/* shouldn't mux be kept as a whole for wr_data_mux_bus ?,
 	 * and in that case remember to handle we_on properly
 	 */
 	if (mux) {
 		temp = max_t(u32, temp,
-			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
-		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+			gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
 	}
-	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
 
 	/* we_on */
 	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
-		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
 	else
 		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
 
@@ -1007,24 +1001,24 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
 	gpmc_t->wr_access = gpmc_t->access;
 
 	/* we_off */
-	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
+	temp = gpmc_t->we_on + dev_t->t_wpl;
 	temp = max_t(u32, temp,
-			(gpmc_t->wr_access + gpmc_ticks_to_ns(1)) * 1000);
+			gpmc_t->wr_access + gpmc_ticks_to_ps(1));
 	temp = max_t(u32, temp,
-		(gpmc_t->we_on + gpmc_ticks_to_ns(dev_t->cyc_wpl)) * 1000);
-	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl));
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off * 1000 +
-							dev_t->t_wph) / 1000;
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
 
 	/* wr_cycle */
 	temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
-	temp += gpmc_t->wr_access * 1000;
+	temp += gpmc_t->wr_access;
 	/* barter t_ce_rdyz with t_cez_w ? */
 	if (dev_t->t_ce_rdyz)
 		temp = max_t(u32, temp,
-				 gpmc_t->cs_wr_off * 1000 + dev_t->t_ce_rdyz);
-	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+				 gpmc_t->cs_wr_off + dev_t->t_ce_rdyz);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1038,35 +1032,33 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
 	/* adv_rd_off */
 	temp = dev_t->t_avdp_r;
 	if (mux)
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
-	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
 
 	/* oe_on */
 	temp = dev_t->t_oeasu;
 	if (mux)
 		temp = max_t(u32, temp,
-			gpmc_t->adv_rd_off * 1000 + dev_t->t_aavdh);
-	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+			gpmc_t->adv_rd_off + dev_t->t_aavdh);
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
 
 	/* access */
 	temp = max_t(u32, dev_t->t_iaa, /* remove t_iaa in async ? */
-				gpmc_t->oe_on * 1000 + dev_t->t_oe);
+				gpmc_t->oe_on + dev_t->t_oe);
 	temp = max_t(u32, temp,
-				gpmc_t->cs_on * 1000 + dev_t->t_ce);
+				gpmc_t->cs_on + dev_t->t_ce);
 	temp = max_t(u32, temp,
-				gpmc_t->adv_on * 1000 + dev_t->t_aa);
-	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+				gpmc_t->adv_on + dev_t->t_aa);
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
 	gpmc_t->cs_rd_off = gpmc_t->oe_off;
 
 	/* rd_cycle */
 	temp = max_t(u32, dev_t->t_rd_cycle,
-			gpmc_t->cs_rd_off * 1000 + dev_t->t_cez_r);
-	temp = max_t(u32, temp,
-			gpmc_t->oe_off * 1000 + dev_t->t_oez);
-	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+			gpmc_t->cs_rd_off + dev_t->t_cez_r);
+	temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1080,37 +1072,35 @@ static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
 	/* adv_wr_off */
 	temp = dev_t->t_avdp_w;
 	if (mux)
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
-	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
 
 	/* wr_data_mux_bus */
 	temp = dev_t->t_weasu;
 	if (mux) {
-		temp = max_t(u32, temp,
-			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
-		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+		temp = max_t(u32, temp,	gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
 	}
-	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
 
 	/* we_on */
 	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
-		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
 	else
 		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
 
 	/* we_off */
-	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
-	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	temp = gpmc_t->we_on + dev_t->t_wpl;
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks((gpmc_t->we_off * 1000 +
-				dev_t->t_wph)) / 1000;
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
 
 	/* wr_cycle */
 	temp = max_t(u32, dev_t->t_wr_cycle,
-				gpmc_t->cs_wr_off * 1000 + dev_t->t_cez_w);
-	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+				gpmc_t->cs_wr_off + dev_t->t_cez_w);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1125,10 +1115,10 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
 
 	gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
 					dev_t->t_bacc,
-					gpmc_t->sync_clk) / 1000;
+					gpmc_t->sync_clk);
 
 	temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
-	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
 
 	if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
 		return 0;
@@ -1151,14 +1141,14 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
 	u32 temp;
 
 	/* cs_on */
-	gpmc_t->cs_on = gpmc_round_ns_to_ticks(dev_t->t_ceasu / 1000);
+	gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
 
 	/* adv_on */
 	temp = dev_t->t_avdasu;
 	if (dev_t->t_ce_avd)
 		temp = max_t(u32, temp,
-				gpmc_t->cs_on * 1000 + dev_t->t_ce_avd);
-	gpmc_t->adv_on = gpmc_round_ns_to_ticks(temp / 1000);
+				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)
 		gpmc_calc_sync_common_timings(gpmc_t, dev_t);
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index e59a932..f1d1d2e 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -116,38 +116,38 @@ struct gpmc_timings {
 	u32 sync_clk;
 
 	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
-	u16 cs_on;		/* Assertion time */
-	u16 cs_rd_off;		/* Read deassertion time */
-	u16 cs_wr_off;		/* Write deassertion time */
+	u32 cs_on;		/* Assertion time */
+	u32 cs_rd_off;		/* Read deassertion time */
+	u32 cs_wr_off;		/* Write deassertion time */
 
 	/* ADV signal timings corresponding to GPMC_CONFIG3 */
-	u16 adv_on;		/* Assertion time */
-	u16 adv_rd_off;		/* Read deassertion time */
-	u16 adv_wr_off;		/* Write deassertion time */
+	u32 adv_on;		/* Assertion time */
+	u32 adv_rd_off;		/* Read deassertion time */
+	u32 adv_wr_off;		/* Write deassertion time */
 
 	/* WE signals timings corresponding to GPMC_CONFIG4 */
-	u16 we_on;		/* WE assertion time */
-	u16 we_off;		/* WE deassertion time */
+	u32 we_on;		/* WE assertion time */
+	u32 we_off;		/* WE deassertion time */
 
 	/* OE signals timings corresponding to GPMC_CONFIG4 */
-	u16 oe_on;		/* OE assertion time */
-	u16 oe_off;		/* OE deassertion time */
+	u32 oe_on;		/* OE assertion time */
+	u32 oe_off;		/* OE deassertion time */
 
 	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
-	u16 page_burst_access;	/* Multiple access word delay */
-	u16 access;		/* Start-cycle to first data valid delay */
-	u16 rd_cycle;		/* Total read cycle time */
-	u16 wr_cycle;		/* Total write cycle time */
+	u32 page_burst_access;	/* Multiple access word delay */
+	u32 access;		/* Start-cycle to first data valid delay */
+	u32 rd_cycle;		/* Total read cycle time */
+	u32 wr_cycle;		/* Total write cycle time */
 
-	u16 bus_turnaround;
-	u16 cycle2cycle_delay;
+	u32 bus_turnaround;
+	u32 cycle2cycle_delay;
 
-	u16 wait_monitoring;
-	u16 clk_activation;
+	u32 wait_monitoring;
+	u32 clk_activation;
 
 	/* The following are only on OMAP3430 */
-	u16 wr_access;		/* WRACCESSTIME */
-	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+	u32 wr_access;		/* WRACCESSTIME */
+	u32 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
 
 	struct gpmc_bool_timings bool_timings;
 };

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

* Re: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-17  8:39                     ` Mohammed, Afzal
@ 2012-09-17 22:50                       ` Tony Lindgren
  -1 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-09-17 22:50 UTC (permalink / raw)
  To: Mohammed, Afzal; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

* Mohammed, Afzal <afzal@ti.com> [120917 01:40]:
> Hi Tony,
> 
> On Fri, Sep 14, 2012 at 15:50:02, Mohammed, Afzal wrote:
> > * Mohammed, Afzal: Wednesday, September 12, 2012 3:20 PM
> 
> > > But some of the tusb async values is less by one. I need
> > > to get it right.
> > 
> > Reason has been identified. It was due to rounding error,
> > no changes are required in the expressions. Moving
> > completely to picoseconds resolves the issue.
> > 
> > Can you please try with the attached patch ?

Gave it a quick try and it seemed to work.. But when I tried
rebasing my patches for the cbus to keep things working with
the watchdog, I ran into multiple merge conflicts with
current linux next and gave up.
 
Care to repost this series updated against current linux
next?

I'm afraid I've pretty much lost track of all the patches
and rather not start resolving the conflicts as I'm sure
I'll break something else :)

Regards,

Tony

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-17 22:50                       ` Tony Lindgren
  0 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-09-17 22:50 UTC (permalink / raw)
  To: linux-arm-kernel

* Mohammed, Afzal <afzal@ti.com> [120917 01:40]:
> Hi Tony,
> 
> On Fri, Sep 14, 2012 at 15:50:02, Mohammed, Afzal wrote:
> > * Mohammed, Afzal: Wednesday, September 12, 2012 3:20 PM
> 
> > > But some of the tusb async values is less by one. I need
> > > to get it right.
> > 
> > Reason has been identified. It was due to rounding error,
> > no changes are required in the expressions. Moving
> > completely to picoseconds resolves the issue.
> > 
> > Can you please try with the attached patch ?

Gave it a quick try and it seemed to work.. But when I tried
rebasing my patches for the cbus to keep things working with
the watchdog, I ran into multiple merge conflicts with
current linux next and gave up.
 
Care to repost this series updated against current linux
next?

I'm afraid I've pretty much lost track of all the patches
and rather not start resolving the conflicts as I'm sure
I'll break something else :)

Regards,

Tony

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

* Re: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-17 22:50                       ` Tony Lindgren
@ 2012-09-17 23:10                         ` Tony Lindgren
  -1 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-09-17 23:10 UTC (permalink / raw)
  To: Mohammed, Afzal; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [120917 15:54]:
> * Mohammed, Afzal <afzal@ti.com> [120917 01:40]:
> > Hi Tony,
> > 
> > On Fri, Sep 14, 2012 at 15:50:02, Mohammed, Afzal wrote:
> > > * Mohammed, Afzal: Wednesday, September 12, 2012 3:20 PM
> > 
> > > > But some of the tusb async values is less by one. I need
> > > > to get it right.
> > > 
> > > Reason has been identified. It was due to rounding error,
> > > no changes are required in the expressions. Moving
> > > completely to picoseconds resolves the issue.
> > > 
> > > Can you please try with the attached patch ?
> 
> Gave it a quick try and it seemed to work.. But when I tried
> rebasing my patches for the cbus to keep things working with
> the watchdog, I ran into multiple merge conflicts with
> current linux next and gave up.

OK went back to my original branch without current linux
next and with the new cbus + retu driver from Aaro applied.
Confirmed it's now working on n800 tusb6010.
  
> Care to repost this series updated against current linux
> next?
> 
> I'm afraid I've pretty much lost track of all the patches
> and rather not start resolving the conflicts as I'm sure
> I'll break something else :)

You should still repost the whole updated series against
linux next.

Regards,

Tony

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-17 23:10                         ` Tony Lindgren
  0 siblings, 0 replies; 74+ messages in thread
From: Tony Lindgren @ 2012-09-17 23:10 UTC (permalink / raw)
  To: linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [120917 15:54]:
> * Mohammed, Afzal <afzal@ti.com> [120917 01:40]:
> > Hi Tony,
> > 
> > On Fri, Sep 14, 2012 at 15:50:02, Mohammed, Afzal wrote:
> > > * Mohammed, Afzal: Wednesday, September 12, 2012 3:20 PM
> > 
> > > > But some of the tusb async values is less by one. I need
> > > > to get it right.
> > > 
> > > Reason has been identified. It was due to rounding error,
> > > no changes are required in the expressions. Moving
> > > completely to picoseconds resolves the issue.
> > > 
> > > Can you please try with the attached patch ?
> 
> Gave it a quick try and it seemed to work.. But when I tried
> rebasing my patches for the cbus to keep things working with
> the watchdog, I ran into multiple merge conflicts with
> current linux next and gave up.

OK went back to my original branch without current linux
next and with the new cbus + retu driver from Aaro applied.
Confirmed it's now working on n800 tusb6010.
  
> Care to repost this series updated against current linux
> next?
> 
> I'm afraid I've pretty much lost track of all the patches
> and rather not start resolving the conflicts as I'm sure
> I'll break something else :)

You should still repost the whole updated series against
linux next.

Regards,

Tony

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

* RE: [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
  2012-09-17 23:10                         ` Tony Lindgren
@ 2012-09-19 13:43                           ` Mohammed, Afzal
  -1 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-19 13:43 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: paul, linux-omap, Hunter, Jon, linux-arm-kernel

Hi Tony,

On Tue, Sep 18, 2012 at 04:40:02, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [120917 15:54]:

> > > > Can you please try with the attached patch ?
> > 
> > Gave it a quick try and it seemed to work.. But when I tried
> > rebasing my patches for the cbus to keep things working with
> > the watchdog, I ran into multiple merge conflicts with
> > current linux next and gave up.
> 
> OK went back to my original branch without current linux
> next and with the new cbus + retu driver from Aaro applied.
> Confirmed it's now working on n800 tusb6010.

Thanks for checking and confirming.

> > Care to repost this series updated against current linux
> > next?
> > 
> > I'm afraid I've pretty much lost track of all the patches
> > and rather not start resolving the conflicts as I'm sure
> > I'll break something else :)
> 
> You should still repost the whole updated series against
> linux next.

New updated version - v7, based over linux next has been posted.

Regards
Afzal

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

* [PATCH v6 10/10] ARM: OMAP2+: tusb6010: generic timing calculation
@ 2012-09-19 13:43                           ` Mohammed, Afzal
  0 siblings, 0 replies; 74+ messages in thread
From: Mohammed, Afzal @ 2012-09-19 13:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

On Tue, Sep 18, 2012 at 04:40:02, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [120917 15:54]:

> > > > Can you please try with the attached patch ?
> > 
> > Gave it a quick try and it seemed to work.. But when I tried
> > rebasing my patches for the cbus to keep things working with
> > the watchdog, I ran into multiple merge conflicts with
> > current linux next and gave up.
> 
> OK went back to my original branch without current linux
> next and with the new cbus + retu driver from Aaro applied.
> Confirmed it's now working on n800 tusb6010.

Thanks for checking and confirming.

> > Care to repost this series updated against current linux
> > next?
> > 
> > I'm afraid I've pretty much lost track of all the patches
> > and rather not start resolving the conflicts as I'm sure
> > I'll break something else :)
> 
> You should still repost the whole updated series against
> linux next.

New updated version - v7, based over linux next has been posted.

Regards
Afzal

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

end of thread, other threads:[~2012-09-19 13:43 UTC | newest]

Thread overview: 74+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-21 10:41 [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver Afzal Mohammed
2012-08-21 10:41 ` Afzal Mohammed
2012-08-21 10:45 ` [PATCH v6 01/10] ARM: OMAP2+: nand: unify init functions Afzal Mohammed
2012-08-21 10:45   ` Afzal Mohammed
2012-08-21 11:37   ` Igor Grinberg
2012-08-21 11:37     ` Igor Grinberg
2012-08-21 10:45 ` [PATCH v6 02/10] ARM: OMAP2+: gpmc: handle additional timings Afzal Mohammed
2012-08-21 10:45   ` Afzal Mohammed
2012-08-21 10:45 ` [PATCH v6 03/10] ARM: OMAP2+: onenand: refactor for clarity Afzal Mohammed
2012-08-21 10:45   ` Afzal Mohammed
2012-08-21 10:45 ` [PATCH v6 04/10] ARM: OMAP2+: GPMC: Remove unused OneNAND get_freq() platform function Afzal Mohammed
2012-08-21 10:45   ` Afzal Mohammed
2012-08-21 10:45 ` [PATCH v6 05/10] ARM: OMAP2+: gpmc: find features by ip rev check Afzal Mohammed
2012-08-21 10:45   ` Afzal Mohammed
2012-08-22  2:08   ` Jon Hunter
2012-08-22  2:08     ` Jon Hunter
2012-08-21 10:45 ` [PATCH v6 06/10] ARM: OMAP2+: gpmc: remove cs# in sync clk div calc Afzal Mohammed
2012-08-21 10:45   ` Afzal Mohammed
2012-08-22  2:11   ` Jon Hunter
2012-08-22  2:11     ` Jon Hunter
2012-08-21 10:45 ` [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation Afzal Mohammed
2012-08-21 10:45   ` Afzal Mohammed
2012-08-23  2:58   ` Jon Hunter
2012-08-23  2:58     ` Jon Hunter
2012-08-24 19:54     ` Tony Lindgren
2012-08-24 19:54       ` Tony Lindgren
2012-08-27 11:46       ` Mohammed, Afzal
2012-08-27 11:46         ` Mohammed, Afzal
2012-08-27 10:37     ` Mohammed, Afzal
2012-08-27 10:37       ` Mohammed, Afzal
2012-08-27 20:30       ` Jon Hunter
2012-08-27 20:30         ` Jon Hunter
2012-08-28 12:21         ` Mohammed, Afzal
2012-08-28 12:21           ` Mohammed, Afzal
2012-08-21 10:45 ` [PATCH v6 08/10] ARM: OMAP2+: onenand: " Afzal Mohammed
2012-08-21 10:45   ` Afzal Mohammed
2012-08-21 10:46 ` [PATCH v6 09/10] ARM: OMAP2+: smc91x: " Afzal Mohammed
2012-08-21 10:46   ` Afzal Mohammed
2012-08-21 10:46 ` [PATCH v6 10/10] ARM: OMAP2+: tusb6010: " Afzal Mohammed
2012-08-21 10:46   ` Afzal Mohammed
2012-08-24 19:46   ` Tony Lindgren
2012-08-24 19:46     ` Tony Lindgren
2012-08-27  8:34     ` Mohammed, Afzal
2012-08-27  8:34       ` Mohammed, Afzal
2012-09-03  5:34       ` Mohammed, Afzal
2012-09-03  5:34         ` Mohammed, Afzal
2012-09-06  7:39         ` Mohammed, Afzal
2012-09-06  7:39           ` Mohammed, Afzal
2012-09-06 20:43           ` Tony Lindgren
2012-09-06 20:43             ` Tony Lindgren
2012-09-11 18:46             ` Tony Lindgren
2012-09-11 18:46               ` Tony Lindgren
2012-09-12  9:50               ` Mohammed, Afzal
2012-09-12  9:50                 ` Mohammed, Afzal
2012-09-14 10:20                 ` Mohammed, Afzal
2012-09-14 10:20                   ` Mohammed, Afzal
2012-09-17  8:39                   ` Mohammed, Afzal
2012-09-17  8:39                     ` Mohammed, Afzal
2012-09-17 22:50                     ` Tony Lindgren
2012-09-17 22:50                       ` Tony Lindgren
2012-09-17 23:10                       ` Tony Lindgren
2012-09-17 23:10                         ` Tony Lindgren
2012-09-19 13:43                         ` Mohammed, Afzal
2012-09-19 13:43                           ` Mohammed, Afzal
2012-09-07  0:15           ` Paul Walmsley
2012-09-07  0:15             ` Paul Walmsley
2012-08-27 12:16 ` [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver Daniel Mack
2012-08-27 12:16   ` Daniel Mack
2012-08-27 12:38   ` Mohammed, Afzal
2012-08-27 12:38     ` Mohammed, Afzal
2012-08-27 13:30     ` Daniel Mack
2012-08-27 13:30       ` Daniel Mack
2012-08-27 14:01       ` Mohammed, Afzal
2012-08-27 14:01         ` Mohammed, Afzal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.