iMX SDRAM controller enter manual self-refresh? (ENGcm1238)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX SDRAM controller enter manual self-refresh? (ENGcm1238)

1,004 Views
andrew_questps
Contributor III

I am attempting to place an iMX25 SDRAM into manual self-refresh mode, reset the PLL and then set the SDRAM controller back into normal mode.

As soon as I attempt to place the SDRAM controller into manual-self refresh the CPU locks up and the watchdog resets the device.

Here is the code I am using:

LEAF_ENTRY OALCPUEnterSuspend

    mov     r0,#0     mcr     p15, 0, r0, c7, c0, 4               ; Enter WFI

    ; Exit Wait For Interrupt set SDRAM to manual self-refresh

    ldr     r1, =CSP_BASE_REG_PA_ESDCTL     ldr     r2, =CSP_BASE_MEM_PA_CSD0

    ; Set precharge command     ldr     r0, =0x93118880     str     r0, [r1, #ESDRAMC_ESDCTL0_OFFSET]

    ; Access SDRAM with A10 high to precharge all banks     ldr     r0, =0x0     strb    r0, [r2, #0x400]

    ; Set manual refresh command     ldr     r0, =0xC3118880     str     r0, [r1, #ESDRAMC_ESDCTL0_OFFSET]

    ; Wait for more than 400 us     ldr     r3, =0x20000 wait     subs    r3, r3, #1     bne     wait

    ; Configure Clock Control Register     ;   Configure ARM and AHB Clock     ;     ;   ARM Clock 399Mhz = MCUPLL * DIVGEN / ARM_DIVIDER     ;                    = 532Mhz * 0.75   / 1     ;                    = 399 Mhz     ;       ARM_DIVIDER (0 << 30)   = 0x00000000     ;       ARM_SRC     (1 << 14)   = 0x00004000     ;     ;   AHB Clock 133Mhz = ARMCLK / AHB_DIVIDER     ;                    = 399Mhz / 3     ;                    = 133 Mhz     ;       AHB_DIVIDER (2 << 28)   = 0x20000000     ;     ;   USB Clock 60Mhz =  UPLL  / USB_DIVIDER     ;                   = 240Mhz / 4     ;                   = 60Mhz     ;       USB_DIVIDER (3 << 16)   = 0x00030000     ;     ;   USB PLL Enable (0 << 23)    = 0x00000000     ;   MPLL and UPLL reset (3<<26) = 0x0C000000     ;   LP CTL (0<<24)              = 0x00000000     ;                               -------------     ;                                 0x2C034000     ldr     r0, =0x2C034000

    ldr     r4, =10000

    ; Wait PLL statibilisation waitClock     sub r4, r4, #1     cmp r4, #0     bne waitClock

    ; Now wait the MPLL is reset, so wait on the MPLL lock bit WaitForMPLL     ldr     r0, [r1, #CRM_MPCTL_OFFSET]     tst     r0, #MPLL_LOCK_FLAG     beq     WaitForMPLL

    ; Now wait the UPLL is reset, so wait on the UPLL lock bit WaitForUPLL     ldr     r0, [r1, #CRM_UPCTL_OFFSET]     tst     r0, #UPLL_LOCK_FLAG     beq     WaitForUPLL

  

    ; Set normal mode command

    ldr     r0, =0x83218880

    str     r0, [r1, #ESDRAMC_ESDCTL0_OFFSET]

    RETURN

    LEAF_ENTRY OALCPUEnterSuspend_sz     ;Entry used to calculate the size of the function     nop     nop     ENTRY_END

    END

Does anyone know what I need to change to get this working?

Cheers,

Andre

Labels (2)
0 Kudos
3 Replies

725 Views
JerryFan
NXP Employee
NXP Employee

Just a reminder: the code was expected running on some non-SDRAM memory, such as internal ram or cache.

0 Kudos

725 Views
andrew_questps
Contributor III

Chongbin Fan wrote:

Just a reminder: the code was expected running on some non-SDRAM memory, such as internal ram or cache.

I know I am doing the following in power.c

VOID OALCPUPowerOff(void)

{

    void (*suspend_func_ptr)();

    int suspend_func_size;

....

    // Need to keep the following clocks gated on for successful handshake

....

    // copy the suspend routine into IRAM

    suspend_func_ptr = (void*)OALPAtoCA(IMAGE_WINCE_IRAM_PA_START);

    suspend_func_size = (UINT32)OALCPUEnterSuspend_sz - (UINT32)OALCPUEnterSuspend + 256;  //include constants

    memcpy(suspend_func_ptr, OALCPUEnterSuspend, suspend_func_size );

    // Enter wait-for-interrupt mode and the system will transition

    // to the low-power mode configured in the CCMR above.

    // OALCPUEnterWFI();

    suspend_func_ptr();

    // exiting suspend

    if (dwSdmaStat)

    {

        OUTREG32(&g_pSDMA->HSTART, dwSdmaStat);

    }

}  

If I comment out the rest of the code except for the two lines:

    mov     r0,#

    mcr     p15, 0, r0, c7, c0, 4               ; Enter WFI 

and return it works OK, it's only when I attempt to access any of the SDRAM control registers.

0 Kudos

725 Views
JerryFan
NXP Employee
NXP Employee

"it's only when I attempt to access any of the SDRAM control registers."

Please make sure 256 is big enough to consisted of the "CSP_BASE_REG_PA_ESDCTL" stuff which was expected at the end of the function, but not sure. You can dump the image and double check.