From patchwork Wed Jul 18 23:25:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Walmsley X-Patchwork-Id: 1213441 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 44AF6DFFFD for ; Wed, 18 Jul 2012 23:29:10 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1SrdcU-0004kG-Hz; Wed, 18 Jul 2012 23:25:26 +0000 Received: from utopia.booyaka.com ([72.9.107.138]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1SrdcO-0004k2-9Z for linux-arm-kernel@lists.infradead.org; Wed, 18 Jul 2012 23:25:22 +0000 Received: (qmail 7157 invoked by uid 1019); 18 Jul 2012 23:25:16 -0000 Date: Wed, 18 Jul 2012 17:25:16 -0600 (MDT) From: Paul Walmsley To: "Mark A. Greer" Subject: Re: [PATCH 2/2] arm: omap3: am35x: Disable hlt when using Davinci EMAC In-Reply-To: <20120718213246.GD27904@animalcreek.com> Message-ID: References: <1336770778-23044-1-git-send-email-mgreer@animalcreek.com> <1336770778-23044-3-git-send-email-mgreer@animalcreek.com> <20120718213246.GD27904@animalcreek.com> User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -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: khilman@ti.com, linux-omap@vger.kernel.org, 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 On Wed, 18 Jul 2012, Mark A. Greer wrote: > On Tue, Jul 17, 2012 at 09:54:53PM -0600, Paul Walmsley wrote: > > > Want to try something like this? It's your patch but modified to not use > > disable/enable_hlt(). If it doesn't work in your test case, maybe > > try uncommenting that second set of deny_idle / allow_idle ... > > I tested the modified patch (to get it to compile) below. Doh, sorry about that. > It did not work with or without the core_dpll_ck deny_idle/allow_idle > commented out. Here's a version with some of the CPUIdle states restricted. Maybe try this one if you're using CPUIdle? If it happens to work, it would also be interesting to know if it works with the CORE DPLL part commented out. - Paul --- arch/arm/mach-omap2/am35xx-emac.c | 56 ++++++++++++++++++++++++++++++--- arch/arm/mach-omap2/am35xx-emac.h | 13 ++++++-- arch/arm/mach-omap2/board-am3517evm.c | 3 +- arch/arm/mach-omap2/board-cm-t3517.c | 3 +- arch/arm/mach-omap2/cpuidle34xx.c | 5 +++ 5 files changed, 71 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c index 2c90ac6..6b0edcd 100644 --- a/arch/arm/mach-omap2/am35xx-emac.c +++ b/arch/arm/mach-omap2/am35xx-emac.c @@ -16,13 +16,50 @@ */ #include +#include #include #include +#include #include #include #include "control.h" #include "am35xx-emac.h" +static struct clk *mpu_dpll_ck, *core_dpll_ck; + +/* + * Default pm_lats for the am35x. + * The net effect of using am35xx_emac_pm_lats[] is that + * pm_idle or CPUidle won't be called while the emac + * interface is open. This is required because the + * EMAC can't wake up PRCM so if the MPU is executing + * a 'wfi' instruction (e.g., from pm_idle or CPUidle), + * it won't break out of it due to emac activity. + */ +static int am35xx_emac_deactivate_func(struct omap_device *od) +{ + mpu_dpll_ck->ops->deny_idle(mpu_dpll_ck); + core_dpll_ck->ops->deny_idle(core_dpll_ck); + return omap_device_idle_hwmods(od); +} + +static int am35xx_emac_activate_func(struct omap_device *od) +{ + mpu_dpll_ck->ops->allow_idle(mpu_dpll_ck); + core_dpll_ck->ops->allow_idle(core_dpll_ck); + return omap_device_enable_hwmods(od); +} + +struct omap_device_pm_latency am35xx_emac_pm_lats[] = { + { + .deactivate_func = am35xx_emac_deactivate_func, + .activate_func = am35xx_emac_activate_func, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, + }, +}; + +int am35xx_emac_pm_lats_size = ARRAY_SIZE(am35xx_emac_pm_lats); + static void am35xx_enable_emac_int(void) { u32 v; @@ -58,12 +95,14 @@ static struct emac_platform_data am35xx_emac_pdata = { static struct mdio_platform_data am35xx_mdio_pdata; static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh, - void *pdata, int pdata_len) + void *pdata, int pdata_len, + struct omap_device_pm_latency *pm_lats, + int pm_lats_size) { struct platform_device *pdev; pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len, - NULL, 0, false); + pm_lats, pm_lats_size, false); if (IS_ERR(pdev)) { WARN(1, "Can't build omap_device for %s:%s.\n", oh->class->name, oh->name); @@ -73,7 +112,8 @@ static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh, return 0; } -void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) +void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en, + struct omap_device_pm_latency *pm_lats, int pm_lats_size) { struct omap_hwmod *oh; u32 v; @@ -88,7 +128,7 @@ void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) am35xx_mdio_pdata.bus_freq = mdio_bus_freq; ret = omap_davinci_emac_dev_init(oh, &am35xx_mdio_pdata, - sizeof(am35xx_mdio_pdata)); + sizeof(am35xx_mdio_pdata), NULL, 0); if (ret) { pr_err("Could not build davinci_mdio hwmod device\n"); return; @@ -103,12 +143,18 @@ void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) am35xx_emac_pdata.rmii_en = rmii_en; ret = omap_davinci_emac_dev_init(oh, &am35xx_emac_pdata, - sizeof(am35xx_emac_pdata)); + sizeof(am35xx_emac_pdata), + pm_lats, pm_lats_size); if (ret) { pr_err("Could not build davinci_emac hwmod device\n"); return; } + mpu_dpll_ck = clk_get(NULL, "dpll1_ck"); + WARN(!mpu_dpll_ck, "Can't get dpll1_ck\n"); + core_dpll_ck = clk_get(NULL, "dpll3_ck"); + WARN(!core_dpll_ck, "Can't get dpll3_ck\n"); + v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); v &= ~AM35XX_CPGMACSS_SW_RST; omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET); diff --git a/arch/arm/mach-omap2/am35xx-emac.h b/arch/arm/mach-omap2/am35xx-emac.h index 15c6f9c..446a429 100644 --- a/arch/arm/mach-omap2/am35xx-emac.h +++ b/arch/arm/mach-omap2/am35xx-emac.h @@ -5,11 +5,20 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #define AM35XX_DEFAULT_MDIO_FREQUENCY 1000000 #if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) -void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en); +extern struct omap_device_pm_latency am35xx_emac_pm_lats[]; +extern int am35xx_emac_pm_lats_size; + +void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en, + struct omap_device_pm_latency *pm_lats, int pm_lats_size); #else -static inline void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) {} +#define am35xx_emac_pm_lats NULL +#define am35xx_emac_pm_lats_size 0 + +static inline am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en, + struct omap_device_pm_latency *pm_lats, int pm_lats_size) {} #endif diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 18f6010..5348d0d 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -368,7 +368,8 @@ static void __init am3517_evm_init(void) i2c_register_board_info(1, am3517evm_i2c1_boardinfo, ARRAY_SIZE(am3517evm_i2c1_boardinfo)); /*Ethernet*/ - am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); + am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1, + am35xx_emac_pm_lats, am35xx_emac_pm_lats_size); /* MUSB */ am3517_evm_musb_init(); diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index a33ad46..8258057 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -292,7 +292,8 @@ static void __init cm_t3517_init(void) cm_t3517_init_rtc(); cm_t3517_init_usbh(); cm_t3517_init_hecc(); - am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); + am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1, + am35xx_emac_pm_lats, am35xx_emac_pm_lats_size); } MACHINE_START(CM_T3517, "Compulab CM-T3517") diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index f2a49a4..d95dd8c 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -291,6 +291,7 @@ struct cpuidle_driver omap3_idle_driver = { .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C3", .desc = "MPU RET + CORE ON", + .disable = 1, }, { .enter = omap3_enter_idle_bm, @@ -299,6 +300,7 @@ struct cpuidle_driver omap3_idle_driver = { .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C4", .desc = "MPU OFF + CORE ON", + .disable = 1, }, { .enter = omap3_enter_idle_bm, @@ -307,6 +309,7 @@ struct cpuidle_driver omap3_idle_driver = { .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C5", .desc = "MPU RET + CORE RET", + .disable = 1, }, { .enter = omap3_enter_idle_bm, @@ -315,6 +318,7 @@ struct cpuidle_driver omap3_idle_driver = { .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C6", .desc = "MPU OFF + CORE RET", + .disable = 1, }, { .enter = omap3_enter_idle_bm, @@ -323,6 +327,7 @@ struct cpuidle_driver omap3_idle_driver = { .flags = CPUIDLE_FLAG_TIME_VALID, .name = "C7", .desc = "MPU OFF + CORE OFF", + .disable = 1, }, }, .state_count = ARRAY_SIZE(omap3_idle_data),