xref: /arm-trusted-firmware/plat/xilinx/versal_net/pm_service/pm_client.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
3*91f16700Schasinglulu  * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
4*91f16700Schasinglulu  *
5*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
6*91f16700Schasinglulu  */
7*91f16700Schasinglulu 
8*91f16700Schasinglulu /*
9*91f16700Schasinglulu  * APU specific definition of processors in the subsystem as well as functions
10*91f16700Schasinglulu  * for getting information about and changing state of the APU.
11*91f16700Schasinglulu  */
12*91f16700Schasinglulu 
13*91f16700Schasinglulu #include <assert.h>
14*91f16700Schasinglulu 
15*91f16700Schasinglulu #include <drivers/arm/gic_common.h>
16*91f16700Schasinglulu #include <drivers/arm/gicv3.h>
17*91f16700Schasinglulu #include <lib/bakery_lock.h>
18*91f16700Schasinglulu #include <lib/mmio.h>
19*91f16700Schasinglulu #include <lib/spinlock.h>
20*91f16700Schasinglulu #include <lib/utils.h>
21*91f16700Schasinglulu #include <plat/common/platform.h>
22*91f16700Schasinglulu 
23*91f16700Schasinglulu #include <plat_ipi.h>
24*91f16700Schasinglulu #include <platform_def.h>
25*91f16700Schasinglulu #include "pm_api_sys.h"
26*91f16700Schasinglulu #include "pm_client.h"
27*91f16700Schasinglulu #include <versal_net_def.h>
28*91f16700Schasinglulu 
29*91f16700Schasinglulu #define UNDEFINED_CPUID		(~0)
30*91f16700Schasinglulu 
31*91f16700Schasinglulu DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7)
32*91f16700Schasinglulu 
33*91f16700Schasinglulu /*
34*91f16700Schasinglulu  * ARM v8.2, the cache will turn off automatically when cpu
35*91f16700Schasinglulu  * power down. Therefore, there is no doubt to use the spin_lock here.
36*91f16700Schasinglulu  */
37*91f16700Schasinglulu #if !HW_ASSISTED_COHERENCY
38*91f16700Schasinglulu DEFINE_BAKERY_LOCK(pm_client_secure_lock);
39*91f16700Schasinglulu static inline void pm_client_lock_get(void)
40*91f16700Schasinglulu {
41*91f16700Schasinglulu 	bakery_lock_get(&pm_client_secure_lock);
42*91f16700Schasinglulu }
43*91f16700Schasinglulu 
44*91f16700Schasinglulu static inline void pm_client_lock_release(void)
45*91f16700Schasinglulu {
46*91f16700Schasinglulu 	bakery_lock_release(&pm_client_secure_lock);
47*91f16700Schasinglulu }
48*91f16700Schasinglulu #else
49*91f16700Schasinglulu spinlock_t pm_client_secure_lock;
50*91f16700Schasinglulu static inline void pm_client_lock_get(void)
51*91f16700Schasinglulu {
52*91f16700Schasinglulu 	spin_lock(&pm_client_secure_lock);
53*91f16700Schasinglulu }
54*91f16700Schasinglulu 
55*91f16700Schasinglulu static inline void pm_client_lock_release(void)
56*91f16700Schasinglulu {
57*91f16700Schasinglulu 	spin_unlock(&pm_client_secure_lock);
58*91f16700Schasinglulu }
59*91f16700Schasinglulu #endif
60*91f16700Schasinglulu 
61*91f16700Schasinglulu static const struct pm_ipi apu_ipi = {
62*91f16700Schasinglulu 	.local_ipi_id = IPI_LOCAL_ID,
63*91f16700Schasinglulu 	.remote_ipi_id = IPI_REMOTE_ID,
64*91f16700Schasinglulu 	.buffer_base = IPI_BUFFER_LOCAL_BASE,
65*91f16700Schasinglulu };
66*91f16700Schasinglulu 
67*91f16700Schasinglulu /* Order in pm_procs_all array must match cpu ids */
68*91f16700Schasinglulu static const struct pm_proc pm_procs_all[] = {
69*91f16700Schasinglulu 	{
70*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER0_ACPU_0,
71*91f16700Schasinglulu 		.ipi = &apu_ipi,
72*91f16700Schasinglulu 		.pwrdn_mask = 0,
73*91f16700Schasinglulu 	},
74*91f16700Schasinglulu 	{
75*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER0_ACPU_1,
76*91f16700Schasinglulu 		.ipi = &apu_ipi,
77*91f16700Schasinglulu 		.pwrdn_mask = 0,
78*91f16700Schasinglulu 	},
79*91f16700Schasinglulu 	{
80*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER0_ACPU_2,
81*91f16700Schasinglulu 		.ipi = &apu_ipi,
82*91f16700Schasinglulu 		.pwrdn_mask = 0,
83*91f16700Schasinglulu 	},
84*91f16700Schasinglulu 	{
85*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER0_ACPU_3,
86*91f16700Schasinglulu 		.ipi = &apu_ipi,
87*91f16700Schasinglulu 		.pwrdn_mask = 0,
88*91f16700Schasinglulu 	},
89*91f16700Schasinglulu 	{
90*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER1_ACPU_0,
91*91f16700Schasinglulu 		.ipi = &apu_ipi,
92*91f16700Schasinglulu 		.pwrdn_mask = 0,
93*91f16700Schasinglulu 	},
94*91f16700Schasinglulu 	{
95*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER1_ACPU_1,
96*91f16700Schasinglulu 		.ipi = &apu_ipi,
97*91f16700Schasinglulu 		.pwrdn_mask = 0,
98*91f16700Schasinglulu 	},
99*91f16700Schasinglulu 	{
100*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER1_ACPU_2,
101*91f16700Schasinglulu 		.ipi = &apu_ipi,
102*91f16700Schasinglulu 		.pwrdn_mask = 0,
103*91f16700Schasinglulu 	},
104*91f16700Schasinglulu 	{
105*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER1_ACPU_3,
106*91f16700Schasinglulu 		.ipi = &apu_ipi,
107*91f16700Schasinglulu 		.pwrdn_mask = 0,
108*91f16700Schasinglulu 	},
109*91f16700Schasinglulu 	{
110*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER2_ACPU_0,
111*91f16700Schasinglulu 		.ipi = &apu_ipi,
112*91f16700Schasinglulu 		.pwrdn_mask = 0,
113*91f16700Schasinglulu 	},
114*91f16700Schasinglulu 	{
115*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER2_ACPU_1,
116*91f16700Schasinglulu 		.ipi = &apu_ipi,
117*91f16700Schasinglulu 		.pwrdn_mask = 0,
118*91f16700Schasinglulu 	},
119*91f16700Schasinglulu 	{
120*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER2_ACPU_2,
121*91f16700Schasinglulu 		.ipi = &apu_ipi,
122*91f16700Schasinglulu 		.pwrdn_mask = 0,
123*91f16700Schasinglulu 	},
124*91f16700Schasinglulu 	{
125*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER2_ACPU_3,
126*91f16700Schasinglulu 		.ipi = &apu_ipi,
127*91f16700Schasinglulu 		.pwrdn_mask = 0,
128*91f16700Schasinglulu 	},
129*91f16700Schasinglulu 	{
130*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER3_ACPU_0,
131*91f16700Schasinglulu 		.ipi = &apu_ipi,
132*91f16700Schasinglulu 		.pwrdn_mask = 0,
133*91f16700Schasinglulu 	},
134*91f16700Schasinglulu 	{
135*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER3_ACPU_1,
136*91f16700Schasinglulu 		.ipi = &apu_ipi,
137*91f16700Schasinglulu 		.pwrdn_mask = 0,
138*91f16700Schasinglulu 	},
139*91f16700Schasinglulu 	{
140*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER3_ACPU_2,
141*91f16700Schasinglulu 		.ipi = &apu_ipi,
142*91f16700Schasinglulu 		.pwrdn_mask = 0,
143*91f16700Schasinglulu 	},
144*91f16700Schasinglulu 	{
145*91f16700Schasinglulu 		.node_id = PM_DEV_CLUSTER3_ACPU_3,
146*91f16700Schasinglulu 		.ipi = &apu_ipi,
147*91f16700Schasinglulu 		.pwrdn_mask = 0,
148*91f16700Schasinglulu 	}
149*91f16700Schasinglulu };
150*91f16700Schasinglulu 
151*91f16700Schasinglulu const struct pm_proc *primary_proc = &pm_procs_all[0];
152*91f16700Schasinglulu 
153*91f16700Schasinglulu /**
154*91f16700Schasinglulu  * pm_get_proc() - returns pointer to the proc structure.
155*91f16700Schasinglulu  * @cpuid: id of the cpu whose proc struct pointer should be returned.
156*91f16700Schasinglulu  *
157*91f16700Schasinglulu  * Return: Pointer to a proc structure if proc is found, otherwise NULL.
158*91f16700Schasinglulu  *
159*91f16700Schasinglulu  */
160*91f16700Schasinglulu const struct pm_proc *pm_get_proc(uint32_t cpuid)
161*91f16700Schasinglulu {
162*91f16700Schasinglulu 	if (cpuid < ARRAY_SIZE(pm_procs_all)) {
163*91f16700Schasinglulu 		return &pm_procs_all[cpuid];
164*91f16700Schasinglulu 	}
165*91f16700Schasinglulu 
166*91f16700Schasinglulu 	NOTICE("ERROR: cpuid: %d proc NULL\n", cpuid);
167*91f16700Schasinglulu 	return NULL;
168*91f16700Schasinglulu }
169*91f16700Schasinglulu 
170*91f16700Schasinglulu /**
171*91f16700Schasinglulu  * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number.
172*91f16700Schasinglulu  * @irq: Interrupt number.
173*91f16700Schasinglulu  *
174*91f16700Schasinglulu  * Return: PM node index corresponding to the specified interrupt.
175*91f16700Schasinglulu  *
176*91f16700Schasinglulu  */
177*91f16700Schasinglulu enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
178*91f16700Schasinglulu {
179*91f16700Schasinglulu 	enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN;
180*91f16700Schasinglulu 
181*91f16700Schasinglulu 	assert(irq <= IRQ_MAX);
182*91f16700Schasinglulu 
183*91f16700Schasinglulu 	switch (irq) {
184*91f16700Schasinglulu 	case 20:
185*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_GPIO;
186*91f16700Schasinglulu 		break;
187*91f16700Schasinglulu 	case 21:
188*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_I2C_0;
189*91f16700Schasinglulu 		break;
190*91f16700Schasinglulu 	case 22:
191*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_I2C_1;
192*91f16700Schasinglulu 		break;
193*91f16700Schasinglulu 	case 23:
194*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_SPI_0;
195*91f16700Schasinglulu 		break;
196*91f16700Schasinglulu 	case 24:
197*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_SPI_1;
198*91f16700Schasinglulu 		break;
199*91f16700Schasinglulu 	case 25:
200*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_UART_0;
201*91f16700Schasinglulu 		break;
202*91f16700Schasinglulu 	case 26:
203*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_UART_1;
204*91f16700Schasinglulu 		break;
205*91f16700Schasinglulu 	case 27:
206*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_CAN_FD_0;
207*91f16700Schasinglulu 		break;
208*91f16700Schasinglulu 	case 28:
209*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_CAN_FD_1;
210*91f16700Schasinglulu 		break;
211*91f16700Schasinglulu 	case 29:
212*91f16700Schasinglulu 	case 30:
213*91f16700Schasinglulu 	case 31:
214*91f16700Schasinglulu 	case 32:
215*91f16700Schasinglulu 	case 33:
216*91f16700Schasinglulu 	case 98:
217*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_USB_0;
218*91f16700Schasinglulu 		break;
219*91f16700Schasinglulu 	case 34:
220*91f16700Schasinglulu 	case 35:
221*91f16700Schasinglulu 	case 36:
222*91f16700Schasinglulu 	case 37:
223*91f16700Schasinglulu 	case 38:
224*91f16700Schasinglulu 	case 99:
225*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_USB_1;
226*91f16700Schasinglulu 		break;
227*91f16700Schasinglulu 	case 39:
228*91f16700Schasinglulu 	case 40:
229*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_GEM_0;
230*91f16700Schasinglulu 		break;
231*91f16700Schasinglulu 	case 41:
232*91f16700Schasinglulu 	case 42:
233*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_GEM_1;
234*91f16700Schasinglulu 		break;
235*91f16700Schasinglulu 	case 43:
236*91f16700Schasinglulu 	case 44:
237*91f16700Schasinglulu 	case 45:
238*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_TTC_0;
239*91f16700Schasinglulu 		break;
240*91f16700Schasinglulu 	case 46:
241*91f16700Schasinglulu 	case 47:
242*91f16700Schasinglulu 	case 48:
243*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_TTC_1;
244*91f16700Schasinglulu 		break;
245*91f16700Schasinglulu 	case 49:
246*91f16700Schasinglulu 	case 50:
247*91f16700Schasinglulu 	case 51:
248*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_TTC_2;
249*91f16700Schasinglulu 		break;
250*91f16700Schasinglulu 	case 52:
251*91f16700Schasinglulu 	case 53:
252*91f16700Schasinglulu 	case 54:
253*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_TTC_3;
254*91f16700Schasinglulu 		break;
255*91f16700Schasinglulu 	case 72:
256*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_ADMA_0;
257*91f16700Schasinglulu 		break;
258*91f16700Schasinglulu 	case 73:
259*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_ADMA_1;
260*91f16700Schasinglulu 		break;
261*91f16700Schasinglulu 	case 74:
262*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_ADMA_2;
263*91f16700Schasinglulu 		break;
264*91f16700Schasinglulu 	case 75:
265*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_ADMA_3;
266*91f16700Schasinglulu 		break;
267*91f16700Schasinglulu 	case 76:
268*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_ADMA_4;
269*91f16700Schasinglulu 		break;
270*91f16700Schasinglulu 	case 77:
271*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_ADMA_5;
272*91f16700Schasinglulu 		break;
273*91f16700Schasinglulu 	case 78:
274*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_ADMA_6;
275*91f16700Schasinglulu 		break;
276*91f16700Schasinglulu 	case 79:
277*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_ADMA_7;
278*91f16700Schasinglulu 		break;
279*91f16700Schasinglulu 	case 184:
280*91f16700Schasinglulu 	case 185:
281*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_SDIO_0;
282*91f16700Schasinglulu 		break;
283*91f16700Schasinglulu 	case 186:
284*91f16700Schasinglulu 	case 187:
285*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_SDIO_1;
286*91f16700Schasinglulu 		break;
287*91f16700Schasinglulu 	case 200:
288*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_RTC;
289*91f16700Schasinglulu 		break;
290*91f16700Schasinglulu 	default:
291*91f16700Schasinglulu 		dev_idx = XPM_NODEIDX_DEV_MIN;
292*91f16700Schasinglulu 		break;
293*91f16700Schasinglulu 	}
294*91f16700Schasinglulu 
295*91f16700Schasinglulu 	return dev_idx;
296*91f16700Schasinglulu }
297*91f16700Schasinglulu 
298*91f16700Schasinglulu /**
299*91f16700Schasinglulu  * pm_client_suspend() - Client-specific suspend actions. This function
300*91f16700Schasinglulu  *                       should contain any PU-specific actions required
301*91f16700Schasinglulu  *                       prior to sending suspend request to PMU. Actions
302*91f16700Schasinglulu  *                       taken depend on the state system is suspending to.
303*91f16700Schasinglulu  * @proc: processor which need to suspend.
304*91f16700Schasinglulu  * @state: desired suspend state.
305*91f16700Schasinglulu  *
306*91f16700Schasinglulu  */
307*91f16700Schasinglulu void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
308*91f16700Schasinglulu {
309*91f16700Schasinglulu 	uint32_t cpu_id = plat_my_core_pos();
310*91f16700Schasinglulu 	uintptr_t val;
311*91f16700Schasinglulu 
312*91f16700Schasinglulu 	pm_client_lock_get();
313*91f16700Schasinglulu 
314*91f16700Schasinglulu 	if (state == PM_STATE_SUSPEND_TO_RAM) {
315*91f16700Schasinglulu 		pm_client_set_wakeup_sources((uint32_t)proc->node_id);
316*91f16700Schasinglulu 	}
317*91f16700Schasinglulu 
318*91f16700Schasinglulu 	val = read_cpu_pwrctrl_val();
319*91f16700Schasinglulu 	val |= CORE_PWRDN_EN_BIT_MASK;
320*91f16700Schasinglulu 	write_cpu_pwrctrl_val(val);
321*91f16700Schasinglulu 
322*91f16700Schasinglulu 	isb();
323*91f16700Schasinglulu 
324*91f16700Schasinglulu 	/* Enable power down interrupt */
325*91f16700Schasinglulu 	mmio_write_32(APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id),
326*91f16700Schasinglulu 		      APU_PCIL_CORE_X_IEN_POWER_MASK);
327*91f16700Schasinglulu 	/* Enable wake interrupt */
328*91f16700Schasinglulu 	mmio_write_32(APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id),
329*91f16700Schasinglulu 		      APU_PCIL_CORE_X_IEN_WAKE_MASK);
330*91f16700Schasinglulu 
331*91f16700Schasinglulu 	pm_client_lock_release();
332*91f16700Schasinglulu }
333*91f16700Schasinglulu 
334*91f16700Schasinglulu /**
335*91f16700Schasinglulu  * pm_get_cpuid() - get the local cpu ID for a global node ID.
336*91f16700Schasinglulu  * @nid: node id of the processor.
337*91f16700Schasinglulu  *
338*91f16700Schasinglulu  * Return: the cpu ID (starting from 0) for the subsystem.
339*91f16700Schasinglulu  *
340*91f16700Schasinglulu  */
341*91f16700Schasinglulu static uint32_t pm_get_cpuid(uint32_t nid)
342*91f16700Schasinglulu {
343*91f16700Schasinglulu 	for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
344*91f16700Schasinglulu 		if (pm_procs_all[i].node_id == nid) {
345*91f16700Schasinglulu 			return i;
346*91f16700Schasinglulu 		}
347*91f16700Schasinglulu 	}
348*91f16700Schasinglulu 	return UNDEFINED_CPUID;
349*91f16700Schasinglulu }
350*91f16700Schasinglulu 
351*91f16700Schasinglulu /**
352*91f16700Schasinglulu  * pm_client_wakeup() - Client-specific wakeup actions.
353*91f16700Schasinglulu  * @proc: Processor which need to wakeup.
354*91f16700Schasinglulu  *
355*91f16700Schasinglulu  * This function should contain any PU-specific actions
356*91f16700Schasinglulu  * required for waking up another APU core.
357*91f16700Schasinglulu  *
358*91f16700Schasinglulu  */
359*91f16700Schasinglulu void pm_client_wakeup(const struct pm_proc *proc)
360*91f16700Schasinglulu {
361*91f16700Schasinglulu 	uint32_t cpuid = pm_get_cpuid(proc->node_id);
362*91f16700Schasinglulu 	uintptr_t val;
363*91f16700Schasinglulu 
364*91f16700Schasinglulu 	if (cpuid == UNDEFINED_CPUID) {
365*91f16700Schasinglulu 		return;
366*91f16700Schasinglulu 	}
367*91f16700Schasinglulu 
368*91f16700Schasinglulu 	pm_client_lock_get();
369*91f16700Schasinglulu 
370*91f16700Schasinglulu 	/* Clear powerdown request */
371*91f16700Schasinglulu 	val = read_cpu_pwrctrl_val();
372*91f16700Schasinglulu 	val &= ~CORE_PWRDN_EN_BIT_MASK;
373*91f16700Schasinglulu 	write_cpu_pwrctrl_val(val);
374*91f16700Schasinglulu 
375*91f16700Schasinglulu 	isb();
376*91f16700Schasinglulu 
377*91f16700Schasinglulu 	/* Disabled power down interrupt */
378*91f16700Schasinglulu 	mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpuid),
379*91f16700Schasinglulu 			APU_PCIL_CORE_X_IDS_POWER_MASK);
380*91f16700Schasinglulu 	/* Disable wake interrupt */
381*91f16700Schasinglulu 	mmio_write_32(APU_PCIL_CORE_X_IDS_WAKE_REG(cpuid),
382*91f16700Schasinglulu 		      APU_PCIL_CORE_X_IDS_WAKE_MASK);
383*91f16700Schasinglulu 
384*91f16700Schasinglulu 	pm_client_lock_release();
385*91f16700Schasinglulu }
386*91f16700Schasinglulu 
387*91f16700Schasinglulu /**
388*91f16700Schasinglulu  * pm_client_abort_suspend() - Client-specific abort-suspend actions.
389*91f16700Schasinglulu  *
390*91f16700Schasinglulu  * This function should contain any PU-specific actions
391*91f16700Schasinglulu  * required for aborting a prior suspend request.
392*91f16700Schasinglulu  *
393*91f16700Schasinglulu  */
394*91f16700Schasinglulu void pm_client_abort_suspend(void)
395*91f16700Schasinglulu {
396*91f16700Schasinglulu 	uint32_t cpu_id = plat_my_core_pos();
397*91f16700Schasinglulu 	uintptr_t val;
398*91f16700Schasinglulu 
399*91f16700Schasinglulu 	/* Enable interrupts at processor level (for current cpu) */
400*91f16700Schasinglulu 	gicv3_cpuif_enable(plat_my_core_pos());
401*91f16700Schasinglulu 
402*91f16700Schasinglulu 	pm_client_lock_get();
403*91f16700Schasinglulu 
404*91f16700Schasinglulu 	/* Clear powerdown request */
405*91f16700Schasinglulu 	val = read_cpu_pwrctrl_val();
406*91f16700Schasinglulu 	val &= ~CORE_PWRDN_EN_BIT_MASK;
407*91f16700Schasinglulu 	write_cpu_pwrctrl_val(val);
408*91f16700Schasinglulu 
409*91f16700Schasinglulu 	isb();
410*91f16700Schasinglulu 
411*91f16700Schasinglulu 	/* Disabled power down interrupt */
412*91f16700Schasinglulu 	mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id),
413*91f16700Schasinglulu 			APU_PCIL_CORE_X_IDS_POWER_MASK);
414*91f16700Schasinglulu 
415*91f16700Schasinglulu 	pm_client_lock_release();
416*91f16700Schasinglulu }
417