]>
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 Instance.
22 @param Offset The offset of the 1-byte width capability register.
24 @return The register content read.
25 @retval If err, return 0xFF.
30 IN USB_XHCI_INSTANCE
*Xhc
,
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 Instance.
58 @param Offset The offset of the 4-bytes width capability register.
60 @return The register content read.
61 @retval If err, return 0xFFFFFFFF.
66 IN USB_XHCI_INSTANCE
*Xhc
,
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 Instance.
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_INSTANCE
*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 Instance.
132 @param Offset The offset of the 4-bytes width operational register.
133 @param Data The data to write.
138 IN USB_XHCI_INSTANCE
*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 Instance.
165 @param Offset The offset of the 2-bytes width operational register.
166 @param Data The data to write.
171 IN USB_XHCI_INSTANCE
*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 Read XHCI door bell register.
197 @param Xhc The XHCI Instance.
198 @param Offset The offset of the door bell register.
200 @return The register content read
205 IN USB_XHCI_INSTANCE
*Xhc
,
212 ASSERT (Xhc
->DBOff
!= 0);
214 Status
= Xhc
->PciIo
->Mem
.Read (
218 (UINT64
) (Xhc
->DBOff
+ Offset
),
223 if (EFI_ERROR (Status
)) {
224 DEBUG ((EFI_D_ERROR
, "XhcReadDoorBellReg: Pci Io Read error - %r at %d\n", Status
, Offset
));
232 Write the data to the XHCI door bell register.
234 @param Xhc The XHCI Instance.
235 @param Offset The offset of the door bell register.
236 @param Data The data to write.
240 XhcWriteDoorBellReg (
241 IN USB_XHCI_INSTANCE
*Xhc
,
248 ASSERT (Xhc
->DBOff
!= 0);
250 Status
= Xhc
->PciIo
->Mem
.Write (
254 (UINT64
) (Xhc
->DBOff
+ Offset
),
259 if (EFI_ERROR (Status
)) {
260 DEBUG ((EFI_D_ERROR
, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status
, Offset
));
265 Read XHCI runtime register.
267 @param Xhc The XHCI Instance.
268 @param Offset The offset of the runtime register.
270 @return The register content read
275 IN USB_XHCI_INSTANCE
*Xhc
,
282 ASSERT (Xhc
->RTSOff
!= 0);
284 Status
= Xhc
->PciIo
->Mem
.Read (
288 (UINT64
) (Xhc
->RTSOff
+ Offset
),
293 if (EFI_ERROR (Status
)) {
294 DEBUG ((EFI_D_ERROR
, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status
, Offset
));
302 Write the data to the XHCI runtime register.
304 @param Xhc The XHCI Instance.
305 @param Offset The offset of the runtime register.
306 @param Data The data to write.
311 IN USB_XHCI_INSTANCE
*Xhc
,
318 ASSERT (Xhc
->RTSOff
!= 0);
320 Status
= Xhc
->PciIo
->Mem
.Write (
324 (UINT64
) (Xhc
->RTSOff
+ Offset
),
329 if (EFI_ERROR (Status
)) {
330 DEBUG ((EFI_D_ERROR
, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status
, Offset
));
335 Read XHCI extended capability register.
337 @param Xhc The XHCI Instance.
338 @param Offset The offset of the extended capability register.
340 @return The register content read
345 IN USB_XHCI_INSTANCE
*Xhc
,
352 ASSERT (Xhc
->ExtCapRegBase
!= 0);
354 Status
= Xhc
->PciIo
->Mem
.Read (
358 (UINT64
) (Xhc
->ExtCapRegBase
+ Offset
),
363 if (EFI_ERROR (Status
)) {
364 DEBUG ((EFI_D_ERROR
, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status
, Offset
));
372 Write the data to the XHCI extended capability register.
374 @param Xhc The XHCI Instance.
375 @param Offset The offset of the extended capability register.
376 @param Data The data to write.
381 IN USB_XHCI_INSTANCE
*Xhc
,
388 ASSERT (Xhc
->ExtCapRegBase
!= 0);
390 Status
= Xhc
->PciIo
->Mem
.Write (
394 (UINT64
) (Xhc
->ExtCapRegBase
+ Offset
),
399 if (EFI_ERROR (Status
)) {
400 DEBUG ((EFI_D_ERROR
, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status
, Offset
));
406 Set one bit of the runtime register while keeping other bits.
408 @param Xhc The XHCI Instance.
409 @param Offset The offset of the runtime register.
410 @param Bit The bit mask of the register to set.
414 XhcSetRuntimeRegBit (
415 IN USB_XHCI_INSTANCE
*Xhc
,
422 Data
= XhcReadRuntimeReg (Xhc
, Offset
);
424 XhcWriteRuntimeReg (Xhc
, Offset
, Data
);
428 Clear one bit of the runtime register while keeping other bits.
430 @param Xhc The XHCI Instance.
431 @param Offset The offset of the runtime register.
432 @param Bit The bit mask of the register to set.
436 XhcClearRuntimeRegBit (
437 IN USB_XHCI_INSTANCE
*Xhc
,
444 Data
= XhcReadRuntimeReg (Xhc
, Offset
);
446 XhcWriteRuntimeReg (Xhc
, Offset
, Data
);
450 Set one bit of the operational register while keeping other bits.
452 @param Xhc The XHCI Instance.
453 @param Offset The offset of the operational register.
454 @param Bit The bit mask of the register to set.
459 IN USB_XHCI_INSTANCE
*Xhc
,
466 Data
= XhcReadOpReg (Xhc
, Offset
);
468 XhcWriteOpReg (Xhc
, Offset
, Data
);
473 Clear one bit of the operational register while keeping other bits.
475 @param Xhc The XHCI Instance.
476 @param Offset The offset of the operational register.
477 @param Bit The bit mask of the register to clear.
482 IN USB_XHCI_INSTANCE
*Xhc
,
489 Data
= XhcReadOpReg (Xhc
, Offset
);
491 XhcWriteOpReg (Xhc
, Offset
, Data
);
495 Wait the operation register's bit as specified by Bit
496 to become set (or clear).
498 @param Xhc The XHCI Instance.
499 @param Offset The offset of the operation register.
500 @param Bit The bit of the register to wait for.
501 @param WaitToSet Wait the bit to set or clear.
502 @param Timeout The time to wait before abort (in millisecond, ms).
504 @retval EFI_SUCCESS The bit successfully changed by host controller.
505 @retval EFI_TIMEOUT The time out occurred.
510 IN USB_XHCI_INSTANCE
*Xhc
,
513 IN BOOLEAN WaitToSet
,
520 Loop
= (Timeout
* XHC_1_MILLISECOND
/ XHC_POLL_DELAY
) + 1;
522 for (Index
= 0; Index
< Loop
; Index
++) {
523 if (XHC_REG_BIT_IS_SET (Xhc
, Offset
, Bit
) == WaitToSet
) {
527 gBS
->Stall (XHC_POLL_DELAY
);
536 @param Xhc The XHCI Instance.
540 XhcSetBiosOwnership (
541 IN USB_XHCI_INSTANCE
*Xhc
546 DEBUG ((EFI_D_INFO
, "XhcSetBiosOwnership: called to set BIOS ownership\n"));
548 Buffer
= XhcReadExtCapReg (Xhc
, Xhc
->UsbLegSupOffset
);
549 Buffer
= ((Buffer
& (~USBLEGSP_OS_SEMAPHORE
)) | USBLEGSP_BIOS_SEMAPHORE
);
550 XhcWriteExtCapReg (Xhc
, Xhc
->UsbLegSupOffset
, Buffer
);
556 @param Xhc The XHCI Instance.
560 XhcClearBiosOwnership (
561 IN USB_XHCI_INSTANCE
*Xhc
566 DEBUG ((EFI_D_INFO
, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));
568 Buffer
= XhcReadExtCapReg (Xhc
, Xhc
->UsbLegSupOffset
);
569 Buffer
= ((Buffer
& (~USBLEGSP_BIOS_SEMAPHORE
)) | USBLEGSP_OS_SEMAPHORE
);
570 XhcWriteExtCapReg (Xhc
, Xhc
->UsbLegSupOffset
, Buffer
);
574 Calculate the XHCI legacy support capability register offset.
576 @param Xhc The XHCI Instance.
578 @return The offset of XHCI legacy support capability register.
582 XhcGetLegSupCapAddr (
583 IN USB_XHCI_INSTANCE
*Xhc
594 // Check if the extended capability register's capability id is USB Legacy Support.
596 Data
= XhcReadExtCapReg (Xhc
, ExtCapOffset
);
597 if ((Data
& 0xFF) == 0x1) {
601 // If not, then traverse all of the ext capability registers till finding out it.
603 NextExtCapReg
= (UINT8
)((Data
>> 8) & 0xFF);
604 ExtCapOffset
+= (NextExtCapReg
<< 2);
605 } while (NextExtCapReg
!= 0);
611 Whether the XHCI host controller is halted.
613 @param Xhc The XHCI Instance.
615 @retval TRUE The controller is halted.
616 @retval FALSE It isn't halted.
621 IN USB_XHCI_INSTANCE
*Xhc
624 return XHC_REG_BIT_IS_SET (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
);
629 Whether system error occurred.
631 @param Xhc The XHCI Instance.
633 @retval TRUE System error happened.
634 @retval FALSE No system error.
639 IN USB_XHCI_INSTANCE
*Xhc
642 return XHC_REG_BIT_IS_SET (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HSE
);
646 Reset the XHCI host controller.
648 @param Xhc The XHCI Instance.
649 @param Timeout Time to wait before abort (in millisecond, ms).
651 @retval EFI_SUCCESS The XHCI host controller is reset.
652 @return Others Failed to reset the XHCI before Timeout.
657 IN USB_XHCI_INSTANCE
*Xhc
,
663 DEBUG ((EFI_D_INFO
, "XhcResetHC!\n"));
665 // Host can only be reset when it is halt. If not so, halt it
667 if (!XHC_REG_BIT_IS_SET (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
)) {
668 Status
= XhcHaltHC (Xhc
, Timeout
);
670 if (EFI_ERROR (Status
)) {
675 XhcSetOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RESET
);
676 Status
= XhcWaitOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RESET
, FALSE
, Timeout
);
682 Halt the XHCI host controller.
684 @param Xhc The XHCI Instance.
685 @param Timeout Time to wait before abort (in millisecond, ms).
687 @return EFI_SUCCESS The XHCI host controller is halt.
688 @return EFI_TIMEOUT Failed to halt the XHCI before Timeout.
693 IN USB_XHCI_INSTANCE
*Xhc
,
699 XhcClearOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RUN
);
700 Status
= XhcWaitOpRegBit (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
, TRUE
, Timeout
);
706 Set the XHCI host controller to run.
708 @param Xhc The XHCI Instance.
709 @param Timeout Time to wait before abort (in millisecond, ms).
711 @return EFI_SUCCESS The XHCI host controller is running.
712 @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout.
717 IN USB_XHCI_INSTANCE
*Xhc
,
723 XhcSetOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RUN
);
724 Status
= XhcWaitOpRegBit (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
, FALSE
, Timeout
);