From patchwork Tue Jan 20 08:17:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenyou Yang X-Patchwork-Id: 5666161 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D3224C058D for ; Tue, 20 Jan 2015 08:25:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D936320389 for ; Tue, 20 Jan 2015 08:25:28 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6C49F20386 for ; Tue, 20 Jan 2015 08:25:27 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YDU5T-0002hF-2z; Tue, 20 Jan 2015 08:22:59 +0000 Received: from eusmtp01.atmel.com ([212.144.249.242]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YDU5E-0002Md-8W for linux-arm-kernel@lists.infradead.org; Tue, 20 Jan 2015 08:22:46 +0000 Received: from apsmtp01.atmel.com (10.168.254.30) by eusmtp01.atmel.com (10.161.101.30) with Microsoft SMTP Server id 14.2.347.0; Tue, 20 Jan 2015 09:22:18 +0100 Received: from shaarm01.corp.atmel.com (10.168.254.13) by apsmtp01.corp.atmel.com (10.168.254.30) with Microsoft SMTP Server id 14.2.347.0; Tue, 20 Jan 2015 16:24:13 +0800 From: Wenyou Yang To: , Subject: [PATCH 07/12] pm: at91: the standby mode uses the same sram function as the suspend to memory mode Date: Tue, 20 Jan 2015 16:17:00 +0800 Message-ID: <1421741825-18226-8-git-send-email-wenyou.yang@atmel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1421741825-18226-1-git-send-email-wenyou.yang@atmel.com> References: <1421741825-18226-1-git-send-email-wenyou.yang@atmel.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150120_002244_752993_01E081B9 X-CRM114-Status: GOOD ( 14.89 ) X-Spam-Score: -0.0 (/) Cc: sylvain.rochet@finsecur.com, linux-kernel@vger.kernel.org, wenyou.yang@atmel.com, alexandre.belloni@free-electrons.com, peda@axentia.se, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP To simply the PM code, the suspend to standby mode uses the same sram function as the suspend to memory mode, running in the internal SRAM, instead of the respective code for each mode. But for the suspend to standby mode, the master clock doesn't switch to the slow clock, and the main oscillator doesn't turn off as well. Signed-off-by: Wenyou Yang Acked-by: Alexandre Belloni --- arch/arm/mach-at91/pm.c | 81 ++++++++++++++++--------------------- arch/arm/mach-at91/pm.h | 6 +++ arch/arm/mach-at91/pm_slowclock.S | 18 +++++++++ 3 files changed, 59 insertions(+), 46 deletions(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 691e6db..a1010f0 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -145,62 +145,51 @@ extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, void __iomem *ramc1, int memctrl); extern u32 at91_slow_clock_sz; +static void at91_pm_suspend(suspend_state_t state) +{ + unsigned int pm_data = at91_pm_data.memctrl; + + pm_data |= (state == PM_SUSPEND_MEM) ? + (AT91_PM_SLOW_CLOCK << AT91_PM_MODE_OFFSET) : 0; + + slow_clock(at91_pmc_base, at91_ramc_base[0], + at91_ramc_base[1], pm_data); +} + static int at91_pm_enter(suspend_state_t state) { at91_pinctrl_gpio_suspend(); switch (state) { + /* + * Suspend-to-RAM is like STANDBY plus slow clock mode, so + * drivers must suspend more deeply, the master clock switches + * to the clk32k and turns off the main oscillator + * + * STANDBY mode has *all* drivers suspended; ignores irqs not + * marked as 'wakeup' event sources; and reduces DRAM power. + * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and + * nothing fancy done with main or cpu clocks. + */ + case PM_SUSPEND_MEM: + case PM_SUSPEND_STANDBY: /* - * Suspend-to-RAM is like STANDBY plus slow clock mode, so - * drivers must suspend more deeply: only the master clock - * controller may be using the main oscillator. + * Ensure that clocks are in a valid state. */ - case PM_SUSPEND_MEM: - /* - * Ensure that clocks are in a valid state. - */ - if (!at91_pm_verify_clocks()) - goto error; - - /* - * Enter slow clock mode by switching over to clk32k and - * turning off the main oscillator; reverse on wakeup. - */ - if (slow_clock) { - slow_clock(at91_pmc_base, at91_ramc_base[0], - at91_ramc_base[1], - at91_pm_data.memctrl); - break; - } else { - pr_info("AT91: PM - no slow clock mode enabled ...\n"); - /* FALLTHROUGH leaving master clock alone */ - } + if (!at91_pm_verify_clocks()) + goto error; - /* - * STANDBY mode has *all* drivers suspended; ignores irqs not - * marked as 'wakeup' event sources; and reduces DRAM power. - * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and - * nothing fancy done with main or cpu clocks. - */ - case PM_SUSPEND_STANDBY: - /* - * NOTE: the Wait-for-Interrupt instruction needs to be - * in icache so no SDRAM accesses are needed until the - * wakeup IRQ occurs and self-refresh is terminated. - * For ARM 926 based chips, this requirement is weaker - * as at91sam9 can access a RAM in self-refresh mode. - */ - if (at91_pm_standby) - at91_pm_standby(); - break; + at91_pm_suspend(state); - case PM_SUSPEND_ON: - cpu_do_idle(); - break; + break; - default: - pr_debug("AT91: PM - bogus suspend state %d\n", state); - goto error; + case PM_SUSPEND_ON: + cpu_do_idle(); + break; + + default: + pr_debug("AT91: PM - bogus suspend state %d\n", state); + goto error; } error: diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 7664d39..fbfea42 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -15,6 +15,12 @@ #include +#define AT91_PM_MEMCTRL_MASK 0x0f +#define AT91_PM_MODE_OFFSET 4 +#define AT91_PM_MODE_MASK 0x0f + +#define AT91_PM_SLOW_CLOCK 0x01 + /* * On all at91 except rm9200 and x40 have the System Controller starts * at address 0xffffc000 and has a size of 16KiB. diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 634d819..92d7e63 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -15,12 +15,15 @@ #include #include +#include "pm.h" + pmc .req r0 sdramc .req r1 ramc1 .req r2 memctrl .req r3 tmp1 .req r4 tmp2 .req r5 +mode .req r6 /* * Wait until master clock is ready (after switching master clock source) @@ -72,6 +75,13 @@ ENTRY(at91_slow_clock) mov tmp1, #0 mcr p15, 0, tmp1, c7, c10, 4 + mov tmp1, memctrl + mov tmp2, tmp1, lsr#AT91_PM_MODE_OFFSET + and mode, tmp2, #AT91_PM_MODE_MASK + + mov tmp1, memctrl + and memctrl, tmp1, #AT91_PM_MEMCTRL_MASK + cmp memctrl, #AT91_MEMCTRL_MC bne ddr_sr_enable @@ -144,6 +154,9 @@ sdr_sr_enable: str tmp1, [sdramc, #AT91_SDRAMC_LPR] sdr_sr_done: + tst mode, #AT91_PM_SLOW_CLOCK + beq skip_disable_clock + /* Save Master clock setting */ ldr tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, .saved_mckr @@ -169,9 +182,13 @@ sdr_sr_done: bic tmp1, tmp1, #AT91_PMC_MOSCEN str tmp1, [pmc, #AT91_CKGR_MOR] +skip_disable_clock: /* Wait for interrupt */ mcr p15, 0, tmp1, c7, c0, 4 + tst mode, #AT91_PM_SLOW_CLOCK + beq skip_enable_clock + /* Turn on the main oscillator */ ldr tmp1, [pmc, #AT91_CKGR_MOR] orr tmp1, tmp1, #AT91_PMC_MOSCEN @@ -199,6 +216,7 @@ sdr_sr_done: wait_mckrdy +skip_enable_clock: /* * at91rm9200 Memory controller * Do nothing - self-refresh is automatically disabled.