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