From patchwork Fri Aug 26 02:33:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Lee X-Patchwork-Id: 111698 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 10523B70C6 for ; Fri, 26 Aug 2011 12:33:55 +1000 (EST) Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QwmEr-00048U-9T; Fri, 26 Aug 2011 02:33:45 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QwmEq-0004m6-GX; Fri, 26 Aug 2011 02:33:44 +0000 Received: from mail-gx0-f177.google.com ([209.85.161.177]) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QwmEV-0004iq-GY for linux-arm-kernel@lists.infradead.org; Fri, 26 Aug 2011 02:33:26 +0000 Received: by gxk2 with SMTP id 2so2734730gxk.36 for ; Thu, 25 Aug 2011 19:33:19 -0700 (PDT) Received: by 10.91.54.8 with SMTP id g8mr243271agk.138.1314325999807; Thu, 25 Aug 2011 19:33:19 -0700 (PDT) Received: from b18647-20 ([64.31.34.40]) by mx.google.com with ESMTPS id c5sm1097809anh.1.2011.08.25.19.33.18 (version=SSLv3 cipher=OTHER); Thu, 25 Aug 2011 19:33:19 -0700 (PDT) From: Robert Lee To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/2] Adding support for the plat-mxc cpuidle driver to mach-mx5. Tested on i.MX51 Babbage board with ARM core running at 800Mhz. Idle OS ARM core power before patch = ~400mW. Idle OS ARM core power after patch = ~1.25mW. Date: Thu, 25 Aug 2011 21:33:15 -0500 Message-Id: <1314325995-29118-2-git-send-email-rob.lee@linaro.org> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1314325995-29118-1-git-send-email-rob.lee@linaro.org> References: <1314325995-29118-1-git-send-email-rob.lee@linaro.org> X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110825_223323_669361_8D7C4E09 X-CRM114-Status: GOOD ( 18.75 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.161.177 listed in list.dnswl.org] Cc: rob.lee@linaro.org, s.hauer@pengutronix.de, amit.kucheria@linaro.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org Signed-off-by: Robert Lee --- arch/arm/mach-mx5/Kconfig | 4 ++ arch/arm/mach-mx5/include/mach/cpuidle.h | 45 ++++++++++++++++++++++++++++++ arch/arm/mach-mx5/system.c | 42 ++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-mx5/include/mach/cpuidle.h diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index b4e7c58..1672cfe 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -19,6 +19,7 @@ config SOC_IMX50 select ARCH_MXC_IOMUX_V3 select ARCH_MXC_AUDMUX_V2 select ARCH_HAS_CPUFREQ + select ARCH_HAS_CPUIDLE select ARCH_MX5 select ARCH_MX50 @@ -30,6 +31,7 @@ config SOC_IMX51 select ARCH_MXC_IOMUX_V3 select ARCH_MXC_AUDMUX_V2 select ARCH_HAS_CPUFREQ + select ARCH_HAS_CPUIDLE select ARCH_MX5 config SOC_IMX53 @@ -38,9 +40,11 @@ config SOC_IMX53 select ARM_L1_CACHE_SHIFT_6 select MXC_TZIC select ARCH_MXC_IOMUX_V3 + select ARCH_HAS_CPUIDLE select ARCH_MX5 select ARCH_MX53 + if ARCH_MX50_SUPPORTED #comment "i.MX50 machines:" diff --git a/arch/arm/mach-mx5/include/mach/cpuidle.h b/arch/arm/mach-mx5/include/mach/cpuidle.h new file mode 100644 index 0000000..6c37963 --- /dev/null +++ b/arch/arm/mach-mx5/include/mach/cpuidle.h @@ -0,0 +1,45 @@ +/* + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ARCH_ARM_PLAT_MXC_CPUIDLE_H__ +#define __ARCH_ARM_PLAT_MXC_CPUIDLE_H__ + + +/* CPUIDLE state parameters: name, description, exit_latency (us) + * exit_latencies were tested using i.MX51 running at 160MHz P-state + * for worst case latencies as to not cause a pm_qos violation when + * running at lower speeds. + */ +#define MXC_CPUIDLE_TABLE {\ +MXC_X_MACRO(POWERED_CLOCKED, "idle cpu clocked, powered.", 12),\ +MXC_X_MACRO(POWERED_NOCLOCK, "idle cpu powered, unclocked.", 14),\ +MXC_X_MACRO(NOPOWER_NOCLOCK, "idle cpu unpowered, unclocked.", 20),\ +MXC_X_MACRO(MXC_NUM_CPUIDLE_STATES, "", -1)} + +#define MXC_X_MACRO(a, b, c) a +enum MXC_CPUIDLE_STATE_NAME MXC_CPUIDLE_TABLE; +#undef MXC_X_MACRO + +struct imx_cpuidle_params { + unsigned int latency; +}; + +void imx_cpu_do_idle(int cpuidle_state_num); + +/* if you want to override the mach level params at the board level, + * define MXC_OVERRIDE_CPUIDLE_PARAMS and pass your board level paramaters + * into the imx_cpuidle_board_params function */ + +/* #define MXC_OVERRIDE_DEFAULT_CPUIDLE_PARAMS */ + +#ifdef CONFIG_MXC_CPUIDLE +extern void imx_cpuidle_board_params(struct imx_cpuidle_params *cpuidle_params); +#else +inline void imx_cpuidle_board_params(struct imx_cpuidle_params *cpuidle_params) +{} +#endif + +#endif /* #ifndef __ARCH_ARM_PLAT_MXC_CPUIDLE_H__ */ diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c index 76ae8dc..6ff938d 100644 --- a/arch/arm/mach-mx5/system.c +++ b/arch/arm/mach-mx5/system.c @@ -12,9 +12,16 @@ */ #include #include +#include +#include #include +#include +#include #include "crm_regs.h" +static int arch_idle_mode = WAIT_UNCLOCKED_POWER_OFF; +static struct clk *gpc_dvfs_clk; + /* set cpu low power mode before WFI instruction. This function is called * mx5 because it can be used for mx50, mx51, and mx53.*/ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) @@ -82,3 +89,38 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR); } } + +void imx_cpu_do_idle(int cpuidle_state_num) +{ + + int local_arch_idle_mode = arch_idle_mode; + + if (gpc_dvfs_clk == NULL) + gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk"); + /* gpc clock is needed for SRPG */ + clk_enable(gpc_dvfs_clk); + + /* convert MXC_CPUIDLE_STATE_NAME to mxc_cpu_pwr_mode. */ + switch (cpuidle_state_num) { + case POWERED_CLOCKED: + local_arch_idle_mode = WAIT_CLOCKED; + break; + case POWERED_NOCLOCK: + local_arch_idle_mode = WAIT_UNCLOCKED; + break; + case NOPOWER_NOCLOCK: + local_arch_idle_mode = WAIT_UNCLOCKED_POWER_OFF; + break; + default: + break; + } + /* prepare registers for upcoming idle mode */ + mx5_cpu_lp_set(local_arch_idle_mode); + + /* enter wfi state which on i.MX5 can trigger */ + cpu_do_idle(); + + clk_disable(gpc_dvfs_clk); +} + +