This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x DeepSleep0 Resume Issue

Other Parts Discussed in Thread: AM3352

I may be missing something, but there appears to be a memory type definition mismatch between the AM335x EMIF and the definitions used by the CM3 PM processor.

From AM335x TRM

And from src/include/msg.h of the AMX3-CM3 wakeup M3 processor firmware source code:

/* Board specifics populated in IPC_REG4 */
extern int mem_type;        /* Memory Type 2 = DDR2, 3 = DDR3, 4 = LPDDR2 */

It looks to me like am33xx_pm_set_ipc_ops() in arch/arm/mach-omap2/pm33xx.c

calls   ti_emif_get_mem_type() in drivers/memory/ti-emif-pm.c

and extracts the memory type directly from the EMIF register and from there

wkup_m3_set_mem_type() in drivers/soc/ti/wkup_m3_ipc.c

sets m3_ipc_state.mem_type which gets passed to the CM3 processor via IPC message

at Suspend time. If I hard code m3_ipc_state.mem_type to 4, Suspend/Resume works normally.

Otherwise, the AM3352 cannot resume if left suspended more than about a minute.

I see that Dave Gerlach seems to have done a lot of work in this code, so perhaps we can get him to address this.

There is a related patch 0001-CM3-ddr-Split-335x-and-437x-ddr-io-ctrl-handling.patch,

but I don't see how that addresses this apparent memory type definition mismatch.

I am using the CM3 firmware version 0x191 and the kernel from TI Processor SDK 2.0.1. It does not appear that there have been changes in this functionality between TI Processor SDK 2.0.1 and TI Processor SDK 2.0.2.

Best Regards,

Paul

  • I inserted a screenshot of the reg_sdram_type field definitions from the EMIF SDRAM_CONFIG register after
    "From AM335x TRM", hopefully this is just being checked out by the moderators and will show up in my posting later. Otherwise, here is the text:
    SDRAM_CONFIG
    reg_sdram_type, bits 31..29
    SDRAM Type selection.
    Set to 0 for DDR1, set to 1 for LPDDR1, set to 2 for DDR2, set to 3 for DDR3.
  • Is your silicon PG1.0 or PG 2.1?  It should print out in u-boot.

    Paul26 said:
    Set to 0 for DDR1, set to 1 for LPDDR1, set to 2 for DDR2, set to 3 for DDR3.

    And you're setting this to a value of 4?  That's a reserved value.

  • You made a reference to the patch mentioned here:

    processors.wiki.ti.com/.../Debugging_AM335x_Suspend-Resume_Issues

    Have you merged that patch? If not, please do.
  • According to the Linux boot trace, it is ES2.1.

    That setting of 4 is for the message sent to the M3 processor doing the PM overseeing.

    As I mentioned, this is from the CM3 PM firmware:
    /* Board specifics populated in IPC_REG4 */
    extern int mem_type; /* Memory Type 2 = DDR2, 3 = DDR3, 4 = LPDDR2 */

    I'm troubled by the apparent disconnect between the two definitions.

    The value retrieved from the EMIF is indeed 1, but the wakeup M3 processor firmware thinks LPDDR is type 4.

  • Ah, now I'm starting to understand your confusion. No, the setting of 4 is for LPDDR2 which is a supported memory type on the AM437x. The correct setting for LPDDR is 1.

    Have you applied the patch I mentioned? I worked with Dave on developing that patch, and although we had considered the impact to LPDDR, we did not have a development board on which to test it! So it's possible we may have screwed it up... Are you able to connect with JTAG after a failed suspend and look at the SDRAM_CONFIG register?
  • For greater context, the main reason we're looking at MEM_TYPE at all relates to Advisory 1.0.17 VDDS_DDR: High-Power Consumption During DeepSleep0. That advisory only applies in the case of PG1.0 silicon where you're using either DDR2 or DDR3 memory. We condition upon PG1.0 && (DDR2 || DDR3). If we meet those criteria, then we set MDDR_SEL during suspend, and we clear it during resume. In your case we should not be touching that bit, in which case it should remain set all the time.
  • We set MDDR_SEL in u-boot and don't touch it after that. I had been suspecting that maybe MDDR_SEL bit was getting lost in the suspend/resume cycle, but as you say, that bit should not get touched by the M3 firmware for our ES2.1 silicon regardless of the memory type.

    I am now wondering if what is helping when I set mem_type = 4, is the pulldowns mentioned here (from ddr_io_suspend() in ddr.c):

    /* Additional weak pull down for DQ, DM */

    __raw_writel(SUSP_IO_PULL_DATA, DDR_DATA2_IOCTRL);

    __raw_writel(SUSP_IO_PULL_DATA, DDR_DATA3_IOCTRL);

    __raw_writel(SUSP_IO_PULL_CMD1_LPDDR2, DDR_CMD1_IOCTRL);

    __raw_writel(SUSP_IO_PULL_CMD2_LPDDR2, DDR_CMD2_IOCTRL);

    The first two registers do not exist in our AM3352, but maybe one of the last two puts a pulldown on CKE, which the Micron data sheet says needs to be kept low for the self-refresh period. We do not have an external pulldown, and I don't know if the EMIF otherwise pulls this down for suspend in our configuration. I did not decipher the DDR PHY to IO Pin Mapping yet, but I think I see that at least some bit in CMD2 does control ddr_cke.

    The other thing I found is a statement that CONTROL_EMIF_SDRAM_CONFIG exports SDRAM configuration to the EMIF after resuming from low power scenarios and that it should be set to the same value as SDRAM _CONFIG during DDR initialization. Our SDRAM configuration is set by u-boot and we do not touch this other register as far as I can remember. Since EMIF is in the PER power domain, its settings should not be lost.

    Keep in mind that we are only attempting standby, and with no PMIC we do not cut any power rails.

    Best Regards,

    Paul

  • Please revert your mem_type change and apply the patch I mentioned.

  • Hi Brad,

    I was able to build the PM firmware 0x191 and reproduce all the behaviors above.
    Then I applied the patch mentioned and reverted my hack of setting mem_type to 4 (LPDDR2).
    The board does Resume successfully with this configuration.

    I then decoded the DDR PHY control bits and changed only the weak pulldown on CKE to NO pullup/pulldown on CKE.
    With that build, the board could not successfully Resume after suspending for a few minutes.
    When I changed just that one bit back to a weak pulldown on CKE, Resume works again.

    The Micron data sheet for the LPDDR mentions that this pin needs to be kept low during self-refresh.

    #define AM335X_SUSP_IO_PULL_CMD2 0xFFA0098B <=== original good value from patch
    #define AM335X_SUSP_IO_PULL_CMD2 0xFF80098B <=== changing CKE to NO pullup/pulldown


    So I believe that I have a good fix and know the root cause of the problem.

    Thank you for your assistance.

    Hopefully others with mDDR/LPDDR Suspend/Resume problems will be able to find this thread, as it seems my description was incorrect.

    I always thought that the mentioned patch would be relevant to our board, but I was wrong about why. I thought maybe we were losing the MDDR_SEL bit which caused us so much trouble when we were trying to get u-boot running on our board.

    Best Regards,
    Paul

  • Thanks for the follow-up info. I agree the root cause was the lack of pulldown on CKE, which was fixed by the patch. I hope you don't mind, but I renamed the thread to hopefully make it easier for people having similar issues to find this info.
  • I'm glad you could rename the thread.

    I wonder if the posting time stamps should show the correct local time?