1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) 2017 NXP
4 *
5 * Peng Fan <peng.fan@nxp.com>
6 */
7
8 #include <arm.h>
9 #include <arm32.h>
10 #include <console.h>
11 #include <drivers/imx_uart.h>
12 #include <io.h>
13 #include <imx.h>
14 #include <imx_pm.h>
15 #include <kernel/panic.h>
16 #include <kernel/cache_helpers.h>
17 #include <kernel/boot.h>
18 #include <kernel/misc.h>
19 #include <mm/core_mmu.h>
20 #include <mm/core_memprot.h>
21 #include <sm/sm.h>
22 #include <sm/pm.h>
23 #include <sm/psci.h>
24 #include <stdint.h>
25
26 static int suspended_init;
27
imx7_cpu_suspend(uint32_t power_state __unused,uintptr_t entry,uint32_t context_id __unused,struct sm_nsec_ctx * nsec)28 int imx7_cpu_suspend(uint32_t power_state __unused, uintptr_t entry,
29 uint32_t context_id __unused, struct sm_nsec_ctx *nsec)
30 {
31 uint32_t suspend_ocram_base = core_mmu_get_va(TRUSTZONE_OCRAM_START +
32 SUSPEND_OCRAM_OFFSET,
33 MEM_AREA_TEE_COHERENT,
34 sizeof(struct
35 imx7_pm_info));
36
37 struct imx7_pm_info *p = (struct imx7_pm_info *)suspend_ocram_base;
38 int ret;
39
40 if (!suspended_init) {
41 imx7_suspend_init();
42 suspended_init = 1;
43 }
44
45 sm_save_unbanked_regs(&nsec->ub_regs);
46
47 ret = sm_pm_cpu_suspend((uint32_t)p, (int (*)(uint32_t))
48 (suspend_ocram_base + sizeof(*p)));
49 /*
50 * Sometimes sm_pm_cpu_suspend may not really suspended,
51 * we need to check it's return value to restore reg or not
52 */
53 if (ret < 0) {
54 DMSG("=== Not suspended, GPC IRQ Pending ===\n");
55 return 0;
56 }
57
58 if (!get_core_pos())
59 plat_primary_init_early();
60
61 sm_restore_unbanked_regs(&nsec->ub_regs);
62
63 /* Set entry for back to Linux */
64 nsec->mon_lr = (uint32_t)entry;
65
66 main_init_gic();
67
68 DMSG("=== Back from Suspended ===\n");
69
70 return 0;
71 }
72