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