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