cc: Stefano Babic <sba...@denx.de>
Cc: Scott Wood <scottw...@freescale.com>
Cc: Tom Rini <tr...@konsulko.com>
Cc: Tapani Utriainen <tap...@technexion.com>
cc: Simon Glass <s...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to