Part Number: OMAPL138B-EP
Other Parts Discussed in Thread: OMAPL138, OMAP-L138
Tool/software: Linux
Hi ,
Working on DEEPSLEEP feature implementation on a device running kernel 3.10.12 on OMAPL138 . we are using the gcc-4.4.1-glibc-2.10.1/bin/arm-none-linux-gnueabi- (GCC toolchain). We are facing issues on linking the code to internal memory in linux.
static void davinci_pm_suspend(void)
{
unsigned val;
//Clear Self Refresh / low power (SR_PD)bit to 0
val = __raw_readl(pdata->ddr2_ctlr_base + 0x0C);
val &= ~(0x00800000);
__raw_writel(val, pdata->ddr2_ctlr_base + 0x0C);
//set the low power enable
val = __raw_readl(pdata->ddr2_ctlr_base + 0x0C);
val |= (0x80000000);
__raw_writel(val, pdata->ddr2_ctlr_base + 0x0C);
/* Switch CPU PLL0 to bypass mode */
val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
val &= ~(PLLCTL_PLLENSRC|PLLCTL_PLLEN);
__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
/* Switch CPU PLL1 to bypass mode */
val = __raw_readl(pdata->ddrpll_reg_base + PLLCTL);
val &= ~(PLLCTL_PLLENSRC|PLLCTL_PLLEN);
__raw_writel(val, pdata->ddrpll_reg_base + PLLCTL);
udelay(PLL_BYPASS_TIME);
/* Powerdown CPU PLL0 */
val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
val |= PLLCTL_PLLPWRDN;
__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
/* Powerdown CPU PLL1 */
val = __raw_readl(pdata->ddrpll_reg_base + PLLCTL);
val |= PLLCTL_PLLPWRDN;
__raw_writel(val, pdata->ddrpll_reg_base + PLLCTL);
/* Set DeepSleep pin in PINMUX0 register */
val = __raw_readl(pdata->pinmux_reg_base +0x120);
val &= ~(0xF0000000);
__raw_writel(val, pdata->pinmux_reg_base + 0x120);
/* Configure sleep count in deep sleep register */
val = __raw_readl(pdata->deepsleep_reg);
val &= ~DEEPSLEEP_SLEEPCOUNT_MASK,
val |= 0x000F;
__raw_writel(val, pdata->deepsleep_reg);
/* Configure Enable Deep bit in the sleep register */
val = __raw_readl(pdata->deepsleep_reg);
val |= 0x80000000;
__raw_writel(val, pdata->deepsleep_reg);
do
{
val = __raw_readl(pdata->deepsleep_reg);
val &= 0x40000000;
}while(0==val);
/* Clear Enable Deepsleep bit in the sleep register */
val = __raw_readl(pdata->deepsleep_reg);
val &= ~(0x80000000);
__raw_writel(val, pdata->deepsleep_reg);
/* Clear PLLRST bit in PLLCTL 0 */
val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
val &= ~PLLCTL_PLLRST;
__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
/* Clear PLLRST bit in PLLCTL 1 */
val = __raw_readl(pdata->ddrpll_reg_base + PLLCTL);
val &= ~PLLCTL_PLLRST;
__raw_writel(val, pdata->ddrpll_reg_base + PLLCTL);
/* Clear PLLPWRDWN bit in PLLCTL 0 */
val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
val &= ~PLLCTL_PLLPWRDN;
__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
/* Clear PLLPWRDWN bit in PLLCTL 1 */
val = __raw_readl(pdata->ddrpll_reg_base + PLLCTL);
val &= ~PLLCTL_PLLPWRDN;
__raw_writel(val, pdata->ddrpll_reg_base + PLLCTL);
/* wait for CPU PLL reset */
udelay(PLL_RESET_TIME);
/* Set PLLRST bit in PLLCTL 0 */
val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
val |= PLLCTL_PLLRST;
__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
/* Set PLLRST bit in PLLCTL 1 */
val = __raw_readl(pdata->ddrpll_reg_base + PLLCTL);
val |= PLLCTL_PLLRST;
__raw_writel(val, pdata->ddrpll_reg_base + PLLCTL);
/* Wait for CPU PLL to lock */
udelay(PLL_LOCK_TIME);
/* Remove CPU PLL0 from bypass mode */
val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
val &= ~(PLLCTL_PLLENSRC);
val |= PLLCTL_PLLEN;
__raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
/* Remove CPU PLL1 from bypass mode */
val = __raw_readl(pdata->ddrpll_reg_base + PLLCTL);
val &= ~(PLLCTL_PLLENSRC);
val |= PLLCTL_PLLEN;
__raw_writel(val, pdata->ddrpll_reg_base + PLLCTL);
//Enable clock to the SDRAM register
val = __raw_readl(pdata->ddrpsc_reg_base);
val |= (0x00000003);
__raw_writel(val, pdata->ddrpsc_reg_base);
//Set Reset PHY bit in DDR PHY reset control register
val = __raw_readl(pdata->ddr2_ctlr_base + 0x60);
val |= (0x00000400);
__raw_writel(val, pdata->ddr2_ctlr_base + 0x60);
//Clear the MCLKSTOPEN bit in SDRCR
val = __raw_readl(pdata->ddr2_ctlr_base + 0x0C);
val &= ~(0x40000000);
__raw_writel(val, pdata->ddr2_ctlr_base + 0x0C);
//Clear the low power mode bit in SDRCR
val = __raw_readl(pdata->ddr2_ctlr_base + 0x0C);
val &= ~(0x80000000);
__raw_writel(val, pdata->ddr2_ctlr_base + 0x0C);
}
On searching forums found sample code on how to link the code from SRAM. Added the below line before the davinci_pm_suspend() function definition.
#pragma CODE_SECTION(davinci_pm_suspend(), ".TI.ramfunc")
During the kernel Image compilation observed the warning : ignoring the #pragma CODE_SECTION. Also the davinci_pm_suspend() function entry is missing from the system.map file.
Please share your thoughts on the same.
Regards,
Shyam G




