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