blob: e84c4547e2fbe0edfb854e9958bbe50340cf6e1b [file] [log] [blame]
Soren Brinkmann76fcae32016-03-06 20:16:27 -08001/*
Rajan Vaja83687612018-01-17 02:39:20 -08002 * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
Soren Brinkmann76fcae32016-03-06 20:16:27 -08003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soren Brinkmann76fcae32016-03-06 20:16:27 -08005 */
6
7/*
8 * ZynqMP system level PM-API functions and communication with PMU via
9 * IPI interrupts
10 */
11
12#include <arch_helpers.h>
13#include <platform.h>
Rajan Vaja35116132018-01-17 02:39:25 -080014#include "pm_api_clock.h"
Rajan Vaja5529a012018-01-17 02:39:23 -080015#include "pm_api_ioctl.h"
Rajan Vaja0ac2be12018-01-17 02:39:21 -080016#include "pm_api_pinctrl.h"
Isla Mitchelle3631462017-07-14 10:46:32 +010017#include "pm_api_sys.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080018#include "pm_client.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080019#include "pm_common.h"
Isla Mitchelle3631462017-07-14 10:46:32 +010020#include "pm_ipi.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080021
22/**
23 * Assigning of argument values into array elements.
24 */
25#define PM_PACK_PAYLOAD1(pl, arg0) { \
26 pl[0] = (uint32_t)(arg0); \
27}
28
29#define PM_PACK_PAYLOAD2(pl, arg0, arg1) { \
30 pl[1] = (uint32_t)(arg1); \
31 PM_PACK_PAYLOAD1(pl, arg0); \
32}
33
34#define PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2) { \
35 pl[2] = (uint32_t)(arg2); \
36 PM_PACK_PAYLOAD2(pl, arg0, arg1); \
37}
38
39#define PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3) { \
40 pl[3] = (uint32_t)(arg3); \
41 PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2); \
42}
43
44#define PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4) { \
45 pl[4] = (uint32_t)(arg4); \
46 PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3); \
47}
48
49#define PM_PACK_PAYLOAD6(pl, arg0, arg1, arg2, arg3, arg4, arg5) { \
50 pl[5] = (uint32_t)(arg5); \
51 PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4); \
52}
53
54/**
55 * pm_self_suspend() - PM call for processor to suspend itself
56 * @nid Node id of the processor or subsystem
57 * @latency Requested maximum wakeup latency (not supported)
Filip Drazic0bd9d0c2016-07-20 17:17:39 +020058 * @state Requested state
Soren Brinkmann76fcae32016-03-06 20:16:27 -080059 * @address Resume address
60 *
61 * This is a blocking call, it will return only once PMU has responded.
62 * On a wakeup, resume address will be automatically set by PMU.
63 *
64 * @return Returns status, either success or error+reason
65 */
66enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
67 unsigned int latency,
68 unsigned int state,
69 uintptr_t address)
70{
71 uint32_t payload[PAYLOAD_ARG_CNT];
72 unsigned int cpuid = plat_my_core_pos();
73 const struct pm_proc *proc = pm_get_proc(cpuid);
74
75 /*
76 * Do client specific suspend operations
77 * (e.g. set powerdown request bit)
78 */
Filip Drazic4c0765a2016-07-26 12:11:33 +020079 pm_client_suspend(proc, state);
Soren Brinkmann76fcae32016-03-06 20:16:27 -080080 /* Send request to the PMU */
81 PM_PACK_PAYLOAD6(payload, PM_SELF_SUSPEND, proc->node_id, latency,
82 state, address, (address >> 32));
Soren Brinkmannd6c9e032016-09-22 11:35:47 -070083 return pm_ipi_send_sync(proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -080084}
85
86/**
87 * pm_req_suspend() - PM call to request for another PU or subsystem to
88 * be suspended gracefully.
89 * @target Node id of the targeted PU or subsystem
90 * @ack Flag to specify whether acknowledge is requested
91 * @latency Requested wakeup latency (not supported)
92 * @state Requested state (not supported)
93 *
94 * @return Returns status, either success or error+reason
95 */
96enum pm_ret_status pm_req_suspend(enum pm_node_id target,
97 enum pm_request_ack ack,
98 unsigned int latency, unsigned int state)
99{
100 uint32_t payload[PAYLOAD_ARG_CNT];
101
102 /* Send request to the PMU */
103 PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
104 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700105 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800106 else
107 return pm_ipi_send(primary_proc, payload);
108}
109
110/**
111 * pm_req_wakeup() - PM call for processor to wake up selected processor
112 * or subsystem
113 * @target Node id of the processor or subsystem to wake up
114 * @ack Flag to specify whether acknowledge requested
115 * @set_address Resume address presence indicator
116 * 1 resume address specified, 0 otherwise
117 * @address Resume address
118 *
119 * This API function is either used to power up another APU core for SMP
120 * (by PSCI) or to power up an entirely different PU or subsystem, such
121 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
122 * automatically set by PMU.
123 *
124 * @return Returns status, either success or error+reason
125 */
126enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
127 unsigned int set_address,
128 uintptr_t address,
129 enum pm_request_ack ack)
130{
131 uint32_t payload[PAYLOAD_ARG_CNT];
132 uint64_t encoded_address;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800133
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800134
135 /* encode set Address into 1st bit of address */
136 encoded_address = address;
137 encoded_address |= !!set_address;
138
139 /* Send request to the PMU to perform the wake of the PU */
140 PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
141 encoded_address >> 32, ack);
142
143 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700144 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800145 else
146 return pm_ipi_send(primary_proc, payload);
147}
148
149/**
150 * pm_force_powerdown() - PM call to request for another PU or subsystem to
151 * be powered down forcefully
152 * @target Node id of the targeted PU or subsystem
153 * @ack Flag to specify whether acknowledge is requested
154 *
155 * @return Returns status, either success or error+reason
156 */
157enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
158 enum pm_request_ack ack)
159{
160 uint32_t payload[PAYLOAD_ARG_CNT];
161
162 /* Send request to the PMU */
163 PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
164
165 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700166 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800167 else
168 return pm_ipi_send(primary_proc, payload);
169}
170
171/**
172 * pm_abort_suspend() - PM call to announce that a prior suspend request
173 * is to be aborted.
174 * @reason Reason for the abort
175 *
176 * Calling PU expects the PMU to abort the initiated suspend procedure.
177 * This is a non-blocking call without any acknowledge.
178 *
179 * @return Returns status, either success or error+reason
180 */
181enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
182{
183 uint32_t payload[PAYLOAD_ARG_CNT];
184
185 /*
186 * Do client specific abort suspend operations
187 * (e.g. enable interrupts and clear powerdown request bit)
188 */
189 pm_client_abort_suspend();
190 /* Send request to the PMU */
191 /* TODO: allow passing the node ID of the affected CPU */
192 PM_PACK_PAYLOAD3(payload, PM_ABORT_SUSPEND, reason,
193 primary_proc->node_id);
194 return pm_ipi_send(primary_proc, payload);
195}
196
197/**
198 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
199 * @target Node id of the targeted PU or subsystem
200 * @wkup_node Node id of the wakeup peripheral
201 * @enable Enable or disable the specified peripheral as wake source
202 *
203 * @return Returns status, either success or error+reason
204 */
205enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
206 enum pm_node_id wkup_node,
207 unsigned int enable)
208{
209 uint32_t payload[PAYLOAD_ARG_CNT];
210
211 PM_PACK_PAYLOAD4(payload, PM_SET_WAKEUP_SOURCE, target, wkup_node,
212 enable);
213 return pm_ipi_send(primary_proc, payload);
214}
215
216/**
217 * pm_system_shutdown() - PM call to request a system shutdown or restart
218 * @restart Shutdown or restart? 0 for shutdown, 1 for restart
219 *
220 * @return Returns status, either success or error+reason
221 */
Soren Brinkmann58fbb9b2016-09-02 09:50:54 -0700222enum pm_ret_status pm_system_shutdown(unsigned int type, unsigned int subtype)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800223{
224 uint32_t payload[PAYLOAD_ARG_CNT];
225
Soren Brinkmann58fbb9b2016-09-02 09:50:54 -0700226 PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800227 return pm_ipi_send(primary_proc, payload);
228}
229
230/* APIs for managing PM slaves: */
231
232/**
233 * pm_req_node() - PM call to request a node with specific capabilities
234 * @nid Node id of the slave
235 * @capabilities Requested capabilities of the slave
236 * @qos Quality of service (not supported)
237 * @ack Flag to specify whether acknowledge is requested
238 *
239 * @return Returns status, either success or error+reason
240 */
241enum pm_ret_status pm_req_node(enum pm_node_id nid,
242 unsigned int capabilities,
243 unsigned int qos,
244 enum pm_request_ack ack)
245{
246 uint32_t payload[PAYLOAD_ARG_CNT];
247
248 PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
249
250 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700251 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800252 else
253 return pm_ipi_send(primary_proc, payload);
254}
255
256/**
257 * pm_set_requirement() - PM call to set requirement for PM slaves
258 * @nid Node id of the slave
259 * @capabilities Requested capabilities of the slave
260 * @qos Quality of service (not supported)
261 * @ack Flag to specify whether acknowledge is requested
262 *
263 * This API function is to be used for slaves a PU already has requested
264 *
265 * @return Returns status, either success or error+reason
266 */
267enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
268 unsigned int capabilities,
269 unsigned int qos,
270 enum pm_request_ack ack)
271{
272 uint32_t payload[PAYLOAD_ARG_CNT];
273
274 PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
275 ack);
276
277 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700278 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800279 else
280 return pm_ipi_send(primary_proc, payload);
281}
282
283/**
284 * pm_release_node() - PM call to release a node
285 * @nid Node id of the slave
286 *
287 * @return Returns status, either success or error+reason
288 */
289enum pm_ret_status pm_release_node(enum pm_node_id nid)
290{
291 uint32_t payload[PAYLOAD_ARG_CNT];
292
293 PM_PACK_PAYLOAD2(payload, PM_RELEASE_NODE, nid);
294 return pm_ipi_send(primary_proc, payload);
295}
296
297/**
298 * pm_set_max_latency() - PM call to set wakeup latency requirements
299 * @nid Node id of the slave
300 * @latency Requested maximum wakeup latency
301 *
302 * @return Returns status, either success or error+reason
303 */
304enum pm_ret_status pm_set_max_latency(enum pm_node_id nid,
305 unsigned int latency)
306{
307 uint32_t payload[PAYLOAD_ARG_CNT];
308
309 PM_PACK_PAYLOAD3(payload, PM_SET_MAX_LATENCY, nid, latency);
310 return pm_ipi_send(primary_proc, payload);
311}
312
313/* Miscellaneous API functions */
314
315/**
316 * pm_get_api_version() - Get version number of PMU PM firmware
317 * @version Returns 32-bit version number of PMU Power Management Firmware
318 *
319 * @return Returns status, either success or error+reason
320 */
321enum pm_ret_status pm_get_api_version(unsigned int *version)
322{
323 uint32_t payload[PAYLOAD_ARG_CNT];
324
325 /* Send request to the PMU */
326 PM_PACK_PAYLOAD1(payload, PM_GET_API_VERSION);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700327 return pm_ipi_send_sync(primary_proc, payload, version, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800328}
329
330/**
331 * pm_set_configuration() - PM call to set system configuration
332 * @phys_addr Physical 32-bit address of data structure in memory
333 *
334 * @return Returns status, either success or error+reason
335 */
336enum pm_ret_status pm_set_configuration(unsigned int phys_addr)
337{
338 return PM_RET_ERROR_NOTSUPPORTED;
339}
340
341/**
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100342 * pm_get_node_status() - PM call to request a node's current status
343 * @nid Node id
344 * @ret_buff Buffer for the return values:
345 * [0] - Current power state of the node
346 * [1] - Current requirements for the node (slave nodes only)
347 * [2] - Current usage status for the node (slave nodes only)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800348 *
349 * @return Returns status, either success or error+reason
350 */
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100351enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
352 uint32_t *ret_buff)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800353{
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800354 uint32_t payload[PAYLOAD_ARG_CNT];
355
356 PM_PACK_PAYLOAD2(payload, PM_GET_NODE_STATUS, nid);
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100357 return pm_ipi_send_sync(primary_proc, payload, ret_buff, 3);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800358}
359
360/**
361 * pm_register_notifier() - Register the PU to be notified of PM events
362 * @nid Node id of the slave
363 * @event The event to be notified about
364 * @wake Wake up on event
365 * @enable Enable or disable the notifier
366 *
367 * @return Returns status, either success or error+reason
368 */
369enum pm_ret_status pm_register_notifier(enum pm_node_id nid,
370 unsigned int event,
371 unsigned int wake,
372 unsigned int enable)
373{
Anes Hadziahmetagicc95ae092016-05-12 16:17:34 +0200374 uint32_t payload[PAYLOAD_ARG_CNT];
375
376 PM_PACK_PAYLOAD5(payload, PM_REGISTER_NOTIFIER,
377 nid, event, wake, enable);
378
Soren Brinkmanna1b0a902016-09-30 11:30:21 -0700379 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800380}
381
382/**
Anes Hadziahmetagic92aee012016-05-12 16:17:30 +0200383 * pm_get_op_characteristic() - PM call to request operating characteristics
384 * of a node
385 * @nid Node id of the slave
386 * @type Type of the operating characteristic
387 * (power, temperature and latency)
388 * @result Returns the operating characteristic for the requested node,
389 * specified by the type
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800390 *
391 * @return Returns status, either success or error+reason
392 */
393enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
Anes Hadziahmetagic92aee012016-05-12 16:17:30 +0200394 enum pm_opchar_type type,
395 uint32_t *result)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800396{
Anes Hadziahmetagic92aee012016-05-12 16:17:30 +0200397 uint32_t payload[PAYLOAD_ARG_CNT];
398
399 /* Send request to the PMU */
400 PM_PACK_PAYLOAD3(payload, PM_GET_OP_CHARACTERISTIC, nid, type);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700401 return pm_ipi_send_sync(primary_proc, payload, result, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800402}
403
404/* Direct-Control API functions */
405
406/**
407 * pm_reset_assert() - Assert reset
408 * @reset Reset ID
409 * @assert Assert (1) or de-assert (0)
410 *
411 * @return Returns status, either success or error+reason
412 */
413enum pm_ret_status pm_reset_assert(unsigned int reset,
414 unsigned int assert)
415{
416 uint32_t payload[PAYLOAD_ARG_CNT];
417
418 /* Send request to the PMU */
419 PM_PACK_PAYLOAD3(payload, PM_RESET_ASSERT, reset, assert);
420 return pm_ipi_send(primary_proc, payload);
421}
422
423/**
424 * pm_reset_get_status() - Get current status of a reset line
425 * @reset Reset ID
426 * @reset_status Returns current status of selected reset line
427 *
428 * @return Returns status, either success or error+reason
429 */
430enum pm_ret_status pm_reset_get_status(unsigned int reset,
431 unsigned int *reset_status)
432{
433 uint32_t payload[PAYLOAD_ARG_CNT];
434
435 /* Send request to the PMU */
436 PM_PACK_PAYLOAD2(payload, PM_RESET_GET_STATUS, reset);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700437 return pm_ipi_send_sync(primary_proc, payload, reset_status, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800438}
439
440/**
441 * pm_mmio_write() - Perform write to protected mmio
442 * @address Address to write to
443 * @mask Mask to apply
444 * @value Value to write
445 *
446 * This function provides access to PM-related control registers
447 * that may not be directly accessible by a particular PU.
448 *
449 * @return Returns status, either success or error+reason
450 */
451enum pm_ret_status pm_mmio_write(uintptr_t address,
452 unsigned int mask,
453 unsigned int value)
454{
455 uint32_t payload[PAYLOAD_ARG_CNT];
456
457 /* Send request to the PMU */
458 PM_PACK_PAYLOAD4(payload, PM_MMIO_WRITE, address, mask, value);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700459 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800460}
461
462/**
463 * pm_mmio_read() - Read value from protected mmio
464 * @address Address to write to
465 * @value Value to write
466 *
467 * This function provides access to PM-related control registers
468 * that may not be directly accessible by a particular PU.
469 *
470 * @return Returns status, either success or error+reason
471 */
472enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value)
473{
474 uint32_t payload[PAYLOAD_ARG_CNT];
475
476 /* Send request to the PMU */
477 PM_PACK_PAYLOAD2(payload, PM_MMIO_READ, address);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700478 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800479}
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530480
481/**
482 * pm_fpga_load() - Load the bitstream into the PL.
483 *
484 * This function provides access to the xilfpga library to load
485 * the Bit-stream into PL.
486 *
487 * address_low: lower 32-bit Linear memory space address
488 *
489 * address_high: higher 32-bit Linear memory space address
490 *
491 * size: Number of 32bit words
492 *
493 * @return Returns status, either success or error+reason
494 */
495enum pm_ret_status pm_fpga_load(uint32_t address_low,
496 uint32_t address_high,
497 uint32_t size,
498 uint32_t flags)
499{
500 uint32_t payload[PAYLOAD_ARG_CNT];
501
502 /* Send request to the PMU */
503 PM_PACK_PAYLOAD5(payload, PM_FPGA_LOAD, address_high, address_low,
504 size, flags);
505 return pm_ipi_send(primary_proc, payload);
506}
507
508/**
509 * pm_fpga_get_status() - Read value from fpga status register
510 * @value Value to read
511 *
512 * This function provides access to the xilfpga library to get
513 * the fpga status
514 * @return Returns status, either success or error+reason
515 */
516enum pm_ret_status pm_fpga_get_status(unsigned int *value)
517{
518 uint32_t payload[PAYLOAD_ARG_CNT];
519
520 /* Send request to the PMU */
521 PM_PACK_PAYLOAD1(payload, PM_FPGA_GET_STATUS);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700522 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530523}
Soren Brinkmanncb366812016-09-22 12:21:11 -0700524
525/**
526 * pm_get_chipid() - Read silicon ID registers
527 * @value Buffer for return values. Must be large enough
528 * to hold 8 bytes.
529 *
530 * @return Returns silicon ID registers
531 */
532enum pm_ret_status pm_get_chipid(uint32_t *value)
533{
534 uint32_t payload[PAYLOAD_ARG_CNT];
535
536 /* Send request to the PMU */
537 PM_PACK_PAYLOAD1(payload, PM_GET_CHIPID);
538 return pm_ipi_send_sync(primary_proc, payload, value, 2);
539}
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700540
541/**
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530542 * pm_secure_rsaaes() - Load the secure images.
543 *
544 * This function provides access to the xilsecure library to load
545 * the authenticated, encrypted, and authenicated/encrypted images.
546 *
547 * address_low: lower 32-bit Linear memory space address
548 *
549 * address_high: higher 32-bit Linear memory space address
550 *
551 * size: Number of 32bit words
552 *
553 * @return Returns status, either success or error+reason
554 */
555enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
556 uint32_t address_high,
557 uint32_t size,
558 uint32_t flags)
559{
560 uint32_t payload[PAYLOAD_ARG_CNT];
561
562 /* Send request to the PMU */
563 PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA_AES, address_high, address_low,
564 size, flags);
565 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
566}
567
568/**
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700569 * pm_get_callbackdata() - Read from IPI response buffer
570 * @data - array of PAYLOAD_ARG_CNT elements
571 *
572 * Read value from ipi buffer response buffer.
573 */
574void pm_get_callbackdata(uint32_t *data, size_t count)
575{
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700576 pm_ipi_buff_read_callb(data, count);
Wendy Liang328105c2017-10-03 23:21:11 -0700577 pm_ipi_irq_clear(primary_proc);
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700578}
Rajan Vaja83687612018-01-17 02:39:20 -0800579
580/**
581 * pm_pinctrl_request() - Request Pin from firmware
582 * @pin Pin number to request
583 *
584 * This function requests pin from firmware.
585 *
586 * @return Returns status, either success or error+reason.
587 */
588enum pm_ret_status pm_pinctrl_request(unsigned int pin)
589{
590 return PM_RET_SUCCESS;
591}
592
593/**
594 * pm_pinctrl_release() - Release Pin from firmware
595 * @pin Pin number to release
596 *
597 * This function releases pin from firmware.
598 *
599 * @return Returns status, either success or error+reason.
600 */
601enum pm_ret_status pm_pinctrl_release(unsigned int pin)
602{
603 return PM_RET_SUCCESS;
604}
605
606/**
607 * pm_pinctrl_get_function() - Read function id set for the given pin
608 * @pin Pin number
609 * @nid Node ID of function currently set for given pin
610 *
611 * This function provides the function currently set for the given pin.
612 *
613 * @return Returns status, either success or error+reason
614 */
615enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
616 enum pm_node_id *nid)
617{
Rajan Vaja0ac2be12018-01-17 02:39:21 -0800618 return pm_api_pinctrl_get_function(pin, nid);
Rajan Vaja83687612018-01-17 02:39:20 -0800619}
620
621/**
622 * pm_pinctrl_set_function() - Set function id set for the given pin
623 * @pin Pin number
624 * @nid Node ID of function to set for given pin
625 *
626 * This function provides the function currently set for the given pin.
627 *
628 * @return Returns status, either success or error+reason
629 */
630enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
631 enum pm_node_id nid)
632{
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800633 return pm_api_pinctrl_set_function(pin, (unsigned int)nid);
Rajan Vaja83687612018-01-17 02:39:20 -0800634}
635
636/**
637 * pm_pinctrl_get_config() - Read value of requested config param for given pin
638 * @pin Pin number
639 * @param Parameter values to be read
640 * @value Buffer for configuration Parameter value
641 *
642 * This function provides the configuration parameter value for the given pin.
643 *
644 * @return Returns status, either success or error+reason
645 */
646enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
647 unsigned int param,
648 unsigned int *value)
649{
Rajan Vaja5e139e72018-01-17 02:39:22 -0800650 return pm_api_pinctrl_get_config(pin, param, value);
Rajan Vaja83687612018-01-17 02:39:20 -0800651}
652
653/**
654 * pm_pinctrl_set_config() - Read value of requested config param for given pin
655 * @pin Pin number
656 * @param Parameter to set
657 * @value Parameter value to set
658 *
659 * This function provides the configuration parameter value for the given pin.
660 *
661 * @return Returns status, either success or error+reason
662 */
663enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
664 unsigned int param,
665 unsigned int value)
666{
Rajan Vaja5e139e72018-01-17 02:39:22 -0800667 return pm_api_pinctrl_set_config(pin, param, value);
Rajan Vaja83687612018-01-17 02:39:20 -0800668}
Rajan Vaja5529a012018-01-17 02:39:23 -0800669
670/**
671 * pm_ioctl() - PM IOCTL API for device control and configs
672 * @node_id Node ID of the device
673 * @ioctl_id ID of the requested IOCTL
674 * @arg1 Argument 1 to requested IOCTL call
675 * @arg2 Argument 2 to requested IOCTL call
676 * @out Returned output value
677 *
678 * This function calls IOCTL to firmware for device control and configuration.
679 *
680 * @return Returns status, either success or error+reason
681 */
682enum pm_ret_status pm_ioctl(enum pm_node_id nid,
683 unsigned int ioctl_id,
684 unsigned int arg1,
685 unsigned int arg2,
686 unsigned int *value)
687{
688 return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
689}
Rajan Vaja35116132018-01-17 02:39:25 -0800690
691/**
692 * pm_clock_get_name() - PM call to request a clock's name
693 * @clock_id Clock ID
694 * @name Name of clock (max 16 bytes)
695 *
696 * This function is used by master to get nmae of clock specified
697 * by given clock ID.
698 *
699 * @return Returns status, either success or error+reason
700 */
701static enum pm_ret_status pm_clock_get_name(unsigned int clock_id, char *name)
702{
703 return pm_api_clock_get_name(clock_id, name);
704}
705
706/**
707 * pm_clock_get_topology() - PM call to request a clock's topology
708 * @clock_id Clock ID
709 * @index Topology index for next toplogy node
710 * @topology Buffer to store nodes in topology and flags
711 *
712 * This function is used by master to get topology information for the
713 * clock specified by given clock ID. Each response would return 3
714 * topology nodes. To get next nodes, caller needs to call this API with
715 * index of next node. Index starts from 0.
716 *
717 * @return Returns status, either success or error+reason
718 */
719static enum pm_ret_status pm_clock_get_topology(unsigned int clock_id,
720 unsigned int index,
721 uint32_t *topology)
722{
723 return pm_api_clock_get_topology(clock_id, index, topology);
724}
725
726/**
727 * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
728 * parameters for fixed clock
729 * @clock_id Clock ID
730 * @mul Multiplication value
731 * @div Divisor value
732 *
733 * This function is used by master to get fixed factor parameers for the
734 * fixed clock. This API is application only for the fixed clock.
735 *
736 * @return Returns status, either success or error+reason
737 */
738static enum pm_ret_status pm_clock_get_fixedfactor_params(unsigned int clock_id,
739 uint32_t *mul,
740 uint32_t *div)
741{
742 return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
743}
744
745/**
746 * pm_clock_get_parents() - PM call to request a clock's first 3 parents
747 * @clock_id Clock ID
748 * @index Index of next parent
749 * @parents Parents of the given clock
750 *
751 * This function is used by master to get clock's parents information.
752 * This API will return 3 parents with a single response. To get other
753 * parents, master should call same API in loop with new parent index
754 * till error is returned.
755 *
756 * E.g First call should have index 0 which will return parents 0, 1 and
757 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
758 * so on.
759 *
760 * @return Returns status, either success or error+reason
761 */
762static enum pm_ret_status pm_clock_get_parents(unsigned int clock_id,
763 unsigned int index,
764 uint32_t *parents)
765{
766 return pm_api_clock_get_parents(clock_id, index, parents);
767}
768
769/**
770 * pm_clock_get_attributes() - PM call to request a clock's attributes
771 * @clock_id Clock ID
772 * @attr Clock attributes
773 *
774 * This function is used by master to get clock's attributes
775 * (e.g. valid, clock type, etc).
776 *
777 * @return Returns status, either success or error+reason
778 */
779static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
780 uint32_t *attr)
781{
782 return pm_api_clock_get_attributes(clock_id, attr);
783}
784
785/**
786 * pm_clock_enable() - Enable the clock for given id
787 * @clock_id: Id of the clock to be enabled
788 *
789 * This function is used by master to enable the clock
790 * including peripherals and PLL clocks.
791 *
792 * Return: Returns status, either success or error+reason.
793 */
794
795enum pm_ret_status pm_clock_enable(unsigned int clock_id)
796{
797 return pm_api_clock_enable(clock_id);
798}
799
800/**
801 * pm_clock_disable - Disable the clock for given id
802 * @clock_id: Id of the clock to be disable
803 *
804 * This function is used by master to disable the clock
805 * including peripherals and PLL clocks.
806 *
807 * Return: Returns status, either success or error+reason.
808 */
809
810enum pm_ret_status pm_clock_disable(unsigned int clock_id)
811{
812 return pm_api_clock_disable(clock_id);
813}
814
815/**
816 * pm_clock_getstate - Get the clock state for given id
817 * @clock_id: Id of the clock to be queried
818 * @state: 1/0 (Enabled/Disabled)
819 *
820 * This function is used by master to get the state of clock
821 * including peripherals and PLL clocks.
822 *
823 * Return: Returns status, either success or error+reason.
824 */
825enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
826 unsigned int *state)
827{
828 return pm_api_clock_getstate(clock_id, state);
829}
830
831/**
832 * pm_clock_setdivider - Set the clock divider for given id
833 * @clock_id: Id of the clock
834 * @divider: divider value
835 *
836 * This function is used by master to set divider for any clock
837 * to achieve desired rate.
838 *
839 * Return: Returns status, either success or error+reason.
840 */
841enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
842 unsigned int divider)
843{
844 return pm_api_clock_setdivider(clock_id, divider);
845}
846
847/**
848 * pm_clock_getdivider - Get the clock divider for given id
849 * @clock_id: Id of the clock
850 * @divider: divider value
851 *
852 * This function is used by master to get divider values
853 * for any clock.
854 *
855 * Return: Returns status, either success or error+reason.
856 */
857enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
858 unsigned int *divider)
859{
860 return pm_api_clock_getdivider(clock_id, divider);
861}
862
863/**
864 * pm_clock_setrate - Set the clock rate for given id
865 * @clock_id: Id of the clock
866 * @rate: rate value in hz
867 *
868 * This function is used by master to set rate for any clock.
869 *
870 * Return: Returns status, either success or error+reason.
871 */
872enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
873 uint64_t rate)
874{
875 return pm_api_clock_setrate(clock_id, rate);
876}
877
878/**
879 * pm_clock_getrate - Get the clock rate for given id
880 * @clock_id: Id of the clock
881 * @rate: rate value in hz
882 *
883 * This function is used by master to get rate
884 * for any clock.
885 *
886 * Return: Returns status, either success or error+reason.
887 */
888enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
889 uint64_t *rate)
890{
891 return pm_api_clock_getrate(clock_id, rate);
892}
893
894/**
895 * pm_clock_setparent - Set the clock parent for given id
896 * @clock_id: Id of the clock
897 * @parent_id: parent id
898 *
899 * This function is used by master to set parent for any clock.
900 *
901 * Return: Returns status, either success or error+reason.
902 */
903enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
904 unsigned int parent_id)
905{
906 return pm_api_clock_setparent(clock_id, parent_id);
907}
908
909/**
910 * pm_clock_getparent - Get the clock parent for given id
911 * @clock_id: Id of the clock
912 * @parent_id: parent id
913 *
914 * This function is used by master to get parent index
915 * for any clock.
916 *
917 * Return: Returns status, either success or error+reason.
918 */
919enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
920 unsigned int *parent_id)
921{
922 return pm_api_clock_getparent(clock_id, parent_id);
923}
924
925/**
Rajan Vajad5dd8362018-01-30 04:16:31 -0800926 * pm_pinctrl_get_num_pins - PM call to request number of pins
927 * @npins: Number of pins
928 *
929 * This function is used by master to get number of pins
930 *
931 * Return: Returns status, either success or error+reason.
932 */
933static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
934{
935 return pm_api_pinctrl_get_num_pins(npins);
936}
937
938/**
939 * pm_pinctrl_get_num_functions - PM call to request number of functions
940 * @nfuncs: Number of functions
941 *
942 * This function is used by master to get number of functions
943 *
944 * Return: Returns status, either success or error+reason.
945 */
946static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
947{
948 return pm_api_pinctrl_get_num_functions(nfuncs);
949}
950
951/**
952 * pm_pinctrl_get_num_function_groups - PM call to request number of
953 * function groups
954 * @fid: Id of function
955 * @ngroups: Number of function groups
956 *
957 * This function is used by master to get number of function groups specified
958 * by given function Id
959 *
960 * Return: Returns status, either success or error+reason.
961 */
962static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid,
963 uint32_t *ngroups)
964{
965 return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
966}
967
968/**
969 * pm_pinctrl_get_function_name - PM call to request function name
970 * @fid: Id of function
971 * @name: Name of function
972 *
973 * This function is used by master to get name of function specified
974 * by given function Id
975 *
976 * Return: Returns status, either success or error+reason.
977 */
978static enum pm_ret_status pm_pinctrl_get_function_name(unsigned int fid,
979 char *name)
980{
981 return pm_api_pinctrl_get_function_name(fid, name);
982}
983
984/**
985 * pm_pinctrl_get_function_groups - PM call to request function groups
986 * @fid: Id of function
987 * @index: Index of next function groups
988 * @groups: Function groups
989 *
990 * This function is used by master to get function groups specified
991 * by given function Id. This API will return 6 function groups with
992 * a single response. To get other function groups, master should call
993 * same API in loop with new function groups index till error is returned.
994 *
995 * E.g First call should have index 0 which will return function groups
996 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
997 * function groups 6, 7, 8, 9, 10 and 11 and so on.
998 *
999 * Return: Returns status, either success or error+reason.
1000 */
1001static enum pm_ret_status pm_pinctrl_get_function_groups(unsigned int fid,
1002 unsigned int index,
1003 uint16_t *groups)
1004{
1005 return pm_api_pinctrl_get_function_groups(fid, index, groups);
1006}
1007
1008/**
1009 * pm_pinctrl_get_pin_groups - PM call to request pin groups
1010 * @pin_id: Id of pin
1011 * @index: Index of next pin groups
1012 * @groups: pin groups
1013 *
1014 * This function is used by master to get pin groups specified
1015 * by given pin Id. This API will return 6 pin groups with
1016 * a single response. To get other pin groups, master should call
1017 * same API in loop with new pin groups index till error is returned.
1018 *
1019 * E.g First call should have index 0 which will return pin groups
1020 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
1021 * pin groups 6, 7, 8, 9, 10 and 11 and so on.
1022 *
1023 * Return: Returns status, either success or error+reason.
1024 */
1025static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id,
1026 unsigned int index,
1027 uint16_t *groups)
1028{
1029 return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
1030}
1031
1032/**
Rajan Vaja35116132018-01-17 02:39:25 -08001033 * pm_query_data() - PM API for querying firmware data
1034 * @arg1 Argument 1 to requested IOCTL call
1035 * @arg2 Argument 2 to requested IOCTL call
1036 * @arg3 Argument 3 to requested IOCTL call
1037 * @arg4 Argument 4 to requested IOCTL call
1038 * @data Returned output data
1039 *
1040 * This function returns requested data.
1041 *
1042 * @return Returns status, either success or error+reason
1043 */
1044enum pm_ret_status pm_query_data(enum pm_query_id qid,
1045 unsigned int arg1,
1046 unsigned int arg2,
1047 unsigned int arg3,
1048 unsigned int *data)
1049{
1050 enum pm_ret_status ret;
1051
1052 switch (qid) {
1053 case PM_QID_CLOCK_GET_NAME:
1054 ret = pm_clock_get_name(arg1, (char *)data);
1055 break;
1056 case PM_QID_CLOCK_GET_TOPOLOGY:
1057 ret = pm_clock_get_topology(arg1, arg2, &data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001058 data[0] = (unsigned int)ret;
Rajan Vaja35116132018-01-17 02:39:25 -08001059 break;
1060 case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
1061 ret = pm_clock_get_fixedfactor_params(arg1, &data[1], &data[2]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001062 data[0] = (unsigned int)ret;
Rajan Vaja35116132018-01-17 02:39:25 -08001063 break;
1064 case PM_QID_CLOCK_GET_PARENTS:
1065 ret = pm_clock_get_parents(arg1, arg2, &data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001066 data[0] = (unsigned int)ret;
Rajan Vaja35116132018-01-17 02:39:25 -08001067 break;
1068 case PM_QID_CLOCK_GET_ATTRIBUTES:
1069 ret = pm_clock_get_attributes(arg1, &data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001070 data[0] = (unsigned int)ret;
Rajan Vaja35116132018-01-17 02:39:25 -08001071 break;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001072 case PM_QID_PINCTRL_GET_NUM_PINS:
1073 ret = pm_pinctrl_get_num_pins(&data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001074 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001075 break;
1076 case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
1077 ret = pm_pinctrl_get_num_functions(&data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001078 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001079 break;
1080 case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
1081 ret = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001082 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001083 break;
1084 case PM_QID_PINCTRL_GET_FUNCTION_NAME:
1085 ret = pm_pinctrl_get_function_name(arg1, (char *)data);
1086 break;
1087 case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
1088 ret = pm_pinctrl_get_function_groups(arg1, arg2,
1089 (uint16_t *)&data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001090 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001091 break;
1092 case PM_QID_PINCTRL_GET_PIN_GROUPS:
1093 ret = pm_pinctrl_get_pin_groups(arg1, arg2,
1094 (uint16_t *)&data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001095 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001096 break;
Rajan Vaja35116132018-01-17 02:39:25 -08001097 default:
1098 ret = PM_RET_ERROR_ARGS;
1099 WARN("Unimplemented query service call: 0x%x\n", qid);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001100 break;
Rajan Vaja35116132018-01-17 02:39:25 -08001101 }
1102
1103 return ret;
1104}