nuttx/configs/open1788/src/lpc17_sdraminitialize.c

238 lines
8.7 KiB
C

/************************************************************************************
* configs/open1788/src/lpc17_sdraminitialize.c
* arch/arm/src/board/lpc17_sdraminitialize.c
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include "up_arch.h"
#include "up_internal.h"
#include "chip/lpc17_syscon.h"
#include "lpc17_emc.h"
#include "open1788.h"
#if defined(CONFIG_LPC17_EMC) && defined(CONFIG_LPC17_EXTDRAM)
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* The core clock is LPC17_EMCCLK which may be either LPC17_CCLK* (undivided), or
* LPC17_CCLK / 2 as determined by settings in the board.h header file.
*
* For example:
* LPC17_CCLCK = 120,000,000
* EMCCLKSEL -> LPC17_CCLK divided by 2
* LPC17_EMCCLK = 60,000,000
* LPC17_EMCCLK_MHZ = 60 (Rounded to an integer)
* EMC_NSPERCLK = 16.667 (Represented with 4 bits of fraction, 267)
*
* EMC_NS2CLK(63) = ((63 << 4) + 266) / 267 = 4 (actual 3.78)
* EMC_NS2CLK(20) = ((20 << 4) + 266) / 267 = 2 (actual 1.20)
*/
#define LPC17_EMCCLK_MHZ ((LPC17_EMCCLK + 500000) / 1000000)
#define EMC_NSPERCLK_B4 (((1000 << 4) + (LPC17_EMCCLK_MHZ >> 1)) / LPC17_EMCCLK_MHZ)
#define EMC_NS2CLK(ns) (((ns << 4) + (EMC_NSPERCLK_B4 - 1)) / EMC_NSPERCLK_B4)
#define MDKCFG_RASCAS0VAL 0x00000303
/* Set up for 32-bit SDRAM at CS0 */
#ifdef CONFIG_LPC17_EXTDRAMSIZE
# define SDRAM_SIZE CONFIG_LPC17_EXTDRAMSIZE
#endif
#ifdef CONFIG_LPC17_SDRAM_16BIT
# ifndef SDRAM_SIZE
# define SDRAM_SIZE 0x02000000 /* 256Mbit */
# endif
#else /* if defined(CONFIG_LPC17_SDRAM_32BIT) */
# undef CONFIG_LPC17_SDRAM_32BIT
# define CONFIG_LPC17_SDRAM_32BIT 1
# ifndef SDRAM_SIZE
# define SDRAM_SIZE 0x04000000 /* 512Mbit */
# endif
#endif
#define SDRAM_BASE 0xa0000000 /* CS0 */
/************************************************************************************
* Private Functions
************************************************************************************/
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: open1788_sdram_initialize
*
* Description:
* Initialize SDRAM
*
************************************************************************************/
void open1788_sdram_initialize(void)
{
uint32_t regval;
int i;
/* Reconfigure delays:
*
* CMDDLY: Programmable delay value for EMC outputs in command delayed
* mode. The delay amount is roughly CMDDLY * 250 picoseconds.
* FBCLKDLY: Programmable delay value for the feedback clock that controls
* input data sampling. The delay amount is roughly (FBCLKDLY+1) * 250
* picoseconds.
* CLKOUT0DLY: Programmable delay value for the CLKOUT0 output. This would
* typically be used in clock delayed mode. The delay amount is roughly
* (CLKOUT0DLY+1) * 250 picoseconds.
* CLKOUT1DLY: Programmable delay value for the CLKOUT1 output. This would
* typically be used in clock delayed mode. The delay amount is roughly
* (CLKOUT1DLY+1) * 250 picoseconds.
*/
regval = SYSCON_EMCDLYCTL_CMDDLY(32) |
SYSCON_EMCDLYCTL_FBCLKDLY(32) |
SYSCON_EMCDLYCTL_CLKOUT0DLY(1) |
SYSCON_EMCDLYCTL_CLKOUT1DLY(1);
putreg32(regval, LPC17_SYSCON_EMCDLYCTL);
/* Configure the SDRAM */
putreg32( EMC_NS2CLK(20), LPC17_EMC_DYNAMICRP); /* TRP = 20 nS */
putreg32( 15, LPC17_EMC_DYNAMICRAS); /* RAS = 42ns to 100K ns, */
putreg32( 0, LPC17_EMC_DYNAMICSREX); /* TSREX = 1 clock */
putreg32( 1, LPC17_EMC_DYNAMICAPR); /* TAPR = 2 clocks? */
putreg32(EMC_NS2CLK(20) + 2, LPC17_EMC_DYNAMICDAL); /* TDAL = TRP + TDPL = 20ns + 2clk */
putreg32( 1, LPC17_EMC_DYNAMICWR); /* TWR = 2 clocks */
putreg32( EMC_NS2CLK(63), LPC17_EMC_DYNAMICRC); /* H57V2562GTR-75C TRC = 63ns(min)*/
putreg32( EMC_NS2CLK(63), LPC17_EMC_DYNAMICRFC); /* H57V2562GTR-75C TRFC = TRC */
putreg32( 15, LPC17_EMC_DYNAMICXSR); /* Exit self-refresh to active */
putreg32( EMC_NS2CLK(63), LPC17_EMC_DYNAMICRRD); /* 3 clock, TRRD = 15ns (min) */
putreg32( 1, LPC17_EMC_DYNAMICMRD); /* 2 clock, TMRD = 2 clocks (min) */
/* Command delayed strategy, using EMCCLKDELAY */
putreg32(EMC_DYNAMICREADCONFIG_RD_CMD, LPC17_EMC_DYNAMICREADCONFIG);
/* H57V2562GTR-75C: TCL=3CLK, TRCD = 20ns(min), 3 CLK = 24ns */
putreg32(MDKCFG_RASCAS0VAL, LPC17_EMC_DYNAMICRASCAS0);
#ifdef CONFIG_LPC17_SDRAM_16BIT
/* For Manley lpc1778 SDRAM: H57V2562GTR-75C, 256Mb, 16Mx16, 4 banks, row=13, column=9:
*
* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC
*/
putreg32(EMC_DYNAMICCONFIG_MD_SDRAM | EMC_DYNAMICCONFIG_AM0(13),
LPC17_EMC_DYNAMICCONFIG0);
#elif defined CONFIG_LPC17_SDRAM_32BIT
/* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
putreg32(EMC_DYNAMICCONFIG_MD_SDRAM | EMC_DYNAMICCONFIG_AM0(13) | EMC_DYNAMICCONFIG_AM1,
LPC17_EMC_DYNAMICCONFIG0);
#endif
up_mdelay(100);
/* Issue NOP command */
putreg32(EMC_DYNAMICCONTROL_CE | EMC_DYNAMICCONTROL_CS | EMC_DYNAMICCONTROL_I_NOP,
LPC17_EMC_DYNAMICCONTROL);
/* Wait 200 Msec */
up_mdelay(200);
/* Issue PALL command */
putreg32(EMC_DYNAMICCONTROL_CE | EMC_DYNAMICCONTROL_CS | EMC_DYNAMICCONTROL_I_PALL,
LPC17_EMC_DYNAMICCONTROL);
putreg32(2, LPC17_EMC_DYNAMICREFRESH); /* ( n * 16 ) -> 32 clock cycles */
/* Wait 128 AHB clock cycles */
for (i = 0; i < 128; i++);
/* 64ms/8192 = 7.8125us, nx16x8.33ns < 7.8125us, n < 58.6*/
regval = 64000000 / (1 << 13);
regval -= 16;
regval >>= 4;
regval = regval * LPC17_EMCCLK_MHZ / 1000;
putreg32(regval, LPC17_EMC_DYNAMICREFRESH);
/* Issue MODE command */
putreg32(EMC_DYNAMICCONTROL_CE | EMC_DYNAMICCONTROL_CS | EMC_DYNAMICCONTROL_I_MODE,
LPC17_EMC_DYNAMICCONTROL);
#ifdef CONFIG_LPC17_SDRAM_16BIT
(void)getreg16(SDRAM_BASE | (0x33 << 12)); /* 8 burst, 3 CAS latency */
#elif defined CONFIG_LPC17_SDRAM_32BIT
(void)getreg32(SDRAM_BASE | (0x32 << 13)); /* 4 burst, 3 CAS latency */
#endif
/* Issue NORMAL command */
putreg32(EMC_DYNAMICCONTROL_I_NORMAL, LPC17_EMC_DYNAMICCONTROL);
/* Enable buffer */
regval = getreg32(LPC17_EMC_DYNAMICCONFIG0);
regval |= EMC_DYNAMICCONFIG_B;
putreg32(regval, LPC17_EMC_DYNAMICCONFIG0);
up_mdelay(12);
regval = getreg32(LPC17_SYSCON_EMCDLYCTL);
regval &= ~SYSCON_EMCDLYCTL_CMDDLY_MASK;
regval |= SYSCON_EMCDLYCTL_CMDDLY(18);
putreg32(regval, LPC17_SYSCON_EMCDLYCTL);
}
#endif /* CONFIG_LPC17_EMC && CONFIG_LPC17_EXTDRAM */