From patchwork Fri Jul 13 14:19:41 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tero Kristo X-Patchwork-Id: 1196011 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 6EB863FC4C for ; Fri, 13 Jul 2012 14:34:18 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Spgn8-0000au-Ct; Fri, 13 Jul 2012 14:24:22 +0000 Received: from arroyo.ext.ti.com ([192.94.94.40]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1SpgjA-0008Rn-F5 for linux-arm-kernel@lists.infradead.org; Fri, 13 Jul 2012 14:20:20 +0000 Received: from dlelxv30.itg.ti.com ([172.17.2.17]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id q6DEJurt008206; Fri, 13 Jul 2012 09:19:56 -0500 Received: from DFLE71.ent.ti.com (dfle71.ent.ti.com [128.247.5.62]) by dlelxv30.itg.ti.com (8.13.8/8.13.8) with ESMTP id q6DEJube023575; Fri, 13 Jul 2012 09:19:56 -0500 Received: from dlelxv22.itg.ti.com (172.17.1.197) by dfle71.ent.ti.com (128.247.5.62) with Microsoft SMTP Server id 14.1.323.3; Fri, 13 Jul 2012 09:19:56 -0500 Received: from localhost.localdomain (h64-15.vpn.ti.com [172.24.64.15]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id q6DEJn57007873; Fri, 13 Jul 2012 09:19:55 -0500 From: Tero Kristo To: , , Subject: [PATCHv4 4/8] ARM: OMAP3: add manual control for mpu / core pwrdm usecounting Date: Fri, 13 Jul 2012 17:19:41 +0300 Message-ID: <1342189185-5306-5-git-send-email-t-kristo@ti.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1342189185-5306-1-git-send-email-t-kristo@ti.com> References: <1342189185-5306-1-git-send-email-t-kristo@ti.com> MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -6.9 (------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-6.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [192.94.94.40 listed in list.dnswl.org] -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org mpu / core powerdomain usecounts are now statically increased by 1 during MPU activity. This allows the domains to reflect actual usage, and will allow the usecount to reach 0 just before all CPUs are ready to idle. Proper powerdomain usecounts are propageted to voltagedomain level also, and will allow vc callbacks to be triggered at right point of time. Signed-off-by: Tero Kristo Cc: Paul Walmsley Cc: Kevin Hilman Reviewed-by: Rajendra Nayak --- arch/arm/mach-omap2/pm34xx.c | 3 ++ arch/arm/mach-omap2/pm44xx.c | 3 ++ arch/arm/mach-omap2/powerdomain.c | 64 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/powerdomain.h | 3 ++ 4 files changed, 73 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 3a595e8..7c7b173 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -758,6 +758,9 @@ int __init omap3_pm_init(void) omap_pm_suspend = omap3_pm_suspend; #endif + /* Notify pwrdm usecounters about active CPU */ + pwrdm_cpu_wakeup(); + arm_pm_idle = omap3_pm_idle; omap3_idle_init(); diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index ea24174..45eef2d 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -206,6 +206,9 @@ int __init omap4_pm_init(void) omap_pm_suspend = omap4_pm_suspend; #endif + /* Notify pwrdm usecounters about active CPU */ + pwrdm_cpu_wakeup(); + /* Overwrite the default cpu_do_idle() */ arm_pm_idle = omap_default_idle; diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 3b4b15d..39a45a9 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -47,6 +47,7 @@ enum { static LIST_HEAD(pwrdm_list); static struct pwrdm_ops *arch_pwrdm; +static struct powerdomain *mpu_pwrdm, *core_pwrdm; /* Private functions */ @@ -1023,11 +1024,15 @@ void pwrdm_clkdm_disable(struct powerdomain *pwrdm) int pwrdm_pre_transition(void) { pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); + /* Decrease mpu / core usecounts to indicate we are entering idle */ + pwrdm_cpu_idle(); return 0; } int pwrdm_post_transition(void) { + /* Increase mpu / core usecounts to indicate we are leaving idle */ + pwrdm_cpu_wakeup(); pwrdm_for_each(_pwrdm_post_transition_cb, NULL); return 0; } @@ -1107,3 +1112,62 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm) return 0; } + +/** + * pwrdm_get_idle_cycle_pwrdms - init pwrdms needed by idle cycle + * + * MPU and CORE powerdomain states are changed automatically by + * hardware during suspend / cpuidle. Thus, the usecounts for + * these domains will be manually changed during pwrdm_pre_transition + * pwrdm_post_transition callbacks. The callbacks will need pointers + * to the MPU and CORE powerdomains, so this init function is used + * to get those once needed. + */ +static void pwrdm_get_idle_cycle_pwrdms(void) +{ + mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); + if (!mpu_pwrdm) + pr_err_once("%s: failed to get mpu_pwrdm\n", __func__); + + core_pwrdm = pwrdm_lookup("core_pwrdm"); + if (!core_pwrdm) + pr_err_once("%s: failed to get core_pwrdm\n", __func__); +} + +/** + * pwrdm_cpu_wakeup - notify pwrdm usecounters about active CPU + * + * This function must be called just after a CPU has become active. + * Some powerdomains have static dependencies with MPU idle cycle, + * namely mpu_pwrdm and core_pwrdm. These powerdomains will get + * their usecounts increased / decreased each sleep cycle so that + * they reach 0 just before all CPUs have reached idle, and wake-up + * right after it. This allows the dependent voltage domains to + * follow idle cycle properly and trigger their callbacks for + * sleep / wakeup, which in turn will control e.g. auto retention + * feature. + */ +void pwrdm_cpu_wakeup(void) +{ + if (!mpu_pwrdm || !core_pwrdm) + pwrdm_get_idle_cycle_pwrdms(); + + pwrdm_clkdm_enable(mpu_pwrdm); + pwrdm_clkdm_enable(core_pwrdm); +} + +/** + * pwrdm_cpu_idle - notify pwrdm usecounters about idling CPU + * + * This function must be called just before CPU is about to idle. + * Similar to pwrdm_cpu_wakeup, this is used to make sure the idle + * cycle dependent powerdomains follow the sleep cycle properly. + */ +void pwrdm_cpu_idle(void) +{ + if (!mpu_pwrdm || !core_pwrdm) + pwrdm_get_idle_cycle_pwrdms(); + + pwrdm_clkdm_disable(mpu_pwrdm); + pwrdm_clkdm_disable(core_pwrdm); +} diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index 705b983..ecf7d3d 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -220,6 +220,9 @@ int pwrdm_post_transition(void); void pwrdm_clkdm_enable(struct powerdomain *pwrdm); void pwrdm_clkdm_disable(struct powerdomain *pwrdm); +void pwrdm_cpu_wakeup(void); +void pwrdm_cpu_idle(void); + int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm); int pwrdm_get_context_loss_count(struct powerdomain *pwrdm); bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);