1 /** @file 2 The OHCI register operation routines. 3 4 Copyright (c) 2013-2015 Intel Corporation. 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 17 #include "OhcPeim.h" 18 19 /** 20 21 Get OHCI operational reg value 22 23 @param Ohc UHC private data 24 @param Offset Offset of the operational reg 25 26 @retval Value of the register 27 28 **/ 29 UINT32 30 OhciGetOperationalReg ( 31 IN USB_OHCI_HC_DEV *Ohc, 32 IN UINT32 Offset 33 ) 34 { 35 36 return MmioRead32 (Ohc->UsbHostControllerBaseAddress + Offset); 37 38 } 39 /** 40 41 Set OHCI operational reg value 42 43 @param Ohc UHC private data 44 @param Offset Offset of the operational reg 45 @param Value Value to set 46 47 @retval EFI_SUCCESS Value set to the reg 48 49 **/ 50 51 52 EFI_STATUS 53 OhciSetOperationalReg ( 54 USB_OHCI_HC_DEV *Ohc, 55 IN UINT32 Offset, 56 IN UINT32 *Value 57 ) 58 { 59 MmioWrite32(Ohc->UsbHostControllerBaseAddress + Offset, *Value); 60 return EFI_SUCCESS; 61 } 62 /** 63 64 Get HcRevision reg value 65 66 @param Ohc UHC private data 67 68 @retval Value of the register 69 70 **/ 71 72 73 UINT32 74 OhciGetHcRevision ( 75 USB_OHCI_HC_DEV *Ohc 76 ) 77 { 78 return OhciGetOperationalReg (Ohc, HC_REVISION); 79 } 80 /** 81 82 Set HcReset reg value 83 84 85 @param Ohc UHC private data 86 @param Field Field to set 87 @param Value Value to set 88 89 @retval EFI_SUCCESS Value set 90 91 **/ 92 93 EFI_STATUS 94 OhciSetHcReset ( 95 IN USB_OHCI_HC_DEV *Ohc, 96 IN UINT32 Field, 97 IN UINT32 Value 98 ) 99 { 100 EFI_STATUS Status; 101 HcRESET Reset; 102 103 Status = EFI_SUCCESS; 104 *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR); 105 106 if (Field & RESET_SYSTEM_BUS) { 107 Reset.FSBIR = Value; 108 } 109 110 if (Field & RESET_HOST_CONTROLLER) { 111 Reset.FHR = Value; 112 } 113 114 if (Field & RESET_CLOCK_GENERATION) { 115 Reset.CGR = Value; 116 } 117 118 if (Field & RESET_SSE_GLOBAL) { 119 Reset.SSE = Value; 120 } 121 122 if (Field & RESET_PSPL) { 123 Reset.PSPL = Value; 124 } 125 126 if (Field & RESET_PCPL) { 127 Reset.PCPL = Value; 128 } 129 130 if (Field & RESET_SSEP1) { 131 Reset.SSEP1 = Value; 132 } 133 134 if (Field & RESET_SSEP2) { 135 Reset.SSEP2 = Value; 136 } 137 138 if (Field & RESET_SSEP3) { 139 Reset.SSEP3 = Value; 140 } 141 142 OhciSetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR, (UINT32*)&Reset); 143 144 return EFI_SUCCESS; 145 } 146 147 /** 148 149 Get specific field of HcReset reg value 150 151 @param Ohc UHC private data 152 @param Field Field to get 153 154 @retval Value of the field 155 156 **/ 157 158 UINT32 159 OhciGetHcReset ( 160 IN USB_OHCI_HC_DEV *Ohc, 161 IN UINT32 Field 162 ) 163 { 164 HcRESET Reset; 165 UINT32 Value; 166 167 168 *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR); 169 Value = 0; 170 171 switch (Field) { 172 case RESET_SYSTEM_BUS: 173 Value = Reset.FSBIR; 174 break; 175 176 case RESET_HOST_CONTROLLER: 177 Value = Reset.FHR; 178 break; 179 180 case RESET_CLOCK_GENERATION: 181 Value = Reset.CGR; 182 break; 183 184 case RESET_SSE_GLOBAL: 185 Value = Reset.SSE; 186 break; 187 188 case RESET_PSPL: 189 Value = Reset.PSPL; 190 break; 191 192 case RESET_PCPL: 193 Value = Reset.PCPL; 194 break; 195 196 case RESET_SSEP1: 197 Value = Reset.SSEP1; 198 break; 199 200 case RESET_SSEP2: 201 Value = Reset.SSEP2; 202 break; 203 204 case RESET_SSEP3: 205 Value = Reset.SSEP3; 206 break; 207 208 default: 209 ASSERT (FALSE); 210 } 211 212 213 return Value; 214 } 215 216 /** 217 218 Set HcControl reg value 219 220 @param Ohc UHC private data 221 @param Field Field to set 222 @param Value Value to set 223 224 @retval EFI_SUCCESS Value set 225 226 **/ 227 228 EFI_STATUS 229 OhciSetHcControl ( 230 IN USB_OHCI_HC_DEV *Ohc, 231 IN UINTN Field, 232 IN UINT32 Value 233 ) 234 { 235 EFI_STATUS Status; 236 HcCONTROL Control; 237 238 239 240 *(UINT32 *) &Control = OhciGetOperationalReg (Ohc, HC_CONTROL); 241 242 if (Field & CONTROL_BULK_RATIO) { 243 Control.ControlBulkRatio = Value; 244 } 245 246 if (Field & HC_FUNCTIONAL_STATE) { 247 Control.FunctionalState = Value; 248 } 249 250 if (Field & PERIODIC_ENABLE) { 251 Control.PeriodicEnable = Value; 252 } 253 254 if (Field & CONTROL_ENABLE) { 255 Control.ControlEnable = Value; 256 } 257 258 if (Field & ISOCHRONOUS_ENABLE) { 259 Control.IsochronousEnable = Value; 260 } 261 262 if (Field & BULK_ENABLE) { 263 Control.BulkEnable = Value; 264 } 265 266 if (Field & INTERRUPT_ROUTING) { 267 Control.InterruptRouting = Value; 268 } 269 270 Status = OhciSetOperationalReg (Ohc, HC_CONTROL, (UINT32*)&Control); 271 272 return Status; 273 } 274 275 276 /** 277 278 Get specific field of HcControl reg value 279 280 @param Ohc UHC private data 281 @param Field Field to get 282 283 @retval Value of the field 284 285 **/ 286 287 288 UINT32 289 OhciGetHcControl ( 290 IN USB_OHCI_HC_DEV *Ohc, 291 IN UINTN Field 292 ) 293 { 294 HcCONTROL Control; 295 296 *(UINT32 *) &Control = OhciGetOperationalReg (Ohc, HC_CONTROL); 297 298 switch (Field) { 299 case CONTROL_BULK_RATIO: 300 return Control.ControlBulkRatio; 301 break; 302 case PERIODIC_ENABLE: 303 return Control.PeriodicEnable; 304 break; 305 case CONTROL_ENABLE: 306 return Control.ControlEnable; 307 break; 308 case BULK_ENABLE: 309 return Control.BulkEnable; 310 break; 311 case ISOCHRONOUS_ENABLE: 312 return Control.IsochronousEnable; 313 break; 314 case HC_FUNCTIONAL_STATE: 315 return Control.FunctionalState; 316 break; 317 case INTERRUPT_ROUTING: 318 return Control.InterruptRouting; 319 break; 320 default: 321 ASSERT (FALSE); 322 } 323 324 return 0; 325 } 326 327 /** 328 329 Set HcCommand reg value 330 331 @param Ohc UHC private data 332 @param Field Field to set 333 @param Value Value to set 334 335 @retval EFI_SUCCESS Value set 336 337 **/ 338 339 EFI_STATUS 340 OhciSetHcCommandStatus ( 341 IN USB_OHCI_HC_DEV *Ohc, 342 IN UINTN Field, 343 IN UINT32 Value 344 ) 345 { 346 EFI_STATUS Status; 347 HcCOMMAND_STATUS CommandStatus; 348 349 ZeroMem (&CommandStatus, sizeof (HcCOMMAND_STATUS)); 350 351 if(Field & HC_RESET){ 352 CommandStatus.HcReset = Value; 353 } 354 355 if(Field & CONTROL_LIST_FILLED){ 356 CommandStatus.ControlListFilled = Value; 357 } 358 359 if(Field & BULK_LIST_FILLED){ 360 CommandStatus.BulkListFilled = Value; 361 } 362 363 if(Field & CHANGE_OWNER_REQUEST){ 364 CommandStatus.ChangeOwnerRequest = Value; 365 } 366 367 if(Field & SCHEDULE_OVERRUN_COUNT){ 368 CommandStatus.ScheduleOverrunCount = Value; 369 } 370 371 Status = OhciSetOperationalReg (Ohc, HC_COMMAND_STATUS, (UINT32*)&CommandStatus); 372 373 return Status; 374 } 375 376 /** 377 378 Get specific field of HcCommand reg value 379 380 @param Ohc UHC private data 381 @param Field Field to get 382 383 @retval Value of the field 384 385 **/ 386 387 UINT32 388 OhciGetHcCommandStatus ( 389 IN USB_OHCI_HC_DEV *Ohc, 390 IN UINTN Field 391 ) 392 { 393 HcCOMMAND_STATUS CommandStatus; 394 395 *(UINT32 *) &CommandStatus = OhciGetOperationalReg (Ohc, HC_COMMAND_STATUS); 396 397 switch (Field){ 398 case HC_RESET: 399 return CommandStatus.HcReset; 400 break; 401 case CONTROL_LIST_FILLED: 402 return CommandStatus.ControlListFilled; 403 break; 404 case BULK_LIST_FILLED: 405 return CommandStatus.BulkListFilled; 406 break; 407 case CHANGE_OWNER_REQUEST: 408 return CommandStatus.ChangeOwnerRequest; 409 break; 410 case SCHEDULE_OVERRUN_COUNT: 411 return CommandStatus.ScheduleOverrunCount; 412 break; 413 default: 414 ASSERT (FALSE); 415 } 416 417 return 0; 418 } 419 420 /** 421 422 Clear specific fields of Interrupt Status 423 424 @param Ohc UHC private data 425 @param Field Field to clear 426 427 @retval EFI_SUCCESS Fields cleared 428 429 **/ 430 431 EFI_STATUS 432 OhciClearInterruptStatus ( 433 IN USB_OHCI_HC_DEV *Ohc, 434 IN UINTN Field 435 ) 436 { 437 EFI_STATUS Status; 438 HcINTERRUPT_STATUS InterruptStatus; 439 440 ZeroMem (&InterruptStatus, sizeof (HcINTERRUPT_STATUS)); 441 442 if(Field & SCHEDULE_OVERRUN){ 443 InterruptStatus.SchedulingOverrun = 1; 444 } 445 446 if(Field & WRITEBACK_DONE_HEAD){ 447 InterruptStatus.WriteBackDone = 1; 448 } 449 if(Field & START_OF_FRAME){ 450 InterruptStatus.Sof = 1; 451 } 452 453 if(Field & RESUME_DETECT){ 454 InterruptStatus.ResumeDetected = 1; 455 } 456 457 if(Field & UNRECOVERABLE_ERROR){ 458 InterruptStatus.UnrecoverableError = 1; 459 } 460 461 if(Field & FRAME_NUMBER_OVERFLOW){ 462 InterruptStatus.FrameNumOverflow = 1; 463 } 464 465 if(Field & ROOTHUB_STATUS_CHANGE){ 466 InterruptStatus.RHStatusChange = 1; 467 } 468 469 if(Field & OWNERSHIP_CHANGE){ 470 InterruptStatus.OwnerChange = 1; 471 } 472 473 Status = OhciSetOperationalReg (Ohc, HC_INTERRUPT_STATUS, (UINT32*)&InterruptStatus); 474 475 return Status; 476 } 477 478 /** 479 480 Get fields of HcInterrupt reg value 481 482 @param Ohc UHC private data 483 @param Field Field to get 484 485 @retval Value of the field 486 487 **/ 488 489 UINT32 490 OhciGetHcInterruptStatus ( 491 IN USB_OHCI_HC_DEV *Ohc, 492 IN UINTN Field 493 ) 494 { 495 HcINTERRUPT_STATUS InterruptStatus; 496 497 *(UINT32 *) &InterruptStatus = OhciGetOperationalReg (Ohc, HC_INTERRUPT_STATUS); 498 499 switch (Field){ 500 case SCHEDULE_OVERRUN: 501 return InterruptStatus.SchedulingOverrun; 502 break; 503 504 case WRITEBACK_DONE_HEAD: 505 return InterruptStatus.WriteBackDone; 506 break; 507 508 case START_OF_FRAME: 509 return InterruptStatus.Sof; 510 break; 511 512 case RESUME_DETECT: 513 return InterruptStatus.ResumeDetected; 514 break; 515 516 case UNRECOVERABLE_ERROR: 517 return InterruptStatus.UnrecoverableError; 518 break; 519 520 case FRAME_NUMBER_OVERFLOW: 521 return InterruptStatus.FrameNumOverflow; 522 break; 523 524 case ROOTHUB_STATUS_CHANGE: 525 return InterruptStatus.RHStatusChange; 526 break; 527 528 case OWNERSHIP_CHANGE: 529 return InterruptStatus.OwnerChange; 530 break; 531 532 default: 533 ASSERT (FALSE); 534 } 535 536 return 0; 537 } 538 539 /** 540 541 Set Interrupt Control reg value 542 543 @param Ohc UHC private data 544 @param StatEnable Enable or Disable 545 @param Field Field to set 546 @param Value Value to set 547 548 @retval EFI_SUCCESS Value set 549 550 **/ 551 552 EFI_STATUS 553 OhciSetInterruptControl ( 554 IN USB_OHCI_HC_DEV *Ohc, 555 IN BOOLEAN StatEnable, 556 IN UINTN Field, 557 IN UINT32 Value 558 ) 559 { 560 EFI_STATUS Status; 561 HcINTERRUPT_CONTROL InterruptState; 562 563 564 ZeroMem (&InterruptState, sizeof (HcINTERRUPT_CONTROL)); 565 566 if(Field & SCHEDULE_OVERRUN) { 567 InterruptState.SchedulingOverrunInt = Value; 568 } 569 570 if(Field & WRITEBACK_DONE_HEAD) { 571 InterruptState.WriteBackDoneInt = Value; 572 } 573 if(Field & START_OF_FRAME) { 574 InterruptState.SofInt = Value; 575 } 576 577 if(Field & RESUME_DETECT) { 578 InterruptState.ResumeDetectedInt = Value; 579 } 580 581 if(Field & UNRECOVERABLE_ERROR) { 582 InterruptState.UnrecoverableErrorInt = Value; 583 } 584 585 if(Field & FRAME_NUMBER_OVERFLOW) { 586 InterruptState.FrameNumOverflowInt = Value; 587 } 588 589 if(Field & ROOTHUB_STATUS_CHANGE) { 590 InterruptState.RHStatusChangeInt = Value; 591 } 592 593 if(Field & OWNERSHIP_CHANGE) { 594 InterruptState.OwnerChangedInt = Value; 595 } 596 597 if(Field & MASTER_INTERRUPT) { 598 InterruptState.MasterInterruptEnable = Value; 599 } 600 601 if (StatEnable) { 602 Status = OhciSetOperationalReg (Ohc, HC_INTERRUPT_ENABLE, (UINT32*)&InterruptState); 603 } else { 604 Status = OhciSetOperationalReg (Ohc, HC_INTERRUPT_DISABLE, (UINT32*)&InterruptState); 605 } 606 607 return Status; 608 } 609 610 /** 611 612 Get field of HcInterruptControl reg value 613 614 @param Ohc UHC private data 615 @param Field Field to get 616 617 @retval Value of the field 618 619 **/ 620 621 UINT32 622 OhciGetHcInterruptControl ( 623 IN USB_OHCI_HC_DEV *Ohc, 624 IN UINTN Field 625 ) 626 { 627 HcINTERRUPT_CONTROL InterruptState; 628 629 *(UINT32 *) &InterruptState = OhciGetOperationalReg (Ohc, HC_INTERRUPT_ENABLE); 630 631 switch (Field){ 632 case SCHEDULE_OVERRUN: 633 return InterruptState.SchedulingOverrunInt; 634 break; 635 636 case WRITEBACK_DONE_HEAD: 637 return InterruptState.WriteBackDoneInt; 638 break; 639 640 case START_OF_FRAME: 641 return InterruptState.SofInt; 642 break; 643 644 case RESUME_DETECT: 645 return InterruptState.ResumeDetectedInt; 646 break; 647 648 case UNRECOVERABLE_ERROR: 649 return InterruptState.UnrecoverableErrorInt; 650 break; 651 652 case FRAME_NUMBER_OVERFLOW: 653 return InterruptState.FrameNumOverflowInt; 654 break; 655 656 case ROOTHUB_STATUS_CHANGE: 657 return InterruptState.RHStatusChangeInt; 658 break; 659 660 case OWNERSHIP_CHANGE: 661 return InterruptState.OwnerChangedInt; 662 break; 663 664 case MASTER_INTERRUPT: 665 return InterruptState.MasterInterruptEnable; 666 break; 667 668 default: 669 ASSERT (FALSE); 670 } 671 672 return 0; 673 } 674 675 /** 676 677 Set memory pointer of specific type 678 679 @param Ohc UHC private data 680 @param PointerType Type of the pointer to set 681 @param Value Value to set 682 683 @retval EFI_SUCCESS Memory pointer set 684 685 **/ 686 687 EFI_STATUS 688 OhciSetMemoryPointer( 689 IN USB_OHCI_HC_DEV *Ohc, 690 IN UINTN PointerType, 691 IN VOID *Value 692 ) 693 { 694 EFI_STATUS Status; 695 UINT32 Verify; 696 697 Status = OhciSetOperationalReg (Ohc, PointerType, (UINT32*)&Value); 698 699 if (EFI_ERROR (Status)) { 700 return Status; 701 } 702 703 Verify = OhciGetOperationalReg (Ohc, PointerType); 704 705 while (Verify != (UINT32) Value) { 706 MicroSecondDelay (HC_1_MILLISECOND); 707 Verify = OhciGetOperationalReg (Ohc, PointerType); 708 }; 709 710 711 return Status; 712 } 713 714 /** 715 716 Get memory pointer of specific type 717 718 @param Ohc UHC private data 719 @param PointerType Type of pointer 720 721 @retval Memory pointer of the specific type 722 723 **/ 724 725 VOID * 726 OhciGetMemoryPointer ( 727 IN USB_OHCI_HC_DEV *Ohc, 728 IN UINTN PointerType 729 ) 730 { 731 732 return (VOID *) OhciGetOperationalReg (Ohc, PointerType); 733 } 734 735 736 /** 737 738 Set Frame Interval value 739 740 @param Ohc UHC private data 741 @param Field Field to set 742 @param Value Value to set 743 744 @retval EFI_SUCCESS Value set 745 746 **/ 747 748 EFI_STATUS 749 OhciSetFrameInterval ( 750 IN USB_OHCI_HC_DEV *Ohc, 751 IN UINTN Field, 752 IN UINT32 Value 753 ) 754 { 755 EFI_STATUS Status; 756 HcFRM_INTERVAL FrameInterval; 757 758 759 *(UINT32 *) &FrameInterval = OhciGetOperationalReg(Ohc, HC_FRM_INTERVAL); 760 761 if (Field & FRAME_INTERVAL) { 762 FrameInterval.FrmIntervalToggle = !FrameInterval.FrmIntervalToggle; 763 FrameInterval.FrameInterval = Value; 764 } 765 766 if (Field & FS_LARGEST_DATA_PACKET) { 767 FrameInterval.FSMaxDataPacket = Value; 768 } 769 770 if (Field & FRMINT_TOGGLE) { 771 FrameInterval.FrmIntervalToggle = Value; 772 } 773 774 Status = OhciSetOperationalReg ( 775 Ohc, 776 HC_FRM_INTERVAL, 777 (UINT32*)&FrameInterval 778 ); 779 780 return Status; 781 } 782 783 784 /** 785 786 Get field of frame interval reg value 787 788 @param Ohc UHC private data 789 @param Field Field to get 790 791 @retval Value of the field 792 793 **/ 794 795 UINT32 796 OhciGetFrameInterval ( 797 IN USB_OHCI_HC_DEV *Ohc, 798 IN UINTN Field 799 ) 800 { 801 HcFRM_INTERVAL FrameInterval; 802 803 *(UINT32 *) &FrameInterval = OhciGetOperationalReg (Ohc, HC_FRM_INTERVAL); 804 805 switch (Field){ 806 case FRAME_INTERVAL: 807 return FrameInterval.FrameInterval; 808 break; 809 810 case FS_LARGEST_DATA_PACKET: 811 return FrameInterval.FSMaxDataPacket; 812 break; 813 814 case FRMINT_TOGGLE: 815 return FrameInterval.FrmIntervalToggle; 816 break; 817 818 default: 819 ASSERT (FALSE); 820 } 821 822 return 0; 823 } 824 825 /** 826 827 Set Frame Remaining reg value 828 829 @param Ohc UHC private data 830 @param Value Value to set 831 832 @retval EFI_SUCCESS Value set 833 834 **/ 835 836 EFI_STATUS 837 OhciSetFrameRemaining ( 838 IN USB_OHCI_HC_DEV *Ohc, 839 IN UINT32 Value 840 ) 841 { 842 EFI_STATUS Status; 843 HcFRAME_REMAINING FrameRemaining; 844 845 846 *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc, HC_FRM_REMAINING); 847 848 FrameRemaining.FrameRemaining = Value; 849 FrameRemaining.FrameRemainingToggle = !FrameRemaining.FrameRemainingToggle; 850 851 Status = OhciSetOperationalReg (Ohc, HC_FRM_REMAINING, (UINT32*)&FrameRemaining); 852 853 return Status; 854 } 855 /** 856 857 Get value of frame remaining reg 858 859 @param Ohc UHC private data 860 @param Field Field to get 861 862 @retval Value of frame remaining reg 863 864 **/ 865 UINT32 866 OhciGetFrameRemaining ( 867 IN USB_OHCI_HC_DEV *Ohc, 868 IN UINTN Field 869 ) 870 871 { 872 HcFRAME_REMAINING FrameRemaining; 873 874 875 *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc, HC_FRM_REMAINING); 876 877 switch (Field){ 878 case FRAME_REMAINING: 879 return FrameRemaining.FrameRemaining; 880 break; 881 882 case FRAME_REMAIN_TOGGLE: 883 return FrameRemaining.FrameRemainingToggle; 884 break; 885 886 default: 887 ASSERT (FALSE); 888 } 889 890 return 0; 891 } 892 893 /** 894 895 Set frame number reg value 896 897 @param Ohc UHC private data 898 @param Value Value to set 899 900 @retval EFI_SUCCESS Value set 901 902 **/ 903 904 EFI_STATUS 905 OhciSetFrameNumber( 906 IN USB_OHCI_HC_DEV *Ohc, 907 IN UINT32 Value 908 ) 909 { 910 EFI_STATUS Status; 911 912 Status = OhciSetOperationalReg (Ohc, HC_FRM_NUMBER, &Value); 913 914 return Status; 915 } 916 917 /** 918 919 Get frame number reg value 920 921 @param Ohc UHC private data 922 923 @retval Value of frame number reg 924 925 **/ 926 927 UINT32 928 OhciGetFrameNumber ( 929 IN USB_OHCI_HC_DEV *Ohc 930 ) 931 { 932 return OhciGetOperationalReg(Ohc, HC_FRM_NUMBER); 933 } 934 935 /** 936 937 Set period start reg value 938 939 @param Ohc UHC private data 940 @param Value Value to set 941 942 @retval EFI_SUCCESS Value set 943 944 **/ 945 946 EFI_STATUS 947 OhciSetPeriodicStart ( 948 IN USB_OHCI_HC_DEV *Ohc, 949 IN UINT32 Value 950 ) 951 { 952 EFI_STATUS Status; 953 954 955 Status = OhciSetOperationalReg (Ohc, HC_PERIODIC_START, &Value); 956 957 return Status; 958 } 959 960 961 /** 962 963 Get periodic start reg value 964 965 @param Ohc UHC private data 966 967 @param Value of periodic start reg 968 969 **/ 970 971 UINT32 972 OhciGetPeriodicStart ( 973 IN USB_OHCI_HC_DEV *Ohc 974 ) 975 { 976 return OhciGetOperationalReg(Ohc, HC_PERIODIC_START); 977 } 978 979 980 /** 981 982 Set Ls Threshold reg value 983 984 @param Ohc UHC private data 985 @param Value Value to set 986 987 @retval EFI_SUCCESS Value set 988 989 **/ 990 991 EFI_STATUS 992 OhciSetLsThreshold ( 993 IN USB_OHCI_HC_DEV *Ohc, 994 IN UINT32 Value 995 ) 996 { 997 EFI_STATUS Status; 998 999 1000 Status = OhciSetOperationalReg (Ohc, HC_LS_THREASHOLD, &Value); 1001 1002 return Status; 1003 } 1004 1005 1006 /** 1007 1008 Get Ls Threshold reg value 1009 1010 @param Ohc UHC private data 1011 1012 @retval Value of Ls Threshold reg 1013 1014 **/ 1015 1016 UINT32 1017 OhciGetLsThreshold ( 1018 IN USB_OHCI_HC_DEV *Ohc 1019 ) 1020 { 1021 return OhciGetOperationalReg(Ohc, HC_LS_THREASHOLD); 1022 } 1023 1024 /** 1025 1026 Set Root Hub Descriptor reg value 1027 1028 @param Ohc UHC private data 1029 @param Field Field to set 1030 @param Value Value to set 1031 1032 @retval EFI_SUCCESS Value set 1033 1034 **/ 1035 EFI_STATUS 1036 OhciSetRootHubDescriptor ( 1037 IN USB_OHCI_HC_DEV *Ohc, 1038 IN UINTN Field, 1039 IN UINT32 Value 1040 ) 1041 { 1042 EFI_STATUS Status; 1043 HcRH_DESC_A DescriptorA; 1044 HcRH_DESC_B DescriptorB; 1045 1046 1047 if (Field & (RH_DEV_REMOVABLE || RH_PORT_PWR_CTRL_MASK)) { 1048 *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc, HC_RH_DESC_B); 1049 1050 if(Field & RH_DEV_REMOVABLE) { 1051 DescriptorB.DeviceRemovable = Value; 1052 } 1053 if(Field & RH_PORT_PWR_CTRL_MASK) { 1054 DescriptorB.PortPowerControlMask = Value; 1055 } 1056 1057 Status = OhciSetOperationalReg (Ohc, HC_RH_DESC_B, (UINT32*)&DescriptorB); 1058 1059 return Status; 1060 } 1061 1062 *(UINT32 *)&DescriptorA = OhciGetOperationalReg (Ohc, HC_RH_DESC_A); 1063 1064 if(Field & RH_NUM_DS_PORTS) { 1065 DescriptorA.NumDownStrmPorts = Value; 1066 } 1067 if(Field & RH_NO_PSWITCH) { 1068 DescriptorA.NoPowerSwitch = Value; 1069 } 1070 if(Field & RH_PSWITCH_MODE) { 1071 DescriptorA.PowerSwitchMode = Value; 1072 } 1073 if(Field & RH_DEVICE_TYPE) { 1074 DescriptorA.DeviceType = Value; 1075 } 1076 if(Field & RH_OC_PROT_MODE) { 1077 DescriptorA.OverCurrentProtMode = Value; 1078 } 1079 if(Field & RH_NOC_PROT) { 1080 DescriptorA.NoOverCurrentProtMode = Value; 1081 } 1082 if(Field & RH_NO_POTPGT) { 1083 DescriptorA.PowerOnToPowerGoodTime = Value; 1084 } 1085 1086 Status = OhciSetOperationalReg (Ohc, HC_RH_DESC_A, (UINT32*)&DescriptorA); 1087 1088 return Status; 1089 } 1090 1091 1092 /** 1093 1094 Get Root Hub Descriptor reg value 1095 1096 @param Ohc UHC private data 1097 @param Field Field to get 1098 1099 @retval Value of the field 1100 1101 **/ 1102 1103 UINT32 1104 OhciGetRootHubDescriptor ( 1105 IN USB_OHCI_HC_DEV *Ohc, 1106 IN UINTN Field 1107 ) 1108 { 1109 HcRH_DESC_A DescriptorA; 1110 HcRH_DESC_B DescriptorB; 1111 1112 1113 *(UINT32 *) &DescriptorA = OhciGetOperationalReg (Ohc, HC_RH_DESC_A); 1114 *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc, HC_RH_DESC_B); 1115 1116 switch (Field){ 1117 case RH_DEV_REMOVABLE: 1118 return DescriptorB.DeviceRemovable; 1119 break; 1120 1121 case RH_PORT_PWR_CTRL_MASK: 1122 return DescriptorB.PortPowerControlMask; 1123 break; 1124 1125 case RH_NUM_DS_PORTS: 1126 return DescriptorA.NumDownStrmPorts; 1127 break; 1128 1129 case RH_NO_PSWITCH: 1130 return DescriptorA.NoPowerSwitch; 1131 break; 1132 1133 case RH_PSWITCH_MODE: 1134 return DescriptorA.PowerSwitchMode; 1135 break; 1136 1137 case RH_DEVICE_TYPE: 1138 return DescriptorA.DeviceType; 1139 break; 1140 1141 case RH_OC_PROT_MODE: 1142 return DescriptorA.OverCurrentProtMode; 1143 break; 1144 1145 case RH_NOC_PROT: 1146 return DescriptorA.NoOverCurrentProtMode; 1147 break; 1148 1149 case RH_NO_POTPGT: 1150 return DescriptorA.PowerOnToPowerGoodTime; 1151 break; 1152 1153 default: 1154 ASSERT (FALSE); 1155 } 1156 1157 return 0; 1158 } 1159 1160 1161 /** 1162 1163 Set Root Hub Status reg value 1164 1165 @param Ohc UHC private data 1166 @param Field Field to set 1167 1168 @retval EFI_SUCCESS Value set 1169 1170 **/ 1171 1172 EFI_STATUS 1173 OhciSetRootHubStatus ( 1174 IN USB_OHCI_HC_DEV *Ohc, 1175 IN UINTN Field 1176 ) 1177 { 1178 EFI_STATUS Status; 1179 HcRH_STATUS RootHubStatus; 1180 1181 1182 ZeroMem (&RootHubStatus, sizeof(HcRH_STATUS)); 1183 1184 if(Field & RH_LOCAL_PSTAT){ 1185 RootHubStatus.LocalPowerStat = 1; 1186 } 1187 if(Field & RH_OC_ID){ 1188 RootHubStatus.OverCurrentIndicator = 1; 1189 } 1190 if(Field & RH_REMOTE_WK_ENABLE){ 1191 RootHubStatus.DevRemoteWakeupEnable = 1; 1192 } 1193 if(Field & RH_LOCAL_PSTAT_CHANGE){ 1194 RootHubStatus.LocalPowerStatChange = 1; 1195 } 1196 if(Field & RH_OC_ID_CHANGE){ 1197 RootHubStatus.OverCurrentIndicatorChange = 1; 1198 } 1199 if(Field & RH_CLR_RMT_WK_ENABLE){ 1200 RootHubStatus.ClearRemoteWakeupEnable = 1; 1201 } 1202 1203 Status = OhciSetOperationalReg (Ohc, HC_RH_STATUS, (UINT32*)&RootHubStatus); 1204 1205 return Status; 1206 } 1207 1208 1209 /** 1210 1211 Get Root Hub Status reg value 1212 1213 @param Ohc UHC private data 1214 @param Field Field to get 1215 1216 @retval Value of the field 1217 1218 **/ 1219 1220 UINT32 1221 OhciGetRootHubStatus ( 1222 IN USB_OHCI_HC_DEV *Ohc, 1223 IN UINTN Field 1224 ) 1225 { 1226 HcRH_STATUS RootHubStatus; 1227 1228 1229 *(UINT32 *) &RootHubStatus = OhciGetOperationalReg (Ohc, HC_RH_STATUS); 1230 1231 switch (Field) { 1232 case RH_LOCAL_PSTAT: 1233 return RootHubStatus.LocalPowerStat; 1234 break; 1235 case RH_OC_ID: 1236 return RootHubStatus.OverCurrentIndicator; 1237 break; 1238 case RH_REMOTE_WK_ENABLE: 1239 return RootHubStatus.DevRemoteWakeupEnable; 1240 break; 1241 case RH_LOCAL_PSTAT_CHANGE: 1242 return RootHubStatus.LocalPowerStatChange; 1243 break; 1244 case RH_OC_ID_CHANGE: 1245 return RootHubStatus.OverCurrentIndicatorChange; 1246 break; 1247 case RH_CLR_RMT_WK_ENABLE: 1248 return RootHubStatus.ClearRemoteWakeupEnable; 1249 break; 1250 default: 1251 ASSERT (FALSE); 1252 } 1253 1254 return 0; 1255 } 1256 1257 1258 /** 1259 1260 Set Root Hub Port Status reg value 1261 1262 @param Ohc UHC private data 1263 @param Index Index of the port 1264 @param Field Field to set 1265 1266 @retval EFI_SUCCESS Value set 1267 1268 **/ 1269 1270 EFI_STATUS 1271 OhciSetRootHubPortStatus ( 1272 IN USB_OHCI_HC_DEV *Ohc, 1273 IN UINT32 Index, 1274 IN UINTN Field 1275 ) 1276 { 1277 EFI_STATUS Status; 1278 HcRHPORT_STATUS PortStatus; 1279 1280 1281 ZeroMem (&PortStatus, sizeof(HcRHPORT_STATUS)); 1282 1283 if (Field & RH_CLEAR_PORT_ENABLE) { 1284 PortStatus.CurrentConnectStat = 1; 1285 } 1286 if (Field & RH_SET_PORT_ENABLE) { 1287 PortStatus.EnableStat = 1; 1288 } 1289 if (Field & RH_SET_PORT_SUSPEND) { 1290 PortStatus.SuspendStat = 1; 1291 } 1292 if (Field & RH_CLEAR_SUSPEND_STATUS) { 1293 PortStatus.OCIndicator = 1; 1294 } 1295 if (Field & RH_SET_PORT_RESET) { 1296 PortStatus.ResetStat = 1; 1297 } 1298 if (Field & RH_SET_PORT_POWER) { 1299 PortStatus.PowerStat = 1; 1300 } 1301 if (Field & RH_CLEAR_PORT_POWER) { 1302 PortStatus.LsDeviceAttached = 1; 1303 } 1304 if (Field & RH_CONNECT_STATUS_CHANGE) { 1305 PortStatus.ConnectStatChange = 1; 1306 } 1307 if (Field & RH_PORT_ENABLE_STAT_CHANGE) { 1308 PortStatus.EnableStatChange = 1; 1309 } 1310 if (Field & RH_PORT_SUSPEND_STAT_CHANGE) { 1311 PortStatus.SuspendStatChange = 1; 1312 } 1313 if (Field & RH_OC_INDICATOR_CHANGE) { 1314 PortStatus.OCIndicatorChange = 1; 1315 } 1316 if (Field & RH_PORT_RESET_STAT_CHANGE ) { 1317 PortStatus.ResetStatChange = 1; 1318 } 1319 1320 Status = OhciSetOperationalReg (Ohc, HC_RH_PORT_STATUS + (Index * 4), (UINT32*)&PortStatus); 1321 1322 return Status; 1323 } 1324 1325 1326 /** 1327 1328 Get Root Hub Port Status reg value 1329 1330 @param Ohc UHC private data 1331 @param Index Index of the port 1332 @param Field Field to get 1333 1334 @retval Value of the field and index 1335 1336 **/ 1337 1338 UINT32 1339 OhciReadRootHubPortStatus ( 1340 IN USB_OHCI_HC_DEV *Ohc, 1341 IN UINT32 Index, 1342 IN UINTN Field 1343 ) 1344 { 1345 HcRHPORT_STATUS PortStatus; 1346 1347 *(UINT32 *) &PortStatus = OhciGetOperationalReg ( 1348 Ohc, 1349 HC_RH_PORT_STATUS + (Index * 4) 1350 ); 1351 1352 switch (Field){ 1353 case RH_CURR_CONNECT_STAT: 1354 return PortStatus.CurrentConnectStat; 1355 break; 1356 case RH_PORT_ENABLE_STAT: 1357 return PortStatus.EnableStat; 1358 break; 1359 case RH_PORT_SUSPEND_STAT: 1360 return PortStatus.SuspendStat; 1361 break; 1362 case RH_PORT_OC_INDICATOR: 1363 return PortStatus.OCIndicator; 1364 break; 1365 case RH_PORT_RESET_STAT: 1366 return PortStatus.ResetStat; 1367 break; 1368 case RH_PORT_POWER_STAT: 1369 return PortStatus.PowerStat; 1370 break; 1371 case RH_LSDEVICE_ATTACHED: 1372 return PortStatus.LsDeviceAttached; 1373 break; 1374 case RH_CONNECT_STATUS_CHANGE: 1375 return PortStatus.ConnectStatChange; 1376 break; 1377 case RH_PORT_ENABLE_STAT_CHANGE: 1378 return PortStatus.EnableStatChange; 1379 break; 1380 case RH_PORT_SUSPEND_STAT_CHANGE: 1381 return PortStatus.SuspendStatChange; 1382 break; 1383 case RH_OC_INDICATOR_CHANGE: 1384 return PortStatus.OCIndicatorChange; 1385 break; 1386 case RH_PORT_RESET_STAT_CHANGE: 1387 return PortStatus.ResetStatChange; 1388 break; 1389 default: 1390 ASSERT (FALSE); 1391 } 1392 1393 return 0; 1394 } 1395