]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / UhciDxe / UhciReg.c
... / ...
CommitLineData
1/** @file\r
2\r
3 The UHCI register operation routines.\r
4\r
5Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
6SPDX-License-Identifier: BSD-2-Clause-Patent\r
7\r
8**/\r
9\r
10#include "Uhci.h"\r
11\r
12\r
13/**\r
14 Read a UHCI register.\r
15\r
16 @param PciIo The EFI_PCI_IO_PROTOCOL to use.\r
17 @param Offset Register offset to USB_BAR_INDEX.\r
18\r
19 @return Content of register.\r
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
41 DEBUG ((EFI_D_ERROR, "UhciReadReg: PciIo Io.Read error: %r at offset %d\n", Status, Offset));\r
42\r
43 Data = 0xFFFF;\r
44 }\r
45\r
46 return Data;\r
47}\r
48\r
49\r
50/**\r
51 Write data to UHCI register.\r
52\r
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
56\r
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
77 DEBUG ((EFI_D_ERROR, "UhciWriteReg: PciIo Io.Write error: %r at offset %d\n", Status, Offset));\r
78 }\r
79}\r
80\r
81\r
82/**\r
83 Set a bit of the UHCI Register.\r
84\r
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
88\r
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
100 Data = (UINT16) (Data |Bit);\r
101 UhciWriteReg (PciIo, Offset, Data);\r
102}\r
103\r
104\r
105/**\r
106 Clear a bit of the UHCI Register.\r
107\r
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
111\r
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
123 Data = (UINT16) (Data & ~Bit);\r
124 UhciWriteReg (PciIo, Offset, Data);\r
125}\r
126\r
127\r
128/**\r
129 Clear all the interrutp status bits, these bits\r
130 are Write-Clean.\r
131\r
132 @param Uhc The UHCI device.\r
133\r
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
147 DEBUG ((EFI_D_ERROR, "UhciAckAllInterrupt: re-enable the UHCI from system error\n"));\r
148 Uhc->Usb2Hc.SetState (&Uhc->Usb2Hc, EfiUsbHcStateOperational);\r
149 }\r
150}\r
151\r
152\r
153/**\r
154 Stop the host controller.\r
155\r
156 @param Uhc The UHCI device.\r
157 @param Timeout Max time allowed.\r
158\r
159 @retval EFI_SUCCESS The host controller is stopped.\r
160 @retval EFI_TIMEOUT Failed to stop the host controller.\r
161\r
162**/\r
163EFI_STATUS\r
164UhciStopHc (\r
165 IN USB_HC_DEV *Uhc,\r
166 IN UINTN Timeout\r
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
193 Check whether the host controller operates well.\r
194\r
195 @param PciIo The PCI_IO protocol to use.\r
196\r
197 @retval TRUE Host controller is working.\r
198 @retval FALSE Host controller is halted or system error.\r
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
210 if ((UsbSts & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) != 0) {\r
211 DEBUG ((EFI_D_ERROR, "UhciIsHcWorking: current USB state is %x\n", UsbSts));\r
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
223 @param PciIo The EFI_PCI_IO_PROTOCOL to use.\r
224 @param Addr Address to set.\r
225\r
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
248 DEBUG ((EFI_D_ERROR, "UhciSetFrameListBaseAddr: PciIo Io.Write error: %r\n", Status));\r
249 }\r
250}\r
251\r
252\r
253/**\r
254 Disable USB Emulation.\r
255\r
256 @param PciIo The EFI_PCI_IO_PROTOCOL protocol to use.\r
257\r
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