]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
MdeModulePkg XhciDxe: Set HSEE Bit if SERR# Enable Bit is set
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciReg.c
CommitLineData
92870c98 1/** @file\r
2\r
3 The XHCI register operation routines.\r
4\r
16f69227 5Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
92870c98 6This 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 "Xhci.h"\r
17\r
18/**\r
19 Read 1-byte width XHCI capability register.\r
20\r
a9292c13 21 @param Xhc The XHCI Instance.\r
92870c98 22 @param Offset The offset of the 1-byte width capability register.\r
23\r
24 @return The register content read.\r
25 @retval If err, return 0xFF.\r
26\r
27**/\r
28UINT8\r
29XhcReadCapReg8 (\r
a9292c13 30 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 31 IN UINT32 Offset\r
32 )\r
33{\r
34 UINT8 Data;\r
35 EFI_STATUS Status;\r
36\r
37 Status = Xhc->PciIo->Mem.Read (\r
38 Xhc->PciIo,\r
39 EfiPciIoWidthUint8,\r
40 XHC_BAR_INDEX,\r
41 (UINT64) Offset,\r
42 1,\r
43 &Data\r
44 );\r
45\r
46 if (EFI_ERROR (Status)) {\r
47 DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
48 Data = 0xFF;\r
49 }\r
50\r
51 return Data;\r
52}\r
53\r
54/**\r
55 Read 4-bytes width XHCI capability register.\r
56\r
a9292c13 57 @param Xhc The XHCI Instance.\r
92870c98 58 @param Offset The offset of the 4-bytes width capability register.\r
59\r
60 @return The register content read.\r
61 @retval If err, return 0xFFFFFFFF.\r
62\r
63**/\r
64UINT32\r
65XhcReadCapReg (\r
a9292c13 66 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 67 IN UINT32 Offset\r
68 )\r
69{\r
70 UINT32 Data;\r
71 EFI_STATUS Status;\r
72\r
73 Status = Xhc->PciIo->Mem.Read (\r
74 Xhc->PciIo,\r
75 EfiPciIoWidthUint32,\r
76 XHC_BAR_INDEX,\r
77 (UINT64) Offset,\r
78 1,\r
79 &Data\r
80 );\r
81\r
82 if (EFI_ERROR (Status)) {\r
83 DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
84 Data = 0xFFFFFFFF;\r
85 }\r
86\r
87 return Data;\r
88}\r
89\r
90/**\r
91 Read 4-bytes width XHCI Operational register.\r
92\r
a9292c13 93 @param Xhc The XHCI Instance.\r
92870c98 94 @param Offset The offset of the 4-bytes width operational register.\r
95\r
96 @return The register content read.\r
97 @retval If err, return 0xFFFFFFFF.\r
98\r
99**/\r
100UINT32\r
101XhcReadOpReg (\r
a9292c13 102 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 103 IN UINT32 Offset\r
104 )\r
105{\r
106 UINT32 Data;\r
107 EFI_STATUS Status;\r
108\r
109 ASSERT (Xhc->CapLength != 0);\r
110\r
111 Status = Xhc->PciIo->Mem.Read (\r
112 Xhc->PciIo,\r
113 EfiPciIoWidthUint32,\r
114 XHC_BAR_INDEX,\r
16f69227 115 Xhc->CapLength + Offset,\r
92870c98 116 1,\r
117 &Data\r
118 );\r
119\r
120 if (EFI_ERROR (Status)) {\r
121 DEBUG ((EFI_D_ERROR, "XhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
122 Data = 0xFFFFFFFF;\r
123 }\r
124\r
125 return Data;\r
126}\r
127\r
128/**\r
129 Write the data to the 4-bytes width XHCI operational register.\r
130\r
a9292c13 131 @param Xhc The XHCI Instance.\r
92870c98 132 @param Offset The offset of the 4-bytes width operational register.\r
133 @param Data The data to write.\r
134\r
135**/\r
136VOID\r
137XhcWriteOpReg (\r
a9292c13 138 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 139 IN UINT32 Offset,\r
140 IN UINT32 Data\r
141 )\r
142{\r
143 EFI_STATUS Status;\r
144\r
145 ASSERT (Xhc->CapLength != 0);\r
146\r
147 Status = Xhc->PciIo->Mem.Write (\r
148 Xhc->PciIo,\r
149 EfiPciIoWidthUint32,\r
150 XHC_BAR_INDEX,\r
16f69227 151 Xhc->CapLength + Offset,\r
92870c98 152 1,\r
153 &Data\r
154 );\r
155\r
156 if (EFI_ERROR (Status)) {\r
157 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
158 }\r
159}\r
160\r
92870c98 161\r
92870c98 162\r
92870c98 163\r
92870c98 164\r
165/**\r
166 Write the data to the XHCI door bell register.\r
167\r
a9292c13 168 @param Xhc The XHCI Instance.\r
92870c98 169 @param Offset The offset of the door bell register.\r
170 @param Data The data to write.\r
171\r
172**/\r
173VOID\r
174XhcWriteDoorBellReg (\r
a9292c13 175 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 176 IN UINT32 Offset,\r
177 IN UINT32 Data\r
178 )\r
179{\r
180 EFI_STATUS Status;\r
181\r
182 ASSERT (Xhc->DBOff != 0);\r
183\r
184 Status = Xhc->PciIo->Mem.Write (\r
185 Xhc->PciIo,\r
186 EfiPciIoWidthUint32,\r
187 XHC_BAR_INDEX,\r
16f69227 188 Xhc->DBOff + Offset,\r
92870c98 189 1,\r
190 &Data\r
191 );\r
192\r
193 if (EFI_ERROR (Status)) {\r
194 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
195 }\r
196}\r
197\r
198/**\r
199 Read XHCI runtime register.\r
200\r
a9292c13 201 @param Xhc The XHCI Instance.\r
92870c98 202 @param Offset The offset of the runtime register.\r
203\r
204 @return The register content read\r
205\r
206**/\r
207UINT32\r
208XhcReadRuntimeReg (\r
a9292c13 209 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 210 IN UINT32 Offset\r
211 )\r
212{\r
213 UINT32 Data;\r
214 EFI_STATUS Status;\r
215\r
216 ASSERT (Xhc->RTSOff != 0);\r
217\r
218 Status = Xhc->PciIo->Mem.Read (\r
219 Xhc->PciIo,\r
220 EfiPciIoWidthUint32,\r
221 XHC_BAR_INDEX,\r
16f69227 222 Xhc->RTSOff + Offset,\r
92870c98 223 1,\r
224 &Data\r
225 );\r
226\r
227 if (EFI_ERROR (Status)) {\r
228 DEBUG ((EFI_D_ERROR, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
229 Data = 0xFFFFFFFF;\r
230 }\r
231\r
232 return Data;\r
233}\r
234\r
92870c98 235/**\r
236 Write the data to the XHCI runtime register.\r
237\r
a9292c13 238 @param Xhc The XHCI Instance.\r
92870c98 239 @param Offset The offset of the runtime register.\r
240 @param Data The data to write.\r
241\r
242**/\r
243VOID\r
244XhcWriteRuntimeReg (\r
a9292c13 245 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 246 IN UINT32 Offset,\r
247 IN UINT32 Data\r
248 )\r
249{\r
250 EFI_STATUS Status;\r
251\r
252 ASSERT (Xhc->RTSOff != 0);\r
253\r
254 Status = Xhc->PciIo->Mem.Write (\r
255 Xhc->PciIo,\r
256 EfiPciIoWidthUint32,\r
257 XHC_BAR_INDEX,\r
16f69227 258 Xhc->RTSOff + Offset,\r
92870c98 259 1,\r
260 &Data\r
261 );\r
262\r
263 if (EFI_ERROR (Status)) {\r
264 DEBUG ((EFI_D_ERROR, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
265 }\r
266}\r
267\r
92870c98 268/**\r
269 Read XHCI extended capability register.\r
270\r
a9292c13 271 @param Xhc The XHCI Instance.\r
92870c98 272 @param Offset The offset of the extended capability register.\r
273\r
274 @return The register content read\r
275\r
276**/\r
277UINT32\r
278XhcReadExtCapReg (\r
a9292c13 279 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 280 IN UINT32 Offset\r
281 )\r
282{\r
283 UINT32 Data;\r
284 EFI_STATUS Status;\r
285\r
286 ASSERT (Xhc->ExtCapRegBase != 0);\r
287\r
288 Status = Xhc->PciIo->Mem.Read (\r
289 Xhc->PciIo,\r
290 EfiPciIoWidthUint32,\r
291 XHC_BAR_INDEX,\r
16f69227 292 Xhc->ExtCapRegBase + Offset,\r
92870c98 293 1,\r
294 &Data\r
295 );\r
296\r
297 if (EFI_ERROR (Status)) {\r
298 DEBUG ((EFI_D_ERROR, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
299 Data = 0xFFFFFFFF;\r
300 }\r
301\r
302 return Data;\r
303}\r
304\r
305/**\r
306 Write the data to the XHCI extended capability register.\r
307\r
a9292c13 308 @param Xhc The XHCI Instance.\r
92870c98 309 @param Offset The offset of the extended capability register.\r
310 @param Data The data to write.\r
311\r
312**/\r
313VOID\r
314XhcWriteExtCapReg (\r
a9292c13 315 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 316 IN UINT32 Offset,\r
317 IN UINT32 Data\r
318 )\r
319{\r
320 EFI_STATUS Status;\r
321\r
322 ASSERT (Xhc->ExtCapRegBase != 0);\r
323\r
324 Status = Xhc->PciIo->Mem.Write (\r
325 Xhc->PciIo,\r
326 EfiPciIoWidthUint32,\r
327 XHC_BAR_INDEX,\r
16f69227 328 Xhc->ExtCapRegBase + Offset,\r
92870c98 329 1,\r
330 &Data\r
331 );\r
332\r
333 if (EFI_ERROR (Status)) {\r
334 DEBUG ((EFI_D_ERROR, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
335 }\r
336}\r
337\r
338\r
339/**\r
340 Set one bit of the runtime register while keeping other bits.\r
341\r
a9292c13 342 @param Xhc The XHCI Instance.\r
92870c98 343 @param Offset The offset of the runtime register.\r
344 @param Bit The bit mask of the register to set.\r
345\r
346**/\r
347VOID\r
348XhcSetRuntimeRegBit (\r
a9292c13 349 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 350 IN UINT32 Offset,\r
351 IN UINT32 Bit\r
352 )\r
353{\r
354 UINT32 Data;\r
355\r
356 Data = XhcReadRuntimeReg (Xhc, Offset);\r
357 Data |= Bit;\r
358 XhcWriteRuntimeReg (Xhc, Offset, Data);\r
359}\r
360\r
361/**\r
362 Clear one bit of the runtime register while keeping other bits.\r
363\r
a9292c13 364 @param Xhc The XHCI Instance.\r
92870c98 365 @param Offset The offset of the runtime register.\r
366 @param Bit The bit mask of the register to set.\r
367\r
368**/\r
369VOID\r
370XhcClearRuntimeRegBit (\r
a9292c13 371 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 372 IN UINT32 Offset,\r
373 IN UINT32 Bit\r
374 )\r
375{\r
376 UINT32 Data;\r
377\r
378 Data = XhcReadRuntimeReg (Xhc, Offset);\r
379 Data &= ~Bit;\r
380 XhcWriteRuntimeReg (Xhc, Offset, Data);\r
381}\r
382\r
383/**\r
384 Set one bit of the operational register while keeping other bits.\r
385\r
a9292c13 386 @param Xhc The XHCI Instance.\r
92870c98 387 @param Offset The offset of the operational register.\r
388 @param Bit The bit mask of the register to set.\r
389\r
390**/\r
391VOID\r
392XhcSetOpRegBit (\r
a9292c13 393 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 394 IN UINT32 Offset,\r
395 IN UINT32 Bit\r
396 )\r
397{\r
398 UINT32 Data;\r
399\r
400 Data = XhcReadOpReg (Xhc, Offset);\r
401 Data |= Bit;\r
402 XhcWriteOpReg (Xhc, Offset, Data);\r
403}\r
404\r
405\r
406/**\r
407 Clear one bit of the operational register while keeping other bits.\r
408\r
a9292c13 409 @param Xhc The XHCI Instance.\r
92870c98 410 @param Offset The offset of the operational register.\r
411 @param Bit The bit mask of the register to clear.\r
412\r
413**/\r
414VOID\r
415XhcClearOpRegBit (\r
a9292c13 416 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 417 IN UINT32 Offset,\r
418 IN UINT32 Bit\r
419 )\r
420{\r
421 UINT32 Data;\r
422\r
423 Data = XhcReadOpReg (Xhc, Offset);\r
424 Data &= ~Bit;\r
425 XhcWriteOpReg (Xhc, Offset, Data);\r
426}\r
427\r
428/**\r
429 Wait the operation register's bit as specified by Bit\r
430 to become set (or clear).\r
431\r
a9292c13 432 @param Xhc The XHCI Instance.\r
92870c98 433 @param Offset The offset of the operation register.\r
434 @param Bit The bit of the register to wait for.\r
435 @param WaitToSet Wait the bit to set or clear.\r
26cd2d6d 436 @param Timeout The time to wait before abort (in millisecond, ms).\r
92870c98 437\r
438 @retval EFI_SUCCESS The bit successfully changed by host controller.\r
439 @retval EFI_TIMEOUT The time out occurred.\r
440\r
441**/\r
442EFI_STATUS\r
443XhcWaitOpRegBit (\r
a9292c13 444 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 445 IN UINT32 Offset,\r
446 IN UINT32 Bit,\r
447 IN BOOLEAN WaitToSet,\r
448 IN UINT32 Timeout\r
449 )\r
450{\r
451 UINT32 Index;\r
26cd2d6d 452 UINT64 Loop;\r
92870c98 453\r
26cd2d6d 454 Loop = Timeout * XHC_1_MILLISECOND;\r
a9292c13 455\r
456 for (Index = 0; Index < Loop; Index++) {\r
92870c98 457 if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) {\r
458 return EFI_SUCCESS;\r
459 }\r
460\r
26cd2d6d 461 gBS->Stall (XHC_1_MICROSECOND);\r
92870c98 462 }\r
463\r
464 return EFI_TIMEOUT;\r
465}\r
466\r
467/**\r
468 Set Bios Ownership\r
469\r
a9292c13 470 @param Xhc The XHCI Instance.\r
92870c98 471\r
472**/\r
473VOID\r
474XhcSetBiosOwnership (\r
a9292c13 475 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 476 )\r
477{\r
478 UINT32 Buffer;\r
479\r
74b04490
SI
480 if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
481 return;\r
482 }\r
483\r
92870c98 484 DEBUG ((EFI_D_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n"));\r
485\r
486 Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
487 Buffer = ((Buffer & (~USBLEGSP_OS_SEMAPHORE)) | USBLEGSP_BIOS_SEMAPHORE);\r
488 XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer);\r
489}\r
490\r
491/**\r
492 Clear Bios Ownership\r
493\r
a9292c13 494 @param Xhc The XHCI Instance.\r
92870c98 495\r
496**/\r
497VOID\r
498XhcClearBiosOwnership (\r
a9292c13 499 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 500 )\r
501{\r
502 UINT32 Buffer;\r
503\r
74b04490
SI
504 if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
505 return;\r
506 }\r
507\r
92870c98 508 DEBUG ((EFI_D_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));\r
509\r
510 Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
511 Buffer = ((Buffer & (~USBLEGSP_BIOS_SEMAPHORE)) | USBLEGSP_OS_SEMAPHORE);\r
512 XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer);\r
513}\r
514\r
515/**\r
5bcb62a4 516 Calculate the offset of the XHCI capability.\r
92870c98 517\r
a9292c13 518 @param Xhc The XHCI Instance.\r
5bcb62a4 519 @param CapId The XHCI Capability ID.\r
92870c98 520\r
521 @return The offset of XHCI legacy support capability register.\r
522\r
523**/\r
524UINT32\r
5bcb62a4
EL
525XhcGetCapabilityAddr (\r
526 IN USB_XHCI_INSTANCE *Xhc,\r
527 IN UINT8 CapId\r
92870c98 528 )\r
529{\r
530 UINT32 ExtCapOffset;\r
531 UINT8 NextExtCapReg;\r
532 UINT32 Data;\r
533\r
534 ExtCapOffset = 0;\r
535\r
536 do {\r
537 //\r
538 // Check if the extended capability register's capability id is USB Legacy Support.\r
539 //\r
540 Data = XhcReadExtCapReg (Xhc, ExtCapOffset);\r
5bcb62a4 541 if ((Data & 0xFF) == CapId) {\r
92870c98 542 return ExtCapOffset;\r
543 }\r
544 //\r
545 // If not, then traverse all of the ext capability registers till finding out it.\r
546 //\r
ce9b5900 547 NextExtCapReg = (UINT8)((Data >> 8) & 0xFF);\r
92870c98 548 ExtCapOffset += (NextExtCapReg << 2);\r
549 } while (NextExtCapReg != 0);\r
550\r
74b04490 551 return 0xFFFFFFFF;\r
92870c98 552}\r
553\r
554/**\r
555 Whether the XHCI host controller is halted.\r
556\r
a9292c13 557 @param Xhc The XHCI Instance.\r
92870c98 558\r
559 @retval TRUE The controller is halted.\r
560 @retval FALSE It isn't halted.\r
561\r
562**/\r
563BOOLEAN\r
564XhcIsHalt (\r
a9292c13 565 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 566 )\r
567{\r
568 return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT);\r
569}\r
570\r
571\r
572/**\r
573 Whether system error occurred.\r
574\r
a9292c13 575 @param Xhc The XHCI Instance.\r
92870c98 576\r
577 @retval TRUE System error happened.\r
578 @retval FALSE No system error.\r
579\r
580**/\r
581BOOLEAN\r
582XhcIsSysError (\r
a9292c13 583 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 584 )\r
585{\r
586 return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE);\r
587}\r
588\r
73dbd6af
SZ
589/**\r
590 Set USBCMD Host System Error Enable(HSEE) Bit if PCICMD SERR# Enable Bit is set.\r
591\r
592 The USBCMD HSEE Bit will be reset to default 0 by USBCMD Host Controller Reset(HCRST).\r
593 This function is to set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
594\r
595 @param Xhc The XHCI Instance.\r
596\r
597**/\r
598VOID\r
599XhcSetHsee (\r
600 IN USB_XHCI_INSTANCE *Xhc\r
601 )\r
602{\r
603 EFI_STATUS Status;\r
604 EFI_PCI_IO_PROTOCOL *PciIo;\r
605 UINT16 XhciCmd;\r
606\r
607 PciIo = Xhc->PciIo;\r
608 Status = PciIo->Pci.Read (\r
609 PciIo,\r
610 EfiPciIoWidthUint16,\r
611 PCI_COMMAND_OFFSET,\r
612 sizeof (XhciCmd),\r
613 &XhciCmd\r
614 );\r
615 if (!EFI_ERROR (Status)) {\r
616 if ((XhciCmd & EFI_PCI_COMMAND_SERR) != 0) {\r
617 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_HSEE);\r
618 }\r
619 }\r
620}\r
621\r
92870c98 622/**\r
623 Reset the XHCI host controller.\r
624\r
a9292c13 625 @param Xhc The XHCI Instance.\r
26cd2d6d 626 @param Timeout Time to wait before abort (in millisecond, ms).\r
92870c98 627\r
628 @retval EFI_SUCCESS The XHCI host controller is reset.\r
629 @return Others Failed to reset the XHCI before Timeout.\r
630\r
631**/\r
632EFI_STATUS\r
633XhcResetHC (\r
a9292c13 634 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 635 IN UINT32 Timeout\r
636 )\r
637{\r
638 EFI_STATUS Status;\r
639\r
5bcb62a4
EL
640 Status = EFI_SUCCESS;\r
641\r
92870c98 642 DEBUG ((EFI_D_INFO, "XhcResetHC!\n"));\r
643 //\r
644 // Host can only be reset when it is halt. If not so, halt it\r
645 //\r
646 if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) {\r
647 Status = XhcHaltHC (Xhc, Timeout);\r
648\r
649 if (EFI_ERROR (Status)) {\r
650 return Status;\r
651 }\r
652 }\r
653\r
74b04490 654 if ((Xhc->DebugCapSupOffset == 0xFFFFFFFF) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) ||\r
5bcb62a4
EL
655 ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0)) {\r
656 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
dbe10619
FT
657 //\r
658 // Some XHCI host controllers require to have extra 1ms delay before accessing any MMIO register during reset.\r
659 // Otherwise there may have the timeout case happened.\r
660 // The below is a workaround to solve such problem.\r
661 //\r
662 gBS->Stall (XHC_1_MILLISECOND);\r
5bcb62a4 663 Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
73dbd6af
SZ
664\r
665 if (!EFI_ERROR (Status)) {\r
666 //\r
667 // The USBCMD HSEE Bit will be reset to default 0 by USBCMD HCRST.\r
668 // Set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
669 //\r
670 XhcSetHsee (Xhc);\r
671 }\r
5bcb62a4
EL
672 }\r
673\r
92870c98 674 return Status;\r
675}\r
676\r
677\r
678/**\r
679 Halt the XHCI host controller.\r
680\r
a9292c13 681 @param Xhc The XHCI Instance.\r
26cd2d6d 682 @param Timeout Time to wait before abort (in millisecond, ms).\r
92870c98 683\r
684 @return EFI_SUCCESS The XHCI host controller is halt.\r
685 @return EFI_TIMEOUT Failed to halt the XHCI before Timeout.\r
686\r
687**/\r
688EFI_STATUS\r
689XhcHaltHC (\r
a9292c13 690 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 691 IN UINT32 Timeout\r
692 )\r
693{\r
694 EFI_STATUS Status;\r
695\r
696 XhcClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
697 Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, TRUE, Timeout);\r
698 return Status;\r
699}\r
700\r
701\r
702/**\r
703 Set the XHCI host controller to run.\r
704\r
a9292c13 705 @param Xhc The XHCI Instance.\r
26cd2d6d 706 @param Timeout Time to wait before abort (in millisecond, ms).\r
92870c98 707\r
708 @return EFI_SUCCESS The XHCI host controller is running.\r
709 @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout.\r
710\r
711**/\r
712EFI_STATUS\r
713XhcRunHC (\r
a9292c13 714 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 715 IN UINT32 Timeout\r
716 )\r
717{\r
718 EFI_STATUS Status;\r
719\r
720 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
721 Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, FALSE, Timeout);\r
722 return Status;\r
723}\r
724\r