blob: c7b60476fac8f14e5409a53d2a7e5cb2b08cbc11 [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.
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 ********************************************************************/
Abhyuday Godhasaraedc38ae2021-08-04 23:58:46 -070024#define LIBPM_MODULE_ID 0x2U
25#define LOADER_MODULE_ID 0x7U
Tejas Patel9d09ff92019-01-08 01:46:35 -080026
Abhyuday Godhasaraedc38ae2021-08-04 23:58:46 -070027#define MODE 0x80000000U
Tanmay Shahff34daa2021-08-09 11:00:41 -070028#define MODULE_ID_MASK 0x0000ff00
29
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -080030/* default shutdown/reboot scope is system(2) */
31static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
32
33/**
34 * pm_get_shutdown_scope() - Get the currently set shutdown scope
35 *
36 * @return Shutdown scope value
37 */
38unsigned int pm_get_shutdown_scope(void)
39{
40 return pm_shutdown_scope;
41}
42
Tejas Patel9d09ff92019-01-08 01:46:35 -080043/**
44 * Assigning of argument values into array elements.
45 */
Tejas Patel18072da2021-02-25 20:16:56 -080046#define PM_PACK_PAYLOAD1(pl, mid, flag, arg0) { \
Abhyuday Godhasara19e47da2021-08-05 10:49:23 -070047 pl[0] = (uint32_t)(((uint32_t)(arg0) & 0xFFU) | ((mid) << 8U) | ((flag) << 24U)); \
Tejas Patel9d09ff92019-01-08 01:46:35 -080048}
49
Tejas Patel18072da2021-02-25 20:16:56 -080050#define PM_PACK_PAYLOAD2(pl, mid, flag, arg0, arg1) { \
51 pl[1] = (uint32_t)(arg1); \
Abhyuday Godhasara19e47da2021-08-05 10:49:23 -070052 PM_PACK_PAYLOAD1(pl, (mid), (flag), (arg0)); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080053}
54
Tejas Patel18072da2021-02-25 20:16:56 -080055#define PM_PACK_PAYLOAD3(pl, mid, flag, arg0, arg1, arg2) { \
56 pl[2] = (uint32_t)(arg2); \
Abhyuday Godhasara19e47da2021-08-05 10:49:23 -070057 PM_PACK_PAYLOAD2(pl, (mid), (flag), (arg0), (arg1)); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080058}
59
Tejas Patel18072da2021-02-25 20:16:56 -080060#define PM_PACK_PAYLOAD4(pl, mid, flag, arg0, arg1, arg2, arg3) { \
61 pl[3] = (uint32_t)(arg3); \
Abhyuday Godhasara19e47da2021-08-05 10:49:23 -070062 PM_PACK_PAYLOAD3(pl, (mid), (flag), (arg0), (arg1), (arg2)); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080063}
64
Tejas Patel18072da2021-02-25 20:16:56 -080065#define PM_PACK_PAYLOAD5(pl, mid, flag, arg0, arg1, arg2, arg3, arg4) { \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080066 pl[4] = (uint32_t)(arg4); \
Abhyuday Godhasara19e47da2021-08-05 10:49:23 -070067 PM_PACK_PAYLOAD4(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3)); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080068}
69
Tejas Patel18072da2021-02-25 20:16:56 -080070#define PM_PACK_PAYLOAD6(pl, mid, flag, arg0, arg1, arg2, arg3, arg4, arg5) { \
71 pl[5] = (uint32_t)(arg5); \
Abhyuday Godhasara19e47da2021-08-05 10:49:23 -070072 PM_PACK_PAYLOAD5(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4)); \
Tejas Patelfe0e10a2019-12-08 23:29:44 -080073}
74
Tejas Patel9d09ff92019-01-08 01:46:35 -080075/* PM API functions */
76
77/**
Tanmay Shahff34daa2021-08-09 11:00:41 -070078 * pm_handle_eemi_call() - PM call for processor to send eemi payload
Tejas Patel18072da2021-02-25 20:16:56 -080079 * @flag 0 - Call from secure source
80 * 1 - Call from non-secure source
Tanmay Shahff34daa2021-08-09 11:00:41 -070081 * @x0 to x5 Arguments received per SMC64 standard
82 * @result Payload received from firmware
Tejas Patel9d09ff92019-01-08 01:46:35 -080083 *
Tanmay Shahff34daa2021-08-09 11:00:41 -070084 * @return PM_RET_SUCCESS on success or error code
Tejas Patel9d09ff92019-01-08 01:46:35 -080085 */
Tanmay Shahff34daa2021-08-09 11:00:41 -070086enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
87 uint32_t x2, uint32_t x3, uint32_t x4,
88 uint32_t x5, uint64_t *result)
Tejas Patel9d09ff92019-01-08 01:46:35 -080089{
Tanmay Shahff34daa2021-08-09 11:00:41 -070090 uint32_t payload[PAYLOAD_ARG_CNT] = {0};
91 uint32_t module_id;
Tejas Patel9d09ff92019-01-08 01:46:35 -080092
Tanmay Shahff34daa2021-08-09 11:00:41 -070093 module_id = (x0 & MODULE_ID_MASK) >> 8;
Tejas Patelfe0e10a2019-12-08 23:29:44 -080094
Tanmay Shahff34daa2021-08-09 11:00:41 -070095 //default module id is for LIBPM
96 if (module_id == 0)
97 module_id = LIBPM_MODULE_ID;
Ravi Patel476b5b12019-08-12 03:10:10 -070098
Tanmay Shahff34daa2021-08-09 11:00:41 -070099 PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
100 return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
Ravi Patel476b5b12019-08-12 03:10:10 -0700101}
102
103/**
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800104 * pm_self_suspend() - PM call for processor to suspend itself
105 * @nid Node id of the processor or subsystem
106 * @latency Requested maximum wakeup latency (not supported)
107 * @state Requested state
108 * @address Resume address
Tejas Patel18072da2021-02-25 20:16:56 -0800109 * @flag 0 - Call from secure source
110 * 1 - Call from non-secure source
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800111 *
112 * This is a blocking call, it will return only once PMU has responded.
113 * On a wakeup, resume address will be automatically set by PMU.
114 *
115 * @return Returns status, either success or error+reason
116 */
117enum pm_ret_status pm_self_suspend(uint32_t nid,
118 unsigned int latency,
119 unsigned int state,
Tejas Patel18072da2021-02-25 20:16:56 -0800120 uintptr_t address, uint32_t flag)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800121{
122 uint32_t payload[PAYLOAD_ARG_CNT];
123 unsigned int cpuid = plat_my_core_pos();
124 const struct pm_proc *proc = pm_get_proc(cpuid);
125
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700126 if (proc == NULL) {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800127 WARN("Failed to get proc %d\n", cpuid);
128 return PM_RET_ERROR_INTERNAL;
129 }
130
131 /*
132 * Do client specific suspend operations
133 * (e.g. set powerdown request bit)
134 */
135 pm_client_suspend(proc, state);
136
137 /* Send request to the PLM */
Tejas Patel18072da2021-02-25 20:16:56 -0800138 PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, flag, PM_SELF_SUSPEND,
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800139 proc->node_id, latency, state, address,
140 (address >> 32));
141 return pm_ipi_send_sync(proc, payload, NULL, 0);
142}
143
144/**
145 * pm_abort_suspend() - PM call to announce that a prior suspend request
146 * is to be aborted.
147 * @reason Reason for the abort
Tejas Patel18072da2021-02-25 20:16:56 -0800148 * @flag 0 - Call from secure source
149 * 1 - Call from non-secure source
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800150 *
151 * Calling PU expects the PMU to abort the initiated suspend procedure.
152 * This is a non-blocking call without any acknowledge.
153 *
154 * @return Returns status, either success or error+reason
155 */
Tejas Patel18072da2021-02-25 20:16:56 -0800156enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800157{
158 uint32_t payload[PAYLOAD_ARG_CNT];
159
160 /*
161 * Do client specific abort suspend operations
162 * (e.g. enable interrupts and clear powerdown request bit)
163 */
164 pm_client_abort_suspend();
165
166 /* Send request to the PLM */
Tejas Patel18072da2021-02-25 20:16:56 -0800167 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_ABORT_SUSPEND,
168 reason, primary_proc->node_id);
Abhyuday Godhasara7ae761b2021-06-24 05:50:44 -0700169 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800170}
171
172/**
173 * pm_req_suspend() - PM call to request for another PU or subsystem to
174 * be suspended gracefully.
175 * @target Node id of the targeted PU or subsystem
176 * @ack Flag to specify whether acknowledge is requested
177 * @latency Requested wakeup latency (not supported)
178 * @state Requested state (not supported)
Tejas Patel18072da2021-02-25 20:16:56 -0800179 * @flag 0 - Call from secure source
180 * 1 - Call from non-secure source
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800181 *
182 * @return Returns status, either success or error+reason
183 */
184enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
Tejas Patel18072da2021-02-25 20:16:56 -0800185 unsigned int latency, unsigned int state,
186 uint32_t flag)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800187{
188 uint32_t payload[PAYLOAD_ARG_CNT];
189
190 /* Send request to the PMU */
Tejas Patel18072da2021-02-25 20:16:56 -0800191 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_REQ_SUSPEND, target,
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800192 latency, state);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700193 if (ack == IPI_BLOCKING) {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800194 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700195 } else {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800196 return pm_ipi_send(primary_proc, payload);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700197 }
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800198}
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800199
200/**
Tejas Patel49cd8712019-01-23 14:18:51 +0530201 * pm_req_wakeup() - PM call for processor to wake up selected processor
202 * or subsystem
203 * @target Device ID of the processor or subsystem to wake up
204 * @set_address Resume address presence indicator
205 * 1 - resume address specified, 0 - otherwise
206 * @address Resume address
207 * @ack Flag to specify whether acknowledge requested
Tejas Patel18072da2021-02-25 20:16:56 -0800208 * @flag 0 - Call from secure source
209 * 1 - Call from non-secure source
Tejas Patel49cd8712019-01-23 14:18:51 +0530210 *
211 * This API function is either used to power up another APU core for SMP
212 * (by PSCI) or to power up an entirely different PU or subsystem, such
213 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
214 * automatically set by PMC.
215 *
216 * @return Returns status, either success or error+reason
217 */
218enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
Tejas Patel18072da2021-02-25 20:16:56 -0800219 uintptr_t address, uint8_t ack, uint32_t flag)
Tejas Patel49cd8712019-01-23 14:18:51 +0530220{
221 uint32_t payload[PAYLOAD_ARG_CNT];
222
223 /* Send request to the PMC to perform the wake of the PU */
Tejas Patel18072da2021-02-25 20:16:56 -0800224 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQ_WAKEUP, target,
Tejas Patel49cd8712019-01-23 14:18:51 +0530225 set_address, address, ack);
226
227 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
228}
229
230/**
Rajan Vaja649e9242019-03-04 11:09:40 +0530231 * pm_get_callbackdata() - Read from IPI response buffer
232 * @data - array of PAYLOAD_ARG_CNT elements
Tejas Patel18072da2021-02-25 20:16:56 -0800233 * @flag - 0 - Call from secure source
234 * 1 - Call from non-secure source
Rajan Vaja649e9242019-03-04 11:09:40 +0530235 *
236 * Read value from ipi buffer response buffer.
237 */
Tejas Patel18072da2021-02-25 20:16:56 -0800238void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag)
Rajan Vaja649e9242019-03-04 11:09:40 +0530239{
240 /* Return if interrupt is not from PMU */
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700241 if (pm_ipi_irq_status(primary_proc) == 0) {
Rajan Vaja649e9242019-03-04 11:09:40 +0530242 return;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700243 }
Rajan Vaja649e9242019-03-04 11:09:40 +0530244
245 pm_ipi_buff_read_callb(data, count);
246 pm_ipi_irq_clear(primary_proc);
247}
248
249/**
Tanmay Shahff34daa2021-08-09 11:00:41 -0700250 * pm_pll_set_param() - Set PLL parameter
Tejas Patel1f56fb12019-01-08 01:46:40 -0800251 *
Tanmay Shahff34daa2021-08-09 11:00:41 -0700252 * This API is deprecated and maintained here for backward compatibility.
253 * New use of this API should be avoided for versal platform.
254 * This API and its use cases will be removed for versal platform.
Tejas Patel84275bf2020-09-01 04:43:53 -0700255 *
Tejas Patel023116d2019-01-08 01:46:41 -0800256 * @clk_id PLL clock ID
257 * @param PLL parameter ID
258 * @value Value to set for PLL parameter
Tejas Patel18072da2021-02-25 20:16:56 -0800259 * @flag 0 - Call from secure source
260 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800261 *
262 * @return Returns status, either success or error+reason
263 */
264enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
Tejas Patel18072da2021-02-25 20:16:56 -0800265 uint32_t value, uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -0800266{
267 uint32_t payload[PAYLOAD_ARG_CNT];
268
269 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800270 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
271 clk_id, param, value);
Tejas Patel023116d2019-01-08 01:46:41 -0800272
273 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
274}
275
276/**
277 * pm_pll_get_param() - Get PLL parameter value
Tanmay Shahff34daa2021-08-09 11:00:41 -0700278 *
279 * This API is deprecated and maintained here for backward compatibility.
280 * New use of this API should be avoided for versal platform.
281 * This API and its use cases will be removed for versal platform.
282 *
Tejas Patel023116d2019-01-08 01:46:41 -0800283 * @clk_id PLL clock ID
284 * @param PLL parameter ID
285 * @value: Buffer to store PLL parameter value
Tejas Patel18072da2021-02-25 20:16:56 -0800286 * @flag 0 - Call from secure source
287 * 1 - Call from non-secure source
Tejas Patel023116d2019-01-08 01:46:41 -0800288 *
289 * @return Returns status, either success or error+reason
290 */
291enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
Tejas Patel18072da2021-02-25 20:16:56 -0800292 uint32_t *value, uint32_t flag)
Tejas Patel023116d2019-01-08 01:46:41 -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_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
298 clk_id, param);
Tejas Patel023116d2019-01-08 01:46:41 -0800299
300 return pm_ipi_send_sync(primary_proc, payload, value, 1);
301}
302
303/**
304 * pm_pll_set_mode() - Set PLL mode
Tanmay Shahff34daa2021-08-09 11:00:41 -0700305 *
306 * This API is deprecated and maintained here for backward compatibility.
307 * New use of this API should be avoided for versal platform.
308 * This API and its use cases will be removed for versal platform.
309 *
Tejas Patel023116d2019-01-08 01:46:41 -0800310 * @clk_id PLL clock ID
311 * @mode PLL mode
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 */
Tejas Patel18072da2021-02-25 20:16:56 -0800317enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
318 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_SET_MODE,
324 clk_id, mode);
Tejas Patel023116d2019-01-08 01:46:41 -0800325
326 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
327}
328
329/**
330 * pm_pll_get_mode() - Get 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: Buffer to store 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_get_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_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
350 clk_id);
Tejas Patel023116d2019-01-08 01:46:41 -0800351
352 return pm_ipi_send_sync(primary_proc, payload, mode, 1);
353}
Tejas Patel6b282252019-01-10 03:03:47 -0800354
355/**
356 * pm_force_powerdown() - PM call to request for another PU or subsystem to
357 * be powered down forcefully
358 * @target Device ID of the PU node to be forced powered down.
359 * @ack Flag to specify whether acknowledge is requested
Tejas Patel18072da2021-02-25 20:16:56 -0800360 * @flag 0 - Call from secure source
361 * 1 - Call from non-secure source
Tejas Patel6b282252019-01-10 03:03:47 -0800362 *
363 * @return Returns status, either success or error+reason
364 */
Tejas Patel18072da2021-02-25 20:16:56 -0800365enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
366 uint32_t flag)
Tejas Patel6b282252019-01-10 03:03:47 -0800367{
368 uint32_t payload[PAYLOAD_ARG_CNT];
369
370 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800371 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN,
372 target, ack);
Tejas Patel6b282252019-01-10 03:03:47 -0800373
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700374 if (ack == IPI_BLOCKING) {
Tejas Patel6b282252019-01-10 03:03:47 -0800375 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700376 } else {
Tejas Patel6b282252019-01-10 03:03:47 -0800377 return pm_ipi_send(primary_proc, payload);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700378 }
Tejas Patel6b282252019-01-10 03:03:47 -0800379}
380
381/**
382 * pm_system_shutdown() - PM call to request a system shutdown or restart
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -0800383 * @type Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
Tejas Patel6b282252019-01-10 03:03:47 -0800384 * @subtype Scope: 0=APU-subsystem, 1=PS, 2=system
Tejas Patel18072da2021-02-25 20:16:56 -0800385 * @flag 0 - Call from secure source
386 * 1 - Call from non-secure source
Tejas Patel6b282252019-01-10 03:03:47 -0800387 *
388 * @return Returns status, either success or error+reason
389 */
Tejas Patel18072da2021-02-25 20:16:56 -0800390enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
391 uint32_t flag)
Tejas Patel6b282252019-01-10 03:03:47 -0800392{
393 uint32_t payload[PAYLOAD_ARG_CNT];
394
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -0800395 if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
396 /* Setting scope for subsequent PSCI reboot or shutdown */
397 pm_shutdown_scope = subtype;
398 return PM_RET_SUCCESS;
399 }
400
Tejas Patel6b282252019-01-10 03:03:47 -0800401 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800402 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SYSTEM_SHUTDOWN,
403 type, subtype);
Tejas Patel6b282252019-01-10 03:03:47 -0800404
405 return pm_ipi_send_non_blocking(primary_proc, payload);
406}
Tejas Patel9141f442019-01-10 03:03:48 -0800407
408/**
Tanmay Shahff34daa2021-08-09 11:00:41 -0700409 * pm_query_data() - PM API for querying firmware data
410 *
411 * This API is deprecated and maintained here for backward compatibility.
412 * New use of this API should be avoided for versal platform.
413 * This API and its use cases will be removed for versal platform.
414 *
415 * @qid The type of data to query
416 * @arg1 Argument 1 to requested query data call
417 * @arg2 Argument 2 to requested query data call
418 * @arg3 Argument 3 to requested query data call
419 * @data Returned output data
420 * @flag 0 - Call from secure source
421 * 1 - Call from non-secure source
422 *
423 * @retur - 0 if success else non-zero error code of type
424 * enum pm_ret_status
425 */
Tejas Patela3e34ad2019-02-01 17:25:19 +0530426enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
Tejas Patel18072da2021-02-25 20:16:56 -0800427 uint32_t arg3, uint32_t *data, uint32_t flag)
Tejas Patela3e34ad2019-02-01 17:25:19 +0530428{
Rajan Vaja030620d2020-11-23 04:13:54 -0800429 uint32_t ret;
Tanmay Shahff34daa2021-08-09 11:00:41 -0700430 uint32_t version[PAYLOAD_ARG_CNT] = {0};
Tejas Patela3e34ad2019-02-01 17:25:19 +0530431 uint32_t payload[PAYLOAD_ARG_CNT];
Rajan Vaja030620d2020-11-23 04:13:54 -0800432 uint32_t fw_api_version;
Tejas Patela3e34ad2019-02-01 17:25:19 +0530433
434 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800435 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
436 arg1, arg2, arg3);
Rajan Vaja030620d2020-11-23 04:13:54 -0800437
Tanmay Shahff34daa2021-08-09 11:00:41 -0700438 ret = pm_feature_check(PM_QUERY_DATA, &version[0], flag);
439 if (ret == PM_RET_SUCCESS) {
440 fw_api_version = version[0] & 0xFFFF;
441 if ((fw_api_version == 2U) &&
442 ((qid == XPM_QID_CLOCK_GET_NAME) ||
443 (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
444 ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
445 if (ret == PM_RET_SUCCESS) {
446 ret = data[0];
447 data[0] = data[1];
448 data[1] = data[2];
449 data[2] = data[3];
450 }
Rajan Vaja030620d2020-11-23 04:13:54 -0800451 } else {
Tanmay Shahff34daa2021-08-09 11:00:41 -0700452 ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
Rajan Vaja030620d2020-11-23 04:13:54 -0800453 }
454 }
455 return ret;
Tejas Patela3e34ad2019-02-01 17:25:19 +0530456}
457/**
Tejas Patel9141f442019-01-10 03:03:48 -0800458 * pm_api_ioctl() - PM IOCTL API for device control and configs
Tanmay Shahff34daa2021-08-09 11:00:41 -0700459 *
460 * This API is deprecated and maintained here for backward compatibility.
461 * New use of this API should be avoided for versal platform.
462 * This API and its use cases will be removed for versal platform.
463 *
Tejas Patel9141f442019-01-10 03:03:48 -0800464 * @device_id Device ID
465 * @ioctl_id ID of the requested IOCTL
466 * @arg1 Argument 1 to requested IOCTL call
467 * @arg2 Argument 2 to requested IOCTL call
Venkatesh Yadav Abbarapu4b233392021-10-20 22:11:53 -0600468 * @arg3 Argument 3 to requested IOCTL call
Tejas Patel9141f442019-01-10 03:03:48 -0800469 * @value Returned output value
Tejas Patel18072da2021-02-25 20:16:56 -0800470 * @flag 0 - Call from secure source
471 * 1 - Call from non-secure source
Tejas Patel9141f442019-01-10 03:03:48 -0800472 *
473 * This function calls IOCTL to firmware for device control and configuration.
474 *
Tanmay Shahff34daa2021-08-09 11:00:41 -0700475 * @return Returns status, either 0 on success or non-zero error code
476 * of type enum pm_ret_status
Tejas Patel9141f442019-01-10 03:03:48 -0800477 */
478enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
Venkatesh Yadav Abbarapu4b233392021-10-20 22:11:53 -0600479 uint32_t arg1, uint32_t arg2, uint32_t arg3,
480 uint32_t *value, uint32_t flag)
Tejas Patel9141f442019-01-10 03:03:48 -0800481{
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700482 enum pm_ret_status ret;
Tejas Patel9141f442019-01-10 03:03:48 -0800483
484 switch (ioctl_id) {
485 case IOCTL_SET_PLL_FRAC_MODE:
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700486 ret = pm_pll_set_mode(arg1, arg2, flag);
487 break;
Tejas Patel9141f442019-01-10 03:03:48 -0800488 case IOCTL_GET_PLL_FRAC_MODE:
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700489 ret = pm_pll_get_mode(arg1, value, flag);
490 break;
Tejas Patel9141f442019-01-10 03:03:48 -0800491 case IOCTL_SET_PLL_FRAC_DATA:
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700492 ret = pm_pll_set_param(arg1, PM_PLL_PARAM_DATA, arg2, flag);
493 break;
Tejas Patel9141f442019-01-10 03:03:48 -0800494 case IOCTL_GET_PLL_FRAC_DATA:
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700495 ret = pm_pll_get_param(arg1, PM_PLL_PARAM_DATA, value, flag);
496 break;
Venkatesh Yadav Abbarapuaa4898a2021-03-31 03:07:40 -0600497 case IOCTL_SET_SGI:
498 /* Get the sgi number */
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700499 if (pm_register_sgi(arg1) != 0) {
Venkatesh Yadav Abbarapuaa4898a2021-03-31 03:07:40 -0600500 return PM_RET_ERROR_ARGS;
501 }
502 gicd_write_irouter(gicv3_driver_data->gicd_base,
Abhyuday Godhasaraedc38ae2021-08-04 23:58:46 -0700503 (unsigned int)PLAT_VERSAL_IPI_IRQ, MODE);
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700504 ret = PM_RET_SUCCESS;
505 break;
Tejas Patel9141f442019-01-10 03:03:48 -0800506 default:
Tanmay Shahff34daa2021-08-09 11:00:41 -0700507 return PM_RET_ERROR_NOTSUPPORTED;
Tejas Patel9141f442019-01-10 03:03:48 -0800508 }
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700509
510 return ret;
Tejas Patel9141f442019-01-10 03:03:48 -0800511}
Tejas Pateldb812052019-01-23 14:18:53 +0530512
513/**
514 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
515 * @target Device id of the targeted PU or subsystem
516 * @wkup_node Device id of the wakeup peripheral
517 * @enable Enable or disable the specified peripheral as wake source
Tejas Patel18072da2021-02-25 20:16:56 -0800518 * @flag 0 - Call from secure source
519 * 1 - Call from non-secure source
Tejas Pateldb812052019-01-23 14:18:53 +0530520 *
521 * @return Returns status, either success or error+reason
522 */
523enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
Tejas Patel18072da2021-02-25 20:16:56 -0800524 uint8_t enable, uint32_t flag)
Tejas Pateldb812052019-01-23 14:18:53 +0530525{
526 uint32_t payload[PAYLOAD_ARG_CNT];
527
Tejas Patel18072da2021-02-25 20:16:56 -0800528 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE,
529 target, wkup_device, enable);
Abhyuday Godhasara7ae761b2021-06-24 05:50:44 -0700530 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Tejas Pateldb812052019-01-23 14:18:53 +0530531}
Ravi Patel22b0b492019-03-06 12:34:46 +0530532
533/**
534 * pm_feature_check() - Returns the supported API version if supported
535 * @api_id API ID to check
Tejas Patel18072da2021-02-25 20:16:56 -0800536 * @flag 0 - Call from secure source
537 * 1 - Call from non-secure source
Ronak Jain70d1c582022-02-04 00:42:55 -0800538 * @ret_payload pointer to array of PAYLOAD_ARG_CNT number of
539 * words Returned supported API version and bitmasks
540 * for IOCTL and QUERY ID
Ravi Patel22b0b492019-03-06 12:34:46 +0530541 *
542 * @return Returns status, either success or error+reason
543 */
Ronak Jain70d1c582022-02-04 00:42:55 -0800544enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
Tejas Patel18072da2021-02-25 20:16:56 -0800545 uint32_t flag)
Ravi Patel22b0b492019-03-06 12:34:46 +0530546{
Ronak Jain70d1c582022-02-04 00:42:55 -0800547 uint32_t payload[PAYLOAD_ARG_CNT];
Tanmay Shahff34daa2021-08-09 11:00:41 -0700548 uint32_t module_id;
549
Ronak Jain70d1c582022-02-04 00:42:55 -0800550 /* Return version of API which are implemented in ATF only */
Ravi Patel22b0b492019-03-06 12:34:46 +0530551 switch (api_id) {
552 case PM_GET_CALLBACK_DATA:
553 case PM_GET_TRUSTZONE_VERSION:
Ronak Jain70d1c582022-02-04 00:42:55 -0800554 ret_payload[0] = PM_API_VERSION_2;
555 return PM_RET_SUCCESS;
Rajan Vajaad1ffff2021-01-20 00:53:45 -0800556 case PM_LOAD_PDI:
Ronak Jain70d1c582022-02-04 00:42:55 -0800557 ret_payload[0] = PM_API_BASE_VERSION;
Tanmay Shahff34daa2021-08-09 11:00:41 -0700558 return PM_RET_SUCCESS;
Ravi Patel22b0b492019-03-06 12:34:46 +0530559 default:
Abhyuday Godhasara95374b42021-08-05 07:07:35 -0700560 break;
561 }
562
Ronak Jain70d1c582022-02-04 00:42:55 -0800563 module_id = (api_id & MODULE_ID_MASK) >> 8;
Ravi Patel22b0b492019-03-06 12:34:46 +0530564
Ronak Jain70d1c582022-02-04 00:42:55 -0800565 /*
566 * feature check should be done only for LIBPM module
567 * If module_id is 0, then we consider it LIBPM module as default id
568 */
569 if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) {
570 return PM_RET_SUCCESS;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700571 }
Ravi Patel22b0b492019-03-06 12:34:46 +0530572
Ronak Jain70d1c582022-02-04 00:42:55 -0800573 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
574 PM_FEATURE_CHECK, api_id);
575 return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
Ravi Patel22b0b492019-03-06 12:34:46 +0530576}
Jolly Shahed05a712019-03-22 05:33:39 +0530577
578/**
579 * pm_load_pdi() - Load the PDI
580 *
581 * This function provides support to load PDI from linux
582 *
583 * src: Source device of pdi(DDR, OCM, SD etc)
584 * address_low: lower 32-bit Linear memory space address
585 * address_high: higher 32-bit Linear memory space address
Tejas Patel18072da2021-02-25 20:16:56 -0800586 * @flag 0 - Call from secure source
587 * 1 - Call from non-secure source
Jolly Shahed05a712019-03-22 05:33:39 +0530588 *
589 * @return Returns status, either success or error+reason
590 */
Tejas Patel18072da2021-02-25 20:16:56 -0800591enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
592 uint32_t address_high, uint32_t flag)
Jolly Shahed05a712019-03-22 05:33:39 +0530593{
594 uint32_t payload[PAYLOAD_ARG_CNT];
595
596 /* Send request to the PMU */
Tejas Patel18072da2021-02-25 20:16:56 -0800597 PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, flag, PM_LOAD_PDI, src,
Jolly Shahed05a712019-03-22 05:33:39 +0530598 address_high, address_low);
599 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
600}
Saeed Nowshadi2294b422019-06-03 10:22:35 -0700601
602/**
Tejas Patel42015552020-11-25 01:56:57 -0800603 * pm_register_notifier() - PM call to register a subsystem to be notified
604 * about the device event
605 * @device_id Device ID for the Node to which the event is related
606 * @event Event in question
607 * @wake Wake subsystem upon capturing the event if value 1
608 * @enable Enable the registration for value 1, disable for value 0
Tejas Patel18072da2021-02-25 20:16:56 -0800609 * @flag 0 - Call from secure source
610 * 1 - Call from non-secure source
Tejas Patel42015552020-11-25 01:56:57 -0800611 *
612 * @return Returns status, either success or error+reason
613 */
614enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
Tejas Patel18072da2021-02-25 20:16:56 -0800615 uint32_t wake, uint32_t enable,
616 uint32_t flag)
Tejas Patel42015552020-11-25 01:56:57 -0800617{
618 uint32_t payload[PAYLOAD_ARG_CNT];
619
620 /* Send request to the PMC */
Tejas Patel18072da2021-02-25 20:16:56 -0800621 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REGISTER_NOTIFIER,
Tejas Patel42015552020-11-25 01:56:57 -0800622 device_id, event, wake, enable);
623
624 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
625}