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