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