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