]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
MdeModulePkg/XhciDxe: Usb legacy support feature is optional. For those usb 3.0 devic...
[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
5Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
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
115 (UINT64) (Xhc->CapLength + Offset),\r
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
151 (UINT64) (Xhc->CapLength + Offset),\r
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
161/**\r
162 Write the data to the 2-bytes width XHCI operational register.\r
163\r
a9292c13 164 @param Xhc The XHCI Instance.\r
92870c98 165 @param Offset The offset of the 2-bytes width operational register.\r
166 @param Data The data to write.\r
167\r
168**/\r
169VOID\r
170XhcWriteOpReg16 (\r
a9292c13 171 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 172 IN UINT32 Offset,\r
173 IN UINT16 Data\r
174 )\r
175{\r
176 EFI_STATUS Status;\r
177\r
178 ASSERT (Xhc->CapLength != 0);\r
179\r
180 Status = Xhc->PciIo->Mem.Write (\r
181 Xhc->PciIo,\r
182 EfiPciIoWidthUint16,\r
183 XHC_BAR_INDEX,\r
184 (UINT64) (Xhc->CapLength + Offset),\r
185 1,\r
186 &Data\r
187 );\r
188\r
189 if (EFI_ERROR (Status)) {\r
190 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg16: Pci Io Write error: %r at %d\n", Status, Offset));\r
191 }\r
192}\r
193\r
92870c98 194/**\r
195 Read XHCI door bell register.\r
196\r
a9292c13 197 @param Xhc The XHCI Instance.\r
92870c98 198 @param Offset The offset of the door bell register.\r
199\r
200 @return The register content read\r
201\r
202**/\r
203UINT32\r
204XhcReadDoorBellReg (\r
a9292c13 205 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 206 IN UINT32 Offset\r
207 )\r
208{\r
209 UINT32 Data;\r
210 EFI_STATUS Status;\r
211\r
212 ASSERT (Xhc->DBOff != 0);\r
213\r
214 Status = Xhc->PciIo->Mem.Read (\r
215 Xhc->PciIo,\r
216 EfiPciIoWidthUint32,\r
217 XHC_BAR_INDEX,\r
218 (UINT64) (Xhc->DBOff + Offset),\r
219 1,\r
220 &Data\r
221 );\r
222\r
223 if (EFI_ERROR (Status)) {\r
224 DEBUG ((EFI_D_ERROR, "XhcReadDoorBellReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
225 Data = 0xFFFFFFFF;\r
226 }\r
227\r
228 return Data;\r
229}\r
230\r
231/**\r
232 Write the data to the XHCI door bell register.\r
233\r
a9292c13 234 @param Xhc The XHCI Instance.\r
92870c98 235 @param Offset The offset of the door bell register.\r
236 @param Data The data to write.\r
237\r
238**/\r
239VOID\r
240XhcWriteDoorBellReg (\r
a9292c13 241 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 242 IN UINT32 Offset,\r
243 IN UINT32 Data\r
244 )\r
245{\r
246 EFI_STATUS Status;\r
247\r
248 ASSERT (Xhc->DBOff != 0);\r
249\r
250 Status = Xhc->PciIo->Mem.Write (\r
251 Xhc->PciIo,\r
252 EfiPciIoWidthUint32,\r
253 XHC_BAR_INDEX,\r
254 (UINT64) (Xhc->DBOff + Offset),\r
255 1,\r
256 &Data\r
257 );\r
258\r
259 if (EFI_ERROR (Status)) {\r
260 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
261 }\r
262}\r
263\r
264/**\r
265 Read XHCI runtime register.\r
266\r
a9292c13 267 @param Xhc The XHCI Instance.\r
92870c98 268 @param Offset The offset of the runtime register.\r
269\r
270 @return The register content read\r
271\r
272**/\r
273UINT32\r
274XhcReadRuntimeReg (\r
a9292c13 275 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 276 IN UINT32 Offset\r
277 )\r
278{\r
279 UINT32 Data;\r
280 EFI_STATUS Status;\r
281\r
282 ASSERT (Xhc->RTSOff != 0);\r
283\r
284 Status = Xhc->PciIo->Mem.Read (\r
285 Xhc->PciIo,\r
286 EfiPciIoWidthUint32,\r
287 XHC_BAR_INDEX,\r
288 (UINT64) (Xhc->RTSOff + Offset),\r
289 1,\r
290 &Data\r
291 );\r
292\r
293 if (EFI_ERROR (Status)) {\r
294 DEBUG ((EFI_D_ERROR, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
295 Data = 0xFFFFFFFF;\r
296 }\r
297\r
298 return Data;\r
299}\r
300\r
92870c98 301/**\r
302 Write the data to the XHCI runtime register.\r
303\r
a9292c13 304 @param Xhc The XHCI Instance.\r
92870c98 305 @param Offset The offset of the runtime register.\r
306 @param Data The data to write.\r
307\r
308**/\r
309VOID\r
310XhcWriteRuntimeReg (\r
a9292c13 311 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 312 IN UINT32 Offset,\r
313 IN UINT32 Data\r
314 )\r
315{\r
316 EFI_STATUS Status;\r
317\r
318 ASSERT (Xhc->RTSOff != 0);\r
319\r
320 Status = Xhc->PciIo->Mem.Write (\r
321 Xhc->PciIo,\r
322 EfiPciIoWidthUint32,\r
323 XHC_BAR_INDEX,\r
324 (UINT64) (Xhc->RTSOff + Offset),\r
325 1,\r
326 &Data\r
327 );\r
328\r
329 if (EFI_ERROR (Status)) {\r
330 DEBUG ((EFI_D_ERROR, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
331 }\r
332}\r
333\r
92870c98 334/**\r
335 Read XHCI extended capability register.\r
336\r
a9292c13 337 @param Xhc The XHCI Instance.\r
92870c98 338 @param Offset The offset of the extended capability register.\r
339\r
340 @return The register content read\r
341\r
342**/\r
343UINT32\r
344XhcReadExtCapReg (\r
a9292c13 345 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 346 IN UINT32 Offset\r
347 )\r
348{\r
349 UINT32 Data;\r
350 EFI_STATUS Status;\r
351\r
352 ASSERT (Xhc->ExtCapRegBase != 0);\r
353\r
354 Status = Xhc->PciIo->Mem.Read (\r
355 Xhc->PciIo,\r
356 EfiPciIoWidthUint32,\r
357 XHC_BAR_INDEX,\r
358 (UINT64) (Xhc->ExtCapRegBase + Offset),\r
359 1,\r
360 &Data\r
361 );\r
362\r
363 if (EFI_ERROR (Status)) {\r
364 DEBUG ((EFI_D_ERROR, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
365 Data = 0xFFFFFFFF;\r
366 }\r
367\r
368 return Data;\r
369}\r
370\r
371/**\r
372 Write the data to the XHCI extended capability register.\r
373\r
a9292c13 374 @param Xhc The XHCI Instance.\r
92870c98 375 @param Offset The offset of the extended capability register.\r
376 @param Data The data to write.\r
377\r
378**/\r
379VOID\r
380XhcWriteExtCapReg (\r
a9292c13 381 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 382 IN UINT32 Offset,\r
383 IN UINT32 Data\r
384 )\r
385{\r
386 EFI_STATUS Status;\r
387\r
388 ASSERT (Xhc->ExtCapRegBase != 0);\r
389\r
390 Status = Xhc->PciIo->Mem.Write (\r
391 Xhc->PciIo,\r
392 EfiPciIoWidthUint32,\r
393 XHC_BAR_INDEX,\r
394 (UINT64) (Xhc->ExtCapRegBase + Offset),\r
395 1,\r
396 &Data\r
397 );\r
398\r
399 if (EFI_ERROR (Status)) {\r
400 DEBUG ((EFI_D_ERROR, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
401 }\r
402}\r
403\r
404\r
405/**\r
406 Set one bit of the runtime register while keeping other bits.\r
407\r
a9292c13 408 @param Xhc The XHCI Instance.\r
92870c98 409 @param Offset The offset of the runtime register.\r
410 @param Bit The bit mask of the register to set.\r
411\r
412**/\r
413VOID\r
414XhcSetRuntimeRegBit (\r
a9292c13 415 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 416 IN UINT32 Offset,\r
417 IN UINT32 Bit\r
418 )\r
419{\r
420 UINT32 Data;\r
421\r
422 Data = XhcReadRuntimeReg (Xhc, Offset);\r
423 Data |= Bit;\r
424 XhcWriteRuntimeReg (Xhc, Offset, Data);\r
425}\r
426\r
427/**\r
428 Clear one bit of the runtime register while keeping other bits.\r
429\r
a9292c13 430 @param Xhc The XHCI Instance.\r
92870c98 431 @param Offset The offset of the runtime register.\r
432 @param Bit The bit mask of the register to set.\r
433\r
434**/\r
435VOID\r
436XhcClearRuntimeRegBit (\r
a9292c13 437 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 438 IN UINT32 Offset,\r
439 IN UINT32 Bit\r
440 )\r
441{\r
442 UINT32 Data;\r
443\r
444 Data = XhcReadRuntimeReg (Xhc, Offset);\r
445 Data &= ~Bit;\r
446 XhcWriteRuntimeReg (Xhc, Offset, Data);\r
447}\r
448\r
449/**\r
450 Set one bit of the operational register while keeping other bits.\r
451\r
a9292c13 452 @param Xhc The XHCI Instance.\r
92870c98 453 @param Offset The offset of the operational register.\r
454 @param Bit The bit mask of the register to set.\r
455\r
456**/\r
457VOID\r
458XhcSetOpRegBit (\r
a9292c13 459 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 460 IN UINT32 Offset,\r
461 IN UINT32 Bit\r
462 )\r
463{\r
464 UINT32 Data;\r
465\r
466 Data = XhcReadOpReg (Xhc, Offset);\r
467 Data |= Bit;\r
468 XhcWriteOpReg (Xhc, Offset, Data);\r
469}\r
470\r
471\r
472/**\r
473 Clear one bit of the operational register while keeping other bits.\r
474\r
a9292c13 475 @param Xhc The XHCI Instance.\r
92870c98 476 @param Offset The offset of the operational register.\r
477 @param Bit The bit mask of the register to clear.\r
478\r
479**/\r
480VOID\r
481XhcClearOpRegBit (\r
a9292c13 482 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 483 IN UINT32 Offset,\r
484 IN UINT32 Bit\r
485 )\r
486{\r
487 UINT32 Data;\r
488\r
489 Data = XhcReadOpReg (Xhc, Offset);\r
490 Data &= ~Bit;\r
491 XhcWriteOpReg (Xhc, Offset, Data);\r
492}\r
493\r
494/**\r
495 Wait the operation register's bit as specified by Bit\r
496 to become set (or clear).\r
497\r
a9292c13 498 @param Xhc The XHCI Instance.\r
92870c98 499 @param Offset The offset of the operation register.\r
500 @param Bit The bit of the register to wait for.\r
501 @param WaitToSet Wait the bit to set or clear.\r
502 @param Timeout The time to wait before abort (in millisecond, ms).\r
503\r
504 @retval EFI_SUCCESS The bit successfully changed by host controller.\r
505 @retval EFI_TIMEOUT The time out occurred.\r
506\r
507**/\r
508EFI_STATUS\r
509XhcWaitOpRegBit (\r
a9292c13 510 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 511 IN UINT32 Offset,\r
512 IN UINT32 Bit,\r
513 IN BOOLEAN WaitToSet,\r
514 IN UINT32 Timeout\r
515 )\r
516{\r
517 UINT32 Index;\r
a9292c13 518 UINTN Loop;\r
92870c98 519\r
a9292c13 520 Loop = (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1;\r
521\r
522 for (Index = 0; Index < Loop; Index++) {\r
92870c98 523 if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) {\r
524 return EFI_SUCCESS;\r
525 }\r
526\r
a9292c13 527 gBS->Stall (XHC_POLL_DELAY);\r
92870c98 528 }\r
529\r
530 return EFI_TIMEOUT;\r
531}\r
532\r
533/**\r
534 Set Bios Ownership\r
535\r
a9292c13 536 @param Xhc The XHCI Instance.\r
92870c98 537\r
538**/\r
539VOID\r
540XhcSetBiosOwnership (\r
a9292c13 541 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 542 )\r
543{\r
544 UINT32 Buffer;\r
545\r
74b04490
SI
546 if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
547 return;\r
548 }\r
549\r
92870c98 550 DEBUG ((EFI_D_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n"));\r
551\r
552 Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
553 Buffer = ((Buffer & (~USBLEGSP_OS_SEMAPHORE)) | USBLEGSP_BIOS_SEMAPHORE);\r
554 XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer);\r
555}\r
556\r
557/**\r
558 Clear Bios Ownership\r
559\r
a9292c13 560 @param Xhc The XHCI Instance.\r
92870c98 561\r
562**/\r
563VOID\r
564XhcClearBiosOwnership (\r
a9292c13 565 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 566 )\r
567{\r
568 UINT32 Buffer;\r
569\r
74b04490
SI
570 if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
571 return;\r
572 }\r
573\r
92870c98 574 DEBUG ((EFI_D_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));\r
575\r
576 Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
577 Buffer = ((Buffer & (~USBLEGSP_BIOS_SEMAPHORE)) | USBLEGSP_OS_SEMAPHORE);\r
578 XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer);\r
579}\r
580\r
581/**\r
5bcb62a4 582 Calculate the offset of the XHCI capability.\r
92870c98 583\r
a9292c13 584 @param Xhc The XHCI Instance.\r
5bcb62a4 585 @param CapId The XHCI Capability ID.\r
92870c98 586\r
587 @return The offset of XHCI legacy support capability register.\r
588\r
589**/\r
590UINT32\r
5bcb62a4
EL
591XhcGetCapabilityAddr (\r
592 IN USB_XHCI_INSTANCE *Xhc,\r
593 IN UINT8 CapId\r
92870c98 594 )\r
595{\r
596 UINT32 ExtCapOffset;\r
597 UINT8 NextExtCapReg;\r
598 UINT32 Data;\r
599\r
600 ExtCapOffset = 0;\r
601\r
602 do {\r
603 //\r
604 // Check if the extended capability register's capability id is USB Legacy Support.\r
605 //\r
606 Data = XhcReadExtCapReg (Xhc, ExtCapOffset);\r
5bcb62a4 607 if ((Data & 0xFF) == CapId) {\r
92870c98 608 return ExtCapOffset;\r
609 }\r
610 //\r
611 // If not, then traverse all of the ext capability registers till finding out it.\r
612 //\r
ce9b5900 613 NextExtCapReg = (UINT8)((Data >> 8) & 0xFF);\r
92870c98 614 ExtCapOffset += (NextExtCapReg << 2);\r
615 } while (NextExtCapReg != 0);\r
616\r
74b04490 617 return 0xFFFFFFFF;\r
92870c98 618}\r
619\r
620/**\r
621 Whether the XHCI host controller is halted.\r
622\r
a9292c13 623 @param Xhc The XHCI Instance.\r
92870c98 624\r
625 @retval TRUE The controller is halted.\r
626 @retval FALSE It isn't halted.\r
627\r
628**/\r
629BOOLEAN\r
630XhcIsHalt (\r
a9292c13 631 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 632 )\r
633{\r
634 return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT);\r
635}\r
636\r
637\r
638/**\r
639 Whether system error occurred.\r
640\r
a9292c13 641 @param Xhc The XHCI Instance.\r
92870c98 642\r
643 @retval TRUE System error happened.\r
644 @retval FALSE No system error.\r
645\r
646**/\r
647BOOLEAN\r
648XhcIsSysError (\r
a9292c13 649 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 650 )\r
651{\r
652 return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE);\r
653}\r
654\r
655/**\r
656 Reset the XHCI host controller.\r
657\r
a9292c13 658 @param Xhc The XHCI Instance.\r
92870c98 659 @param Timeout Time to wait before abort (in millisecond, ms).\r
660\r
661 @retval EFI_SUCCESS The XHCI host controller is reset.\r
662 @return Others Failed to reset the XHCI before Timeout.\r
663\r
664**/\r
665EFI_STATUS\r
666XhcResetHC (\r
a9292c13 667 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 668 IN UINT32 Timeout\r
669 )\r
670{\r
671 EFI_STATUS Status;\r
672\r
5bcb62a4
EL
673 Status = EFI_SUCCESS;\r
674\r
92870c98 675 DEBUG ((EFI_D_INFO, "XhcResetHC!\n"));\r
676 //\r
677 // Host can only be reset when it is halt. If not so, halt it\r
678 //\r
679 if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) {\r
680 Status = XhcHaltHC (Xhc, Timeout);\r
681\r
682 if (EFI_ERROR (Status)) {\r
683 return Status;\r
684 }\r
685 }\r
686\r
74b04490 687 if ((Xhc->DebugCapSupOffset == 0xFFFFFFFF) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) ||\r
5bcb62a4
EL
688 ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0)) {\r
689 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
690 Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
691 }\r
692\r
92870c98 693 return Status;\r
694}\r
695\r
696\r
697/**\r
698 Halt the XHCI host controller.\r
699\r
a9292c13 700 @param Xhc The XHCI Instance.\r
92870c98 701 @param Timeout Time to wait before abort (in millisecond, ms).\r
702\r
703 @return EFI_SUCCESS The XHCI host controller is halt.\r
704 @return EFI_TIMEOUT Failed to halt the XHCI before Timeout.\r
705\r
706**/\r
707EFI_STATUS\r
708XhcHaltHC (\r
a9292c13 709 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 710 IN UINT32 Timeout\r
711 )\r
712{\r
713 EFI_STATUS Status;\r
714\r
715 XhcClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
716 Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, TRUE, Timeout);\r
717 return Status;\r
718}\r
719\r
720\r
721/**\r
722 Set the XHCI host controller to run.\r
723\r
a9292c13 724 @param Xhc The XHCI Instance.\r
92870c98 725 @param Timeout Time to wait before abort (in millisecond, ms).\r
726\r
727 @return EFI_SUCCESS The XHCI host controller is running.\r
728 @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout.\r
729\r
730**/\r
731EFI_STATUS\r
732XhcRunHC (\r
a9292c13 733 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 734 IN UINT32 Timeout\r
735 )\r
736{\r
737 EFI_STATUS Status;\r
738\r
739 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
740 Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, FALSE, Timeout);\r
741 return Status;\r
742}\r
743\r