From patchwork Wed Jun 25 16:18:34 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Figa X-Patchwork-Id: 4421731 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.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 8E529BEEAA for ; Wed, 25 Jun 2014 16:21:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A00362038D for ; Wed, 25 Jun 2014 16:21:42 +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 B0E2E2018B for ; Wed, 25 Jun 2014 16:21:41 +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 1Wzpv6-0001Hx-2n; Wed, 25 Jun 2014 16:19:36 +0000 Received: from mailout3.w1.samsung.com ([210.118.77.13]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Wzpv2-00018w-Ua for linux-arm-kernel@lists.infradead.org; Wed, 25 Jun 2014 16:19:33 +0000 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N7Q00E6CFZW0K50@mailout3.w1.samsung.com> for linux-arm-kernel@lists.infradead.org; Wed, 25 Jun 2014 17:19:08 +0100 (BST) X-AuditID: cbfec7f5-b7f626d000004b39-80-53aaf67de161 Received: from eusync3.samsung.com ( [203.254.199.213]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id 88.A7.19257.D76FAA35; Wed, 25 Jun 2014 17:19:09 +0100 (BST) Received: from AMDC1227.digital.local ([106.116.147.199]) by eusync3.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0N7Q00FRPFZRTFA0@eusync3.samsung.com>; Wed, 25 Jun 2014 17:19:09 +0100 (BST) From: Tomasz Figa To: linux-samsung-soc@vger.kernel.org Subject: [PATCH 2/2] ARM: EXYNOS: Add support for firmware-assisted suspend/resume Date: Wed, 25 Jun 2014 18:18:34 +0200 Message-id: <1403713114-18923-3-git-send-email-t.figa@samsung.com> X-Mailer: git-send-email 1.9.3 In-reply-to: <1403713114-18923-1-git-send-email-t.figa@samsung.com> References: <1403713114-18923-1-git-send-email-t.figa@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprNLMWRmVeSWpSXmKPExsVy+t/xq7q131YFG5zawmfx/eEpVou/k46x W/QuuMpmsenxNVaLy7vmsFnMOL+PyeL2ZV6LtUfuslucuv6ZzeLG9BZWi/UzXrNYrNr1h9GB x6OluYfN4/evSYweO2fdZffYvKTe48qJJlaP3uZ3bB59W1YxenzeJBfAEcVlk5Kak1mWWqRv l8CV8frOdZaCZUoVO15pNzCeleli5OCQEDCReL3NuIuRE8gUk7hwbz1bFyMXh5DAUkaJS5uf skA4fUwSn5a9ZgapYhNQk/jc8IgNxBYRUJX43LaAHaSIWWA1s8Spr83sIAlhgRCJl8cOgNks QEVnup6A2bwCThIT2trYINbJSfRuewM2lFPAWWLfn81gNUJANYv7fjNNYORdwMiwilE0tTS5 oDgpPddIrzgxt7g0L10vOT93EyMkQL/uYFx6zOoQowAHoxIPbwDPqmAh1sSy4srcQ4wSHMxK IrxRz4FCvCmJlVWpRfnxRaU5qcWHGJk4OKUaGA8dsMiOUdzQb31+xY8JrK6679eey4hgl5i1 cf8lAV3XFkaLtPta/08uWdf+4ujpZa+DjuhIbs8WZ9u29/aub7V8LVqC5iuWl8zQuLN+Cc+t PpOLiusOqqy5lrRlX7rarlX6aywSdjz3fVdlIqLUuzHnzYqLjAcP/2Scumq10GZvQYZ+N5m8 IGYlluKMREMt5qLiRABMX4RULgIAAA== X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140625_091933_124465_27DC81A1 X-CRM114-Status: GOOD ( 15.33 ) X-Spam-Score: -5.0 (-----) Cc: Kukjin Kim , Russell King - ARM Linux , Arnd Bergmann , Tomasz Figa , linux-kernel@vger.kernel.org, Tomasz Figa , Alexandre Courbot , Olof Johansson , Stephen Warren , linux-arm-kernel@lists.infradead.org, Marek Szyprowski 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, 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 On a numer of Exynos-based boards Linux kernel is running in non-secure mode under a secure firmware. This means that certain operations need to be handled in special way, with firmware assistance. System-wide suspend/resume is an example of such operations. This patch adds support for firmware-assisted suspend/resume by leveraging recently introduced suspend and resume firmware operations and modifying existing suspend/resume paths to account for presence of secure firmware. Signed-off-by: Tomasz Figa --- arch/arm/mach-exynos/firmware.c | 47 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-exynos/pm.c | 16 +++++++++----- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c index def7bb4..cd554a1 100644 --- a/arch/arm/mach-exynos/firmware.c +++ b/arch/arm/mach-exynos/firmware.c @@ -14,15 +14,21 @@ #include #include +#include #include #include #include +#include #include #include "common.h" #include "smc.h" +#define EXYNOS_SLEEP_MAGIC 0x00000bad +#define EXYNOS_BOOT_ADDR 0x8 +#define EXYNOS_BOOT_FLAG 0xc + static int exynos_do_idle(void) { exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); @@ -66,10 +72,51 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr) return 0; } +/* For Cortex-A9 Diagnostic and Power control register */ +static unsigned int cp15_power; +static unsigned int cp15_diag; + +static int exynos_cpu_suspend(unsigned long arg) +{ + flush_cache_all(); + outer_flush_all(); + + exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); + + pr_info("Failed to suspend the system\n"); + writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG); + return 1; +} + +static int exynos_suspend(void) +{ + /* Save Power control and Diagnostic registers */ + asm ("mrc p15, 0, %0, c15, c0, 0\n" + "mrc p15, 0, %1, c15, c0, 1\n" + : "=r" (cp15_power), "=r" (cp15_diag) : : "cc"); + + writel(EXYNOS_SLEEP_MAGIC, sysram_ns_base_addr + EXYNOS_BOOT_FLAG); + writel(virt_to_phys(cpu_resume), + sysram_ns_base_addr + EXYNOS_BOOT_ADDR); + + return cpu_suspend(0, exynos_cpu_suspend); +} + +static int exynos_resume(void) +{ + exynos_smc(SMC_CMD_C15RESUME, cp15_power, cp15_diag, 0); + writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG); + outer_resume(); + + return 0; +} + static const struct firmware_ops exynos_firmware_ops = { .do_idle = exynos_do_idle, .set_cpu_boot_addr = exynos_set_cpu_boot_addr, .cpu_boot = exynos_cpu_boot, + .suspend = exynos_suspend, + .resume = exynos_resume, }; static void exynos_l2_write_sec(unsigned long val, void __iomem *base, diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index f23cc77..ed20318 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -331,12 +332,11 @@ static int exynos_pm_central_resume(void) static void exynos_pm_resume(void) { + u32 cpuid = read_cpuid_part_number(); + if (exynos_pm_central_resume()) goto early_wakeup; - if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) - exynos_cpu_restore_register(); - /* For release retention */ __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); @@ -353,9 +353,13 @@ static void exynos_pm_resume(void) s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); - if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) + if (cpuid == ARM_CPU_PART_CORTEX_A9) scu_enable(S5P_VA_SCU); + if (call_firmware_op(resume) == -ENOSYS + && cpuid == ARM_CPU_PART_CORTEX_A9) + exynos_cpu_restore_register(); + early_wakeup: /* Clear SLEEP mode set in INFORM1 */ @@ -391,7 +395,9 @@ static int exynos_suspend_enter(suspend_state_t state) flush_cache_all(); s3c_pm_check_store(); - ret = cpu_suspend(0, exynos_cpu_suspend); + ret = call_firmware_op(suspend); + if (ret == -ENOSYS) + ret = cpu_suspend(0, exynos_cpu_suspend); if (ret) return ret;