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