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