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 #include <zynqmp_def.h> 17 18 #include "pm_api_clock.h" 19 #include "pm_api_ioctl.h" 20 #include "pm_client.h" 21 #include "pm_common.h" 22 #include "pm_ipi.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_set_sgmii_mode() - Set SGMII mode for the GEM device. 178 * @nid: Node ID of the device. 179 * @value: Enable/Disable. 180 * 181 * This function enable/disable SGMII mode for the GEM device. 182 * While enabling SGMII mode, it also ties the GEM PCS Signal 183 * Detect to 1 and selects EMIO for RX clock generation. 184 * 185 * Return: Returns status, either success or error+reason. 186 * 187 */ 188 static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid, 189 uint32_t value) 190 { 191 uint32_t val, mask, shift; 192 enum pm_ret_status ret; 193 194 if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) { 195 return PM_RET_ERROR_ARGS; 196 } 197 198 switch (nid) { 199 case NODE_ETH_0: 200 shift = 0; 201 break; 202 case NODE_ETH_1: 203 shift = 1; 204 break; 205 case NODE_ETH_2: 206 shift = 2; 207 break; 208 case NODE_ETH_3: 209 shift = 3; 210 break; 211 default: 212 return PM_RET_ERROR_ARGS; 213 } 214 215 if (value == PM_SGMII_DISABLE) { 216 mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift; 217 ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U); 218 } else { 219 /* Tie the GEM PCS Signal Detect to 1 */ 220 mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift; 221 val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift; 222 ret = pm_mmio_write(IOU_GEM_CTRL, mask, val); 223 if (ret != PM_RET_SUCCESS) { 224 return ret; 225 } 226 227 /* Set the GEM to SGMII mode */ 228 mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift; 229 val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE; 230 val <<= GEM_CLK_CTRL_OFFSET * shift; 231 ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val); 232 } 233 234 return ret; 235 } 236 237 /** 238 * pm_ioctl_sd_dll_reset() - Reset DLL logic. 239 * @nid: Node ID of the device. 240 * @type: Reset type. 241 * 242 * This function resets DLL logic for the SD device. 243 * 244 * Return: Returns status, either success or error+reason. 245 * 246 */ 247 static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid, 248 uint32_t type) 249 { 250 uint32_t mask, val; 251 enum pm_ret_status ret; 252 253 if (nid == NODE_SD_0) { 254 mask = ZYNQMP_SD0_DLL_RST_MASK; 255 val = ZYNQMP_SD0_DLL_RST; 256 } else if (nid == NODE_SD_1) { 257 mask = ZYNQMP_SD1_DLL_RST_MASK; 258 val = ZYNQMP_SD1_DLL_RST; 259 } else { 260 return PM_RET_ERROR_ARGS; 261 } 262 263 switch (type) { 264 case PM_DLL_RESET_ASSERT: 265 case PM_DLL_RESET_PULSE: 266 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val); 267 if (ret != PM_RET_SUCCESS) { 268 return ret; 269 } 270 271 if (type == PM_DLL_RESET_ASSERT) { 272 break; 273 } 274 mdelay(1); 275 /* Fallthrough */ 276 case PM_DLL_RESET_RELEASE: 277 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0); 278 break; 279 default: 280 ret = PM_RET_ERROR_ARGS; 281 break; 282 } 283 284 return ret; 285 } 286 287 /** 288 * pm_ioctl_sd_set_tapdelay() - Set tap delay for the SD device. 289 * @nid: Node ID of the device. 290 * @type: Type of tap delay to set (input/output). 291 * @value: Value to set fot the tap delay. 292 * 293 * This function sets input/output tap delay for the SD device. 294 * 295 * Return: Returns status, either success or error+reason. 296 * 297 */ 298 static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid, 299 enum tap_delay_type type, 300 uint32_t value) 301 { 302 uint32_t shift; 303 enum pm_ret_status ret; 304 uint32_t val, mask; 305 306 if (nid == NODE_SD_0) { 307 shift = 0; 308 mask = ZYNQMP_SD0_DLL_RST_MASK; 309 } else if (nid == NODE_SD_1) { 310 shift = ZYNQMP_SD_TAP_OFFSET; 311 mask = ZYNQMP_SD1_DLL_RST_MASK; 312 } else { 313 return PM_RET_ERROR_ARGS; 314 } 315 316 ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val); 317 if (ret != PM_RET_SUCCESS) { 318 return ret; 319 } 320 321 if ((val & mask) == 0U) { 322 ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT); 323 if (ret != PM_RET_SUCCESS) { 324 return ret; 325 } 326 } 327 328 if (type == PM_TAPDELAY_INPUT) { 329 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 330 (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 331 (ZYNQMP_SD_ITAPCHGWIN << shift)); 332 333 if (ret != PM_RET_SUCCESS) { 334 goto reset_release; 335 } 336 337 if (value == 0U) { 338 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 339 (ZYNQMP_SD_ITAPDLYENA_MASK << 340 shift), 0); 341 } else { 342 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 343 (ZYNQMP_SD_ITAPDLYENA_MASK << 344 shift), (ZYNQMP_SD_ITAPDLYENA << 345 shift)); 346 } 347 348 if (ret != PM_RET_SUCCESS) { 349 goto reset_release; 350 } 351 352 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 353 (ZYNQMP_SD_ITAPDLYSEL_MASK << shift), 354 (value << shift)); 355 356 if (ret != PM_RET_SUCCESS) { 357 goto reset_release; 358 } 359 360 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY, 361 (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0); 362 } else if (type == PM_TAPDELAY_OUTPUT) { 363 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY, 364 (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0); 365 366 if (ret != PM_RET_SUCCESS) { 367 goto reset_release; 368 } 369 370 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY, 371 (ZYNQMP_SD_OTAPDLYSEL_MASK << shift), 372 (value << shift)); 373 } else { 374 ret = PM_RET_ERROR_ARGS; 375 } 376 377 reset_release: 378 if ((val & mask) == 0) { 379 (void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE); 380 } 381 382 return ret; 383 } 384 385 /** 386 * pm_ioctl_set_pll_frac_mode() - Ioctl function for setting pll mode. 387 * @pll: PLL clock id. 388 * @mode: Mode fraction/integar. 389 * 390 * This function sets PLL mode. 391 * 392 * Return: Returns status, either success or error+reason. 393 * 394 */ 395 static enum pm_ret_status pm_ioctl_set_pll_frac_mode 396 (uint32_t pll, uint32_t mode) 397 { 398 return pm_clock_set_pll_mode(pll, mode); 399 } 400 401 /** 402 * pm_ioctl_get_pll_frac_mode() - Ioctl function for getting pll mode. 403 * @pll: PLL clock id. 404 * @mode: Mode fraction/integar. 405 * 406 * This function return current PLL mode. 407 * 408 * Return: Returns status, either success or error+reason. 409 * 410 */ 411 static enum pm_ret_status pm_ioctl_get_pll_frac_mode 412 (uint32_t pll, uint32_t *mode) 413 { 414 return pm_clock_get_pll_mode(pll, mode); 415 } 416 417 /** 418 * pm_ioctl_set_pll_frac_data() - Ioctl function for setting pll fraction data. 419 * @pll: PLL clock id. 420 * @data: fraction data. 421 * 422 * This function sets fraction data. 423 * It is valid for fraction mode only. 424 * 425 * Return: Returns status, either success or error+reason. 426 * 427 */ 428 static enum pm_ret_status pm_ioctl_set_pll_frac_data 429 (uint32_t pll, uint32_t data) 430 { 431 enum pm_node_id pll_nid; 432 enum pm_ret_status status; 433 434 /* Get PLL node ID using PLL clock ID */ 435 status = pm_clock_get_pll_node_id(pll, &pll_nid); 436 if (status != PM_RET_SUCCESS) { 437 return status; 438 } 439 440 return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data); 441 } 442 443 /** 444 * pm_ioctl_get_pll_frac_data() - Ioctl function for getting pll fraction data. 445 * @pll: PLL clock id. 446 * @data: fraction data. 447 * 448 * This function returns fraction data value. 449 * 450 * Return: Returns status, either success or error+reason. 451 * 452 */ 453 static enum pm_ret_status pm_ioctl_get_pll_frac_data 454 (uint32_t pll, uint32_t *data) 455 { 456 enum pm_node_id pll_nid; 457 enum pm_ret_status status; 458 459 /* Get PLL node ID using PLL clock ID */ 460 status = pm_clock_get_pll_node_id(pll, &pll_nid); 461 if (status != PM_RET_SUCCESS) { 462 return status; 463 } 464 465 return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data); 466 } 467 468 /** 469 * pm_ioctl_write_ggs() - Ioctl function for writing global general storage 470 * (ggs). 471 * @index: GGS register index. 472 * @value: Register value to be written. 473 * 474 * This function writes value to GGS register. 475 * 476 * Return: Returns status, either success or error+reason. 477 * 478 */ 479 static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index, 480 uint32_t value) 481 { 482 if (index >= GGS_NUM_REGS) { 483 return PM_RET_ERROR_ARGS; 484 } 485 486 return pm_mmio_write(GGS_BASEADDR + (index << 2), 487 0xFFFFFFFFU, value); 488 } 489 490 /** 491 * pm_ioctl_read_ggs() - Ioctl function for reading global general storage 492 * (ggs). 493 * @index: GGS register index. 494 * @value: Register value. 495 * 496 * This function returns GGS register value. 497 * 498 * Return: Returns status, either success or error+reason. 499 * 500 */ 501 static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index, 502 uint32_t *value) 503 { 504 if (index >= GGS_NUM_REGS) { 505 return PM_RET_ERROR_ARGS; 506 } 507 508 return pm_mmio_read(GGS_BASEADDR + (index << 2), value); 509 } 510 511 /** 512 * pm_ioctl_write_pggs() - Ioctl function for writing persistent global general 513 * storage (pggs). 514 * @index: PGGS register index. 515 * @value: Register value to be written. 516 * 517 * This function writes value to PGGS register. 518 * 519 * Return: Returns status, either success or error+reason. 520 * 521 */ 522 static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index, 523 uint32_t value) 524 { 525 if (index >= PGGS_NUM_REGS) { 526 return PM_RET_ERROR_ARGS; 527 } 528 529 return pm_mmio_write(PGGS_BASEADDR + (index << 2), 530 0xFFFFFFFFU, value); 531 } 532 533 /** 534 * pm_ioctl_afi() - Ioctl function for writing afi values. 535 * @index: AFI register index. 536 * @value: Register value to be written. 537 * 538 * Return: Returns status, either success or error+reason. 539 * 540 */ 541 static enum pm_ret_status pm_ioctl_afi(uint32_t index, 542 uint32_t value) 543 { 544 uint32_t mask; 545 uint32_t regarr[] = {0xFD360000U, 546 0xFD360014U, 547 0xFD370000U, 548 0xFD370014U, 549 0xFD380000U, 550 0xFD380014U, 551 0xFD390000U, 552 0xFD390014U, 553 0xFD3a0000U, 554 0xFD3a0014U, 555 0xFD3b0000U, 556 0xFD3b0014U, 557 0xFF9b0000U, 558 0xFF9b0014U, 559 0xFD615000U, 560 0xFF419000U, 561 }; 562 563 if (index >= ARRAY_SIZE(regarr)) { 564 return PM_RET_ERROR_ARGS; 565 } 566 567 if (index <= AFIFM6_WRCTRL) { 568 mask = FABRIC_WIDTH; 569 } else { 570 mask = 0xf00; 571 } 572 573 return pm_mmio_write(regarr[index], mask, value); 574 } 575 576 /** 577 * pm_ioctl_read_pggs() - Ioctl function for reading persistent global general 578 * storage (pggs). 579 * @index: PGGS register index. 580 * @value: Register value. 581 * 582 * This function returns PGGS register value. 583 * 584 * Return: Returns status, either success or error+reason. 585 * 586 */ 587 static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index, 588 uint32_t *value) 589 { 590 if (index >= PGGS_NUM_REGS) { 591 return PM_RET_ERROR_ARGS; 592 } 593 594 return pm_mmio_read(PGGS_BASEADDR + (index << 2), value); 595 } 596 597 /** 598 * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset. 599 * 600 * Return: Returns status, either success or error+reason. 601 * 602 * This function peerforms the ULPI reset sequence for resetting 603 * the ULPI transceiver. 604 */ 605 static enum pm_ret_status pm_ioctl_ulpi_reset(void) 606 { 607 enum pm_ret_status ret; 608 609 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK, 610 ZYNQMP_ULPI_RESET_VAL_HIGH); 611 if (ret != PM_RET_SUCCESS) { 612 return ret; 613 } 614 615 /* Drive ULPI assert for atleast 1ms */ 616 mdelay(1); 617 618 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK, 619 ZYNQMP_ULPI_RESET_VAL_LOW); 620 if (ret != PM_RET_SUCCESS) { 621 return ret; 622 } 623 624 /* Drive ULPI de-assert for atleast 1ms */ 625 mdelay(1); 626 627 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK, 628 ZYNQMP_ULPI_RESET_VAL_HIGH); 629 630 return ret; 631 } 632 633 /** 634 * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status. 635 * @value: Value to write. 636 * 637 * This function sets healthy bit value to indicate boot health status 638 * to firmware. 639 * 640 * Return: Returns status, either success or error+reason. 641 * 642 */ 643 static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value) 644 { 645 return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4, 646 PM_BOOT_HEALTH_STATUS_MASK, value); 647 } 648 649 /** 650 * pm_api_ioctl() - PM IOCTL API for device control and configs. 651 * @nid: Node ID of the device. 652 * @ioctl_id: ID of the requested IOCTL. 653 * @arg1: Argument 1 to requested IOCTL call. 654 * @arg2: Argument 2 to requested IOCTL call. 655 * @value: Returned output value. 656 * 657 * This function calls IOCTL to firmware for device control and configuration. 658 * 659 * Return: Returns status, either success or error+reason. 660 * 661 */ 662 enum pm_ret_status pm_api_ioctl(enum pm_node_id nid, 663 uint32_t ioctl_id, 664 uint32_t arg1, 665 uint32_t arg2, 666 uint32_t *value) 667 { 668 enum pm_ret_status ret; 669 uint32_t payload[PAYLOAD_ARG_CNT]; 670 671 switch (ioctl_id) { 672 case IOCTL_GET_RPU_OPER_MODE: 673 ret = pm_ioctl_get_rpu_oper_mode(value); 674 break; 675 case IOCTL_SET_RPU_OPER_MODE: 676 ret = pm_ioctl_set_rpu_oper_mode(arg1); 677 break; 678 case IOCTL_RPU_BOOT_ADDR_CONFIG: 679 ret = pm_ioctl_config_boot_addr(nid, arg1); 680 break; 681 case IOCTL_TCM_COMB_CONFIG: 682 ret = pm_ioctl_config_tcm_comb(arg1); 683 break; 684 case IOCTL_SET_TAPDELAY_BYPASS: 685 ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2); 686 break; 687 case IOCTL_SET_SGMII_MODE: 688 ret = pm_ioctl_set_sgmii_mode(nid, arg1); 689 break; 690 case IOCTL_SD_DLL_RESET: 691 ret = pm_ioctl_sd_dll_reset(nid, arg1); 692 break; 693 case IOCTL_SET_SD_TAPDELAY: 694 ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2); 695 break; 696 case IOCTL_SET_PLL_FRAC_MODE: 697 ret = pm_ioctl_set_pll_frac_mode(arg1, arg2); 698 break; 699 case IOCTL_GET_PLL_FRAC_MODE: 700 ret = pm_ioctl_get_pll_frac_mode(arg1, value); 701 break; 702 case IOCTL_SET_PLL_FRAC_DATA: 703 ret = pm_ioctl_set_pll_frac_data(arg1, arg2); 704 break; 705 case IOCTL_GET_PLL_FRAC_DATA: 706 ret = pm_ioctl_get_pll_frac_data(arg1, value); 707 break; 708 case IOCTL_WRITE_GGS: 709 ret = pm_ioctl_write_ggs(arg1, arg2); 710 break; 711 case IOCTL_READ_GGS: 712 ret = pm_ioctl_read_ggs(arg1, value); 713 break; 714 case IOCTL_WRITE_PGGS: 715 ret = pm_ioctl_write_pggs(arg1, arg2); 716 break; 717 case IOCTL_READ_PGGS: 718 ret = pm_ioctl_read_pggs(arg1, value); 719 break; 720 case IOCTL_ULPI_RESET: 721 ret = pm_ioctl_ulpi_reset(); 722 break; 723 case IOCTL_SET_BOOT_HEALTH_STATUS: 724 ret = pm_ioctl_set_boot_health_status(arg1); 725 break; 726 case IOCTL_AFI: 727 ret = pm_ioctl_afi(arg1, arg2); 728 break; 729 default: 730 /* Send request to the PMU */ 731 PM_PACK_PAYLOAD5(payload, PM_IOCTL, nid, ioctl_id, arg1, arg2); 732 733 ret = pm_ipi_send_sync(primary_proc, payload, value, 1); 734 break; 735 } 736 737 return ret; 738 } 739 740 /** 741 * tfa_ioctl_bitmask() - API to get supported IOCTL ID mask. 742 * @bit_mask: Returned bit mask of supported IOCTL IDs. 743 * 744 * Return: 0 success, negative value for errors. 745 * 746 */ 747 enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask) 748 { 749 uint8_t supported_ids[] = { 750 IOCTL_GET_RPU_OPER_MODE, 751 IOCTL_SET_RPU_OPER_MODE, 752 IOCTL_RPU_BOOT_ADDR_CONFIG, 753 IOCTL_TCM_COMB_CONFIG, 754 IOCTL_SET_TAPDELAY_BYPASS, 755 IOCTL_SET_SGMII_MODE, 756 IOCTL_SD_DLL_RESET, 757 IOCTL_SET_SD_TAPDELAY, 758 IOCTL_SET_PLL_FRAC_MODE, 759 IOCTL_GET_PLL_FRAC_MODE, 760 IOCTL_SET_PLL_FRAC_DATA, 761 IOCTL_GET_PLL_FRAC_DATA, 762 IOCTL_WRITE_GGS, 763 IOCTL_READ_GGS, 764 IOCTL_WRITE_PGGS, 765 IOCTL_READ_PGGS, 766 IOCTL_ULPI_RESET, 767 IOCTL_SET_BOOT_HEALTH_STATUS, 768 IOCTL_AFI, 769 }; 770 uint8_t i, ioctl_id; 771 int32_t ret; 772 773 for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) { 774 ioctl_id = supported_ids[i]; 775 if (ioctl_id >= 64U) { 776 return PM_RET_ERROR_NOTSUPPORTED; 777 } 778 ret = check_api_dependency(ioctl_id); 779 if (ret == PM_RET_SUCCESS) { 780 bit_mask[ioctl_id / 32U] |= BIT(ioctl_id % 32U); 781 } 782 } 783 784 return PM_RET_SUCCESS; 785 } 786