]>
git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
3 The XHCI register operation routines.
5 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
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
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.
19 Read 1-byte width XHCI capability register.
21 @param Xhc The XHCI device.
22 @param Offset The offset of the 1-byte width capability register.
24 @return The register content read.
25 @retval If err, return 0xFF.
37 Status
= Xhc
->PciIo
->Mem
.Read (
46 if (EFI_ERROR (Status
)) {
47 DEBUG ((EFI_D_ERROR
, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status
, Offset
));
55 Read 4-bytes width XHCI capability register.
57 @param Xhc The XHCI device.
58 @param Offset The offset of the 4-bytes width capability register.
60 @return The register content read.
61 @retval If err, return 0xFFFFFFFF.
73 Status
= Xhc
->PciIo
->Mem
.Read (
82 if (EFI_ERROR (Status
)) {
83 DEBUG ((EFI_D_ERROR
, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status
, Offset
));
91 Read 4-bytes width XHCI Operational register.
93 @param Xhc The XHCI device.
94 @param Offset The offset of the 4-bytes width operational register.
96 @return The register content read.
97 @retval If err, return 0xFFFFFFFF.
102 IN USB_XHCI_DEV
*Xhc
,
109 ASSERT (Xhc
->CapLength
!= 0);
111 Status
= Xhc
->PciIo
->Mem
.Read (
115 (UINT64
) (Xhc
->CapLength
+ Offset
),
120 if (EFI_ERROR (Status
)) {
121 DEBUG ((EFI_D_ERROR
, "XhcReadOpReg: Pci Io Read error - %r at %d\n", Status
, Offset
));
129 Write the data to the 4-bytes width XHCI operational register.
131 @param Xhc The XHCI device.
132 @param Offset The offset of the 4-bytes width operational register.
133 @param Data The data to write.
138 IN USB_XHCI_DEV
*Xhc
,
145 ASSERT (Xhc
->CapLength
!= 0);
147 Status
= Xhc
->PciIo
->Mem
.Write (
151 (UINT64
) (Xhc
->CapLength
+ Offset
),
156 if (EFI_ERROR (Status
)) {
157 DEBUG ((EFI_D_ERROR
, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status
, Offset
));
162 Write the data to the 2-bytes width XHCI operational register.
164 @param Xhc The XHCI device.
165 @param Offset The offset of the 2-bytes width operational register.
166 @param Data The data to write.
171 IN USB_XHCI_DEV
*Xhc
,
178 ASSERT (Xhc
->CapLength
!= 0);
180 Status
= Xhc
->PciIo
->Mem
.Write (
184 (UINT64
) (Xhc
->CapLength
+ Offset
),
189 if (EFI_ERROR (Status
)) {
190 DEBUG ((EFI_D_ERROR
, "XhcWriteOpReg16: Pci Io Write error: %r at %d\n", Status
, Offset
));
195 Write the data to the 8-bytes width XHCI operational register.
197 @param Xhc The XHCI device.
198 @param Offset The offset of the 8-bytes width operational register.
199 @param Data The data to write.
204 IN USB_XHCI_DEV
*Xhc
,
211 ASSERT (Xhc
->CapLength
!= 0);
213 Status
= Xhc
->PciIo
->Mem
.Write (
217 (UINT64
) (Xhc
->CapLength
+ Offset
),
222 if (EFI_ERROR (Status
)) {
223 DEBUG ((EFI_D_ERROR
, "XhcWriteOpReg64: Pci Io Write error: %r at %d\n", Status
, Offset
));
228 Read XHCI door bell register.
230 @param Xhc The XHCI device.
231 @param Offset The offset of the door bell register.
233 @return The register content read
238 IN USB_XHCI_DEV
*Xhc
,
245 ASSERT (Xhc
->DBOff
!= 0);
247 Status
= Xhc
->PciIo
->Mem
.Read (
251 (UINT64
) (Xhc
->DBOff
+ Offset
),
256 if (EFI_ERROR (Status
)) {
257 DEBUG ((EFI_D_ERROR
, "XhcReadDoorBellReg: Pci Io Read error - %r at %d\n", Status
, Offset
));
265 Write the data to the XHCI door bell register.
267 @param Xhc The XHCI device.
268 @param Offset The offset of the door bell register.
269 @param Data The data to write.
273 XhcWriteDoorBellReg (
274 IN USB_XHCI_DEV
*Xhc
,
281 ASSERT (Xhc
->DBOff
!= 0);
283 Status
= Xhc
->PciIo
->Mem
.Write (
287 (UINT64
) (Xhc
->DBOff
+ Offset
),
292 if (EFI_ERROR (Status
)) {
293 DEBUG ((EFI_D_ERROR
, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status
, Offset
));
298 Read XHCI runtime register.
300 @param Xhc The XHCI device.
301 @param Offset The offset of the runtime register.
303 @return The register content read
308 IN USB_XHCI_DEV
*Xhc
,
315 ASSERT (Xhc
->RTSOff
!= 0);
317 Status
= Xhc
->PciIo
->Mem
.Read (
321 (UINT64
) (Xhc
->RTSOff
+ Offset
),
326 if (EFI_ERROR (Status
)) {
327 DEBUG ((EFI_D_ERROR
, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status
, Offset
));
335 Read 8-bytes width XHCI runtime register.
337 @param Xhc The XHCI device.
338 @param Offset The offset of the 8-bytes width runtime register.
340 @return The register content read
344 XhcReadRuntimeReg64 (
345 IN USB_XHCI_DEV
*Xhc
,
352 ASSERT (Xhc
->RTSOff
!= 0);
354 Status
= Xhc
->PciIo
->Mem
.Read (
358 (UINT64
) (Xhc
->RTSOff
+ Offset
),
363 if (EFI_ERROR (Status
)) {
364 DEBUG ((EFI_D_ERROR
, "XhcReadRuntimeReg64: Pci Io Read error - %r at %d\n", Status
, Offset
));
365 Data
= 0xFFFFFFFFFFFFFFFFULL
;
372 Write the data to the XHCI runtime register.
374 @param Xhc The XHCI device.
375 @param Offset The offset of the runtime register.
376 @param Data The data to write.
381 IN USB_XHCI_DEV
*Xhc
,
388 ASSERT (Xhc
->RTSOff
!= 0);
390 Status
= Xhc
->PciIo
->Mem
.Write (
394 (UINT64
) (Xhc
->RTSOff
+ Offset
),
399 if (EFI_ERROR (Status
)) {
400 DEBUG ((EFI_D_ERROR
, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status
, Offset
));
405 Write the data to the 8-bytes width XHCI runtime register.
407 @param Xhc The XHCI device.
408 @param Offset The offset of the 8-bytes width runtime register.
409 @param Data The data to write.
413 XhcWriteRuntimeReg64 (
414 IN USB_XHCI_DEV
*Xhc
,
421 ASSERT (Xhc
->RTSOff
!= 0);
423 Status
= Xhc
->PciIo
->Mem
.Write (
427 (UINT64
) (Xhc
->RTSOff
+ Offset
),
432 if (EFI_ERROR (Status
)) {
433 DEBUG ((EFI_D_ERROR
, "XhcWriteRuntimeReg64: Pci Io Write error: %r at %d\n", Status
, Offset
));
438 Read XHCI extended capability register.
440 @param Xhc The XHCI device.
441 @param Offset The offset of the extended capability register.
443 @return The register content read
448 IN USB_XHCI_DEV
*Xhc
,
455 ASSERT (Xhc
->ExtCapRegBase
!= 0);
457 Status
= Xhc
->PciIo
->Mem
.Read (
461 (UINT64
) (Xhc
->ExtCapRegBase
+ Offset
),
466 if (EFI_ERROR (Status
)) {
467 DEBUG ((EFI_D_ERROR
, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status
, Offset
));
475 Write the data to the XHCI extended capability register.
477 @param Xhc The XHCI device.
478 @param Offset The offset of the extended capability register.
479 @param Data The data to write.
484 IN USB_XHCI_DEV
*Xhc
,
491 ASSERT (Xhc
->ExtCapRegBase
!= 0);
493 Status
= Xhc
->PciIo
->Mem
.Write (
497 (UINT64
) (Xhc
->ExtCapRegBase
+ Offset
),
502 if (EFI_ERROR (Status
)) {
503 DEBUG ((EFI_D_ERROR
, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status
, Offset
));
509 Set one bit of the runtime register while keeping other bits.
511 @param Xhc The XHCI device.
512 @param Offset The offset of the runtime register.
513 @param Bit The bit mask of the register to set.
517 XhcSetRuntimeRegBit (
518 IN USB_XHCI_DEV
*Xhc
,
525 Data
= XhcReadRuntimeReg (Xhc
, Offset
);
527 XhcWriteRuntimeReg (Xhc
, Offset
, Data
);
531 Clear one bit of the runtime register while keeping other bits.
533 @param Xhc The XHCI device.
534 @param Offset The offset of the runtime register.
535 @param Bit The bit mask of the register to set.
539 XhcClearRuntimeRegBit (
540 IN USB_XHCI_DEV
*Xhc
,
547 Data
= XhcReadRuntimeReg (Xhc
, Offset
);
549 XhcWriteRuntimeReg (Xhc
, Offset
, Data
);
553 Set one bit of the operational register while keeping other bits.
555 @param Xhc The XHCI device.
556 @param Offset The offset of the operational register.
557 @param Bit The bit mask of the register to set.
562 IN USB_XHCI_DEV
*Xhc
,
569 Data
= XhcReadOpReg (Xhc
, Offset
);
571 XhcWriteOpReg (Xhc
, Offset
, Data
);
576 Clear one bit of the operational register while keeping other bits.
578 @param Xhc The XHCI device.
579 @param Offset The offset of the operational register.
580 @param Bit The bit mask of the register to clear.
585 IN USB_XHCI_DEV
*Xhc
,
592 Data
= XhcReadOpReg (Xhc
, Offset
);
594 XhcWriteOpReg (Xhc
, Offset
, Data
);
598 Wait the operation register's bit as specified by Bit
599 to become set (or clear).
601 @param Xhc The XHCI device.
602 @param Offset The offset of the operation register.
603 @param Bit The bit of the register to wait for.
604 @param WaitToSet Wait the bit to set or clear.
605 @param Timeout The time to wait before abort (in millisecond, ms).
607 @retval EFI_SUCCESS The bit successfully changed by host controller.
608 @retval EFI_TIMEOUT The time out occurred.
613 IN USB_XHCI_DEV
*Xhc
,
616 IN BOOLEAN WaitToSet
,
622 for (Index
= 0; Index
< Timeout
/ XHC_SYNC_POLL_INTERVAL
+ 1; Index
++) {
623 if (XHC_REG_BIT_IS_SET (Xhc
, Offset
, Bit
) == WaitToSet
) {
627 gBS
->Stall (XHC_SYNC_POLL_INTERVAL
);
636 @param Xhc The XHCI device.
640 XhcSetBiosOwnership (
646 DEBUG ((EFI_D_INFO
, "XhcSetBiosOwnership: called to set BIOS ownership\n"));
648 Buffer
= XhcReadExtCapReg (Xhc
, Xhc
->UsbLegSupOffset
);
649 Buffer
= ((Buffer
& (~USBLEGSP_OS_SEMAPHORE
)) | USBLEGSP_BIOS_SEMAPHORE
);
650 XhcWriteExtCapReg (Xhc
, Xhc
->UsbLegSupOffset
, Buffer
);
656 @param Xhc The XHCI device.
660 XhcClearBiosOwnership (
666 DEBUG ((EFI_D_INFO
, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));
668 Buffer
= XhcReadExtCapReg (Xhc
, Xhc
->UsbLegSupOffset
);
669 Buffer
= ((Buffer
& (~USBLEGSP_BIOS_SEMAPHORE
)) | USBLEGSP_OS_SEMAPHORE
);
670 XhcWriteExtCapReg (Xhc
, Xhc
->UsbLegSupOffset
, Buffer
);
674 Calculate the XHCI legacy support capability register offset.
676 @param Xhc The XHCI device.
678 @return The offset of XHCI legacy support capability register.
682 XhcGetLegSupCapAddr (
694 // Check if the extended capability register's capability id is USB Legacy Support.
696 Data
= XhcReadExtCapReg (Xhc
, ExtCapOffset
);
697 if ((Data
& 0xFF) == 0x1) {
701 // If not, then traverse all of the ext capability registers till finding out it.
703 NextExtCapReg
= (UINT8
)((Data
>> 8) & 0xFF);
704 ExtCapOffset
+= (NextExtCapReg
<< 2);
705 } while (NextExtCapReg
!= 0);
711 Whether the XHCI host controller is halted.
713 @param Xhc The XHCI device.
715 @retval TRUE The controller is halted.
716 @retval FALSE It isn't halted.
724 return XHC_REG_BIT_IS_SET (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
);
729 Whether system error occurred.
731 @param Xhc The XHCI device.
733 @retval TRUE System error happened.
734 @retval FALSE No system error.
742 return XHC_REG_BIT_IS_SET (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HSE
);
746 Reset the XHCI host controller.
748 @param Xhc The XHCI device.
749 @param Timeout Time to wait before abort (in millisecond, ms).
751 @retval EFI_SUCCESS The XHCI host controller is reset.
752 @return Others Failed to reset the XHCI before Timeout.
757 IN USB_XHCI_DEV
*Xhc
,
763 DEBUG ((EFI_D_INFO
, "XhcResetHC!\n"));
765 // Host can only be reset when it is halt. If not so, halt it
767 if (!XHC_REG_BIT_IS_SET (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
)) {
768 Status
= XhcHaltHC (Xhc
, Timeout
);
770 if (EFI_ERROR (Status
)) {
775 XhcSetOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RESET
);
776 Status
= XhcWaitOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RESET
, FALSE
, Timeout
);
782 Halt the XHCI host controller.
784 @param Xhc The XHCI device.
785 @param Timeout Time to wait before abort (in millisecond, ms).
787 @return EFI_SUCCESS The XHCI host controller is halt.
788 @return EFI_TIMEOUT Failed to halt the XHCI before Timeout.
793 IN USB_XHCI_DEV
*Xhc
,
799 XhcClearOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RUN
);
800 Status
= XhcWaitOpRegBit (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
, TRUE
, Timeout
);
806 Set the XHCI host controller to run.
808 @param Xhc The XHCI device.
809 @param Timeout Time to wait before abort (in millisecond, ms).
811 @return EFI_SUCCESS The XHCI host controller is running.
812 @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout.
817 IN USB_XHCI_DEV
*Xhc
,
823 XhcSetOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RUN
);
824 Status
= XhcWaitOpRegBit (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
, FALSE
, Timeout
);