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