blob: 900af8889c6d1c5b8f5481de69a77f01bf480e98 [file] [log] [blame]
Tejas Patel9d09ff92019-01-08 01:46:35 -08001/*
Tanmay Shahff34daa2021-08-09 11:00:41 -07002 * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
Jay Buddhabhatti26e138a2022-12-21 23:03:35 -08003 * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
Tejas Patel9d09ff92019-01-08 01:46:35 -08004 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8/*
9 * Versal system level PM-API functions and communication with PMC via
10 * IPI interrupts
11 */
12
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080013#include <drivers/arm/gic_common.h>
14#include <lib/mmio.h>
15#include <lib/utils.h>
16#include <plat/common/platform.h>
17#include <platform_def.h>
18#include <pm_api_sys.h>
19#include <pm_client.h>
Tejas Patel9d09ff92019-01-08 01:46:35 -080020#include <pm_common.h>
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080021#include <pm_defs.h>
Tejas Patel9d09ff92019-01-08 01:46:35 -080022#include <pm_ipi.h>
Shubhrajyoti Dattaabf61222021-03-17 23:01:17 +053023#include "pm_svc_main.h"
Tejas Patel9d09ff92019-01-08 01:46:35 -080024
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080025#define NUM_GICD_ISENABLER ((IRQ_MAX >> 5U) + 1U)
26
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -080027/* default shutdown/reboot scope is system(2) */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +053028static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -080029
30/**
31 * pm_get_shutdown_scope() - Get the currently set shutdown scope
32 *
33 * @return Shutdown scope value
34 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +053035uint32_t pm_get_shutdown_scope(void)
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -080036{
37 return pm_shutdown_scope;
38}
39
Tejas Patel9d09ff92019-01-08 01:46:35 -080040/* PM API functions */
41
42/**
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080043 * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as
44 * wake sources in the XilPM.
45 * @node_id: Node id of processor
46 */
47void pm_client_set_wakeup_sources(uint32_t node_id)
48{
49 uint32_t reg_num, device_id;
50 uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = {0U};
Jay Buddhabhattif2f84b32023-02-09 22:56:53 -080051 uint32_t isenabler1 = PLAT_GICD_BASE_VALUE + GICD_ISENABLER + 4U;
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080052
53 zeromem(&pm_wakeup_nodes_set, (u_register_t)sizeof(pm_wakeup_nodes_set));
54
55 for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
56 uint32_t base_irq = reg_num << ISENABLER_SHIFT;
57 uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
58
59 if (reg == 0U) {
60 continue;
61 }
62
63 while (reg != 0U) {
64 enum pm_device_node_idx node_idx;
65 uint32_t idx, irq, lowest_set = reg & (-reg);
66 enum pm_ret_status ret;
67
Jay Buddhabhattif2f84b32023-02-09 22:56:53 -080068 idx = (uint32_t)__builtin_ctz(lowest_set);
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080069 irq = base_irq + idx;
70
71 if (irq > IRQ_MAX) {
72 break;
73 }
74
75 node_idx = irq_to_pm_node_idx(irq);
76 reg &= ~lowest_set;
77
Jay Buddhabhattiac323fd2023-02-03 01:16:44 -080078 if (node_idx > XPM_NODEIDX_DEV_MIN) {
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080079 if (pm_wakeup_nodes_set[node_idx] == 0U) {
80 /* Get device ID from node index */
Jay Buddhabhattif2f84b32023-02-09 22:56:53 -080081 device_id = PERIPH_DEVID((uint32_t)node_idx);
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080082 ret = pm_set_wakeup_source(node_id,
83 device_id, 1U,
84 SECURE_FLAG);
85 pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ?
86 1U : 0U;
87 }
88 }
89 }
90 }
91}
92
93/**
Tanmay Shahff34daa2021-08-09 11:00:41 -070094 * pm_handle_eemi_call() - PM call for processor to send eemi payload
Tejas Patel18072da2021-02-25 20:16:56 -080095 * @flag 0 - Call from secure source
96 * 1 - Call from non-secure source
Tanmay Shahff34daa2021-08-09 11:00:41 -070097 * @x0 to x5 Arguments received per SMC64 standard
98 * @result Payload received from firmware
Tejas Patel9d09ff92019-01-08 01:46:35 -080099 *
Tanmay Shahff34daa2021-08-09 11:00:41 -0700100 * @return PM_RET_SUCCESS on success or error code
Tejas Patel9d09ff92019-01-08 01:46:35 -0800101 */
Tanmay Shahff34daa2021-08-09 11:00:41 -0700102enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
103 uint32_t x2, uint32_t x3, uint32_t x4,
104 uint32_t x5, uint64_t *result)
Tejas Patel9d09ff92019-01-08 01:46:35 -0800105{
Tanmay Shahff34daa2021-08-09 11:00:41 -0700106 uint32_t payload[PAYLOAD_ARG_CNT] = {0};
107 uint32_t module_id;
Tejas Patel9d09ff92019-01-08 01:46:35 -0800108
Venkatesh Yadav Abbarapua0657d92022-07-20 09:03:22 +0530109 module_id = (x0 & MODULE_ID_MASK) >> 8U;
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800110
Tanmay Shahff34daa2021-08-09 11:00:41 -0700111 //default module id is for LIBPM
Venkatesh Yadav Abbarapuab167132022-05-25 15:18:24 +0530112 if (module_id == 0) {
Tanmay Shahff34daa2021-08-09 11:00:41 -0700113 module_id = LIBPM_MODULE_ID;
Venkatesh Yadav Abbarapuab167132022-05-25 15:18:24 +0530114 }
Ravi Patel476b5b12019-08-12 03:10:10 -0700115
Tanmay Shahff34daa2021-08-09 11:00:41 -0700116 PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
117 return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
Ravi Patel476b5b12019-08-12 03:10:10 -0700118}
119
120/**
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800121 * pm_self_suspend() - PM call for processor to suspend itself
122 * @nid Node id of the processor or subsystem
123 * @latency Requested maximum wakeup latency (not supported)
124 * @state Requested state
125 * @address Resume address
Tejas Patel18072da2021-02-25 20:16:56 -0800126 * @flag 0 - Call from secure source
127 * 1 - Call from non-secure source
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800128 *
129 * This is a blocking call, it will return only once PMU has responded.
130 * On a wakeup, resume address will be automatically set by PMU.
131 *
132 * @return Returns status, either success or error+reason
133 */
134enum pm_ret_status pm_self_suspend(uint32_t nid,
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530135 uint32_t latency,
136 uint32_t state,
Tejas Patel18072da2021-02-25 20:16:56 -0800137 uintptr_t address, uint32_t flag)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800138{
139 uint32_t payload[PAYLOAD_ARG_CNT];
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530140 uint32_t cpuid = plat_my_core_pos();
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800141 const struct pm_proc *proc = pm_get_proc(cpuid);
142
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700143 if (proc == NULL) {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800144 WARN("Failed to get proc %d\n", cpuid);
145 return PM_RET_ERROR_INTERNAL;
146 }
147
148 /*
149 * Do client specific suspend operations
150 * (e.g. set powerdown request bit)
151 */
152 pm_client_suspend(proc, state);
153
154 /* Send request to the PLM */
Tejas Patel18072da2021-02-25 20:16:56 -0800155 PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, flag, PM_SELF_SUSPEND,
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800156 proc->node_id, latency, state, address,
157 (address >> 32));
158 return pm_ipi_send_sync(proc, payload, NULL, 0);
159}
160
161/**
162 * pm_abort_suspend() - PM call to announce that a prior suspend request
163 * is to be aborted.
164 * @reason Reason for the abort
Tejas Patel18072da2021-02-25 20:16:56 -0800165 * @flag 0 - Call from secure source
166 * 1 - Call from non-secure source
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800167 *
168 * Calling PU expects the PMU to abort the initiated suspend procedure.
169 * This is a non-blocking call without any acknowledge.
170 *
171 * @return Returns status, either success or error+reason
172 */
Tejas Patel18072da2021-02-25 20:16:56 -0800173enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800174{
175 uint32_t payload[PAYLOAD_ARG_CNT];
176
177 /*
178 * Do client specific abort suspend operations
179 * (e.g. enable interrupts and clear powerdown request bit)
180 */
181 pm_client_abort_suspend();
182
183 /* Send request to the PLM */
Tejas Patel18072da2021-02-25 20:16:56 -0800184 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_ABORT_SUSPEND,
185 reason, primary_proc->node_id);
Abhyuday Godhasara7ae761b2021-06-24 05:50:44 -0700186 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800187}
188
189/**
190 * pm_req_suspend() - PM call to request for another PU or subsystem to
191 * be suspended gracefully.
192 * @target Node id of the targeted PU or subsystem
193 * @ack Flag to specify whether acknowledge is requested
194 * @latency Requested wakeup latency (not supported)
195 * @state Requested state (not supported)
Tejas Patel18072da2021-02-25 20:16:56 -0800196 * @flag 0 - Call from secure source
197 * 1 - Call from non-secure source
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800198 *
199 * @return Returns status, either success or error+reason
200 */
201enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530202 uint32_t latency, uint32_t state,
Tejas Patel18072da2021-02-25 20:16:56 -0800203 uint32_t flag)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800204{
205 uint32_t payload[PAYLOAD_ARG_CNT];
206
207 /* Send request to the PMU */
Tejas Patel18072da2021-02-25 20:16:56 -0800208 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_REQ_SUSPEND, target,
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800209 latency, state);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700210 if (ack == IPI_BLOCKING) {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800211 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700212 } else {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800213 return pm_ipi_send(primary_proc, payload);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700214 }
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800215}
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800216
217/**
Tejas Patel49cd8712019-01-23 14:18:51 +0530218 * pm_req_wakeup() - PM call for processor to wake up selected processor
219 * or subsystem
220 * @target Device ID of the processor or subsystem to wake up
221 * @set_address Resume address presence indicator
222 * 1 - resume address specified, 0 - otherwise
223 * @address Resume address
224 * @ack Flag to specify whether acknowledge requested
Tejas Patel18072da2021-02-25 20:16:56 -0800225 * @flag 0 - Call from secure source
226 * 1 - Call from non-secure source
Tejas Patel49cd8712019-01-23 14:18:51 +0530227 *
228 * This API function is either used to power up another APU core for SMP
229 * (by PSCI) or to power up an entirely different PU or subsystem, such
230 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
231 * automatically set by PMC.
232 *
233 * @return Returns status, either success or error+reason
234 */
235enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
Tejas Patel18072da2021-02-25 20:16:56 -0800236 uintptr_t address, uint8_t ack, uint32_t flag)
Tejas Patel49cd8712019-01-23 14:18:51 +0530237{
238 uint32_t payload[PAYLOAD_ARG_CNT];
239
240 /* Send request to the PMC to perform the wake of the PU */
Tejas Patel18072da2021-02-25 20:16:56 -0800241 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQ_WAKEUP, target,
Tejas Patel49cd8712019-01-23 14:18:51 +0530242 set_address, address, ack);
243
244 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
245}
246
247/**
Rajan Vaja649e9242019-03-04 11:09:40 +0530248 * pm_get_callbackdata() - Read from IPI response buffer
249 * @data - array of PAYLOAD_ARG_CNT elements
Tejas Patel18072da2021-02-25 20:16:56 -0800250 * @flag - 0 - Call from secure source
251 * 1 - Call from non-secure source
Tanmay Shahfdae9e82022-08-26 15:06:00 -0700252 * @ack - 0 - Do not ack IPI after reading payload
253 * 1 - Ack IPI after reading payload
Rajan Vaja649e9242019-03-04 11:09:40 +0530254 *
255 * Read value from ipi buffer response buffer.
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530256 * @return Returns status, either success or error
Rajan Vaja649e9242019-03-04 11:09:40 +0530257 */
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530258enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
Rajan Vaja649e9242019-03-04 11:09:40 +0530259{
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530260 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vaja649e9242019-03-04 11:09:40 +0530261 /* Return if interrupt is not from PMU */
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700262 if (pm_ipi_irq_status(primary_proc) == 0) {
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530263 return ret;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700264 }
Rajan Vaja649e9242019-03-04 11:09:40 +0530265
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530266 ret = pm_ipi_buff_read_callb(data, count);
Tanmay Shahfdae9e82022-08-26 15:06:00 -0700267
268 if (ack != 0U) {
269 pm_ipi_irq_clear(primary_proc);
270 }
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530271
272 return ret;
Rajan Vaja649e9242019-03-04 11:09:40 +0530273}
274
275/**
Tanmay Shahff34daa2021-08-09 11:00:41 -0700276 * pm_pll_set_param() - Set PLL parameter
Tejas Patel1f56fb12019-01-08 01:46:40 -0800277 *
Tanmay Shahff34daa2021-08-09 11:00:41 -0700278 * This API is deprecated and maintained here for backward compatibility.
279 * New use of this API should be avoided for versal platform.
280 * This API and its use cases will be removed for versal platform.
Tejas Patel84275bf2020-09-01 04:43:53 -0700281 *
Tejas Patel023116d2019-01-08 01:46:41 -0800282 * @clk_id PLL clock ID
283 * @param PLL parameter ID
284 * @value Value to set for PLL parameter
Tejas Patel18072da2021-02-25 20:16:56 -0800285 * @flag 0 - Call from secure source
286 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800287 *
288 * @return Returns status, either success or error+reason
289 */
290enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
Tejas Patel18072da2021-02-25 20:16:56 -0800291 uint32_t value, uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -0800292{
293 uint32_t payload[PAYLOAD_ARG_CNT];
294
295 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800296 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
297 clk_id, param, value);
Tejas Patel023116d2019-01-08 01:46:41 -0800298
299 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
300}
301
302/**
303 * pm_pll_get_param() - Get PLL parameter value
Tanmay Shahff34daa2021-08-09 11:00:41 -0700304 *
305 * This API is deprecated and maintained here for backward compatibility.
306 * New use of this API should be avoided for versal platform.
307 * This API and its use cases will be removed for versal platform.
308 *
Tejas Patel023116d2019-01-08 01:46:41 -0800309 * @clk_id PLL clock ID
310 * @param PLL parameter ID
311 * @value: Buffer to store PLL parameter value
Tejas Patel18072da2021-02-25 20:16:56 -0800312 * @flag 0 - Call from secure source
313 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800314 *
315 * @return Returns status, either success or error+reason
316 */
317enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
Tejas Patel18072da2021-02-25 20:16:56 -0800318 uint32_t *value, uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -0800319{
320 uint32_t payload[PAYLOAD_ARG_CNT];
321
322 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800323 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
324 clk_id, param);
Tejas Patel023116d2019-01-08 01:46:41 -0800325
326 return pm_ipi_send_sync(primary_proc, payload, value, 1);
327}
328
329/**
330 * pm_pll_set_mode() - Set PLL mode
Tanmay Shahff34daa2021-08-09 11:00:41 -0700331 *
332 * This API is deprecated and maintained here for backward compatibility.
333 * New use of this API should be avoided for versal platform.
334 * This API and its use cases will be removed for versal platform.
335 *
Tejas Patel023116d2019-01-08 01:46:41 -0800336 * @clk_id PLL clock ID
337 * @mode PLL mode
Tejas Patel18072da2021-02-25 20:16:56 -0800338 * @flag 0 - Call from secure source
339 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800340 *
341 * @return Returns status, either success or error+reason
342 */
Tejas Patel18072da2021-02-25 20:16:56 -0800343enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
344 uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -0800345{
346 uint32_t payload[PAYLOAD_ARG_CNT];
347
348 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800349 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
350 clk_id, mode);
Tejas Patel023116d2019-01-08 01:46:41 -0800351
352 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
353}
354
355/**
356 * pm_pll_get_mode() - Get PLL mode
Tanmay Shahff34daa2021-08-09 11:00:41 -0700357 *
358 * This API is deprecated and maintained here for backward compatibility.
359 * New use of this API should be avoided for versal platform.
360 * This API and its use cases will be removed for versal platform.
361 *
Tejas Patel023116d2019-01-08 01:46:41 -0800362 * @clk_id PLL clock ID
363 * @mode: Buffer to store PLL mode
Tejas Patel18072da2021-02-25 20:16:56 -0800364 * @flag 0 - Call from secure source
365 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800366 *
367 * @return Returns status, either success or error+reason
368 */
Tejas Patel18072da2021-02-25 20:16:56 -0800369enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
370 uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -0800371{
372 uint32_t payload[PAYLOAD_ARG_CNT];
373
374 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800375 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
376 clk_id);
Tejas Patel023116d2019-01-08 01:46:41 -0800377
378 return pm_ipi_send_sync(primary_proc, payload, mode, 1);
379}
Tejas Patel6b282252019-01-10 03:03:47 -0800380
381/**
382 * pm_force_powerdown() - PM call to request for another PU or subsystem to
383 * be powered down forcefully
384 * @target Device ID of the PU node to be forced powered down.
385 * @ack Flag to specify whether acknowledge is requested
Tejas Patel18072da2021-02-25 20:16:56 -0800386 * @flag 0 - Call from secure source
387 * 1 - Call from non-secure source
Tejas Patel6b282252019-01-10 03:03:47 -0800388 *
389 * @return Returns status, either success or error+reason
390 */
Tejas Patel18072da2021-02-25 20:16:56 -0800391enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
392 uint32_t flag)
Tejas Patel6b282252019-01-10 03:03:47 -0800393{
394 uint32_t payload[PAYLOAD_ARG_CNT];
395
396 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800397 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN,
398 target, ack);
Tejas Patel6b282252019-01-10 03:03:47 -0800399
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700400 if (ack == IPI_BLOCKING) {
Tejas Patel6b282252019-01-10 03:03:47 -0800401 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700402 } else {
Tejas Patel6b282252019-01-10 03:03:47 -0800403 return pm_ipi_send(primary_proc, payload);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700404 }
Tejas Patel6b282252019-01-10 03:03:47 -0800405}
406
407/**
408 * pm_system_shutdown() - PM call to request a system shutdown or restart
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -0800409 * @type Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
Tejas Patel6b282252019-01-10 03:03:47 -0800410 * @subtype Scope: 0=APU-subsystem, 1=PS, 2=system
Tejas Patel18072da2021-02-25 20:16:56 -0800411 * @flag 0 - Call from secure source
412 * 1 - Call from non-secure source
Tejas Patel6b282252019-01-10 03:03:47 -0800413 *
414 * @return Returns status, either success or error+reason
415 */
Tejas Patel18072da2021-02-25 20:16:56 -0800416enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
417 uint32_t flag)
Tejas Patel6b282252019-01-10 03:03:47 -0800418{
419 uint32_t payload[PAYLOAD_ARG_CNT];
420
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -0800421 if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
422 /* Setting scope for subsequent PSCI reboot or shutdown */
423 pm_shutdown_scope = subtype;
424 return PM_RET_SUCCESS;
425 }
426
Tejas Patel6b282252019-01-10 03:03:47 -0800427 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800428 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SYSTEM_SHUTDOWN,
429 type, subtype);
Tejas Patel6b282252019-01-10 03:03:47 -0800430
431 return pm_ipi_send_non_blocking(primary_proc, payload);
432}
Tejas Patel9141f442019-01-10 03:03:48 -0800433
434/**
Tanmay Shahff34daa2021-08-09 11:00:41 -0700435 * pm_query_data() - PM API for querying firmware data
436 *
437 * This API is deprecated and maintained here for backward compatibility.
438 * New use of this API should be avoided for versal platform.
439 * This API and its use cases will be removed for versal platform.
440 *
441 * @qid The type of data to query
442 * @arg1 Argument 1 to requested query data call
443 * @arg2 Argument 2 to requested query data call
444 * @arg3 Argument 3 to requested query data call
445 * @data Returned output data
446 * @flag 0 - Call from secure source
447 * 1 - Call from non-secure source
448 *
449 * @retur - 0 if success else non-zero error code of type
450 * enum pm_ret_status
451 */
Tejas Patela3e34ad2019-02-01 17:25:19 +0530452enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
Tejas Patel18072da2021-02-25 20:16:56 -0800453 uint32_t arg3, uint32_t *data, uint32_t flag)
Tejas Patela3e34ad2019-02-01 17:25:19 +0530454{
Rajan Vaja030620d2020-11-23 04:13:54 -0800455 uint32_t ret;
Tanmay Shahff34daa2021-08-09 11:00:41 -0700456 uint32_t version[PAYLOAD_ARG_CNT] = {0};
Tejas Patela3e34ad2019-02-01 17:25:19 +0530457 uint32_t payload[PAYLOAD_ARG_CNT];
Rajan Vaja030620d2020-11-23 04:13:54 -0800458 uint32_t fw_api_version;
Tejas Patela3e34ad2019-02-01 17:25:19 +0530459
460 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800461 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
462 arg1, arg2, arg3);
Rajan Vaja030620d2020-11-23 04:13:54 -0800463
Jay Buddhabhattif2f84b32023-02-09 22:56:53 -0800464 ret = pm_feature_check((uint32_t)PM_QUERY_DATA, &version[0], flag);
Tanmay Shahff34daa2021-08-09 11:00:41 -0700465 if (ret == PM_RET_SUCCESS) {
Venkatesh Yadav Abbarapua0657d92022-07-20 09:03:22 +0530466 fw_api_version = version[0] & 0xFFFFU;
Tanmay Shahff34daa2021-08-09 11:00:41 -0700467 if ((fw_api_version == 2U) &&
468 ((qid == XPM_QID_CLOCK_GET_NAME) ||
469 (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
470 ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
471 if (ret == PM_RET_SUCCESS) {
472 ret = data[0];
473 data[0] = data[1];
474 data[1] = data[2];
475 data[2] = data[3];
476 }
Rajan Vaja030620d2020-11-23 04:13:54 -0800477 } else {
Tanmay Shahff34daa2021-08-09 11:00:41 -0700478 ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
Rajan Vaja030620d2020-11-23 04:13:54 -0800479 }
480 }
481 return ret;
Tejas Patela3e34ad2019-02-01 17:25:19 +0530482}
483/**
Tejas Patel9141f442019-01-10 03:03:48 -0800484 * pm_api_ioctl() - PM IOCTL API for device control and configs
Tanmay Shahff34daa2021-08-09 11:00:41 -0700485 *
486 * This API is deprecated and maintained here for backward compatibility.
487 * New use of this API should be avoided for versal platform.
488 * This API and its use cases will be removed for versal platform.
489 *
Tejas Patel9141f442019-01-10 03:03:48 -0800490 * @device_id Device ID
491 * @ioctl_id ID of the requested IOCTL
492 * @arg1 Argument 1 to requested IOCTL call
493 * @arg2 Argument 2 to requested IOCTL call
Venkatesh Yadav Abbarapu4b233392021-10-20 22:11:53 -0600494 * @arg3 Argument 3 to requested IOCTL call
Tejas Patel9141f442019-01-10 03:03:48 -0800495 * @value Returned output value
Tejas Patel18072da2021-02-25 20:16:56 -0800496 * @flag 0 - Call from secure source
497 * 1 - Call from non-secure source
Tejas Patel9141f442019-01-10 03:03:48 -0800498 *
499 * This function calls IOCTL to firmware for device control and configuration.
500 *
Tanmay Shahff34daa2021-08-09 11:00:41 -0700501 * @return Returns status, either 0 on success or non-zero error code
502 * of type enum pm_ret_status
Tejas Patel9141f442019-01-10 03:03:48 -0800503 */
504enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
Venkatesh Yadav Abbarapu4b233392021-10-20 22:11:53 -0600505 uint32_t arg1, uint32_t arg2, uint32_t arg3,
506 uint32_t *value, uint32_t flag)
Tejas Patel9141f442019-01-10 03:03:48 -0800507{
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700508 enum pm_ret_status ret;
Tejas Patel9141f442019-01-10 03:03:48 -0800509
510 switch (ioctl_id) {
511 case IOCTL_SET_PLL_FRAC_MODE:
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700512 ret = pm_pll_set_mode(arg1, arg2, flag);
513 break;
Tejas Patel9141f442019-01-10 03:03:48 -0800514 case IOCTL_GET_PLL_FRAC_MODE:
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700515 ret = pm_pll_get_mode(arg1, value, flag);
516 break;
Tejas Patel9141f442019-01-10 03:03:48 -0800517 case IOCTL_SET_PLL_FRAC_DATA:
Jay Buddhabhattif2f84b32023-02-09 22:56:53 -0800518 ret = pm_pll_set_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, arg2, flag);
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700519 break;
Tejas Patel9141f442019-01-10 03:03:48 -0800520 case IOCTL_GET_PLL_FRAC_DATA:
Jay Buddhabhattif2f84b32023-02-09 22:56:53 -0800521 ret = pm_pll_get_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, value, flag);
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700522 break;
Venkatesh Yadav Abbarapuaa4898a2021-03-31 03:07:40 -0600523 case IOCTL_SET_SGI:
524 /* Get the sgi number */
Venkatesh Yadav Abbarapuc8bbedc2021-04-19 07:49:57 -0600525 ret = pm_register_sgi(arg1, arg2);
526 if (ret != 0) {
Venkatesh Yadav Abbarapuaa4898a2021-03-31 03:07:40 -0600527 return PM_RET_ERROR_ARGS;
528 }
Michal Simek89e3c292022-08-04 14:08:32 +0200529 ret = PM_RET_SUCCESS;
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700530 break;
Tejas Patel9141f442019-01-10 03:03:48 -0800531 default:
Tanmay Shahff34daa2021-08-09 11:00:41 -0700532 return PM_RET_ERROR_NOTSUPPORTED;
Tejas Patel9141f442019-01-10 03:03:48 -0800533 }
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700534
535 return ret;
Tejas Patel9141f442019-01-10 03:03:48 -0800536}
Tejas Pateldb812052019-01-23 14:18:53 +0530537
538/**
539 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
540 * @target Device id of the targeted PU or subsystem
541 * @wkup_node Device id of the wakeup peripheral
542 * @enable Enable or disable the specified peripheral as wake source
Tejas Patel18072da2021-02-25 20:16:56 -0800543 * @flag 0 - Call from secure source
544 * 1 - Call from non-secure source
Tejas Pateldb812052019-01-23 14:18:53 +0530545 *
546 * @return Returns status, either success or error+reason
547 */
548enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
Tejas Patel18072da2021-02-25 20:16:56 -0800549 uint8_t enable, uint32_t flag)
Tejas Pateldb812052019-01-23 14:18:53 +0530550{
551 uint32_t payload[PAYLOAD_ARG_CNT];
552
Tejas Patel18072da2021-02-25 20:16:56 -0800553 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE,
554 target, wkup_device, enable);
Abhyuday Godhasara7ae761b2021-06-24 05:50:44 -0700555 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Tejas Pateldb812052019-01-23 14:18:53 +0530556}
Ravi Patel22b0b492019-03-06 12:34:46 +0530557
558/**
559 * pm_feature_check() - Returns the supported API version if supported
560 * @api_id API ID to check
Tejas Patel18072da2021-02-25 20:16:56 -0800561 * @flag 0 - Call from secure source
562 * 1 - Call from non-secure source
Ronak Jain70d1c582022-02-04 00:42:55 -0800563 * @ret_payload pointer to array of PAYLOAD_ARG_CNT number of
564 * words Returned supported API version and bitmasks
565 * for IOCTL and QUERY ID
Ravi Patel22b0b492019-03-06 12:34:46 +0530566 *
567 * @return Returns status, either success or error+reason
568 */
Ronak Jain70d1c582022-02-04 00:42:55 -0800569enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
Tejas Patel18072da2021-02-25 20:16:56 -0800570 uint32_t flag)
Ravi Patel22b0b492019-03-06 12:34:46 +0530571{
Ronak Jain70d1c582022-02-04 00:42:55 -0800572 uint32_t payload[PAYLOAD_ARG_CNT];
Tanmay Shahff34daa2021-08-09 11:00:41 -0700573 uint32_t module_id;
574
Prasad Kummarie0783112023-04-26 11:02:07 +0530575 /* Return version of API which are implemented in TF-A only */
Ravi Patel22b0b492019-03-06 12:34:46 +0530576 switch (api_id) {
577 case PM_GET_CALLBACK_DATA:
578 case PM_GET_TRUSTZONE_VERSION:
Ronak Jain70d1c582022-02-04 00:42:55 -0800579 ret_payload[0] = PM_API_VERSION_2;
580 return PM_RET_SUCCESS;
Tanmay Shah5e3af332022-08-26 15:13:48 -0700581 case TF_A_PM_REGISTER_SGI:
Ronak Jain70d1c582022-02-04 00:42:55 -0800582 ret_payload[0] = PM_API_BASE_VERSION;
Tanmay Shahff34daa2021-08-09 11:00:41 -0700583 return PM_RET_SUCCESS;
Ravi Patel22b0b492019-03-06 12:34:46 +0530584 default:
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700585 break;
586 }
587
Venkatesh Yadav Abbarapua0657d92022-07-20 09:03:22 +0530588 module_id = (api_id & MODULE_ID_MASK) >> 8U;
Ravi Patel22b0b492019-03-06 12:34:46 +0530589
Ronak Jain70d1c582022-02-04 00:42:55 -0800590 /*
591 * feature check should be done only for LIBPM module
592 * If module_id is 0, then we consider it LIBPM module as default id
593 */
594 if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) {
595 return PM_RET_SUCCESS;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700596 }
Ravi Patel22b0b492019-03-06 12:34:46 +0530597
Ronak Jain70d1c582022-02-04 00:42:55 -0800598 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
599 PM_FEATURE_CHECK, api_id);
600 return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
Ravi Patel22b0b492019-03-06 12:34:46 +0530601}
Jolly Shahed05a712019-03-22 05:33:39 +0530602
603/**
604 * pm_load_pdi() - Load the PDI
605 *
606 * This function provides support to load PDI from linux
607 *
608 * src: Source device of pdi(DDR, OCM, SD etc)
609 * address_low: lower 32-bit Linear memory space address
610 * address_high: higher 32-bit Linear memory space address
Tejas Patel18072da2021-02-25 20:16:56 -0800611 * @flag 0 - Call from secure source
612 * 1 - Call from non-secure source
Jolly Shahed05a712019-03-22 05:33:39 +0530613 *
614 * @return Returns status, either success or error+reason
615 */
Tejas Patel18072da2021-02-25 20:16:56 -0800616enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
617 uint32_t address_high, uint32_t flag)
Jolly Shahed05a712019-03-22 05:33:39 +0530618{
619 uint32_t payload[PAYLOAD_ARG_CNT];
620
621 /* Send request to the PMU */
Tejas Patel18072da2021-02-25 20:16:56 -0800622 PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, flag, PM_LOAD_PDI, src,
Jolly Shahed05a712019-03-22 05:33:39 +0530623 address_high, address_low);
624 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
625}
Saeed Nowshadi2294b422019-06-03 10:22:35 -0700626
627/**
Tejas Patel42015552020-11-25 01:56:57 -0800628 * pm_register_notifier() - PM call to register a subsystem to be notified
629 * about the device event
630 * @device_id Device ID for the Node to which the event is related
631 * @event Event in question
632 * @wake Wake subsystem upon capturing the event if value 1
633 * @enable Enable the registration for value 1, disable for value 0
Tejas Patel18072da2021-02-25 20:16:56 -0800634 * @flag 0 - Call from secure source
635 * 1 - Call from non-secure source
Tejas Patel42015552020-11-25 01:56:57 -0800636 *
637 * @return Returns status, either success or error+reason
638 */
639enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
Tejas Patel18072da2021-02-25 20:16:56 -0800640 uint32_t wake, uint32_t enable,
641 uint32_t flag)
Tejas Patel42015552020-11-25 01:56:57 -0800642{
643 uint32_t payload[PAYLOAD_ARG_CNT];
644
645 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800646 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REGISTER_NOTIFIER,
Tejas Patel42015552020-11-25 01:56:57 -0800647 device_id, event, wake, enable);
648
649 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
650}