[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