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