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