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.

Sitara power management

We are using Linux-3.2.0-PSP04.06.00.11. for Sitara AM335x  (SDK-06.00.00.00) 

we have issues with the DVFS and CPU IDLE  : generally there is stability issues after adding some improvements to the existing mechanisms 

DVFS

We’re using On Demand governor , we added an additional Low Power  Opp ( CPU PLL Freq 50 MHz ) , in addition we added DFS mechanism for Core PLL ( 200/100 MHz )

When low power Opp enabled we see some issues

1.UART : UART runtime suspend not completed ( UART runtime driver enter to suspending transaction which not completed  ( we saw a similar issue when Core  DFS enabled (PLL went down to 100 MHz  ) .
2.From time to time there is a system crash ( Processor Halt with JTAG  fails   )

CPU IDLE :

1.We defined 4 IDLE C-states

1.C0 : wait for interrupt (wfi ) – works fine
2.C1 : C0 + PLL bypass  - work fine
3.C2 : C1 + RAM self refresh  - works fine
4.C3: C2 + RAM self refresh + EMIF stand by  : stability issues – there is frequent system crash ( this mode is critical for us since the current saving is significant comparing the other C-states ) 
added:
Below you can see enter - exit sequence for C3 state:

/* emif_context_save */
enter_ram_self_refresh1:

/* Weak pull down for DQ, DM ddr_data0_ioctrl 0x3FF00003 */
ldr r1, virt_ddr_io_pull1 @ 1440h ddr_data0_ioctrl = 0x3FF00003
ldr r2, susp_io_pull_data
str r2, [r1]

ldr r1, virt_ddr_io_pull2 @1444h ddr_data1_ioctrl = 0x3FF00003
ldr r2, susp_io_pull_data
str r2, [r1]

/* Weak pull down for macro CMD0 */
ldr r1, virt_ddr_cmd0_ioctrl @ 1404h ddr_cmd0_ioctrl = 0xFFE0018B
ldr r2, susp_io_pull_cmd1
str r2, [r1]

/* Weak pull down for macro CMD1 */
ldr r1, virt_ddr_cmd1_ioctrl @1408h ddr_cmd1_ioctrl = 0xFFE0018B
ldr r2, susp_io_pull_cmd1
str r2, [r1]

/*
* Weak pull down for macro CMD2
* exception: keep DDR_RESET pullup
*/
ldr r1, virt_ddr_cmd2_ioctrl @ 140Ch ddr_cmd2_ioctrl = 0xFFA0098B
ldr r2, susp_io_pull_cmd2
str r2, [r1]

/* Disable EMIF at this point */
disable_emif 2, virt_emif_clkctrl @ ldr r1, \emif_addr ;; ldr r2, [r1] ; bic r2, r2, #(3 << 0) ; str r2, [r1]
@ CMD0_REG_PHY_DLL_LOCK_DIFF_0 =& ~0x3;clear 0,1 bis


/* Hold CKE low */
ldr r1, virt_ddr_cke_ctrl @ 131Ch ddr_cke_ctrl = 0
mov r2, #0
str r2, [r1]

/* DDR3 reset override and mDDR mode selection */
ldr r0, virt_ddr_io_ctrl @E04h ddr_io_ctrl = 0x90000000
mov r1, #(0x9 << 28)
str r1, [r0]

/* Disable VTP */
ldr r1, virt_ddr_vtp_ctrl @ E0Ch vtp_ctrl = 1
ldr r2, susp_vtp_ctrl_val
str r2, [r1]

/* Enable SRAM LDO ret mode */
ldr r0, virt_sram_ldo_addr @ 1Ch PRM_LDO_SRAM_MPU_CTRL Register =| 1
ldr r1, [r0]
orr r1, #1
str r1, [r0]

pll_bypass mpu, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val


dsb
dmb
isb

wfi
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop


/* Relock the PLLs */
pll_lock mpu_abt, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val

/* Disable SRAM LDO ret mode */
ldr r0, virt_sram_ldo_addr @ 1Ch PRM_LDO_SRAM_MPU_CTRL Register =& ~1
ldr r1, [r0]
bic r1, #1
str r1, [r0]

/* Enable EMIF */
ldr r1, virt_emif_clkctrl @ @ 1Ch PRM_LDO_SRAM_MPU_CTRL Register = 2
mov r2, #0x2
str r2, [r1]
wait_emif_enable:
ldr r3, [r1]
cmp r2, r3
bne wait_emif_enable

/* DDR3 reset override and mDDR mode clear */
ldr r0, virt_ddr_io_ctrl

/* LPDDR1 io ctrl value write */
lpddr1_io_ctrl_abt: @E04h ddr_io_ctrl = 0x10000000
mov r1, #(0x1 << 28)
str r1, [r0]

/* Enable VTP */
config_vtp_abt:
ldr r0, virt_ddr_vtp_ctrl @ E0Ch vtp_ctrl
ldr r1, [r0]
mov r2, #0x0 @ clear the register
str r2, [r0]
mov r2, #0x6 @ write the filter value
str r2, [r0]

ldr r1, [r0]
ldr r2, vtp_enable @ set the enable bit @ set the enable bit VTP_CTRL_ENABLE (0x1 << 6)
orr r2, r2, r1
str r2, [r0]

ldr r1, [r0] @ toggle the CLRZ bit
bic r1, #1
str r1, [r0]

ldr r1, [r0]
orr r1, #1
str r1, [r0]

poll_vtp_ready_abt:
ldr r1, [r0] @ poll for VTP ready
tst r1, #(1 << 5)
beq poll_vtp_ready_abt

/* Restore the pull for DQ, DM */
ldr r1, virt_ddr_io_pull1 @ 1440h ddr_data0_ioctrl = 0x18B
ldr r2, resume_io_pull_data
str r2, [r1]
ldr r1, virt_ddr_io_pull2 @1444h ddr_data1_ioctrl = 0x18B
ldr r2, resume_io_pull_data
str r2, [r1]
/* Disable the pull for CMD2 */
ldr r1, virt_ddr_cmd2_ioctrl @ 140Ch ddr_cmd2_ioctrl = 0x18B
ldr r2, resume_io_pull_cmd
str r2, [r1]
/* Disable the pull for CMD1 */
ldr r1, virt_ddr_cmd1_ioctrl @1408h ddr_cmd1_ioctrl = 0x18B
ldr r2, resume_io_pull_cmd
str r2, [r1]
/* Disable the pull for CMD0 */
ldr r1, virt_ddr_cmd0_ioctrl @ 1404h ddr_cmd0_ioctrl = 0x18B
ldr r2, resume_io_pull_cmd
str r2, [r1]

/* Restore EMIF control of CKE */
ldr r1, virt_ddr_cke_ctrl @ 131Ch ddr_cke_ctrl = 1
mov r2, #1
str r2, [r1]

emif_self_refresh_dis:
disable_emif_self_refresh emif_addr_virt @ 38h PWR_MGMT_CTRL Register clear bit (0x7 << 8)
@ and write the same value to PWR_MGMT_CTRL_SHDW Register (offset = 3Ch)

/*
* A write to SDRAM CONFIG register triggers
* an init sequence and hence it must be done
* at the end
*/
ldr r0, emif_addr_virt
add r0, r0, #EMIF4_0_SDRAM_CONFIG @ SDRAM_CONFIG Register (offset = 8h) restore register from .macro emif_context_save
ldr r4, emif_sdcfg_val
str r4, [r0]

mov r0, #0x2000
wait_loop4:
subs r0, r0, #1
bne wait_loop4

mov r0, #7
ldmfd sp!, {r4 - r11, pc} @ restore regs and return

  • Hi Yuri,

    I will forward this to a PM expert.

  • The c-state described by the customer is not supported in TI platform and SW.

    The Linux PM features might have been changed over different SDK releases.

    Here are links to the latest Linux PM wiki.

    SDK
    processors.wiki.ti.com/.../AM335x_Linux_Power_Management_User_Guide;tisearch=Search-EN

    C-state definition: processors.wiki.ti.com/.../AM335x_Linux_Power_Management_User_Guide;tisearch=Search-EN#C-states
  • Can you post patches with the changes you made? I can try to recreate over here. Also, is this DDR2 or DDR3?

    Steve K.

  • Hi ,

    The memory used is LPDDR.

    A lot of changes was done in kernel to support customer board. I think it is not reasonable   to send all changes.

    I send only main changes related to power management. 

    Thank in advance.

     

    cpuidle.txt
     
    diff -Naur /view/byu003_rst/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx.c /view/byu003_scmV12/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx.c
    --- /view/byu003_rst/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx.c	2013-06-26 00:37:58.000000000 +0300
    +++ /view/byu003_scmV12/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx.c	2015-07-12 07:37:41.380330000 +0300
    @@ -28,8 +28,10 @@
     #include <plat/emif.h>
     
     #include "cpuidle33xx.h"
    -
    -#define AM33XX_CPUIDLE_MAX_STATES	2
    +#include <plat/sram.h>
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +#include "pm33xx.h"
    +#endif
     
     struct am33xx_ops {
     	void (*enter) (u32 flags);
    @@ -40,6 +42,15 @@
     /* fields in am33xx_ops.flags */
     #define AM33XX_CPUIDLE_FLAGS_DDR2_PWDN	BIT(0)
     
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +void (*am33xx_do_wfi_sram_idle)(u32 *);
    +extern unsigned int am33xx_do_wfi_sz_idle;
    +u8 ImodPmTmp_get_max_Cstate(void);
    +#define AM33XX_CPUIDLE_MAX_STATES	4
    +#else
    +#define AM33XX_CPUIDLE_MAX_STATES	2
    +#endif
    +
     static struct cpuidle_driver am33xx_idle_driver = {
     	.name	= "cpuidle-am33xx",
     	.owner	= THIS_MODULE,
    @@ -56,28 +67,85 @@
     
     	/* TODO: Choose the mode based on memory type */
     	if (enter)
    -		val = SELF_REFRESH_ENABLE(64);
    +		val = SELF_REFRESH_ENABLE(4); /*<bml001> was 64*/
     	else
     		val = SELF_REFRESH_DISABLE;
     
     	__raw_writel(val, emif_base + EMIF4_0_SDRAM_MGMT_CTRL);
     }
     
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +static void am33xx_c1state_enter(u32 flags)
    +{
    +	if(am33xx_do_wfi_sram_idle)
    +	{
    +		am33xx_do_wfi_sram_idle(PM_IDLE_SPU_PLL_BP);
    +	}
    +}
    +#endif
    +
     static void am33xx_c2state_enter(u32 flags)
     {
    -	am33xx_save_ddr_power(1, !!(flags & AM33XX_CPUIDLE_FLAGS_DDR2_PWDN));
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +	if(am33xx_do_wfi_sram_idle)
    +	{
    +		am33xx_do_wfi_sram_idle(  (PM_IDLE_RAM_SR |  PM_IDLE_SPU_PLL_BP)  );
    +	}
    +#else
    +*	am33xx_save_ddr_power(1, !!(flags & AM33XX_CPUIDLE_FLAGS_DDR2_PWDN)); 
    +#endif 
    +
    +}
    +
    +static void am33xx_c3state_enter(u32 flags)
    +{
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +	if(am33xx_do_wfi_sram_idle)
    +	{
    +		am33xx_do_wfi_sram_idle(  (PM_IDLE_RAM_SR |  PM_IDLE_SPU_PLL_BP | PM_IDLE_EMIF_STNDB )  );
    +	}
    +#else
    +*	am33xx_save_ddr_power(1, !!(flags & AM33XX_CPUIDLE_FLAGS_DDR2_PWDN)); 
    +#endif 
    +
     }
     
     static void am33xx_c2state_exit(u32 flags)
     {
    -	am33xx_save_ddr_power(0, !!(flags & AM33XX_CPUIDLE_FLAGS_DDR2_PWDN));
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +	;/* do nothing */
    +#else
    +	am33xx_save_ddr_power(0, !!(flags & AM33XX_CPUIDLE_FLAGS_DDR2_PWDN)); 
    +#endif
    +	
     }
     
     static struct am33xx_ops am33xx_states[AM33XX_CPUIDLE_MAX_STATES] = {
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +
    +	[0] = {
    +		.enter	= NULL,
    +		.exit	= NULL,
    +	},
     	[1] = {
    +		.enter	= am33xx_c1state_enter,
    +		.exit	= am33xx_c2state_exit,
    +	},
    +	[2] = {
     		.enter	= am33xx_c2state_enter,
     		.exit	= am33xx_c2state_exit,
     	},
    +	[3] = {
    +		.enter	= am33xx_c3state_enter,
    +		.exit	= am33xx_c2state_exit,
    +	},
    +
    +#else
    +[1] = {
    +		.enter	= am33xx_c2state_enter,
    +		.exit	= am33xx_c2state_exit,
    +	},
    +#endif
     };
     
     /* Actual code that puts the SoC in different idle states */
    @@ -93,10 +161,17 @@
     	do_gettimeofday(&before);
     
     	if (ops && ops->enter)
    +	{
     		ops->enter(ops->flags);
    +	}
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +	else
    +#endif
    +	{
    +		cpu_do_idle();
    +	}
     
     	/* Wait for interrupt state */
    -	cpu_do_idle();
     	if (ops && ops->exit)
     		ops->exit(ops->flags);
     
    @@ -113,6 +188,7 @@
     static int __init am33xx_cpuidle_probe(struct platform_device *pdev)
     {
     	int ret;
    +	int i;
     	struct cpuidle_device *device;
     	struct cpuidle_driver *driver = &am33xx_idle_driver;
     	struct am33xx_cpuidle_config *pdata = pdev->dev.platform_data;
    @@ -124,8 +200,49 @@
     		return -ENOENT;
     	}
     
    +	am33xx_do_wfi_sram_idle = (void *)omap_sram_push(am33xx_do_wfi_idle, am33xx_do_wfi_sz_idle);
    +
    +	if(!am33xx_do_wfi_sram_idle)
    +		printk(KERN_ERR "ImodPmTmp omap_sram_push am33xx_do_wfi_sram_idle FAIL  \n");
    +			
    +
     	emif_base = pdata->emif_base;
     
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +	/* Wait for interrupt state */
    +	driver->states[0].enter = am33xx_enter_idle;
    +	driver->states[0].exit_latency = 1;
    +	driver->states[0].target_residency = 150;
    +	driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
    +	strcpy(driver->states[0].name, "WFI");
    +	strcpy(driver->states[0].desc, "Wait for interrupt");
    +
    +	
    +	driver->states[1].enter = am33xx_enter_idle;
    +	driver->states[1].exit_latency = 176;
    +	driver->states[1].target_residency = 300;
    +	driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
    +	strcpy(driver->states[1].name, "C1");
    +	strcpy(driver->states[1].desc,"Bypass MPU PLL");
    +
    +	/* Wait for interrupt and DDR self refresh and PLL bypass state */
    +	driver->states[2].enter = am33xx_enter_idle;
    +	driver->states[2].exit_latency = 390;
    +	driver->states[2].target_residency = 500;
    +	driver->states[2].flags = CPUIDLE_FLAG_TIME_VALID;
    +	strcpy(driver->states[2].name,"C1+SR");
    +	strcpy(driver->states[2].desc, "Bypass MPU PLL + DDR SR");
    +
    +	/* Wait for interrupt and DDR self refresh and PLL bypass state */
    +	driver->states[3].enter = am33xx_enter_idle;
    +	driver->states[3].exit_latency = 490;
    +	driver->states[3].target_residency = 700;
    +	driver->states[3].flags = CPUIDLE_FLAG_TIME_VALID;
    +	strcpy(driver->states[3].name,"C2+EMIF dis");
    +	strcpy(driver->states[3].desc, "C2 + EMIF stand by mode");
    +
    +
    +#else	
     	/* Wait for interrupt state */
     	driver->states[0].enter = am33xx_enter_idle;
     	driver->states[0].exit_latency = 1;
    @@ -141,9 +258,16 @@
     	driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
     	strcpy(driver->states[1].name, "DDR SR");
     	strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
    +
     	if (pdata->ddr2_pdown)
     		am33xx_states[1].flags |= AM33XX_CPUIDLE_FLAGS_DDR2_PWDN;
     	cpuidle_set_statedata(&device->states_usage[1], &am33xx_states[1]);
    +#endif
    +
    +	for(i = 0; i < AM33XX_CPUIDLE_MAX_STATES ; i++)
    +	{
    +		cpuidle_set_statedata(&device->states_usage[i], &am33xx_states[i]);
    +	}
     
     	device->state_count = AM33XX_CPUIDLE_MAX_STATES;
     	driver->state_count = AM33XX_CPUIDLE_MAX_STATES;
    diff -Naur /view/byu003_rst/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx.h /view/byu003_scmV12/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx.h
    --- /view/byu003_rst/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx.h	2013-06-26 00:37:58.000000000 +0300
    +++ /view/byu003_scmV12/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx.h	2015-06-11 10:15:37.401442000 +0300
    @@ -20,5 +20,6 @@
     	u32 ddr2_pdown;
     	void __iomem *emif_base;
     };
    +extern void am33xx_do_wfi_idle(void);
     
     #endif
    diff -Naur /view/byu003_rst/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx_imod.S /view/byu003_scmV12/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx_imod.S
    --- /view/byu003_rst/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx_imod.S	1970-01-01 02:00:00.000000000 +0200
    +++ /view/byu003_scmV12/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/cpuidle33xx_imod.S	2015-07-12 07:39:00.173277000 +0300
    @@ -0,0 +1,1009 @@
    +
    +/*
    + * Low level suspend code for AM33XX SoCs
    + *
    + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License as
    + * published by the Free Software Foundation version 2.
    + *
    + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
    + * kind, whether express or implied; without even the implied warranty
    + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    + * GNU General Public License for more details.
    + */
    +
    +#include <linux/linkage.h>
    +#include <linux/init.h>
    +#include <asm/memory.h>
    +#include <asm/assembler.h>
    +#include <mach/io.h>
    +
    +#ifdef CONFIG_MACH_AM335XEVM
    +#include <mach/board-am335xevm.h>
    +#endif
    +#ifdef CONFIG_MACH_AM335X_IMOD
    +#include <mach/board-am335x-imod.h>
    +#endif
    +
    +#include <plat/emif.h>
    +#include <plat/sram.h>
    +#include <plat/gpio.h>
    +
    +#include "cm33xx.h"
    +#include "pm33xx.h"
    +#include "prm33xx.h"
    +#include "control.h"
    +
    +/*
    + * We should probably pass in the virtual address of PRCM, Control and EMIF
    + * along with the physical addresses, load it into the registers
    + * and then continue.
    + *
    + * This routine is executed from internal RAM 
    + * Input parameter  in r0 saved in imod_pm_job
    + * PM_IDLE_SPU_PLL_BP  -  cpuidle state C1 CPU PLL bypass 
    + * PM_IDLE_SPU_PLL_BP_RAM_SR -  cpuidle state C2  C1 + RAM self refresh mode
    + * PM_RAM_ENTER_SR   -  used by core DFS: during clock changes memory should be in self refresh mode 
    + * PM_RAM_EXIT_SR -  used by core DFS: during clock changes memory should be in self refresh mode 
    + *
    + *
    + */
    + 
    +	.align 3
    +ENTRY(am33xx_do_wfi_idle)
    +	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
    +
    +	.macro	pll_bypass, name, clk_mode_addr, idlest_addr, pll_mode
    +pll_bypass_\name:
    +	ldr	r0, \clk_mode_addr
    +	ldr	r1, [r0]
    +	str	r1, clk_mode_\pll_mode
    +	bic	r1, r1, #(7 << 0)
    +	orr	r1, r1, #0x5
    +	str	r1, [r0]
    +	ldr	r0, \idlest_addr
    +wait_pll_bypass_\name:
    +	ldr	r1, [r0]
    +	tst	r1, #0x0
    +	bne	wait_pll_bypass_\name
    +	.endm
    +
    +	.macro	pll_lock, name, clk_mode_addr, idlest_addr, pll_mode
    +pll_lock_\name:
    +	ldr	r0, \clk_mode_addr
    +	ldr	r1, clk_mode_\pll_mode
    +	str	r1, [r0]
    +	and	r1, r1, #0x7
    +	cmp	r1, #0x7
    +	bne	pll_mode_restored_\name
    +	ldr	r0, \idlest_addr
    +wait_pll_lock_\name:
    +	ldr	r1, [r0]
    +	ands	r1, #0x1
    +	beq	wait_pll_lock_\name
    +pll_mode_restored_\name:
    +	nop
    +	.endm
    +
    +	.macro	ddr_self_refresh, num
    +ddr_self_refresh_\num:
    +	add	r1, r0, #EMIF4_0_SDRAM_MGMT_CTRL
    +	ldr	r3, [r1, #0]
    +	orr	r3, r3, #0x200		@ now set the LP MODE to Self-Refresh
    +	str	r3, [r1, #0]
    +
    +	mov	r1, #0x1000		@ Give some time for system to enter SR
    +wait_sr_\num:
    +	subs	r1, r1, #1
    +	bne	wait_sr_\num
    +	.endm
    +
    +	.macro	wait_sdram_config ,num
    +wait_sdram_config_\num:
    +	mov	r0, #0x100
    +wait_sc_\num:
    +	subs	r0, r0 ,#1
    +	bne	wait_sc_\num
    +	.endm
    +
    +	.macro disable_emif, num, emif_addr
    +disable_emif_\num:
    +	/* Disable EMIF at this point */
    +	ldr	r1, \emif_addr
    +	ldr	r2, [r1]
    +	bic	r2, r2, #(3 << 0)
    +	str	r2, [r1]
    +
    +	ldr	r1, \emif_addr
    +ddr2_wait_emif_disable_\num:
    +	ldr	r2, [r1]
    +	ldr	r3, module_disabled_val
    +	cmp	r2, r3
    +	bne	ddr2_wait_emif_disable_\num
    +	.endm
    +
    +	.macro emif_context_save
    +	ldr	r0, emif_addr_virt
    +
    +	/* Save EMIF configuration */
    +	ldr	r1, [r0, #EMIF4_0_SDRAM_CONFIG]
    +	str	r1, emif_sdcfg_val
    +	ldr	r1, [r0, #EMIF4_0_SDRAM_REF_CTRL]
    +	str	r1, emif_ref_ctrl_val
    +	ldr	r1, [r0, #EMIF4_0_SDRAM_TIM_1]
    +	str	r1, emif_timing1_val
    +	ldr	r1, [r0, #EMIF4_0_SDRAM_TIM_2]
    +	str	r1, emif_timing2_val
    +	ldr	r1, [r0, #EMIF4_0_SDRAM_TIM_3]
    +	str	r1, emif_timing3_val
    +	ldr	r1, [r0, #EMIF4_0_SDRAM_MGMT_CTRL]
    +	str	r1, emif_pmcr_val
    +	ldr	r1, [r0, #EMIF4_0_SDRAM_MGMT_CTRL_SHADOW]
    +	str	r1, emif_pmcr_shdw_val
    +	ldr	r1, [r0, #EMIF4_0_ZQ_CONFIG]
    +	str	r1, emif_zqcfg_val
    +	ldr	r1, [r0, #EMIF4_0_DDR_PHY_CTRL_1]
    +	str	r1, emif_rd_lat_val
    +	.endm
    +
    +	.macro emif_context_restore, emif_addr
    +	ldr	r3, \emif_addr
    +	ldr	r4, emif_rd_lat_val
    +
    +	str	r4, [r3, #EMIF4_0_DDR_PHY_CTRL_1]
    +	str	r4, [r3, #EMIF4_0_DDR_PHY_CTRL_1_SHADOW]
    +
    +	ldr	r4, emif_timing1_val
    +	str	r4, [r3, #EMIF4_0_SDRAM_TIM_1]
    +	str	r4, [r3, #EMIF4_0_SDRAM_TIM_1_SHADOW]
    +
    +	ldr	r4, emif_timing2_val
    +	str	r4, [r3, #EMIF4_0_SDRAM_TIM_2]
    +	str	r4, [r3, #EMIF4_0_SDRAM_TIM_2_SHADOW]
    +
    +	ldr	r4, emif_timing3_val
    +	str	r4, [r3, #EMIF4_0_SDRAM_TIM_3]
    +	str	r4, [r3, #EMIF4_0_SDRAM_TIM_3_SHADOW]
    +
    +	ldr	r4, emif_ref_ctrl_val
    +	str	r4, [r3, #EMIF4_0_SDRAM_REF_CTRL]
    +	str	r4, [r3, #EMIF4_0_SDRAM_REF_CTRL_SHADOW]
    +
    +	ldr	r4, emif_pmcr_val
    +	str	r4, [r3, #EMIF4_0_SDRAM_MGMT_CTRL]
    +
    +	ldr	r4, emif_pmcr_shdw_val
    +	str	r4, [r3, #EMIF4_0_SDRAM_MGMT_CTRL_SHADOW]
    +	.endm
    +
    +	.macro disable_emif_self_refresh, emif_addr
    +	/* Disable EMIF self-refresh */
    +	ldr	r0, \emif_addr
    +	add	r0, r0, #EMIF4_0_SDRAM_MGMT_CTRL
    +	ldr	r1, [r0]
    +	bic	r1, r1, #(0x7 << 8)
    +	str	r1, [r0]
    +	str	r1, [r0, #4]
    +	.endm
    +
    +
    +/*#ifdef  ImodPmTmp_SLEEP */
    +
    +/* ImodPmTmp start */
    +
    +	mov	r8, r0			@ same arg list passed to us
    +	str	r0, imod_pm_job
    +
    +	/* EMIF config for low power mode */
    +	ldr	r0, emif_addr_func
    +	blx	r0
    +	str	r0, emif_addr_virt
    +
    +	ldr	r0, gpio0_addr_func
    +	blx	r0
    +	str	r0, gpio0_addr_virt
    +
    +	/* This ensures isb */
    +	ldr	r0, dcache_flush
    +	blx	r0
    +
    +	/* Same as v7_flush_icache_all - saving a branch */
    +	mov	r0, #0
    +	mcr	p15, 0, r0, c7, c5, 0	@ I+BTB cache invalidate
    +
    +
    +	emif_context_save
    +
    +	/* Ensure that all the writes to DDR leave the A8 */
    +	dsb
    +	dmb
    +	isb
    +
    +
    +emif_standby:
    +
    +	ldr 	r0, imod_pm_job
    +	and	r0, r0, #PM_IDLE_EMIF_STNDB
    +	cmp	 r0, #PM_IDLE_EMIF_STNDB
    +	beq	emif_standby_start    
    +
    +       ldr 	r0, imod_pm_job
    +	and	r0, r0, #PM_IDLE_RAM_SR
    +	cmp	 r0, #PM_IDLE_RAM_SR
    +	bne	rum_self_refresh_enter_end   @skipp ram self refresh job 
    +
    +rum_self_refresh_enter_start:
    +
    +    ldr	r0, emif_addr_virt
    + /*  SDRAM_REF_CTRL offset 0x10  bit  26-24 reg_pasr*/
    +
    +/*PWR_MGMT_CTRL Register (offset = 38h) bit 7-4 reg_sr_tim  timer for Self Refresh.
    + * The EMIF will put the external SDRAM in Self Refresh mode after
    + * the EMIF is idle for these number of DDR clock cycles and if reg_lp_mode field is set to 2.
    + * Set to 0 to immediately enter Self Refresh mode
    + */
    +    ldr	r1, [r0, #0x38]
    +    and	r1, r1, #0xFFFFF80F
    +    str	r1, [r0, #0x38]
    +
    +/* PWR_MGMT_CTRL Register (offset = 38h) bit 10-8 reg_lp_mode Automatic Power Management enable.
    + *  Set to 1 for Clock Stop, set to 2 for Self Refresh, and set to 4 for Power-Down.
    + *  All other values will disable automatic power management.
    + */
    +    orr	r1, r1, #0x200
    +    str	r1, [r0, #0x38]
    +
    +rum_self_refresh_enter_end:
    +
    +       ldr 	r0, imod_pm_job
    +	and	r0, r0, #PM_IDLE_SPU_PLL_BP
    +	cmp	 r0, #PM_IDLE_SPU_PLL_BP
    +	bne	mpu_pll_bypass_end   @skipp mpu pll bypass job 
    +
    +
    +mpu_pll_bypass_start:
    +	pll_bypass	mpu, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val
    +mpu_pll_bypass_end:
    +
    +	dsb
    +	dmb
    +	isb
    +
    +	wfi
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +
    +
    +       ldr 	r0, imod_pm_job
    +	and	r0, r0, #PM_IDLE_SPU_PLL_BP
    +	cmp	 r0, #PM_IDLE_SPU_PLL_BP
    +	bne	mpu_pll_lock_end   @skipp mpu pll lock  
    +
    +mpu_pll_lock_start:
    +	pll_lock	mpu_abt, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val
    +mpu_pll_lock_end:
    +
    +
    +       ldr 	r0, imod_pm_job
    +	and	r0, r0, #PM_IDLE_RAM_SR
    +	cmp	 r0, #PM_IDLE_RAM_SR
    +	bne	rum_self_refresh_exit_end   @skipp ram self refresh job 
    +
    +rum_self_refresh_exit_start:
    +
    +/* PWR_MGMT_CTRL Register (offset = 38h) bit 10-8 reg_lp_mode Automatic Power Management enable.
    + *  Set to 1 for Clock Stop, set to 2 for Self Refresh, and set to 4 for Power-Down.
    + *  All other values will disable automatic power management.
    + */
    +    ldr	r0, emif_addr_virt
    +    ldr	r1, [r0, #0x38]
    +    and	r1, r1, #0xFFFFF8FF
    +    str	r1, [r0, #0x38]
    +
    +rum_self_refresh_exit_end:
    +
    +	mov	r0, #7
    +	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
    +
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +
    +
    +/* #endif */
    +/* #ifdef  ImodPmTmp_SLEEP  */
    +
    +emif_standby_start:
    +
    +ram_self_refresh_start1:
    +
    +	/* Weak pull down for DQ, DM    ddr_data0_ioctrl   0x3FF00003 */
    +	ldr	r1, virt_ddr_io_pull1
    +	ldr	r2, susp_io_pull_data
    +	str	r2, [r1]
    +
    +	ldr	r1, virt_ddr_io_pull2
    +	ldr	r2, susp_io_pull_data
    +	str	r2, [r1]
    +
    +	/* Weak pull down for macro CMD0 */
    +	ldr	r1, virt_ddr_cmd0_ioctrl
    +	ldr	r2, susp_io_pull_cmd1
    +	str	r2, [r1]
    +
    +	/* Weak pull down for macro CMD1 */
    +	ldr	r1, virt_ddr_cmd1_ioctrl
    +	ldr	r2, susp_io_pull_cmd1
    +	str	r2, [r1]
    +
    +	/*
    +	 * Weak pull down for macro CMD2
    +	 * exception: keep DDR_RESET pullup
    +	 */
    +	ldr	r1, virt_ddr_cmd2_ioctrl
    +	ldr	r2, susp_io_pull_cmd2
    +	str	r2, [r1]
    +
    +	/* Disable EMIF at this point */
    +	disable_emif	2, virt_emif_clkctrl
    +
    +	/* Hold CKE low */
    +	ldr	r1, virt_ddr_cke_ctrl
    +	mov	r2, #0
    +	str	r2, [r1]
    +
    +	/* DDR3 reset override and mDDR mode selection */
    +	ldr	r0, virt_ddr_io_ctrl
    +	mov	r1, #(0x9 << 28)
    +	str	r1, [r0]
    +
    +	/* Disable VTP */
    +	ldr	r1, virt_ddr_vtp_ctrl
    +	ldr	r2, susp_vtp_ctrl_val
    +	str	r2, [r1]
    +
    +	/* Enable SRAM LDO ret mode */
    +	ldr	r0, virt_sram_ldo_addr
    +	ldr	r1, [r0]
    +	orr	r1, #1
    +	str	r1, [r0]
    +
    +rum_self_refresh_enter_end1:
    +
    +
    +mpu_pll_bypass_start1:
    +#ifdef ImodPmTmp
    +put_pll_bypass:
    +	/* Put the PLLs in bypass mode */
    +	pll_bypass	core, virt_core_clk_mode, virt_core_idlest, core_val
    +	pll_bypass	ddr, virt_ddr_clk_mode, virt_ddr_idlest, ddr_val
    +	pll_bypass	disp, virt_disp_clk_mode, virt_disp_idlest, disp_val
    +	pll_bypass	per, virt_per_clk_mode, virt_per_idlest, per_val
    +#endif
    +	pll_bypass	mpu_1, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val
    +mpu_pll_bypass_end1:
    +
    +	dsb
    +	dmb
    +	isb
    +
    +	wfi
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +
    +mpu_pll_bypass_start2:
    +/* Relock the PLLs */
    +	pll_lock	mpu_ab_1t, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val
    +#ifdef ImodPmTmp
    +	pll_lock	per_abt, virt_per_clk_mode, virt_per_idlest, per_val
    +	pll_lock	disp_abt, virt_disp_clk_mode, virt_disp_idlest, disp_val
    +	pll_lock	ddr_abt, virt_ddr_clk_mode, virt_ddr_idlest, ddr_val
    +	pll_lock	core_abt, virt_core_clk_mode, virt_core_idlest, core_val
    +#endif
    +mpu_pll_bypass_end2:
    +
    +rum_self_refresh_enter_start2:
    +	/* Disable SRAM LDO ret mode */
    +	ldr	r0, virt_sram_ldo_addr
    +	ldr	r1, [r0]
    +	bic	r1, #1
    +	str	r1, [r0]
    +
    +	/* Enable EMIF */
    +	ldr	r1, virt_emif_clkctrl
    +	mov	r2, #0x2
    +	str	r2, [r1]
    +wait_emif_enable:
    +	ldr	r3, [r1]
    +	cmp	r2, r3
    +	bne	wait_emif_enable
    +
    +	/* DDR3 reset override and mDDR mode clear */
    +	ldr	r0, virt_ddr_io_ctrl
    +
    +	/* LPDDR1 io ctrl value write */
    +lpddr1_io_ctrl_abt:
    +	mov	r1, #(0x1 << 28)
    +	str	r1, [r0]
    +
    +	/* Enable VTP */
    +config_vtp_abt:
    +	ldr	r0, virt_ddr_vtp_ctrl
    +	ldr	r1, [r0]
    +	mov	r2, #0x0	@ clear the register
    +	str	r2, [r0]
    +	mov	r2, #0x6	@ write the filter value
    +	str	r2, [r0]
    +
    +	ldr	r1, [r0]
    +	ldr	r2, vtp_enable	@ set the enable bit
    +	orr	r2, r2, r1
    +	str	r2, [r0]
    +
    +	ldr	r1, [r0]	@ toggle the CLRZ bit
    +	bic	r1, #1
    +	str	r1, [r0]
    +
    +	ldr	r1, [r0]
    +	orr	r1, #1
    +	str	r1, [r0]
    +
    +poll_vtp_ready_abt:
    +	ldr	r1, [r0]	@ poll for VTP ready
    +	tst	r1, #(1 << 5)
    +	beq	poll_vtp_ready_abt
    +
    +	/* Restore the pull for DQ, DM */
    +	ldr	r1, virt_ddr_io_pull1
    +	ldr	r2, resume_io_pull_data
    +	str	r2, [r1]
    +	ldr	r1, virt_ddr_io_pull2
    +	ldr	r2, resume_io_pull_data
    +	str	r2, [r1]
    +	/* Disable the pull for CMD2 */
    +	ldr	r1, virt_ddr_cmd2_ioctrl
    +	ldr	r2, resume_io_pull_cmd
    +	str	r2, [r1]
    +	/* Disable the pull for CMD1 */
    +	ldr	r1, virt_ddr_cmd1_ioctrl
    +	ldr	r2, resume_io_pull_cmd
    +	str	r2, [r1]
    +	/* Disable the pull for CMD0 */
    +	ldr	r1, virt_ddr_cmd0_ioctrl
    +	ldr	r2, resume_io_pull_cmd
    +	str	r2, [r1]
    +
    +	/* Restore EMIF control of CKE */
    +	ldr	r1, virt_ddr_cke_ctrl
    +	mov	r2, #1
    +	str	r2, [r1]
    +
    +emif_self_refresh_dis:
    +	disable_emif_self_refresh	emif_addr_virt
    +
    +/*
    + * A write to SDRAM CONFIG register triggers
    + * an init sequence and hence it must be done
    + * at the end
    + */
    +	ldr r0,	emif_addr_virt
    +	add r0,	r0, #EMIF4_0_SDRAM_CONFIG
    +	ldr r4,	emif_sdcfg_val
    +	str r4,	[r0]
    +
    +	mov r0,	#0x2000
    +wait_loop4:
    +	subs	r0, r0, #1
    +	bne	wait_loop4
    +rum_self_refresh_enter_end2:
    +
    +
    +	mov	r0, #7
    +	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +	nop
    +
    +
    +ENTRY(am33xx_resume_offset_idle)
    +	.word . - am33xx_do_wfi_idle
    +
    +ENTRY(am33xx_resume_from_deep_sleep_idle)
    +
    +#ifdef  ImodPmTmp_SLEEP 
    +
    +	/* Take the PLLs out of LP_BYPASS */
    +	pll_lock	mpu, phys_mpu_clk_mode, phys_mpu_idlest, mpu_val
    +	pll_lock	per, phys_per_clk_mode, phys_per_idlest, per_val
    +	pll_lock	disp, phys_disp_clk_mode, phys_disp_idlest, disp_val
    +	pll_lock	ddr, phys_ddr_clk_mode, phys_ddr_idlest, ddr_val
    +	pll_lock	core, phys_core_clk_mode, phys_core_idlest, core_val
    +
    +	ldr	r6, mem_type
    +	cmp	r6, #MEM_TYPE_DDR2
    +	beq	ddr2_resume_seq
    +
    +	cmp	r6, #MEM_TYPE_LPDDR1
    +	beq	lpddr1_resume_seq
    +
    +	/* DDR3 resume path */
    +
    +	/* Disable SRAM LDO ret mode */
    +	ldr	r0, phys_sram_ldo_addr
    +	ldr	r1, [r0]
    +	bic	r1, #1
    +	str	r1, [r0]
    +
    +	/* TODO: Put EMIF enable here */
    +
    +	/* mddr mode selection not required for PG2.0 */
    +	ldr	r6, cpu_rev
    +	cmp	r6, #CPU_REV_2
    +	beq	config_vtp3
    +
    +	/* Take out IO of mDDR mode */
    +	ldr	r0, phys_ddr_io_ctrl
    +	ldr	r1, [r0]
    +	bic	r1, r1, #(1 << 28)
    +	str	r1, [r0]
    +
    +config_vtp3:
    +	ldr	r0, phys_ddr_vtp_ctrl
    +	ldr	r1, [r0]
    +	mov	r2, #0x0	@ clear the register
    +	str	r2, [r0]
    +	mov	r2, #0x6	@ write the filter value
    +	str	r2, [r0]
    +
    +	ldr	r1, [r0]
    +	ldr	r2, vtp_enable	@ set the enable bit
    +	orr	r2, r2, r1
    +	str	r2, [r0]
    +
    +	ldr	r1, [r0]	@ toggle the CLRZ bit
    +	bic	r1, #1
    +	str	r1, [r0]
    +
    +	ldr	r1, [r0]
    +	orr	r1, #1
    +	str	r1, [r0]
    +poll_vtp_ready3:
    +	ldr	r1, [r0]	@ poll for VTP ready
    +	tst	r1, #(1 << 5)
    +	beq	poll_vtp_ready3
    +
    +	/* Disable the pull for CMD2 */
    +	ldr	r1, phys_ddr_cmd2_ioctrl
    +	ldr	r2, resume_io_pull_cmd
    +	str	r2, [r1]
    +	/* Disable the pull for CMD1 */
    +	ldr	r1, phys_ddr_cmd1_ioctrl
    +	ldr	r2, resume_io_pull_cmd
    +	str	r2, [r1]
    +	/* Disable the pull for CMD0 */
    +	ldr	r1, phys_ddr_cmd0_ioctrl
    +	ldr	r2, resume_io_pull_cmd
    +	str	r2, [r1]
    +	/* Disable the pull for DATA1 */
    +	ldr	r1, phys_ddr_data1_ioctrl
    +	ldr	r2, resume_io_pull_data
    +	str	r2, [r1]
    +	/* Disable the pull for DATA0 */
    +	ldr	r1, phys_ddr_data0_ioctrl
    +	ldr	r2, resume_io_pull_data
    +	str	r2, [r1]
    +
    +	wait_sdram_config	2
    +
    +	/* Enable VTT_Regulator	on EVM-SK */
    +	ldr	r6, evm_id
    +	cmp	r6, #EVM_SK
    +	bne	no_gpio_toggle3
    +
    +	/*
    +	 * GPIO0 was not disabled during standby for EVM_SK
    +	 * Hence no need to enable it back here.
    +	 */
    +	ldr 	r6, imod_pm_job
    +	cmp	r6, #PM_STANDBY
    +	beq	skip_gpio_enable2
    +
    +	/* Enable GPIO0 for EVM-SK here */
    +	ldr	r1, phys_gpio0_clkctrl
    +	mov	r2, #0x2
    +	str	r2, [r1]
    +wait_gpio0_phys_enable:
    +	ldr	r3, [r1]
    +	cmp	r2, r3
    +	bne	wait_gpio0_phys_enable
    +
    +skip_gpio_enable2:
    +	/* Drive GPIO0_7 HIGH */
    +	ldr	r0, gpio0_phys_addr
    +	ldr	r1, [r0, #OMAP4_GPIO_SETDATAOUT]
    +	mov	r2, #(1 << 7)
    +	str	r2, [r0, #OMAP4_GPIO_SETDATAOUT]
    +
    +no_gpio_toggle3:
    +	emif_context_restore	emif_phys_addr
    +	b	zqcfg
    +
    +	/* DDR2 resume path */
    +lpddr1_resume_seq:
    +ddr2_resume_seq:
    +	/* Disable SRAM LDO ret mode */
    +	ldr	r0, phys_sram_ldo_addr
    +	ldr	r1, [r0]
    +	bic	r1, #1
    +	str	r1, [r0]
    +	
    +	emif_context_restore	emif_phys_addr
    +
    +	/* DDR3 reset override and mDDR mode clear */
    +	ldr	r0, phys_ddr_io_ctrl
    +
    +	/* set different io ctrl value for DDR2 vs. LPDDR1 */
    +	ldr	r6, mem_type
    +	cmp	r6, #MEM_TYPE_LPDDR1
    +	beq	lpddr1_io_ctrl
    +
    +	/* DDR2 io ctrl value write */
    +	mov	r1, #0
    +	str	r1, [r0]
    +	b	config_vtp
    +
    +	/* LPDDR1 io ctrl value write */
    +lpddr1_io_ctrl:
    +	mov	r1, #(1 << 28)
    +	str	r1, [r0]
    +
    +config_vtp:
    +	ldr	r0, phys_ddr_vtp_ctrl
    +	ldr	r1, [r0]
    +	mov	r2, #0x0	@ clear the register
    +	str	r2, [r0]
    +	mov	r2, #0x6	@ write the filter value
    +	str	r2, [r0]
    +
    +	ldr	r1, [r0]
    +	ldr	r2, vtp_enable	@ set the enable bit
    +	orr	r2, r2, r1
    +	str	r2, [r0]
    +
    +	ldr	r1, [r0]	@ toggle the CLRZ bit
    +	bic	r1, #1
    +	str	r1, [r0]
    +
    +	ldr	r1, [r0]
    +	orr	r1, #1
    +	str	r1, [r0]
    +
    +poll_vtp_ready:
    +	ldr	r1, [r0]	@ poll for VTP ready
    +	tst	r1, #(1 << 5)
    +	beq	poll_vtp_ready
    +
    +	/* Restore the pull for DQ, DM */
    +	ldr	r1, phys_ddr_io_pull1
    +	ldr	r2, resume_io_pull_data
    +	str	r2, [r1]
    +
    +	ldr	r1, phys_ddr_io_pull2
    +	ldr	r2, resume_io_pull_data
    +	str	r2, [r1]
    +
    +	/* Disable the pull for CMD2 */
    +	ldr	r1, phys_ddr_cmd2_ioctrl
    +	ldr	r2, resume_io_pull_cmd
    +	str	r2, [r1]
    +	/* Disable the pull for CMD1 */
    +	ldr	r1, phys_ddr_cmd1_ioctrl
    +	ldr	r2, resume_io_pull_cmd
    +	str	r2, [r1]
    +	/* Disable the pull for CMD0 */
    +	ldr	r1, phys_ddr_cmd0_ioctrl
    +	ldr	r2, resume_io_pull_cmd
    +	str	r2, [r1]
    +
    +	/* Restore EMIF control of CKE */
    +	ldr	r1, phys_ddr_cke_ctrl
    +	mov	r2, #1
    +	str	r2, [r1]
    +
    +	/* take EMIF out of self refresh */
    +	disable_emif_self_refresh	emif_phys_addr
    +
    +	/* lpddr1 and DDR2 resume sequence ends */
    +
    +	/*
    +	 * Output impedence calib needed only for DDR3
    +	 * but since the initial state of this will be
    +	 * disabled for DDR2 no harm in restoring the
    +	 * old configuration
    +	 */
    +zqcfg:
    +	ldr	r4, emif_zqcfg_val
    +	str	r4, [r3, #EMIF4_0_ZQ_CONFIG]
    +
    +	/* Write to SDRAM_CONFIG only for DDR2 */
    +	ldr	r6, mem_type
    +	cmp	r6, #MEM_TYPE_DDR2
    +	beq	ddr2_sdcfg
    +
    +	cmp	r6, #MEM_TYPE_LPDDR1
    +	beq	lpddr1_sdcfg
    +
    +	/* For DDR3, make DDR_RESET low via control module */
    +	ldr	r0, phys_ddr_io_ctrl
    +	ldr	r1, [r0]
    +	bic	r1, r1, #(1 << 31)
    +	str	r1, [r0]
    +
    +	b	return_to_ddr
    +
    +	/*
    +	 * A write to SDRAM CONFIG register triggers
    +	 * an init sequence and hence it must be done
    +	 * at the end for DDR2
    +	 */
    +lpddr1_sdcfg:
    +ddr2_sdcfg:
    +	ldr	r4, emif_sdcfg_val
    +	str	r4, [r3, #EMIF4_0_SDRAM_CONFIG]
    +
    +return_to_ddr:
    +	/* Back from la-la-land. Kill some time for sanity to settle in */
    +	mov	r0, #0x1000
    +wait_loop2:
    +	subs	r0, r0, #1
    +	bne	wait_loop2
    +
    +#endif
    +/* #ifdef  ImodPmTmp_SLEEP */
    +
    +
    +	/* We are back. Branch to the common CPU resume routine */
    +ENTRY(am33xx_resume_vector_idle)
    +	ldr	pc, resume_addr
    +
    +/*
    + * Local variables
    + */
    +
    +dcache_flush:
    +	.word   v7_flush_dcache_all
    +resume_addr:
    +	.word	cpu_resume - PAGE_OFFSET + 0x80000000
    +
    +emif_addr_func:
    +	.word	am33xx_get_ram_base
    +emif_phys_addr:
    +	.word	AM33XX_EMIF0_BASE
    +
    +gpio0_addr_func:
    +	.word	am33xx_get_gpio0_base
    +gpio0_phys_addr:
    +	.word	AM33XX_GPIO0_BASE
    +
    +ddr_start:
    +	.word	PAGE_OFFSET
    +
    +virt_mpu_idlest:
    +	.word	AM33XX_CM_IDLEST_DPLL_MPU
    +virt_mpu_clk_mode:
    +	.word	AM33XX_CM_CLKMODE_DPLL_MPU
    +
    +phys_pll_mod:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD
    +phys_mpu_clk_mode:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_MPU_OFFSET
    +phys_mpu_idlest:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_MPU_OFFSET
    +
    +virt_core_idlest:
    +	.word	AM33XX_CM_IDLEST_DPLL_CORE
    +virt_core_clk_mode:
    +	.word	AM33XX_CM_CLKMODE_DPLL_CORE
    +phys_core_clk_mode:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_CORE_OFFSET
    +phys_core_idlest:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_CORE_OFFSET
    +
    +virt_per_idlest:
    +	.word	AM33XX_CM_IDLEST_DPLL_PER
    +virt_per_clk_mode:
    +	.word	AM33XX_CM_CLKMODE_DPLL_PER
    +phys_per_clk_mode:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_PER_OFFSET
    +phys_per_idlest:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_PER_OFFSET
    +
    +virt_disp_idlest:
    +	.word	AM33XX_CM_IDLEST_DPLL_DISP
    +virt_disp_clk_mode:
    +	.word	AM33XX_CM_CLKMODE_DPLL_DISP
    +phys_disp_clk_mode:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_DISP_OFFSET
    +phys_disp_idlest:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_DISP_OFFSET
    +
    +virt_ddr_idlest:
    +	.word	AM33XX_CM_IDLEST_DPLL_DDR
    +virt_ddr_clk_mode:
    +	.word	AM33XX_CM_CLKMODE_DPLL_DDR
    +phys_ddr_clk_mode:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_DDR_OFFSET
    +phys_ddr_idlest:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_DDR_OFFSET
    +
    +virt_sram_ldo_addr:
    +	.word	AM33XX_PRM_LDO_SRAM_MPU_CTRL
    +phys_sram_ldo_addr:
    +	.word	AM33XX_PRM_BASE + AM33XX_PRM_DEVICE_MOD + AM33XX_PRM_LDO_SRAM_MPU_CTRL_OFFSET
    +
    +virt_gpio0_clkctrl:
    +	.word	AM33XX_CM_WKUP_GPIO0_CLKCTRL
    +phys_gpio0_clkctrl:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET
    +
    +virt_emif_clkctrl:
    +	.word	AM33XX_CM_PER_EMIF_CLKCTRL
    +phys_emif_clkctrl:
    +	.word	AM33XX_CM_BASE + AM33XX_CM_PER_MOD + AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET
    +module_disabled_val:
    +	.word	0x30000
    +
    +/* DDR related stuff */
    +virt_ddr_io_ctrl:
    +	.word	AM33XX_CTRL_REGADDR(0x0E04)
    +phys_ddr_io_ctrl:
    +	.word	DDR_IO_CTRL
    +virt_ddr_vtp_ctrl:
    +	.word	AM33XX_CTRL_REGADDR(0x0E0C)
    +phys_ddr_vtp_ctrl:
    +	.word	VTP0_CTRL_REG
    +
    +virt_ddr_cke_ctrl:
    +	.word	AM33XX_CTRL_REGADDR(0x131C)
    +phys_ddr_cke_ctrl:
    +	.word	DDR_CKE_CTRL
    +
    +virt_ddr_cmd0_ioctrl:
    +	.word	AM33XX_CTRL_REGADDR(0x1404)
    +phys_ddr_cmd0_ioctrl:
    +	.word	DDR_CMD0_IOCTRL
    +virt_ddr_cmd1_ioctrl:
    +	.word	AM33XX_CTRL_REGADDR(0x1408)
    +phys_ddr_cmd1_ioctrl:
    +	.word	DDR_CMD1_IOCTRL
    +virt_ddr_cmd2_ioctrl:
    +	.word	AM33XX_CTRL_REGADDR(0x140C)
    +phys_ddr_cmd2_ioctrl:
    +	.word	DDR_CMD2_IOCTRL
    +virt_ddr_data0_ioctrl:
    +	.word	AM33XX_CTRL_REGADDR(0x1440)
    +phys_ddr_data0_ioctrl:
    +	.word	DDR_DATA0_IOCTRL
    +virt_ddr_data1_ioctrl:
    +	.word	AM33XX_CTRL_REGADDR(0x1444)
    +phys_ddr_data1_ioctrl:
    +	.word	DDR_DATA1_IOCTRL
    +vtp_enable:
    +	.word	VTP_CTRL_ENABLE
    +
    +virt_ddr_io_pull1:
    +	.word	AM33XX_CTRL_REGADDR(0x1440)
    +phys_ddr_io_pull1:
    +	.word	AM33XX_CTRL_BASE + (0x1440)
    +virt_ddr_io_pull2:
    +	.word	AM33XX_CTRL_REGADDR(0x1444)
    +phys_ddr_io_pull2:
    +	.word	AM33XX_CTRL_BASE + (0x1444)
    +virt_ddr_io_pull3:
    +	.word	AM33XX_CTRL_REGADDR(0x1448)
    +phys_ddr_io_pull3:
    +	.word	AM33XX_CTRL_BASE + (0x1448)
    +
    +susp_io_pull_data:
    +	.word	0x3FF00003
    +susp_io_pull_cmd1:
    +	.word   0xFFE0018B
    +susp_io_pull_cmd2:
    +	.word   0xFFA0098B
    +
    +resume_io_pull_data:
    +	.word	0x18B
    +resume_io_pull_cmd:
    +	.word	0x18B
    +
    +susp_vtp_ctrl_val:
    +	.word	SUSP_VTP_CTRL_LPDDR1
    +mem_type:
    +	.word	0xDEADBEEF
    +evm_id:
    +	.word	0xDEADBEEF
    +cpu_rev:
    +	.word	0xDEADBEEF
    +imod_pm_job:
    +	.word	0xDEADBEEF
    +emif_addr_virt:
    +	.word	0xDEADBEEF
    +gpio0_addr_virt:
    +	.word	0xDEADBEEF
    +emif_rd_lat_val:
    +	.word	0xDEADBEEF
    +emif_timing1_val:
    +	.word	0xDEADBEEF
    +emif_timing2_val:
    +	.word	0xDEADBEEF
    +emif_timing3_val:
    +	.word	0xDEADBEEF
    +emif_sdcfg_val:
    +	.word	0xDEADBEEF
    +emif_ref_ctrl_val:
    +	.word	0xDEADBEEF
    +emif_zqcfg_val:
    +	.word	0xDEADBEEF
    +emif_pmcr_val:
    +	.word	0xDEADBEEF
    +emif_pmcr_shdw_val:
    +	.word	0xDEADBEEF
    +
    +/* PLL CLKMODE before suspend */
    +clk_mode_mpu_val:
    +	.word	0xDEADBEEF
    +clk_mode_per_val:
    +	.word	0xDEADBEEF
    +clk_mode_disp_val:
    +	.word	0xDEADBEEF
    +clk_mode_ddr_val:
    +	.word	0xDEADBEEF
    +clk_mode_core_val:
    +	.word	0xDEADBEEF
    +
    +ENTRY(am33xx_do_wfi_sz_idle)
    +	.word	. - am33xx_do_wfi_idle
    
    diff -Naur /view/byu003_rst/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/opp3xxx_data.c /view/byu003_scmV12/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/opp3xxx_data.c
    --- /view/byu003_rst/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/opp3xxx_data.c	2013-06-26 00:37:58.000000000 +0300
    +++ /view/byu003_scmV12/vobs/imod_scm/Development/PSP/SDK-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/arch/arm/mach-omap2/opp3xxx_data.c	2015-07-12 07:43:32.815268000 +0300
    @@ -208,12 +208,19 @@
     #define AM33XX_ES2_1_VDD_MPU_OPPTURBO_UV	1260000
     #define AM33XX_ES2_1_VDD_MPU_OPPNITRO_UV	1325000
     
    -#define OPP_50_300_INDEX	0
    -#define OPP_100_300_INDEX	1
    -#define OPP_100_600_INDEX	2
    -#define OPP_120_720_INDEX	3
    -#define OPP_TURBO_800_INDEX	4
    -#define OPP_NITRO_1GHZ_INDEX	5
    +enum {
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +	OPP_10_50_INDEX =0,
    +	OPP_50_300_INDEX,
    +#else
    +	OPP_50_300_INDEX=0,
    +#endif
    +	OPP_100_300_INDEX,
    +	OPP_100_600_INDEX,
    +	OPP_120_720_INDEX,
    +	OPP_TURBO_800_INDEX,
    +	OPP_NITRO_1GHZ_INDEX
    +};
     
     /* From AM335x TRM, SPRUH73H, Section 9.3.50 */
     #define AM33XX_EFUSE_SMA_OFFSET	0x7fc
    @@ -234,6 +241,11 @@
     #define OPP_NITRO_1GHZ_BIT		(0x1 << 9)
     
     static struct omap_opp_def __initdata am33xx_es2_1_opp_list[] = {
    +#ifdef CONFIG_DENALI_INT_POWER_MANAGEMENT
    +	/* MPU OPP0 - OPP10-50MHz */
    +	OPP_INITIALIZER("mpu", true,   100000000    /*50000000*/,
    +				AM33XX_ES2_1_VDD_MPU_OPP50_UV),
    +#endif
     	/* MPU OPP1 - OPP50-300MHz */
     	OPP_INITIALIZER("mpu", false,  300000000,
     				AM33XX_ES2_1_VDD_MPU_OPP50_UV),