3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
33 ReadEhcOperationalReg (
39 Value
= Value
& (~USBCMD_RS
);
40 WriteEhcOperationalReg (
49 ReadEhcOperationalReg (
54 if ((Value
& USBSTS_HCH
) != 0) {
60 DEBUG((gEHCErrorLevel
, "TimeOut for clearing Run/Stop bit\n"));
63 ReadEhcOperationalReg (
68 Value
= Value
| USBCMD_HCRESET
;
69 WriteEhcOperationalReg (
78 ReadEhcOperationalReg (
83 if ((Value
& USBCMD_HCRESET
) == 0) {
89 DEBUG((gEHCErrorLevel
, "TimeOut for Host Reset\n"));
95 ReadEhcCapabiltiyReg (
96 IN USB2_HC_DEV
*HcDev
,
97 IN UINT32 CapabiltiyRegAddr
,
104 Read Ehc Capabitlity register
109 CapabiltiyRegAddr - Ehc Capability register address
110 Data - A pointer to data read from register
115 EFI_DEVICE_ERROR Fail
119 return HcDev
->PciIo
->Mem
.Read (
123 (UINT64
) CapabiltiyRegAddr
,
130 ReadEhcOperationalReg (
131 IN USB2_HC_DEV
*HcDev
,
132 IN UINT32 OperationalRegAddr
,
139 Read Ehc Operation register
144 OperationalRegAddr - Ehc Operation register address
145 Data - A pointer to data read from register
150 EFI_DEVICE_ERROR Fail
154 ASSERT (HcDev
->UsbCapabilityLen
);
155 return HcDev
->PciIo
->Mem
.Read (
159 (UINT64
) (OperationalRegAddr
+ HcDev
->UsbCapabilityLen
),
166 WriteEhcOperationalReg (
167 IN USB2_HC_DEV
*HcDev
,
168 IN UINT32 OperationalRegAddr
,
175 Write Ehc Operation register
180 OperationalRegAddr - Ehc Operation register address
181 Data - 32bit write to register
186 EFI_DEVICE_ERROR Fail
190 ASSERT (HcDev
->UsbCapabilityLen
);
191 return HcDev
->PciIo
->Mem
.Write (
195 (UINT64
) (OperationalRegAddr
+ HcDev
->UsbCapabilityLen
),
203 IN USB2_HC_DEV
*HcDev
209 Stop the legacy USB SMI
218 EFI_DEVICE_ERROR Fail
226 ReadEhcCapabiltiyReg (
232 EECP
= (EECP
>> 8) & 0xFF;
234 DEBUG ((gEHCDebugLevel
, "EHCI: EECPBase = 0x%x\n", EECP
));
237 HcDev
->PciIo
->Pci
.Read (
245 DEBUG((gEHCDebugLevel
, "EECP[0] = 0x%x\n", Value
));
247 HcDev
->PciIo
->Pci
.Read (
255 DEBUG((gEHCDebugLevel
, "EECP[4] = 0x%x\n", Value
));
257 HcDev
->PciIo
->Pci
.Read (
265 Value
= Value
| (0x1 << 24);
266 DEBUG((gEHCErrorLevel
, "Value Written = 0x%x\n", Value
));
268 HcDev
->PciIo
->Pci
.Write (
280 HcDev
->PciIo
->Pci
.Read (
287 if ((Value
& 0x01010000) == 0x01000000) {
293 DEBUG((gEHCErrorLevel
, "Timeout for getting HC OS Owned Semaphore\n" ));
296 DEBUG((gEHCErrorLevel
, "After Release Value\n" ));
298 HcDev
->PciIo
->Pci
.Read (
306 DEBUG((gEHCDebugLevel
, "EECP[0] = 0x%x\n", Value
));
308 HcDev
->PciIo
->Pci
.Read (
316 DEBUG((gEHCDebugLevel
, "EECP[4] = 0x%x\n", Value
));
323 IN USB2_HC_DEV
*HcDev
329 Get the length of capability register
338 EFI_DEVICE_ERROR Fail
343 UINT32 CapabilityLenAddr
;
345 CapabilityLenAddr
= CAPLENGTH
;
347 Status
= ReadEhcCapabiltiyReg (
350 &(HcDev
->UsbCapabilityLen
)
352 HcDev
->UsbCapabilityLen
= (UINT8
) HcDev
->UsbCapabilityLen
;
359 IN USB2_HC_DEV
*HcDev
,
366 Set the length of Frame List
371 Length - the required length of frame list
376 EFI_INVALID_PARAMETER Invalid parameter
377 EFI_DEVICE_ERROR Fail
382 UINT32 UsbCommandAddr
;
383 UINT32 UsbCommandReg
;
385 UsbCommandAddr
= USBCMD
;
387 if (256 != Length
&& 512 != Length
) {
388 Status
= EFI_INVALID_PARAMETER
;
392 Status
= ReadEhcOperationalReg (
397 if (EFI_ERROR (Status
)) {
398 Status
= EFI_DEVICE_ERROR
;
403 UsbCommandReg
|= USBCMD_FLS_256
;
405 UsbCommandReg
|= USBCMD_FLS_512
;
408 Status
= WriteEhcOperationalReg (
413 if (EFI_ERROR (Status
)) {
414 Status
= EFI_DEVICE_ERROR
;
422 SetFrameListBaseAddr (
423 IN USB2_HC_DEV
*HcDev
,
424 IN UINT32 FrameBuffer
430 Set base address of frame list first entry
435 FrameBuffer - base address of first entry of frame list
442 UINT32 PeriodicListBaseAddr
;
443 UINT32 PeriodicListBaseReg
;
445 Status
= EFI_SUCCESS
;
446 PeriodicListBaseAddr
= PERIODICLISTBASE
;
447 PeriodicListBaseReg
= FrameBuffer
& 0xfffff000;
449 if (IsEhcHalted (HcDev
)) {
451 Status
= WriteEhcOperationalReg (
453 PeriodicListBaseAddr
,
456 if (EFI_ERROR (Status
)) {
457 Status
= EFI_DEVICE_ERROR
;
469 IN USB2_HC_DEV
*HcDev
,
470 IN EHCI_QH_ENTITY
*QhPtr
476 Set address of first Async schedule Qh
481 QhPtr - A pointer to first Qh in the Async schedule
486 EFI_DEVICE_ERROR Fail
491 UINT32 AsyncListAddr
;
494 AsyncListAddr
= ASYNCLISTADDR
;
495 AsyncListReg
= (UINT32
) GET_0B_TO_31B (&(QhPtr
->Qh
));
497 Status
= WriteEhcOperationalReg (
507 SetCtrlDataStructSeg (
508 IN USB2_HC_DEV
*HcDev
514 Set register of control and data structure segment
523 EFI_DEVICE_ERROR Fail
529 UINT32 CtrlDsSegmentAddr
;
530 UINT32 CtrlDsSegmentReg
;
532 CtrlDsSegmentAddr
= CTRLDSSGMENT
;
533 CtrlDsSegmentReg
= HcDev
->High32BitAddr
;
535 Status
= WriteEhcOperationalReg (
546 IN USB2_HC_DEV
*HcDev
552 Set Ehc port routing bit
561 EFI_DEVICE_ERROR Fail
566 UINT32 ConfigFlagAddr
;
567 UINT32 ConfigFlagReg
;
569 ConfigFlagAddr
= CONFIGFLAG
;
571 Status
= ReadEhcOperationalReg (
576 if (EFI_ERROR (Status
)) {
577 Status
= EFI_DEVICE_ERROR
;
581 ConfigFlagReg
|= CONFIGFLAG_CF
;
582 Status
= WriteEhcOperationalReg (
587 if (EFI_ERROR (Status
)) {
588 Status
= EFI_DEVICE_ERROR
;
597 IN USB2_HC_DEV
*HcDev
603 Set Ehc door bell bit
612 EFI_DEVICE_ERROR Fail
617 UINT32 UsbCommandAddr
;
618 UINT32 UsbCommandReg
;
620 UsbCommandAddr
= USBCMD
;
622 Status
= ReadEhcOperationalReg (
627 if (EFI_ERROR (Status
)) {
628 Status
= EFI_DEVICE_ERROR
;
632 UsbCommandReg
|= USBCMD_IAAD
;
633 Status
= WriteEhcOperationalReg (
638 if (EFI_ERROR (Status
)) {
639 Status
= EFI_DEVICE_ERROR
;
648 IN USB2_HC_DEV
*HcDev
654 Clear Ehc all status bits
663 EFI_DEVICE_ERROR Fail
667 UINT32 UsbStatusAddr
;
669 UsbStatusAddr
= USBSTS
;
671 return WriteEhcOperationalReg (
679 EnablePeriodicSchedule (
680 IN USB2_HC_DEV
*HcDev
686 Enable periodic schedule
695 EFI_DEVICE_ERROR Fail
700 UINT32 UsbCommandAddr
;
701 UINT32 UsbCommandReg
;
703 UsbCommandAddr
= USBCMD
;
705 Status
= ReadEhcOperationalReg (
710 if (EFI_ERROR (Status
)) {
711 Status
= EFI_DEVICE_ERROR
;
715 UsbCommandReg
|= USBCMD_PSE
;
716 Status
= WriteEhcOperationalReg (
721 if (EFI_ERROR (Status
)) {
722 Status
= EFI_DEVICE_ERROR
;
730 DisablePeriodicSchedule (
731 IN USB2_HC_DEV
*HcDev
737 Disable periodic schedule
746 EFI_DEVICE_ERROR Fail
751 UINT32 UsbCommandAddr
;
752 UINT32 UsbCommandReg
;
754 UsbCommandAddr
= USBCMD
;
756 Status
= ReadEhcOperationalReg (
761 if (EFI_ERROR (Status
)) {
762 return EFI_DEVICE_ERROR
;
765 UsbCommandReg
&= ~USBCMD_PSE
;
766 Status
= WriteEhcOperationalReg (
771 if (EFI_ERROR (Status
)) {
772 return EFI_DEVICE_ERROR
;
779 EnableAsynchronousSchedule (
780 IN USB2_HC_DEV
*HcDev
786 Enable asynchrounous schedule
795 EFI_DEVICE_ERROR Fail
800 UINT32 UsbCommandAddr
;
801 UINT32 UsbCommandReg
;
803 UsbCommandAddr
= USBCMD
;
805 Status
= ReadEhcOperationalReg (
810 if (EFI_ERROR (Status
)) {
811 Status
= EFI_DEVICE_ERROR
;
815 UsbCommandReg
|= USBCMD_ASE
;
816 Status
= WriteEhcOperationalReg (
821 if (EFI_ERROR (Status
)) {
822 Status
= EFI_DEVICE_ERROR
;
830 DisableAsynchronousSchedule (
831 IN USB2_HC_DEV
*HcDev
837 Disable asynchrounous schedule
846 EFI_DEVICE_ERROR Fail
851 UINT32 UsbCommandAddr
;
852 UINT32 UsbCommandReg
;
854 UsbCommandAddr
= USBCMD
;
856 Status
= ReadEhcOperationalReg (
861 if (EFI_ERROR (Status
)) {
862 return EFI_DEVICE_ERROR
;
865 UsbCommandReg
&= ~USBCMD_ASE
;
866 Status
= WriteEhcOperationalReg (
871 if (EFI_ERROR (Status
)) {
872 return EFI_DEVICE_ERROR
;
880 IN USB2_HC_DEV
*HcDev
895 EFI_DEVICE_ERROR Fail
900 UINT32 UsbCommandAddr
;
901 UINT32 UsbCommandReg
;
903 UsbCommandAddr
= USBCMD
;
905 Status
= ReadEhcOperationalReg (
910 if (EFI_ERROR (Status
)) {
911 Status
= EFI_DEVICE_ERROR
;
915 UsbCommandReg
|= USBCMD_HCRESET
;
916 Status
= WriteEhcOperationalReg (
921 if (EFI_ERROR (Status
)) {
922 Status
= EFI_DEVICE_ERROR
;
930 StartScheduleExecution (
931 IN USB2_HC_DEV
*HcDev
937 Start Ehc schedule execution
946 EFI_DEVICE_ERROR Fail
951 UINT32 UsbCommandAddr
;
952 UINT32 UsbCommandReg
;
954 UsbCommandAddr
= USBCMD
;
956 Status
= ReadEhcOperationalReg (
961 if (EFI_ERROR (Status
)) {
962 Status
= EFI_DEVICE_ERROR
;
966 UsbCommandReg
|= USBCMD_RS
;
967 Status
= WriteEhcOperationalReg (
972 if (EFI_ERROR (Status
)) {
973 Status
= EFI_DEVICE_ERROR
;
981 IsFrameListProgrammable (
982 IN USB2_HC_DEV
*HcDev
988 Whether frame list is programmable
1002 UINT32 HcCapParamsAddr
;
1003 UINT32 HcCapParamsReg
;
1005 HcCapParamsAddr
= HCCPARAMS
;
1007 ReadEhcCapabiltiyReg(
1013 if (HcCapParamsReg
& HCCP_PFLF
) {
1023 IsPeriodicScheduleEnabled (
1024 IN USB2_HC_DEV
*HcDev
1028 Routine Description:
1030 Whether periodic schedule is enabled
1044 UINT32 UsbStatusAddr
;
1045 UINT32 UsbStatusReg
;
1047 UsbStatusAddr
= USBSTS
;
1049 ReadEhcOperationalReg (
1055 if (UsbStatusReg
& USBSTS_PSS
) {
1065 IsAsyncScheduleEnabled (
1066 IN USB2_HC_DEV
*HcDev
1070 Routine Description:
1072 Whether asynchronous schedule is enabled
1086 UINT32 UsbStatusAddr
;
1087 UINT32 UsbStatusReg
;
1089 UsbStatusAddr
= USBSTS
;
1091 ReadEhcOperationalReg (
1097 if (UsbStatusReg
& USBSTS_ASS
) {
1108 IN USB2_HC_DEV
*HcDev
,
1113 Routine Description:
1115 Whether port is enabled
1128 UINT32 PortStatusControlAddr
;
1129 UINT32 PortStatusControlReg
;
1131 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNum
));
1133 ReadEhcOperationalReg (
1135 PortStatusControlAddr
,
1136 &PortStatusControlReg
1139 return ((BOOLEAN
) ((PortStatusControlReg
& PORTSC_PED
) ? TRUE
: FALSE
));
1144 IN USB2_HC_DEV
*HcDev
1148 Routine Description:
1150 Whether Ehc is reseted
1164 UINT32 UsbCommandAddr
;
1165 UINT32 UsbCommandReg
;
1167 UsbCommandAddr
= USBCMD
;
1169 ReadEhcOperationalReg (
1175 if (UsbCommandReg
& USBCMD_HCRESET
) {
1186 IN USB2_HC_DEV
*HcDev
1190 Routine Description:
1192 Whether Ehc is halted
1206 UINT32 UsbStatusAddr
;
1207 UINT32 UsbStatusReg
;
1209 UsbStatusAddr
= USBSTS
;
1211 ReadEhcOperationalReg (
1217 if (UsbStatusReg
& USBSTS_HCH
) {
1228 IN USB2_HC_DEV
*HcDev
1232 Routine Description:
1234 Whether Ehc is system error
1243 FALSE No system error
1248 UINT32 UsbStatusAddr
;
1249 UINT32 UsbStatusReg
;
1251 UsbStatusAddr
= USBSTS
;
1253 ReadEhcOperationalReg (
1259 if (UsbStatusReg
& USBSTS_HSE
) {
1270 IN EFI_USB2_HC_PROTOCOL
*This
,
1275 Routine Description:
1277 Whether high speed device attached
1291 UINT32 PortStatusControlAddr
;
1292 UINT32 PortStatusControlReg
;
1294 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1295 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNum
));
1298 // Set port reset bit
1300 ReadEhcOperationalReg (
1302 PortStatusControlAddr
,
1303 &PortStatusControlReg
1306 // Make sure Host Controller not halt before reset it
1308 if (IsEhcHalted (HcDev
)) {
1309 StartScheduleExecution (HcDev
);
1310 WaitForEhcNotHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1312 PortStatusControlReg
&= 0xffffffd5;
1313 PortStatusControlReg
|= PORTSC_PR
;
1315 // Set one to PortReset bit must also set zero to PortEnable bit
1317 PortStatusControlReg
&= ~PORTSC_PED
;
1318 WriteEhcOperationalReg (
1320 PortStatusControlAddr
,
1321 PortStatusControlReg
1325 // Set Port reset recovery time
1327 gBS
->Stall (EHCI_SET_PORT_RESET_RECOVERY_TIME
);
1330 // Clear port reset bit
1332 ReadEhcOperationalReg (
1334 PortStatusControlAddr
,
1335 &PortStatusControlReg
1337 PortStatusControlReg
&= 0xffffffd5;
1338 PortStatusControlReg
&= ~PORTSC_PR
;
1339 WriteEhcOperationalReg (
1341 PortStatusControlAddr
,
1342 PortStatusControlReg
1346 // Clear port reset recovery time
1348 gBS
->Stall (EHCI_CLEAR_PORT_RESET_RECOVERY_TIME
);
1350 return ((BOOLEAN
) (IsEhcPortEnabled (HcDev
, PortNum
) ? TRUE
: FALSE
));
1355 IN USB2_HC_DEV
*HcDev
,
1360 Routine Description:
1362 wait for Ehc reset or timeout
1367 Timeout - timeout threshold
1380 // Timeout is in US unit
1382 Delay
= (Timeout
/ 50) + 1;
1385 if (IsEhcReseted (HcDev
)) {
1386 Status
= EFI_SUCCESS
;
1389 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1393 Status
= EFI_TIMEOUT
;
1401 IN USB2_HC_DEV
*HcDev
,
1406 Routine Description:
1408 wait for Ehc halt or timeout
1413 Timeout - timeout threshold
1426 // Timeout is in US unit
1428 Delay
= (Timeout
/ 50) + 1;
1431 if (IsEhcHalted (HcDev
)) {
1432 Status
= EFI_SUCCESS
;
1435 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1439 Status
= EFI_TIMEOUT
;
1447 IN USB2_HC_DEV
*HcDev
,
1452 Routine Description:
1454 wait for Ehc not halt or timeout
1459 Timeout - timeout threshold
1472 // Timeout is in US unit
1474 Delay
= (Timeout
/ 50) + 1;
1477 if (!IsEhcHalted (HcDev
)) {
1478 Status
= EFI_SUCCESS
;
1481 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1485 Status
= EFI_TIMEOUT
;
1492 WaitForAsyncScheduleEnable (
1493 IN USB2_HC_DEV
*HcDev
,
1498 Routine Description:
1500 Wait for Ehc asynchronous schedule enable or timeout
1505 Timeout - timeout threshold
1518 // Timeout is in US unit
1520 Delay
= (Timeout
/ 50) + 1;
1523 if (IsAsyncScheduleEnabled (HcDev
)) {
1524 Status
= EFI_SUCCESS
;
1527 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1531 Status
= EFI_TIMEOUT
;
1538 WaitForAsyncScheduleDisable (
1539 IN USB2_HC_DEV
*HcDev
,
1544 Routine Description:
1546 Wait for Ehc asynchronous schedule disable or timeout
1551 Timeout - timeout threshold
1564 // Timeout is in US unit
1566 Delay
= (Timeout
/ 50) + 1;
1569 if (!IsAsyncScheduleEnabled (HcDev
)) {
1570 Status
= EFI_SUCCESS
;
1573 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1577 Status
= EFI_TIMEOUT
;
1584 WaitForPeriodicScheduleEnable (
1585 IN USB2_HC_DEV
*HcDev
,
1590 Routine Description:
1592 Wait for Ehc periodic schedule enable or timeout
1597 Timeout - timeout threshold
1610 // Timeout is in US unit
1612 Delay
= (Timeout
/ 50) + 1;
1615 if (IsPeriodicScheduleEnabled (HcDev
)) {
1616 Status
= EFI_SUCCESS
;
1619 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1623 Status
= EFI_TIMEOUT
;
1630 WaitForPeriodicScheduleDisable (
1631 IN USB2_HC_DEV
*HcDev
,
1636 Routine Description:
1638 Wait for periodic schedule disable or timeout
1643 Timeout - timeout threshold
1656 // Timeout is in US unit
1658 Delay
= (Timeout
/ 50) + 1;
1661 if (!IsPeriodicScheduleEnabled (HcDev
)) {
1662 Status
= EFI_SUCCESS
;
1665 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1669 Status
= EFI_TIMEOUT
;
1676 WaitForEhcDoorbell (
1677 IN USB2_HC_DEV
*HcDev
,
1682 Routine Description:
1684 Wait for periodic schedule disable or timeout
1689 Timeout - timeout threshold
1699 UINT32 UsbCommandAddr
;
1700 UINT32 UsbCommandReg
;
1703 UsbCommandAddr
= USBCMD
;
1704 Delay
= (Timeout
/ 50) + 1;
1707 Status
= ReadEhcOperationalReg (
1712 if (EFI_ERROR (Status
)) {
1713 Status
= EFI_DEVICE_ERROR
;
1716 if (!(UsbCommandReg
& USBCMD_IAAD
)) {
1723 Status
= EFI_TIMEOUT
;