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