blob: 7ba528e3f7fe45f9cceeeecd720a68c12dc5b402 [file] [log] [blame]
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (C) 2017 NXP
*
* Peng Fan <peng.fan@nxp.com>
*/
#include <arm.h>
#include <arm32.h>
#include <console.h>
#include <drivers/imx_uart.h>
#include <io.h>
#include <imx.h>
#include <imx_pm.h>
#include <kernel/panic.h>
#include <kernel/cache_helpers.h>
#include <kernel/generic_boot.h>
#include <kernel/misc.h>
#include <mm/core_mmu.h>
#include <mm/core_memprot.h>
#include <sm/sm.h>
#include <sm/pm.h>
#include <sm/psci.h>
#include <stdint.h>
static int suspended_init;
int imx7_cpu_suspend(uint32_t power_state __unused, uintptr_t entry,
uint32_t context_id __unused, struct sm_nsec_ctx *nsec)
{
uint32_t suspend_ocram_base = core_mmu_get_va(TRUSTZONE_OCRAM_START +
SUSPEND_OCRAM_OFFSET,
MEM_AREA_TEE_COHERENT);
struct imx7_pm_info *p = (struct imx7_pm_info *)suspend_ocram_base;
int ret;
if (!suspended_init) {
imx7_suspend_init();
suspended_init = 1;
}
sm_save_unbanked_regs(&nsec->ub_regs);
ret = sm_pm_cpu_suspend((uint32_t)p, (int (*)(uint32_t))
(suspend_ocram_base + sizeof(*p)));
/*
* Sometimes sm_pm_cpu_suspend may not really suspended,
* we need to check it's return value to restore reg or not
*/
if (ret < 0) {
DMSG("=== Not suspended, GPC IRQ Pending ===\n");
return 0;
}
if (!get_core_pos())
plat_primary_init_early();
sm_restore_unbanked_regs(&nsec->ub_regs);
/* Set entry for back to Linux */
nsec->mon_lr = (uint32_t)entry;
main_init_gic();
DMSG("=== Back from Suspended ===\n");
return 0;
}