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