[U-Boot] [RFC] tam3517: add GPMC nand timing (brutally)

Jeroen Hofstee jeroen at myspectrum.nl
Sat May 30 11:16:25 CEST 2015


cc: Stefano Babic <sbabic at denx.de>
Cc: Scott Wood <scottwood at freescale.com>
Cc: Tom Rini <trini at konsulko.com>
Cc: Tapani Utriainen <tapani at technexion.com>
cc: Simon Glass <sjg at chromium.org>
---
Hi,

This patch intends to set the proper timing for the MT29F4G16ABBDAHC as used
on the tam3517 SOM by brutally changing the defaults values. Some ascii art
is included to describe why I believe these timing values to be correct.

Of course we should find a better way for a board to set proper timings, some
options:
  - do the CONFIG_* foo
  - implement a weak function to get the timing
  - find a spot to let the board overwrite the timing (spl and/or u-boot?)

I think the last option is the best one in general, since it allows to read
for example a dtb from the nand with the timing, and allows ONFI detection /
timing modes to be set before changing the gpmc timing. Since this is a SOM
we need to find a decent place to put that logic, since all derived boards
would like to have the timing.

Comments / ideas are welcome,

With kind regards,

Jeroen

orig
195.247 0.005: NAND read: device 0 offset 0x400000, size 0x600000
196.362 1.116:  6291456 bytes read: OK

prefetch
0.025 0.004: NAND read: device 0 offset 0x400000, size 0x600000
0.843 0.818:  6291456 bytes read: OK

timing
120.332 0.005: NAND read: device 0 offset 0x400000, size 0x600000
121.329 0.997:  6291456 bytes read: OK

timing + prefetech
2515.535 0.004: NAND read: device 0 offset 0x400000, size 0x600000
2516.117 0.582:  6291456 bytes read: OK

orig -> prefetch = 298ms
orig -> timing = 119ms
pretech -> prefetch + timing = 236ms
timing -> timing + prefetch = 415ms
orig -> timing + prefetch = 534ms

 arch/arm/cpu/armv7/omap-common/mem-common.c | 148 ++++++++++++++++++++++++++--
 1 file changed, 142 insertions(+), 6 deletions(-)

diff --git a/arch/arm/cpu/armv7/omap-common/mem-common.c b/arch/arm/cpu/armv7/omap-common/mem-common.c
index fc4290c..42346e6 100644
--- a/arch/arm/cpu/armv7/omap-common/mem-common.c
+++ b/arch/arm/cpu/armv7/omap-common/mem-common.c
@@ -68,6 +68,141 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
 	sdelay(2000);
 }
 
+#include <asm/arch/omap3-regs.h>
+
+/*
+ * ========================== WRITE CYCLE ===============================
+ *
+ * Sending a command:
+ *
+ *                     |-         WRCYCLETIME      -|
+ *
+ *               CSONTIME=0               CSWROFFTIME=WRCYCLETIME
+ * CE#    xxxxxxxxxxxxx|_____________________________|xxxxxxxxxxxxxxxxxx
+ *
+ *
+ *                WEONTIME=0         WEOFFTIME (trigger)
+ *                                      *_____________
+ * WE#    xxxxxxxxxxxxx|________________|             |xxxxxxxxxxxxxxxxxx
+ *
+ *                      ______________________________
+ * DATA   xxxxxxxxxxxxx|                              |xxxxxxxxxxxxxxxxxx
+ *
+ *
+ *
+ * ========================== LATCH CYCLE ===============================
+ *
+ * Sending a address (note uses WRCYCLETIME!)
+ *
+ *                     |-         WRCYCLETIME      -|
+ *
+ *               CSONTIME=0               CSWROFFTIME=WRCYCLETIME
+ * CE#    xxxxxxxxxxxxx|_____________________________|xxxxxxxxxxxxxxxxxx
+ *
+ *
+ *                WEONTIME=0         WEOFFTIME (trigger)
+ *                                      *_____________
+ * WE#    xxxxxxxxxxxxx|________________|             |xxxxxxxxxxxxxxxxxx
+ *
+ *             ADVONTIME=0                ADVWROFFTIME=WRCYCLETIME
+ *                      ______________________________
+ * ALE    xxxxxxxxxxxxx|                              |xxxxxxxxxxxxxxxxxx
+ *
+ *                      ______________________________
+ * DATA   xxxxxxxxxxxxx|                              |xxxxxxxxxxxxxxxxxx
+ *
+ *
+ *
+ * ========================== READ CYCLE ===============================
+ *
+ *
+ * NAND triggers the READY signal, which is a flags in status register and
+ * causes the code to perform the (next) read. CE is enabled again, RE# pulled
+ * down and data is read at READACCESSTIME. After the read the CE is off again.
+ *
+ *                     |-         RDCYCLETIME      -|
+ *
+ *                   ____________________________________________________
+ * READY  __________|
+ *
+ *               CSONTIME=0               CSRDOFFTIME=RDCYCLETIME
+ * CE#    xxxxxxxxxxxxx|_____________________________|xxxxxxxxxxxxxxxxxx
+ *
+ *
+ *                OEONTIME=0         OEOFFTIME
+ *                      *                 _____________
+ * RE#    xxxxxxxxxxxxxx|________________|            |xxxxxxxxxxxxxxxxxx
+ *
+ *                                       READACCESTIME
+ *                                    ________|_______
+ * DATA   xxxxxxxxxxxxxxxxxxxxxxxxxxxx|       |       |xxxxxxxxxxxxxxxxxx
+ */
+
+
+/* The gpmc is timed from the L3 (165 MHz, so T ~= 6.06 ns */
+
+/* read acces time is 25ms from CS. -> 4.5 cycle */
+#define OEONTIME_NAND			0x0    			/* RE# on time */
+#define OEOFFTIME_NAND			0x3	    		/* RE# off time */
+#define RDACCESSTIME_NAND		0x6			/* sampling point for read */
+#define RDCYCLETIME_NAND		0x6			/* complete read time */
+
+/*
+ * The WEOFFTIME triggers the NAND to sample the data line (command or address).
+ * There must be enough time before that to satisy the setup times, so it must
+ * be after at least tCLS, tCS, tALS, tDS. Futhermore there is a minimum time
+ * the WE# must be held low, tWP for the NAND to detect the edge. For the
+ * MT29F4G16ABBDAHC these are tCLS=10ns, tCS=20ns, tALS=10ns, tDS=10ns and tW=12ns.
+ * So at least 4 clock ticks are needed before the WE# can be pulled up. Thereafter
+ * the lines must be held for some hold times, for the NAND to sample them. Hold
+ * times for the chip are tCLH=5ns, tCH=5ns, tALH=5ns, tDH=5ns. The WE must be held
+ * high for the tWH=10ns.
+ *
+ * From above timing 2,4,6 should work from the NAND chips point of view. It doesn't
+ * and since the TRM mentions "For the AccessCompletion: 1 cycle is required for data
+ * hold time (nCS deassertion)" make it 3,5,7....
+ */
+#define WEONTIME_NAND	 		0x3			/* WE# on time */
+#define WEOFFTIME_NAND			0x5			/* WE# off time */
+#define WRCYCLETIME_NAND		0x7   			/* complete write, latch time */
+
+/* For a latch ALE should be high at WEOFFTIME, just make it high during the whole cycle */
+#define ADVONTIME_NAND			0       		/* ALE on time */
+#define ADVWROFFTIME_NAND		WRCYCLETIME_NAND	/* ALE off time for latch */
+
+#define CSONTIME_NAND			0			/* CE# on time for read, latch, write */
+#define CSRDOFFTIME_NAND		RDCYCLETIME_NAND	/* CE# off for read */
+#define CSWROFFTIME_NAND		WRCYCLETIME_NAND	/* CE# off for latch, write */
+
+/* tRLOH=5ns, wait for data lines to be released when switching to other CS */
+#define BUSTURNAROUND_NAND		1
+#define CYCLE2CYCLEDELAY_NAND		0x0
+
+/* CONFIG1: Type of Device, Type of Access */
+#define NAND_GPMC_CONFIG1 ( GPMCFCLKDIVIDER(0) /* not used for NAND */ | 0 /* TIMEPARAGRANULARITY */ | \
+	0 /* MUXADDDATA */ | DEVICETYPE_NAND | DEVICESIZE_16BIT | WAITPINSELECT(0) | WAITMONITORINGTIME(0) | \
+	0 /* WAITWRITEMONITORING */ | 0 /* WAITREADMONITORING */ | ATTACHEDDEVICEPAGELENGTH(0) | \
+	CLKACTIVATIONTIME(0) | 0 /* WRITETYPE */ | 0 /* WRITEMULTIPLE */ | 0 /* READTYPE */ | \
+	0 /* READMULTIPLE */ | 0 /* WRAPBURST */ )
+/* CONFIG2: Chip Select */
+#define NAND_GPMC_CONFIG2 (CSWROFFTIME(CSWROFFTIME_NAND) | CSRDOFFTIME(CSRDOFFTIME_NAND) | \
+	CSONTIME(CSONTIME_NAND) | 0 /* CSEXTRADELAY */ )
+/* CONFIG3: ADV/ALE */
+#define NAND_GPMC_CONFIG3 ( ADVWROFFTIME(ADVWROFFTIME_NAND) | ADVRDOFFTIME(0) | \
+	0 /* ADVEXTRADELAY */ | ADVONTIME(ADVONTIME_NAND) )
+/* CONFIG4: WE/OE */
+#define NAND_GPMC_CONFIG4 ( WEOFFTIME(WEOFFTIME_NAND) | 0 /* WEEXTRADELAY */ | WEONTIME(WEONTIME_NAND) | \
+	OEOFFTIME(WEOFFTIME_NAND) |  OEEXTRADELAY | OEONTIME(OEONTIME_NAND) )
+/* CONFIG5: Cycle Timing */
+#define NAND_GPMC_CONFIG5 ( PAGEBURSTACCESSTIME(1) | RDACCESSTIME(RDACCESSTIME_NAND) | \
+	WRCYCLETIME(WRCYCLETIME_NAND) |  RDCYCLETIME(RDCYCLETIME_NAND) )
+/* CONFIG6: Rest of the Pack */
+#define NAND_GPMC_CONFIG6 ( WRACCESSTIME(0) /* not NAND */ | WRDATAONADMUXBUS(0) | \
+	CYCLE2CYCLEDELAY(CYCLE2CYCLEDELAY_NAND) | \
+	CYCLE2CYCLESAMECSEN | 0 /* CYCLE2CYCLEDIFFCSEN */ | BUSTURNAROUND(BUSTURNAROUND_NAND) )
+/* CONFIG7: Address Mapping */
+#define NAND_GPMC_CONFIG7	( MASKADDRESS(0xC) /* 64MB */ | CSVALID | BASEADDRESS(0x4) )
+
 /*****************************************************
  * gpmc_init(): init gpmc bus
  * Init GPMC for x16, MuxMode (SDRAM in x32).
@@ -95,12 +230,13 @@ void gpmc_init(void)
 	/* min 16MB */	GPMC_SIZE_16M)));
 #elif defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
 /* configure GPMC for NAND */
-	const u32  gpmc_regs[GPMC_MAX_REG] = {	M_NAND_GPMC_CONFIG1,
-						M_NAND_GPMC_CONFIG2,
-						M_NAND_GPMC_CONFIG3,
-						M_NAND_GPMC_CONFIG4,
-						M_NAND_GPMC_CONFIG5,
-						M_NAND_GPMC_CONFIG6,
+	const u32  gpmc_regs[GPMC_MAX_REG] = {
+						NAND_GPMC_CONFIG1,
+						NAND_GPMC_CONFIG2,
+						NAND_GPMC_CONFIG3,
+						NAND_GPMC_CONFIG4,
+						NAND_GPMC_CONFIG5,
+						NAND_GPMC_CONFIG6,
 						0
 						};
 	u32 base = CONFIG_SYS_NAND_BASE;
-- 
1.9.1



More information about the U-Boot mailing list