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