]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
[PATCH] OMAP: DSP pm fix
authorToshihiro Kobayashi <Toshihiro.Kobayashi@nokia.com>
Tue, 10 May 2005 20:47:01 +0000 (13:47 -0700)
committerTony Lindgren <tony@atomide.com>
Tue, 10 May 2005 20:47:01 +0000 (13:47 -0700)
This is a fix for pm code with regard to the DSP.

In the current code we have a problem that DSP won't
re-enabled after suspend if DSP is just turned on
(with idle request) from McBSP  driver but not used
by DSP Gateway.

I moved DSP related code from pm.c to dsp_common.c.
With this patch DSP will be resumed to the original state
after suspend, whichever state (reset / idling for
McBSP / running with DSP Gateway) DSP was in.

Signed-off-by: Toshihiro Kobayashi <Toshihiro.Kobayashi@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap/dsp/dsp_common.c
arch/arm/mach-omap/dsp/dsp_ctl.c
arch/arm/mach-omap/pm.c
include/asm-arm/arch-omap/dsp_common.h

index 175cb987702a237c327cf3ae3b7b38fe3a2e52d6..e24c1afbbaddf3d5806e4df1a11a227ee4fe1e4b 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
+#include <asm/io.h>
 #include <asm/tlbflush.h>
 #include <asm/irq.h>
 #include <asm/arch/dsp.h>
@@ -162,6 +163,43 @@ void dsp_set_idle_boot_base(unsigned long adr, size_t size)
                dsp_idle();
 }
 
+static unsigned short save_dsp_idlect2;
+
+/*
+ * note: if we are in pm_suspend / pm_resume function,
+ * we are out of clk_use() management.
+ */
+void omap_dsp_pm_suspend(void)
+{
+       unsigned short save_arm_idlect2;
+
+       /* Reset DSP */
+       __dsp_reset();
+
+       clk_disable(dsp_ck_handle);
+
+       /* Stop any DSP domain clocks */
+       save_arm_idlect2 = omap_readw(ARM_IDLECT2); // api_ck is in ARM_IDLECT2
+       clk_enable(api_ck_handle);
+       save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
+       __raw_writew(0, DSP_IDLECT2);
+       omap_writew(save_arm_idlect2, ARM_IDLECT2);
+}
+
+void omap_dsp_pm_resume(void)
+{
+       unsigned short save_arm_idlect2;
+
+       /* Restore DSP domain clocks */
+       save_arm_idlect2 = omap_readw(ARM_IDLECT2); // api_ck is in ARM_IDLECT2
+       clk_enable(api_ck_handle);
+       __raw_writew(save_dsp_idlect2, DSP_IDLECT2);
+       omap_writew(save_arm_idlect2, ARM_IDLECT2);
+
+       /* Run DSP, if it was running */
+       if (dsp_runstat != RUNSTAT_RESET)
+               __dsp_run();
+}
 static int init_done;
 
 static int __init omap_dsp_init(void)
@@ -216,6 +254,8 @@ void omap_dsp_request_idle(void)
 
 arch_initcall(omap_dsp_init);
 
+EXPORT_SYMBOL(omap_dsp_pm_suspend);
+EXPORT_SYMBOL(omap_dsp_pm_resume);
 EXPORT_SYMBOL(omap_dsp_request_idle);
 
 #ifdef CONFIG_OMAP_DSP_MODULE
index 3c65bf06b85f49fedebd17753f8b211b5fe9e6b5..f9fe7c6a475b0f969c8b1599f00ac1c7b375c42e 100644 (file)
@@ -271,8 +271,6 @@ int dsp_suspend(void)
                return -ERESTARTSYS;
 
        if (!dsp_is_ready()) {
-               printk(KERN_WARNING
-                      "omapdsp: DSP is not ready. suspend failed.\n");
                ret = -EINVAL;
                goto up_out;
        }
@@ -288,7 +286,6 @@ int dsp_suspend(void)
        }
 
        udelay(100);
-       dsp_reset();
        cfgstat = CFG_SUSPEND;
 up_out:
        up(&ioctl_sem);
@@ -301,7 +298,6 @@ int dsp_resume(void)
                return 0;
 
        cfgstat = CFG_READY;
-       dsp_run();
        return 0;
 }
 
@@ -433,11 +429,15 @@ static int dsp_ctl_ioctl(struct inode *inode, struct file *file,
                break;
 
        case OMAP_DSP_IOCTL_SUSPEND:
-               ret = dsp_suspend();
+               if ((ret = dsp_suspend()) < 0)
+                       break;
+               dsp_reset();
                break;
 
        case OMAP_DSP_IOCTL_RESUME:
-               ret = dsp_resume();
+               if ((ret = dsp_resume()) < 0)
+                       break;
+               dsp_run();
                break;
 
        case OMAP_DSP_IOCTL_REGMEMR:
index 2d35de9f6fd2a7cc199afcc08c16e499dec132c8..f97b60741ceb3ef5e967e211d0b0a59988550e34 100644 (file)
@@ -52,6 +52,7 @@
 #include <asm/arch/pm.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/tps65010.h>
+#include <asm/arch/dsp_common.h>
 
 #include "clock.h"
 
@@ -161,7 +162,6 @@ void omap_pm_suspend(void)
 {
        unsigned long arg0 = 0, arg1 = 0;
        int (*func_ptr)(unsigned short, unsigned short) = NULL;
-       unsigned short save_dsp_idlect2;
 
        printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
 
@@ -229,20 +229,7 @@ void omap_pm_suspend(void)
         * Step 4: OMAP DSP Shutdown
         */
 
-       /* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */
-       omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE,
-                   ARM_RSTCT1);
-
-       /* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */
-        omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG);
-
-       /* Set EN_DSPCK = 0, stop DSP block clock */
-       omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL);
-
-       /* Stop any DSP domain clocks */
-       omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
-       save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
-       __raw_writew(0, DSP_IDLECT2);
+       omap_dsp_pm_suspend();
 
        /*
         * Step 5: Wakeup Event Setup
@@ -295,9 +282,7 @@ void omap_pm_suspend(void)
         */
 
        /* Restore DSP clocks */
-       omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
-       __raw_writew(save_dsp_idlect2, DSP_IDLECT2);
-       ARM_RESTORE(ARM_IDLECT2);
+       omap_dsp_pm_resume();
 
        /*
         * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
index 2cad37e1ae8384b7b06baf38ff2bebbf1e5e0f29..9931e325ebc0b3d921c7108cfd20bf5b2ca9062f 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef ASM_ARCH_DSP_COMMON_H
 #define ASM_ARCH_DSP_COMMON_H
 
+void omap_dsp_pm_suspend(void);
+void omap_dsp_pm_resume(void);
 void omap_dsp_request_idle(void);
 
 #endif /* ASM_ARCH_DSP_COMMON_H */