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