]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
MdeModulePkg/XhciDxe:1ms delay before access MMIO reg during reset
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciReg.c
index 9d50ef824261acc357812e33a911eec017bea09b..0e1c86cc16f4b7f2464b3e2e69bc44842c353713 100644 (file)
@@ -2,7 +2,7 @@
 \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
@@ -515,16 +515,16 @@ XhcWaitOpRegBit (
   )\r
 {\r
   UINT32                  Index;\r
-  UINT                  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
@@ -543,6 +543,10 @@ XhcSetBiosOwnership (
 {\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
@@ -563,6 +567,10 @@ XhcClearBiosOwnership (
 {\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
@@ -571,16 +579,18 @@ XhcClearBiosOwnership (
 }\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
@@ -594,7 +604,7 @@ XhcGetLegSupCapAddr (
     // 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
@@ -604,7 +614,7 @@ XhcGetLegSupCapAddr (
     ExtCapOffset += (NextExtCapReg << 2);\r
   } while (NextExtCapReg != 0);\r
 \r
-  return 0;\r
+  return 0xFFFFFFFF;\r
 }\r
 \r
 /**\r
@@ -660,6 +670,8 @@ XhcResetHC (
 {\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
@@ -672,8 +684,18 @@ XhcResetHC (
     }\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