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.

OMAP-L138: OMAP-L138 Power Consumption

Part Number: OMAP-L138

Dear Forum,

We are in the process of going as low power as possible while in deepsleep on our current custom design based on the OMAP-L138  

We are using 

OMAPL138EZCED4E + mDDR

We are having problems with power optimization in deep sleep mode

CVDD: 2.06mA

VGroup - A: 0.32mA

VGroup - B: 0.075mA (Disable pull-up/down internal when sleepmode)

VGroup - C: 0.64mA

DDR_DVDD current so high: 3.27mA

We are having problems with the PHY supply source (DDR_DVDD)

Thank you

  • Hi,

    Please post what software you are using, and which version.
  • Dear Biser
    I send source deep_sleep

    Thank you

    void deep_sleep_mode (void)
    {
    SOS_DEBUG("Entry to Deepsleep mode! \r\n");

    uint32_t savePinMux;
    uint32_t pscstatus;
    uint32_t count;

    changeOptimalPoint(OPP_1000MV_100MHZ);

    // Clear OMAP_STM32_INT_PIN to low
    // 0x68h Set_data45; 0x6Ch Clr_Data45, Pin offset is 23
    HWREG(SOC_GPIO_0_REGS + 0x6C) = (1 << 23);

    // 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)) = 0x80000002;//(PSC_MDCTL_NEXT_DISABLE & PSC_MDCTL_NEXT); //Nhan: use force bit
    do
    {
    pscstatus = HWREG(SOC_PSC_1_REGS + PSC_PTSTAT) & PSC_PTSTAT_GOSTAT0;
    }
    while (pscstatus);

    HWREG(SOC_PSC_1_REGS + PSC_MDCTL(HW_PSC_DDR2_MDDR)) = 0x80000002;

    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);

    /* RXACTIVE Register*/
    HWREG(0x01E2C014) = 1;

    /* 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) | 4096);

    // 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
    do
    {
    pscstatus = HWREG(SOC_PSC_1_REGS + PSC_PTSTAT) & PSC_PTSTAT_GOSTAT0;
    }
    while (pscstatus);

    /* RXACTIVE Register*/
    HWREG(0x01E2C014) = 0xffffffff;

    HWREG(SOC_PSC_1_REGS + PSC_MDCTL(HW_PSC_DDR2_MDDR)) = 0x80000003;//(PSC_MDCTL_NEXT_ENABLE & PSC_MDCTL_NEXT); Use force bit

    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;

    // Set OMAP_STM32_INT_PIN to high
    // 0x68h Set_data45; 0x6Ch Clr_Data45, Pin offset is 23
    HWREG(SOC_GPIO_0_REGS + 0x68) = (1 << 23);

    changeOptimalPoint(OPP_1200MV_300MHZ);
    }
  • Hi,

    I couldn't see the part of code where you disable the OMAP-L138 peripherals. For example: SATA, USB, EMAC, EMIFA, Audio (McASP, McBSP) and whatever you use. This should happen prior to configuring the PLLs in bypass mode.

    Best Regards,
    Yordan
  • Dear Yordan

    I send you config Omap-L138 peripherals

    PSCModuleControl (SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_LCDC, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_UART0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART2, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_I2C1, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_MCASP0,PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl (SOC_PSC_1_REGS, HW_PSC_EMAC, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_CC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_TC0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_VPIF, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_UART1, PSC_POWERDOMAIN_ALWAYS_ON,PSC_MDCTL_NEXT_ENABLE);

    Thank you
  • Ok, in that case have you used the Power Consumption spreadsheet (processors.wiki.ti.com/.../OMAP-L138_Power_Consumption_Summary to validate what values you can achieve and pinpoint where exactly are you having troubles.