diff options
Diffstat (limited to 'nuttx/configs/ea3152/src/up_mem.c')
-rwxr-xr-x | nuttx/configs/ea3152/src/up_mem.c | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/nuttx/configs/ea3152/src/up_mem.c b/nuttx/configs/ea3152/src/up_mem.c new file mode 100755 index 000000000..5eae04e0f --- /dev/null +++ b/nuttx/configs/ea3152/src/up_mem.c @@ -0,0 +1,359 @@ +/**************************************************************************** + * configs/ea3152/src/up_mem.c + * arch/arm/src/board/up_mem.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * References: + * - NXP UM10314 LPC3130/31 User manual Rev. 1.01 — 9 September 2009 + * - NXP lpc313x.cdl.drivers.zip example driver code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> +#include <debug.h> + +#include <nuttx/arch.h> +#include <arch/board/board.h> + +#include "chip.h" +#include "up_arch.h" + +#include "lpc31_syscreg.h" +#include "lpc31_cgudrvr.h" +#include "lpc31_mpmc.h" +#include "ea3152_internal.h" + +#ifdef CONFIG_LPC31XX_EXTSDRAM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The MPMC delay based on trace lengths between SDRAM and the chip and on + * the delay strategy used for SDRAM. + */ + +#define EA3152_MPMC_DELAY 0x824 + +/* Delay constants in nanosecondss for MT48LC32M16LF SDRAM on board */ + +#define EA3152_SDRAM_TRP (20) +#define EA3152_SDRAM_TRFC (66) +#define EA3152_SDRAM_TRAS (44) +#define EA3152_SDRAM_TREX (75) +#define EA3152_SDRAM_TARP 4 +#define EA3152_SDRAM_TWR (75) +#define EA3152_SDRAM_TRC (66) +#define EA3152_SDRAM_TRRD (15) +#define EA3152_SDRAM_TMRD (20) +#define EA3152_SDRAM_TXSR (75) +#define EA3152_SDRAM_TDAL (50) +#define EA3152_SDRAM_REFRESH (100) +#define EA3152_SDRAM_OPERREFRESH (7812) + +/* Macro used to convert the above values (in nanoseconds) into units of + * the HCLK. + */ + +#define NS2HCLKS(ns,hclk2,mask) \ + ((uint32_t)(((uint64_t)ns *(uint64_t)hclk2) / 1000000000ull) & mask) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_sdraminitialize + * + * Description: + * Configure SDRAM on the EA3152 board + * + * Micron Initialization Sequence from their data sheet for the Micron + * MT48LC32M16A2 32M x 16 SDRAM chip: + * + * "SDRAMs must be powered up and initialized in a predefined manner. + * Operational procedures other than those specified may result in + * undefined operation. Once power is applied to VDD and VDDQ + * (simultaneously) and the clock is stable (stable clock is defined as + * a signal cycling within timing constraints specified for the clock + * pin), the SDRAM requires a 100µs delay prior to issuing any command + * other than a COMMAND INHIBIT or NOP. + * + * "Starting at some point during this 100µs period and continuing at least + * through the end of this period, COMMAND INHIBIT or NOP commands should + * be applied. Once the 100µs delay has been satisfied with at least one + * COMMAND INHIBIT or NOP command having been applied, a PRECHARGE command + * should be applied. All banks must then be precharged, thereby placing + * the device in the all banks idle state. + * + * "Once in the idle state, two AUTO REFRESH cycles must be performed. After + * the AUTO REFRESH cycles are complete, the SDRAM is ready for mode + * register programming. + * + * "Because the mode register will power up in an unknown state, it should + * be loaded prior to applying any operational command." + * + * The JEDEC recommendation for initializing SDRAM is: + * + * APPLY POWER (Vdd/Vddq equally, and CLK is stable) + * Wait 200uS + * PRECHARGE all + * 8 AUTO REFRESH COMMANDS + * LOAD MODE REGISTER + * SDRAM is ready for operation + * + * The Micron SDRAM parts will work fine with the JEDEC sequence, but also + * allow for a quicker init sequence of: + * + * APPLY POWER (Vdd/Vddq equally, and CLK is stable) + * Wait at least 100uS (during which time start applying and + * continue applying NOP or COMMAND INHIBIT) + * PRECHARGE all + * 2 AUTO REFRESH COMMANDS (min requirement, more than 2 is also ok) + * LOAD MODE REGISTER + * SDRAM is ready for operation + * + ****************************************************************************/ + +static void lpc31_sdraminitialize(void) +{ + uint32_t tmp; + uint32_t regval; + + /* These run-time calculations can be reduced dramatically if hclk is + * replaced with an apriori value. + */ + +#ifdef CONFIG_LPC31XX_SDRAMHCLK +# define HCLK CONFIG_LPC31XX_SDRAMHCLK +#else + uint32_t hclk = lpc31_clkfreq(CLKID_MPMCCFGCLK2, DOMAINID_SYS); +# define HCLK hclk +#endif + + /* Check RTL for divide by 2 possible. If so change then enable the followng logic */ +#if 0 + uint32_t hclk2 = hclk; + + if (((getreg32(LPC31_MPMC_CONFIG) & MPMC_CONFIG_CLK)) != 0) + { + hclk2 >>= 1; + } +# define HCLK2 hclk2 +#else +# define HCLK2 hclk +#endif + up_udelay(100); + + /* Set command delay startergy */ + + putreg32(MPMC_DYNREADCONFIG_CMDDEL, LPC31_MPMC_DYNREADCONFIG); + + /* Configure device config register nSDCE0 for proper width SDRAM */ + + putreg32((MPMC_DYNCONFIG0_MDSDRAM|MPMC_DYNCONFIG_HP16_32MX16), + LPC31_MPMC_DYNCONFIG0); + putreg32((MPMC_DYNRASCAS0_RAS2CLK|MPMC_DYNRASCAS0_CAS2CLK), + LPC31_MPMC_DYNRASCAS0); + + /* Min 20ns program 1 so that at least 2 HCLKs are used */ + + putreg32(NS2HCLKS(EA3152_SDRAM_TRP, HCLK2, MPMC_DYNTRP_MASK), + LPC31_MPMC_DYNTRP); + putreg32(NS2HCLKS(EA3152_SDRAM_TRAS, HCLK2, MPMC_DYNTRAS_MASK), + LPC31_MPMC_DYNTRAS); + putreg32(NS2HCLKS(EA3152_SDRAM_TREX, HCLK2, MPMC_DYNTSREX_MASK), + LPC31_MPMC_DYNTSREX); + putreg32(EA3152_SDRAM_TARP, + LPC31_MPMC_DYNTAPR); + putreg32(NS2HCLKS(EA3152_SDRAM_TDAL, HCLK2, MPMC_DYNTDAL_MASK), + LPC31_MPMC_DYNTDAL); + putreg32(NS2HCLKS(EA3152_SDRAM_TWR, HCLK2, MPMC_DYNTWR_MASK), + LPC31_MPMC_DYNTWR); + putreg32(NS2HCLKS(EA3152_SDRAM_TRC, HCLK2, MPMC_DYNTRC_MASK), + LPC31_MPMC_DYNTRC); + putreg32(NS2HCLKS(EA3152_SDRAM_TRFC, HCLK2, MPMC_DYNTRFC_MASK), + LPC31_MPMC_DYNTRFC); + putreg32(NS2HCLKS(EA3152_SDRAM_TXSR, HCLK2, MPMC_DYNTXSR_MASK), + LPC31_MPMC_DYNTXSR); + putreg32(NS2HCLKS(EA3152_SDRAM_TRRD, HCLK2, MPMC_DYNTRRD_MASK), + LPC31_MPMC_DYNTRRD); + putreg32(NS2HCLKS(EA3152_SDRAM_TMRD, HCLK2, MPMC_DYNTMRD_MASK), + LPC31_MPMC_DYNTMRD); + up_udelay(100); + + /* Issue continuous NOP commands */ + + putreg32((MPMC_DYNCONTROL_CE|MPMC_DYNCONTROL_CS|MPMC_DYNCONTROL_INOP), + LPC31_MPMC_DYNCONTROL); + + /* Load ~200us delay value to timer1 */ + + up_udelay(200); + + /* Issue a "pre-charge all" command */ + + putreg32((MPMC_DYNCONTROL_CE|MPMC_DYNCONTROL_CS|MPMC_DYNCONTROL_IPALL), + LPC31_MPMC_DYNCONTROL); + + /* Minimum refresh pulse interval (tRFC) for MT48LC32M16A2=80nsec, + * 100nsec provides more than adequate interval. + */ + + putreg32(NS2HCLKS(EA3152_SDRAM_REFRESH, HCLK, MPMC_DYNREFRESH_TIMER_MASK), + LPC31_MPMC_DYNREFRESH); + + /* Load ~250us delay value to timer1 */ + + up_udelay(250); + + /* Recommended refresh interval for normal operation of the Micron + * MT48LC16LFFG = 7.8125usec (128KHz rate). ((HCLK / 128000) - 1) = + * refresh counter interval rate, (subtract one for safety margin). + */ + + putreg32(NS2HCLKS(EA3152_SDRAM_OPERREFRESH, HCLK, MPMC_DYNREFRESH_TIMER_MASK), + LPC31_MPMC_DYNREFRESH); + + /* Select mode register update mode */ + + putreg32((MPMC_DYNCONTROL_CE|MPMC_DYNCONTROL_CS|MPMC_DYNCONTROL_IMODE), + LPC31_MPMC_DYNCONTROL); + + /* Program the SDRAM internal mode registers on bank nSDCE0 and reconfigure + * the SDRAM chips. Bus speeds up to 90MHz requires use of a CAS latency = 2. + * To get correct value on address bus CAS cycle, requires a shift by 13 for + * 16bit mode + */ + + tmp = getreg32(LPC31_EXTSDRAM0_VSECTION | (0x23 << 13)); + + putreg32((MPMC_DYNCONFIG0_MDSDRAM|MPMC_DYNCONFIG_HP16_32MX16), + LPC31_MPMC_DYNCONFIG0); + putreg32((MPMC_DYNRASCAS0_RAS2CLK|MPMC_DYNRASCAS0_CAS2CLK), + LPC31_MPMC_DYNRASCAS0); + + /* Select normal operating mode */ + + putreg32((MPMC_DYNCONTROL_CE|MPMC_DYNCONTROL_CS|MPMC_DYNCONTROL_INORMAL), + LPC31_MPMC_DYNCONTROL); + + /* Enable buffers */ + + regval = getreg32(LPC31_MPMC_DYNCONFIG0); + regval |= MPMC_DYNCONFIG0_B; + putreg32(regval, LPC31_MPMC_DYNCONFIG0); + + putreg32((MPMC_DYNCONTROL_INORMAL|MPMC_DYNCONTROL_CS), + LPC31_MPMC_DYNCONTROL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc31_meminitialize + * + * Description: + * Initialize external memory resources (sram, sdram, nand, nor, etc.) + * + ****************************************************************************/ + +void lpc31_meminitialize(void) +{ + /* Configure the LCD pins in external bus interface (EBI/MPMC) memory mode. + * + * LCD_CSB -> MPMC_NSTCS_0 + * LCD_DB_1 -> MPMC_NSTCS_1 + * LCD_DB_0 -> MPMC_CLKOUT + * LCD_E_RD -> MPMC_CKE + * LCD_RS -> MPMC_NDYCS + * LCD_RW_WR -> MPMC_DQM_1 + * LCD_DB_2 -> EBI_A_2 + * LCD_DB_3 -> EBI_A_3 l + * LCD_DB_4 -> EBI_A_4 l + * LCD_DB_5 -> EBI_A_5 l + * LCD_DB_6 -> EBI_A_6 + * LCD_DB_7 -> EBI_A_7 + * LCD_DB_8 -> EBI_A_8 + * LCD_DB_9 -> EBI_A_9 + * LCD_DB_10 -> EBI_A_10 + * LCD_DB_11 -> EBI_A_11 + * LCD_DB_12 -> EBI_A_12 + * LCD_DB_13 -> EBI_A_13 + * LCD_DB_14 -> EBI_A_14 + * LCD_DB_15 -> EBI_A_15 + */ + + putreg32(SYSCREG_MUX_LCDEBISEL_EBIMPMC, LPC31_SYSCREG_MUX_LCDEBISEL); + + /* Enable EBI clock */ + + lpc31_enableclock(CLKID_EBICLK); + + /* Enable MPMC controller clocks */ + + lpc31_enableclock(CLKID_MPMCCFGCLK); + lpc31_enableclock(CLKID_MPMCCFGCLK2); + lpc31_enableclock(CLKID_MPMCCFGCLK3); + + /* Enable the external memory controller */ + + putreg32(MPMC_CONTROL_E, LPC31_MPMC_CONTROL); + + /* Force HCLK to MPMC_CLK to 1:1 ratio, little-endian mode */ + + putreg32(0, LPC31_MPMC_CONFIG); + + /* Set MPMC delay based on trace lengths between SDRAM and the chip + * and on the delay strategy used for SDRAM. + */ + + putreg32(EA3152_MPMC_DELAY, LPC31_SYSCREG_MPMC_DELAYMODES); + + /* Configure Micron MT48LC32M16A2 SDRAM on the EA3152 board */ + + lpc31_sdraminitialize(); +} +#endif /* CONFIG_LPC31XX_EXTSDRAM */ |