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