xref: /rk3399_ARM-atf/plat/amd/versal2/pm_service/pm_client.c (revision 047b1b9afce13993db8363f55be6e0cbfb69bf0d)
1414cf08bSSenthil Nathan Thangaraj /*
2414cf08bSSenthil Nathan Thangaraj  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
3414cf08bSSenthil Nathan Thangaraj  * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
4414cf08bSSenthil Nathan Thangaraj  *
5414cf08bSSenthil Nathan Thangaraj  * SPDX-License-Identifier: BSD-3-Clause
6414cf08bSSenthil Nathan Thangaraj  */
7414cf08bSSenthil Nathan Thangaraj 
8414cf08bSSenthil Nathan Thangaraj /*
9414cf08bSSenthil Nathan Thangaraj  * APU specific definition of processors in the subsystem as well as functions
10414cf08bSSenthil Nathan Thangaraj  * for getting information about and changing state of the APU.
11414cf08bSSenthil Nathan Thangaraj  */
12414cf08bSSenthil Nathan Thangaraj 
13414cf08bSSenthil Nathan Thangaraj #include <assert.h>
14414cf08bSSenthil Nathan Thangaraj 
15414cf08bSSenthil Nathan Thangaraj #include <drivers/arm/gic_common.h>
16414cf08bSSenthil Nathan Thangaraj #include <drivers/arm/gicv3.h>
17414cf08bSSenthil Nathan Thangaraj #include <lib/bakery_lock.h>
18414cf08bSSenthil Nathan Thangaraj #include <lib/mmio.h>
19414cf08bSSenthil Nathan Thangaraj #include <lib/spinlock.h>
20414cf08bSSenthil Nathan Thangaraj #include <lib/utils.h>
21414cf08bSSenthil Nathan Thangaraj #include <plat/common/platform.h>
22414cf08bSSenthil Nathan Thangaraj 
23414cf08bSSenthil Nathan Thangaraj #include <platform_def.h>
24414cf08bSSenthil Nathan Thangaraj #include "def.h"
25414cf08bSSenthil Nathan Thangaraj #include <plat_ipi.h>
26*4fd510e0SRonak Jain #include <plat_pm_common.h>
27414cf08bSSenthil Nathan Thangaraj #include "pm_api_sys.h"
28414cf08bSSenthil Nathan Thangaraj #include "pm_client.h"
29414cf08bSSenthil Nathan Thangaraj 
30414cf08bSSenthil Nathan Thangaraj #define UNDEFINED_CPUID	UINT32_MAX
31414cf08bSSenthil Nathan Thangaraj 
DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val,S3_0_C15_C2_7)32414cf08bSSenthil Nathan Thangaraj DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7)
33414cf08bSSenthil Nathan Thangaraj 
34414cf08bSSenthil Nathan Thangaraj /*
35414cf08bSSenthil Nathan Thangaraj  * ARM v8.2, the cache will turn off automatically when cpu
36414cf08bSSenthil Nathan Thangaraj  * power down. Therefore, there is no doubt to use the spin_lock here.
37414cf08bSSenthil Nathan Thangaraj  */
38414cf08bSSenthil Nathan Thangaraj static spinlock_t pm_client_secure_lock;
39414cf08bSSenthil Nathan Thangaraj static inline void pm_client_lock_get(void)
40414cf08bSSenthil Nathan Thangaraj {
41414cf08bSSenthil Nathan Thangaraj 	spin_lock(&pm_client_secure_lock);
42414cf08bSSenthil Nathan Thangaraj }
43414cf08bSSenthil Nathan Thangaraj 
pm_client_lock_release(void)44414cf08bSSenthil Nathan Thangaraj static inline void pm_client_lock_release(void)
45414cf08bSSenthil Nathan Thangaraj {
46414cf08bSSenthil Nathan Thangaraj 	spin_unlock(&pm_client_secure_lock);
47414cf08bSSenthil Nathan Thangaraj }
48414cf08bSSenthil Nathan Thangaraj 
49414cf08bSSenthil Nathan Thangaraj static const struct pm_ipi apu_ipi = {
50414cf08bSSenthil Nathan Thangaraj 	.local_ipi_id = IPI_LOCAL_ID,
51414cf08bSSenthil Nathan Thangaraj 	.remote_ipi_id = IPI_REMOTE_ID,
52414cf08bSSenthil Nathan Thangaraj 	.buffer_base = IPI_BUFFER_LOCAL_BASE,
53414cf08bSSenthil Nathan Thangaraj };
54414cf08bSSenthil Nathan Thangaraj 
55414cf08bSSenthil Nathan Thangaraj /* Order in pm_procs_all array must match cpu ids */
56414cf08bSSenthil Nathan Thangaraj static const struct pm_proc pm_procs_all[] = {
57414cf08bSSenthil Nathan Thangaraj 	{
58414cf08bSSenthil Nathan Thangaraj 		.node_id = PM_DEV_CLUSTER0_ACPU_0,
59414cf08bSSenthil Nathan Thangaraj 		.ipi = &apu_ipi,
60414cf08bSSenthil Nathan Thangaraj 	},
61414cf08bSSenthil Nathan Thangaraj 	{
62414cf08bSSenthil Nathan Thangaraj 		.node_id = PM_DEV_CLUSTER0_ACPU_1,
63414cf08bSSenthil Nathan Thangaraj 		.ipi = &apu_ipi,
64414cf08bSSenthil Nathan Thangaraj 	},
65414cf08bSSenthil Nathan Thangaraj 	{
66414cf08bSSenthil Nathan Thangaraj 		.node_id = PM_DEV_CLUSTER1_ACPU_0,
67414cf08bSSenthil Nathan Thangaraj 		.ipi = &apu_ipi,
68414cf08bSSenthil Nathan Thangaraj 	},
69414cf08bSSenthil Nathan Thangaraj 	{
70414cf08bSSenthil Nathan Thangaraj 		.node_id = PM_DEV_CLUSTER1_ACPU_1,
71414cf08bSSenthil Nathan Thangaraj 		.ipi = &apu_ipi,
72414cf08bSSenthil Nathan Thangaraj 	},
73414cf08bSSenthil Nathan Thangaraj 	{
74414cf08bSSenthil Nathan Thangaraj 		.node_id = PM_DEV_CLUSTER2_ACPU_0,
75414cf08bSSenthil Nathan Thangaraj 		.ipi = &apu_ipi,
76414cf08bSSenthil Nathan Thangaraj 	},
77414cf08bSSenthil Nathan Thangaraj 	{
78414cf08bSSenthil Nathan Thangaraj 		.node_id = PM_DEV_CLUSTER2_ACPU_1,
79414cf08bSSenthil Nathan Thangaraj 		.ipi = &apu_ipi,
80414cf08bSSenthil Nathan Thangaraj 	},
81414cf08bSSenthil Nathan Thangaraj 	{
82414cf08bSSenthil Nathan Thangaraj 		.node_id = PM_DEV_CLUSTER3_ACPU_0,
83414cf08bSSenthil Nathan Thangaraj 		.ipi = &apu_ipi,
84414cf08bSSenthil Nathan Thangaraj 	},
85414cf08bSSenthil Nathan Thangaraj 	{
86414cf08bSSenthil Nathan Thangaraj 		.node_id = PM_DEV_CLUSTER3_ACPU_1,
87414cf08bSSenthil Nathan Thangaraj 		.ipi = &apu_ipi,
88414cf08bSSenthil Nathan Thangaraj 	},
89414cf08bSSenthil Nathan Thangaraj };
90414cf08bSSenthil Nathan Thangaraj 
91414cf08bSSenthil Nathan Thangaraj const struct pm_proc *primary_proc = &pm_procs_all[0];
92414cf08bSSenthil Nathan Thangaraj 
93414cf08bSSenthil Nathan Thangaraj /**
94414cf08bSSenthil Nathan Thangaraj  * pm_get_proc() - returns pointer to the proc structure.
95414cf08bSSenthil Nathan Thangaraj  * @cpuid: id of the cpu whose proc struct pointer should be returned.
96414cf08bSSenthil Nathan Thangaraj  *
97414cf08bSSenthil Nathan Thangaraj  * Return: Pointer to a proc structure if proc is found, otherwise NULL.
98414cf08bSSenthil Nathan Thangaraj  */
pm_get_proc(uint32_t cpuid)99414cf08bSSenthil Nathan Thangaraj const struct pm_proc *pm_get_proc(uint32_t cpuid)
100414cf08bSSenthil Nathan Thangaraj {
101414cf08bSSenthil Nathan Thangaraj 	const struct pm_proc *proc = NULL;
102414cf08bSSenthil Nathan Thangaraj 
103414cf08bSSenthil Nathan Thangaraj 	if (cpuid < ARRAY_SIZE(pm_procs_all)) {
104414cf08bSSenthil Nathan Thangaraj 		proc = &pm_procs_all[cpuid];
105414cf08bSSenthil Nathan Thangaraj 	} else {
106414cf08bSSenthil Nathan Thangaraj 		ERROR("cpuid: %d proc NULL\n", cpuid);
107414cf08bSSenthil Nathan Thangaraj 	}
108414cf08bSSenthil Nathan Thangaraj 
109414cf08bSSenthil Nathan Thangaraj 	return proc;
110414cf08bSSenthil Nathan Thangaraj }
111414cf08bSSenthil Nathan Thangaraj 
112414cf08bSSenthil Nathan Thangaraj /**
113414cf08bSSenthil Nathan Thangaraj  * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number.
114414cf08bSSenthil Nathan Thangaraj  * @irq: Interrupt number.
115414cf08bSSenthil Nathan Thangaraj  *
116414cf08bSSenthil Nathan Thangaraj  * Return: PM node index corresponding to the specified interrupt.
117414cf08bSSenthil Nathan Thangaraj  */
irq_to_pm_node_idx(uint32_t irq)118414cf08bSSenthil Nathan Thangaraj enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
119414cf08bSSenthil Nathan Thangaraj {
120414cf08bSSenthil Nathan Thangaraj 	enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN;
121414cf08bSSenthil Nathan Thangaraj 
122414cf08bSSenthil Nathan Thangaraj 	assert(irq <= IRQ_MAX);
123414cf08bSSenthil Nathan Thangaraj 
124414cf08bSSenthil Nathan Thangaraj 	switch (irq) {
125414cf08bSSenthil Nathan Thangaraj 	case 11:
126414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_I2C_2;
127414cf08bSSenthil Nathan Thangaraj 		break;
128414cf08bSSenthil Nathan Thangaraj 	case 12:
129414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_I2C_3;
130414cf08bSSenthil Nathan Thangaraj 		break;
131414cf08bSSenthil Nathan Thangaraj 	case 13:
132414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_I2C_4;
133414cf08bSSenthil Nathan Thangaraj 		break;
134414cf08bSSenthil Nathan Thangaraj 	case 20:
135414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_GPIO;
136414cf08bSSenthil Nathan Thangaraj 		break;
137414cf08bSSenthil Nathan Thangaraj 	case 21:
138414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_I2C_0;
139414cf08bSSenthil Nathan Thangaraj 		break;
140414cf08bSSenthil Nathan Thangaraj 	case 22:
141414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_I2C_1;
142414cf08bSSenthil Nathan Thangaraj 		break;
143414cf08bSSenthil Nathan Thangaraj 	case 23:
144414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_SPI_0;
145414cf08bSSenthil Nathan Thangaraj 		break;
146414cf08bSSenthil Nathan Thangaraj 	case 24:
147414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_SPI_1;
148414cf08bSSenthil Nathan Thangaraj 		break;
149414cf08bSSenthil Nathan Thangaraj 	case 25:
150414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_UART_0;
151414cf08bSSenthil Nathan Thangaraj 		break;
152414cf08bSSenthil Nathan Thangaraj 	case 26:
153414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_UART_1;
154414cf08bSSenthil Nathan Thangaraj 		break;
155414cf08bSSenthil Nathan Thangaraj 	case 27:
156414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_CAN_FD_0;
157414cf08bSSenthil Nathan Thangaraj 		break;
158414cf08bSSenthil Nathan Thangaraj 	case 28:
159414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_CAN_FD_1;
160414cf08bSSenthil Nathan Thangaraj 		break;
161414cf08bSSenthil Nathan Thangaraj 	case 29:
162414cf08bSSenthil Nathan Thangaraj 	case 30:
163414cf08bSSenthil Nathan Thangaraj 	case 31:
164414cf08bSSenthil Nathan Thangaraj 	case 32:
165414cf08bSSenthil Nathan Thangaraj 	case 33:
166414cf08bSSenthil Nathan Thangaraj 	case 98:
167414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_USB_0;
168414cf08bSSenthil Nathan Thangaraj 		break;
169414cf08bSSenthil Nathan Thangaraj 	case 34:
170414cf08bSSenthil Nathan Thangaraj 	case 35:
171414cf08bSSenthil Nathan Thangaraj 	case 36:
172414cf08bSSenthil Nathan Thangaraj 	case 37:
173414cf08bSSenthil Nathan Thangaraj 	case 38:
174414cf08bSSenthil Nathan Thangaraj 	case 99:
175414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_USB_1;
176414cf08bSSenthil Nathan Thangaraj 		break;
177414cf08bSSenthil Nathan Thangaraj 	case 39:
178414cf08bSSenthil Nathan Thangaraj 	case 40:
179414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_GEM_0;
180414cf08bSSenthil Nathan Thangaraj 		break;
181414cf08bSSenthil Nathan Thangaraj 	case 41:
182414cf08bSSenthil Nathan Thangaraj 	case 42:
183414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_GEM_1;
184414cf08bSSenthil Nathan Thangaraj 		break;
185414cf08bSSenthil Nathan Thangaraj 	case 43:
186414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_TTC_0;
187414cf08bSSenthil Nathan Thangaraj 		break;
188414cf08bSSenthil Nathan Thangaraj 	case 44:
189414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_TTC_1;
190414cf08bSSenthil Nathan Thangaraj 		break;
191414cf08bSSenthil Nathan Thangaraj 	case 45:
192414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_TTC_2;
193414cf08bSSenthil Nathan Thangaraj 		break;
194414cf08bSSenthil Nathan Thangaraj 	case 46:
195414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_TTC_3;
196414cf08bSSenthil Nathan Thangaraj 		break;
197414cf08bSSenthil Nathan Thangaraj 	case 47:
198414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_TTC_4;
199414cf08bSSenthil Nathan Thangaraj 		break;
200414cf08bSSenthil Nathan Thangaraj 	case 48:
201414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_TTC_5;
202414cf08bSSenthil Nathan Thangaraj 		break;
203414cf08bSSenthil Nathan Thangaraj 	case 49:
204414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_TTC_6;
205414cf08bSSenthil Nathan Thangaraj 		break;
206414cf08bSSenthil Nathan Thangaraj 	case 50:
207414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_TTC_7;
208414cf08bSSenthil Nathan Thangaraj 		break;
209414cf08bSSenthil Nathan Thangaraj 	case 72:
210414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_ADMA_0;
211414cf08bSSenthil Nathan Thangaraj 		break;
212414cf08bSSenthil Nathan Thangaraj 	case 73:
213414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_ADMA_1;
214414cf08bSSenthil Nathan Thangaraj 		break;
215414cf08bSSenthil Nathan Thangaraj 	case 74:
216414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_ADMA_2;
217414cf08bSSenthil Nathan Thangaraj 		break;
218414cf08bSSenthil Nathan Thangaraj 	case 75:
219414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_ADMA_3;
220414cf08bSSenthil Nathan Thangaraj 		break;
221414cf08bSSenthil Nathan Thangaraj 	case 76:
222414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_ADMA_4;
223414cf08bSSenthil Nathan Thangaraj 		break;
224414cf08bSSenthil Nathan Thangaraj 	case 77:
225414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_ADMA_5;
226414cf08bSSenthil Nathan Thangaraj 		break;
227414cf08bSSenthil Nathan Thangaraj 	case 78:
228414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_ADMA_6;
229414cf08bSSenthil Nathan Thangaraj 		break;
230414cf08bSSenthil Nathan Thangaraj 	case 79:
231414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_ADMA_7;
232414cf08bSSenthil Nathan Thangaraj 		break;
233414cf08bSSenthil Nathan Thangaraj 	case 95:
234414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_CAN_FD_2;
235414cf08bSSenthil Nathan Thangaraj 		break;
236414cf08bSSenthil Nathan Thangaraj 	case 96:
237414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_CAN_FD_3;
238414cf08bSSenthil Nathan Thangaraj 		break;
239414cf08bSSenthil Nathan Thangaraj 	case 100:
240414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_I2C_5;
241414cf08bSSenthil Nathan Thangaraj 		break;
242414cf08bSSenthil Nathan Thangaraj 	case 101:
243414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_I2C_6;
244414cf08bSSenthil Nathan Thangaraj 		break;
245414cf08bSSenthil Nathan Thangaraj 	case 102:
246414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_I2C_7;
247414cf08bSSenthil Nathan Thangaraj 		break;
2484589ce0aSNaman Trivedi 	case 164:
2494589ce0aSNaman Trivedi 		dev_idx = XPM_NODEIDX_DEV_MMI_GEM;
2504589ce0aSNaman Trivedi 		break;
251414cf08bSSenthil Nathan Thangaraj 	case 200:
252414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_RTC;
253414cf08bSSenthil Nathan Thangaraj 		break;
254414cf08bSSenthil Nathan Thangaraj 	case 218:
255414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_SDIO_0;
256414cf08bSSenthil Nathan Thangaraj 		break;
257414cf08bSSenthil Nathan Thangaraj 	case 220:
258414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_SDIO_1;
259414cf08bSSenthil Nathan Thangaraj 		break;
260414cf08bSSenthil Nathan Thangaraj 	default:
261414cf08bSSenthil Nathan Thangaraj 		dev_idx = XPM_NODEIDX_DEV_MIN;
262414cf08bSSenthil Nathan Thangaraj 		break;
263414cf08bSSenthil Nathan Thangaraj 	}
264414cf08bSSenthil Nathan Thangaraj 
265414cf08bSSenthil Nathan Thangaraj 	return dev_idx;
266414cf08bSSenthil Nathan Thangaraj }
267414cf08bSSenthil Nathan Thangaraj 
268414cf08bSSenthil Nathan Thangaraj /**
269414cf08bSSenthil Nathan Thangaraj  * pm_client_suspend() - Client-specific suspend actions. This function
270414cf08bSSenthil Nathan Thangaraj  *                       perform actions required prior to sending suspend
271414cf08bSSenthil Nathan Thangaraj  *                       request.
272414cf08bSSenthil Nathan Thangaraj  *                       Actions taken depend on the state system is
273414cf08bSSenthil Nathan Thangaraj  *                       suspending to.
274414cf08bSSenthil Nathan Thangaraj  * @proc: processor which need to suspend.
275414cf08bSSenthil Nathan Thangaraj  * @state: desired suspend state.
2765cac1d85SRonak Jain  * @flag: 0 - Call from secure source.
2775cac1d85SRonak Jain  *	  1 - Call from non-secure source.
278414cf08bSSenthil Nathan Thangaraj  */
pm_client_suspend(const struct pm_proc * proc,uint32_t state,uint32_t flag)2795cac1d85SRonak Jain void pm_client_suspend(const struct pm_proc *proc, uint32_t state, uint32_t flag)
280414cf08bSSenthil Nathan Thangaraj {
281414cf08bSSenthil Nathan Thangaraj 	uint32_t cpu_id = plat_my_core_pos();
282414cf08bSSenthil Nathan Thangaraj 	uintptr_t val;
283414cf08bSSenthil Nathan Thangaraj 	/*
284414cf08bSSenthil Nathan Thangaraj 	 * Get the core index, use it calculate offset for secondary cores
285414cf08bSSenthil Nathan Thangaraj 	 * to match with register database
286414cf08bSSenthil Nathan Thangaraj 	 */
287414cf08bSSenthil Nathan Thangaraj 	uint32_t core_index = cpu_id + ((cpu_id / 2U) * 2U);
288414cf08bSSenthil Nathan Thangaraj 
289414cf08bSSenthil Nathan Thangaraj 	pm_client_lock_get();
290414cf08bSSenthil Nathan Thangaraj 
291414cf08bSSenthil Nathan Thangaraj 	if (state == PM_STATE_SUSPEND_TO_RAM) {
2925cac1d85SRonak Jain 		pm_client_set_wakeup_sources((uint32_t)proc->node_id, flag);
293414cf08bSSenthil Nathan Thangaraj 	}
294414cf08bSSenthil Nathan Thangaraj 
295414cf08bSSenthil Nathan Thangaraj 	val = read_cpu_pwrctrl_val();
296414cf08bSSenthil Nathan Thangaraj 	val |= CORE_PWRDN_EN_BIT_MASK;
297414cf08bSSenthil Nathan Thangaraj 	write_cpu_pwrctrl_val(val);
298414cf08bSSenthil Nathan Thangaraj 
299414cf08bSSenthil Nathan Thangaraj 	isb();
300414cf08bSSenthil Nathan Thangaraj 
301414cf08bSSenthil Nathan Thangaraj 	/* Enable power down interrupt */
302414cf08bSSenthil Nathan Thangaraj 	mmio_write_32(APU_PCIL_CORE_X_IEN_POWER_REG(core_index),
303414cf08bSSenthil Nathan Thangaraj 		      APU_PCIL_CORE_X_IEN_POWER_MASK);
304414cf08bSSenthil Nathan Thangaraj 	/* Enable wake interrupt */
305414cf08bSSenthil Nathan Thangaraj 	mmio_write_32(APU_PCIL_CORE_X_IEN_WAKE_REG(core_index),
306414cf08bSSenthil Nathan Thangaraj 		      APU_PCIL_CORE_X_IEN_WAKE_MASK);
307414cf08bSSenthil Nathan Thangaraj 
308414cf08bSSenthil Nathan Thangaraj 	pm_client_lock_release();
309414cf08bSSenthil Nathan Thangaraj }
310414cf08bSSenthil Nathan Thangaraj 
311414cf08bSSenthil Nathan Thangaraj /**
312414cf08bSSenthil Nathan Thangaraj  * pm_get_cpuid() - get the local cpu ID for a global node ID.
313414cf08bSSenthil Nathan Thangaraj  * @nid: node id of the processor.
314414cf08bSSenthil Nathan Thangaraj  *
315414cf08bSSenthil Nathan Thangaraj  * Return: the cpu ID (starting from 0) for the subsystem.
316414cf08bSSenthil Nathan Thangaraj  */
pm_get_cpuid(uint32_t nid)317414cf08bSSenthil Nathan Thangaraj static uint32_t pm_get_cpuid(uint32_t nid)
318414cf08bSSenthil Nathan Thangaraj {
319414cf08bSSenthil Nathan Thangaraj 	uint32_t ret = (uint32_t) UNDEFINED_CPUID;
320414cf08bSSenthil Nathan Thangaraj 	size_t i;
321414cf08bSSenthil Nathan Thangaraj 
322414cf08bSSenthil Nathan Thangaraj 	for (i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
323414cf08bSSenthil Nathan Thangaraj 		if (pm_procs_all[i].node_id == nid) {
324414cf08bSSenthil Nathan Thangaraj 			ret = (uint32_t)i;
325414cf08bSSenthil Nathan Thangaraj 			break;
326414cf08bSSenthil Nathan Thangaraj 		}
327414cf08bSSenthil Nathan Thangaraj 	}
328414cf08bSSenthil Nathan Thangaraj 
329414cf08bSSenthil Nathan Thangaraj 	return ret;
330414cf08bSSenthil Nathan Thangaraj }
331414cf08bSSenthil Nathan Thangaraj 
332414cf08bSSenthil Nathan Thangaraj /**
333414cf08bSSenthil Nathan Thangaraj  * pm_client_wakeup() - Client-specific wakeup actions.
334414cf08bSSenthil Nathan Thangaraj  * @proc: Processor which need to wakeup.
335414cf08bSSenthil Nathan Thangaraj  *
336414cf08bSSenthil Nathan Thangaraj  * This function should contain any PU-specific actions
337414cf08bSSenthil Nathan Thangaraj  * required for waking up another APU core.
338414cf08bSSenthil Nathan Thangaraj  */
pm_client_wakeup(const struct pm_proc * proc)339414cf08bSSenthil Nathan Thangaraj void pm_client_wakeup(const struct pm_proc *proc)
340414cf08bSSenthil Nathan Thangaraj {
341414cf08bSSenthil Nathan Thangaraj 	uint32_t cpuid = pm_get_cpuid(proc->node_id);
342414cf08bSSenthil Nathan Thangaraj 	uintptr_t val;
343414cf08bSSenthil Nathan Thangaraj 
344414cf08bSSenthil Nathan Thangaraj 	if (cpuid != (uint32_t) UNDEFINED_CPUID) {
34502210f63SJay Buddhabhatti 		/*
34602210f63SJay Buddhabhatti 		 * Get the core index and use it to calculate offset for
34702210f63SJay Buddhabhatti 		 * disabling power down and wakeup interrupts.
34802210f63SJay Buddhabhatti 		 * i.e., Convert cpu-id to core_index with the following mapping:
34902210f63SJay Buddhabhatti 		 *  cpu-id -> core_index
35002210f63SJay Buddhabhatti 		 *       0 -> 0
35102210f63SJay Buddhabhatti 		 *       1 -> 1
35202210f63SJay Buddhabhatti 		 *       2 -> 4
35302210f63SJay Buddhabhatti 		 *       3 -> 5
35402210f63SJay Buddhabhatti 		 *       4 -> 8
35502210f63SJay Buddhabhatti 		 *       5 -> 9
35602210f63SJay Buddhabhatti 		 *       6 -> 12
35702210f63SJay Buddhabhatti 		 *       7 -> 13
35802210f63SJay Buddhabhatti 		 * to match with register database.
35902210f63SJay Buddhabhatti 		 */
36002210f63SJay Buddhabhatti 		uint32_t core_index = cpuid + ((cpuid / 2U) * 2U);
36102210f63SJay Buddhabhatti 
362414cf08bSSenthil Nathan Thangaraj 		pm_client_lock_get();
363414cf08bSSenthil Nathan Thangaraj 
364414cf08bSSenthil Nathan Thangaraj 		/* Clear powerdown request */
365414cf08bSSenthil Nathan Thangaraj 		val = read_cpu_pwrctrl_val();
366414cf08bSSenthil Nathan Thangaraj 		val &= ~CORE_PWRDN_EN_BIT_MASK;
367414cf08bSSenthil Nathan Thangaraj 		write_cpu_pwrctrl_val(val);
368414cf08bSSenthil Nathan Thangaraj 
369414cf08bSSenthil Nathan Thangaraj 		isb();
370414cf08bSSenthil Nathan Thangaraj 
371414cf08bSSenthil Nathan Thangaraj 		/* Disabled power down interrupt */
37202210f63SJay Buddhabhatti 		mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(core_index),
373414cf08bSSenthil Nathan Thangaraj 			      APU_PCIL_CORE_X_IDS_POWER_MASK);
374414cf08bSSenthil Nathan Thangaraj 		/* Disable wake interrupt */
37502210f63SJay Buddhabhatti 		mmio_write_32(APU_PCIL_CORE_X_IDS_WAKE_REG(core_index),
376414cf08bSSenthil Nathan Thangaraj 			      APU_PCIL_CORE_X_IDS_WAKE_MASK);
377414cf08bSSenthil Nathan Thangaraj 
378414cf08bSSenthil Nathan Thangaraj 		pm_client_lock_release();
379414cf08bSSenthil Nathan Thangaraj 	}
380414cf08bSSenthil Nathan Thangaraj }
381