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