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