\r
The XHCI register operation routines.\r
\r
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
)\r
{\r
UINT32 Index;\r
- UINTN Loop;\r
+ UINT64 Loop;\r
\r
- Loop = (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1;\r
+ Loop = Timeout * XHC_1_MILLISECOND;\r
\r
for (Index = 0; Index < Loop; Index++) {\r
if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) {\r
return EFI_SUCCESS;\r
}\r
\r
- gBS->Stall (XHC_POLL_DELAY);\r
+ gBS->Stall (XHC_1_MICROSECOND);\r
}\r
\r
return EFI_TIMEOUT;\r
{\r
UINT32 Buffer;\r
\r
+ if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
+ return;\r
+ }\r
+\r
DEBUG ((EFI_D_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n"));\r
\r
Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
{\r
UINT32 Buffer;\r
\r
+ if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
+ return;\r
+ }\r
+\r
DEBUG ((EFI_D_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));\r
\r
Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
}\r
\r
/**\r
- Calculate the XHCI legacy support capability register offset.\r
+ Calculate the offset of the XHCI capability.\r
\r
@param Xhc The XHCI Instance.\r
+ @param CapId The XHCI Capability ID.\r
\r
@return The offset of XHCI legacy support capability register.\r
\r
**/\r
UINT32\r
-XhcGetLegSupCapAddr (\r
- IN USB_XHCI_INSTANCE *Xhc\r
+XhcGetCapabilityAddr (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 CapId\r
)\r
{\r
UINT32 ExtCapOffset;\r
// Check if the extended capability register's capability id is USB Legacy Support.\r
//\r
Data = XhcReadExtCapReg (Xhc, ExtCapOffset);\r
- if ((Data & 0xFF) == 0x1) {\r
+ if ((Data & 0xFF) == CapId) {\r
return ExtCapOffset;\r
}\r
//\r
ExtCapOffset += (NextExtCapReg << 2);\r
} while (NextExtCapReg != 0);\r
\r
- return 0;\r
+ return 0xFFFFFFFF;\r
}\r
\r
/**\r
{\r
EFI_STATUS Status;\r
\r
+ Status = EFI_SUCCESS;\r
+\r
DEBUG ((EFI_D_INFO, "XhcResetHC!\n"));\r
//\r
// Host can only be reset when it is halt. If not so, halt it\r
}\r
}\r
\r
- XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
- Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
+ if ((Xhc->DebugCapSupOffset == 0xFFFFFFFF) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) ||\r
+ ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0)) {\r
+ XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
+ //\r
+ // Some XHCI host controllers require to have extra 1ms delay before accessing any MMIO register during reset.\r
+ // Otherwise there may have the timeout case happened.\r
+ // The below is a workaround to solve such problem.\r
+ //\r
+ gBS->Stall (XHC_1_MILLISECOND);\r
+ Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
+ }\r
+\r
return Status;\r
}\r
\r