ARM: OMAP: AM33XX: Low power optimizations
authorVaibhav Bedia <vaibhav.bedia@ti.com>
Fri, 23 Mar 2012 05:35:08 +0000 (11:05 +0530)
committerVaibhav Bedia <vaibhav.bedia@ti.com>
Tue, 27 Mar 2012 10:53:18 +0000 (16:23 +0530)
As per the design team, in order to reduce VDDS_DDR
is suspend state the following things must be done:
1. Set the IOs to work in mDDR mode by setting mDDR_SEL
bit in the DDR_IO_CTRL register
2. Enable weak pull down for DQ and DM by configuring
the DDR_DATA0/1_IOCTRL registers
3. Disable VTP and also set P and N in VTP_CTRL to 1.

In the suspend state, A8 SRAM is configured to OFF state,
so to further reduce the power consumption SRAM LDO
is also configured to go to RET mode.

In the resume path all these registers need to restored
back to the pre-suspend state before any access to DDR
happens.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
arch/arm/mach-omap2/pm33xx.h
arch/arm/mach-omap2/sleep33xx.S

index 2c24804320d9527d02d50121b77ff0d7751e3923..3a00eaa96dd489261013259c51536d27bfb36c09 100644 (file)
@@ -47,7 +47,7 @@ struct am33xx_padconf {
 
 #define M3_TXEV_EOI                    (AM33XX_CTRL_BASE + 0x1324)
 #define A8_M3_IPC_REGS                 (AM33XX_CTRL_BASE + 0x1328)
-#define DS_RESUME_ADDR                 0x40300220
+#define DS_RESUME_ADDR                 0x40300340
 #define DS_IPC_DEFAULT                 0xffffffff
 #define M3_UMEM                                0x44D00000
 
index a674a028e9a74ea66d0fd0ef3d2b18175cde5047..69b49ea2497abf800de5c1abbecf9f2ee7ed4520 100644 (file)
@@ -26,6 +26,7 @@
 
 #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
@@ -64,9 +65,17 @@ wait_pll_lock_\name:
        bne     wait_pll_lock_\name
        .endm
 
-       /* Put DDR in Self-Refresh */
+       /* EMIF config for low power mode */
        ldr     r0, emif_addr_func
        blx     r0
+
+       str     r0, emif_addr_virt
+
+       /* Ensure that all the writes to DDR leave the A8 */
+       dsb
+       dmb
+       isb
+
        add     r1, r0, #EMIF4_0_SDRAM_MGMT_CTRL
        ldr     r2, [r1]
        orr     r2, r2, #0xa0           @ a reasonable delay for entering SR
@@ -75,14 +84,42 @@ wait_pll_lock_\name:
        ldr     r2, ddr_start           @ do a dummy access to DDR
        ldr     r3, [r2, #0]
        ldr     r3, [r1, #0]
-       orr     r3, r3, #0x200
+       orr     r3, r3, #0x200          @ now set the LP MODE to Self-Refresh
        str     r3, [r1, #0]
+       str     r2, [r1, #4]            @ write to shadow register also
 
        mov     r1, #0x1000             @ Give some time for the system to enter SR
 wait_sr:
        subs    r1, r1, #1
        bne     wait_sr
 
+       /* Disable EMIF at this point */
+       ldr     r1, virt_emif_clkctrl
+       ldr     r2, [r1]
+       bic     r2, r2, #(3 << 0)
+       str     r2, [r1]
+
+       ldr     r1, virt_emif_clkctrl
+wait_emif_disable:
+       ldr     r2, [r1]
+       ldr     r3, module_disabled_val
+       cmp     r2, r3
+       bne     wait_emif_disable
+
+       /* Weak pull down for DQ, DM */
+       ldr     r1, virt_ddr_io_pull1
+       ldr     r2, susp_io_pull
+       str     r2, [r1]
+
+       ldr     r1, virt_ddr_io_pull2
+       ldr     r2, susp_io_pull
+       str     r2, [r1]
+
+       /* Disable VTP with N & P = 0x1 */
+       ldr     r1, virt_ddr_vtp_ctrl
+       ldr     r2, susp_vtp_ctrl_val
+       str     r2, [r1]
+
        /* IO to work in mDDR mode */
        ldr     r0, virt_ddr_io_ctrl
        ldr     r1, [r0]
@@ -90,6 +127,12 @@ wait_sr:
        mov     r3, r2, lsl #28
        str     r3, [r0]
 
+       /* Enable SRAM LDO ret mode */
+       ldr     r0, virt_sram_ldo_addr
+       ldr     r1, [r0]
+       orr     r1, #1
+       str     r1, [r0]
+
        /* Put the PLLs in bypass mode */
        pll_bypass      core, virt_core_clk_mode, virt_core_idlest
        pll_bypass      ddr, virt_ddr_clk_mode, virt_ddr_idlest
@@ -115,7 +158,6 @@ wait_sr:
        nop
 
        /* We come here in case of an abort */
-       /* Revert the PHY and PLL related changes */
 
        /* Relock the PLLs */
        pll_lock        mpu_abt, virt_mpu_clk_mode, virt_mpu_idlest
@@ -124,12 +166,71 @@ wait_sr:
        pll_lock        ddr_abt, virt_ddr_clk_mode, virt_ddr_idlest
        pll_lock        core_abt, virt_core_clk_mode, virt_core_idlest
 
-       /* IO to work in mDDR mode */
+       /* Disable SRAM LDO ret mode */
+       ldr     r0, virt_sram_ldo_addr
+       ldr     r1, [r0]
+       bic     r1, #1
+       str     r1, [r0]
+
+       /* IO to work in DDR mode */
        ldr     r0, virt_ddr_io_ctrl
        ldr     r1, [r0]
+       mov     r2, #0x0
        mov     r3, r2, lsl #28
        str     r3, [r0]
 
+       /* Restore the pull for DQ, DM */
+       ldr     r1, virt_ddr_io_pull1
+       ldr     r2, resume_io_pull1
+       str     r2, [r1]
+
+       ldr     r1, virt_ddr_io_pull2
+       ldr     r2, resume_io_pull2
+       str     r2, [r1]
+
+       /* 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
+
+       /* 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
+
+       /* Disable EMIF self-refresh */
+       ldr     r0, emif_addr_virt
+       add     r0, r0, #EMIF4_0_SDRAM_MGMT_CTRL
+       ldr     r1, [r0]
+       bic     r1, r1, #(0x7 << 7)
+       str     r1, [r0]
+
        mov     r0, #7
        ldmfd   sp!, {r4 - r11, pc}     @ restore regs and return
 
@@ -154,6 +255,21 @@ wait_sr:
        pll_lock        ddr, phys_ddr_clk_mode, phys_ddr_idlest
        pll_lock        core, phys_core_clk_mode, phys_core_idlest
 
+       /* Disable SRAM LDO ret mode */
+       ldr     r0, phys_sram_ldo_addr
+       ldr     r1, [r0]
+       bic     r1, #1
+       str     r1, [r0]
+
+       /* Restore the pull for DQ, DM */
+       ldr     r1, phys_ddr_io_pull1
+       ldr     r2, resume_io_pull1
+       str     r2, [r1]
+
+       ldr     r1, phys_ddr_io_pull2
+       ldr     r2, resume_io_pull2
+       str     r2, [r1]
+
        /* Disable EMIF self-refresh */
        ldr     r0, emif_phys_addr
        add     r0, r0, #EMIF4_0_SDRAM_MGMT_CTRL
@@ -183,11 +299,17 @@ wait_sr:
 config_vtp:
        ldr     r0, vtp0_addr
        ldr     r1, [r0]
-       ldr     r2, vtp_enable
-       orr     r1, r2
-       str     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]
 
@@ -196,7 +318,7 @@ config_vtp:
        str     r1, [r0]
 
 poll_vtp_ready:
-       ldr     r1, [r0]
+       ldr     r1, [r0]        @ poll for VTP ready
        tst     r1, #(1 << 5)
        beq     poll_vtp_ready
 
@@ -503,6 +625,17 @@ phys_ddr_clk_mode:
 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_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 */
 vtp0_addr:
@@ -564,6 +697,22 @@ 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_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)
 
 ddr_cke_addr:
        .word   DDR_CKE_CTRL
@@ -582,5 +731,21 @@ emif_ref_ctrl_const_val:
 emif_ref_ctrl_val:
        .word   EMIF_SDREF
 
+susp_io_pull:
+       .word   0x3FF00003
+resume_io_pull1:
+       .word   0x18B
+resume_io_pull2:
+       .word   0x18B
+dyn_pd_val:
+       .word   0x100000
+susp_sdram_config:
+       .word   0x40805332
+susp_vtp_ctrl_val:
+       .word   0x10117
+emif_addr_virt:
+       .word   0xDEADBEEF
+
+
 ENTRY(am33xx_do_wfi_sz)
        .word   . - am33xx_do_wfi