blob: 06c70bcd1304f88b41ecbd57621adde86a4bba0e [file] [log] [blame]
Tejas Patel9d09ff92019-01-08 01:46:35 -08001/*
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -07002 * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
Tejas Patel9d09ff92019-01-08 01:46:35 -08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7/*
8 * Versal system level PM-API functions and communication with PMC via
9 * IPI interrupts
10 */
11
12#include <pm_common.h>
13#include <pm_ipi.h>
Tejas Patelfe0e10a2019-12-08 23:29:44 -080014#include <plat/common/platform.h>
Tejas Patel9d09ff92019-01-08 01:46:35 -080015#include "pm_api_sys.h"
16#include "pm_client.h"
Rajan Vaja030620d2020-11-23 04:13:54 -080017#include "pm_defs.h"
Shubhrajyoti Dattaabf61222021-03-17 23:01:17 +053018#include "pm_svc_main.h"
Venkatesh Yadav Abbarapuaa4898a2021-03-31 03:07:40 -060019#include "../drivers/arm/gic/v3/gicv3_private.h"
Tejas Patel9d09ff92019-01-08 01:46:35 -080020
21/*********************************************************************
22 * Target module IDs macros
23 ********************************************************************/
24#define LIBPM_MODULE_ID 0x2
25#define LOADER_MODULE_ID 0x7
26
Venkatesh Yadav Abbarapuaa4898a2021-03-31 03:07:40 -060027#define MODE 0x80000000
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -080028/* default shutdown/reboot scope is system(2) */
29static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
30
31/**
32 * pm_get_shutdown_scope() - Get the currently set shutdown scope
33 *
34 * @return Shutdown scope value
35 */
36unsigned int pm_get_shutdown_scope(void)
37{
38 return pm_shutdown_scope;
39}
40
Tejas Patel9d09ff92019-01-08 01:46:35 -080041/**
42 * Assigning of argument values into array elements.
43 */
Tejas Patel18072da2021-02-25 20:16:56 -080044#define PM_PACK_PAYLOAD1(pl, mid, flag, arg0) { \
45 pl[0] = (uint32_t)((uint32_t)((arg0) & 0xFF) | (mid << 8) | ((flag) << 24)); \
Tejas Patel9d09ff92019-01-08 01:46:35 -080046}
47
Tejas Patel18072da2021-02-25 20:16:56 -080048#define PM_PACK_PAYLOAD2(pl, mid, flag, arg0, arg1) { \
49 pl[1] = (uint32_t)(arg1); \
50 PM_PACK_PAYLOAD1(pl, mid, flag, arg0); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080051}
52
Tejas Patel18072da2021-02-25 20:16:56 -080053#define PM_PACK_PAYLOAD3(pl, mid, flag, arg0, arg1, arg2) { \
54 pl[2] = (uint32_t)(arg2); \
55 PM_PACK_PAYLOAD2(pl, mid, flag, arg0, arg1); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080056}
57
Tejas Patel18072da2021-02-25 20:16:56 -080058#define PM_PACK_PAYLOAD4(pl, mid, flag, arg0, arg1, arg2, arg3) { \
59 pl[3] = (uint32_t)(arg3); \
60 PM_PACK_PAYLOAD3(pl, mid, flag, arg0, arg1, arg2); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080061}
62
Tejas Patel18072da2021-02-25 20:16:56 -080063#define PM_PACK_PAYLOAD5(pl, mid, flag, arg0, arg1, arg2, arg3, arg4) { \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080064 pl[4] = (uint32_t)(arg4); \
Tejas Patel18072da2021-02-25 20:16:56 -080065 PM_PACK_PAYLOAD4(pl, mid, flag, arg0, arg1, arg2, arg3); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080066}
67
Tejas Patel18072da2021-02-25 20:16:56 -080068#define PM_PACK_PAYLOAD6(pl, mid, flag, arg0, arg1, arg2, arg3, arg4, arg5) { \
69 pl[5] = (uint32_t)(arg5); \
70 PM_PACK_PAYLOAD5(pl, mid, flag, arg0, arg1, arg2, arg3, arg4); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080071}
72
Tejas Patel9d09ff92019-01-08 01:46:35 -080073/* PM API functions */
74
75/**
76 * pm_get_api_version() - Get version number of PMC PM firmware
77 * @version Returns 32-bit version number of PMC Power Management Firmware
Tejas Patel18072da2021-02-25 20:16:56 -080078 * @flag 0 - Call from secure source
79 * 1 - Call from non-secure source
Tejas Patel9d09ff92019-01-08 01:46:35 -080080 *
81 * @return Returns status, either success or error+reason
82 */
Tejas Patel18072da2021-02-25 20:16:56 -080083enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag)
Tejas Patel9d09ff92019-01-08 01:46:35 -080084{
85 uint32_t payload[PAYLOAD_ARG_CNT];
86
87 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -080088 PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_API_VERSION);
Tejas Patel9d09ff92019-01-08 01:46:35 -080089 return pm_ipi_send_sync(primary_proc, payload, version, 1);
90}
Tejas Patelfe0e10a2019-12-08 23:29:44 -080091
92/**
Ravi Patel476b5b12019-08-12 03:10:10 -070093 * pm_init_finalize() - Call to notify PMC PM firmware that master has power
94 * management enabled and that it has finished its
95 * initialization
Tejas Patel18072da2021-02-25 20:16:56 -080096 * @flag 0 - Call from secure source
97 * 1 - Call from non-secure source
Ravi Patel476b5b12019-08-12 03:10:10 -070098 *
99 * @return Status returned by the PMU firmware
100 */
Tejas Patel18072da2021-02-25 20:16:56 -0800101enum pm_ret_status pm_init_finalize(uint32_t flag)
Ravi Patel476b5b12019-08-12 03:10:10 -0700102{
103 uint32_t payload[PAYLOAD_ARG_CNT];
104
105 /* Send request to the PMU */
Tejas Patel18072da2021-02-25 20:16:56 -0800106 PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_INIT_FINALIZE);
Ravi Patel476b5b12019-08-12 03:10:10 -0700107 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
108}
109
110/**
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800111 * pm_self_suspend() - PM call for processor to suspend itself
112 * @nid Node id of the processor or subsystem
113 * @latency Requested maximum wakeup latency (not supported)
114 * @state Requested state
115 * @address Resume address
Tejas Patel18072da2021-02-25 20:16:56 -0800116 * @flag 0 - Call from secure source
117 * 1 - Call from non-secure source
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800118 *
119 * This is a blocking call, it will return only once PMU has responded.
120 * On a wakeup, resume address will be automatically set by PMU.
121 *
122 * @return Returns status, either success or error+reason
123 */
124enum pm_ret_status pm_self_suspend(uint32_t nid,
125 unsigned int latency,
126 unsigned int state,
Tejas Patel18072da2021-02-25 20:16:56 -0800127 uintptr_t address, uint32_t flag)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800128{
129 uint32_t payload[PAYLOAD_ARG_CNT];
130 unsigned int cpuid = plat_my_core_pos();
131 const struct pm_proc *proc = pm_get_proc(cpuid);
132
133 if (!proc) {
134 WARN("Failed to get proc %d\n", cpuid);
135 return PM_RET_ERROR_INTERNAL;
136 }
137
138 /*
139 * Do client specific suspend operations
140 * (e.g. set powerdown request bit)
141 */
142 pm_client_suspend(proc, state);
143
144 /* Send request to the PLM */
Tejas Patel18072da2021-02-25 20:16:56 -0800145 PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, flag, PM_SELF_SUSPEND,
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800146 proc->node_id, latency, state, address,
147 (address >> 32));
148 return pm_ipi_send_sync(proc, payload, NULL, 0);
149}
150
151/**
152 * pm_abort_suspend() - PM call to announce that a prior suspend request
153 * is to be aborted.
154 * @reason Reason for the abort
Tejas Patel18072da2021-02-25 20:16:56 -0800155 * @flag 0 - Call from secure source
156 * 1 - Call from non-secure source
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800157 *
158 * Calling PU expects the PMU to abort the initiated suspend procedure.
159 * This is a non-blocking call without any acknowledge.
160 *
161 * @return Returns status, either success or error+reason
162 */
Tejas Patel18072da2021-02-25 20:16:56 -0800163enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800164{
165 uint32_t payload[PAYLOAD_ARG_CNT];
166
167 /*
168 * Do client specific abort suspend operations
169 * (e.g. enable interrupts and clear powerdown request bit)
170 */
171 pm_client_abort_suspend();
172
173 /* Send request to the PLM */
Tejas Patel18072da2021-02-25 20:16:56 -0800174 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_ABORT_SUSPEND,
175 reason, primary_proc->node_id);
Abhyuday Godhasara7ae761b2021-06-24 05:50:44 -0700176 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800177}
178
179/**
180 * pm_req_suspend() - PM call to request for another PU or subsystem to
181 * be suspended gracefully.
182 * @target Node id of the targeted PU or subsystem
183 * @ack Flag to specify whether acknowledge is requested
184 * @latency Requested wakeup latency (not supported)
185 * @state Requested state (not supported)
Tejas Patel18072da2021-02-25 20:16:56 -0800186 * @flag 0 - Call from secure source
187 * 1 - Call from non-secure source
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800188 *
189 * @return Returns status, either success or error+reason
190 */
191enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
Tejas Patel18072da2021-02-25 20:16:56 -0800192 unsigned int latency, unsigned int state,
193 uint32_t flag)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800194{
195 uint32_t payload[PAYLOAD_ARG_CNT];
196
197 /* Send request to the PMU */
Tejas Patel18072da2021-02-25 20:16:56 -0800198 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_REQ_SUSPEND, target,
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800199 latency, state);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700200 if (ack == IPI_BLOCKING) {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800201 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700202 } else {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800203 return pm_ipi_send(primary_proc, payload);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700204 }
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800205}
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800206
207/**
Tejas Patel49cd8712019-01-23 14:18:51 +0530208 * pm_req_wakeup() - PM call for processor to wake up selected processor
209 * or subsystem
210 * @target Device ID of the processor or subsystem to wake up
211 * @set_address Resume address presence indicator
212 * 1 - resume address specified, 0 - otherwise
213 * @address Resume address
214 * @ack Flag to specify whether acknowledge requested
Tejas Patel18072da2021-02-25 20:16:56 -0800215 * @flag 0 - Call from secure source
216 * 1 - Call from non-secure source
Tejas Patel49cd8712019-01-23 14:18:51 +0530217 *
218 * This API function is either used to power up another APU core for SMP
219 * (by PSCI) or to power up an entirely different PU or subsystem, such
220 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
221 * automatically set by PMC.
222 *
223 * @return Returns status, either success or error+reason
224 */
225enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
Tejas Patel18072da2021-02-25 20:16:56 -0800226 uintptr_t address, uint8_t ack, uint32_t flag)
Tejas Patel49cd8712019-01-23 14:18:51 +0530227{
228 uint32_t payload[PAYLOAD_ARG_CNT];
229
230 /* Send request to the PMC to perform the wake of the PU */
Tejas Patel18072da2021-02-25 20:16:56 -0800231 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQ_WAKEUP, target,
Tejas Patel49cd8712019-01-23 14:18:51 +0530232 set_address, address, ack);
233
234 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
235}
236
237/**
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800238 * pm_request_device() - Request a device
239 * @device_id Device ID
240 * @capabilities Requested capabilities for the device
241 * @qos Required Quality of Service
242 * @ack Flag to specify whether acknowledge requested
Tejas Patel18072da2021-02-25 20:16:56 -0800243 * @flag 0 - Call from secure source
244 * 1 - Call from non-secure source
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800245 *
246 * @return Returns status, either success or error+reason
247 */
248enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
Tejas Patel18072da2021-02-25 20:16:56 -0800249 uint32_t qos, uint32_t ack, uint32_t flag)
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800250{
251 uint32_t payload[PAYLOAD_ARG_CNT];
252
253 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800254 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQUEST_DEVICE,
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800255 device_id, capabilities, qos, ack);
256
257 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
258}
259
260/**
261 * pm_release_device() - Release a device
262 * @device_id Device ID
Tejas Patel18072da2021-02-25 20:16:56 -0800263 * @flag 0 - Call from secure source
264 * 1 - Call from non-secure source
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800265 *
266 * @return Returns status, either success or error+reason
267 */
Tejas Patel18072da2021-02-25 20:16:56 -0800268enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag)
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800269{
270 uint32_t payload[PAYLOAD_ARG_CNT];
271
272 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800273 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RELEASE_DEVICE,
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800274 device_id);
275
276 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
277}
278
279/**
280 * pm_set_requirement() - Set requirement for the device
281 * @device_id Device ID
282 * @capabilities Requested capabilities for the device
283 * @latency Requested maximum latency
284 * @qos Required Quality of Service
Tejas Patel18072da2021-02-25 20:16:56 -0800285 * @flag 0 - Call from secure source
286 * 1 - Call from non-secure source
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800287 *
288 * @return Returns status, either success or error+reason
289 */
290enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
Tejas Patel18072da2021-02-25 20:16:56 -0800291 uint32_t latency, uint32_t qos,
292 uint32_t flag)
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800293{
294 uint32_t payload[PAYLOAD_ARG_CNT];
295
296 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800297 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_SET_REQUIREMENT,
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800298 device_id, capabilities, latency, qos);
299
300 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
301}
302
303/**
304 * pm_get_device_status() - Get device's status
305 * @device_id Device ID
306 * @response Buffer to store device status response
Tejas Patel18072da2021-02-25 20:16:56 -0800307 * @flag 0 - Call from secure source
308 * 1 - Call from non-secure source
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800309 *
310 * @return Returns status, either success or error+reason
311 */
Tejas Patel18072da2021-02-25 20:16:56 -0800312enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
313 uint32_t flag)
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800314{
315 uint32_t payload[PAYLOAD_ARG_CNT];
316
317 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800318 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_GET_DEVICE_STATUS,
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800319 device_id);
320
321 return pm_ipi_send_sync(primary_proc, payload, response, 3);
322}
Tejas Patel87c4f3a2019-01-08 01:46:38 -0800323
324/**
325 * pm_reset_assert() - Assert/De-assert reset
326 * @reset Reset ID
327 * @assert Assert (1) or de-assert (0)
Tejas Patel18072da2021-02-25 20:16:56 -0800328 * @flag 0 - Call from secure source
329 * 1 - Call from non-secure source
Tejas Patel87c4f3a2019-01-08 01:46:38 -0800330 *
331 * @return Returns status, either success or error+reason
332 */
Tejas Patel18072da2021-02-25 20:16:56 -0800333enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag)
Tejas Patel87c4f3a2019-01-08 01:46:38 -0800334{
335 uint32_t payload[PAYLOAD_ARG_CNT];
336
337 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800338 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT, reset,
Tejas Patel87c4f3a2019-01-08 01:46:38 -0800339 assert);
340
341 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
342}
343
344/**
345 * pm_reset_get_status() - Get current status of a reset line
346 * @reset Reset ID
347 * @status Returns current status of selected reset ID
Tejas Patel18072da2021-02-25 20:16:56 -0800348 * @flag 0 - Call from secure source
349 * 1 - Call from non-secure source
Tejas Patel87c4f3a2019-01-08 01:46:38 -0800350 *
351 * @return Returns status, either success or error+reason
352 */
Tejas Patel18072da2021-02-25 20:16:56 -0800353enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
354 uint32_t flag)
Tejas Patel87c4f3a2019-01-08 01:46:38 -0800355{
356 uint32_t payload[PAYLOAD_ARG_CNT];
357
358 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800359 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT,
360 reset);
Tejas Patel87c4f3a2019-01-08 01:46:38 -0800361
362 return pm_ipi_send_sync(primary_proc, payload, status, 1);
363}
Tejas Patel20e92022019-01-08 01:46:39 -0800364
365/**
Rajan Vaja649e9242019-03-04 11:09:40 +0530366 * pm_get_callbackdata() - Read from IPI response buffer
367 * @data - array of PAYLOAD_ARG_CNT elements
Tejas Patel18072da2021-02-25 20:16:56 -0800368 * @flag - 0 - Call from secure source
369 * 1 - Call from non-secure source
Rajan Vaja649e9242019-03-04 11:09:40 +0530370 *
371 * Read value from ipi buffer response buffer.
372 */
Tejas Patel18072da2021-02-25 20:16:56 -0800373void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag)
Rajan Vaja649e9242019-03-04 11:09:40 +0530374{
375 /* Return if interrupt is not from PMU */
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700376 if (!pm_ipi_irq_status(primary_proc)) {
Rajan Vaja649e9242019-03-04 11:09:40 +0530377 return;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700378 }
Rajan Vaja649e9242019-03-04 11:09:40 +0530379
380 pm_ipi_buff_read_callb(data, count);
381 pm_ipi_irq_clear(primary_proc);
382}
383
384/**
Tejas Patel20e92022019-01-08 01:46:39 -0800385 * pm_pinctrl_request() - Request a pin
386 * @pin Pin ID
Tejas Patel18072da2021-02-25 20:16:56 -0800387 * @flag 0 - Call from secure source
388 * 1 - Call from non-secure source
Tejas Patel20e92022019-01-08 01:46:39 -0800389 *
390 * @return Returns status, either success or error+reason
391 */
Tejas Patel18072da2021-02-25 20:16:56 -0800392enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag)
Tejas Patel20e92022019-01-08 01:46:39 -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_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_REQUEST,
398 pin);
Tejas Patel20e92022019-01-08 01:46:39 -0800399
400 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
401}
402
403/**
404 * pm_pinctrl_release() - Release a pin
405 * @pin Pin ID
Tejas Patel18072da2021-02-25 20:16:56 -0800406 * @flag 0 - Call from secure source
407 * 1 - Call from non-secure source
Tejas Patel20e92022019-01-08 01:46:39 -0800408 *
409 * @return Returns status, either success or error+reason
410 */
Tejas Patel18072da2021-02-25 20:16:56 -0800411enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag)
Tejas Patel20e92022019-01-08 01:46:39 -0800412{
413 uint32_t payload[PAYLOAD_ARG_CNT];
414
415 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800416 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_RELEASE,
417 pin);
Tejas Patel20e92022019-01-08 01:46:39 -0800418
419 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
420}
421
422/**
423 * pm_pinctrl_set_function() - Set pin function
424 * @pin Pin ID
425 * @function Function ID
Tejas Patel18072da2021-02-25 20:16:56 -0800426 * @flag 0 - Call from secure source
427 * 1 - Call from non-secure source
Tejas Patel20e92022019-01-08 01:46:39 -0800428 *
429 * @return Returns status, either success or error+reason
430 */
Tejas Patel18072da2021-02-25 20:16:56 -0800431enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
432 uint32_t flag)
Tejas Patel20e92022019-01-08 01:46:39 -0800433{
434 uint32_t payload[PAYLOAD_ARG_CNT];
435
436 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800437 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
438 PM_PINCTRL_SET_FUNCTION, pin, function)
Tejas Patel20e92022019-01-08 01:46:39 -0800439
440 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
441}
442
443/**
444 * pm_pinctrl_get_function() - Get function set on the pin
445 * @pin Pin ID
446 * @function Function set on the pin
Tejas Patel18072da2021-02-25 20:16:56 -0800447 * @flag 0 - Call from secure source
448 * 1 - Call from non-secure source
Tejas Patel20e92022019-01-08 01:46:39 -0800449 *
450 * @return Returns status, either success or error+reason
451 */
Tejas Patel18072da2021-02-25 20:16:56 -0800452enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
453 uint32_t flag)
Tejas Patel20e92022019-01-08 01:46:39 -0800454{
455 uint32_t payload[PAYLOAD_ARG_CNT];
456
457 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800458 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
459 PM_PINCTRL_SET_FUNCTION, pin);
Tejas Patel20e92022019-01-08 01:46:39 -0800460
461 return pm_ipi_send_sync(primary_proc, payload, function, 1);
462}
463
464/**
465 * pm_pinctrl_set_pin_param() - Set configuration parameter for the pin
466 * @pin Pin ID
467 * @param Parameter ID
468 * @value Parameter value
Tejas Patel18072da2021-02-25 20:16:56 -0800469 * @flag 0 - Call from secure source
470 * 1 - Call from non-secure source
Tejas Patel20e92022019-01-08 01:46:39 -0800471 *
472 * @return Returns status, either success or error+reason
473 */
474enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
Tejas Patel18072da2021-02-25 20:16:56 -0800475 uint32_t value, uint32_t flag)
Tejas Patel20e92022019-01-08 01:46:39 -0800476{
477 uint32_t payload[PAYLOAD_ARG_CNT];
478
479 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800480 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag,
481 PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value);
Tejas Patel20e92022019-01-08 01:46:39 -0800482
483 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
484}
485
486/**
487 * pm_pinctrl_get_pin_param() - Get configuration parameter value for the pin
488 * @pin Pin ID
489 * @param Parameter ID
490 * @value Buffer to store parameter value
Tejas Patel18072da2021-02-25 20:16:56 -0800491 * @flag 0 - Call from secure source
492 * 1 - Call from non-secure source
Tejas Patel20e92022019-01-08 01:46:39 -0800493 *
494 * @return Returns status, either success or error+reason
495 */
496enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
Tejas Patel18072da2021-02-25 20:16:56 -0800497 uint32_t *value, uint32_t flag)
Tejas Patel20e92022019-01-08 01:46:39 -0800498{
499 uint32_t payload[PAYLOAD_ARG_CNT];
500
501 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800502 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
503 PM_PINCTRL_CONFIG_PARAM_GET, pin, param);
Tejas Patel20e92022019-01-08 01:46:39 -0800504
505 return pm_ipi_send_sync(primary_proc, payload, value, 1);
506}
Tejas Patel1f56fb12019-01-08 01:46:40 -0800507
508/**
509 * pm_clock_enable() - Enable the clock
510 * @clk_id Clock ID
Tejas Patel18072da2021-02-25 20:16:56 -0800511 * @flag 0 - Call from secure source
512 * 1 - Call from non-secure source
Tejas Patel1f56fb12019-01-08 01:46:40 -0800513 *
514 * @return Returns status, either success or error+reason
515 */
Tejas Patel18072da2021-02-25 20:16:56 -0800516enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag)
Tejas Patel1f56fb12019-01-08 01:46:40 -0800517{
518 uint32_t payload[PAYLOAD_ARG_CNT];
519
520 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800521 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_ENABLE,
522 clk_id);
Tejas Patel1f56fb12019-01-08 01:46:40 -0800523
524 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
525}
526
527/**
528 * pm_clock_disable() - Disable the clock
529 * @clk_id Clock ID
Tejas Patel18072da2021-02-25 20:16:56 -0800530 * @flag 0 - Call from secure source
531 * 1 - Call from non-secure source
Tejas Patel1f56fb12019-01-08 01:46:40 -0800532 *
533 * @return Returns status, either success or error+reason
534 */
Tejas Patel18072da2021-02-25 20:16:56 -0800535enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag)
Tejas Patel1f56fb12019-01-08 01:46:40 -0800536{
537 uint32_t payload[PAYLOAD_ARG_CNT];
538
539 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800540 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_DISABLE,
541 clk_id);
Tejas Patel1f56fb12019-01-08 01:46:40 -0800542
543 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
544}
545
546/**
547 * pm_clock_get_state() - Get clock status
548 * @clk_id Clock ID
549 * @state: Buffer to store clock status (1: Enabled, 0:Disabled)
Tejas Patel18072da2021-02-25 20:16:56 -0800550 * @flag 0 - Call from secure source
551 * 1 - Call from non-secure source
Tejas Patel1f56fb12019-01-08 01:46:40 -0800552 *
553 * @return Returns status, either success or error+reason
554 */
Tejas Patel18072da2021-02-25 20:16:56 -0800555enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
556 uint32_t flag)
Tejas Patel1f56fb12019-01-08 01:46:40 -0800557{
558 uint32_t payload[PAYLOAD_ARG_CNT];
559
560 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800561 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETSTATE,
562 clk_id);
Tejas Patel1f56fb12019-01-08 01:46:40 -0800563
564 return pm_ipi_send_sync(primary_proc, payload, state, 1);
565}
566
567/**
568 * pm_clock_set_divider() - Set divider for the clock
569 * @clk_id Clock ID
570 * @divider Divider value
Tejas Patel18072da2021-02-25 20:16:56 -0800571 * @flag 0 - Call from secure source
572 * 1 - Call from non-secure source
Tejas Patel1f56fb12019-01-08 01:46:40 -0800573 *
574 * @return Returns status, either success or error+reason
575 */
Tejas Patel18072da2021-02-25 20:16:56 -0800576enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
577 uint32_t flag)
Tejas Patel1f56fb12019-01-08 01:46:40 -0800578{
579 uint32_t payload[PAYLOAD_ARG_CNT];
580
581 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800582 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETDIVIDER,
583 clk_id, divider);
Tejas Patel1f56fb12019-01-08 01:46:40 -0800584
585 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
586}
587
588/**
589 * pm_clock_get_divider() - Get divider value for the clock
590 * @clk_id Clock ID
591 * @divider: Buffer to store clock divider value
Tejas Patel18072da2021-02-25 20:16:56 -0800592 * @flag 0 - Call from secure source
593 * 1 - Call from non-secure source
Tejas Patel1f56fb12019-01-08 01:46:40 -0800594 *
595 * @return Returns status, either success or error+reason
596 */
Tejas Patel18072da2021-02-25 20:16:56 -0800597enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
598 uint32_t flag)
Tejas Patel1f56fb12019-01-08 01:46:40 -0800599{
600 uint32_t payload[PAYLOAD_ARG_CNT];
601
602 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800603 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETDIVIDER,
604 clk_id);
Tejas Patel1f56fb12019-01-08 01:46:40 -0800605
606 return pm_ipi_send_sync(primary_proc, payload, divider, 1);
607}
608
609/**
610 * pm_clock_set_parent() - Set parent for the clock
611 * @clk_id Clock ID
612 * @parent Parent ID
Tejas Patel18072da2021-02-25 20:16:56 -0800613 * @flag 0 - Call from secure source
614 * 1 - Call from non-secure source
Tejas Patel1f56fb12019-01-08 01:46:40 -0800615 *
616 * @return Returns status, either success or error+reason
617 */
Tejas Patel18072da2021-02-25 20:16:56 -0800618enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
619 uint32_t flag)
Tejas Patel1f56fb12019-01-08 01:46:40 -0800620{
621 uint32_t payload[PAYLOAD_ARG_CNT];
622
623 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800624 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETPARENT,
625 clk_id, parent);
Tejas Patel1f56fb12019-01-08 01:46:40 -0800626
627 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
628}
629
630/**
631 * pm_clock_get_parent() - Get parent value for the clock
632 * @clk_id Clock ID
633 * @parent: Buffer to store clock parent value
Tejas Patel18072da2021-02-25 20:16:56 -0800634 * @flag 0 - Call from secure source
635 * 1 - Call from non-secure source
Tejas Patel1f56fb12019-01-08 01:46:40 -0800636 *
637 * @return Returns status, either success or error+reason
638 */
Tejas Patel18072da2021-02-25 20:16:56 -0800639enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
640 uint32_t flag)
Tejas Patel1f56fb12019-01-08 01:46:40 -0800641{
642 uint32_t payload[PAYLOAD_ARG_CNT];
643
644 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800645 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETPARENT,
646 clk_id);
Tejas Patel1f56fb12019-01-08 01:46:40 -0800647
648 return pm_ipi_send_sync(primary_proc, payload, parent, 1);
649}
Tejas Patel84275bf2020-09-01 04:43:53 -0700650/**
651 * pm_clock_get_rate() - Get the rate value for the clock
652 * @clk_id Clock ID
653 * @rate: Buffer to store clock rate value
Tejas Patel18072da2021-02-25 20:16:56 -0800654 * @flag 0 - Call from secure source
655 * 1 - Call from non-secure source
Tejas Patel84275bf2020-09-01 04:43:53 -0700656 *
657 * @return Returns status, either success or error+reason
658 */
Tejas Patel18072da2021-02-25 20:16:56 -0800659enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
660 uint32_t flag)
Tejas Patel84275bf2020-09-01 04:43:53 -0700661{
662 uint32_t payload[PAYLOAD_ARG_CNT];
663
664 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800665 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETRATE,
666 clk_id);
Tejas Patel84275bf2020-09-01 04:43:53 -0700667
668 return pm_ipi_send_sync(primary_proc, payload, clk_rate, 2);
669}
Tejas Patel023116d2019-01-08 01:46:41 -0800670
671/**
672 * pm_pll_set_param() - Set PLL parameter
673 * @clk_id PLL clock ID
674 * @param PLL parameter ID
675 * @value Value to set for PLL parameter
Tejas Patel18072da2021-02-25 20:16:56 -0800676 * @flag 0 - Call from secure source
677 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800678 *
679 * @return Returns status, either success or error+reason
680 */
681enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
Tejas Patel18072da2021-02-25 20:16:56 -0800682 uint32_t value, uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -0800683{
684 uint32_t payload[PAYLOAD_ARG_CNT];
685
686 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800687 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
688 clk_id, param, value);
Tejas Patel023116d2019-01-08 01:46:41 -0800689
690 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
691}
692
693/**
694 * pm_pll_get_param() - Get PLL parameter value
695 * @clk_id PLL clock ID
696 * @param PLL parameter ID
697 * @value: Buffer to store PLL parameter value
Tejas Patel18072da2021-02-25 20:16:56 -0800698 * @flag 0 - Call from secure source
699 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800700 *
701 * @return Returns status, either success or error+reason
702 */
703enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
Tejas Patel18072da2021-02-25 20:16:56 -0800704 uint32_t *value, uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -0800705{
706 uint32_t payload[PAYLOAD_ARG_CNT];
707
708 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800709 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
710 clk_id, param);
Tejas Patel023116d2019-01-08 01:46:41 -0800711
712 return pm_ipi_send_sync(primary_proc, payload, value, 1);
713}
714
715/**
716 * pm_pll_set_mode() - Set PLL mode
717 * @clk_id PLL clock ID
718 * @mode PLL mode
Tejas Patel18072da2021-02-25 20:16:56 -0800719 * @flag 0 - Call from secure source
720 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800721 *
722 * @return Returns status, either success or error+reason
723 */
Tejas Patel18072da2021-02-25 20:16:56 -0800724enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
725 uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -0800726{
727 uint32_t payload[PAYLOAD_ARG_CNT];
728
729 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800730 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
731 clk_id, mode);
Tejas Patel023116d2019-01-08 01:46:41 -0800732
733 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
734}
735
736/**
737 * pm_pll_get_mode() - Get PLL mode
738 * @clk_id PLL clock ID
739 * @mode: Buffer to store PLL mode
Tejas Patel18072da2021-02-25 20:16:56 -0800740 * @flag 0 - Call from secure source
741 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800742 *
743 * @return Returns status, either success or error+reason
744 */
Tejas Patel18072da2021-02-25 20:16:56 -0800745enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
746 uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -0800747{
748 uint32_t payload[PAYLOAD_ARG_CNT];
749
750 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800751 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
752 clk_id);
Tejas Patel023116d2019-01-08 01:46:41 -0800753
754 return pm_ipi_send_sync(primary_proc, payload, mode, 1);
755}
Tejas Patel6b282252019-01-10 03:03:47 -0800756
757/**
758 * pm_force_powerdown() - PM call to request for another PU or subsystem to
759 * be powered down forcefully
760 * @target Device ID of the PU node to be forced powered down.
761 * @ack Flag to specify whether acknowledge is requested
Tejas Patel18072da2021-02-25 20:16:56 -0800762 * @flag 0 - Call from secure source
763 * 1 - Call from non-secure source
Tejas Patel6b282252019-01-10 03:03:47 -0800764 *
765 * @return Returns status, either success or error+reason
766 */
Tejas Patel18072da2021-02-25 20:16:56 -0800767enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
768 uint32_t flag)
Tejas Patel6b282252019-01-10 03:03:47 -0800769{
770 uint32_t payload[PAYLOAD_ARG_CNT];
771
772 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800773 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN,
774 target, ack);
Tejas Patel6b282252019-01-10 03:03:47 -0800775
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700776 if (ack == IPI_BLOCKING) {
Tejas Patel6b282252019-01-10 03:03:47 -0800777 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700778 } else {
Tejas Patel6b282252019-01-10 03:03:47 -0800779 return pm_ipi_send(primary_proc, payload);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700780 }
Tejas Patel6b282252019-01-10 03:03:47 -0800781}
782
783/**
784 * pm_system_shutdown() - PM call to request a system shutdown or restart
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -0800785 * @type Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
Tejas Patel6b282252019-01-10 03:03:47 -0800786 * @subtype Scope: 0=APU-subsystem, 1=PS, 2=system
Tejas Patel18072da2021-02-25 20:16:56 -0800787 * @flag 0 - Call from secure source
788 * 1 - Call from non-secure source
Tejas Patel6b282252019-01-10 03:03:47 -0800789 *
790 * @return Returns status, either success or error+reason
791 */
Tejas Patel18072da2021-02-25 20:16:56 -0800792enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
793 uint32_t flag)
Tejas Patel6b282252019-01-10 03:03:47 -0800794{
795 uint32_t payload[PAYLOAD_ARG_CNT];
796
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -0800797 if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
798 /* Setting scope for subsequent PSCI reboot or shutdown */
799 pm_shutdown_scope = subtype;
800 return PM_RET_SUCCESS;
801 }
802
Tejas Patel6b282252019-01-10 03:03:47 -0800803 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800804 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SYSTEM_SHUTDOWN,
805 type, subtype);
Tejas Patel6b282252019-01-10 03:03:47 -0800806
807 return pm_ipi_send_non_blocking(primary_proc, payload);
808}
Tejas Patel9141f442019-01-10 03:03:48 -0800809
810/**
Tejas Patela3e34ad2019-02-01 17:25:19 +0530811* pm_query_data() - PM API for querying firmware data
812* @qid The type of data to query
813* @arg1 Argument 1 to requested query data call
814* @arg2 Argument 2 to requested query data call
815* @arg3 Argument 3 to requested query data call
816* @data Returned output data
Tejas Patel18072da2021-02-25 20:16:56 -0800817* @flag 0 - Call from secure source
818* 1 - Call from non-secure source
Tejas Patela3e34ad2019-02-01 17:25:19 +0530819*
820* This function returns requested data.
821*/
822enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
Tejas Patel18072da2021-02-25 20:16:56 -0800823 uint32_t arg3, uint32_t *data, uint32_t flag)
Tejas Patela3e34ad2019-02-01 17:25:19 +0530824{
Rajan Vaja030620d2020-11-23 04:13:54 -0800825 uint32_t ret;
826 uint32_t version;
Tejas Patela3e34ad2019-02-01 17:25:19 +0530827 uint32_t payload[PAYLOAD_ARG_CNT];
Rajan Vaja030620d2020-11-23 04:13:54 -0800828 uint32_t fw_api_version;
Tejas Patela3e34ad2019-02-01 17:25:19 +0530829
830 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800831 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
832 arg1, arg2, arg3);
Rajan Vaja030620d2020-11-23 04:13:54 -0800833
Tejas Patel18072da2021-02-25 20:16:56 -0800834 ret = pm_feature_check(PM_QUERY_DATA, &version, flag);
Manish Pandey3bc1bea2020-12-10 10:48:22 +0000835 if (PM_RET_SUCCESS == ret) {
Rajan Vaja030620d2020-11-23 04:13:54 -0800836 fw_api_version = version & 0xFFFF ;
837 if ((2U == fw_api_version) &&
838 ((XPM_QID_CLOCK_GET_NAME == qid) ||
839 (XPM_QID_PINCTRL_GET_FUNCTION_NAME == qid))) {
840 ret = pm_ipi_send_sync(primary_proc, payload, data, 8);
841 ret = data[0];
842 data[0] = data[1];
843 data[1] = data[2];
844 data[2] = data[3];
845 } else {
846 ret = pm_ipi_send_sync(primary_proc, payload, data, 4);
847 }
848 }
849 return ret;
Tejas Patela3e34ad2019-02-01 17:25:19 +0530850}
851/**
Tejas Patel9141f442019-01-10 03:03:48 -0800852 * pm_api_ioctl() - PM IOCTL API for device control and configs
853 * @device_id Device ID
854 * @ioctl_id ID of the requested IOCTL
855 * @arg1 Argument 1 to requested IOCTL call
856 * @arg2 Argument 2 to requested IOCTL call
857 * @value Returned output value
Tejas Patel18072da2021-02-25 20:16:56 -0800858 * @flag 0 - Call from secure source
859 * 1 - Call from non-secure source
Tejas Patel9141f442019-01-10 03:03:48 -0800860 *
861 * This function calls IOCTL to firmware for device control and configuration.
862 *
863 * @return Returns status, either success or error+reason
864 */
865enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
Tejas Patel18072da2021-02-25 20:16:56 -0800866 uint32_t arg1, uint32_t arg2, uint32_t *value,
867 uint32_t flag)
Tejas Patel9141f442019-01-10 03:03:48 -0800868{
869 uint32_t payload[PAYLOAD_ARG_CNT];
Venkatesh Yadav Abbarapuaa4898a2021-03-31 03:07:40 -0600870 int ret;
Tejas Patel9141f442019-01-10 03:03:48 -0800871
872 switch (ioctl_id) {
873 case IOCTL_SET_PLL_FRAC_MODE:
Tejas Patel18072da2021-02-25 20:16:56 -0800874 return pm_pll_set_mode(arg1, arg2, flag);
Tejas Patel9141f442019-01-10 03:03:48 -0800875 case IOCTL_GET_PLL_FRAC_MODE:
Tejas Patel18072da2021-02-25 20:16:56 -0800876 return pm_pll_get_mode(arg1, value, flag);
Tejas Patel9141f442019-01-10 03:03:48 -0800877 case IOCTL_SET_PLL_FRAC_DATA:
Tejas Patel18072da2021-02-25 20:16:56 -0800878 return pm_pll_set_param(arg1, PM_PLL_PARAM_DATA, arg2, flag);
Tejas Patel9141f442019-01-10 03:03:48 -0800879 case IOCTL_GET_PLL_FRAC_DATA:
Tejas Patel18072da2021-02-25 20:16:56 -0800880 return pm_pll_get_param(arg1, PM_PLL_PARAM_DATA, value, flag);
Venkatesh Yadav Abbarapuaa4898a2021-03-31 03:07:40 -0600881 case IOCTL_SET_SGI:
882 /* Get the sgi number */
883 ret = pm_register_sgi(arg1);
884 if (ret) {
885 return PM_RET_ERROR_ARGS;
886 }
887 gicd_write_irouter(gicv3_driver_data->gicd_base,
888 PLAT_VERSAL_IPI_IRQ, MODE);
889 return PM_RET_SUCCESS;
Tejas Patel9141f442019-01-10 03:03:48 -0800890 default:
891 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800892 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_IOCTL,
893 device_id, ioctl_id, arg1, arg2);
Tejas Patel9141f442019-01-10 03:03:48 -0800894 return pm_ipi_send_sync(primary_proc, payload, value, 1);
895 }
896}
Tejas Pateldb812052019-01-23 14:18:53 +0530897
898/**
899 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
900 * @target Device id of the targeted PU or subsystem
901 * @wkup_node Device id of the wakeup peripheral
902 * @enable Enable or disable the specified peripheral as wake source
Tejas Patel18072da2021-02-25 20:16:56 -0800903 * @flag 0 - Call from secure source
904 * 1 - Call from non-secure source
Tejas Pateldb812052019-01-23 14:18:53 +0530905 *
906 * @return Returns status, either success or error+reason
907 */
908enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
Tejas Patel18072da2021-02-25 20:16:56 -0800909 uint8_t enable, uint32_t flag)
Tejas Pateldb812052019-01-23 14:18:53 +0530910{
911 uint32_t payload[PAYLOAD_ARG_CNT];
912
Tejas Patel18072da2021-02-25 20:16:56 -0800913 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE,
914 target, wkup_device, enable);
Abhyuday Godhasara7ae761b2021-06-24 05:50:44 -0700915 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Tejas Pateldb812052019-01-23 14:18:53 +0530916}
Ravi Patel22b0b492019-03-06 12:34:46 +0530917
918/**
Ravi Patelbd4aa5a2019-08-12 03:17:54 -0700919 * pm_get_chipid() - Read silicon ID registers
920 * @value Buffer for return values. Must be large enough
921 * to hold 8 bytes.
Tejas Patel18072da2021-02-25 20:16:56 -0800922 * @flag 0 - Call from secure source
923 * 1 - Call from non-secure source
Ravi Patelbd4aa5a2019-08-12 03:17:54 -0700924 *
925 * @return Returns silicon ID registers
926 */
Tejas Patel18072da2021-02-25 20:16:56 -0800927enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag)
Ravi Patelbd4aa5a2019-08-12 03:17:54 -0700928{
929 uint32_t payload[PAYLOAD_ARG_CNT];
930
931 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800932 PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_CHIPID);
Ravi Patelbd4aa5a2019-08-12 03:17:54 -0700933
934 return pm_ipi_send_sync(primary_proc, payload, value, 2);
935}
936
937/**
Ravi Patel22b0b492019-03-06 12:34:46 +0530938 * pm_feature_check() - Returns the supported API version if supported
939 * @api_id API ID to check
940 * @value Returned supported API version
Tejas Patel18072da2021-02-25 20:16:56 -0800941 * @flag 0 - Call from secure source
942 * 1 - Call from non-secure source
Ravi Patel22b0b492019-03-06 12:34:46 +0530943 *
944 * @return Returns status, either success or error+reason
945 */
Tejas Patel18072da2021-02-25 20:16:56 -0800946enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
947 uint32_t flag)
Ravi Patel22b0b492019-03-06 12:34:46 +0530948{
949 uint32_t payload[PAYLOAD_ARG_CNT], fw_api_version;
950 uint32_t status;
951
952 switch (api_id) {
953 case PM_GET_CALLBACK_DATA:
954 case PM_GET_TRUSTZONE_VERSION:
Rajan Vajaad1ffff2021-01-20 00:53:45 -0800955 case PM_LOAD_PDI:
Ravi Patel22b0b492019-03-06 12:34:46 +0530956 *version = (PM_API_BASE_VERSION << 16);
957 return PM_RET_SUCCESS;
958 case PM_GET_API_VERSION:
959 case PM_GET_DEVICE_STATUS:
Saeed Nowshadi2294b422019-06-03 10:22:35 -0700960 case PM_GET_OP_CHARACTERISTIC:
Ravi Patel22b0b492019-03-06 12:34:46 +0530961 case PM_REQ_SUSPEND:
962 case PM_SELF_SUSPEND:
963 case PM_FORCE_POWERDOWN:
964 case PM_ABORT_SUSPEND:
965 case PM_REQ_WAKEUP:
966 case PM_SET_WAKEUP_SOURCE:
967 case PM_SYSTEM_SHUTDOWN:
968 case PM_REQUEST_DEVICE:
969 case PM_RELEASE_DEVICE:
970 case PM_SET_REQUIREMENT:
971 case PM_RESET_ASSERT:
972 case PM_RESET_GET_STATUS:
Venkatesh Yadav Abbarapu95ecd452019-12-10 22:16:36 -0500973 case PM_GET_CHIPID:
Ravi Patel22b0b492019-03-06 12:34:46 +0530974 case PM_PINCTRL_REQUEST:
975 case PM_PINCTRL_RELEASE:
976 case PM_PINCTRL_GET_FUNCTION:
977 case PM_PINCTRL_SET_FUNCTION:
978 case PM_PINCTRL_CONFIG_PARAM_GET:
979 case PM_PINCTRL_CONFIG_PARAM_SET:
980 case PM_IOCTL:
Ravi Patel22b0b492019-03-06 12:34:46 +0530981 case PM_CLOCK_ENABLE:
982 case PM_CLOCK_DISABLE:
983 case PM_CLOCK_GETSTATE:
984 case PM_CLOCK_SETDIVIDER:
985 case PM_CLOCK_GETDIVIDER:
986 case PM_CLOCK_SETPARENT:
987 case PM_CLOCK_GETPARENT:
Tejas Patel84275bf2020-09-01 04:43:53 -0700988 case PM_CLOCK_GETRATE:
Ravi Patel22b0b492019-03-06 12:34:46 +0530989 case PM_PLL_SET_PARAMETER:
990 case PM_PLL_GET_PARAMETER:
991 case PM_PLL_SET_MODE:
992 case PM_PLL_GET_MODE:
993 case PM_FEATURE_CHECK:
Ravi Patel476b5b12019-08-12 03:10:10 -0700994 case PM_INIT_FINALIZE:
Tejas Patel5c154e12020-11-25 01:53:12 -0800995 case PM_SET_MAX_LATENCY:
Tejas Patel42015552020-11-25 01:56:57 -0800996 case PM_REGISTER_NOTIFIER:
Ravi Patel22b0b492019-03-06 12:34:46 +0530997 *version = (PM_API_BASE_VERSION << 16);
998 break;
Rajan Vajaad1ffff2021-01-20 00:53:45 -0800999 case PM_QUERY_DATA:
1000 *version = (PM_API_QUERY_DATA_VERSION << 16);
1001 break;
Ravi Patel22b0b492019-03-06 12:34:46 +05301002 default:
1003 *version = 0U;
1004 return PM_RET_ERROR_NOFEATURE;
1005 }
1006
Tejas Patel18072da2021-02-25 20:16:56 -08001007 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
1008 PM_FEATURE_CHECK, api_id);
Ravi Patel22b0b492019-03-06 12:34:46 +05301009
1010 status = pm_ipi_send_sync(primary_proc, payload, &fw_api_version, 1);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -07001011 if (status != PM_RET_SUCCESS) {
Ravi Patel22b0b492019-03-06 12:34:46 +05301012 return status;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -07001013 }
Ravi Patel22b0b492019-03-06 12:34:46 +05301014
1015 *version |= fw_api_version;
1016
1017 return PM_RET_SUCCESS;
1018}
Jolly Shahed05a712019-03-22 05:33:39 +05301019
1020/**
1021 * pm_load_pdi() - Load the PDI
1022 *
1023 * This function provides support to load PDI from linux
1024 *
1025 * src: Source device of pdi(DDR, OCM, SD etc)
1026 * address_low: lower 32-bit Linear memory space address
1027 * address_high: higher 32-bit Linear memory space address
Tejas Patel18072da2021-02-25 20:16:56 -08001028 * @flag 0 - Call from secure source
1029 * 1 - Call from non-secure source
Jolly Shahed05a712019-03-22 05:33:39 +05301030 *
1031 * @return Returns status, either success or error+reason
1032 */
Tejas Patel18072da2021-02-25 20:16:56 -08001033enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
1034 uint32_t address_high, uint32_t flag)
Jolly Shahed05a712019-03-22 05:33:39 +05301035{
1036 uint32_t payload[PAYLOAD_ARG_CNT];
1037
1038 /* Send request to the PMU */
Tejas Patel18072da2021-02-25 20:16:56 -08001039 PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, flag, PM_LOAD_PDI, src,
Jolly Shahed05a712019-03-22 05:33:39 +05301040 address_high, address_low);
1041 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1042}
Saeed Nowshadi2294b422019-06-03 10:22:35 -07001043
1044/**
1045 * pm_get_op_characteristic() - PM call to request operating characteristics
1046 * of a device
1047 * @device_id Device id
1048 * @type Type of the operating characteristic
1049 * (power, temperature and latency)
1050 * @result Returns the operating characteristic for the requested device,
1051 * specified by the type
Tejas Patel18072da2021-02-25 20:16:56 -08001052 * @flag 0 - Call from secure source
1053 * 1 - Call from non-secure source
Saeed Nowshadi2294b422019-06-03 10:22:35 -07001054 *
1055 * @return Returns status, either success or error+reason
1056 */
1057enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
1058 enum pm_opchar_type type,
Tejas Patel18072da2021-02-25 20:16:56 -08001059 uint32_t *result, uint32_t flag)
Saeed Nowshadi2294b422019-06-03 10:22:35 -07001060{
1061 uint32_t payload[PAYLOAD_ARG_CNT];
1062
1063 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -08001064 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
1065 PM_GET_OP_CHARACTERISTIC, device_id, type);
Saeed Nowshadi2294b422019-06-03 10:22:35 -07001066 return pm_ipi_send_sync(primary_proc, payload, result, 1);
1067}
Tejas Patel5c154e12020-11-25 01:53:12 -08001068
1069/**
1070 * pm_set_max_latency() - PM call to change in the maximum wake-up latency
1071 * requirements for a specific device currently
1072 * used by that CPU.
1073 * @device_id Device ID
1074 * @latency Latency value
Tejas Patel18072da2021-02-25 20:16:56 -08001075 * @flag 0 - Call from secure source
1076 * 1 - Call from non-secure source
Tejas Patel5c154e12020-11-25 01:53:12 -08001077 *
1078 * @return Returns status, either success or error+reason
1079 */
Tejas Patel18072da2021-02-25 20:16:56 -08001080enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
1081 uint32_t flag)
Tejas Patel5c154e12020-11-25 01:53:12 -08001082{
1083 uint32_t payload[PAYLOAD_ARG_CNT];
1084
1085 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -08001086 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SET_MAX_LATENCY,
Tejas Patel5c154e12020-11-25 01:53:12 -08001087 device_id, latency);
1088
1089 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1090}
Tejas Patel42015552020-11-25 01:56:57 -08001091
1092/**
1093 * pm_register_notifier() - PM call to register a subsystem to be notified
1094 * about the device event
1095 * @device_id Device ID for the Node to which the event is related
1096 * @event Event in question
1097 * @wake Wake subsystem upon capturing the event if value 1
1098 * @enable Enable the registration for value 1, disable for value 0
Tejas Patel18072da2021-02-25 20:16:56 -08001099 * @flag 0 - Call from secure source
1100 * 1 - Call from non-secure source
Tejas Patel42015552020-11-25 01:56:57 -08001101 *
1102 * @return Returns status, either success or error+reason
1103 */
1104enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
Tejas Patel18072da2021-02-25 20:16:56 -08001105 uint32_t wake, uint32_t enable,
1106 uint32_t flag)
Tejas Patel42015552020-11-25 01:56:57 -08001107{
1108 uint32_t payload[PAYLOAD_ARG_CNT];
1109
1110 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -08001111 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REGISTER_NOTIFIER,
Tejas Patel42015552020-11-25 01:56:57 -08001112 device_id, event, wake, enable);
1113
1114 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1115}