1 /* 2 * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved. 3 * Copyright (c) 2022-2025, 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 for ioctl. 10 */ 11 12 #include <arch_helpers.h> 13 #include <drivers/delay_timer.h> 14 #include <lib/mmio.h> 15 #include <plat/common/platform.h> 16 17 #include "pm_api_clock.h" 18 #include "pm_api_ioctl.h" 19 #include "pm_client.h" 20 #include "pm_common.h" 21 #include "pm_ipi.h" 22 #include <zynqmp_def.h> 23 #include "zynqmp_pm_api_sys.h" 24 25 /** 26 * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode. 27 * @mode: Buffer to store value of oper mode(Split/Lock-step) 28 * 29 * This function provides current configured RPU operational mode. 30 * 31 * Return: Returns status, either success or error+reason. 32 * 33 */ 34 static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode) 35 { 36 uint32_t val; 37 38 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL); 39 val &= ZYNQMP_SLSPLIT_MASK; 40 if (val == 0U) { 41 *mode = PM_RPU_MODE_LOCKSTEP; 42 } else { 43 *mode = PM_RPU_MODE_SPLIT; 44 } 45 46 return PM_RET_SUCCESS; 47 } 48 49 /** 50 * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode. 51 * @mode: Value to set for oper mode(Split/Lock-step). 52 * 53 * This function configures RPU operational mode(Split/Lock-step). 54 * It also sets TCM combined mode in RPU lock-step and TCM non-combined 55 * mode for RPU split mode. In case of Lock step mode, RPU1's output is 56 * clamped. 57 * 58 * Return: Returns status, either success or error+reason. 59 * 60 */ 61 static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode) 62 { 63 uint32_t val; 64 enum pm_ret_status status = PM_RET_SUCCESS; 65 66 if ((mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) != 0U) { 67 status = PM_RET_ERROR_ACCESS; 68 goto exit_label; 69 } 70 71 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL); 72 73 if (mode == PM_RPU_MODE_SPLIT) { 74 val |= ZYNQMP_SLSPLIT_MASK; 75 val &= ~ZYNQMP_TCM_COMB_MASK; 76 val &= ~ZYNQMP_SLCLAMP_MASK; 77 } else if (mode == PM_RPU_MODE_LOCKSTEP) { 78 val &= ~ZYNQMP_SLSPLIT_MASK; 79 val |= ZYNQMP_TCM_COMB_MASK; 80 val |= ZYNQMP_SLCLAMP_MASK; 81 } else { 82 status = PM_RET_ERROR_ARGS; 83 goto exit_label; 84 } 85 86 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val); 87 88 exit_label: 89 return status; 90 } 91 92 /** 93 * pm_ioctl_config_boot_addr() - Configure RPU boot address. 94 * @nid: Node ID of RPU. 95 * @value: Value to set for boot address (TCM/OCM). 96 * 97 * This function configures RPU boot address(memory). 98 * 99 * Return: Returns status, either success or error+reason. 100 * 101 */ 102 static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid, 103 uint32_t value) 104 { 105 uint32_t rpu_cfg_addr, val; 106 107 if (nid == NODE_RPU_0) { 108 rpu_cfg_addr = ZYNQMP_RPU0_CFG; 109 } else if (nid == NODE_RPU_1) { 110 rpu_cfg_addr = ZYNQMP_RPU1_CFG; 111 } else { 112 return PM_RET_ERROR_ARGS; 113 } 114 115 val = mmio_read_32(rpu_cfg_addr); 116 117 if (value == PM_RPU_BOOTMEM_LOVEC) { 118 val &= ~ZYNQMP_VINITHI_MASK; 119 } else if (value == PM_RPU_BOOTMEM_HIVEC) { 120 val |= ZYNQMP_VINITHI_MASK; 121 } else { 122 return PM_RET_ERROR_ARGS; 123 } 124 125 mmio_write_32(rpu_cfg_addr, val); 126 127 return PM_RET_SUCCESS; 128 } 129 130 /** 131 * pm_ioctl_config_tcm_comb() - Configure TCM combined mode. 132 * @value: Value to set (Split/Combined). 133 * 134 * This function configures TCM to be in split mode or combined 135 * mode. 136 * 137 * Return: Returns status, either success or error+reason. 138 * 139 */ 140 static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value) 141 { 142 uint32_t val; 143 enum pm_ret_status status = PM_RET_SUCCESS; 144 145 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL); 146 147 if (value == PM_RPU_TCM_SPLIT) { 148 val &= ~ZYNQMP_TCM_COMB_MASK; 149 } else if (value == PM_RPU_TCM_COMB) { 150 val |= ZYNQMP_TCM_COMB_MASK; 151 } else { 152 status = PM_RET_ERROR_ARGS; 153 goto exit_label; 154 } 155 156 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val); 157 158 exit_label: 159 return status; 160 } 161 162 /** 163 * pm_ioctl_set_tapdelay_bypass() - Enable/Disable tap delay bypass. 164 * @type: Type of tap delay to enable/disable (e.g. QSPI). 165 * @value: Enable/Disable. 166 * @flag: 0 - Call from secure source. 167 * 1 - Call from non-secure source. 168 * 169 * This function enable/disable tap delay bypass. 170 * 171 * Return: Returns status, either success or error+reason. 172 * 173 */ 174 static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type, 175 uint32_t value, 176 uint32_t flag) 177 { 178 enum pm_ret_status status = PM_RET_SUCCESS; 179 180 if ((((value != PM_TAPDELAY_BYPASS_ENABLE) && 181 (value != PM_TAPDELAY_BYPASS_DISABLE)) || (type >= PM_TAPDELAY_MAX))) { 182 status = PM_RET_ERROR_ARGS; 183 } else { 184 status = pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, 185 value << type, flag); 186 } 187 188 return status; 189 } 190 191 /** 192 * pm_ioctl_sd_dll_reset() - Reset DLL logic. 193 * @nid: Node ID of the device. 194 * @type: Reset type. 195 * @flag: 0 - Call from secure source. 196 * 1 - Call from non-secure source. 197 * 198 * This function resets DLL logic for the SD device. 199 * 200 * Return: Returns status, either success or error+reason. 201 * 202 */ 203 static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid, 204 uint32_t type, 205 uint32_t flag) 206 { 207 uint32_t mask, val; 208 enum pm_ret_status ret; 209 210 if (nid == NODE_SD_0) { 211 mask = ZYNQMP_SD0_DLL_RST_MASK; 212 val = ZYNQMP_SD0_DLL_RST; 213 } else if (nid == NODE_SD_1) { 214 mask = ZYNQMP_SD1_DLL_RST_MASK; 215 val = ZYNQMP_SD1_DLL_RST; 216 } else { 217 return PM_RET_ERROR_ARGS; 218 } 219 220 switch (type) { 221 case PM_DLL_RESET_ASSERT: 222 case PM_DLL_RESET_PULSE: 223 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val, flag); 224 if (ret != PM_RET_SUCCESS) { 225 return ret; 226 } 227 228 if (type == PM_DLL_RESET_ASSERT) { 229 break; 230 } 231 mdelay(1); 232 /* Fallthrough */ 233 case PM_DLL_RESET_RELEASE: 234 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0, flag); 235 break; 236 default: 237 ret = PM_RET_ERROR_ARGS; 238 break; 239 } 240 241 return ret; 242 } 243 244 /** 245 * pm_ioctl_sd_set_tapdelay() - Set tap delay for the SD device. 246 * @nid: Node ID of the device. 247 * @type: Type of tap delay to set (input/output). 248 * @value: Value to set fot the tap delay. 249 * @flag: 0 - Call from secure source. 250 * 1 - Call from non-secure source. 251 * 252 * This function sets input/output tap delay for the SD device. 253 * 254 * Return: Returns status, either success or error+reason. 255 * 256 */ 257 static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid, 258 enum tap_delay_type type, 259 uint32_t value, 260 uint32_t flag) 261 { 262 uint32_t shift; 263 enum pm_ret_status ret; 264 uint32_t val, mask; 265 266 if (nid == NODE_SD_0) { 267 shift = 0; 268 mask = ZYNQMP_SD0_DLL_RST_MASK; 269 } else if (nid == NODE_SD_1) { 270 shift = ZYNQMP_SD_TAP_OFFSET; 271 mask = ZYNQMP_SD1_DLL_RST_MASK; 272 } else { 273 return PM_RET_ERROR_ARGS; 274 } 275 276 ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val, flag); 277 if (ret != PM_RET_SUCCESS) { 278 return ret; 279 } 280 281 if ((val & mask) == 0U) { 282 ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT, flag); 283 if (ret != PM_RET_SUCCESS) { 284 return ret; 285 } 286 } 287 288 if (type == PM_TAPDELAY_INPUT) { 289 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 290 (uint64_t)(ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 291 (ZYNQMP_SD_ITAPCHGWIN << shift), 292 flag); 293 294 if (ret != PM_RET_SUCCESS) { 295 goto reset_release; 296 } 297 298 if (value == 0U) { 299 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 300 (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK << 301 shift), 0, flag); 302 } else { 303 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 304 (uint64_t)(ZYNQMP_SD_ITAPDLYENA_MASK << 305 shift), (uint64_t)(ZYNQMP_SD_ITAPDLYENA << 306 shift), flag); 307 } 308 309 if (ret != PM_RET_SUCCESS) { 310 goto reset_release; 311 } 312 313 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 314 (uint64_t)(ZYNQMP_SD_ITAPDLYSEL_MASK << shift), 315 (value << shift), 316 flag); 317 318 if (ret != PM_RET_SUCCESS) { 319 goto reset_release; 320 } 321 322 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 323 (uint64_t)(ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0, 324 flag); 325 } else if (type == PM_TAPDELAY_OUTPUT) { 326 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY, 327 (uint64_t)(ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0, 328 flag); 329 330 if (ret != PM_RET_SUCCESS) { 331 goto reset_release; 332 } 333 334 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY, 335 (uint64_t)(ZYNQMP_SD_OTAPDLYSEL_MASK << shift), 336 (value << shift), 337 flag); 338 } else { 339 ret = PM_RET_ERROR_ARGS; 340 } 341 342 reset_release: 343 if ((val & mask) == 0) { 344 (void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE, flag); 345 } 346 347 return ret; 348 } 349 350 /** 351 * pm_ioctl_set_pll_frac_mode() - Ioctl function for setting pll mode. 352 * @pll: PLL clock id. 353 * @mode: Mode fraction/integar. 354 * 355 * This function sets PLL mode. 356 * 357 * Return: Returns status, either success or error+reason. 358 * 359 */ 360 static enum pm_ret_status pm_ioctl_set_pll_frac_mode 361 (uint32_t pll, uint32_t mode) 362 { 363 return pm_clock_set_pll_mode(pll, mode); 364 } 365 366 /** 367 * pm_ioctl_get_pll_frac_mode() - Ioctl function for getting pll mode. 368 * @pll: PLL clock id. 369 * @mode: Mode fraction/integar. 370 * 371 * This function return current PLL mode. 372 * 373 * Return: Returns status, either success or error+reason. 374 * 375 */ 376 static enum pm_ret_status pm_ioctl_get_pll_frac_mode 377 (uint32_t pll, uint32_t *mode) 378 { 379 return pm_clock_get_pll_mode(pll, mode); 380 } 381 382 /** 383 * pm_ioctl_set_pll_frac_data() - Ioctl function for setting pll fraction data. 384 * @pll: PLL clock id. 385 * @data: fraction data. 386 * @flag: 0 - Call from secure source. 387 * 1 - Call from non-secure source. 388 * 389 * This function sets fraction data. 390 * It is valid for fraction mode only. 391 * 392 * Return: Returns status, either success or error+reason. 393 * 394 */ 395 static enum pm_ret_status pm_ioctl_set_pll_frac_data 396 (uint32_t pll, uint32_t data, uint32_t flag) 397 { 398 enum pm_node_id pll_nid; 399 enum pm_ret_status status; 400 401 /* Get PLL node ID using PLL clock ID */ 402 status = pm_clock_get_pll_node_id(pll, &pll_nid); 403 if (status == PM_RET_SUCCESS) { 404 status = pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, 405 data, flag); 406 } 407 408 return status; 409 } 410 411 /** 412 * pm_ioctl_get_pll_frac_data() - Ioctl function for getting pll fraction data. 413 * @pll: PLL clock id. 414 * @data: fraction data. 415 * @flag: 0 - Call from secure source. 416 * 1 - Call from non-secure source. 417 * 418 * This function returns fraction data value. 419 * 420 * Return: Returns status, either success or error+reason. 421 * 422 */ 423 static enum pm_ret_status pm_ioctl_get_pll_frac_data 424 (uint32_t pll, uint32_t *data, uint32_t flag) 425 { 426 enum pm_node_id pll_nid; 427 enum pm_ret_status status; 428 429 /* Get PLL node ID using PLL clock ID */ 430 status = pm_clock_get_pll_node_id(pll, &pll_nid); 431 if (status == PM_RET_SUCCESS) { 432 status = pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, 433 data, flag); 434 } 435 436 return status; 437 } 438 439 /** 440 * pm_ioctl_write_ggs() - Ioctl function for writing global general storage 441 * (ggs). 442 * @index: GGS register index. 443 * @value: Register value to be written. 444 * @flag: 0 - Call from secure source. 445 * 1 - Call from non-secure source. 446 * 447 * This function writes value to GGS register. 448 * 449 * Return: Returns status, either success or error+reason. 450 * 451 */ 452 static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index, 453 uint32_t value, 454 uint32_t flag) 455 { 456 enum pm_ret_status ret_status = PM_RET_SUCCESS; 457 458 if (index >= GGS_NUM_REGS) { 459 ret_status = PM_RET_ERROR_ARGS; 460 } else { 461 ret_status = pm_mmio_write((uint64_t)GGS_BASEADDR + (index << 2), 462 0xFFFFFFFFU, value, flag); 463 } 464 465 return ret_status; 466 } 467 468 /** 469 * pm_ioctl_read_ggs() - Ioctl function for reading global general storage 470 * (ggs). 471 * @index: GGS register index. 472 * @value: Register value. 473 * @flag: 0 - Call from secure source. 474 * 1 - Call from non-secure source. 475 * 476 * This function returns GGS register value. 477 * 478 * Return: Returns status, either success or error+reason. 479 * 480 */ 481 static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index, 482 uint32_t *value, 483 uint32_t flag) 484 { 485 enum pm_ret_status ret_status = PM_RET_SUCCESS; 486 487 if (index >= GGS_NUM_REGS) { 488 ret_status = PM_RET_ERROR_ARGS; 489 } else { 490 ret_status = pm_mmio_read((uint64_t)GGS_BASEADDR + (index << 2), 491 value, flag); 492 } 493 494 return ret_status; 495 } 496 497 /** 498 * pm_ioctl_write_pggs() - Ioctl function for writing persistent global general 499 * storage (pggs). 500 * @index: PGGS register index. 501 * @value: Register value to be written. 502 * @flag: 0 - Call from secure source. 503 * 1 - Call from non-secure source. 504 * 505 * This function writes value to PGGS register. 506 * 507 * Return: Returns status, either success or error+reason. 508 * 509 */ 510 static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index, 511 uint32_t value, 512 uint32_t flag) 513 { 514 enum pm_ret_status ret_status = PM_RET_SUCCESS; 515 516 if (index >= PGGS_NUM_REGS) { 517 ret_status = PM_RET_ERROR_ARGS; 518 } else { 519 ret_status = pm_mmio_write((uint64_t)PGGS_BASEADDR + (index << 2), 520 0xFFFFFFFFU, value, flag); 521 } 522 523 return ret_status; 524 } 525 526 /** 527 * pm_ioctl_afi() - Ioctl function for writing afi values. 528 * @index: AFI register index. 529 * @value: Register value to be written. 530 * @flag: 0 - Call from secure source. 531 * 1 - Call from non-secure source. 532 * 533 * Return: Returns status, either success or error+reason. 534 * 535 */ 536 static enum pm_ret_status pm_ioctl_afi(uint32_t index, 537 uint32_t value, 538 uint32_t flag) 539 { 540 uint32_t mask; 541 enum pm_ret_status status = PM_RET_ERROR_ARGS; 542 const uint32_t regarr[] = {0xFD360000U, 543 0xFD360014U, 544 0xFD370000U, 545 0xFD370014U, 546 0xFD380000U, 547 0xFD380014U, 548 0xFD390000U, 549 0xFD390014U, 550 0xFD3a0000U, 551 0xFD3a0014U, 552 0xFD3b0000U, 553 0xFD3b0014U, 554 0xFF9b0000U, 555 0xFF9b0014U, 556 0xFD615000U, 557 0xFF419000U, 558 }; 559 560 if (index < ARRAY_SIZE(regarr)) { 561 if (index <= AFIFM6_WRCTRL) { 562 mask = FABRIC_WIDTH; 563 } else { 564 mask = 0xf00; 565 } 566 status = pm_mmio_write(regarr[index], mask, value, flag); 567 } 568 569 return status; 570 } 571 572 /** 573 * pm_ioctl_read_pggs() - Ioctl function for reading persistent global general 574 * storage (pggs). 575 * @index: PGGS register index. 576 * @value: Register value. 577 * @flag: 0 - Call from secure source. 578 * 1 - Call from non-secure source. 579 * 580 * This function returns PGGS register value. 581 * 582 * Return: Returns status, either success or error+reason. 583 * 584 */ 585 static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index, 586 uint32_t *value, 587 uint32_t flag) 588 { 589 enum pm_ret_status status = 0; 590 591 if (index >= PGGS_NUM_REGS) { 592 status = PM_RET_ERROR_ARGS; 593 } else { 594 status = pm_mmio_read((uint64_t)PGGS_BASEADDR + (index << 2), 595 value, flag); 596 } 597 598 return status; 599 } 600 601 /** 602 * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset. 603 * 604 * @flag: 0 - Call from secure source. 605 * 1 - Call from non-secure source. 606 * 607 * Return: Returns status, either success or error+reason. 608 * 609 * This function peerforms the ULPI reset sequence for resetting 610 * the ULPI transceiver. 611 */ 612 static enum pm_ret_status pm_ioctl_ulpi_reset(uint32_t flag) 613 { 614 enum pm_ret_status ret; 615 616 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK, 617 ZYNQMP_ULPI_RESET_VAL_HIGH, flag); 618 if (ret != PM_RET_SUCCESS) { 619 goto exit_label; 620 } 621 622 /* Drive ULPI assert for atleast 1ms */ 623 mdelay(1); 624 625 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK, 626 ZYNQMP_ULPI_RESET_VAL_LOW, flag); 627 if (ret != PM_RET_SUCCESS) { 628 goto exit_label; 629 } 630 631 /* Drive ULPI de-assert for atleast 1ms */ 632 mdelay(1); 633 634 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK, 635 ZYNQMP_ULPI_RESET_VAL_HIGH, flag); 636 637 exit_label: 638 return ret; 639 } 640 641 /** 642 * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status. 643 * @value: Value to write. 644 * @flag: 0 - Call from secure source. 645 * 1 - Call from non-secure source. 646 * 647 * This function sets healthy bit value to indicate boot health status 648 * to firmware. 649 * 650 * Return: Returns status, either success or error+reason. 651 * 652 */ 653 static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value, 654 uint32_t flag) 655 { 656 return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4, 657 PM_BOOT_HEALTH_STATUS_MASK, value, flag); 658 } 659 660 /** 661 * pm_api_ioctl() - PM IOCTL API for device control and configs. 662 * @nid: Node ID of the device. 663 * @ioctl_id: ID of the requested IOCTL. 664 * @arg1: Argument 1 to requested IOCTL call. 665 * @arg2: Argument 2 to requested IOCTL call. 666 * @value: Returned output value. 667 * @flag: 0 - Call from secure source. 668 * 1 - Call from non-secure source. 669 * 670 * This function calls IOCTL to firmware for device control and configuration. 671 * 672 * Return: Returns status, either success or error+reason. 673 * 674 */ 675 enum pm_ret_status pm_api_ioctl(enum pm_node_id nid, 676 uint32_t ioctl_id, 677 uint32_t arg1, 678 uint32_t arg2, 679 uint32_t *value, 680 uint32_t flag) 681 { 682 enum pm_ret_status ret; 683 uint32_t payload[PAYLOAD_ARG_CNT]; 684 685 switch (ioctl_id) { 686 case IOCTL_GET_RPU_OPER_MODE: 687 ret = pm_ioctl_get_rpu_oper_mode(value); 688 break; 689 case IOCTL_SET_RPU_OPER_MODE: 690 ret = pm_ioctl_set_rpu_oper_mode(arg1); 691 break; 692 case IOCTL_RPU_BOOT_ADDR_CONFIG: 693 ret = pm_ioctl_config_boot_addr(nid, arg1); 694 break; 695 case IOCTL_TCM_COMB_CONFIG: 696 ret = pm_ioctl_config_tcm_comb(arg1); 697 break; 698 case IOCTL_SET_TAPDELAY_BYPASS: 699 ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2, flag); 700 break; 701 case IOCTL_SD_DLL_RESET: 702 ret = pm_ioctl_sd_dll_reset(nid, arg1, flag); 703 break; 704 case IOCTL_SET_SD_TAPDELAY: 705 ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2, flag); 706 break; 707 case IOCTL_SET_PLL_FRAC_MODE: 708 ret = pm_ioctl_set_pll_frac_mode(arg1, arg2); 709 break; 710 case IOCTL_GET_PLL_FRAC_MODE: 711 ret = pm_ioctl_get_pll_frac_mode(arg1, value); 712 break; 713 case IOCTL_SET_PLL_FRAC_DATA: 714 ret = pm_ioctl_set_pll_frac_data(arg1, arg2, flag); 715 break; 716 case IOCTL_GET_PLL_FRAC_DATA: 717 ret = pm_ioctl_get_pll_frac_data(arg1, value, flag); 718 break; 719 case IOCTL_WRITE_GGS: 720 ret = pm_ioctl_write_ggs(arg1, arg2, flag); 721 break; 722 case IOCTL_READ_GGS: 723 ret = pm_ioctl_read_ggs(arg1, value, flag); 724 break; 725 case IOCTL_WRITE_PGGS: 726 ret = pm_ioctl_write_pggs(arg1, arg2, flag); 727 break; 728 case IOCTL_READ_PGGS: 729 ret = pm_ioctl_read_pggs(arg1, value, flag); 730 break; 731 case IOCTL_ULPI_RESET: 732 ret = pm_ioctl_ulpi_reset(flag); 733 break; 734 case IOCTL_SET_BOOT_HEALTH_STATUS: 735 ret = pm_ioctl_set_boot_health_status(arg1, flag); 736 break; 737 case IOCTL_AFI: 738 ret = pm_ioctl_afi(arg1, arg2, flag); 739 break; 740 default: 741 /* Send request to the PMU */ 742 PM_PACK_PAYLOAD5(payload, flag, PM_IOCTL, nid, ioctl_id, arg1, arg2); 743 744 ret = pm_ipi_send_sync(primary_proc, payload, value, 1); 745 break; 746 } 747 748 return ret; 749 } 750 751 /** 752 * tfa_ioctl_bitmask() - API to get supported IOCTL ID mask. 753 * @bit_mask: Returned bit mask of supported IOCTL IDs. 754 * @flag: 0 - Call from secure source. 755 * 1 - Call from non-secure source. 756 * 757 * Return: 0 success, negative value for errors. 758 * 759 */ 760 enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask, uint32_t flag) 761 { 762 const uint8_t supported_ids[] = { 763 IOCTL_GET_RPU_OPER_MODE, 764 IOCTL_SET_RPU_OPER_MODE, 765 IOCTL_RPU_BOOT_ADDR_CONFIG, 766 IOCTL_TCM_COMB_CONFIG, 767 IOCTL_SET_TAPDELAY_BYPASS, 768 IOCTL_SD_DLL_RESET, 769 IOCTL_SET_SD_TAPDELAY, 770 IOCTL_SET_PLL_FRAC_MODE, 771 IOCTL_GET_PLL_FRAC_MODE, 772 IOCTL_SET_PLL_FRAC_DATA, 773 IOCTL_GET_PLL_FRAC_DATA, 774 IOCTL_WRITE_GGS, 775 IOCTL_READ_GGS, 776 IOCTL_WRITE_PGGS, 777 IOCTL_READ_PGGS, 778 IOCTL_ULPI_RESET, 779 IOCTL_SET_BOOT_HEALTH_STATUS, 780 IOCTL_AFI, 781 }; 782 uint8_t i, ioctl_id; 783 enum pm_ret_status ret = PM_RET_SUCCESS; 784 785 for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) { 786 ioctl_id = supported_ids[i]; 787 if (ioctl_id >= 64U) { 788 ret = PM_RET_ERROR_NOTSUPPORTED; 789 break; 790 } 791 ret = check_api_dependency(ioctl_id, flag); 792 if (ret == PM_RET_SUCCESS) { 793 bit_mask[ioctl_id / 32U] |= BIT(ioctl_id % 32U); 794 } 795 } 796 797 return ret; 798 } 799