]>
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 offset of the XHCI capability.
576 @param Xhc The XHCI Instance.
577 @param CapId The XHCI Capability ID.
579 @return The offset of XHCI legacy support capability register.
583 XhcGetCapabilityAddr (
584 IN USB_XHCI_INSTANCE
*Xhc
,
596 // Check if the extended capability register's capability id is USB Legacy Support.
598 Data
= XhcReadExtCapReg (Xhc
, ExtCapOffset
);
599 if ((Data
& 0xFF) == CapId
) {
603 // If not, then traverse all of the ext capability registers till finding out it.
605 NextExtCapReg
= (UINT8
)((Data
>> 8) & 0xFF);
606 ExtCapOffset
+= (NextExtCapReg
<< 2);
607 } while (NextExtCapReg
!= 0);
613 Whether the XHCI host controller is halted.
615 @param Xhc The XHCI Instance.
617 @retval TRUE The controller is halted.
618 @retval FALSE It isn't halted.
623 IN USB_XHCI_INSTANCE
*Xhc
626 return XHC_REG_BIT_IS_SET (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
);
631 Whether system error occurred.
633 @param Xhc The XHCI Instance.
635 @retval TRUE System error happened.
636 @retval FALSE No system error.
641 IN USB_XHCI_INSTANCE
*Xhc
644 return XHC_REG_BIT_IS_SET (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HSE
);
648 Reset the XHCI host controller.
650 @param Xhc The XHCI Instance.
651 @param Timeout Time to wait before abort (in millisecond, ms).
653 @retval EFI_SUCCESS The XHCI host controller is reset.
654 @return Others Failed to reset the XHCI before Timeout.
659 IN USB_XHCI_INSTANCE
*Xhc
,
665 Status
= EFI_SUCCESS
;
667 DEBUG ((EFI_D_INFO
, "XhcResetHC!\n"));
669 // Host can only be reset when it is halt. If not so, halt it
671 if (!XHC_REG_BIT_IS_SET (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
)) {
672 Status
= XhcHaltHC (Xhc
, Timeout
);
674 if (EFI_ERROR (Status
)) {
679 if (((XhcReadExtCapReg (Xhc
, Xhc
->DebugCapSupOffset
) & 0xFF) != XHC_CAP_USB_DEBUG
) ||
680 ((XhcReadExtCapReg (Xhc
, Xhc
->DebugCapSupOffset
+ XHC_DC_DCCTRL
) & BIT0
) == 0)) {
681 XhcSetOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RESET
);
682 Status
= XhcWaitOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RESET
, FALSE
, Timeout
);
690 Halt the XHCI host controller.
692 @param Xhc The XHCI Instance.
693 @param Timeout Time to wait before abort (in millisecond, ms).
695 @return EFI_SUCCESS The XHCI host controller is halt.
696 @return EFI_TIMEOUT Failed to halt the XHCI before Timeout.
701 IN USB_XHCI_INSTANCE
*Xhc
,
707 XhcClearOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RUN
);
708 Status
= XhcWaitOpRegBit (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
, TRUE
, Timeout
);
714 Set the XHCI host controller to run.
716 @param Xhc The XHCI Instance.
717 @param Timeout Time to wait before abort (in millisecond, ms).
719 @return EFI_SUCCESS The XHCI host controller is running.
720 @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout.
725 IN USB_XHCI_INSTANCE
*Xhc
,
731 XhcSetOpRegBit (Xhc
, XHC_USBCMD_OFFSET
, XHC_USBCMD_RUN
);
732 Status
= XhcWaitOpRegBit (Xhc
, XHC_USBSTS_OFFSET
, XHC_USBSTS_HALT
, FALSE
, Timeout
);