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