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