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.

RTOS: can secure OMAP go to deepsleep mode?

Other Parts Discussed in Thread: OMAPL138, OMAP-L138

Tool/software: TI-RTOS

Hi,

My projecy use OMAPL138. And it turn to deepsleep mode and wakeup ok. But when I replace normal OMAPL138 by secure OMAPL138, it cannot turn to deepsleep mode. The secure OMAP is unlocked and debug by jtag, but when turn to deepsleep, it stop at   " while (pscstatus);"

Here is my code

uint32_t savePinMux;
    uint32_t pscstatus;
    uint32_t count;

    // Unlock PLL configuration
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_CFGCHIP0) &=
                                               ~SYSCFG_CFGCHIP0_PLL_MASTER_LOCK;
    /* Clear PLL lock bit */
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_CFGCHIP3) &=
                                              ~SYSCFG_CFGCHIP3_PLL1_MASTER_LOCK;

    // Config GP0[8] - DEEPSLEEP pin - pin number 9
    // Ensure DEEPSLEEP pin is pinmux to DEEPSLEEP function
    savePinMux = HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0));
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = PINMUX0_31_28_DEEPSLEEP & \
                                                                     savePinMux;

    // Clear self refresh/low power (SR_PD) bit to 0
    HWREG(SOC_DDR2_0_CTRL_REGS + DDR2_MDDR_SDRCR) &= ~DDR2_MDDR_SDRCR_SR_PD;

    // Set the low power mode enable
    HWREG(SOC_DDR2_0_CTRL_REGS + DDR2_MDDR_SDRCR) |= DDR2_MDDR_SDRCR_LPMODEN;

    // Shut off MCLK by set MCLKSTOPEN to 1
    HWREG(SOC_DDR2_0_CTRL_REGS + DDR2_MDDR_SDRCR) |= DDR2_MDDR_SDRCR_MCLKSTOPEN;

    // wait 150 CPU clock to allow MCLK to stop
    for(count = 0; count < MCLK_STOP_TIME_DELAY; count++)
    {
        asm(" nop");
    }

    // Disable VCLK of SDRAM (For self-refresh mode)
    // Turn off PSC for DDR2

    // Wait for any previously initiated transitions
    HWREG(SOC_PSC_1_REGS +  PSC_MDCTL(HW_PSC_DDR2_MDDR)) = (PSC_MDCTL_NEXT_DISABLE & PSC_MDCTL_NEXT);

    HWREG(SOC_PSC_1_REGS + PSC_PTCMD) = PSC_PTCMD_GO0;
    do
    {
        pscstatus = HWREG(SOC_PSC_1_REGS + PSC_PTSTAT) & PSC_PTSTAT_GOSTAT0;
    }
    while (pscstatus);


    // Recheck status
    pscstatus = PSC_MDCTL_NEXT_DISABLE & PSC_MDCTL_NEXT;
    while ((HWREG(SOC_PSC_1_REGS + PSC_MDSTAT(HW_PSC_DDR2_MDDR)) & PSC_MDSTAT_STATE) != pscstatus);

    /* PLLENSRC must be cleared before PLLEN bit have any effect */
    HWREG(SOC_PLLC_0_REGS + PLLC_PLLCTL) &= ~PLLC_PLLCTL_PLLENSRC;

    // PLLEN = 0 put pll in bypass mode in PLL0
    HWREG(SOC_PLLC_0_REGS + PLLC_PLLCTL) &= ~PLLC_PLLCTL_PLLEN;

    // Wait 4 cycle OSCIN
    for(count = 0; count < PLLEN_MUX_SWITCH; count++)
    {
        asm(" nop");
    }

    // PLLPWRDN = 1 in PLL0
    HWREG(SOC_PLLC_0_REGS + PLLC_PLLCTL) |= PLLC_PLLCTL_PLLPWRDN;

    /* PLLENSRC must be cleared before PLLEN has any effect*/
    HWREG(SOC_PLLC_1_REGS + PLLC_PLLCTL) &= ~PLLC_PLLCTL_PLLENSRC;

    // PLLEN = 0 put pll in bypass mode in PLL1
    HWREG(SOC_PLLC_1_REGS + PLLC_PLLCTL) &= ~PLLC_PLLCTL_PLLEN;

    // Wait 4 cycle OSCIN
    for(count = 0; count < PLLEN_MUX_SWITCH; count++)
    {
        asm(" nop");
    }

    // PLLPWRDN = 1 in PLL1
    HWREG(SOC_PLLC_1_REGS + PLLC_PLLCTL) |= PLLC_PLLCTL_PLLPWRDN;

    // Config delay in the SLEEPCOUNT bit (ex: 0x0F)
    HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_DEEPSLEEP) = \
                               ((HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_DEEPSLEEP) &
                                       ~SYSCFG1_DEEPSLEEP_SLEEPCOUNT) | 0x000F);

    // Set SLEEPENABLE bit in DEEPSLEEP to 1
    HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_DEEPSLEEP)|=SYSCFG1_DEEPSLEEP_SLEEPENABLE;

    // Polling bit SLEEPCOMPLETE
    while (0 == (SYSCFG1_DEEPSLEEP_SLEEPCOMPLETE & HWREG(SOC_SYSCFG_1_REGS +
                                                            SYSCFG1_DEEPSLEEP)))
    {
    }

    // Clear SLEEPENABLE bit in DEEPSLEEP to 0
    HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_DEEPSLEEP) &= \
                                                 ~SYSCFG1_DEEPSLEEP_SLEEPENABLE;

    // Clear PLLRST bit in PLLCTL to 0
    HWREG(SOC_PLLC_0_REGS + PLLC_PLLCTL) &= ~PLLC_PLLCTL_PLLRST;

    // Clear PLLPWRDN bit in PLLCTL
    HWREG(SOC_PLLC_0_REGS + PLLC_PLLCTL) &= ~PLLC_PLLCTL_PLLPWRDN;

    // Set PLLRST bit in PLLCTL to 1 - out of reset
    HWREG(SOC_PLLC_0_REGS + PLLC_PLLCTL) |= PLLC_PLLCTL_PLLRST;

    // Clear PLLRST bit in PLLCTL to 0
    HWREG(SOC_PLLC_1_REGS + PLLC_PLLCTL) &= ~PLLC_PLLCTL_PLLRST;

    // Clear PLLPWRDN bit in PLLCTL
    HWREG(SOC_PLLC_1_REGS + PLLC_PLLCTL) &= ~PLLC_PLLCTL_PLLPWRDN;

    // Set PLLRST bit in PLLCTL to 1 - out of reset
    HWREG(SOC_PLLC_1_REGS + PLLC_PLLCTL) |= PLLC_PLLCTL_PLLRST;

    // Wait for PLL to lock
    for(count = 0; count < PLL_LOCK_TIME_CNT; count++)
    {
        asm(" nop");
    }

    // Set the PLLEN bit in PLLCTL to 1 - remove bypass mode
    HWREG(SOC_PLLC_0_REGS + PLLC_PLLCTL) |= PLLC_PLLCTL_PLLEN;

    // Set the PLLEN bit in PLLCTL to 1 - remove bypass mode
    HWREG(SOC_PLLC_1_REGS + PLLC_PLLCTL) |= PLLC_PLLCTL_PLLEN;

    /* set PLL lock bit */
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_CFGCHIP0) |=
                                     (0x01 << SYSCFG_CFGCHIP0_PLL_MASTER_LOCK_SHIFT )
                                      & SYSCFG_CFGCHIP0_PLL_MASTER_LOCK ;

    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_CFGCHIP3) &= CLK_PLL0_SYSCLK3;

    /* set PLL lock bit */
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_CFGCHIP3) |=
    (0x1 << SYSCFG_CFGCHIP3_PLL1_MASTER_LOCK_SHIFT)
        & SYSCFG_CFGCHIP3_PLL1_MASTER_LOCK ;

    // Enable VCLK of SDRAM
    HWREG(SOC_PSC_1_REGS +  PSC_MDCTL(HW_PSC_DDR2_MDDR)) = (PSC_MDCTL_NEXT_ENABLE & PSC_MDCTL_NEXT);

    HWREG(SOC_PSC_1_REGS + PSC_PTCMD) = PSC_PTCMD_GO0;
    do
    {
        pscstatus = HWREG(SOC_PSC_1_REGS + PSC_PTSTAT) & PSC_PTSTAT_GOSTAT0;
    }
    while (pscstatus);

    // Recheck status
    pscstatus = PSC_MDCTL_NEXT_ENABLE & PSC_MDCTL_NEXT;
    while ((HWREG(SOC_PSC_1_REGS + PSC_MDSTAT(HW_PSC_DDR2_MDDR)) & PSC_MDSTAT_STATE) != pscstatus);

    // Set RESET_PHY bit in DDR PHY
    HWREG(SOC_DDR2_0_CTRL_REGS + DDR2_MDR_DRPYCRC) |= \
                                                    DDR2_MDDR_DRPYRCR_RESET_PHY;
    while(DDR2_MDDR_DRPYRCR_RESET_PHY & \
                                HWREG(SOC_DDR2_0_CTRL_REGS + DDR2_MDR_DRPYCRC));

    // Clear MCLKSTOPEN bit in SDRCR
    HWREG(SOC_DDR2_0_CTRL_REGS + DDR2_MDDR_SDRCR) &= \
                                                    ~DDR2_MDDR_SDRCR_MCLKSTOPEN;

    // Disable Self refresh rate
    // clear the low power mode
    HWREG(SOC_DDR2_0_CTRL_REGS + DDR2_MDDR_SDRCR) &= ~DDR2_MDDR_SDRCR_LPMODEN;

Thanks,

Nhan

  • Hi,

    Which RTOS SDK version are you using?

    Best Regards,
    Yordan
  • Hi Yordan,

    I use SYS/BIOS version 6.45.1.29, but in my code, the "go to deepsleep" function run in ARM, follow "OMAP-L138 Technical Reference Manual 10.10 Deepsleep mode", it run ok with normal omap, but stop at disabling VCLK of DDR, all IOPUs are unlock by ini file

    [IOPUCONFIG]
    IOPUSELECT = 0x000000FF
    MPPAVALUE = 0xFFFFFFFF

    [IOPUCONFIG]
    IOPUSELECT = 0x000100FF
    MPPAVALUE = 0xFFFFFFFF

    [IOPUCONFIG]
    IOPUSELECT = 0x000200FF
    MPPAVALUE = 0xFFFFFFFF

    [IOPUCONFIG]
    IOPUSELECT = 0x000300FF
    MPPAVALUE = 0xFFFFFFFF

    [IOPUCONFIG]
    IOPUSELECT = 0x000600FF
    MPPAVALUE = 0xFFFFFFFF

    [IOPUCONFIG]
    IOPUSELECT = 0x00060707
    MPPAVALUE = 0x00000000

    And I dont know what is difference between normal and secure omap
  • Hi Nhan
    We have not seen any customer use-case using security with deep sleep, and I am not sure if we have explicitly tested that combination, however I also do not think it should be any different on other psc handling in secure vs non secure land. I will discuss further with our security expert on this.

    I would like to confirm a few things

    1) Are you completely sure there is no difference between your secure vs non secure image specifically in terms of use of DDR. Usually PSC will not allow clock gating a module if the module you are trying to disable is in use and its state machine is not idle. Can you make sure that you are not trying to execute this code from DDR (no program/data fetches or outstanding transactions from DDR)? Maybe good to also visually compare the map files on your non secure vs secure?
    2) Just to ensure there is no issues with PSC handling in secure, can you confirm that if you tried to enable/disable any other module prior to DDR VCLK , in your deep sleep code, it works without issue in your secure device?
    3) If needed, would it be possible for you to send a self contained test program to try this on our hardware? Is the deep sleep code test part of some bigger system test or you trying this stand alone on your custom board?

    Regards
    Mukul
  • Hi Mukul,

    Thanks for your reply,

    1, I am completely sure there is no difference between secure and non-secure image. I also make sure that the code run in shareRAM, not DDR.

    2, I will try and feetback you

    3, I have the standalone code on my board, and I will send you the test program later.

    I read the flow and seem like soneone have the same problem

    I try to use FORCE bit to turn off, turn on VCLK, It can turn off the VLCK, but cannot wake up. I still dont know why...

    Please, help me!

  • Hi Nhan
    thanks for pointing to the 5 year old thread, I do not see any history of that customer coming back to us to drive the issue to closure.

    So please keep me posted on your observations (including some of the questions that I asked in that older e2e post also, that were not addressed/clarified).

    Can you also check if the deep sleep test with force bit works for you if you were to try this on a non-secure device?

    Regards
    Mukul
  • Hi Mukul,

    Now secure OMAPL138 go to deepsleep mode and wakeup successful with force bit. I hope it run stable. cause I still dont know the secure OMAPL138 architecture.

    Thanks,

    Nhan 

  • Hi Nhan
    Thanks for the update. I see that you have marked the post as resolved. It would be great if you could share, for future users, what was the issue where you were able to put the device in deep sleep with force bit for DDR but not wake it back up?

    I am assuming that the use of force bit was only needed for secure boot device , as per your previous post you did not need to use this when you had deep sleep working with the general purpose (non secure device), correct?

    In general we do not recommend using the force bit as it is essentially by passing the PSC "graceful" handshake to disable clocks to the IP. So if you do not plan to root cause this further, please do make sure that you test this thoroughly.

    All the best.
    Let us know if you have any additional questions.
    Regars
    Mukul
  • Hi Mukul,

    Thanks for your idea. Of course, when the issue is solved by not realy clearly solution, it may run unstable. I sure that, I dont need use force bit for non-secure OMAP. I still want to know the reason that secure device need force bit for going to sleep mode.

    I will test it carefully, and hope the it run fine.

    Thanks for your enthusiasm,

    Nhan.