From 3a1f2f38fb82b7a3bc7351d7e38df5a1e9c901d2 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Mon, 18 Feb 2019 15:34:11 +0100 Subject: ARM: exynos: Add CPU state management for Exynos542x under secure firmware Add required CPU state management done via secure monitor call for Exynos542x running unsed Secure Firmware. Signed-off-by: Joonyoung Shim [mszyprow: rewrote code to use defines and sysram base address instead of the magic numbers, added second smc call in pm_resume, rephrased subject and commit message] Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/suspend.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-exynos/suspend.c') diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index c1e082ab2a1e..42f36843892e 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -31,6 +31,7 @@ #include #include "common.h" +#include "smc.h" #define REG_TABLE_END (-1U) @@ -62,6 +63,8 @@ struct exynos_pm_state { int cpu_state; unsigned int pmu_spare3; void __iomem *sysram_base; + phys_addr_t sysram_phys; + bool secure_firmware; }; static const struct exynos_pm_data *pm_data __ro_after_init; @@ -340,6 +343,10 @@ static void exynos5420_pm_prepare(void) pm_state.cpu_state = readl_relaxed(pm_state.sysram_base + EXYNOS5420_CPU_STATE); writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE); + if (pm_state.secure_firmware) + exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(pm_state.sysram_phys + + EXYNOS5420_CPU_STATE), + 0, 0); exynos_pm_enter_sleep_mode(); @@ -459,6 +466,11 @@ static void exynos5420_pm_resume(void) /* Restore the sysram cpu state register */ writel_relaxed(pm_state.cpu_state, pm_state.sysram_base + EXYNOS5420_CPU_STATE); + if (pm_state.secure_firmware) + exynos_smc(SMC_CMD_REG, + SMC_REG_ID_SFR_W(pm_state.sysram_phys + + EXYNOS5420_CPU_STATE), + EXYNOS_AFTR_MAGIC, 0); pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); @@ -658,8 +670,11 @@ void __init exynos_pm_init(void) * Applicable as of now only to Exynos542x. If booted under secure * firmware, the non-secure region of sysram should be used. */ - if (exynos_secure_firmware_available()) + if (exynos_secure_firmware_available()) { + pm_state.sysram_phys = sysram_base_phys; pm_state.sysram_base = sysram_ns_base_addr; - else + pm_state.secure_firmware = true; + } else { pm_state.sysram_base = sysram_base_addr; + } } -- cgit v1.2.3