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