xref: /arm-trusted-firmware/services/spd/tlkd/tlkd_pm.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
4*91f16700Schasinglulu  *
5*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
6*91f16700Schasinglulu  */
7*91f16700Schasinglulu 
8*91f16700Schasinglulu #include <assert.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <arch_helpers.h>
11*91f16700Schasinglulu #include <bl32/payloads/tlk.h>
12*91f16700Schasinglulu #include <common/bl_common.h>
13*91f16700Schasinglulu #include <common/debug.h>
14*91f16700Schasinglulu #include <lib/el3_runtime/context_mgmt.h>
15*91f16700Schasinglulu #include <lib/psci/psci.h>
16*91f16700Schasinglulu 
17*91f16700Schasinglulu #include "tlkd_private.h"
18*91f16700Schasinglulu 
19*91f16700Schasinglulu extern tlk_context_t tlk_ctx;
20*91f16700Schasinglulu 
21*91f16700Schasinglulu #define MPIDR_CPU0	0x80000000
22*91f16700Schasinglulu 
23*91f16700Schasinglulu /*******************************************************************************
24*91f16700Schasinglulu  * Return the type of payload TLKD is dealing with. Report the current
25*91f16700Schasinglulu  * resident cpu (mpidr format) if it is a UP/UP migratable payload.
26*91f16700Schasinglulu  ******************************************************************************/
27*91f16700Schasinglulu static int32_t cpu_migrate_info(u_register_t *resident_cpu)
28*91f16700Schasinglulu {
29*91f16700Schasinglulu 	/* the payload runs only on CPU0 */
30*91f16700Schasinglulu 	*resident_cpu = MPIDR_CPU0;
31*91f16700Schasinglulu 
32*91f16700Schasinglulu 	/* Uniprocessor, not migrate capable payload */
33*91f16700Schasinglulu 	return PSCI_TOS_NOT_UP_MIG_CAP;
34*91f16700Schasinglulu }
35*91f16700Schasinglulu 
36*91f16700Schasinglulu /*******************************************************************************
37*91f16700Schasinglulu  * This cpu is being suspended. Inform TLK of the SYSTEM_SUSPEND event, so
38*91f16700Schasinglulu  * that it can pass this information to its Trusted Apps.
39*91f16700Schasinglulu  ******************************************************************************/
40*91f16700Schasinglulu static void cpu_suspend_handler(u_register_t suspend_level)
41*91f16700Schasinglulu {
42*91f16700Schasinglulu 	gp_regs_t *gp_regs;
43*91f16700Schasinglulu 	int cpu = read_mpidr() & MPIDR_CPU_MASK;
44*91f16700Schasinglulu 	int32_t rc = 0;
45*91f16700Schasinglulu 
46*91f16700Schasinglulu 	/*
47*91f16700Schasinglulu 	 * TLK runs only on CPU0 and suspends its Trusted Apps during
48*91f16700Schasinglulu 	 * SYSTEM_SUSPEND. It has no role to play during CPU_SUSPEND.
49*91f16700Schasinglulu 	 */
50*91f16700Schasinglulu 	if ((cpu != 0) || (suspend_level != PLAT_MAX_PWR_LVL))
51*91f16700Schasinglulu 		return;
52*91f16700Schasinglulu 
53*91f16700Schasinglulu 	/* pass system suspend event to TLK */
54*91f16700Schasinglulu 	gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx);
55*91f16700Schasinglulu 	write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_SUSPEND);
56*91f16700Schasinglulu 
57*91f16700Schasinglulu 	/* Program the entry point and enter TLK */
58*91f16700Schasinglulu 	rc = tlkd_synchronous_sp_entry(&tlk_ctx);
59*91f16700Schasinglulu 
60*91f16700Schasinglulu 	/*
61*91f16700Schasinglulu 	 * Read the response from TLK. A non-zero return means that
62*91f16700Schasinglulu 	 * something went wrong while communicating with it.
63*91f16700Schasinglulu 	 */
64*91f16700Schasinglulu 	if (rc != 0)
65*91f16700Schasinglulu 		panic();
66*91f16700Schasinglulu }
67*91f16700Schasinglulu 
68*91f16700Schasinglulu /*******************************************************************************
69*91f16700Schasinglulu  * This cpu is being resumed. Inform TLK of the SYSTEM_SUSPEND exit, so
70*91f16700Schasinglulu  * that it can pass this information to its Trusted Apps.
71*91f16700Schasinglulu  ******************************************************************************/
72*91f16700Schasinglulu static void cpu_resume_handler(u_register_t suspend_level)
73*91f16700Schasinglulu {
74*91f16700Schasinglulu 	gp_regs_t *gp_regs;
75*91f16700Schasinglulu 	int cpu = read_mpidr() & MPIDR_CPU_MASK;
76*91f16700Schasinglulu 	int32_t rc = 0;
77*91f16700Schasinglulu 
78*91f16700Schasinglulu 	/*
79*91f16700Schasinglulu 	 * TLK runs only on CPU0 and resumes its Trusted Apps during
80*91f16700Schasinglulu 	 * SYSTEM_SUSPEND exit. It has no role to play during CPU_SUSPEND
81*91f16700Schasinglulu 	 * exit.
82*91f16700Schasinglulu 	 */
83*91f16700Schasinglulu 	if ((cpu != 0) || (suspend_level != PLAT_MAX_PWR_LVL))
84*91f16700Schasinglulu 		return;
85*91f16700Schasinglulu 
86*91f16700Schasinglulu 	/* pass system resume event to TLK */
87*91f16700Schasinglulu 	gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx);
88*91f16700Schasinglulu 	write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_RESUME);
89*91f16700Schasinglulu 
90*91f16700Schasinglulu 	/* Program the entry point and enter TLK */
91*91f16700Schasinglulu 	rc = tlkd_synchronous_sp_entry(&tlk_ctx);
92*91f16700Schasinglulu 
93*91f16700Schasinglulu 	/*
94*91f16700Schasinglulu 	 * Read the response from TLK. A non-zero return means that
95*91f16700Schasinglulu 	 * something went wrong while communicating with it.
96*91f16700Schasinglulu 	 */
97*91f16700Schasinglulu 	if (rc != 0)
98*91f16700Schasinglulu 		panic();
99*91f16700Schasinglulu }
100*91f16700Schasinglulu 
101*91f16700Schasinglulu /*******************************************************************************
102*91f16700Schasinglulu  * Structure populated by the Dispatcher to be given a chance to perform any
103*91f16700Schasinglulu  * bookkeeping before PSCI executes a power mgmt.  operation.
104*91f16700Schasinglulu  ******************************************************************************/
105*91f16700Schasinglulu const spd_pm_ops_t tlkd_pm_ops = {
106*91f16700Schasinglulu 	.svc_migrate_info = cpu_migrate_info,
107*91f16700Schasinglulu 	.svc_suspend = cpu_suspend_handler,
108*91f16700Schasinglulu 	.svc_suspend_finish = cpu_resume_handler,
109*91f16700Schasinglulu };
110