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