This patch updates omap_sram_idle with CORE OFF support

Signed-off-by: Rajendra Nayak <[EMAIL PROTECTED]>
---
 arch/arm/mach-omap2/cpuidle34xx.c |   37 ++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm.h          |    2 +
 arch/arm/mach-omap2/pm34xx.c      |   43 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+)

Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/cpuidle34xx.c       2008-09-01
18:12:35.000000000 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c    2008-09-01
18:25:25.000000000 +0530
@@ -26,11 +26,48 @@
 #include <mach/pm.h>
 #include <mach/prcm.h>
 #include <mach/powerdomain.h>
+#include <mach/gpmc.h>
 #include <mach/control.h>
+#include <mach/irqs.h>
 #include <linux/sched.h>

 #include "cpuidle34xx.h"

+static int padconf_saved;
+void omap3_save_core_ctx(void)
+{
+       u32 control_padconf_off;
+       if (!padconf_saved) {
+              /* Save the padconf registers */
+              control_padconf_off =
+                       omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_OFF);
+              control_padconf_off |= START_PADCONF_SAVE;
+              omap_ctrl_writel(control_padconf_off,
+                       OMAP343X_CONTROL_PADCONF_OFF);
+              /* wait for the save to complete */
+              while (!omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS)
+                       & PADCONF_SAVE_DONE);
+              padconf_saved = 1;
+       }
+       /* Save the Interrupt controller context */
+       omap3_save_intc_ctx();
+       /* Save the GPMC context */
+       omap3_save_gpmc_ctx();
+       /* Save the system control module context, padconf already save above*/
+       omap3_save_control_ctx();
+}
+
+void omap3_restore_core_ctx(void)
+{
+       /* Restore the control module context, padconf restored by h/w */
+       omap3_restore_control_ctx();
+       /* Restore the GPMC context */
+       omap3_restore_gpmc_ctx();
+       /* Restore the interrupt controller context */
+       omap3_restore_intc_ctx();
+       padconf_saved = 0;
+}
+
 #ifdef CONFIG_CPU_IDLE

 struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c    2008-09-01
18:23:19.000000000 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-09-01 18:24:02.000000000
+0530
@@ -27,10 +27,13 @@
 #include <mach/gpio.h>
 #include <mach/sram.h>
 #include <mach/pm.h>
+#include <mach/prcm.h>
 #include <mach/clockdomain.h>
 #include <mach/powerdomain.h>
 #include <mach/common.h>
 #include <mach/control.h>
+#include <mach/serial.h>
+#include <mach/gpio.h>
 #include <asm/tlbflush.h>

 #include "cm.h"
@@ -58,6 +61,7 @@ static struct powerdomain *mpu_pwrdm, *n
 static struct powerdomain *core_pwrdm, *per_pwrdm;

 int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
+void omap3_restore_sram_ctx(void);

 u32 context_mem[128];

@@ -91,6 +95,16 @@ static void gpio_fclk_mask(u32 *fclk)
        *fclk &= ~(0x1f << 13);
 }

+void omap3_save_per_ctx(void)
+{
+       omap3_gpio_save();
+}
+
+void omap3_restore_per_ctx(void)
+{
+       omap3_gpio_restore();
+}
+
 /* PRCM Interrupt Handler for wakeups */
 static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 {
@@ -225,6 +239,7 @@ void omap_sram_idle(void)
        int mpu_next_state = PWRDM_POWER_ON;
        int per_next_state = PWRDM_POWER_ON;
        int core_next_state = PWRDM_POWER_ON;
+       int core_prev_state, per_prev_state;

        if (!_omap_sram_idle)
                return;
@@ -261,15 +276,27 @@ void omap_sram_idle(void)
                /* PER changes only with core */
                per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
                if (per_next_state < PWRDM_POWER_ON) {
+                       if (per_next_state == PWRDM_POWER_OFF) {
+                               omap3_save_per_ctx();
+                               omap3_save_uart_ctx(2);
+                       }
                        if (clocks_off_while_idle) {
                                per_gpio_clk_disable();
                                omap_serial_enable_clocks(0, 2);
                        }
                }
+               if (core_next_state == PWRDM_POWER_OFF) {
+                       omap3_save_core_ctx();
+                       omap3_save_prcm_ctx();
+                       omap3_save_uart_ctx(0);
+                       omap3_save_uart_ctx(1);
+               }
                if (clocks_off_while_idle) {
                        omap_serial_enable_clocks(0, 0);
                        omap_serial_enable_clocks(0, 1);
                }
+               if (core_next_state == PWRDM_POWER_OFF)
+                       omap3_save_prcm_ctx();
                /* Enable IO-PAD wakeup */
                prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
        }
@@ -284,16 +311,31 @@ void omap_sram_idle(void)
        if (core_next_state < PWRDM_POWER_ON) {
                /* Disable IO-PAD wakeup */
                prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
+               core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
+               if (core_prev_state == PWRDM_POWER_OFF)
+                       omap3_restore_prcm_ctx();
                if (clocks_off_while_idle) {
                        omap_serial_enable_clocks(1, 0);
                        omap_serial_enable_clocks(1, 1);
                }
+               if (core_prev_state == PWRDM_POWER_OFF) {
+                       omap3_restore_core_ctx();
+                       omap3_restore_sram_ctx();
+                       omap3_restore_uart_ctx(0);
+                       omap3_restore_uart_ctx(1);
+               }
                if (per_next_state < PWRDM_POWER_ON) {
                        if (clocks_off_while_idle) {
                                per_gpio_clk_enable();
                                /* This would be actually more effective */
                                omap_serial_enable_clocks(1, 2);
                        }
+                       per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
+                       if (per_prev_state == PWRDM_POWER_OFF) {
+                               omap3_restore_per_ctx();
+                               /* This would be actually more effective */
+                               omap3_restore_uart_ctx(2);
+                       }
                }
                omap2_gpio_resume_after_retention();
        }
@@ -815,6 +857,7 @@ int __init omap3_pm_init(void)
        /* XXX prcm_setup_regs needs to be before enabling hw
         * supervised mode for powerdomains */
        prcm_setup_regs();
+       omap3_save_scratchpad_contents();

        ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
                          (irq_handler_t)prcm_interrupt_handler,
Index: linux-omap-2.6/arch/arm/mach-omap2/pm.h
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm.h        2008-09-01 
18:12:35.000000000
+0530
+++ linux-omap-2.6/arch/arm/mach-omap2/pm.h     2008-09-01 18:24:02.000000000 
+0530
@@ -22,6 +22,8 @@ extern atomic_t sleep_block;

 extern void omap2_block_sleep(void);
 extern void omap2_allow_sleep(void);
+extern void omap3_save_core_ctx(void);
+extern void omap3_restore_core_ctx(void);

 #define OMAP343X_TABLE_ADDRESS_OFFSET  0x31
 #define OMAP343X_TABLE_VALUE_OFFSET    0x30


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to