\r
The XHCI register operation routines.\r
\r
-Copyright (c) 2011, 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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->CapLength + Offset),\r
+ Xhc->CapLength + Offset,\r
1,\r
&Data\r
);\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->CapLength + Offset),\r
+ Xhc->CapLength + Offset,\r
1,\r
&Data\r
);\r
}\r
}\r
\r
-/**\r
- Write the data to the 2-bytes width XHCI operational register.\r
-\r
- @param Xhc The XHCI Instance.\r
- @param Offset The offset of the 2-bytes width operational register.\r
- @param Data The data to write.\r
-\r
-**/\r
-VOID\r
-XhcWriteOpReg16 (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT16 Data\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- ASSERT (Xhc->CapLength != 0);\r
-\r
- Status = Xhc->PciIo->Mem.Write (\r
- Xhc->PciIo,\r
- EfiPciIoWidthUint16,\r
- XHC_BAR_INDEX,\r
- (UINT64) (Xhc->CapLength + Offset),\r
- 1,\r
- &Data\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcWriteOpReg16: Pci Io Write error: %r at %d\n", Status, Offset));\r
- }\r
-}\r
-\r
-/**\r
- Read XHCI door bell register.\r
-\r
- @param Xhc The XHCI Instance.\r
- @param Offset The offset of the door bell register.\r
-\r
- @return The register content read\r
-\r
-**/\r
-UINT32\r
-XhcReadDoorBellReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset\r
- )\r
-{\r
- UINT32 Data;\r
- EFI_STATUS Status;\r
-\r
- ASSERT (Xhc->DBOff != 0);\r
\r
- Status = Xhc->PciIo->Mem.Read (\r
- Xhc->PciIo,\r
- EfiPciIoWidthUint32,\r
- XHC_BAR_INDEX,\r
- (UINT64) (Xhc->DBOff + Offset),\r
- 1,\r
- &Data\r
- );\r
\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcReadDoorBellReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
- Data = 0xFFFFFFFF;\r
- }\r
\r
- return Data;\r
-}\r
\r
/**\r
Write the data to the XHCI door bell register.\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->DBOff + Offset),\r
+ Xhc->DBOff + Offset,\r
1,\r
&Data\r
);\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->RTSOff + Offset),\r
+ Xhc->RTSOff + Offset,\r
1,\r
&Data\r
);\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->RTSOff + Offset),\r
+ Xhc->RTSOff + Offset,\r
1,\r
&Data\r
);\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->ExtCapRegBase + Offset),\r
+ Xhc->ExtCapRegBase + Offset,\r
1,\r
&Data\r
);\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->ExtCapRegBase + Offset),\r
+ Xhc->ExtCapRegBase + Offset,\r
1,\r
&Data\r
);\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
ExtCapOffset += (NextExtCapReg << 2);\r
} while (NextExtCapReg != 0);\r
\r
- return 0;\r
+ return 0xFFFFFFFF;\r
}\r
\r
/**\r
return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE);\r
}\r
\r
+/**\r
+ Set USBCMD Host System Error Enable(HSEE) Bit if PCICMD SERR# Enable Bit is set.\r
+\r
+ The USBCMD HSEE Bit will be reset to default 0 by USBCMD Host Controller Reset(HCRST).\r
+ This function is to set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
+\r
+ @param Xhc The XHCI Instance.\r
+\r
+**/\r
+VOID\r
+XhcSetHsee (\r
+ IN USB_XHCI_INSTANCE *Xhc\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT16 XhciCmd;\r
+\r
+ PciIo = Xhc->PciIo;\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PCI_COMMAND_OFFSET,\r
+ sizeof (XhciCmd) / sizeof (UINT16),\r
+ &XhciCmd\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ if ((XhciCmd & EFI_PCI_COMMAND_SERR) != 0) {\r
+ XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_HSEE);\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Reset the XHCI host controller.\r
\r
}\r
}\r
\r
- if (((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) ||\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
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // The USBCMD HSEE Bit will be reset to default 0 by USBCMD HCRST.\r
+ // Set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
+ //\r
+ XhcSetHsee (Xhc);\r
+ }\r
}\r
\r
return Status;\r