]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / UhciDxe / UhciReg.c
CommitLineData
913cb9dc 1/** @file\r
2\r
ab6495ea 3 The UHCI register operation routines.\r
4\r
cd5ebaa0 5Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
913cb9dc 7\r
913cb9dc 8**/\r
9\r
10#include "Uhci.h"\r
11\r
913cb9dc 12/**\r
ab6495ea 13 Read a UHCI register.\r
913cb9dc 14\r
ab6495ea 15 @param PciIo The EFI_PCI_IO_PROTOCOL to use.\r
16 @param Offset Register offset to USB_BAR_INDEX.\r
913cb9dc 17\r
ab6495ea 18 @return Content of register.\r
913cb9dc 19\r
20**/\r
21UINT16\r
22UhciReadReg (\r
1436aea4
MK
23 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
24 IN UINT32 Offset\r
913cb9dc 25 )\r
26{\r
27 UINT16 Data;\r
28 EFI_STATUS Status;\r
29\r
30 Status = PciIo->Io.Read (\r
1436aea4
MK
31 PciIo,\r
32 EfiPciIoWidthUint16,\r
33 USB_BAR_INDEX,\r
34 Offset,\r
35 1,\r
36 &Data\r
37 );\r
913cb9dc 38\r
39 if (EFI_ERROR (Status)) {\r
87000d77 40 DEBUG ((DEBUG_ERROR, "UhciReadReg: PciIo Io.Read error: %r at offset %d\n", Status, Offset));\r
913cb9dc 41\r
42 Data = 0xFFFF;\r
43 }\r
44\r
45 return Data;\r
46}\r
47\r
913cb9dc 48/**\r
ab6495ea 49 Write data to UHCI register.\r
913cb9dc 50\r
ab6495ea 51 @param PciIo The EFI_PCI_IO_PROTOCOL to use.\r
52 @param Offset Register offset to USB_BAR_INDEX.\r
53 @param Data Data to write.\r
913cb9dc 54\r
913cb9dc 55**/\r
56VOID\r
57UhciWriteReg (\r
1436aea4
MK
58 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
59 IN UINT32 Offset,\r
60 IN UINT16 Data\r
913cb9dc 61 )\r
62{\r
63 EFI_STATUS Status;\r
64\r
65 Status = PciIo->Io.Write (\r
1436aea4
MK
66 PciIo,\r
67 EfiPciIoWidthUint16,\r
68 USB_BAR_INDEX,\r
69 Offset,\r
70 1,\r
71 &Data\r
72 );\r
913cb9dc 73\r
74 if (EFI_ERROR (Status)) {\r
87000d77 75 DEBUG ((DEBUG_ERROR, "UhciWriteReg: PciIo Io.Write error: %r at offset %d\n", Status, Offset));\r
913cb9dc 76 }\r
77}\r
78\r
913cb9dc 79/**\r
ab6495ea 80 Set a bit of the UHCI Register.\r
913cb9dc 81\r
ab6495ea 82 @param PciIo The EFI_PCI_IO_PROTOCOL to use.\r
83 @param Offset Register offset to USB_BAR_INDEX.\r
84 @param Bit The bit to set.\r
913cb9dc 85\r
913cb9dc 86**/\r
87VOID\r
88UhciSetRegBit (\r
1436aea4
MK
89 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
90 IN UINT32 Offset,\r
91 IN UINT16 Bit\r
913cb9dc 92 )\r
93{\r
94 UINT16 Data;\r
95\r
96 Data = UhciReadReg (PciIo, Offset);\r
1436aea4 97 Data = (UINT16)(Data |Bit);\r
913cb9dc 98 UhciWriteReg (PciIo, Offset, Data);\r
99}\r
100\r
913cb9dc 101/**\r
ab6495ea 102 Clear a bit of the UHCI Register.\r
913cb9dc 103\r
ab6495ea 104 @param PciIo The PCI_IO protocol to access the PCI.\r
105 @param Offset Register offset to USB_BAR_INDEX.\r
106 @param Bit The bit to clear.\r
913cb9dc 107\r
913cb9dc 108**/\r
109VOID\r
110UhciClearRegBit (\r
1436aea4
MK
111 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
112 IN UINT32 Offset,\r
113 IN UINT16 Bit\r
913cb9dc 114 )\r
115{\r
116 UINT16 Data;\r
117\r
118 Data = UhciReadReg (PciIo, Offset);\r
1436aea4 119 Data = (UINT16)(Data & ~Bit);\r
913cb9dc 120 UhciWriteReg (PciIo, Offset, Data);\r
121}\r
122\r
913cb9dc 123/**\r
124 Clear all the interrutp status bits, these bits\r
ab6495ea 125 are Write-Clean.\r
913cb9dc 126\r
ab6495ea 127 @param Uhc The UHCI device.\r
913cb9dc 128\r
913cb9dc 129**/\r
130VOID\r
131UhciAckAllInterrupt (\r
1436aea4 132 IN USB_HC_DEV *Uhc\r
913cb9dc 133 )\r
134{\r
135 UhciWriteReg (Uhc->PciIo, USBSTS_OFFSET, 0x3F);\r
136\r
137 //\r
138 // If current HC is halted, re-enable it. Host Controller Process Error\r
139 // is a temporary error status.\r
140 //\r
141 if (!UhciIsHcWorking (Uhc->PciIo)) {\r
87000d77 142 DEBUG ((DEBUG_ERROR, "UhciAckAllInterrupt: re-enable the UHCI from system error\n"));\r
ea5632e5 143 Uhc->Usb2Hc.SetState (&Uhc->Usb2Hc, EfiUsbHcStateOperational);\r
913cb9dc 144 }\r
145}\r
146\r
913cb9dc 147/**\r
ab6495ea 148 Stop the host controller.\r
913cb9dc 149\r
ab6495ea 150 @param Uhc The UHCI device.\r
151 @param Timeout Max time allowed.\r
913cb9dc 152\r
ab6495ea 153 @retval EFI_SUCCESS The host controller is stopped.\r
154 @retval EFI_TIMEOUT Failed to stop the host controller.\r
913cb9dc 155\r
156**/\r
157EFI_STATUS\r
158UhciStopHc (\r
1436aea4
MK
159 IN USB_HC_DEV *Uhc,\r
160 IN UINTN Timeout\r
913cb9dc 161 )\r
162{\r
1436aea4
MK
163 UINT16 UsbSts;\r
164 UINTN Index;\r
913cb9dc 165\r
166 UhciClearRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_RS);\r
167\r
168 //\r
169 // ensure the HC is in halt status after send the stop command\r
170 // Timeout is in us unit.\r
171 //\r
172 for (Index = 0; Index < (Timeout / 50) + 1; Index++) {\r
173 UsbSts = UhciReadReg (Uhc->PciIo, USBSTS_OFFSET);\r
174\r
175 if ((UsbSts & USBSTS_HCH) == USBSTS_HCH) {\r
176 return EFI_SUCCESS;\r
177 }\r
178\r
179 gBS->Stall (50);\r
180 }\r
181\r
182 return EFI_TIMEOUT;\r
183}\r
184\r
913cb9dc 185/**\r
ab6495ea 186 Check whether the host controller operates well.\r
913cb9dc 187\r
ab6495ea 188 @param PciIo The PCI_IO protocol to use.\r
913cb9dc 189\r
ab6495ea 190 @retval TRUE Host controller is working.\r
191 @retval FALSE Host controller is halted or system error.\r
913cb9dc 192\r
193**/\r
194BOOLEAN\r
195UhciIsHcWorking (\r
1436aea4 196 IN EFI_PCI_IO_PROTOCOL *PciIo\r
913cb9dc 197 )\r
198{\r
1436aea4 199 UINT16 UsbSts;\r
913cb9dc 200\r
201 UsbSts = UhciReadReg (PciIo, USBSTS_OFFSET);\r
202\r
ab6495ea 203 if ((UsbSts & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) != 0) {\r
87000d77 204 DEBUG ((DEBUG_ERROR, "UhciIsHcWorking: current USB state is %x\n", UsbSts));\r
913cb9dc 205 return FALSE;\r
206 }\r
207\r
208 return TRUE;\r
209}\r
210\r
913cb9dc 211/**\r
212 Set the UHCI frame list base address. It can't use\r
213 UhciWriteReg which access memory in UINT16.\r
214\r
ab6495ea 215 @param PciIo The EFI_PCI_IO_PROTOCOL to use.\r
216 @param Addr Address to set.\r
913cb9dc 217\r
913cb9dc 218**/\r
219VOID\r
220UhciSetFrameListBaseAddr (\r
1436aea4
MK
221 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
222 IN VOID *Addr\r
913cb9dc 223 )\r
224{\r
1436aea4
MK
225 EFI_STATUS Status;\r
226 UINT32 Data;\r
913cb9dc 227\r
1436aea4 228 Data = (UINT32)((UINTN)Addr & 0xFFFFF000);\r
913cb9dc 229\r
230 Status = PciIo->Io.Write (\r
231 PciIo,\r
232 EfiPciIoWidthUint32,\r
233 USB_BAR_INDEX,\r
1436aea4 234 (UINT64)USB_FRAME_BASE_OFFSET,\r
913cb9dc 235 1,\r
236 &Data\r
237 );\r
238\r
239 if (EFI_ERROR (Status)) {\r
87000d77 240 DEBUG ((DEBUG_ERROR, "UhciSetFrameListBaseAddr: PciIo Io.Write error: %r\n", Status));\r
913cb9dc 241 }\r
242}\r
243\r
913cb9dc 244/**\r
ab6495ea 245 Disable USB Emulation.\r
913cb9dc 246\r
ab6495ea 247 @param PciIo The EFI_PCI_IO_PROTOCOL protocol to use.\r
913cb9dc 248\r
913cb9dc 249**/\r
250VOID\r
251UhciTurnOffUsbEmulation (\r
1436aea4 252 IN EFI_PCI_IO_PROTOCOL *PciIo\r
913cb9dc 253 )\r
254{\r
1436aea4 255 UINT16 Command;\r
913cb9dc 256\r
257 Command = 0;\r
258\r
259 PciIo->Pci.Write (\r
260 PciIo,\r
261 EfiPciIoWidthUint16,\r
262 USB_EMULATION_OFFSET,\r
263 1,\r
264 &Command\r
265 );\r
266}\r