aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-exynos/suspend.c
diff options
context:
space:
mode:
authorJoonyoung Shim2019-02-18 15:34:11 +0100
committerKrzysztof Kozlowski2019-03-19 21:07:47 +0100
commit3a1f2f38fb82b7a3bc7351d7e38df5a1e9c901d2 (patch)
tree0c8578a1c8a16faa5a4464a2c85e67dd5cfc56b6 /arch/arm/mach-exynos/suspend.c
parent47efaf6ba6971e669f198e8e60fe6e674b5020ac (diff)
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 <jy0922.shim@samsung.com> [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 <m.szyprowski@samsung.com> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Diffstat (limited to 'arch/arm/mach-exynos/suspend.c')
-rw-r--r--arch/arm/mach-exynos/suspend.c19
1 files changed, 17 insertions, 2 deletions
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 <asm/suspend.h>
#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;
+ }
}