1 /*
2 * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
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 <plat/common/platform.h>
14
15 #include "pm_api_clock.h"
16 #include "pm_api_ioctl.h"
17 #include "pm_api_pinctrl.h"
18 #include "pm_api_sys.h"
19 #include "pm_client.h"
20 #include "pm_common.h"
21 #include "pm_ipi.h"
22
23 /* default shutdown/reboot scope is system(2) */
24 static unsigned int pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
25
26 /**
27 * pm_get_shutdown_scope() - Get the currently set shutdown scope
28 *
29 * @return Shutdown scope value
30 */
pm_get_shutdown_scope(void)31 unsigned int pm_get_shutdown_scope(void)
32 {
33 return pm_shutdown_scope;
34 }
35
36 /**
37 * Assigning of argument values into array elements.
38 */
39 #define PM_PACK_PAYLOAD1(pl, arg0) { \
40 pl[0] = (uint32_t)(arg0); \
41 }
42
43 #define PM_PACK_PAYLOAD2(pl, arg0, arg1) { \
44 pl[1] = (uint32_t)(arg1); \
45 PM_PACK_PAYLOAD1(pl, arg0); \
46 }
47
48 #define PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2) { \
49 pl[2] = (uint32_t)(arg2); \
50 PM_PACK_PAYLOAD2(pl, arg0, arg1); \
51 }
52
53 #define PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3) { \
54 pl[3] = (uint32_t)(arg3); \
55 PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2); \
56 }
57
58 #define PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4) { \
59 pl[4] = (uint32_t)(arg4); \
60 PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3); \
61 }
62
63 #define PM_PACK_PAYLOAD6(pl, arg0, arg1, arg2, arg3, arg4, arg5) { \
64 pl[5] = (uint32_t)(arg5); \
65 PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4); \
66 }
67
68 #define EM_PACK_PAYLOAD1(pl, arg0) { \
69 pl[0] = (uint16_t)(0xE) << 16 | (uint16_t)arg0; \
70 }
71
72 /**
73 * pm_self_suspend() - PM call for processor to suspend itself
74 * @nid Node id of the processor or subsystem
75 * @latency Requested maximum wakeup latency (not supported)
76 * @state Requested state
77 * @address Resume address
78 *
79 * This is a blocking call, it will return only once PMU has responded.
80 * On a wakeup, resume address will be automatically set by PMU.
81 *
82 * @return Returns status, either success or error+reason
83 */
pm_self_suspend(enum pm_node_id nid,unsigned int latency,unsigned int state,uintptr_t address)84 enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
85 unsigned int latency,
86 unsigned int state,
87 uintptr_t address)
88 {
89 uint32_t payload[PAYLOAD_ARG_CNT];
90 unsigned int cpuid = plat_my_core_pos();
91 const struct pm_proc *proc = pm_get_proc(cpuid);
92
93 /*
94 * Do client specific suspend operations
95 * (e.g. set powerdown request bit)
96 */
97 pm_client_suspend(proc, state);
98 /* Send request to the PMU */
99 PM_PACK_PAYLOAD6(payload, PM_SELF_SUSPEND, proc->node_id, latency,
100 state, address, (address >> 32));
101 return pm_ipi_send_sync(proc, payload, NULL, 0);
102 }
103
104 /**
105 * pm_req_suspend() - PM call to request for another PU or subsystem to
106 * be suspended gracefully.
107 * @target Node id of the targeted PU or subsystem
108 * @ack Flag to specify whether acknowledge is requested
109 * @latency Requested wakeup latency (not supported)
110 * @state Requested state (not supported)
111 *
112 * @return Returns status, either success or error+reason
113 */
pm_req_suspend(enum pm_node_id target,enum pm_request_ack ack,unsigned int latency,unsigned int state)114 enum pm_ret_status pm_req_suspend(enum pm_node_id target,
115 enum pm_request_ack ack,
116 unsigned int latency, unsigned int state)
117 {
118 uint32_t payload[PAYLOAD_ARG_CNT];
119
120 /* Send request to the PMU */
121 PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
122 if (ack == REQ_ACK_BLOCKING)
123 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
124 else
125 return pm_ipi_send(primary_proc, payload);
126 }
127
128 /**
129 * pm_req_wakeup() - PM call for processor to wake up selected processor
130 * or subsystem
131 * @target Node id of the processor or subsystem to wake up
132 * @ack Flag to specify whether acknowledge requested
133 * @set_address Resume address presence indicator
134 * 1 resume address specified, 0 otherwise
135 * @address Resume address
136 *
137 * This API function is either used to power up another APU core for SMP
138 * (by PSCI) or to power up an entirely different PU or subsystem, such
139 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
140 * automatically set by PMU.
141 *
142 * @return Returns status, either success or error+reason
143 */
pm_req_wakeup(enum pm_node_id target,unsigned int set_address,uintptr_t address,enum pm_request_ack ack)144 enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
145 unsigned int set_address,
146 uintptr_t address,
147 enum pm_request_ack ack)
148 {
149 uint32_t payload[PAYLOAD_ARG_CNT];
150 uint64_t encoded_address;
151
152
153 /* encode set Address into 1st bit of address */
154 encoded_address = address;
155 encoded_address |= !!set_address;
156
157 /* Send request to the PMU to perform the wake of the PU */
158 PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
159 encoded_address >> 32, ack);
160
161 if (ack == REQ_ACK_BLOCKING)
162 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
163 else
164 return pm_ipi_send(primary_proc, payload);
165 }
166
167 /**
168 * pm_force_powerdown() - PM call to request for another PU or subsystem to
169 * be powered down forcefully
170 * @target Node id of the targeted PU or subsystem
171 * @ack Flag to specify whether acknowledge is requested
172 *
173 * @return Returns status, either success or error+reason
174 */
pm_force_powerdown(enum pm_node_id target,enum pm_request_ack ack)175 enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
176 enum pm_request_ack ack)
177 {
178 uint32_t payload[PAYLOAD_ARG_CNT];
179
180 /* Send request to the PMU */
181 PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
182
183 if (ack == REQ_ACK_BLOCKING)
184 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
185 else
186 return pm_ipi_send(primary_proc, payload);
187 }
188
189 /**
190 * pm_abort_suspend() - PM call to announce that a prior suspend request
191 * is to be aborted.
192 * @reason Reason for the abort
193 *
194 * Calling PU expects the PMU to abort the initiated suspend procedure.
195 * This is a non-blocking call without any acknowledge.
196 *
197 * @return Returns status, either success or error+reason
198 */
pm_abort_suspend(enum pm_abort_reason reason)199 enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
200 {
201 uint32_t payload[PAYLOAD_ARG_CNT];
202
203 /*
204 * Do client specific abort suspend operations
205 * (e.g. enable interrupts and clear powerdown request bit)
206 */
207 pm_client_abort_suspend();
208 /* Send request to the PMU */
209 /* TODO: allow passing the node ID of the affected CPU */
210 PM_PACK_PAYLOAD3(payload, PM_ABORT_SUSPEND, reason,
211 primary_proc->node_id);
212 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
213 }
214
215 /**
216 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
217 * @target Node id of the targeted PU or subsystem
218 * @wkup_node Node id of the wakeup peripheral
219 * @enable Enable or disable the specified peripheral as wake source
220 *
221 * @return Returns status, either success or error+reason
222 */
pm_set_wakeup_source(enum pm_node_id target,enum pm_node_id wkup_node,unsigned int enable)223 enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
224 enum pm_node_id wkup_node,
225 unsigned int enable)
226 {
227 uint32_t payload[PAYLOAD_ARG_CNT];
228
229 PM_PACK_PAYLOAD4(payload, PM_SET_WAKEUP_SOURCE, target, wkup_node,
230 enable);
231 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
232 }
233
234 /**
235 * pm_system_shutdown() - PM call to request a system shutdown or restart
236 * @type Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
237 * @subtype Scope: 0=APU-subsystem, 1=PS, 2=system
238 *
239 * @return Returns status, either success or error+reason
240 */
pm_system_shutdown(unsigned int type,unsigned int subtype)241 enum pm_ret_status pm_system_shutdown(unsigned int type, unsigned int subtype)
242 {
243 uint32_t payload[PAYLOAD_ARG_CNT];
244
245 if (type == PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
246 /* Setting scope for subsequent PSCI reboot or shutdown */
247 pm_shutdown_scope = subtype;
248 return PM_RET_SUCCESS;
249 }
250
251 PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
252 return pm_ipi_send_non_blocking(primary_proc, payload);
253 }
254
255 /* APIs for managing PM slaves: */
256
257 /**
258 * pm_req_node() - PM call to request a node with specific capabilities
259 * @nid Node id of the slave
260 * @capabilities Requested capabilities of the slave
261 * @qos Quality of service (not supported)
262 * @ack Flag to specify whether acknowledge is requested
263 *
264 * @return Returns status, either success or error+reason
265 */
pm_req_node(enum pm_node_id nid,unsigned int capabilities,unsigned int qos,enum pm_request_ack ack)266 enum pm_ret_status pm_req_node(enum pm_node_id nid,
267 unsigned int capabilities,
268 unsigned int qos,
269 enum pm_request_ack ack)
270 {
271 uint32_t payload[PAYLOAD_ARG_CNT];
272
273 PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
274
275 if (ack == REQ_ACK_BLOCKING)
276 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
277 else
278 return pm_ipi_send(primary_proc, payload);
279 }
280
281 /**
282 * pm_set_requirement() - PM call to set requirement for PM slaves
283 * @nid Node id of the slave
284 * @capabilities Requested capabilities of the slave
285 * @qos Quality of service (not supported)
286 * @ack Flag to specify whether acknowledge is requested
287 *
288 * This API function is to be used for slaves a PU already has requested
289 *
290 * @return Returns status, either success or error+reason
291 */
pm_set_requirement(enum pm_node_id nid,unsigned int capabilities,unsigned int qos,enum pm_request_ack ack)292 enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
293 unsigned int capabilities,
294 unsigned int qos,
295 enum pm_request_ack ack)
296 {
297 uint32_t payload[PAYLOAD_ARG_CNT];
298
299 PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
300 ack);
301
302 if (ack == REQ_ACK_BLOCKING)
303 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
304 else
305 return pm_ipi_send(primary_proc, payload);
306 }
307
308 /**
309 * pm_release_node() - PM call to release a node
310 * @nid Node id of the slave
311 *
312 * @return Returns status, either success or error+reason
313 */
pm_release_node(enum pm_node_id nid)314 enum pm_ret_status pm_release_node(enum pm_node_id nid)
315 {
316 uint32_t payload[PAYLOAD_ARG_CNT];
317
318 PM_PACK_PAYLOAD2(payload, PM_RELEASE_NODE, nid);
319 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
320 }
321
322 /**
323 * pm_set_max_latency() - PM call to set wakeup latency requirements
324 * @nid Node id of the slave
325 * @latency Requested maximum wakeup latency
326 *
327 * @return Returns status, either success or error+reason
328 */
pm_set_max_latency(enum pm_node_id nid,unsigned int latency)329 enum pm_ret_status pm_set_max_latency(enum pm_node_id nid,
330 unsigned int latency)
331 {
332 uint32_t payload[PAYLOAD_ARG_CNT];
333
334 PM_PACK_PAYLOAD3(payload, PM_SET_MAX_LATENCY, nid, latency);
335 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
336 }
337
338 /* Miscellaneous API functions */
339
340 /**
341 * pm_get_api_version() - Get version number of PMU PM firmware
342 * @version Returns 32-bit version number of PMU Power Management Firmware
343 *
344 * @return Returns status, either success or error+reason
345 */
pm_get_api_version(unsigned int * version)346 enum pm_ret_status pm_get_api_version(unsigned int *version)
347 {
348 uint32_t payload[PAYLOAD_ARG_CNT];
349
350 /* Send request to the PMU */
351 PM_PACK_PAYLOAD1(payload, PM_GET_API_VERSION);
352 return pm_ipi_send_sync(primary_proc, payload, version, 1);
353 }
354
355 /**
356 * pm_set_configuration() - PM call to set system configuration
357 * @phys_addr Physical 32-bit address of data structure in memory
358 *
359 * @return Returns status, either success or error+reason
360 */
pm_set_configuration(unsigned int phys_addr)361 enum pm_ret_status pm_set_configuration(unsigned int phys_addr)
362 {
363 uint32_t payload[PAYLOAD_ARG_CNT];
364
365 PM_PACK_PAYLOAD2(payload, PM_SET_CONFIGURATION, phys_addr);
366 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
367 }
368
369 /**
370 * pm_init_finalize() - Call to notify PMU firmware that master has power
371 * management enabled and that it has finished its
372 * initialization
373 *
374 * @return Status returned by the PMU firmware
375 */
pm_init_finalize(void)376 enum pm_ret_status pm_init_finalize(void)
377 {
378 uint32_t payload[PAYLOAD_ARG_CNT];
379
380 /* Send request to the PMU */
381 PM_PACK_PAYLOAD1(payload, PM_INIT_FINALIZE);
382 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
383 }
384
385 /**
386 * pm_get_node_status() - PM call to request a node's current status
387 * @nid Node id
388 * @ret_buff Buffer for the return values:
389 * [0] - Current power state of the node
390 * [1] - Current requirements for the node (slave nodes only)
391 * [2] - Current usage status for the node (slave nodes only)
392 *
393 * @return Returns status, either success or error+reason
394 */
pm_get_node_status(enum pm_node_id nid,uint32_t * ret_buff)395 enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
396 uint32_t *ret_buff)
397 {
398 uint32_t payload[PAYLOAD_ARG_CNT];
399
400 PM_PACK_PAYLOAD2(payload, PM_GET_NODE_STATUS, nid);
401 return pm_ipi_send_sync(primary_proc, payload, ret_buff, 3);
402 }
403
404 /**
405 * pm_register_notifier() - Register the PU to be notified of PM events
406 * @nid Node id of the slave
407 * @event The event to be notified about
408 * @wake Wake up on event
409 * @enable Enable or disable the notifier
410 *
411 * @return Returns status, either success or error+reason
412 */
pm_register_notifier(enum pm_node_id nid,unsigned int event,unsigned int wake,unsigned int enable)413 enum pm_ret_status pm_register_notifier(enum pm_node_id nid,
414 unsigned int event,
415 unsigned int wake,
416 unsigned int enable)
417 {
418 uint32_t payload[PAYLOAD_ARG_CNT];
419
420 PM_PACK_PAYLOAD5(payload, PM_REGISTER_NOTIFIER,
421 nid, event, wake, enable);
422
423 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
424 }
425
426 /**
427 * pm_get_op_characteristic() - PM call to request operating characteristics
428 * of a node
429 * @nid Node id of the slave
430 * @type Type of the operating characteristic
431 * (power, temperature and latency)
432 * @result Returns the operating characteristic for the requested node,
433 * specified by the type
434 *
435 * @return Returns status, either success or error+reason
436 */
pm_get_op_characteristic(enum pm_node_id nid,enum pm_opchar_type type,uint32_t * result)437 enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
438 enum pm_opchar_type type,
439 uint32_t *result)
440 {
441 uint32_t payload[PAYLOAD_ARG_CNT];
442
443 /* Send request to the PMU */
444 PM_PACK_PAYLOAD3(payload, PM_GET_OP_CHARACTERISTIC, nid, type);
445 return pm_ipi_send_sync(primary_proc, payload, result, 1);
446 }
447
448 /* Direct-Control API functions */
449
450 /**
451 * pm_reset_assert() - Assert reset
452 * @reset Reset ID
453 * @assert Assert (1) or de-assert (0)
454 *
455 * @return Returns status, either success or error+reason
456 */
pm_reset_assert(unsigned int reset,unsigned int assert)457 enum pm_ret_status pm_reset_assert(unsigned int reset,
458 unsigned int assert)
459 {
460 uint32_t payload[PAYLOAD_ARG_CNT];
461
462 /* Send request to the PMU */
463 PM_PACK_PAYLOAD3(payload, PM_RESET_ASSERT, reset, assert);
464 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
465 }
466
467 /**
468 * pm_reset_get_status() - Get current status of a reset line
469 * @reset Reset ID
470 * @reset_status Returns current status of selected reset line
471 *
472 * @return Returns status, either success or error+reason
473 */
pm_reset_get_status(unsigned int reset,unsigned int * reset_status)474 enum pm_ret_status pm_reset_get_status(unsigned int reset,
475 unsigned int *reset_status)
476 {
477 uint32_t payload[PAYLOAD_ARG_CNT];
478
479 /* Send request to the PMU */
480 PM_PACK_PAYLOAD2(payload, PM_RESET_GET_STATUS, reset);
481 return pm_ipi_send_sync(primary_proc, payload, reset_status, 1);
482 }
483
484 /**
485 * pm_mmio_write() - Perform write to protected mmio
486 * @address Address to write to
487 * @mask Mask to apply
488 * @value Value to write
489 *
490 * This function provides access to PM-related control registers
491 * that may not be directly accessible by a particular PU.
492 *
493 * @return Returns status, either success or error+reason
494 */
pm_mmio_write(uintptr_t address,unsigned int mask,unsigned int value)495 enum pm_ret_status pm_mmio_write(uintptr_t address,
496 unsigned int mask,
497 unsigned int value)
498 {
499 uint32_t payload[PAYLOAD_ARG_CNT];
500
501 /* Send request to the PMU */
502 PM_PACK_PAYLOAD4(payload, PM_MMIO_WRITE, address, mask, value);
503 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
504 }
505
506 /**
507 * pm_mmio_read() - Read value from protected mmio
508 * @address Address to write to
509 * @value Value to write
510 *
511 * This function provides access to PM-related control registers
512 * that may not be directly accessible by a particular PU.
513 *
514 * @return Returns status, either success or error+reason
515 */
pm_mmio_read(uintptr_t address,unsigned int * value)516 enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value)
517 {
518 uint32_t payload[PAYLOAD_ARG_CNT];
519
520 /* Send request to the PMU */
521 PM_PACK_PAYLOAD2(payload, PM_MMIO_READ, address);
522 return pm_ipi_send_sync(primary_proc, payload, value, 1);
523 }
524
525 /**
526 * pm_fpga_load() - Load the bitstream into the PL.
527 *
528 * This function provides access to the xilfpga library to load
529 * the Bit-stream into PL.
530 *
531 * address_low: lower 32-bit Linear memory space address
532 *
533 * address_high: higher 32-bit Linear memory space address
534 *
535 * size: Number of 32bit words
536 *
537 * @return Returns status, either success or error+reason
538 */
pm_fpga_load(uint32_t address_low,uint32_t address_high,uint32_t size,uint32_t flags)539 enum pm_ret_status pm_fpga_load(uint32_t address_low,
540 uint32_t address_high,
541 uint32_t size,
542 uint32_t flags)
543 {
544 uint32_t payload[PAYLOAD_ARG_CNT];
545
546 /* Send request to the PMU */
547 PM_PACK_PAYLOAD5(payload, PM_FPGA_LOAD, address_high, address_low,
548 size, flags);
549 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
550 }
551
552 /**
553 * pm_fpga_get_status() - Read value from fpga status register
554 * @value Value to read
555 *
556 * This function provides access to the xilfpga library to get
557 * the fpga status
558 * @return Returns status, either success or error+reason
559 */
pm_fpga_get_status(unsigned int * value)560 enum pm_ret_status pm_fpga_get_status(unsigned int *value)
561 {
562 uint32_t payload[PAYLOAD_ARG_CNT];
563
564 /* Send request to the PMU */
565 PM_PACK_PAYLOAD1(payload, PM_FPGA_GET_STATUS);
566 return pm_ipi_send_sync(primary_proc, payload, value, 1);
567 }
568
569 /**
570 * pm_get_chipid() - Read silicon ID registers
571 * @value Buffer for return values. Must be large enough
572 * to hold 8 bytes.
573 *
574 * @return Returns silicon ID registers
575 */
pm_get_chipid(uint32_t * value)576 enum pm_ret_status pm_get_chipid(uint32_t *value)
577 {
578 uint32_t payload[PAYLOAD_ARG_CNT];
579
580 /* Send request to the PMU */
581 PM_PACK_PAYLOAD1(payload, PM_GET_CHIPID);
582 return pm_ipi_send_sync(primary_proc, payload, value, 2);
583 }
584
585 /**
586 * pm_secure_rsaaes() - Load the secure images.
587 *
588 * This function provides access to the xilsecure library to load
589 * the authenticated, encrypted, and authenicated/encrypted images.
590 *
591 * address_low: lower 32-bit Linear memory space address
592 *
593 * address_high: higher 32-bit Linear memory space address
594 *
595 * size: Number of 32bit words
596 *
597 * @return Returns status, either success or error+reason
598 */
pm_secure_rsaaes(uint32_t address_low,uint32_t address_high,uint32_t size,uint32_t flags)599 enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
600 uint32_t address_high,
601 uint32_t size,
602 uint32_t flags)
603 {
604 uint32_t payload[PAYLOAD_ARG_CNT];
605
606 /* Send request to the PMU */
607 PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA_AES, address_high, address_low,
608 size, flags);
609 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
610 }
611
612 /**
613 * pm_aes_engine() - Aes data blob encryption/decryption
614 * This function provides access to the xilsecure library to
615 * encrypt/decrypt data blobs.
616 *
617 * address_low: lower 32-bit address of the AesParams structure
618 *
619 * address_high: higher 32-bit address of the AesParams structure
620 *
621 * value: Returned output value
622 *
623 * @return Returns status, either success or error+reason
624 */
pm_aes_engine(uint32_t address_high,uint32_t address_low,uint32_t * value)625 enum pm_ret_status pm_aes_engine(uint32_t address_high,
626 uint32_t address_low,
627 uint32_t *value)
628 {
629 uint32_t payload[PAYLOAD_ARG_CNT];
630
631 /* Send request to the PMU */
632 PM_PACK_PAYLOAD3(payload, PM_SECURE_AES, address_high, address_low);
633 return pm_ipi_send_sync(primary_proc, payload, value, 1);
634 }
635
636 /**
637 * pm_get_callbackdata() - Read from IPI response buffer
638 * @data - array of PAYLOAD_ARG_CNT elements
639 *
640 * Read value from ipi buffer response buffer.
641 */
pm_get_callbackdata(uint32_t * data,size_t count)642 void pm_get_callbackdata(uint32_t *data, size_t count)
643 {
644 /* Return if interrupt is not from PMU */
645 if (!pm_ipi_irq_status(primary_proc))
646 return;
647
648 pm_ipi_buff_read_callb(data, count);
649 pm_ipi_irq_clear(primary_proc);
650 }
651
652 /**
653 * pm_pinctrl_request() - Request Pin from firmware
654 * @pin Pin number to request
655 *
656 * This function requests pin from firmware.
657 *
658 * @return Returns status, either success or error+reason.
659 */
pm_pinctrl_request(unsigned int pin)660 enum pm_ret_status pm_pinctrl_request(unsigned int pin)
661 {
662 uint32_t payload[PAYLOAD_ARG_CNT];
663
664 /* Send request to the PMU */
665 PM_PACK_PAYLOAD2(payload, PM_PINCTRL_REQUEST, pin);
666 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
667 }
668
669 /**
670 * pm_pinctrl_release() - Release Pin from firmware
671 * @pin Pin number to release
672 *
673 * This function releases pin from firmware.
674 *
675 * @return Returns status, either success or error+reason.
676 */
pm_pinctrl_release(unsigned int pin)677 enum pm_ret_status pm_pinctrl_release(unsigned int pin)
678 {
679 uint32_t payload[PAYLOAD_ARG_CNT];
680
681 /* Send request to the PMU */
682 PM_PACK_PAYLOAD2(payload, PM_PINCTRL_RELEASE, pin);
683 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
684 }
685
686 /**
687 * pm_pinctrl_get_function() - Read function id set for the given pin
688 * @pin Pin number
689 * @fid ID of function currently set for given pin
690 *
691 * This function provides the function currently set for the given pin.
692 *
693 * @return Returns status, either success or error+reason
694 */
pm_pinctrl_get_function(unsigned int pin,unsigned int * fid)695 enum pm_ret_status pm_pinctrl_get_function(unsigned int pin, unsigned int *fid)
696 {
697 uint32_t payload[PAYLOAD_ARG_CNT];
698
699 PM_PACK_PAYLOAD2(payload, PM_PINCTRL_GET_FUNCTION, pin);
700 return pm_ipi_send_sync(primary_proc, payload, fid, 1);
701 }
702
703 /**
704 * pm_pinctrl_set_function() - Set function id set for the given pin
705 * @pin Pin number
706 * @fid ID of function to set for given pin
707 *
708 * @return Returns status, either success or error+reason
709 */
pm_pinctrl_set_function(unsigned int pin,unsigned int fid)710 enum pm_ret_status pm_pinctrl_set_function(unsigned int pin, unsigned int fid)
711 {
712 uint32_t payload[PAYLOAD_ARG_CNT];
713
714 /* Send request to the PMU */
715 PM_PACK_PAYLOAD3(payload, PM_PINCTRL_SET_FUNCTION, pin, fid);
716 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
717 }
718
719 /**
720 * pm_pinctrl_get_config() - Read value of requested config param for given pin
721 * @pin Pin number
722 * @param Parameter values to be read
723 * @value Buffer for configuration Parameter value
724 *
725 * This function provides the configuration parameter value for the given pin.
726 *
727 * @return Returns status, either success or error+reason
728 */
pm_pinctrl_get_config(unsigned int pin,unsigned int param,unsigned int * value)729 enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
730 unsigned int param,
731 unsigned int *value)
732 {
733 uint32_t payload[PAYLOAD_ARG_CNT];
734
735 PM_PACK_PAYLOAD3(payload, PM_PINCTRL_CONFIG_PARAM_GET, pin, param);
736 return pm_ipi_send_sync(primary_proc, payload, value, 1);
737 }
738
739 /**
740 * pm_pinctrl_set_config() - Set value of requested config param for given pin
741 * @pin Pin number
742 * @param Parameter to set
743 * @value Parameter value to set
744 *
745 * @return Returns status, either success or error+reason
746 */
pm_pinctrl_set_config(unsigned int pin,unsigned int param,unsigned int value)747 enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
748 unsigned int param,
749 unsigned int value)
750 {
751 uint32_t payload[PAYLOAD_ARG_CNT];
752
753 /* Send request to the PMU */
754 PM_PACK_PAYLOAD4(payload, PM_PINCTRL_CONFIG_PARAM_SET, pin, param,
755 value);
756 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
757 }
758
759 /**
760 * pm_ioctl() - PM IOCTL API for device control and configs
761 * @node_id Node ID of the device
762 * @ioctl_id ID of the requested IOCTL
763 * @arg1 Argument 1 to requested IOCTL call
764 * @arg2 Argument 2 to requested IOCTL call
765 * @out Returned output value
766 *
767 * This function calls IOCTL to firmware for device control and configuration.
768 *
769 * @return Returns status, either success or error+reason
770 */
pm_ioctl(enum pm_node_id nid,unsigned int ioctl_id,unsigned int arg1,unsigned int arg2,unsigned int * value)771 enum pm_ret_status pm_ioctl(enum pm_node_id nid,
772 unsigned int ioctl_id,
773 unsigned int arg1,
774 unsigned int arg2,
775 unsigned int *value)
776 {
777 return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
778 }
779
780 /**
781 * pm_clock_get_max_divisor - PM call to get max divisor
782 * @clock_id Clock ID
783 * @div_type Divisor ID (TYPE_DIV1 or TYPE_DIV2)
784 * @max_div Maximum supported divisor
785 *
786 * This function is used by master to get maximum supported value.
787 *
788 * Return: Returns status, either success or error+reason.
789 */
pm_clock_get_max_divisor(unsigned int clock_id,uint8_t div_type,uint32_t * max_div)790 static enum pm_ret_status pm_clock_get_max_divisor(unsigned int clock_id,
791 uint8_t div_type,
792 uint32_t *max_div)
793 {
794 return pm_api_clock_get_max_divisor(clock_id, div_type, max_div);
795 }
796
797 /**
798 * pm_clock_get_num_clocks - PM call to request number of clocks
799 * @nclockss: Number of clocks
800 *
801 * This function is used by master to get number of clocks.
802 *
803 * Return: Returns status, either success or error+reason.
804 */
pm_clock_get_num_clocks(uint32_t * nclocks)805 static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks)
806 {
807 return pm_api_clock_get_num_clocks(nclocks);
808 }
809
810 /**
811 * pm_clock_get_name() - PM call to request a clock's name
812 * @clock_id Clock ID
813 * @name Name of clock (max 16 bytes)
814 *
815 * This function is used by master to get nmae of clock specified
816 * by given clock ID.
817 */
pm_clock_get_name(unsigned int clock_id,char * name)818 static void pm_clock_get_name(unsigned int clock_id, char *name)
819 {
820 pm_api_clock_get_name(clock_id, name);
821 }
822
823 /**
824 * pm_clock_get_topology() - PM call to request a clock's topology
825 * @clock_id Clock ID
826 * @index Topology index for next toplogy node
827 * @topology Buffer to store nodes in topology and flags
828 *
829 * This function is used by master to get topology information for the
830 * clock specified by given clock ID. Each response would return 3
831 * topology nodes. To get next nodes, caller needs to call this API with
832 * index of next node. Index starts from 0.
833 *
834 * @return Returns status, either success or error+reason
835 */
pm_clock_get_topology(unsigned int clock_id,unsigned int index,uint32_t * topology)836 static enum pm_ret_status pm_clock_get_topology(unsigned int clock_id,
837 unsigned int index,
838 uint32_t *topology)
839 {
840 return pm_api_clock_get_topology(clock_id, index, topology);
841 }
842
843 /**
844 * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
845 * parameters for fixed clock
846 * @clock_id Clock ID
847 * @mul Multiplication value
848 * @div Divisor value
849 *
850 * This function is used by master to get fixed factor parameers for the
851 * fixed clock. This API is application only for the fixed clock.
852 *
853 * @return Returns status, either success or error+reason
854 */
pm_clock_get_fixedfactor_params(unsigned int clock_id,uint32_t * mul,uint32_t * div)855 static enum pm_ret_status pm_clock_get_fixedfactor_params(unsigned int clock_id,
856 uint32_t *mul,
857 uint32_t *div)
858 {
859 return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
860 }
861
862 /**
863 * pm_clock_get_parents() - PM call to request a clock's first 3 parents
864 * @clock_id Clock ID
865 * @index Index of next parent
866 * @parents Parents of the given clock
867 *
868 * This function is used by master to get clock's parents information.
869 * This API will return 3 parents with a single response. To get other
870 * parents, master should call same API in loop with new parent index
871 * till error is returned.
872 *
873 * E.g First call should have index 0 which will return parents 0, 1 and
874 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
875 * so on.
876 *
877 * @return Returns status, either success or error+reason
878 */
pm_clock_get_parents(unsigned int clock_id,unsigned int index,uint32_t * parents)879 static enum pm_ret_status pm_clock_get_parents(unsigned int clock_id,
880 unsigned int index,
881 uint32_t *parents)
882 {
883 return pm_api_clock_get_parents(clock_id, index, parents);
884 }
885
886 /**
887 * pm_clock_get_attributes() - PM call to request a clock's attributes
888 * @clock_id Clock ID
889 * @attr Clock attributes
890 *
891 * This function is used by master to get clock's attributes
892 * (e.g. valid, clock type, etc).
893 *
894 * @return Returns status, either success or error+reason
895 */
pm_clock_get_attributes(unsigned int clock_id,uint32_t * attr)896 static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
897 uint32_t *attr)
898 {
899 return pm_api_clock_get_attributes(clock_id, attr);
900 }
901
902 /**
903 * pm_clock_gate() - Configure clock gate
904 * @clock_id Id of the clock to be configured
905 * @enable Flag 0=disable (gate the clock), !0=enable (activate the clock)
906 *
907 * @return Error if an argument is not valid or status as returned by the
908 * PM controller (PMU)
909 */
pm_clock_gate(unsigned int clock_id,unsigned char enable)910 static enum pm_ret_status pm_clock_gate(unsigned int clock_id,
911 unsigned char enable)
912 {
913 uint32_t payload[PAYLOAD_ARG_CNT];
914 enum pm_ret_status status;
915 enum pm_api_id api_id;
916
917 /* Check if clock ID is valid and return an error if it is not */
918 status = pm_clock_id_is_valid(clock_id);
919 if (status != PM_RET_SUCCESS)
920 return status;
921
922 if (enable)
923 api_id = PM_CLOCK_ENABLE;
924 else
925 api_id = PM_CLOCK_DISABLE;
926
927 /* Send request to the PMU */
928 PM_PACK_PAYLOAD2(payload, api_id, clock_id);
929 status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
930
931 /* If action fails due to the lack of permissions filter the error */
932 if (status == PM_RET_ERROR_ACCESS)
933 status = PM_RET_SUCCESS;
934
935 return status;
936 }
937
938 /**
939 * pm_clock_enable() - Enable the clock for given id
940 * @clock_id: Id of the clock to be enabled
941 *
942 * This function is used by master to enable the clock
943 * including peripherals and PLL clocks.
944 *
945 * @return: Error if an argument is not valid or status as returned by the
946 * pm_clock_gate
947 */
pm_clock_enable(unsigned int clock_id)948 enum pm_ret_status pm_clock_enable(unsigned int clock_id)
949 {
950 struct pm_pll *pll;
951
952 /* First try to handle it as a PLL */
953 pll = pm_clock_get_pll(clock_id);
954 if (pll)
955 return pm_clock_pll_enable(pll);
956
957 /* It's an on-chip clock, PMU should configure clock's gate */
958 return pm_clock_gate(clock_id, 1);
959 }
960
961 /**
962 * pm_clock_disable - Disable the clock for given id
963 * @clock_id: Id of the clock to be disable
964 *
965 * This function is used by master to disable the clock
966 * including peripherals and PLL clocks.
967 *
968 * @return: Error if an argument is not valid or status as returned by the
969 * pm_clock_gate
970 */
pm_clock_disable(unsigned int clock_id)971 enum pm_ret_status pm_clock_disable(unsigned int clock_id)
972 {
973 struct pm_pll *pll;
974
975 /* First try to handle it as a PLL */
976 pll = pm_clock_get_pll(clock_id);
977 if (pll)
978 return pm_clock_pll_disable(pll);
979
980 /* It's an on-chip clock, PMU should configure clock's gate */
981 return pm_clock_gate(clock_id, 0);
982 }
983
984 /**
985 * pm_clock_getstate - Get the clock state for given id
986 * @clock_id: Id of the clock to be queried
987 * @state: 1/0 (Enabled/Disabled)
988 *
989 * This function is used by master to get the state of clock
990 * including peripherals and PLL clocks.
991 *
992 * Return: Returns status, either success or error+reason.
993 */
pm_clock_getstate(unsigned int clock_id,unsigned int * state)994 enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
995 unsigned int *state)
996 {
997 struct pm_pll *pll;
998 uint32_t payload[PAYLOAD_ARG_CNT];
999 enum pm_ret_status status;
1000
1001 /* First try to handle it as a PLL */
1002 pll = pm_clock_get_pll(clock_id);
1003 if (pll)
1004 return pm_clock_pll_get_state(pll, state);
1005
1006 /* Check if clock ID is a valid on-chip clock */
1007 status = pm_clock_id_is_valid(clock_id);
1008 if (status != PM_RET_SUCCESS)
1009 return status;
1010
1011 /* Send request to the PMU */
1012 PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
1013 return pm_ipi_send_sync(primary_proc, payload, state, 1);
1014 }
1015
1016 /**
1017 * pm_clock_setdivider - Set the clock divider for given id
1018 * @clock_id: Id of the clock
1019 * @divider: divider value
1020 *
1021 * This function is used by master to set divider for any clock
1022 * to achieve desired rate.
1023 *
1024 * Return: Returns status, either success or error+reason.
1025 */
pm_clock_setdivider(unsigned int clock_id,unsigned int divider)1026 enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
1027 unsigned int divider)
1028 {
1029 enum pm_ret_status status;
1030 enum pm_node_id nid;
1031 enum pm_clock_div_id div_id;
1032 uint32_t payload[PAYLOAD_ARG_CNT];
1033 const uint32_t div0 = 0xFFFF0000;
1034 const uint32_t div1 = 0x0000FFFF;
1035 uint32_t val;
1036
1037 /* Get PLL node ID using PLL clock ID */
1038 status = pm_clock_get_pll_node_id(clock_id, &nid);
1039 if (status == PM_RET_SUCCESS)
1040 return pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
1041
1042 /* Check if clock ID is a valid on-chip clock */
1043 status = pm_clock_id_is_valid(clock_id);
1044 if (status != PM_RET_SUCCESS)
1045 return status;
1046
1047 if (div0 == (divider & div0)) {
1048 div_id = PM_CLOCK_DIV0_ID;
1049 val = divider & ~div0;
1050 } else if (div1 == (divider & div1)) {
1051 div_id = PM_CLOCK_DIV1_ID;
1052 val = (divider & ~div1) >> 16;
1053 } else {
1054 return PM_RET_ERROR_ARGS;
1055 }
1056
1057 /* Send request to the PMU */
1058 PM_PACK_PAYLOAD4(payload, PM_CLOCK_SETDIVIDER, clock_id, div_id, val);
1059 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1060 }
1061
1062 /**
1063 * pm_clock_getdivider - Get the clock divider for given id
1064 * @clock_id: Id of the clock
1065 * @divider: divider value
1066 *
1067 * This function is used by master to get divider values
1068 * for any clock.
1069 *
1070 * Return: Returns status, either success or error+reason.
1071 */
pm_clock_getdivider(unsigned int clock_id,unsigned int * divider)1072 enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
1073 unsigned int *divider)
1074 {
1075 enum pm_ret_status status;
1076 enum pm_node_id nid;
1077 uint32_t payload[PAYLOAD_ARG_CNT];
1078 uint32_t val;
1079
1080 /* Get PLL node ID using PLL clock ID */
1081 status = pm_clock_get_pll_node_id(clock_id, &nid);
1082 if (status == PM_RET_SUCCESS)
1083 return pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
1084
1085 /* Check if clock ID is a valid on-chip clock */
1086 status = pm_clock_id_is_valid(clock_id);
1087 if (status != PM_RET_SUCCESS)
1088 return status;
1089
1090 if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
1091 /* Send request to the PMU to get div0 */
1092 PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
1093 PM_CLOCK_DIV0_ID);
1094 status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
1095 if (status != PM_RET_SUCCESS)
1096 return status;
1097 *divider = val;
1098 }
1099
1100 if (pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) {
1101 /* Send request to the PMU to get div1 */
1102 PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
1103 PM_CLOCK_DIV1_ID);
1104 status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
1105 if (status != PM_RET_SUCCESS)
1106 return status;
1107 *divider |= val << 16;
1108 }
1109
1110 return status;
1111 }
1112
1113 /**
1114 * pm_clock_setrate - Set the clock rate for given id
1115 * @clock_id: Id of the clock
1116 * @rate: rate value in hz
1117 *
1118 * This function is used by master to set rate for any clock.
1119 *
1120 * Return: Returns status, either success or error+reason.
1121 */
pm_clock_setrate(unsigned int clock_id,uint64_t rate)1122 enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
1123 uint64_t rate)
1124 {
1125 return PM_RET_ERROR_NOTSUPPORTED;
1126 }
1127
1128 /**
1129 * pm_clock_getrate - Get the clock rate for given id
1130 * @clock_id: Id of the clock
1131 * @rate: rate value in hz
1132 *
1133 * This function is used by master to get rate
1134 * for any clock.
1135 *
1136 * Return: Returns status, either success or error+reason.
1137 */
pm_clock_getrate(unsigned int clock_id,uint64_t * rate)1138 enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
1139 uint64_t *rate)
1140 {
1141 return PM_RET_ERROR_NOTSUPPORTED;
1142 }
1143
1144 /**
1145 * pm_clock_setparent - Set the clock parent for given id
1146 * @clock_id: Id of the clock
1147 * @parent_index: Index of the parent clock into clock's parents array
1148 *
1149 * This function is used by master to set parent for any clock.
1150 *
1151 * Return: Returns status, either success or error+reason.
1152 */
pm_clock_setparent(unsigned int clock_id,unsigned int parent_index)1153 enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
1154 unsigned int parent_index)
1155 {
1156 struct pm_pll *pll;
1157 uint32_t payload[PAYLOAD_ARG_CNT];
1158 enum pm_ret_status status;
1159
1160 /* First try to handle it as a PLL */
1161 pll = pm_clock_get_pll_by_related_clk(clock_id);
1162 if (pll)
1163 return pm_clock_pll_set_parent(pll, clock_id, parent_index);
1164
1165 /* Check if clock ID is a valid on-chip clock */
1166 status = pm_clock_id_is_valid(clock_id);
1167 if (status != PM_RET_SUCCESS)
1168 return status;
1169
1170 /* Send request to the PMU */
1171 PM_PACK_PAYLOAD3(payload, PM_CLOCK_SETPARENT, clock_id, parent_index);
1172 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1173 }
1174
1175 /**
1176 * pm_clock_getparent - Get the clock parent for given id
1177 * @clock_id: Id of the clock
1178 * @parent_index: parent index
1179 *
1180 * This function is used by master to get parent index
1181 * for any clock.
1182 *
1183 * Return: Returns status, either success or error+reason.
1184 */
pm_clock_getparent(unsigned int clock_id,unsigned int * parent_index)1185 enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
1186 unsigned int *parent_index)
1187 {
1188 struct pm_pll *pll;
1189 uint32_t payload[PAYLOAD_ARG_CNT];
1190 enum pm_ret_status status;
1191
1192 /* First try to handle it as a PLL */
1193 pll = pm_clock_get_pll_by_related_clk(clock_id);
1194 if (pll)
1195 return pm_clock_pll_get_parent(pll, clock_id, parent_index);
1196
1197 /* Check if clock ID is a valid on-chip clock */
1198 status = pm_clock_id_is_valid(clock_id);
1199 if (status != PM_RET_SUCCESS)
1200 return status;
1201
1202 /* Send request to the PMU */
1203 PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETPARENT, clock_id);
1204 return pm_ipi_send_sync(primary_proc, payload, parent_index, 1);
1205 }
1206
1207 /**
1208 * pm_pinctrl_get_num_pins - PM call to request number of pins
1209 * @npins: Number of pins
1210 *
1211 * This function is used by master to get number of pins
1212 *
1213 * Return: Returns status, either success or error+reason.
1214 */
pm_pinctrl_get_num_pins(uint32_t * npins)1215 static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
1216 {
1217 return pm_api_pinctrl_get_num_pins(npins);
1218 }
1219
1220 /**
1221 * pm_pinctrl_get_num_functions - PM call to request number of functions
1222 * @nfuncs: Number of functions
1223 *
1224 * This function is used by master to get number of functions
1225 *
1226 * Return: Returns status, either success or error+reason.
1227 */
pm_pinctrl_get_num_functions(uint32_t * nfuncs)1228 static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
1229 {
1230 return pm_api_pinctrl_get_num_functions(nfuncs);
1231 }
1232
1233 /**
1234 * pm_pinctrl_get_num_function_groups - PM call to request number of
1235 * function groups
1236 * @fid: Id of function
1237 * @ngroups: Number of function groups
1238 *
1239 * This function is used by master to get number of function groups specified
1240 * by given function Id
1241 *
1242 * Return: Returns status, either success or error+reason.
1243 */
pm_pinctrl_get_num_function_groups(unsigned int fid,uint32_t * ngroups)1244 static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid,
1245 uint32_t *ngroups)
1246 {
1247 return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
1248 }
1249
1250 /**
1251 * pm_pinctrl_get_function_name - PM call to request function name
1252 * @fid: Id of function
1253 * @name: Name of function
1254 *
1255 * This function is used by master to get name of function specified
1256 * by given function Id
1257 */
pm_pinctrl_get_function_name(unsigned int fid,char * name)1258 static void pm_pinctrl_get_function_name(unsigned int fid, char *name)
1259 {
1260 pm_api_pinctrl_get_function_name(fid, name);
1261 }
1262
1263 /**
1264 * pm_pinctrl_get_function_groups - PM call to request function groups
1265 * @fid: Id of function
1266 * @index: Index of next function groups
1267 * @groups: Function groups
1268 *
1269 * This function is used by master to get function groups specified
1270 * by given function Id. This API will return 6 function groups with
1271 * a single response. To get other function groups, master should call
1272 * same API in loop with new function groups index till error is returned.
1273 *
1274 * E.g First call should have index 0 which will return function groups
1275 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
1276 * function groups 6, 7, 8, 9, 10 and 11 and so on.
1277 *
1278 * Return: Returns status, either success or error+reason.
1279 */
pm_pinctrl_get_function_groups(unsigned int fid,unsigned int index,uint16_t * groups)1280 static enum pm_ret_status pm_pinctrl_get_function_groups(unsigned int fid,
1281 unsigned int index,
1282 uint16_t *groups)
1283 {
1284 return pm_api_pinctrl_get_function_groups(fid, index, groups);
1285 }
1286
1287 /**
1288 * pm_pinctrl_get_pin_groups - PM call to request pin groups
1289 * @pin_id: Id of pin
1290 * @index: Index of next pin groups
1291 * @groups: pin groups
1292 *
1293 * This function is used by master to get pin groups specified
1294 * by given pin Id. This API will return 6 pin groups with
1295 * a single response. To get other pin groups, master should call
1296 * same API in loop with new pin groups index till error is returned.
1297 *
1298 * E.g First call should have index 0 which will return pin groups
1299 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
1300 * pin groups 6, 7, 8, 9, 10 and 11 and so on.
1301 *
1302 * Return: Returns status, either success or error+reason.
1303 */
pm_pinctrl_get_pin_groups(unsigned int pin_id,unsigned int index,uint16_t * groups)1304 static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id,
1305 unsigned int index,
1306 uint16_t *groups)
1307 {
1308 return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
1309 }
1310
1311 /**
1312 * pm_query_data() - PM API for querying firmware data
1313 * @arg1 Argument 1 to requested IOCTL call
1314 * @arg2 Argument 2 to requested IOCTL call
1315 * @arg3 Argument 3 to requested IOCTL call
1316 * @arg4 Argument 4 to requested IOCTL call
1317 * @data Returned output data
1318 *
1319 * This function returns requested data.
1320 */
pm_query_data(enum pm_query_id qid,unsigned int arg1,unsigned int arg2,unsigned int arg3,unsigned int * data)1321 void pm_query_data(enum pm_query_id qid, unsigned int arg1, unsigned int arg2,
1322 unsigned int arg3, unsigned int *data)
1323 {
1324 switch (qid) {
1325 case PM_QID_CLOCK_GET_NAME:
1326 pm_clock_get_name(arg1, (char *)data);
1327 break;
1328 case PM_QID_CLOCK_GET_TOPOLOGY:
1329 data[0] = pm_clock_get_topology(arg1, arg2, &data[1]);
1330 break;
1331 case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
1332 data[0] = pm_clock_get_fixedfactor_params(arg1, &data[1],
1333 &data[2]);
1334 break;
1335 case PM_QID_CLOCK_GET_PARENTS:
1336 data[0] = pm_clock_get_parents(arg1, arg2, &data[1]);
1337 break;
1338 case PM_QID_CLOCK_GET_ATTRIBUTES:
1339 data[0] = pm_clock_get_attributes(arg1, &data[1]);
1340 break;
1341 case PM_QID_PINCTRL_GET_NUM_PINS:
1342 data[0] = pm_pinctrl_get_num_pins(&data[1]);
1343 break;
1344 case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
1345 data[0] = pm_pinctrl_get_num_functions(&data[1]);
1346 break;
1347 case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
1348 data[0] = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
1349 break;
1350 case PM_QID_PINCTRL_GET_FUNCTION_NAME:
1351 pm_pinctrl_get_function_name(arg1, (char *)data);
1352 break;
1353 case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
1354 data[0] = pm_pinctrl_get_function_groups(arg1, arg2,
1355 (uint16_t *)&data[1]);
1356 break;
1357 case PM_QID_PINCTRL_GET_PIN_GROUPS:
1358 data[0] = pm_pinctrl_get_pin_groups(arg1, arg2,
1359 (uint16_t *)&data[1]);
1360 break;
1361 case PM_QID_CLOCK_GET_NUM_CLOCKS:
1362 data[0] = pm_clock_get_num_clocks(&data[1]);
1363 break;
1364
1365 case PM_QID_CLOCK_GET_MAX_DIVISOR:
1366 data[0] = pm_clock_get_max_divisor(arg1, arg2, &data[1]);
1367 break;
1368 default:
1369 data[0] = PM_RET_ERROR_ARGS;
1370 WARN("Unimplemented query service call: 0x%x\n", qid);
1371 }
1372 }
1373
pm_sha_hash(uint32_t address_high,uint32_t address_low,uint32_t size,uint32_t flags)1374 enum pm_ret_status pm_sha_hash(uint32_t address_high,
1375 uint32_t address_low,
1376 uint32_t size,
1377 uint32_t flags)
1378 {
1379 uint32_t payload[PAYLOAD_ARG_CNT];
1380
1381 /* Send request to the PMU */
1382 PM_PACK_PAYLOAD5(payload, PM_SECURE_SHA, address_high, address_low,
1383 size, flags);
1384 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1385 }
1386
pm_rsa_core(uint32_t address_high,uint32_t address_low,uint32_t size,uint32_t flags)1387 enum pm_ret_status pm_rsa_core(uint32_t address_high,
1388 uint32_t address_low,
1389 uint32_t size,
1390 uint32_t flags)
1391 {
1392 uint32_t payload[PAYLOAD_ARG_CNT];
1393
1394 /* Send request to the PMU */
1395 PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA, address_high, address_low,
1396 size, flags);
1397 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1398 }
1399
pm_secure_image(uint32_t address_low,uint32_t address_high,uint32_t key_lo,uint32_t key_hi,uint32_t * value)1400 enum pm_ret_status pm_secure_image(uint32_t address_low,
1401 uint32_t address_high,
1402 uint32_t key_lo,
1403 uint32_t key_hi,
1404 uint32_t *value)
1405 {
1406 uint32_t payload[PAYLOAD_ARG_CNT];
1407
1408 /* Send request to the PMU */
1409 PM_PACK_PAYLOAD5(payload, PM_SECURE_IMAGE, address_high, address_low,
1410 key_hi, key_lo);
1411 return pm_ipi_send_sync(primary_proc, payload, value, 2);
1412 }
1413
1414 /**
1415 * pm_fpga_read - Perform the fpga configuration readback
1416 *
1417 * @reg_numframes: Configuration register offset (or) Number of frames to read
1418 * @address_low: lower 32-bit Linear memory space address
1419 * @address_high: higher 32-bit Linear memory space address
1420 * @readback_type: Type of fpga readback operation
1421 * 0 -- Configuration Register readback
1422 * 1 -- Configuration Data readback
1423 * @value: Value to read
1424 *
1425 * This function provides access to the xilfpga library to read
1426 * the PL configuration.
1427 *
1428 * Return: Returns status, either success or error+reason.
1429 */
pm_fpga_read(uint32_t reg_numframes,uint32_t address_low,uint32_t address_high,uint32_t readback_type,uint32_t * value)1430 enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
1431 uint32_t address_low,
1432 uint32_t address_high,
1433 uint32_t readback_type,
1434 uint32_t *value)
1435 {
1436 uint32_t payload[PAYLOAD_ARG_CNT];
1437
1438 /* Send request to the PMU */
1439 PM_PACK_PAYLOAD5(payload, PM_FPGA_READ, reg_numframes, address_low,
1440 address_high, readback_type);
1441 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1442 }
1443
1444 /*
1445 * pm_pll_set_parameter() - Set the PLL parameter value
1446 * @nid Node id of the target PLL
1447 * @param_id ID of the PLL parameter
1448 * @value Parameter value to be set
1449 *
1450 * Setting the parameter will have physical effect once the PLL mode is set to
1451 * integer or fractional.
1452 *
1453 * @return Error if an argument is not valid or status as returned by the
1454 * PM controller (PMU)
1455 */
pm_pll_set_parameter(enum pm_node_id nid,enum pm_pll_param param_id,unsigned int value)1456 enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
1457 enum pm_pll_param param_id,
1458 unsigned int value)
1459 {
1460 uint32_t payload[PAYLOAD_ARG_CNT];
1461
1462 /* Check if given node ID is a PLL node */
1463 if (nid < NODE_APLL || nid > NODE_IOPLL)
1464 return PM_RET_ERROR_ARGS;
1465
1466 /* Check if parameter ID is valid and return an error if it's not */
1467 if (param_id >= PM_PLL_PARAM_MAX)
1468 return PM_RET_ERROR_ARGS;
1469
1470 /* Send request to the PMU */
1471 PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
1472 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1473 }
1474
1475 /**
1476 * pm_pll_get_parameter() - Get the PLL parameter value
1477 * @nid Node id of the target PLL
1478 * @param_id ID of the PLL parameter
1479 * @value Location to store the parameter value
1480 *
1481 * @return Error if an argument is not valid or status as returned by the
1482 * PM controller (PMU)
1483 */
pm_pll_get_parameter(enum pm_node_id nid,enum pm_pll_param param_id,unsigned int * value)1484 enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
1485 enum pm_pll_param param_id,
1486 unsigned int *value)
1487 {
1488 uint32_t payload[PAYLOAD_ARG_CNT];
1489
1490 /* Check if given node ID is a PLL node */
1491 if (nid < NODE_APLL || nid > NODE_IOPLL)
1492 return PM_RET_ERROR_ARGS;
1493
1494 /* Check if parameter ID is valid and return an error if it's not */
1495 if (param_id >= PM_PLL_PARAM_MAX)
1496 return PM_RET_ERROR_ARGS;
1497
1498 /* Send request to the PMU */
1499 PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
1500 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1501 }
1502
1503 /**
1504 * pm_pll_set_mode() - Set the PLL mode
1505 * @nid Node id of the target PLL
1506 * @mode PLL mode to be set
1507 *
1508 * If reset mode is set the PM controller will first bypass the PLL and then
1509 * assert the reset. If integer or fractional mode is set the PM controller will
1510 * ensure that the complete PLL programming sequence is satisfied. After this
1511 * function returns success the PLL is locked and its bypass is deasserted.
1512 *
1513 * @return Error if an argument is not valid or status as returned by the
1514 * PM controller (PMU)
1515 */
pm_pll_set_mode(enum pm_node_id nid,enum pm_pll_mode mode)1516 enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
1517 {
1518 uint32_t payload[PAYLOAD_ARG_CNT];
1519
1520 /* Check if given node ID is a PLL node */
1521 if (nid < NODE_APLL || nid > NODE_IOPLL)
1522 return PM_RET_ERROR_ARGS;
1523
1524 /* Check if PLL mode is valid */
1525 if (mode >= PM_PLL_MODE_MAX)
1526 return PM_RET_ERROR_ARGS;
1527
1528 /* Send request to the PMU */
1529 PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
1530 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1531 }
1532
1533 /**
1534 * pm_pll_get_mode() - Get the PLL mode
1535 * @nid Node id of the target PLL
1536 * @mode Location to store the mode of the PLL
1537 *
1538 * @return Error if an argument is not valid or status as returned by the
1539 * PM controller (PMU)
1540 */
pm_pll_get_mode(enum pm_node_id nid,enum pm_pll_mode * mode)1541 enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
1542 {
1543 uint32_t payload[PAYLOAD_ARG_CNT];
1544
1545 /* Check if given node ID is a PLL node */
1546 if (nid < NODE_APLL || nid > NODE_IOPLL)
1547 return PM_RET_ERROR_ARGS;
1548
1549 /* Send request to the PMU */
1550 PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
1551 return pm_ipi_send_sync(primary_proc, payload, mode, 1);
1552 }
1553
1554 /**
1555 * pm_register_access() - PM API for register read/write access data
1556 *
1557 * @register_access_id Register_access_id which says register read/write
1558 *
1559 * @address Address of the register to be accessed
1560 *
1561 * @mask Mask value to be used while writing value
1562 *
1563 * @value Value to be written to register
1564 *
1565 * @out Returned output data
1566 *
1567 * This function returns requested data.
1568 *
1569 * @return Returns status, either success or error+reason
1570 */
pm_register_access(unsigned int register_access_id,unsigned int address,unsigned int mask,unsigned int value,unsigned int * out)1571 enum pm_ret_status pm_register_access(unsigned int register_access_id,
1572 unsigned int address,
1573 unsigned int mask,
1574 unsigned int value,
1575 unsigned int *out)
1576 {
1577 enum pm_ret_status ret;
1578
1579 if (((ZYNQMP_CSU_BASEADDR & address) != ZYNQMP_CSU_BASEADDR) &&
1580 ((CSUDMA_BASE & address) != CSUDMA_BASE) &&
1581 ((RSA_CORE_BASE & address) != RSA_CORE_BASE) &&
1582 ((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE))
1583 return PM_RET_ERROR_ACCESS;
1584
1585 switch (register_access_id) {
1586 case CONFIG_REG_WRITE:
1587 ret = pm_mmio_write(address, mask, value);
1588 break;
1589 case CONFIG_REG_READ:
1590 ret = pm_mmio_read(address, out);
1591 break;
1592 default:
1593 ret = PM_RET_ERROR_ARGS;
1594 WARN("Unimplemented register_access call\n\r");
1595 }
1596 return ret;
1597 }
1598
1599 /**
1600 * pm_efuse_access() - To program or read efuse bits.
1601 *
1602 * This function provides access to the xilskey library to program/read
1603 * efuse bits.
1604 *
1605 * address_low: lower 32-bit Linear memory space address
1606 * address_high: higher 32-bit Linear memory space address
1607 *
1608 * value: Returned output value
1609 *
1610 * @return Returns status, either success or error+reason
1611 *
1612 */
pm_efuse_access(uint32_t address_high,uint32_t address_low,uint32_t * value)1613 enum pm_ret_status pm_efuse_access(uint32_t address_high,
1614 uint32_t address_low,
1615 uint32_t *value)
1616 {
1617 uint32_t payload[PAYLOAD_ARG_CNT];
1618
1619 /* Send request to the PMU */
1620 PM_PACK_PAYLOAD3(payload, PM_EFUSE_ACCESS, address_high, address_low);
1621
1622 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1623 }
1624
em_set_action(unsigned int * value)1625 enum pm_ret_status em_set_action(unsigned int *value)
1626 {
1627 uint32_t payload[PAYLOAD_ARG_CNT];
1628
1629 /* Send request to the PMU */
1630 EM_PACK_PAYLOAD1(payload, EM_SET_ACTION);
1631 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1632 }
1633
em_remove_action(unsigned int * value)1634 enum pm_ret_status em_remove_action(unsigned int *value)
1635 {
1636 uint32_t payload[PAYLOAD_ARG_CNT];
1637
1638 /* Send request to the PMU */
1639 EM_PACK_PAYLOAD1(payload, EM_REMOVE_ACTION);
1640 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1641 }
1642
em_send_errors(unsigned int * value)1643 enum pm_ret_status em_send_errors(unsigned int *value)
1644 {
1645 uint32_t payload[PAYLOAD_ARG_CNT];
1646
1647 /* Send request to the PMU */
1648 EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS);
1649 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1650 }
1651
1652 /**
1653 * pm_feature_config() - feature configuration at runtime
1654 *
1655 * This function is used to send IPI request to PMUFW to configure feature
1656 * at runtime. The feature can be enable or disable as well as the feature
1657 * can be configure at runtime using an IOCTL call.
1658 *
1659 * @ioctl_id The ioctl id for the feature configuration
1660 * @config_id The config id of the feature to be configured
1661 * @value The value to be configured
1662 * @response Return to reference pointer
1663 *
1664 * @return Returns 0 on success or error value on failure
1665 */
pm_feature_config(unsigned int ioctl_id,unsigned int config_id,unsigned int value,unsigned int * response)1666 enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
1667 unsigned int config_id,
1668 unsigned int value,
1669 unsigned int *response)
1670 {
1671 uint32_t payload[PAYLOAD_ARG_CNT];
1672
1673 /* Send request to the PMU */
1674 PM_PACK_PAYLOAD5(payload, PM_IOCTL, 0, ioctl_id, config_id, value);
1675
1676 if (ioctl_id == IOCTL_GET_FEATURE_CONFIG) {
1677 return pm_ipi_send_sync(primary_proc, payload, response, 1);
1678 } else if (ioctl_id == IOCTL_SET_FEATURE_CONFIG) {
1679 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1680 } else {
1681 return PM_RET_ERROR_ARGS;
1682 }
1683 }
1684