blob: 99897ba9de7ce19e03067ef0c04459bd3932ecc6 [file] [log] [blame]
Tejas Patel9d09ff92019-01-08 01:46:35 -08001/*
2 * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
3 *
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"
17
18/*********************************************************************
19 * Target module IDs macros
20 ********************************************************************/
21#define LIBPM_MODULE_ID 0x2
22#define LOADER_MODULE_ID 0x7
23
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -080024/* default shutdown/reboot scope is system(2) */
25static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
26
27/**
28 * pm_get_shutdown_scope() - Get the currently set shutdown scope
29 *
30 * @return Shutdown scope value
31 */
32unsigned int pm_get_shutdown_scope(void)
33{
34 return pm_shutdown_scope;
35}
36
Tejas Patel9d09ff92019-01-08 01:46:35 -080037/**
38 * Assigning of argument values into array elements.
39 */
40#define PM_PACK_PAYLOAD1(pl, mid, arg0) { \
41 pl[0] = (uint32_t)((uint32_t)((arg0) & 0xFF) | (mid << 8)); \
42}
43
Tejas Patelfe0e10a2019-12-08 23:29:44 -080044#define PM_PACK_PAYLOAD2(pl, mid, arg0, arg1) { \
45 pl[1] = (uint32_t)(arg1); \
46 PM_PACK_PAYLOAD1(pl, mid, arg0); \
47}
48
49#define PM_PACK_PAYLOAD3(pl, mid, arg0, arg1, arg2) { \
50 pl[2] = (uint32_t)(arg2); \
51 PM_PACK_PAYLOAD2(pl, mid, arg0, arg1); \
52}
53
54#define PM_PACK_PAYLOAD4(pl, mid, arg0, arg1, arg2, arg3) { \
55 pl[3] = (uint32_t)(arg3); \
56 PM_PACK_PAYLOAD3(pl, mid, arg0, arg1, arg2); \
57}
58
59#define PM_PACK_PAYLOAD5(pl, mid, arg0, arg1, arg2, arg3, arg4) { \
60 pl[4] = (uint32_t)(arg4); \
61 PM_PACK_PAYLOAD4(pl, mid, arg0, arg1, arg2, arg3); \
62}
63
64#define PM_PACK_PAYLOAD6(pl, mid, arg0, arg1, arg2, arg3, arg4, arg5) { \
65 pl[5] = (uint32_t)(arg5); \
66 PM_PACK_PAYLOAD5(pl, mid, arg0, arg1, arg2, arg3, arg4); \
67}
68
Tejas Patel9d09ff92019-01-08 01:46:35 -080069/* PM API functions */
70
71/**
72 * pm_get_api_version() - Get version number of PMC PM firmware
73 * @version Returns 32-bit version number of PMC Power Management Firmware
74 *
75 * @return Returns status, either success or error+reason
76 */
77enum pm_ret_status pm_get_api_version(unsigned int *version)
78{
79 uint32_t payload[PAYLOAD_ARG_CNT];
80
81 /* Send request to the PMC */
82 PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, PM_GET_API_VERSION);
83 return pm_ipi_send_sync(primary_proc, payload, version, 1);
84}
Tejas Patelfe0e10a2019-12-08 23:29:44 -080085
86/**
87 * pm_self_suspend() - PM call for processor to suspend itself
88 * @nid Node id of the processor or subsystem
89 * @latency Requested maximum wakeup latency (not supported)
90 * @state Requested state
91 * @address Resume address
92 *
93 * This is a blocking call, it will return only once PMU has responded.
94 * On a wakeup, resume address will be automatically set by PMU.
95 *
96 * @return Returns status, either success or error+reason
97 */
98enum pm_ret_status pm_self_suspend(uint32_t nid,
99 unsigned int latency,
100 unsigned int state,
101 uintptr_t address)
102{
103 uint32_t payload[PAYLOAD_ARG_CNT];
104 unsigned int cpuid = plat_my_core_pos();
105 const struct pm_proc *proc = pm_get_proc(cpuid);
106
107 if (!proc) {
108 WARN("Failed to get proc %d\n", cpuid);
109 return PM_RET_ERROR_INTERNAL;
110 }
111
112 /*
113 * Do client specific suspend operations
114 * (e.g. set powerdown request bit)
115 */
116 pm_client_suspend(proc, state);
117
118 /* Send request to the PLM */
119 PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, PM_SELF_SUSPEND,
120 proc->node_id, latency, state, address,
121 (address >> 32));
122 return pm_ipi_send_sync(proc, payload, NULL, 0);
123}
124
125/**
126 * pm_abort_suspend() - PM call to announce that a prior suspend request
127 * is to be aborted.
128 * @reason Reason for the abort
129 *
130 * Calling PU expects the PMU to abort the initiated suspend procedure.
131 * This is a non-blocking call without any acknowledge.
132 *
133 * @return Returns status, either success or error+reason
134 */
135enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
136{
137 uint32_t payload[PAYLOAD_ARG_CNT];
138
139 /*
140 * Do client specific abort suspend operations
141 * (e.g. enable interrupts and clear powerdown request bit)
142 */
143 pm_client_abort_suspend();
144
145 /* Send request to the PLM */
146 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_ABORT_SUSPEND, reason,
147 primary_proc->node_id);
148 return pm_ipi_send(primary_proc, payload);
149}
150
151/**
152 * pm_req_suspend() - PM call to request for another PU or subsystem to
153 * be suspended gracefully.
154 * @target Node id of the targeted PU or subsystem
155 * @ack Flag to specify whether acknowledge is requested
156 * @latency Requested wakeup latency (not supported)
157 * @state Requested state (not supported)
158 *
159 * @return Returns status, either success or error+reason
160 */
161enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
162 unsigned int latency, unsigned int state)
163{
164 uint32_t payload[PAYLOAD_ARG_CNT];
165
166 /* Send request to the PMU */
167 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, PM_REQ_SUSPEND, target,
168 latency, state);
169 if (ack == IPI_BLOCKING)
170 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
171 else
172 return pm_ipi_send(primary_proc, payload);
173}
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800174
175/**
Tejas Patel49cd8712019-01-23 14:18:51 +0530176 * pm_req_wakeup() - PM call for processor to wake up selected processor
177 * or subsystem
178 * @target Device ID of the processor or subsystem to wake up
179 * @set_address Resume address presence indicator
180 * 1 - resume address specified, 0 - otherwise
181 * @address Resume address
182 * @ack Flag to specify whether acknowledge requested
183 *
184 * This API function is either used to power up another APU core for SMP
185 * (by PSCI) or to power up an entirely different PU or subsystem, such
186 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
187 * automatically set by PMC.
188 *
189 * @return Returns status, either success or error+reason
190 */
191enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
192 uintptr_t address, uint8_t ack)
193{
194 uint32_t payload[PAYLOAD_ARG_CNT];
195
196 /* Send request to the PMC to perform the wake of the PU */
197 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_REQ_WAKEUP, target,
198 set_address, address, ack);
199
200 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
201}
202
203/**
Tejas Patel41f3e0b2019-01-08 01:46:37 -0800204 * pm_request_device() - Request a device
205 * @device_id Device ID
206 * @capabilities Requested capabilities for the device
207 * @qos Required Quality of Service
208 * @ack Flag to specify whether acknowledge requested
209 *
210 * @return Returns status, either success or error+reason
211 */
212enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
213 uint32_t qos, uint32_t ack)
214{
215 uint32_t payload[PAYLOAD_ARG_CNT];
216
217 /* Send request to the PMC */
218 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_REQUEST_DEVICE,
219 device_id, capabilities, qos, ack);
220
221 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
222}
223
224/**
225 * pm_release_device() - Release a device
226 * @device_id Device ID
227 *
228 * @return Returns status, either success or error+reason
229 */
230enum pm_ret_status pm_release_device(uint32_t device_id)
231{
232 uint32_t payload[PAYLOAD_ARG_CNT];
233
234 /* Send request to the PMC */
235 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_RELEASE_DEVICE,
236 device_id);
237
238 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
239}
240
241/**
242 * pm_set_requirement() - Set requirement for the device
243 * @device_id Device ID
244 * @capabilities Requested capabilities for the device
245 * @latency Requested maximum latency
246 * @qos Required Quality of Service
247 *
248 * @return Returns status, either success or error+reason
249 */
250enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
251 uint32_t latency, uint32_t qos)
252{
253 uint32_t payload[PAYLOAD_ARG_CNT];
254
255 /* Send request to the PMC */
256 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_SET_REQUIREMENT,
257 device_id, capabilities, latency, qos);
258
259 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
260}
261
262/**
263 * pm_get_device_status() - Get device's status
264 * @device_id Device ID
265 * @response Buffer to store device status response
266 *
267 * @return Returns status, either success or error+reason
268 */
269enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response)
270{
271 uint32_t payload[PAYLOAD_ARG_CNT];
272
273 /* Send request to the PMC */
274 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_GET_DEVICE_STATUS,
275 device_id);
276
277 return pm_ipi_send_sync(primary_proc, payload, response, 3);
278}
Tejas Patel87c4f3a2019-01-08 01:46:38 -0800279
280/**
281 * pm_reset_assert() - Assert/De-assert reset
282 * @reset Reset ID
283 * @assert Assert (1) or de-assert (0)
284 *
285 * @return Returns status, either success or error+reason
286 */
287enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert)
288{
289 uint32_t payload[PAYLOAD_ARG_CNT];
290
291 /* Send request to the PMC */
292 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_RESET_ASSERT, reset,
293 assert);
294
295 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
296}
297
298/**
299 * pm_reset_get_status() - Get current status of a reset line
300 * @reset Reset ID
301 * @status Returns current status of selected reset ID
302 *
303 * @return Returns status, either success or error+reason
304 */
305enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status)
306{
307 uint32_t payload[PAYLOAD_ARG_CNT];
308
309 /* Send request to the PMC */
310 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_RESET_ASSERT, reset);
311
312 return pm_ipi_send_sync(primary_proc, payload, status, 1);
313}
Tejas Patel20e92022019-01-08 01:46:39 -0800314
315/**
316 * pm_pinctrl_request() - Request a pin
317 * @pin Pin ID
318 *
319 * @return Returns status, either success or error+reason
320 */
321enum pm_ret_status pm_pinctrl_request(uint32_t pin)
322{
323 uint32_t payload[PAYLOAD_ARG_CNT];
324
325 /* Send request to the PMC */
326 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_PINCTRL_REQUEST, pin);
327
328 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
329}
330
331/**
332 * pm_pinctrl_release() - Release a pin
333 * @pin Pin ID
334 *
335 * @return Returns status, either success or error+reason
336 */
337enum pm_ret_status pm_pinctrl_release(uint32_t pin)
338{
339 uint32_t payload[PAYLOAD_ARG_CNT];
340
341 /* Send request to the PMC */
342 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_PINCTRL_RELEASE, pin);
343
344 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
345}
346
347/**
348 * pm_pinctrl_set_function() - Set pin function
349 * @pin Pin ID
350 * @function Function ID
351 *
352 * @return Returns status, either success or error+reason
353 */
354enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function)
355{
356 uint32_t payload[PAYLOAD_ARG_CNT];
357
358 /* Send request to the PMC */
359 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_PINCTRL_SET_FUNCTION, pin,
360 function)
361
362 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
363}
364
365/**
366 * pm_pinctrl_get_function() - Get function set on the pin
367 * @pin Pin ID
368 * @function Function set on the pin
369 *
370 * @return Returns status, either success or error+reason
371 */
372enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function)
373{
374 uint32_t payload[PAYLOAD_ARG_CNT];
375
376 /* Send request to the PMC */
377 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_PINCTRL_SET_FUNCTION,
378 pin);
379
380 return pm_ipi_send_sync(primary_proc, payload, function, 1);
381}
382
383/**
384 * pm_pinctrl_set_pin_param() - Set configuration parameter for the pin
385 * @pin Pin ID
386 * @param Parameter ID
387 * @value Parameter value
388 *
389 * @return Returns status, either success or error+reason
390 */
391enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
392 uint32_t value)
393{
394 uint32_t payload[PAYLOAD_ARG_CNT];
395
396 /* Send request to the PMC */
397 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, PM_PINCTRL_CONFIG_PARAM_SET,
398 pin, param, value);
399
400 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
401}
402
403/**
404 * pm_pinctrl_get_pin_param() - Get configuration parameter value for the pin
405 * @pin Pin ID
406 * @param Parameter ID
407 * @value Buffer to store parameter value
408 *
409 * @return Returns status, either success or error+reason
410 */
411enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
412 uint32_t *value)
413{
414 uint32_t payload[PAYLOAD_ARG_CNT];
415
416 /* Send request to the PMC */
417 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_PINCTRL_CONFIG_PARAM_GET,
418 pin, param);
419
420 return pm_ipi_send_sync(primary_proc, payload, value, 1);
421}
Tejas Patel1f56fb12019-01-08 01:46:40 -0800422
423/**
424 * pm_clock_enable() - Enable the clock
425 * @clk_id Clock ID
426 *
427 * @return Returns status, either success or error+reason
428 */
429enum pm_ret_status pm_clock_enable(uint32_t clk_id)
430{
431 uint32_t payload[PAYLOAD_ARG_CNT];
432
433 /* Send request to the PMC */
434 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_ENABLE, clk_id);
435
436 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
437}
438
439/**
440 * pm_clock_disable() - Disable the clock
441 * @clk_id Clock ID
442 *
443 * @return Returns status, either success or error+reason
444 */
445enum pm_ret_status pm_clock_disable(uint32_t clk_id)
446{
447 uint32_t payload[PAYLOAD_ARG_CNT];
448
449 /* Send request to the PMC */
450 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_DISABLE, clk_id);
451
452 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
453}
454
455/**
456 * pm_clock_get_state() - Get clock status
457 * @clk_id Clock ID
458 * @state: Buffer to store clock status (1: Enabled, 0:Disabled)
459 *
460 * @return Returns status, either success or error+reason
461 */
462enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state)
463{
464 uint32_t payload[PAYLOAD_ARG_CNT];
465
466 /* Send request to the PMC */
467 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_GETSTATE, clk_id);
468
469 return pm_ipi_send_sync(primary_proc, payload, state, 1);
470}
471
472/**
473 * pm_clock_set_divider() - Set divider for the clock
474 * @clk_id Clock ID
475 * @divider Divider value
476 *
477 * @return Returns status, either success or error+reason
478 */
479enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider)
480{
481 uint32_t payload[PAYLOAD_ARG_CNT];
482
483 /* Send request to the PMC */
484 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_CLOCK_SETDIVIDER, clk_id,
485 divider);
486
487 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
488}
489
490/**
491 * pm_clock_get_divider() - Get divider value for the clock
492 * @clk_id Clock ID
493 * @divider: Buffer to store clock divider value
494 *
495 * @return Returns status, either success or error+reason
496 */
497enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider)
498{
499 uint32_t payload[PAYLOAD_ARG_CNT];
500
501 /* Send request to the PMC */
502 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_GETDIVIDER, clk_id);
503
504 return pm_ipi_send_sync(primary_proc, payload, divider, 1);
505}
506
507/**
508 * pm_clock_set_parent() - Set parent for the clock
509 * @clk_id Clock ID
510 * @parent Parent ID
511 *
512 * @return Returns status, either success or error+reason
513 */
514enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent)
515{
516 uint32_t payload[PAYLOAD_ARG_CNT];
517
518 /* Send request to the PMC */
519 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_CLOCK_SETPARENT, clk_id,
520 parent);
521
522 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
523}
524
525/**
526 * pm_clock_get_parent() - Get parent value for the clock
527 * @clk_id Clock ID
528 * @parent: Buffer to store clock parent value
529 *
530 * @return Returns status, either success or error+reason
531 */
532enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent)
533{
534 uint32_t payload[PAYLOAD_ARG_CNT];
535
536 /* Send request to the PMC */
537 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_GETPARENT, clk_id);
538
539 return pm_ipi_send_sync(primary_proc, payload, parent, 1);
540}
Tejas Patel023116d2019-01-08 01:46:41 -0800541
542/**
543 * pm_pll_set_param() - Set PLL parameter
544 * @clk_id PLL clock ID
545 * @param PLL parameter ID
546 * @value Value to set for PLL parameter
547 *
548 * @return Returns status, either success or error+reason
549 */
550enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
551 uint32_t value)
552{
553 uint32_t payload[PAYLOAD_ARG_CNT];
554
555 /* Send request to the PMC */
556 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, PM_PLL_SET_PARAMETER, clk_id,
557 param, value);
558
559 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
560}
561
562/**
563 * pm_pll_get_param() - Get PLL parameter value
564 * @clk_id PLL clock ID
565 * @param PLL parameter ID
566 * @value: Buffer to store PLL parameter value
567 *
568 * @return Returns status, either success or error+reason
569 */
570enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
571 uint32_t *value)
572{
573 uint32_t payload[PAYLOAD_ARG_CNT];
574
575 /* Send request to the PMC */
576 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_PLL_GET_PARAMETER, clk_id,
577 param);
578
579 return pm_ipi_send_sync(primary_proc, payload, value, 1);
580}
581
582/**
583 * pm_pll_set_mode() - Set PLL mode
584 * @clk_id PLL clock ID
585 * @mode PLL mode
586 *
587 * @return Returns status, either success or error+reason
588 */
589enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode)
590{
591 uint32_t payload[PAYLOAD_ARG_CNT];
592
593 /* Send request to the PMC */
594 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_PLL_SET_MODE, clk_id,
595 mode);
596
597 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
598}
599
600/**
601 * pm_pll_get_mode() - Get PLL mode
602 * @clk_id PLL clock ID
603 * @mode: Buffer to store PLL mode
604 *
605 * @return Returns status, either success or error+reason
606 */
607enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode)
608{
609 uint32_t payload[PAYLOAD_ARG_CNT];
610
611 /* Send request to the PMC */
612 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_PLL_GET_MODE, clk_id);
613
614 return pm_ipi_send_sync(primary_proc, payload, mode, 1);
615}
Tejas Patel6b282252019-01-10 03:03:47 -0800616
617/**
618 * pm_force_powerdown() - PM call to request for another PU or subsystem to
619 * be powered down forcefully
620 * @target Device ID of the PU node to be forced powered down.
621 * @ack Flag to specify whether acknowledge is requested
622 *
623 * @return Returns status, either success or error+reason
624 */
625enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack)
626{
627 uint32_t payload[PAYLOAD_ARG_CNT];
628
629 /* Send request to the PMC */
630 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_FORCE_POWERDOWN, target,
631 ack);
632
633 if (ack == IPI_BLOCKING)
634 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
635 else
636 return pm_ipi_send(primary_proc, payload);
637}
638
639/**
640 * pm_system_shutdown() - PM call to request a system shutdown or restart
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -0800641 * @type Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
Tejas Patel6b282252019-01-10 03:03:47 -0800642 * @subtype Scope: 0=APU-subsystem, 1=PS, 2=system
643 *
644 * @return Returns status, either success or error+reason
645 */
646enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
647{
648 uint32_t payload[PAYLOAD_ARG_CNT];
649
Saeed Nowshadic5a1bda2019-12-08 23:35:35 -0800650 if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
651 /* Setting scope for subsequent PSCI reboot or shutdown */
652 pm_shutdown_scope = subtype;
653 return PM_RET_SUCCESS;
654 }
655
Tejas Patel6b282252019-01-10 03:03:47 -0800656 /* Send request to the PMC */
657 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_SYSTEM_SHUTDOWN, type,
658 subtype);
659
660 return pm_ipi_send_non_blocking(primary_proc, payload);
661}
Tejas Patel9141f442019-01-10 03:03:48 -0800662
663/**
Tejas Patela3e34ad2019-02-01 17:25:19 +0530664* pm_query_data() - PM API for querying firmware data
665* @qid The type of data to query
666* @arg1 Argument 1 to requested query data call
667* @arg2 Argument 2 to requested query data call
668* @arg3 Argument 3 to requested query data call
669* @data Returned output data
670*
671* This function returns requested data.
672*/
673enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
674 uint32_t arg3, uint32_t *data)
675{
676 uint32_t payload[PAYLOAD_ARG_CNT];
677
678 /* Send request to the PMC */
679 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_QUERY_DATA, qid, arg1,
680 arg2, arg3);
681 return pm_ipi_send_sync(primary_proc, payload, data, 4);
682}
683/**
Tejas Patel9141f442019-01-10 03:03:48 -0800684 * pm_api_ioctl() - PM IOCTL API for device control and configs
685 * @device_id Device ID
686 * @ioctl_id ID of the requested IOCTL
687 * @arg1 Argument 1 to requested IOCTL call
688 * @arg2 Argument 2 to requested IOCTL call
689 * @value Returned output value
690 *
691 * This function calls IOCTL to firmware for device control and configuration.
692 *
693 * @return Returns status, either success or error+reason
694 */
695enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
696 uint32_t arg1, uint32_t arg2, uint32_t *value)
697{
698 uint32_t payload[PAYLOAD_ARG_CNT];
699
700 switch (ioctl_id) {
701 case IOCTL_SET_PLL_FRAC_MODE:
702 return pm_pll_set_mode(arg1, arg2);
703 case IOCTL_GET_PLL_FRAC_MODE:
704 return pm_pll_get_mode(arg1, value);
705 case IOCTL_SET_PLL_FRAC_DATA:
706 return pm_pll_set_param(arg1, PM_PLL_PARAM_DATA, arg2);
707 case IOCTL_GET_PLL_FRAC_DATA:
708 return pm_pll_get_param(arg1, PM_PLL_PARAM_DATA, value);
709 default:
710 /* Send request to the PMC */
711 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_IOCTL, device_id,
712 ioctl_id, arg1, arg2);
713 return pm_ipi_send_sync(primary_proc, payload, value, 1);
714 }
715}
Tejas Pateldb812052019-01-23 14:18:53 +0530716
717/**
718 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
719 * @target Device id of the targeted PU or subsystem
720 * @wkup_node Device id of the wakeup peripheral
721 * @enable Enable or disable the specified peripheral as wake source
722 *
723 * @return Returns status, either success or error+reason
724 */
725enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
726 uint8_t enable)
727{
728 uint32_t payload[PAYLOAD_ARG_CNT];
729
730 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, PM_SET_WAKEUP_SOURCE, target,
731 wkup_device, enable);
732 return pm_ipi_send(primary_proc, payload);
733}