From 075e370c297aeadb44bb244c4531398d5fd15a6d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 2 Aug 2013 18:30:27 -0600 Subject: [PATCH] Various changes to get SAMA5 SDRAM working. Marginally functional, but there is more to be done --- configs/sama5d3x-ek/README.txt | 34 +++++++++++++++++++------ configs/sama5d3x-ek/src/sam_sdram.c | 39 +++++++++++++++++------------ 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/configs/sama5d3x-ek/README.txt b/configs/sama5d3x-ek/README.txt index 00387fe3e1..b67752680e 100644 --- a/configs/sama5d3x-ek/README.txt +++ b/configs/sama5d3x-ek/README.txt @@ -846,7 +846,10 @@ Configurations 5. SDRAM support can be enabled by adding the following to your NuttX configuration file: + System Type->ATSAMA5 Peripheral Support CONFIG_SAMA5_MPDDRC=y : Enable the DDR controller + + System Type->External Memory Configuration CONFIG_SAMA5_DDRCS=y : Tell the system that DRAM is at the DDR CS CONFIG_SAMA5_DDRCS_SIZE=268435456 : 2Gb DRAM -> 256GB CONFIG_SAMA5_DDRCS_LPDDR2=y : Its DDR2 @@ -855,7 +858,10 @@ Configurations Now that you have SDRAM enabled, what are you going to do with it? One thing you can is add it to the heap + System Type->Heap Configuration CONFIG_SAMA5_DDRCS_HEAP=y : Add the SDRAM to the heap + + Memory Management CONFIG_MM_REGIONS=2 : Two memory regions: ISRAM and SDRAM Another thing you could do is to enable the RAM test built-in @@ -865,9 +871,17 @@ Configurations external SDAM. To do this, keep the SDRAM out of the heap so that it can be tested without crashing programs using the memory: + System Type->Heap Configuration CONFIG_SAMA5_DDRCS_HEAP=n : Don't add the SDRAM to the heap + + Memory Management CONFIG_MM_REGIONS=1 : One memory regions: ISRAM + Then enable the RAM test built-in application: + + Application Configuration->System NSH Add-Ons->Ram Test + CONFIG_SYSTEM_RAMTEST=y + In this configuration, the SDRAM is not added to heap and so is not excessible to the applications. So the RAM test can be freely executed against the SRAM memory beginning at address 0x2000:0000 @@ -885,13 +899,13 @@ Configurations To test the entire external 256MB SRAM: - nsh> ramtest 20000000 268435456 - RAMTest: Marching ones: 60000000 268435456 - RAMTest: Marching zeroes: 60000000 268435456 - RAMTest: Pattern test: 60000000 268435456 55555555 aaaaaaaa - RAMTest: Pattern test: 60000000 268435456 66666666 99999999 - RAMTest: Pattern test: 60000000 268435456 33333333 cccccccc - RAMTest: Address-in-address test: 60000000 268435456 + nsh> ramtest -w 20000000 268435456 + RAMTest: Marching ones: 20000000 268435456 + RAMTest: Marching zeroes: 20000000 268435456 + RAMTest: Pattern test: 20000000 268435456 55555555 aaaaaaaa + RAMTest: Pattern test: 20000000 268435456 66666666 99999999 + RAMTest: Pattern test: 20000000 268435456 33333333 cccccccc + RAMTest: Address-in-address test: 20000000 268435456 STATUS: 2013-7-19: This configuration (as do the others) run at 396MHz. @@ -914,7 +928,11 @@ Configurations configuration needs to be recalibrated. 2013-8-31: SDRAM configuration and RAM test usage are documented, - but untested. + but only partially functional. SDRAM is accessible but many regions + on the SDRAM fail the RAM test. Most likely there is some error in + the SDRAM timing configuration. I am also seeing occasional crashes + involving unexpected interrupts and the UART when running the RAM + test. Not sure what to make of that yet ostest: This configuration directory, performs a simple OS test using diff --git a/configs/sama5d3x-ek/src/sam_sdram.c b/configs/sama5d3x-ek/src/sam_sdram.c index e78d07d39a..cfa4ef426e 100644 --- a/configs/sama5d3x-ek/src/sam_sdram.c +++ b/configs/sama5d3x-ek/src/sam_sdram.c @@ -162,14 +162,14 @@ void sam_sdram_config(void) /* Enable DDR clocking */ regval = getreg32(SAM_PMC_SCER); - regval |= SAM_PMC_SCER; + regval |= PMC_DDRCK; putreg32(regval, SAM_PMC_SCER); /* Clear the low power register */ putreg32(0, SAM_MPDDRC_LPR); - /* Enabled autofresh during calibration (undocumented) */ + /* Enable autofresh during calibration (undocumented) */ regval = getreg32(SAM_MPDDRC_HS); regval |= MPDDRC_HS_AUTOREFRESH_CAL; @@ -194,7 +194,7 @@ void sam_sdram_config(void) regval = MPDDRC_DLL_MOR_MOFF(7) | /* DLL Master Delay Line Offset */ MPDDRC_DLL_MOR_CLK90OFF(31) | /* DLL CLK90 Delay Line Offset */ MPDDRC_DLL_MOR_SELOFF | /* DLL Offset Selection */ - MPDDRC_DLL_MOR_KEY | /* Undocumented key */ + MPDDRC_DLL_MOR_KEY; /* Undocumented key */ putreg32(regval, SAM_MPDDRC_DLL_MOR); /* Configure the I/O calibration register */ @@ -320,12 +320,12 @@ void sam_sdram_config(void) * min 18ns */ MPDDRC_TPR2_TRTP(2) | /* Four Active Windows: * 2 * 7.5 = 15 ns (min 7.5ns) */ - MPDDRC_TPR2_TFAW(10) ; + MPDDRC_TPR2_TFAW(10); putreg32(regval, SAM_MPDDRC_TPR2); /* DDRSDRC Low-power Register */ - sam_sdram_delay(13200); + sam_sdram_delay(13300); regval = MPDDRC_LPR_LPCB_DISABLED | /* Low-power Feature is inhibited */ MPDDRC_LPR_TIMEOUT_0CLKS | /* Activates low-power mode after the end of transfer */ @@ -345,7 +345,14 @@ void sam_sdram_config(void) *ddr = 0; - /* Now clocks which drive DDR2-SDRAM device are enabled.*/ + /* Now clocks which drive DDR2-SDRAM device are enabled. + * + * A minimum pause of 200 usec is provided to precede any signal toggle. + * (6 core cycles per iteration, core is at 396MHz: min 13200 loops) + */ + + sam_sdram_delay(13300); + /* Step 4: An NOP command is issued to the DDR2-SDRAM */ putreg32(MPDDRC_MR_MODE_NOP, SAM_MPDDRC_MR); @@ -379,7 +386,7 @@ void sam_sdram_config(void) */ putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA1)) = 0; + *((volatile uint8_t *)(ddr + DDR2_BA1)) = 0; /* Wait 2 cycles min */ @@ -392,20 +399,20 @@ void sam_sdram_config(void) * set to 1. */ - putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA1 + DDR2_BA0)) = 0; + putreg32(MPDDRC_MR_MODE_LMR, SAM_MPDDRC_MR); + *((volatile uint8_t *)(ddr + DDR2_BA1 + DDR2_BA0)) = 0; /* Wait 2 cycles min */ sam_sdram_delay(100); - /* Step 8: An Extended Mode Register set (EMRS1) cycle is issued to enable DLL. - * - * The write address must be chosen so that BA[1] is set to 0 and BA[0] is set to 1. - */ + /* Step 8: An Extended Mode Register set (EMRS1) cycle is issued to enable DLL. + * + * The write address must be chosen so that BA[1] is set to 0 and BA[0] is set to 1. + */ putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA0)) = 0; + *((volatile uint8_t *)(ddr + DDR2_BA0)) = 0; /* An additional 200 cycles of clock are required for locking DLL */ @@ -505,7 +512,7 @@ void sam_sdram_config(void) */ putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA0)) = 0; + *((volatile uint8_t *)(ddr + DDR2_BA0)) = 0; /* Wait 2 cycles min */ @@ -529,7 +536,7 @@ void sam_sdram_config(void) */ putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA0)) = 0; + *((volatile uint8_t *)(ddr + DDR2_BA0)) = 0; /* Wait 2 cycles min */