diff mbox

[1/1] omap3: Save and restore CM_AUTOIDLE_PLL across off mode

Message ID 1297353724-11665-2-git-send-email-premi@ti.com (mailing list archive)
State Changes Requested
Delegated to: Paul Walmsley
Headers show

Commit Message

Sanjeev Premi Feb. 10, 2011, 4:02 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c
index 96954aa..a775d8a 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c
@@ -178,6 +178,7 @@  struct omap3_cm_regs {
 	u32 per_cm_clksel;
 	u32 emu_cm_clksel;
 	u32 emu_cm_clkstctrl;
+	u32 pll_cm_autoidle;
 	u32 pll_cm_autoidle2;
 	u32 pll_cm_clksel4;
 	u32 pll_cm_clksel5;
@@ -250,6 +251,8 @@  void omap3_cm_save_context(void)
 		omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
 	cm_context.emu_cm_clkstctrl =
 		omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
+	cm_context.pll_cm_autoidle =
+		 omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
 	cm_context.pll_cm_autoidle2 =
 		omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
 	cm_context.pll_cm_clksel4 =
@@ -468,4 +471,14 @@  void omap3_cm_restore_context(void)
 	omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
 			       OMAP3_CM_CLKOUT_CTRL_OFFSET);
 }
+
+
+/**
+ * Returns the value corresponding to CM_AUTOIDLE_PLL from the most recent
+ * context saved before entering the OFF mode.
+ */
+u32 stored_cm_autoidle_pll(void)
+{
+	return cm_context.pll_cm_autoidle;
+}
 #endif
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 8bb85fb..25bd230 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -91,6 +91,8 @@  static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
 static struct powerdomain *core_pwrdm, *per_pwrdm;
 static struct powerdomain *cam_pwrdm;
 
+extern u32 stored_cm_autoidle_pll(void);
+
 static inline void omap3_per_save_context(void)
 {
 	omap_gpio_save_context();
@@ -163,6 +165,25 @@  static void omap3_core_restore_context(void)
 	omap_dma_global_context_restore();
 }
 
+/**
+ * Restore the contents of CM_AUTOIDLE_PLL register.
+ *
+ * The implementation below restores AUTO_CORE_DPLL as 'good' redundancy.
+ */
+static void pll_mod_restore_autoidle(void)
+{
+	u32 ctx = stored_cm_autoidle_pll();
+	u32 val = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+
+	if (ctx & OMAP3430_AUTO_CORE_DPLL_MASK)
+		val |= ctx & OMAP3430_AUTO_CORE_DPLL_MASK;
+
+	if (ctx & OMAP3430_AUTO_PERIPH_DPLL_MASK)
+		val |= ctx & OMAP3430_AUTO_PERIPH_DPLL_MASK;
+
+	omap2_cm_write_mod_reg(val, PLL_MOD, CM_AUTOIDLE);
+}
+
 /*
  * FIXME: This function should be called before entering off-mode after
  * OMAP3 secure services have been accessed. Currently it is only called
@@ -488,8 +509,10 @@  void omap_sram_idle(void)
 	if (per_next_state < PWRDM_POWER_ON) {
 		per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
 		omap2_gpio_resume_after_idle();
-		if (per_prev_state == PWRDM_POWER_OFF)
+		if (per_prev_state == PWRDM_POWER_OFF) {
 			omap3_per_restore_context();
+			pll_mod_restore_autoidle();
+		}
 		omap_uart_resume_idle(2);
 		omap_uart_resume_idle(3);
 	}