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