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