1 /*
2 * Copyright (c) 2019-2020, 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>
14 #include <plat/common/platform.h>
15 #include "pm_api_sys.h"
16 #include "pm_client.h"
17 #include "pm_defs.h"
18 #include "pm_svc_main.h"
19 #include "../drivers/arm/gic/v3/gicv3_private.h"
20
21 /*********************************************************************
22 * Target module IDs macros
23 ********************************************************************/
24 #define LIBPM_MODULE_ID 0x2
25 #define LOADER_MODULE_ID 0x7
26
27 #define MODE 0x80000000
28 /* default shutdown/reboot scope is system(2) */
29 static 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 */
pm_get_shutdown_scope(void)36 unsigned int pm_get_shutdown_scope(void)
37 {
38 return pm_shutdown_scope;
39 }
40
41 /**
42 * Assigning of argument values into array elements.
43 */
44 #define PM_PACK_PAYLOAD1(pl, mid, flag, arg0) { \
45 pl[0] = (uint32_t)((uint32_t)((arg0) & 0xFF) | (mid << 8) | ((flag) << 24)); \
46 }
47
48 #define PM_PACK_PAYLOAD2(pl, mid, flag, arg0, arg1) { \
49 pl[1] = (uint32_t)(arg1); \
50 PM_PACK_PAYLOAD1(pl, mid, flag, arg0); \
51 }
52
53 #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); \
56 }
57
58 #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); \
61 }
62
63 #define PM_PACK_PAYLOAD5(pl, mid, flag, arg0, arg1, arg2, arg3, arg4) { \
64 pl[4] = (uint32_t)(arg4); \
65 PM_PACK_PAYLOAD4(pl, mid, flag, arg0, arg1, arg2, arg3); \
66 }
67
68 #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); \
71 }
72
73 /* 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
78 * @flag 0 - Call from secure source
79 * 1 - Call from non-secure source
80 *
81 * @return Returns status, either success or error+reason
82 */
pm_get_api_version(unsigned int * version,uint32_t flag)83 enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag)
84 {
85 uint32_t payload[PAYLOAD_ARG_CNT];
86
87 /* Send request to the PMC */
88 PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_API_VERSION);
89 return pm_ipi_send_sync(primary_proc, payload, version, 1);
90 }
91
92 /**
93 * pm_init_finalize() - Call to notify PMC PM firmware that master has power
94 * management enabled and that it has finished its
95 * initialization
96 * @flag 0 - Call from secure source
97 * 1 - Call from non-secure source
98 *
99 * @return Status returned by the PMU firmware
100 */
pm_init_finalize(uint32_t flag)101 enum pm_ret_status pm_init_finalize(uint32_t flag)
102 {
103 uint32_t payload[PAYLOAD_ARG_CNT];
104
105 /* Send request to the PMU */
106 PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_INIT_FINALIZE);
107 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
108 }
109
110 /**
111 * 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
116 * @flag 0 - Call from secure source
117 * 1 - Call from non-secure source
118 *
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 */
pm_self_suspend(uint32_t nid,unsigned int latency,unsigned int state,uintptr_t address,uint32_t flag)124 enum pm_ret_status pm_self_suspend(uint32_t nid,
125 unsigned int latency,
126 unsigned int state,
127 uintptr_t address, uint32_t flag)
128 {
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 */
145 PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, flag, PM_SELF_SUSPEND,
146 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
155 * @flag 0 - Call from secure source
156 * 1 - Call from non-secure source
157 *
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 */
pm_abort_suspend(enum pm_abort_reason reason,uint32_t flag)163 enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag)
164 {
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 */
174 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_ABORT_SUSPEND,
175 reason, primary_proc->node_id);
176 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
177 }
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)
186 * @flag 0 - Call from secure source
187 * 1 - Call from non-secure source
188 *
189 * @return Returns status, either success or error+reason
190 */
pm_req_suspend(uint32_t target,uint8_t ack,unsigned int latency,unsigned int state,uint32_t flag)191 enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
192 unsigned int latency, unsigned int state,
193 uint32_t flag)
194 {
195 uint32_t payload[PAYLOAD_ARG_CNT];
196
197 /* Send request to the PMU */
198 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_REQ_SUSPEND, target,
199 latency, state);
200 if (ack == IPI_BLOCKING)
201 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
202 else
203 return pm_ipi_send(primary_proc, payload);
204 }
205
206 /**
207 * pm_req_wakeup() - PM call for processor to wake up selected processor
208 * or subsystem
209 * @target Device ID of the processor or subsystem to wake up
210 * @set_address Resume address presence indicator
211 * 1 - resume address specified, 0 - otherwise
212 * @address Resume address
213 * @ack Flag to specify whether acknowledge requested
214 * @flag 0 - Call from secure source
215 * 1 - Call from non-secure source
216 *
217 * This API function is either used to power up another APU core for SMP
218 * (by PSCI) or to power up an entirely different PU or subsystem, such
219 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
220 * automatically set by PMC.
221 *
222 * @return Returns status, either success or error+reason
223 */
pm_req_wakeup(uint32_t target,uint32_t set_address,uintptr_t address,uint8_t ack,uint32_t flag)224 enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
225 uintptr_t address, uint8_t ack, uint32_t flag)
226 {
227 uint32_t payload[PAYLOAD_ARG_CNT];
228
229 /* Send request to the PMC to perform the wake of the PU */
230 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQ_WAKEUP, target,
231 set_address, address, ack);
232
233 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
234 }
235
236 /**
237 * pm_request_device() - Request a device
238 * @device_id Device ID
239 * @capabilities Requested capabilities for the device
240 * @qos Required Quality of Service
241 * @ack Flag to specify whether acknowledge requested
242 * @flag 0 - Call from secure source
243 * 1 - Call from non-secure source
244 *
245 * @return Returns status, either success or error+reason
246 */
pm_request_device(uint32_t device_id,uint32_t capabilities,uint32_t qos,uint32_t ack,uint32_t flag)247 enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
248 uint32_t qos, uint32_t ack, uint32_t flag)
249 {
250 uint32_t payload[PAYLOAD_ARG_CNT];
251
252 /* Send request to the PMC */
253 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQUEST_DEVICE,
254 device_id, capabilities, qos, ack);
255
256 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
257 }
258
259 /**
260 * pm_release_device() - Release a device
261 * @device_id Device ID
262 * @flag 0 - Call from secure source
263 * 1 - Call from non-secure source
264 *
265 * @return Returns status, either success or error+reason
266 */
pm_release_device(uint32_t device_id,uint32_t flag)267 enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag)
268 {
269 uint32_t payload[PAYLOAD_ARG_CNT];
270
271 /* Send request to the PMC */
272 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RELEASE_DEVICE,
273 device_id);
274
275 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
276 }
277
278 /**
279 * pm_set_requirement() - Set requirement for the device
280 * @device_id Device ID
281 * @capabilities Requested capabilities for the device
282 * @latency Requested maximum latency
283 * @qos Required Quality of Service
284 * @flag 0 - Call from secure source
285 * 1 - Call from non-secure source
286 *
287 * @return Returns status, either success or error+reason
288 */
pm_set_requirement(uint32_t device_id,uint32_t capabilities,uint32_t latency,uint32_t qos,uint32_t flag)289 enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
290 uint32_t latency, uint32_t qos,
291 uint32_t flag)
292 {
293 uint32_t payload[PAYLOAD_ARG_CNT];
294
295 /* Send request to the PMC */
296 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_SET_REQUIREMENT,
297 device_id, capabilities, latency, qos);
298
299 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
300 }
301
302 /**
303 * pm_get_device_status() - Get device's status
304 * @device_id Device ID
305 * @response Buffer to store device status response
306 * @flag 0 - Call from secure source
307 * 1 - Call from non-secure source
308 *
309 * @return Returns status, either success or error+reason
310 */
pm_get_device_status(uint32_t device_id,uint32_t * response,uint32_t flag)311 enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
312 uint32_t flag)
313 {
314 uint32_t payload[PAYLOAD_ARG_CNT];
315
316 /* Send request to the PMC */
317 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_GET_DEVICE_STATUS,
318 device_id);
319
320 return pm_ipi_send_sync(primary_proc, payload, response, 3);
321 }
322
323 /**
324 * pm_reset_assert() - Assert/De-assert reset
325 * @reset Reset ID
326 * @assert Assert (1) or de-assert (0)
327 * @flag 0 - Call from secure source
328 * 1 - Call from non-secure source
329 *
330 * @return Returns status, either success or error+reason
331 */
pm_reset_assert(uint32_t reset,bool assert,uint32_t flag)332 enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag)
333 {
334 uint32_t payload[PAYLOAD_ARG_CNT];
335
336 /* Send request to the PMC */
337 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT, reset,
338 assert);
339
340 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
341 }
342
343 /**
344 * pm_reset_get_status() - Get current status of a reset line
345 * @reset Reset ID
346 * @status Returns current status of selected reset ID
347 * @flag 0 - Call from secure source
348 * 1 - Call from non-secure source
349 *
350 * @return Returns status, either success or error+reason
351 */
pm_reset_get_status(uint32_t reset,uint32_t * status,uint32_t flag)352 enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
353 uint32_t flag)
354 {
355 uint32_t payload[PAYLOAD_ARG_CNT];
356
357 /* Send request to the PMC */
358 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT,
359 reset);
360
361 return pm_ipi_send_sync(primary_proc, payload, status, 1);
362 }
363
364 /**
365 * pm_get_callbackdata() - Read from IPI response buffer
366 * @data - array of PAYLOAD_ARG_CNT elements
367 * @flag - 0 - Call from secure source
368 * 1 - Call from non-secure source
369 *
370 * Read value from ipi buffer response buffer.
371 */
pm_get_callbackdata(uint32_t * data,size_t count,uint32_t flag)372 void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag)
373 {
374 /* Return if interrupt is not from PMU */
375 if (!pm_ipi_irq_status(primary_proc))
376 return;
377
378 pm_ipi_buff_read_callb(data, count);
379 pm_ipi_irq_clear(primary_proc);
380 }
381
382 /**
383 * pm_pinctrl_request() - Request a pin
384 * @pin Pin ID
385 * @flag 0 - Call from secure source
386 * 1 - Call from non-secure source
387 *
388 * @return Returns status, either success or error+reason
389 */
pm_pinctrl_request(uint32_t pin,uint32_t flag)390 enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag)
391 {
392 uint32_t payload[PAYLOAD_ARG_CNT];
393
394 /* Send request to the PMC */
395 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_REQUEST,
396 pin);
397
398 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
399 }
400
401 /**
402 * pm_pinctrl_release() - Release a pin
403 * @pin Pin ID
404 * @flag 0 - Call from secure source
405 * 1 - Call from non-secure source
406 *
407 * @return Returns status, either success or error+reason
408 */
pm_pinctrl_release(uint32_t pin,uint32_t flag)409 enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag)
410 {
411 uint32_t payload[PAYLOAD_ARG_CNT];
412
413 /* Send request to the PMC */
414 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_RELEASE,
415 pin);
416
417 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
418 }
419
420 /**
421 * pm_pinctrl_set_function() - Set pin function
422 * @pin Pin ID
423 * @function Function ID
424 * @flag 0 - Call from secure source
425 * 1 - Call from non-secure source
426 *
427 * @return Returns status, either success or error+reason
428 */
pm_pinctrl_set_function(uint32_t pin,uint32_t function,uint32_t flag)429 enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
430 uint32_t flag)
431 {
432 uint32_t payload[PAYLOAD_ARG_CNT];
433
434 /* Send request to the PMC */
435 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
436 PM_PINCTRL_SET_FUNCTION, pin, function)
437
438 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
439 }
440
441 /**
442 * pm_pinctrl_get_function() - Get function set on the pin
443 * @pin Pin ID
444 * @function Function set on the pin
445 * @flag 0 - Call from secure source
446 * 1 - Call from non-secure source
447 *
448 * @return Returns status, either success or error+reason
449 */
pm_pinctrl_get_function(uint32_t pin,uint32_t * function,uint32_t flag)450 enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
451 uint32_t flag)
452 {
453 uint32_t payload[PAYLOAD_ARG_CNT];
454
455 /* Send request to the PMC */
456 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
457 PM_PINCTRL_SET_FUNCTION, pin);
458
459 return pm_ipi_send_sync(primary_proc, payload, function, 1);
460 }
461
462 /**
463 * pm_pinctrl_set_pin_param() - Set configuration parameter for the pin
464 * @pin Pin ID
465 * @param Parameter ID
466 * @value Parameter value
467 * @flag 0 - Call from secure source
468 * 1 - Call from non-secure source
469 *
470 * @return Returns status, either success or error+reason
471 */
pm_pinctrl_set_pin_param(uint32_t pin,uint32_t param,uint32_t value,uint32_t flag)472 enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
473 uint32_t value, uint32_t flag)
474 {
475 uint32_t payload[PAYLOAD_ARG_CNT];
476
477 /* Send request to the PMC */
478 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag,
479 PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value);
480
481 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
482 }
483
484 /**
485 * pm_pinctrl_get_pin_param() - Get configuration parameter value for the pin
486 * @pin Pin ID
487 * @param Parameter ID
488 * @value Buffer to store parameter value
489 * @flag 0 - Call from secure source
490 * 1 - Call from non-secure source
491 *
492 * @return Returns status, either success or error+reason
493 */
pm_pinctrl_get_pin_param(uint32_t pin,uint32_t param,uint32_t * value,uint32_t flag)494 enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
495 uint32_t *value, uint32_t flag)
496 {
497 uint32_t payload[PAYLOAD_ARG_CNT];
498
499 /* Send request to the PMC */
500 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
501 PM_PINCTRL_CONFIG_PARAM_GET, pin, param);
502
503 return pm_ipi_send_sync(primary_proc, payload, value, 1);
504 }
505
506 /**
507 * pm_clock_enable() - Enable the clock
508 * @clk_id Clock ID
509 * @flag 0 - Call from secure source
510 * 1 - Call from non-secure source
511 *
512 * @return Returns status, either success or error+reason
513 */
pm_clock_enable(uint32_t clk_id,uint32_t flag)514 enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag)
515 {
516 uint32_t payload[PAYLOAD_ARG_CNT];
517
518 /* Send request to the PMC */
519 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_ENABLE,
520 clk_id);
521
522 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
523 }
524
525 /**
526 * pm_clock_disable() - Disable the clock
527 * @clk_id Clock ID
528 * @flag 0 - Call from secure source
529 * 1 - Call from non-secure source
530 *
531 * @return Returns status, either success or error+reason
532 */
pm_clock_disable(uint32_t clk_id,uint32_t flag)533 enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag)
534 {
535 uint32_t payload[PAYLOAD_ARG_CNT];
536
537 /* Send request to the PMC */
538 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_DISABLE,
539 clk_id);
540
541 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
542 }
543
544 /**
545 * pm_clock_get_state() - Get clock status
546 * @clk_id Clock ID
547 * @state: Buffer to store clock status (1: Enabled, 0:Disabled)
548 * @flag 0 - Call from secure source
549 * 1 - Call from non-secure source
550 *
551 * @return Returns status, either success or error+reason
552 */
pm_clock_get_state(uint32_t clk_id,uint32_t * state,uint32_t flag)553 enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
554 uint32_t flag)
555 {
556 uint32_t payload[PAYLOAD_ARG_CNT];
557
558 /* Send request to the PMC */
559 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETSTATE,
560 clk_id);
561
562 return pm_ipi_send_sync(primary_proc, payload, state, 1);
563 }
564
565 /**
566 * pm_clock_set_divider() - Set divider for the clock
567 * @clk_id Clock ID
568 * @divider Divider value
569 * @flag 0 - Call from secure source
570 * 1 - Call from non-secure source
571 *
572 * @return Returns status, either success or error+reason
573 */
pm_clock_set_divider(uint32_t clk_id,uint32_t divider,uint32_t flag)574 enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
575 uint32_t flag)
576 {
577 uint32_t payload[PAYLOAD_ARG_CNT];
578
579 /* Send request to the PMC */
580 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETDIVIDER,
581 clk_id, divider);
582
583 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
584 }
585
586 /**
587 * pm_clock_get_divider() - Get divider value for the clock
588 * @clk_id Clock ID
589 * @divider: Buffer to store clock divider value
590 * @flag 0 - Call from secure source
591 * 1 - Call from non-secure source
592 *
593 * @return Returns status, either success or error+reason
594 */
pm_clock_get_divider(uint32_t clk_id,uint32_t * divider,uint32_t flag)595 enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
596 uint32_t flag)
597 {
598 uint32_t payload[PAYLOAD_ARG_CNT];
599
600 /* Send request to the PMC */
601 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETDIVIDER,
602 clk_id);
603
604 return pm_ipi_send_sync(primary_proc, payload, divider, 1);
605 }
606
607 /**
608 * pm_clock_set_parent() - Set parent for the clock
609 * @clk_id Clock ID
610 * @parent Parent ID
611 * @flag 0 - Call from secure source
612 * 1 - Call from non-secure source
613 *
614 * @return Returns status, either success or error+reason
615 */
pm_clock_set_parent(uint32_t clk_id,uint32_t parent,uint32_t flag)616 enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
617 uint32_t flag)
618 {
619 uint32_t payload[PAYLOAD_ARG_CNT];
620
621 /* Send request to the PMC */
622 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETPARENT,
623 clk_id, parent);
624
625 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
626 }
627
628 /**
629 * pm_clock_get_parent() - Get parent value for the clock
630 * @clk_id Clock ID
631 * @parent: Buffer to store clock parent value
632 * @flag 0 - Call from secure source
633 * 1 - Call from non-secure source
634 *
635 * @return Returns status, either success or error+reason
636 */
pm_clock_get_parent(uint32_t clk_id,uint32_t * parent,uint32_t flag)637 enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
638 uint32_t flag)
639 {
640 uint32_t payload[PAYLOAD_ARG_CNT];
641
642 /* Send request to the PMC */
643 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETPARENT,
644 clk_id);
645
646 return pm_ipi_send_sync(primary_proc, payload, parent, 1);
647 }
648 /**
649 * pm_clock_get_rate() - Get the rate value for the clock
650 * @clk_id Clock ID
651 * @rate: Buffer to store clock rate value
652 * @flag 0 - Call from secure source
653 * 1 - Call from non-secure source
654 *
655 * @return Returns status, either success or error+reason
656 */
pm_clock_get_rate(uint32_t clk_id,uint32_t * clk_rate,uint32_t flag)657 enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
658 uint32_t flag)
659 {
660 uint32_t payload[PAYLOAD_ARG_CNT];
661
662 /* Send request to the PMC */
663 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETRATE,
664 clk_id);
665
666 return pm_ipi_send_sync(primary_proc, payload, clk_rate, 2);
667 }
668
669 /**
670 * pm_pll_set_param() - Set PLL parameter
671 * @clk_id PLL clock ID
672 * @param PLL parameter ID
673 * @value Value to set for PLL parameter
674 * @flag 0 - Call from secure source
675 * 1 - Call from non-secure source
676 *
677 * @return Returns status, either success or error+reason
678 */
pm_pll_set_param(uint32_t clk_id,uint32_t param,uint32_t value,uint32_t flag)679 enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
680 uint32_t value, uint32_t flag)
681 {
682 uint32_t payload[PAYLOAD_ARG_CNT];
683
684 /* Send request to the PMC */
685 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
686 clk_id, param, value);
687
688 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
689 }
690
691 /**
692 * pm_pll_get_param() - Get PLL parameter value
693 * @clk_id PLL clock ID
694 * @param PLL parameter ID
695 * @value: Buffer to store PLL parameter value
696 * @flag 0 - Call from secure source
697 * 1 - Call from non-secure source
698 *
699 * @return Returns status, either success or error+reason
700 */
pm_pll_get_param(uint32_t clk_id,uint32_t param,uint32_t * value,uint32_t flag)701 enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
702 uint32_t *value, uint32_t flag)
703 {
704 uint32_t payload[PAYLOAD_ARG_CNT];
705
706 /* Send request to the PMC */
707 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
708 clk_id, param);
709
710 return pm_ipi_send_sync(primary_proc, payload, value, 1);
711 }
712
713 /**
714 * pm_pll_set_mode() - Set PLL mode
715 * @clk_id PLL clock ID
716 * @mode PLL mode
717 * @flag 0 - Call from secure source
718 * 1 - Call from non-secure source
719 *
720 * @return Returns status, either success or error+reason
721 */
pm_pll_set_mode(uint32_t clk_id,uint32_t mode,uint32_t flag)722 enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
723 uint32_t flag)
724 {
725 uint32_t payload[PAYLOAD_ARG_CNT];
726
727 /* Send request to the PMC */
728 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
729 clk_id, mode);
730
731 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
732 }
733
734 /**
735 * pm_pll_get_mode() - Get PLL mode
736 * @clk_id PLL clock ID
737 * @mode: Buffer to store PLL mode
738 * @flag 0 - Call from secure source
739 * 1 - Call from non-secure source
740 *
741 * @return Returns status, either success or error+reason
742 */
pm_pll_get_mode(uint32_t clk_id,uint32_t * mode,uint32_t flag)743 enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
744 uint32_t flag)
745 {
746 uint32_t payload[PAYLOAD_ARG_CNT];
747
748 /* Send request to the PMC */
749 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
750 clk_id);
751
752 return pm_ipi_send_sync(primary_proc, payload, mode, 1);
753 }
754
755 /**
756 * pm_force_powerdown() - PM call to request for another PU or subsystem to
757 * be powered down forcefully
758 * @target Device ID of the PU node to be forced powered down.
759 * @ack Flag to specify whether acknowledge is requested
760 * @flag 0 - Call from secure source
761 * 1 - Call from non-secure source
762 *
763 * @return Returns status, either success or error+reason
764 */
pm_force_powerdown(uint32_t target,uint8_t ack,uint32_t flag)765 enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
766 uint32_t flag)
767 {
768 uint32_t payload[PAYLOAD_ARG_CNT];
769
770 /* Send request to the PMC */
771 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN,
772 target, ack);
773
774 if (ack == IPI_BLOCKING)
775 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
776 else
777 return pm_ipi_send(primary_proc, payload);
778 }
779
780 /**
781 * pm_system_shutdown() - PM call to request a system shutdown or restart
782 * @type Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
783 * @subtype Scope: 0=APU-subsystem, 1=PS, 2=system
784 * @flag 0 - Call from secure source
785 * 1 - Call from non-secure source
786 *
787 * @return Returns status, either success or error+reason
788 */
pm_system_shutdown(uint32_t type,uint32_t subtype,uint32_t flag)789 enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
790 uint32_t flag)
791 {
792 uint32_t payload[PAYLOAD_ARG_CNT];
793
794 if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
795 /* Setting scope for subsequent PSCI reboot or shutdown */
796 pm_shutdown_scope = subtype;
797 return PM_RET_SUCCESS;
798 }
799
800 /* Send request to the PMC */
801 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SYSTEM_SHUTDOWN,
802 type, subtype);
803
804 return pm_ipi_send_non_blocking(primary_proc, payload);
805 }
806
807 /**
808 * pm_query_data() - PM API for querying firmware data
809 * @qid The type of data to query
810 * @arg1 Argument 1 to requested query data call
811 * @arg2 Argument 2 to requested query data call
812 * @arg3 Argument 3 to requested query data call
813 * @data Returned output data
814 * @flag 0 - Call from secure source
815 * 1 - Call from non-secure source
816 *
817 * This function returns requested data.
818 */
pm_query_data(uint32_t qid,uint32_t arg1,uint32_t arg2,uint32_t arg3,uint32_t * data,uint32_t flag)819 enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
820 uint32_t arg3, uint32_t *data, uint32_t flag)
821 {
822 uint32_t ret;
823 uint32_t version;
824 uint32_t payload[PAYLOAD_ARG_CNT];
825 uint32_t fw_api_version;
826
827 /* Send request to the PMC */
828 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
829 arg1, arg2, arg3);
830
831 ret = pm_feature_check(PM_QUERY_DATA, &version, flag);
832 if (PM_RET_SUCCESS == ret) {
833 fw_api_version = version & 0xFFFF ;
834 if ((2U == fw_api_version) &&
835 ((XPM_QID_CLOCK_GET_NAME == qid) ||
836 (XPM_QID_PINCTRL_GET_FUNCTION_NAME == qid))) {
837 ret = pm_ipi_send_sync(primary_proc, payload, data, 8);
838 ret = data[0];
839 data[0] = data[1];
840 data[1] = data[2];
841 data[2] = data[3];
842 } else {
843 ret = pm_ipi_send_sync(primary_proc, payload, data, 4);
844 }
845 }
846 return ret;
847 }
848 /**
849 * pm_api_ioctl() - PM IOCTL API for device control and configs
850 * @device_id Device ID
851 * @ioctl_id ID of the requested IOCTL
852 * @arg1 Argument 1 to requested IOCTL call
853 * @arg2 Argument 2 to requested IOCTL call
854 * @value Returned output value
855 * @flag 0 - Call from secure source
856 * 1 - Call from non-secure source
857 *
858 * This function calls IOCTL to firmware for device control and configuration.
859 *
860 * @return Returns status, either success or error+reason
861 */
pm_api_ioctl(uint32_t device_id,uint32_t ioctl_id,uint32_t arg1,uint32_t arg2,uint32_t * value,uint32_t flag)862 enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
863 uint32_t arg1, uint32_t arg2, uint32_t *value,
864 uint32_t flag)
865 {
866 uint32_t payload[PAYLOAD_ARG_CNT];
867 int ret;
868
869 switch (ioctl_id) {
870 case IOCTL_SET_PLL_FRAC_MODE:
871 return pm_pll_set_mode(arg1, arg2, flag);
872 case IOCTL_GET_PLL_FRAC_MODE:
873 return pm_pll_get_mode(arg1, value, flag);
874 case IOCTL_SET_PLL_FRAC_DATA:
875 return pm_pll_set_param(arg1, PM_PLL_PARAM_DATA, arg2, flag);
876 case IOCTL_GET_PLL_FRAC_DATA:
877 return pm_pll_get_param(arg1, PM_PLL_PARAM_DATA, value, flag);
878 case IOCTL_SET_SGI:
879 /* Get the sgi number */
880 ret = pm_register_sgi(arg1);
881 if (ret) {
882 return PM_RET_ERROR_ARGS;
883 }
884 gicd_write_irouter(gicv3_driver_data->gicd_base,
885 PLAT_VERSAL_IPI_IRQ, MODE);
886 return PM_RET_SUCCESS;
887 default:
888 /* Send request to the PMC */
889 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_IOCTL,
890 device_id, ioctl_id, arg1, arg2);
891 return pm_ipi_send_sync(primary_proc, payload, value, 1);
892 }
893 }
894
895 /**
896 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
897 * @target Device id of the targeted PU or subsystem
898 * @wkup_node Device id of the wakeup peripheral
899 * @enable Enable or disable the specified peripheral as wake source
900 * @flag 0 - Call from secure source
901 * 1 - Call from non-secure source
902 *
903 * @return Returns status, either success or error+reason
904 */
pm_set_wakeup_source(uint32_t target,uint32_t wkup_device,uint8_t enable,uint32_t flag)905 enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
906 uint8_t enable, uint32_t flag)
907 {
908 uint32_t payload[PAYLOAD_ARG_CNT];
909
910 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE,
911 target, wkup_device, enable);
912 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
913 }
914
915 /**
916 * pm_get_chipid() - Read silicon ID registers
917 * @value Buffer for return values. Must be large enough
918 * to hold 8 bytes.
919 * @flag 0 - Call from secure source
920 * 1 - Call from non-secure source
921 *
922 * @return Returns silicon ID registers
923 */
pm_get_chipid(uint32_t * value,uint32_t flag)924 enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag)
925 {
926 uint32_t payload[PAYLOAD_ARG_CNT];
927
928 /* Send request to the PMC */
929 PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_CHIPID);
930
931 return pm_ipi_send_sync(primary_proc, payload, value, 2);
932 }
933
934 /**
935 * pm_feature_check() - Returns the supported API version if supported
936 * @api_id API ID to check
937 * @value Returned supported API version
938 * @flag 0 - Call from secure source
939 * 1 - Call from non-secure source
940 *
941 * @return Returns status, either success or error+reason
942 */
pm_feature_check(uint32_t api_id,unsigned int * version,uint32_t flag)943 enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
944 uint32_t flag)
945 {
946 uint32_t payload[PAYLOAD_ARG_CNT], fw_api_version;
947 uint32_t status;
948
949 switch (api_id) {
950 case PM_GET_CALLBACK_DATA:
951 case PM_GET_TRUSTZONE_VERSION:
952 case PM_LOAD_PDI:
953 *version = (PM_API_BASE_VERSION << 16);
954 return PM_RET_SUCCESS;
955 case PM_GET_API_VERSION:
956 case PM_GET_DEVICE_STATUS:
957 case PM_GET_OP_CHARACTERISTIC:
958 case PM_REQ_SUSPEND:
959 case PM_SELF_SUSPEND:
960 case PM_FORCE_POWERDOWN:
961 case PM_ABORT_SUSPEND:
962 case PM_REQ_WAKEUP:
963 case PM_SET_WAKEUP_SOURCE:
964 case PM_SYSTEM_SHUTDOWN:
965 case PM_REQUEST_DEVICE:
966 case PM_RELEASE_DEVICE:
967 case PM_SET_REQUIREMENT:
968 case PM_RESET_ASSERT:
969 case PM_RESET_GET_STATUS:
970 case PM_GET_CHIPID:
971 case PM_PINCTRL_REQUEST:
972 case PM_PINCTRL_RELEASE:
973 case PM_PINCTRL_GET_FUNCTION:
974 case PM_PINCTRL_SET_FUNCTION:
975 case PM_PINCTRL_CONFIG_PARAM_GET:
976 case PM_PINCTRL_CONFIG_PARAM_SET:
977 case PM_IOCTL:
978 case PM_CLOCK_ENABLE:
979 case PM_CLOCK_DISABLE:
980 case PM_CLOCK_GETSTATE:
981 case PM_CLOCK_SETDIVIDER:
982 case PM_CLOCK_GETDIVIDER:
983 case PM_CLOCK_SETPARENT:
984 case PM_CLOCK_GETPARENT:
985 case PM_CLOCK_GETRATE:
986 case PM_PLL_SET_PARAMETER:
987 case PM_PLL_GET_PARAMETER:
988 case PM_PLL_SET_MODE:
989 case PM_PLL_GET_MODE:
990 case PM_FEATURE_CHECK:
991 case PM_INIT_FINALIZE:
992 case PM_SET_MAX_LATENCY:
993 case PM_REGISTER_NOTIFIER:
994 *version = (PM_API_BASE_VERSION << 16);
995 break;
996 case PM_QUERY_DATA:
997 *version = (PM_API_QUERY_DATA_VERSION << 16);
998 break;
999 default:
1000 *version = 0U;
1001 return PM_RET_ERROR_NOFEATURE;
1002 }
1003
1004 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
1005 PM_FEATURE_CHECK, api_id);
1006
1007 status = pm_ipi_send_sync(primary_proc, payload, &fw_api_version, 1);
1008 if (status != PM_RET_SUCCESS)
1009 return status;
1010
1011 *version |= fw_api_version;
1012
1013 return PM_RET_SUCCESS;
1014 }
1015
1016 /**
1017 * pm_load_pdi() - Load the PDI
1018 *
1019 * This function provides support to load PDI from linux
1020 *
1021 * src: Source device of pdi(DDR, OCM, SD etc)
1022 * address_low: lower 32-bit Linear memory space address
1023 * address_high: higher 32-bit Linear memory space address
1024 * @flag 0 - Call from secure source
1025 * 1 - Call from non-secure source
1026 *
1027 * @return Returns status, either success or error+reason
1028 */
pm_load_pdi(uint32_t src,uint32_t address_low,uint32_t address_high,uint32_t flag)1029 enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
1030 uint32_t address_high, uint32_t flag)
1031 {
1032 uint32_t payload[PAYLOAD_ARG_CNT];
1033
1034 /* Send request to the PMU */
1035 PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, flag, PM_LOAD_PDI, src,
1036 address_high, address_low);
1037 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1038 }
1039
1040 /**
1041 * pm_get_op_characteristic() - PM call to request operating characteristics
1042 * of a device
1043 * @device_id Device id
1044 * @type Type of the operating characteristic
1045 * (power, temperature and latency)
1046 * @result Returns the operating characteristic for the requested device,
1047 * specified by the type
1048 * @flag 0 - Call from secure source
1049 * 1 - Call from non-secure source
1050 *
1051 * @return Returns status, either success or error+reason
1052 */
pm_get_op_characteristic(uint32_t device_id,enum pm_opchar_type type,uint32_t * result,uint32_t flag)1053 enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
1054 enum pm_opchar_type type,
1055 uint32_t *result, uint32_t flag)
1056 {
1057 uint32_t payload[PAYLOAD_ARG_CNT];
1058
1059 /* Send request to the PMC */
1060 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
1061 PM_GET_OP_CHARACTERISTIC, device_id, type);
1062 return pm_ipi_send_sync(primary_proc, payload, result, 1);
1063 }
1064
1065 /**
1066 * pm_set_max_latency() - PM call to change in the maximum wake-up latency
1067 * requirements for a specific device currently
1068 * used by that CPU.
1069 * @device_id Device ID
1070 * @latency Latency value
1071 * @flag 0 - Call from secure source
1072 * 1 - Call from non-secure source
1073 *
1074 * @return Returns status, either success or error+reason
1075 */
pm_set_max_latency(uint32_t device_id,uint32_t latency,uint32_t flag)1076 enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
1077 uint32_t flag)
1078 {
1079 uint32_t payload[PAYLOAD_ARG_CNT];
1080
1081 /* Send request to the PMC */
1082 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SET_MAX_LATENCY,
1083 device_id, latency);
1084
1085 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1086 }
1087
1088 /**
1089 * pm_register_notifier() - PM call to register a subsystem to be notified
1090 * about the device event
1091 * @device_id Device ID for the Node to which the event is related
1092 * @event Event in question
1093 * @wake Wake subsystem upon capturing the event if value 1
1094 * @enable Enable the registration for value 1, disable for value 0
1095 * @flag 0 - Call from secure source
1096 * 1 - Call from non-secure source
1097 *
1098 * @return Returns status, either success or error+reason
1099 */
pm_register_notifier(uint32_t device_id,uint32_t event,uint32_t wake,uint32_t enable,uint32_t flag)1100 enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
1101 uint32_t wake, uint32_t enable,
1102 uint32_t flag)
1103 {
1104 uint32_t payload[PAYLOAD_ARG_CNT];
1105
1106 /* Send request to the PMC */
1107 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REGISTER_NOTIFIER,
1108 device_id, event, wake, enable);
1109
1110 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1111 }
1112