From: Toshihiro Kobayashi Date: Tue, 10 May 2005 20:47:01 +0000 (-0700) Subject: [PATCH] OMAP: DSP pm fix X-Git-Tag: v2.6.13-omap1~152 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=e9d0d7cd810deb957167a72e861205866daee459;p=linux-2.6-omap-h63xx.git [PATCH] OMAP: DSP pm fix 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 Signed-off-by: Tony Lindgren --- diff --git a/arch/arm/mach-omap/dsp/dsp_common.c b/arch/arm/mach-omap/dsp/dsp_common.c index 175cb987702..e24c1afbbad 100644 --- a/arch/arm/mach-omap/dsp/dsp_common.c +++ b/arch/arm/mach-omap/dsp/dsp_common.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -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 diff --git a/arch/arm/mach-omap/dsp/dsp_ctl.c b/arch/arm/mach-omap/dsp/dsp_ctl.c index 3c65bf06b85..f9fe7c6a475 100644 --- a/arch/arm/mach-omap/dsp/dsp_ctl.c +++ b/arch/arm/mach-omap/dsp/dsp_ctl.c @@ -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: diff --git a/arch/arm/mach-omap/pm.c b/arch/arm/mach-omap/pm.c index 2d35de9f6fd..f97b60741ce 100644 --- a/arch/arm/mach-omap/pm.c +++ b/arch/arm/mach-omap/pm.c @@ -52,6 +52,7 @@ #include #include #include +#include #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<