summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8ff773a)
raw | patch | inline | side by side (parent: 8ff773a)
author | Vaibhav Bedia <vaibhav.bedia@ti.com> | |
Thu, 8 Mar 2012 14:42:15 +0000 (20:12 +0530) | ||
committer | Vaibhav Bedia <vaibhav.bedia@ti.com> | |
Fri, 9 Mar 2012 19:08:30 +0000 (00:38 +0530) |
When suspending the PHY is programmed in mDDR mode
and the PLLs put in LP bypass mode.
While at it also cleanup the low level assembly code
and PM code. Also fixup the error message in case of
suspend failure
Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
and the PLLs put in LP bypass mode.
While at it also cleanup the low level assembly code
and PM code. Also fixup the error message in case of
suspend failure
Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
index e27fb0029f09ffb918b02c157f4cf574a0543d36..bdb08645c8a5dab5b5fc0808876462805d89c270 100644 (file)
void __iomem *m3_code;
bool enable_deep_sleep = true;
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
static struct device *mpu_dev;
static struct omap_mbox *m3_mbox;
+static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm;
+static struct clockdomain *gfx_l3_clkdm, *gfx_l4ls_clkdm;
static int core_suspend_stat = -1;
static int m3_state = M3_STATE_UNKNOWN;
-static suspend_state_t suspend_state = PM_SUSPEND_ON;
-
-struct a8_wkup_m3_ipc_data {
- int resume_addr;
- int sleep_mode;
- int ipc_data1;
- int ipc_data2;
-} am33xx_lp_ipc;
-
static int am33xx_ipc_cmd(struct a8_wkup_m3_ipc_data *);
static int am33xx_verify_lp_state(void);
static void am33xx_m3_state_machine_reset(void);
-static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm;
-static struct clockdomain *gfx_l3_clkdm, *gfx_l4ls_clkdm;
static DECLARE_COMPLETION(a8_m3_sync);
pr_info("Successfully transitioned all domains to low power state\n");
goto clear_old_status;
} else if (status == 0x10000) {
- pr_info("Could enter low power state\n"
+ pr_info("Could not enter low power state\n"
"Please check for active clocks in PER domain\n");
ret = -1;
goto clear_old_status;
index ed7a0faf5274e0927eab0532d5eb3a9379f39669..67ec84c34b5ed6475ccecf545bf07fcdbf2c7240 100644 (file)
#ifndef __ASSEMBLER__
extern void __iomem *am33xx_get_ram_base(void);
+
+struct a8_wkup_m3_ipc_data {
+ int resume_addr;
+ int sleep_mode;
+ int ipc_data1;
+ int ipc_data2;
+} am33xx_lp_ipc;
#endif /* ASSEMBLER */
#define M3_TXEV_EOI (AM33XX_CTRL_BASE + 0x1324)
#define A8_M3_IPC_REGS (AM33XX_CTRL_BASE + 0x1328)
-#define DS_RESUME_ADDR 0x403000A0
+#define DS_RESUME_ADDR 0x40300220
#define DS_IPC_DEFAULT 0xffffffff
#define M3_UMEM 0x44D00000
diff --git a/arch/arm/mach-omap2/powerdomains33xx_data.c b/arch/arm/mach-omap2/powerdomains33xx_data.c
index 8075f8ac2cace7d44c7982a555c84823644d20da..32a75e5745cd33c6fc8a6bb7bdec1a5667275499 100644 (file)
.prcm_partition = AM33XX_PRM_PARTITION,
.prcm_offs = AM33XX_PRM_GFX_MOD,
.pwrsts = PWRSTS_OFF_ON,
-// .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
.pwrstctrl_offs = AM33XX_PM_GFX_PWRSTCTRL_OFFSET,
.pwrstst_offs = AM33XX_PM_GFX_PWRSTST_OFFSET,
-#if 0
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
.banks = 1,
.pwrsts_mem_ret = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* gfx_mem */
},
-#endif
};
static struct powerdomain rtc_33xx_pwrdm = {
index ceabed0d95015c6a34a3775f40f0bfe9300c299b..a674a028e9a74ea66d0fd0ef3d2b18175cde5047 100644 (file)
ENTRY(am33xx_do_wfi)
stmfd sp!, {r4 - r11, lr} @ save registers on stack
+ .macro pll_bypass, name, clk_mode_addr, idlest_addr
+pll_bypass_\name:
+ ldr r0, \clk_mode_addr
+ ldr r1, [r0]
+ 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_lock_\name:
+ ldr r0, \clk_mode_addr
+ ldr r1, [r0]
+ bic r1, r1, #(7 << 0)
+ orr r1, r1, #0x7
+ str r1, [r0]
+ ldr r0, \idlest_addr
+wait_pll_lock_\name:
+ ldr r1, [r0]
+ tst r1, #0x1
+ bne wait_pll_lock_\name
+ .endm
+
/* Put DDR in Self-Refresh */
ldr r0, emif_addr_func
blx r0
wait_sr:
subs r1, r1, #1
bne wait_sr
- /* What if the system does not enter self-refresh at this point? */
-
- /* The dark arts */
-#if 0
- /* Now put the PHY in low power mode */
-ddr_lp_config:
- add r1, r0, #EMIF4_0_DDR_PHY_CTRL_1
- mov r2, #1
- mov r3, r2, lsl #20
- str r3, [r1]
/* IO to work in mDDR mode */
ldr r0, virt_ddr_io_ctrl
ldr r1, [r0]
+ mov r2, #1
mov r3, r2, lsl #28
str r3, [r0]
-#endif
- /* Put the PLLs to LP bypass */
-#if 0
- ldr r0, virt_mpu_pll_clk_mode_addr
- ldr r1, [r0]
- bic r1, r1, #(7 << 0)
- orr r1, r1, #0x5
- str r1, [r0]
- ldr r0, virt_mpu_pll_idlest_addr
-wait_pll_by1:
- ldr r1, [r0]
- tst r1, #0x0
- bne wait_pll_by1
-
- ldr r0, virt_per_pll_clk_mode_addr
- ldr r1, [r0]
- bic r1, r1, #(7 << 0)
- orr r1, r1, #0x5
- str r1, [r0]
- ldr r0, virt_per_pll_idlest_addr
-wait_pll_by2:
- ldr r1, [r0]
- tst r1, #0x0
- bne wait_pll_by2
-
- ldr r0, virt_disp_pll_clk_mode_addr
- ldr r1, [r0]
- bic r1, r1, #(7 << 0)
- orr r1, r1, #0x5
- str r1, [r0]
- ldr r0, virt_disp_pll_idlest_addr
-wait_pll_by3:
- ldr r1, [r0]
- tst r1, #0x0
- bne wait_pll_by3
-
- ldr r0, virt_ddr_pll_clk_mode_addr
- ldr r1, [r0]
- bic r1, r1, #(7 << 0)
- orr r1, r1, #0x5
- str r1, [r0]
- ldr r0, virt_ddr_pll_idlest_addr
-wait_pll_by4:
- ldr r1, [r0]
- tst r1, #0x0
- bne wait_pll_by4
-
- ldr r0, virt_core_pll_clk_mode_addr
- ldr r1, [r0]
- bic r1, r1, #(7 << 0)
- orr r1, r1, #0x5
- str r1, [r0]
- ldr r0, virt_core_pll_idlest_addr
-wait_pll_by5:
- ldr r1, [r0]
- tst r1, #0x0
- bne wait_pll_by5
-#endif
+ /* 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
+ pll_bypass disp, virt_disp_clk_mode, virt_disp_idlest
+ pll_bypass per, virt_per_clk_mode, virt_per_idlest
+ pll_bypass mpu, virt_mpu_clk_mode, virt_mpu_idlest
dsb
dmb
nop
/* We come here in case of an abort */
- /* We must revert the PHY related changes before we can
- * start accessing DDR again
- */
-#if 0
-catch_race_conditions:
- nop
- b catch_race_conditions
-#endif
+ /* Revert the PHY and PLL related changes */
-#if 0
- add r1, r0, #EMIF4_0_DDR_PHY_CTRL_1
- mov r2, #1
- mov r3, r2, lsl #20
- str r3, [r1]
+ /* Relock the PLLs */
+ pll_lock mpu_abt, virt_mpu_clk_mode, virt_mpu_idlest
+ pll_lock per_abt, virt_per_clk_mode, virt_per_idlest
+ pll_lock disp_abt, virt_disp_clk_mode, virt_disp_idlest
+ 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 */
ldr r0, virt_ddr_io_ctrl
ldr r1, [r0]
mov r3, r2, lsl #28
str r3, [r0]
-#endif
+
mov r0, #7
ldmfd sp!, {r4 - r11, pc} @ restore regs and return
-
- /* Take the PLLs out of LP_BYPASS */
-#if 0
- ldr r1, phys_mpu_pll_clk_mode_addr
- ldr r2, [r1]
- bic r2, r2, #(7 << 0)
- orr r2, r2, #0x7
- str r2, [r1]
- ldr r1, phys_mpu_pll_idlest_addr
-wait_pll_lock1:
- ldr r2, [r1]
- tst r2, #0x1
- bne wait_pll_lock1
-
- ldr r1, phys_core_pll_clk_mode_addr
- ldr r2, [r1]
- bic r2, r2, #(7 << 0)
- orr r2, r2, #0x7
- str r2, [r1]
- ldr r1, phys_core_pll_idlest_addr
-wait_pll_lock2:
- ldr r2, [r1]
- tst r2, #0x1
- bne wait_pll_lock2
-
- ldr r1, phys_per_pll_clk_mode_addr
- ldr r2, [r1]
- bic r2, r2, #(7 << 0)
- orr r2, r2, #0x7
- str r2, [r1]
- ldr r1, phys_per_pll_idlest_addr
-wait_pll_lock3:
- ldr r2, [r1]
- tst r2, #0x1
- bne wait_pll_lock3
-
- ldr r1, phys_disp_pll_clk_mode_addr
- ldr r2, [r1]
- bic r2, r2, #(7 << 0)
- orr r2, r2, #0x7
- str r2, [r1]
- ldr r1, phys_disp_pll_idlest_addr
-wait_pll_lock4:
- ldr r2, [r1]
- tst r2, #0x1
- bne wait_pll_lock4
-
- ldr r1, phys_ddr_pll_clk_mode_addr
- ldr r2, [r1]
- bic r2, r2, #(7 << 0)
- orr r2, r2, #0x7
- str r2, [r1]
- ldr r1, phys_ddr_pll_idlest_addr
-wait_pll_lock5:
- ldr r2, [r1]
- tst r2, #0x1
- bne wait_pll_lock5
-
- ldr r0, emif_phys_addr
- add r0, r0, #EMIF4_0_SDRAM_MGMT_CTRL
- ldr r1, [r0]
- bic r1, r1, #(0x7 << 7)
- str r1, [r0]
-#endif
-
nop
nop
nop
nop
nop
nop
+ nop
+
+ /* Take the PLLs out of LP_BYPASS */
+ pll_lock mpu, phys_mpu_clk_mode, phys_mpu_idlest
+ pll_lock per, phys_per_clk_mode, phys_per_idlest
+ pll_lock disp, phys_disp_clk_mode, phys_disp_idlest
+ pll_lock ddr, phys_ddr_clk_mode, phys_ddr_idlest
+ pll_lock core, phys_core_clk_mode, phys_core_idlest
-#if 0
-ddr_lp_config_revert:
- ldr r0, phys_emif_phy_ctrl_addr
+ /* Disable EMIF self-refresh */
+ ldr r0, emif_phys_addr
+ add r0, r0, #EMIF4_0_SDRAM_MGMT_CTRL
ldr r1, [r0]
- bic r1, r1, #20
+ bic r1, r1, #(0x7 << 7)
str r1, [r0]
/* Take out IO of mDDR mode */
ldr r1, [r0]
bic r1, r1, #28
str r1, [r0]
-#endif
- /* Assume the PLL is locked at this point */
-restore_emif:
- nop
- nop
+/*
+ * Instead of harcoding the EMIF and DDR PHY related settings
+ * in this file, the sane thing to do would have been to backup
+ * the register contents during suspend and restore it back in
+ * the resume path. However, due to the Si errata related to
+ * DDR PHY registers, these registers are read-only. So, we'll
+ * need to hardcode atleast the DDR PHY configuration over here.
+ * We _could_ back up the EMIF registers but in order to be
+ * consistent with the DDR setup procedure we skip this for now.
+ * The person updating the DDR PHY config values is expected
+ * to update the EMIF config values also.
+ */
config_vtp:
ldr r0, vtp0_addr
orr r2, r2, r5
orr r2, r2, r6
orr r2, r2, r7
+ /* Done with crazy bit ops. store it now */
str r2, [r0, #220]
ldr r1, data0_wr_dqs_slave_ratio1_val
mov r2, r1
orr r2, r2, r5
orr r2, r2, r6
orr r2, r2, r7
+ /* Done with crazy bit ops. store it now */
str r2, [r0, #240]
ldr r1, data0_wr_lvl_init_ratio1_val
mov r2, r1
orr r2, r2, r5
orr r2, r2, r6
orr r2, r2, r7
+ /* Done with crazy bit ops. store it now */
str r2, [r0, #248]
ldr r1, data0_gate_lvl_init_ratio1_val
mov r2, r1
orr r2, r2, r5
orr r2, r2, r6
orr r2, r2, r7
+ /* Done with crazy bit ops. store it now */
str r2, [r0, #264]
ldr r1, data0_wr_lvl_slave_ratio1_val
mov r2, r1
orr r2, r2, r5
orr r2, r2, r6
orr r2, r2, r7
+ /* Done with crazy bit ops. store it now */
str r2, [r0, #288]
ldr r1, data0_wr_data_slave_ratio1_val
mov r2, r1
resume_addr:
.word cpu_resume - PAGE_OFFSET + 0x80000000
-#define DPLL_LP_BYP_MODE 0x5
-#define DPLL_LOCK_MODE 0x7
-
emif_addr_func:
.word am33xx_get_ram_base
emif_phys_addr:
ddr_start:
.word PAGE_OFFSET
-mpu_pll_n:
- .word 0xDEADBEEF
-mpu_pll_m:
- .word 0xDEADBEEF
-mpu_pll_m2:
- .word 0xDEADBEEF
-ddr_pll_m2:
- .word 0xDEADBEEF
-ddr_pll_n:
- .word 0xDEADBEEF
-ddr_pll_m:
- .word 0xDEADBEEF
-per_pll_n:
- .word 0xDEADBEEF
-per_pll_m:
- .word 0xDEADBEEF
-per_pll_m2:
- .word 0xDEADBEEF
-
-virt_ddr_io_ctrl:
- .word AM33XX_CTRL_REGADDR(0x0E04)
-phys_ddr_io_ctrl:
- .word 0x44E10E04
-phys_emif_phy_ctrl_addr:
- .word 0x4C0000E4
-
-virt_mpu_pll_idlest_addr:
+virt_mpu_idlest:
.word AM33XX_CM_IDLEST_DPLL_MPU
-virt_mpu_pll_clk_mode_addr:
+virt_mpu_clk_mode:
.word AM33XX_CM_CLKMODE_DPLL_MPU
phys_pll_mod:
.word AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD
-phys_mpu_pll_idlest_addr:
- .word AM33XX_CM_CLKMODE_DPLL_MPU_OFFSET
-phys_mpu_pll_clk_mode_addr:
- .word AM33XX_CM_IDLEST_DPLL_MPU_OFFSET
+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_pll_idlest_addr:
+virt_core_idlest:
.word AM33XX_CM_IDLEST_DPLL_CORE
-virt_core_pll_clk_mode_addr:
+virt_core_clk_mode:
.word AM33XX_CM_CLKMODE_DPLL_CORE
-phys_core_pll_idlest_addr:
- .word AM33XX_CM_CLKMODE_DPLL_CORE_OFFSET
-phys_core_pll_clk_mode_addr:
- .word AM33XX_CM_IDLEST_DPLL_CORE_OFFSET
+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_pll_idlest_addr:
+virt_per_idlest:
.word AM33XX_CM_IDLEST_DPLL_PER
-virt_per_pll_clk_mode_addr:
+virt_per_clk_mode:
.word AM33XX_CM_CLKMODE_DPLL_PER
-phys_per_pll_idlest_addr:
- .word AM33XX_CM_CLKMODE_DPLL_PER_OFFSET
-phys_per_pll_clk_mode_addr:
- .word AM33XX_CM_IDLEST_DPLL_PER_OFFSET
+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_pll_idlest_addr:
+virt_disp_idlest:
.word AM33XX_CM_IDLEST_DPLL_DISP
-virt_disp_pll_clk_mode_addr:
+virt_disp_clk_mode:
.word AM33XX_CM_CLKMODE_DPLL_DISP
-phys_disp_pll_idlest_addr:
- .word AM33XX_CM_CLKMODE_DPLL_DISP_OFFSET
-phys_disp_pll_clk_mode_addr:
- .word AM33XX_CM_IDLEST_DPLL_DISP_OFFSET
+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_pll_idlest_addr:
+virt_ddr_idlest:
.word AM33XX_CM_IDLEST_DPLL_DDR
-virt_ddr_pll_clk_mode_addr:
+virt_ddr_clk_mode:
.word AM33XX_CM_CLKMODE_DPLL_DDR
-phys_ddr_pll_idlest_addr:
- .word AM33XX_CM_CLKMODE_DPLL_DDR_OFFSET
-phys_ddr_pll_clk_mode_addr:
- .word AM33XX_CM_IDLEST_DPLL_DDR_OFFSET
+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
/* DDR related stuff */
control_base:
.word AM33XX_CTRL_BASE
-Rddr_ioctrl_val:
- .word DDR_IOCTRL_VALUE
ddr_io_ctrl_addr:
.word DDR_IO_CTRL
ddr_ioctrl_val:
.word 0x1404
ddr_data_offset:
.word 0x1440
+virt_ddr_io_ctrl:
+ .word AM33XX_CTRL_REGADDR(0x0E04)
+phys_ddr_io_ctrl:
+ .word DDR_IO_CTRL
ddr_cke_addr:
.word DDR_CKE_CTRL