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