1a92681d9SJay Buddhabhatti /*
2a92681d9SJay Buddhabhatti * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
3c35fe294SDevanshi Chauhan Alpeshbhai * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
4a92681d9SJay Buddhabhatti *
5a92681d9SJay Buddhabhatti * SPDX-License-Identifier: BSD-3-Clause
6a92681d9SJay Buddhabhatti */
7a92681d9SJay Buddhabhatti
8a92681d9SJay Buddhabhatti /*
9a92681d9SJay Buddhabhatti * Versal system level PM-API functions and communication with PMC via
10a92681d9SJay Buddhabhatti * IPI interrupts
11a92681d9SJay Buddhabhatti */
12a92681d9SJay Buddhabhatti
134fd510e0SRonak Jain #include <common/ep_info.h>
144fd510e0SRonak Jain #include <common/debug.h>
153ae28aa4SJay Buddhabhatti #include <drivers/arm/gic_common.h>
163ae28aa4SJay Buddhabhatti #include <lib/mmio.h>
173ae28aa4SJay Buddhabhatti #include <lib/utils.h>
18a92681d9SJay Buddhabhatti #include <plat/common/platform.h>
193ae28aa4SJay Buddhabhatti #include <platform_def.h>
203ae28aa4SJay Buddhabhatti #include <pm_api_sys.h>
213ae28aa4SJay Buddhabhatti #include <pm_client.h>
223ae28aa4SJay Buddhabhatti #include <pm_common.h>
233ae28aa4SJay Buddhabhatti #include <pm_defs.h>
243ae28aa4SJay Buddhabhatti #include <pm_ipi.h>
25a92681d9SJay Buddhabhatti #include "pm_svc_main.h"
26a92681d9SJay Buddhabhatti
273ae28aa4SJay Buddhabhatti #define NUM_GICD_ISENABLER ((IRQ_MAX >> 5U) + 1U)
283ae28aa4SJay Buddhabhatti
29a92681d9SJay Buddhabhatti /* default shutdown/reboot scope is system(2) */
30a92681d9SJay Buddhabhatti static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
31a92681d9SJay Buddhabhatti
32a92681d9SJay Buddhabhatti /**
33de7ed953SPrasad Kummari * pm_get_shutdown_scope() - Get the currently set shutdown scope.
34a92681d9SJay Buddhabhatti *
35de7ed953SPrasad Kummari * Return: Shutdown scope value.
36de7ed953SPrasad Kummari *
37a92681d9SJay Buddhabhatti */
pm_get_shutdown_scope(void)38a92681d9SJay Buddhabhatti uint32_t pm_get_shutdown_scope(void)
39a92681d9SJay Buddhabhatti {
40a92681d9SJay Buddhabhatti return pm_shutdown_scope;
41a92681d9SJay Buddhabhatti }
42a92681d9SJay Buddhabhatti
43a92681d9SJay Buddhabhatti /* PM API functions */
44a92681d9SJay Buddhabhatti
45a92681d9SJay Buddhabhatti /**
463ae28aa4SJay Buddhabhatti * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as
473ae28aa4SJay Buddhabhatti * wake sources in the XilPM.
48de7ed953SPrasad Kummari * @node_id: Node id of processor.
495cac1d85SRonak Jain * @flag: 0 - Call from secure source.
505cac1d85SRonak Jain * 1 - Call from non-secure source.
51de7ed953SPrasad Kummari *
523ae28aa4SJay Buddhabhatti */
pm_client_set_wakeup_sources(uint32_t node_id,uint32_t flag)535cac1d85SRonak Jain void pm_client_set_wakeup_sources(uint32_t node_id, uint32_t flag)
543ae28aa4SJay Buddhabhatti {
553ae28aa4SJay Buddhabhatti uint32_t reg_num, device_id;
563ae28aa4SJay Buddhabhatti uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = {0U};
5779953190SJay Buddhabhatti uint32_t isenabler1 = PLAT_ARM_GICD_BASE + GICD_ISENABLER + 4U;
583ae28aa4SJay Buddhabhatti
593ae28aa4SJay Buddhabhatti zeromem(&pm_wakeup_nodes_set, (u_register_t)sizeof(pm_wakeup_nodes_set));
603ae28aa4SJay Buddhabhatti
613ae28aa4SJay Buddhabhatti for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
623ae28aa4SJay Buddhabhatti uint32_t base_irq = reg_num << ISENABLER_SHIFT;
63b3d25dcaSMadhav Bhatt uint32_t reg = mmio_read_32((uint64_t)(isenabler1 + (reg_num << 2)));
643ae28aa4SJay Buddhabhatti
653ae28aa4SJay Buddhabhatti if (reg == 0U) {
663ae28aa4SJay Buddhabhatti continue;
673ae28aa4SJay Buddhabhatti }
683ae28aa4SJay Buddhabhatti
693ae28aa4SJay Buddhabhatti while (reg != 0U) {
703ae28aa4SJay Buddhabhatti enum pm_device_node_idx node_idx;
713ae28aa4SJay Buddhabhatti uint32_t idx, irq, lowest_set = reg & (-reg);
723ae28aa4SJay Buddhabhatti enum pm_ret_status ret;
733ae28aa4SJay Buddhabhatti
74964e5592SJay Buddhabhatti idx = (uint32_t)__builtin_ctz(lowest_set);
753ae28aa4SJay Buddhabhatti irq = base_irq + idx;
763ae28aa4SJay Buddhabhatti
773ae28aa4SJay Buddhabhatti if (irq > IRQ_MAX) {
783ae28aa4SJay Buddhabhatti break;
793ae28aa4SJay Buddhabhatti }
803ae28aa4SJay Buddhabhatti
813ae28aa4SJay Buddhabhatti node_idx = irq_to_pm_node_idx(irq);
823ae28aa4SJay Buddhabhatti reg &= ~lowest_set;
833ae28aa4SJay Buddhabhatti
84c9841236SJay Buddhabhatti if (node_idx > XPM_NODEIDX_DEV_MIN) {
853ae28aa4SJay Buddhabhatti if (pm_wakeup_nodes_set[node_idx] == 0U) {
863ae28aa4SJay Buddhabhatti /* Get device ID from node index */
87964e5592SJay Buddhabhatti device_id = PERIPH_DEVID((uint32_t)node_idx);
883ae28aa4SJay Buddhabhatti ret = pm_set_wakeup_source(node_id,
893ae28aa4SJay Buddhabhatti device_id, 1U,
905cac1d85SRonak Jain flag);
913ae28aa4SJay Buddhabhatti pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ?
923ae28aa4SJay Buddhabhatti 1U : 0U;
933ae28aa4SJay Buddhabhatti }
943ae28aa4SJay Buddhabhatti }
953ae28aa4SJay Buddhabhatti }
963ae28aa4SJay Buddhabhatti }
973ae28aa4SJay Buddhabhatti }
983ae28aa4SJay Buddhabhatti
993ae28aa4SJay Buddhabhatti /**
100de7ed953SPrasad Kummari * pm_handle_eemi_call() - PM call for processor to send eemi payload.
101de7ed953SPrasad Kummari * @flag: 0 - Call from secure source.
102de7ed953SPrasad Kummari * 1 - Call from non-secure source.
103de7ed953SPrasad Kummari * @x0: Arguments received per SMC64 standard.
104de7ed953SPrasad Kummari * @x1: Arguments received per SMC64 standard.
105de7ed953SPrasad Kummari * @x2: Arguments received per SMC64 standard.
106de7ed953SPrasad Kummari * @x3: Arguments received per SMC64 standard.
107de7ed953SPrasad Kummari * @x4: Arguments received per SMC64 standard.
108de7ed953SPrasad Kummari * @x5: Arguments received per SMC64 standard.
109de7ed953SPrasad Kummari * @result: Payload received from firmware.
110a92681d9SJay Buddhabhatti *
111de7ed953SPrasad Kummari * Return: PM_RET_SUCCESS on success or error code.
112de7ed953SPrasad Kummari *
113a92681d9SJay Buddhabhatti */
pm_handle_eemi_call(uint32_t flag,uint32_t x0,uint32_t x1,uint32_t x2,uint32_t x3,uint32_t x4,uint32_t x5,uint32_t * result)114a92681d9SJay Buddhabhatti enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
115a92681d9SJay Buddhabhatti uint32_t x2, uint32_t x3, uint32_t x4,
116c35fe294SDevanshi Chauhan Alpeshbhai uint32_t x5, uint32_t *result)
117a92681d9SJay Buddhabhatti {
118a92681d9SJay Buddhabhatti uint32_t payload[PAYLOAD_ARG_CNT] = {0};
119a92681d9SJay Buddhabhatti uint32_t module_id;
120a92681d9SJay Buddhabhatti
121a92681d9SJay Buddhabhatti module_id = (x0 & MODULE_ID_MASK) >> 8U;
122a92681d9SJay Buddhabhatti
123a92681d9SJay Buddhabhatti //default module id is for LIBPM
12483bcef3fSMaheedhar Bollapalli if (module_id == 0U) {
125a92681d9SJay Buddhabhatti module_id = LIBPM_MODULE_ID;
126a92681d9SJay Buddhabhatti }
127a92681d9SJay Buddhabhatti
128a92681d9SJay Buddhabhatti PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
129c35fe294SDevanshi Chauhan Alpeshbhai return pm_ipi_send_sync(primary_proc, payload, result, RET_PAYLOAD_ARG_CNT);
130a92681d9SJay Buddhabhatti }
131a92681d9SJay Buddhabhatti
132a92681d9SJay Buddhabhatti /**
133a92681d9SJay Buddhabhatti * pm_self_suspend() - PM call for processor to suspend itself
134de7ed953SPrasad Kummari * @nid: Node id of the processor or subsystem.
135de7ed953SPrasad Kummari * @latency: Requested maximum wakeup latency (not supported).
136de7ed953SPrasad Kummari * @state: Requested state.
137de7ed953SPrasad Kummari * @address: Resume address.
138de7ed953SPrasad Kummari * @flag: 0 - Call from secure source.
139de7ed953SPrasad Kummari * 1 - Call from non-secure source.
140a92681d9SJay Buddhabhatti *
141a92681d9SJay Buddhabhatti * This is a blocking call, it will return only once PMU has responded.
142a92681d9SJay Buddhabhatti * On a wakeup, resume address will be automatically set by PMU.
143a92681d9SJay Buddhabhatti *
144de7ed953SPrasad Kummari * Return: Returns status, either success or error+reason.
145de7ed953SPrasad Kummari *
146a92681d9SJay Buddhabhatti */
pm_self_suspend(uint32_t nid,uint32_t latency,uint32_t state,uintptr_t address,uint32_t flag)147a92681d9SJay Buddhabhatti enum pm_ret_status pm_self_suspend(uint32_t nid,
148a92681d9SJay Buddhabhatti uint32_t latency,
149a92681d9SJay Buddhabhatti uint32_t state,
150a92681d9SJay Buddhabhatti uintptr_t address, uint32_t flag)
151a92681d9SJay Buddhabhatti {
152a92681d9SJay Buddhabhatti uint32_t payload[PAYLOAD_ARG_CNT];
153a92681d9SJay Buddhabhatti uint32_t cpuid = plat_my_core_pos();
154a92681d9SJay Buddhabhatti const struct pm_proc *proc = pm_get_proc(cpuid);
155906d5892SNithin G enum pm_ret_status ret = PM_RET_ERROR_INTERNAL;
156a92681d9SJay Buddhabhatti
157a92681d9SJay Buddhabhatti if (proc == NULL) {
158a92681d9SJay Buddhabhatti WARN("Failed to get proc %d\n", cpuid);
159906d5892SNithin G goto exit_label;
160a92681d9SJay Buddhabhatti }
161a92681d9SJay Buddhabhatti
162a92681d9SJay Buddhabhatti /*
163a92681d9SJay Buddhabhatti * Do client specific suspend operations
164a92681d9SJay Buddhabhatti * (e.g. set powerdown request bit)
165a92681d9SJay Buddhabhatti */
1665cac1d85SRonak Jain pm_client_suspend(proc, state, flag);
167a92681d9SJay Buddhabhatti
168a92681d9SJay Buddhabhatti /* Send request to the PLM */
169a92681d9SJay Buddhabhatti PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, flag, PM_SELF_SUSPEND,
170d87b0ce3SDevanshi Chauhan Alpeshbhai nid, latency, state, address, (address >> 32));
171906d5892SNithin G ret = pm_ipi_send_sync(proc, payload, NULL, 0);
172906d5892SNithin G
173906d5892SNithin G exit_label:
174906d5892SNithin G return ret;
175a92681d9SJay Buddhabhatti }
176a92681d9SJay Buddhabhatti
177a92681d9SJay Buddhabhatti /**
178a92681d9SJay Buddhabhatti * pm_req_wakeup() - PM call for processor to wake up selected processor
179de7ed953SPrasad Kummari * or subsystem.
180de7ed953SPrasad Kummari * @target: Device ID of the processor or subsystem to wake up.
181de7ed953SPrasad Kummari * @set_address: Resume address presence indicator.
182de7ed953SPrasad Kummari * 1 - resume address specified, 0 - otherwise.
183de7ed953SPrasad Kummari * @address: Resume address.
184de7ed953SPrasad Kummari * @ack: Flag to specify whether acknowledge requested.
185de7ed953SPrasad Kummari * @flag: 0 - Call from secure source.
186de7ed953SPrasad Kummari * 1 - Call from non-secure source.
187a92681d9SJay Buddhabhatti *
188a92681d9SJay Buddhabhatti * This API function is either used to power up another APU core for SMP
189a92681d9SJay Buddhabhatti * (by PSCI) or to power up an entirely different PU or subsystem, such
190a92681d9SJay Buddhabhatti * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
191a92681d9SJay Buddhabhatti * automatically set by PMC.
192a92681d9SJay Buddhabhatti *
193de7ed953SPrasad Kummari * Return: Returns status, either success or error+reason.
194de7ed953SPrasad Kummari *
195a92681d9SJay Buddhabhatti */
pm_req_wakeup(uint32_t target,uint32_t set_address,uintptr_t address,uint8_t ack,uint32_t flag)196a92681d9SJay Buddhabhatti enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
197a92681d9SJay Buddhabhatti uintptr_t address, uint8_t ack, uint32_t flag)
198a92681d9SJay Buddhabhatti {
199a92681d9SJay Buddhabhatti uint32_t payload[PAYLOAD_ARG_CNT];
200a92681d9SJay Buddhabhatti
201a92681d9SJay Buddhabhatti /* Send request to the PMC to perform the wake of the PU */
202a92681d9SJay Buddhabhatti PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQ_WAKEUP, target,
203a92681d9SJay Buddhabhatti set_address, address, ack);
204a92681d9SJay Buddhabhatti
205a92681d9SJay Buddhabhatti return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
206a92681d9SJay Buddhabhatti }
207a92681d9SJay Buddhabhatti
208a92681d9SJay Buddhabhatti /**
209de7ed953SPrasad Kummari * pm_get_callbackdata() - Read from IPI response buffer.
210de7ed953SPrasad Kummari * @data: array of PAYLOAD_ARG_CNT elements.
211de7ed953SPrasad Kummari * @count: Number of values to return.
212de7ed953SPrasad Kummari * @flag: 0 - Call from secure source.
213de7ed953SPrasad Kummari * 1 - Call from non-secure source.
214de7ed953SPrasad Kummari * @ack: 0 - Do not ack IPI after reading payload.
215de7ed953SPrasad Kummari * 1 - Ack IPI after reading payload.
216a92681d9SJay Buddhabhatti *
217a92681d9SJay Buddhabhatti * Read value from ipi buffer response buffer.
218de7ed953SPrasad Kummari * Return: Returns status, either success or error.
219de7ed953SPrasad Kummari *
220a92681d9SJay Buddhabhatti */
pm_get_callbackdata(uint32_t * data,size_t count,uint32_t flag,uint32_t ack)221a92681d9SJay Buddhabhatti enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
222a92681d9SJay Buddhabhatti {
223a92681d9SJay Buddhabhatti enum pm_ret_status ret = PM_RET_SUCCESS;
224906d5892SNithin G
225d87b0ce3SDevanshi Chauhan Alpeshbhai /*
226d87b0ce3SDevanshi Chauhan Alpeshbhai * Typecasting to void to intentionally retain the variable and avoid
227d87b0ce3SDevanshi Chauhan Alpeshbhai * MISRA violation for unused parameters. This may be used in the
228d87b0ce3SDevanshi Chauhan Alpeshbhai * future if callbacks to a secure target are required.
229d87b0ce3SDevanshi Chauhan Alpeshbhai */
230d87b0ce3SDevanshi Chauhan Alpeshbhai (void)flag;
231d87b0ce3SDevanshi Chauhan Alpeshbhai
232a92681d9SJay Buddhabhatti /* Return if interrupt is not from PMU */
233906d5892SNithin G if (pm_ipi_irq_status(primary_proc) != 0U) {
234a92681d9SJay Buddhabhatti
235a92681d9SJay Buddhabhatti ret = pm_ipi_buff_read_callb(data, count);
236a92681d9SJay Buddhabhatti
237a92681d9SJay Buddhabhatti if (ack != 0U) {
238a92681d9SJay Buddhabhatti pm_ipi_irq_clear(primary_proc);
239a92681d9SJay Buddhabhatti }
240906d5892SNithin G }
241a92681d9SJay Buddhabhatti
242a92681d9SJay Buddhabhatti return ret;
243a92681d9SJay Buddhabhatti }
244a92681d9SJay Buddhabhatti
245a92681d9SJay Buddhabhatti /**
246a92681d9SJay Buddhabhatti * pm_force_powerdown() - PM call to request for another PU or subsystem to
247de7ed953SPrasad Kummari * be powered down forcefully.
248de7ed953SPrasad Kummari * @target: Device ID of the PU node to be forced powered down.
249de7ed953SPrasad Kummari * @ack: Flag to specify whether acknowledge is requested
250de7ed953SPrasad Kummari * @flag: 0 - Call from secure source
251a92681d9SJay Buddhabhatti * 1 - Call from non-secure source
252a92681d9SJay Buddhabhatti *
253de7ed953SPrasad Kummari * Return: Returns status, either success or error+reason.
254de7ed953SPrasad Kummari *
255a92681d9SJay Buddhabhatti */
pm_force_powerdown(uint32_t target,uint8_t ack,uint32_t flag)256a92681d9SJay Buddhabhatti enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
257a92681d9SJay Buddhabhatti uint32_t flag)
258a92681d9SJay Buddhabhatti {
259a92681d9SJay Buddhabhatti uint32_t payload[PAYLOAD_ARG_CNT];
260906d5892SNithin G enum pm_ret_status ret = PM_RET_SUCCESS;
261a92681d9SJay Buddhabhatti
262a92681d9SJay Buddhabhatti /* Send request to the PMC */
263a92681d9SJay Buddhabhatti PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN,
264a92681d9SJay Buddhabhatti target, ack);
265a92681d9SJay Buddhabhatti
26683bcef3fSMaheedhar Bollapalli if (ack == (uint32_t)IPI_BLOCKING) {
267906d5892SNithin G ret = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
268a92681d9SJay Buddhabhatti } else {
269906d5892SNithin G ret = pm_ipi_send(primary_proc, payload);
270a92681d9SJay Buddhabhatti }
271906d5892SNithin G
272906d5892SNithin G return ret;
273a92681d9SJay Buddhabhatti }
274a92681d9SJay Buddhabhatti
275a92681d9SJay Buddhabhatti /**
276de7ed953SPrasad Kummari * pm_system_shutdown() - PM call to request a system shutdown or restart.
277de7ed953SPrasad Kummari * @type: Shutdown or restart? 0=shutdown, 1=restart, 2=setscope.
278de7ed953SPrasad Kummari * @subtype: Scope: 0=APU-subsystem, 1=PS, 2=system.
279de7ed953SPrasad Kummari * @flag: 0 - Call from secure source.
280de7ed953SPrasad Kummari * 1 - Call from non-secure source.
281a92681d9SJay Buddhabhatti *
282de7ed953SPrasad Kummari * Return: Returns status, either success or error+reason.
283de7ed953SPrasad Kummari *
284a92681d9SJay Buddhabhatti */
pm_system_shutdown(uint32_t type,uint32_t subtype,uint32_t flag)285a92681d9SJay Buddhabhatti enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
286a92681d9SJay Buddhabhatti uint32_t flag)
287a92681d9SJay Buddhabhatti {
288a92681d9SJay Buddhabhatti uint32_t payload[PAYLOAD_ARG_CNT];
289906d5892SNithin G enum pm_ret_status ret = PM_RET_SUCCESS;
290a92681d9SJay Buddhabhatti
291a92681d9SJay Buddhabhatti if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
292a92681d9SJay Buddhabhatti /* Setting scope for subsequent PSCI reboot or shutdown */
293a92681d9SJay Buddhabhatti pm_shutdown_scope = subtype;
294906d5892SNithin G goto exit_label;
295a92681d9SJay Buddhabhatti }
296a92681d9SJay Buddhabhatti
297a92681d9SJay Buddhabhatti /* Send request to the PMC */
298a92681d9SJay Buddhabhatti PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SYSTEM_SHUTDOWN,
299a92681d9SJay Buddhabhatti type, subtype);
300a92681d9SJay Buddhabhatti
301906d5892SNithin G ret = pm_ipi_send_non_blocking(primary_proc, payload);
302906d5892SNithin G
303906d5892SNithin G exit_label:
304906d5892SNithin G return ret;
305a92681d9SJay Buddhabhatti }
306a92681d9SJay Buddhabhatti
307a92681d9SJay Buddhabhatti /**
308de7ed953SPrasad Kummari * pm_set_wakeup_source() - PM call to specify the wakeup source while
309de7ed953SPrasad Kummari * suspended.
310de7ed953SPrasad Kummari * @target: Device id of the targeted PU or subsystem
311de7ed953SPrasad Kummari * @wkup_device: Device id of the wakeup peripheral
312de7ed953SPrasad Kummari * @enable: Enable or disable the specified peripheral as wake source
313de7ed953SPrasad Kummari * @flag: 0 - Call from secure source
314a92681d9SJay Buddhabhatti * 1 - Call from non-secure source
315a92681d9SJay Buddhabhatti *
316de7ed953SPrasad Kummari * Return: Returns status, either success or error+reason.
317de7ed953SPrasad Kummari *
318a92681d9SJay Buddhabhatti */
pm_set_wakeup_source(uint32_t target,uint32_t wkup_device,uint8_t enable,uint32_t flag)319a92681d9SJay Buddhabhatti enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
320a92681d9SJay Buddhabhatti uint8_t enable, uint32_t flag)
321a92681d9SJay Buddhabhatti {
322a92681d9SJay Buddhabhatti uint32_t payload[PAYLOAD_ARG_CNT];
323a92681d9SJay Buddhabhatti
324a92681d9SJay Buddhabhatti PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE,
325a92681d9SJay Buddhabhatti target, wkup_device, enable);
326a92681d9SJay Buddhabhatti return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
327a92681d9SJay Buddhabhatti }
328a92681d9SJay Buddhabhatti
329a92681d9SJay Buddhabhatti /**
330e25fad87SDevanshi Chauhan * tfa_api_feature_check() - Returns the supported TF-A API version if supported.
331e25fad87SDevanshi Chauhan * @api_id: TF-A specific API ID to check.
3329a0f5d12SJay Buddhabhatti * @ret_payload: pointer to array of PAYLOAD_ARG_CNT number of
3339a0f5d12SJay Buddhabhatti * words Returned supported API version
3349a0f5d12SJay Buddhabhatti *
3359a0f5d12SJay Buddhabhatti * Return: Returns status, either success or error+reason.
3369a0f5d12SJay Buddhabhatti */
tfa_api_feature_check(uint32_t api_id,uint32_t * ret_payload)337e25fad87SDevanshi Chauhan enum pm_ret_status tfa_api_feature_check(uint32_t api_id, uint32_t *ret_payload)
3389a0f5d12SJay Buddhabhatti {
3399a0f5d12SJay Buddhabhatti enum pm_ret_status ret;
3409a0f5d12SJay Buddhabhatti
3419a0f5d12SJay Buddhabhatti /* Return version of API which are implemented in TF-A only */
3429a0f5d12SJay Buddhabhatti switch (api_id) {
3439a0f5d12SJay Buddhabhatti case PM_GET_CALLBACK_DATA:
3449a0f5d12SJay Buddhabhatti case PM_GET_TRUSTZONE_VERSION:
3459a0f5d12SJay Buddhabhatti ret_payload[0] = PM_API_VERSION_2;
3469a0f5d12SJay Buddhabhatti ret = PM_RET_SUCCESS;
3479a0f5d12SJay Buddhabhatti break;
3489a0f5d12SJay Buddhabhatti case TF_A_PM_REGISTER_SGI:
3499a0f5d12SJay Buddhabhatti case TF_A_FEATURE_CHECK:
3501d4372c4SJay Buddhabhatti case TF_A_CLEAR_PM_STATE:
3519a0f5d12SJay Buddhabhatti ret_payload[0] = PM_API_BASE_VERSION;
3529a0f5d12SJay Buddhabhatti ret = PM_RET_SUCCESS;
3539a0f5d12SJay Buddhabhatti break;
3549a0f5d12SJay Buddhabhatti default:
3559a0f5d12SJay Buddhabhatti ret = PM_RET_ERROR_NO_FEATURE;
356a335cd91SDevanshi Chauhan Alpeshbhai break;
3579a0f5d12SJay Buddhabhatti }
3589a0f5d12SJay Buddhabhatti
3599a0f5d12SJay Buddhabhatti return ret;
3609a0f5d12SJay Buddhabhatti }
3619a0f5d12SJay Buddhabhatti
3629a0f5d12SJay Buddhabhatti /**
363de7ed953SPrasad Kummari * pm_feature_check() - Returns the supported API version if supported.
364de7ed953SPrasad Kummari * @api_id: API ID to check.
365de7ed953SPrasad Kummari * @flag: 0 - Call from secure source.
366de7ed953SPrasad Kummari * 1 - Call from non-secure source.
367de7ed953SPrasad Kummari * @ret_payload: pointer to array of PAYLOAD_ARG_CNT number of
368a92681d9SJay Buddhabhatti * words Returned supported API version and bitmasks
369a92681d9SJay Buddhabhatti * for IOCTL and QUERY ID
370a92681d9SJay Buddhabhatti *
371de7ed953SPrasad Kummari * Return: Returns status, either success or error+reason.
372de7ed953SPrasad Kummari *
373a92681d9SJay Buddhabhatti */
pm_feature_check(uint32_t api_id,uint32_t * ret_payload,uint32_t flag)374a92681d9SJay Buddhabhatti enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
375a92681d9SJay Buddhabhatti uint32_t flag)
376a92681d9SJay Buddhabhatti {
377a92681d9SJay Buddhabhatti uint32_t payload[PAYLOAD_ARG_CNT];
378a92681d9SJay Buddhabhatti uint32_t module_id;
379906d5892SNithin G enum pm_ret_status ret;
380*eaceb373SDevanshi Chauhan static bool deprecation_warned;
381a92681d9SJay Buddhabhatti
382*eaceb373SDevanshi Chauhan if (!deprecation_warned) {
383*eaceb373SDevanshi Chauhan WARN("%s will be deprecated in 2027.1 release. Use tfa_api_feature_check() for TF-A specific APIs.\n",
384*eaceb373SDevanshi Chauhan __func__);
385*eaceb373SDevanshi Chauhan deprecation_warned = true;
386*eaceb373SDevanshi Chauhan }
387de5c4451SDevanshi Chauhan
388c8be2240SPrasad Kummari /* Return version of API which are implemented in TF-A only */
389a92681d9SJay Buddhabhatti switch (api_id) {
390a92681d9SJay Buddhabhatti case PM_GET_CALLBACK_DATA:
391a92681d9SJay Buddhabhatti case PM_GET_TRUSTZONE_VERSION:
392a92681d9SJay Buddhabhatti ret_payload[0] = PM_API_VERSION_2;
393906d5892SNithin G ret = PM_RET_SUCCESS;
394ea3ec865SDevanshi Chauhan Alpeshbhai break;
395a92681d9SJay Buddhabhatti case TF_A_PM_REGISTER_SGI:
396a92681d9SJay Buddhabhatti ret_payload[0] = PM_API_BASE_VERSION;
397906d5892SNithin G ret = PM_RET_SUCCESS;
398a92681d9SJay Buddhabhatti break;
399ea3ec865SDevanshi Chauhan Alpeshbhai default:
400a92681d9SJay Buddhabhatti module_id = (api_id & MODULE_ID_MASK) >> 8U;
401a92681d9SJay Buddhabhatti
402a92681d9SJay Buddhabhatti /*
403a92681d9SJay Buddhabhatti * feature check should be done only for LIBPM module
404a92681d9SJay Buddhabhatti * If module_id is 0, then we consider it LIBPM module as default id
405a92681d9SJay Buddhabhatti */
40683bcef3fSMaheedhar Bollapalli if ((module_id > 0U) && (module_id != LIBPM_MODULE_ID)) {
407906d5892SNithin G ret = PM_RET_SUCCESS;
408ea3ec865SDevanshi Chauhan Alpeshbhai break;
409a92681d9SJay Buddhabhatti }
410a92681d9SJay Buddhabhatti
411a92681d9SJay Buddhabhatti PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
412a92681d9SJay Buddhabhatti PM_FEATURE_CHECK, api_id);
413906d5892SNithin G ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, RET_PAYLOAD_ARG_CNT);
414906d5892SNithin G
415ea3ec865SDevanshi Chauhan Alpeshbhai break;
416ea3ec865SDevanshi Chauhan Alpeshbhai }
417906d5892SNithin G
418ea3ec865SDevanshi Chauhan Alpeshbhai return ret;
419a92681d9SJay Buddhabhatti }
420a92681d9SJay Buddhabhatti
421a92681d9SJay Buddhabhatti /**
422de7ed953SPrasad Kummari * pm_load_pdi() - Load the PDI. This function provides support to load
423de7ed953SPrasad Kummari * PDI from linux.
424a92681d9SJay Buddhabhatti *
425de7ed953SPrasad Kummari * @src: Source device of pdi(DDR, OCM, SD etc).
426de7ed953SPrasad Kummari * @address_low: lower 32-bit Linear memory space address.
427de7ed953SPrasad Kummari * @address_high: higher 32-bit Linear memory space address.
428de7ed953SPrasad Kummari * @flag: 0 - Call from secure source.
429de7ed953SPrasad Kummari * 1 - Call from non-secure source.
430a92681d9SJay Buddhabhatti *
431de7ed953SPrasad Kummari * Return: Returns status, either success or error+reason.
432a92681d9SJay Buddhabhatti *
433a92681d9SJay Buddhabhatti */
pm_load_pdi(uint32_t src,uint32_t address_low,uint32_t address_high,uint32_t flag)434a92681d9SJay Buddhabhatti enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
435a92681d9SJay Buddhabhatti uint32_t address_high, uint32_t flag)
436a92681d9SJay Buddhabhatti {
437a92681d9SJay Buddhabhatti uint32_t payload[PAYLOAD_ARG_CNT];
438a92681d9SJay Buddhabhatti
439a92681d9SJay Buddhabhatti /* Send request to the PMU */
440a92681d9SJay Buddhabhatti PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, flag, PM_LOAD_PDI, src,
441a92681d9SJay Buddhabhatti address_high, address_low);
442a92681d9SJay Buddhabhatti return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
443a92681d9SJay Buddhabhatti }
444a92681d9SJay Buddhabhatti
445a92681d9SJay Buddhabhatti /**
446a92681d9SJay Buddhabhatti * pm_register_notifier() - PM call to register a subsystem to be notified
447de7ed953SPrasad Kummari * about the device event.
448de7ed953SPrasad Kummari * @device_id: Device ID for the Node to which the event is related.
449de7ed953SPrasad Kummari * @event: Event in question.
450de7ed953SPrasad Kummari * @wake: Wake subsystem upon capturing the event if value 1.
451de7ed953SPrasad Kummari * @enable: Enable the registration for value 1, disable for value 0.
452de7ed953SPrasad Kummari * @flag: 0 - Call from secure source.
453de7ed953SPrasad Kummari * 1 - Call from non-secure source.
454a92681d9SJay Buddhabhatti *
455de7ed953SPrasad Kummari * Return: Returns status, either success or error+reason.
456de7ed953SPrasad Kummari *
457a92681d9SJay Buddhabhatti */
pm_register_notifier(uint32_t device_id,uint32_t event,uint32_t wake,uint32_t enable,uint32_t flag)458a92681d9SJay Buddhabhatti enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
459a92681d9SJay Buddhabhatti uint32_t wake, uint32_t enable,
460a92681d9SJay Buddhabhatti uint32_t flag)
461a92681d9SJay Buddhabhatti {
462a92681d9SJay Buddhabhatti uint32_t payload[PAYLOAD_ARG_CNT];
463a92681d9SJay Buddhabhatti
464a92681d9SJay Buddhabhatti /* Send request to the PMC */
465a92681d9SJay Buddhabhatti PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REGISTER_NOTIFIER,
466a92681d9SJay Buddhabhatti device_id, event, wake, enable);
467a92681d9SJay Buddhabhatti
468a92681d9SJay Buddhabhatti return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
469a92681d9SJay Buddhabhatti }
4700563601fSAkshay Belsare
4710563601fSAkshay Belsare /**
472de7ed953SPrasad Kummari * pm_get_chipid() - Read silicon ID registers.
4730563601fSAkshay Belsare * @value: Buffer for two 32bit words.
4740563601fSAkshay Belsare *
475de7ed953SPrasad Kummari * Return: Returns status, either success or error+reason and,
4760563601fSAkshay Belsare * optionally, @value.
4770563601fSAkshay Belsare */
pm_get_chipid(uint32_t * value)4780563601fSAkshay Belsare enum pm_ret_status pm_get_chipid(uint32_t *value)
4790563601fSAkshay Belsare {
4800563601fSAkshay Belsare uint32_t payload[PAYLOAD_ARG_CNT];
4810563601fSAkshay Belsare
4824fd510e0SRonak Jain PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, SECURE, PM_GET_CHIPID);
4830563601fSAkshay Belsare
4840563601fSAkshay Belsare return pm_ipi_send_sync(primary_proc, payload, value, 2);
4850563601fSAkshay Belsare }
486