[This is a re-post of https://stackoverflow.com/q/5346225/69172]
I'm new to iMX31 and embedded systems, please help me to understand the translation from SDRAM address to ARM CPU address, especially in "special" command modes of the SDRAM controller.
Here is the SDRAM initialization code I have problem with:
ldr r0, ESDCTL_BASE_W
mov r2, #SDRAM_BASE_ADDR /* 0x80000000 */
ldr r1, =0x92100000 /* Precharge */
str r1, [r0]
ldr r1, =0x0
ldr r12, =0x80000F00
str r1, [r12]
ldr r1, =0xA2100000 /* Auto-refresh */
str r1, [r0]
ldr r1, =0x0
str r1, [r2]
ldr r1, SDRAM_0xB2100000 /* Load Mode Register */
str r1, [r0]
ldr r1, =0x0
strb r1, [r2, #0x33]
ldr r1, =0xFF
ldr r12, =0x81000000
The RAM I have is Micron LPDDR MT46H64M32LF, and this code follows the initialization procedure nicely, but in PRECHARGE step, where is the address 0x80000F00
coming from?
From iMX31 reference manual I learned that during the PRECHARGE step, I need to set SDRAM pin A10
to HIGH which will therefore result a PRECHARGE ALL. Here is the text on PRECHARGE from RM:
...While in this mode, an access (either read or write) to the SDRAM/LPDDR address space will generate a precharge command cycle. SDRAM/LPDDR address bit A10 determines whether a single bank, or all banks, are precharged by the command. Accessing an address with the SDRAM/LPDDR address A10 low will precharge only the bank selected by the bank addresses, as illustrated in Figure 19-75. Conversely, accesses with A10 high will precharge all banks regardless of the bank address, ...Note that A10 is the SDRAM pin, not the A10 bit ARM address bus. Translation of the SDRAM A10 to the corresponding ARM address is dependent on the memory configuration.
And here is another text on multiplexed address bus during “special” mode:
During “special” mode, for example, precharge mode (SMODE=1) or load mode registers (SMODE=3) there is no address shifting, means that CPU address A0 is mapped on MA0 at all memory width. For example, in order to drive MA10 bit (for the precharge all command) the CPU A10 bit should be set (for both 16 or 32 bit external devices). The same logic is valid for the load mode register command, as can be seen on the initialization routine example on Section 19.5.4.1, “SDRAM Initialization.”
According to the text above and assuming A0 is the first bit of 0x80000000
, setting A10 to 1 should give address 0x80000400
, not the 0x80000F00
in the code. Why???
The code snippet I showed here is supposed to work with DDR. For SDRAM, it actually uses 0x80000400
in PRECHARGE.
Is there anything related to the characteristics of DDR? And how can I get the proper translation between SDRAM pins and ARM CPU address?