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