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
),
205 IN USB2_HC_DEV
*HcDev
211 Stop the legacy USB SMI
220 EFI_DEVICE_ERROR Fail
228 ReadEhcCapabiltiyReg (
234 EECP
= (EECP
>> 8) & 0xFF;
236 DEBUG ((gEHCDebugLevel
, "EHCI: EECPBase = 0x%x\n", EECP
));
239 HcDev
->PciIo
->Pci
.Read (
247 DEBUG((gEHCDebugLevel
, "EECP[0] = 0x%x\n", Value
));
249 HcDev
->PciIo
->Pci
.Read (
257 DEBUG((gEHCDebugLevel
, "EECP[4] = 0x%x\n", Value
));
259 HcDev
->PciIo
->Pci
.Read (
267 Value
= Value
| (0x1 << 24);
268 DEBUG((gEHCErrorLevel
, "Value Written = 0x%x\n", Value
));
270 HcDev
->PciIo
->Pci
.Write (
282 HcDev
->PciIo
->Pci
.Read (
289 if ((Value
& 0x01010000) == 0x01000000) {
295 DEBUG((gEHCErrorLevel
, "Timeout for getting HC OS Owned Semaphore\n" ));
298 DEBUG((gEHCErrorLevel
, "After Release Value\n" ));
300 HcDev
->PciIo
->Pci
.Read (
308 DEBUG((gEHCDebugLevel
, "EECP[0] = 0x%x\n", Value
));
310 HcDev
->PciIo
->Pci
.Read (
318 DEBUG((gEHCDebugLevel
, "EECP[4] = 0x%x\n", Value
));
325 IN USB2_HC_DEV
*HcDev
331 Get the length of capability register
340 EFI_DEVICE_ERROR Fail
345 UINT32 CapabilityLenAddr
;
347 CapabilityLenAddr
= CAPLENGTH
;
349 Status
= ReadEhcCapabiltiyReg (
352 &(HcDev
->UsbCapabilityLen
)
354 HcDev
->UsbCapabilityLen
= (UINT8
) HcDev
->UsbCapabilityLen
;
361 IN USB2_HC_DEV
*HcDev
,
368 Set the length of Frame List
373 Length - the required length of frame list
378 EFI_INVALID_PARAMETER Invalid parameter
379 EFI_DEVICE_ERROR Fail
384 UINT32 UsbCommandAddr
;
385 UINT32 UsbCommandReg
;
387 UsbCommandAddr
= USBCMD
;
389 if (256 != Length
&& 512 != Length
) {
390 Status
= EFI_INVALID_PARAMETER
;
394 Status
= ReadEhcOperationalReg (
399 if (EFI_ERROR (Status
)) {
400 Status
= EFI_DEVICE_ERROR
;
405 UsbCommandReg
|= USBCMD_FLS_256
;
407 UsbCommandReg
|= USBCMD_FLS_512
;
410 Status
= WriteEhcOperationalReg (
415 if (EFI_ERROR (Status
)) {
416 Status
= EFI_DEVICE_ERROR
;
424 SetFrameListBaseAddr (
425 IN USB2_HC_DEV
*HcDev
,
426 IN UINT32 FrameBuffer
432 Set base address of frame list first entry
437 FrameBuffer - base address of first entry of frame list
444 UINT32 PeriodicListBaseAddr
;
445 UINT32 PeriodicListBaseReg
;
447 Status
= EFI_SUCCESS
;
448 PeriodicListBaseAddr
= PERIODICLISTBASE
;
449 PeriodicListBaseReg
= FrameBuffer
& 0xfffff000;
451 if (IsEhcHalted (HcDev
)) {
453 Status
= WriteEhcOperationalReg (
455 PeriodicListBaseAddr
,
458 if (EFI_ERROR (Status
)) {
459 Status
= EFI_DEVICE_ERROR
;
471 IN USB2_HC_DEV
*HcDev
,
472 IN EHCI_QH_ENTITY
*QhPtr
478 Set address of first Async schedule Qh
483 QhPtr - A pointer to first Qh in the Async schedule
488 EFI_DEVICE_ERROR Fail
493 UINT32 AsyncListAddr
;
496 AsyncListAddr
= ASYNCLISTADDR
;
497 AsyncListReg
= (UINT32
) GET_0B_TO_31B (&(QhPtr
->Qh
));
499 Status
= WriteEhcOperationalReg (
509 SetCtrlDataStructSeg (
510 IN USB2_HC_DEV
*HcDev
516 Set register of control and data structure segment
525 EFI_DEVICE_ERROR Fail
531 UINT32 CtrlDsSegmentAddr
;
532 UINT32 CtrlDsSegmentReg
;
534 CtrlDsSegmentAddr
= CTRLDSSGMENT
;
535 CtrlDsSegmentReg
= HcDev
->High32BitAddr
;
537 Status
= WriteEhcOperationalReg (
548 IN USB2_HC_DEV
*HcDev
554 Set Ehc port routing bit
563 EFI_DEVICE_ERROR Fail
568 UINT32 ConfigFlagAddr
;
569 UINT32 ConfigFlagReg
;
571 ConfigFlagAddr
= CONFIGFLAG
;
573 Status
= ReadEhcOperationalReg (
578 if (EFI_ERROR (Status
)) {
579 Status
= EFI_DEVICE_ERROR
;
583 ConfigFlagReg
|= CONFIGFLAG_CF
;
584 Status
= WriteEhcOperationalReg (
589 if (EFI_ERROR (Status
)) {
590 Status
= EFI_DEVICE_ERROR
;
599 IN USB2_HC_DEV
*HcDev
605 Set Ehc door bell bit
614 EFI_DEVICE_ERROR Fail
619 UINT32 UsbCommandAddr
;
620 UINT32 UsbCommandReg
;
622 UsbCommandAddr
= USBCMD
;
624 Status
= ReadEhcOperationalReg (
629 if (EFI_ERROR (Status
)) {
630 Status
= EFI_DEVICE_ERROR
;
634 UsbCommandReg
|= USBCMD_IAAD
;
635 Status
= WriteEhcOperationalReg (
640 if (EFI_ERROR (Status
)) {
641 Status
= EFI_DEVICE_ERROR
;
650 IN USB2_HC_DEV
*HcDev
656 Clear Ehc all status bits
665 EFI_DEVICE_ERROR Fail
669 UINT32 UsbStatusAddr
;
671 UsbStatusAddr
= USBSTS
;
673 return WriteEhcOperationalReg (
681 EnablePeriodicSchedule (
682 IN USB2_HC_DEV
*HcDev
688 Enable periodic schedule
697 EFI_DEVICE_ERROR Fail
702 UINT32 UsbCommandAddr
;
703 UINT32 UsbCommandReg
;
705 UsbCommandAddr
= USBCMD
;
707 Status
= ReadEhcOperationalReg (
712 if (EFI_ERROR (Status
)) {
713 Status
= EFI_DEVICE_ERROR
;
717 UsbCommandReg
|= USBCMD_PSE
;
718 Status
= WriteEhcOperationalReg (
723 if (EFI_ERROR (Status
)) {
724 Status
= EFI_DEVICE_ERROR
;
732 DisablePeriodicSchedule (
733 IN USB2_HC_DEV
*HcDev
739 Disable periodic schedule
748 EFI_DEVICE_ERROR Fail
753 UINT32 UsbCommandAddr
;
754 UINT32 UsbCommandReg
;
756 UsbCommandAddr
= USBCMD
;
758 Status
= ReadEhcOperationalReg (
763 if (EFI_ERROR (Status
)) {
764 return EFI_DEVICE_ERROR
;
767 UsbCommandReg
&= ~USBCMD_PSE
;
768 Status
= WriteEhcOperationalReg (
773 if (EFI_ERROR (Status
)) {
774 return EFI_DEVICE_ERROR
;
781 EnableAsynchronousSchedule (
782 IN USB2_HC_DEV
*HcDev
788 Enable asynchrounous schedule
797 EFI_DEVICE_ERROR Fail
802 UINT32 UsbCommandAddr
;
803 UINT32 UsbCommandReg
;
805 UsbCommandAddr
= USBCMD
;
807 Status
= ReadEhcOperationalReg (
812 if (EFI_ERROR (Status
)) {
813 Status
= EFI_DEVICE_ERROR
;
817 UsbCommandReg
|= USBCMD_ASE
;
818 Status
= WriteEhcOperationalReg (
823 if (EFI_ERROR (Status
)) {
824 Status
= EFI_DEVICE_ERROR
;
832 DisableAsynchronousSchedule (
833 IN USB2_HC_DEV
*HcDev
839 Disable asynchrounous schedule
848 EFI_DEVICE_ERROR Fail
853 UINT32 UsbCommandAddr
;
854 UINT32 UsbCommandReg
;
856 UsbCommandAddr
= USBCMD
;
858 Status
= ReadEhcOperationalReg (
863 if (EFI_ERROR (Status
)) {
864 return EFI_DEVICE_ERROR
;
867 UsbCommandReg
&= ~USBCMD_ASE
;
868 Status
= WriteEhcOperationalReg (
873 if (EFI_ERROR (Status
)) {
874 return EFI_DEVICE_ERROR
;
882 IN USB2_HC_DEV
*HcDev
897 EFI_DEVICE_ERROR Fail
902 UINT32 UsbCommandAddr
;
903 UINT32 UsbCommandReg
;
905 UsbCommandAddr
= USBCMD
;
907 Status
= ReadEhcOperationalReg (
912 if (EFI_ERROR (Status
)) {
913 Status
= EFI_DEVICE_ERROR
;
917 UsbCommandReg
|= USBCMD_HCRESET
;
918 Status
= WriteEhcOperationalReg (
923 if (EFI_ERROR (Status
)) {
924 Status
= EFI_DEVICE_ERROR
;
932 StartScheduleExecution (
933 IN USB2_HC_DEV
*HcDev
939 Start Ehc schedule execution
948 EFI_DEVICE_ERROR Fail
953 UINT32 UsbCommandAddr
;
954 UINT32 UsbCommandReg
;
956 UsbCommandAddr
= USBCMD
;
958 Status
= ReadEhcOperationalReg (
963 if (EFI_ERROR (Status
)) {
964 Status
= EFI_DEVICE_ERROR
;
968 UsbCommandReg
|= USBCMD_RS
;
969 Status
= WriteEhcOperationalReg (
974 if (EFI_ERROR (Status
)) {
975 Status
= EFI_DEVICE_ERROR
;
983 IsFrameListProgrammable (
984 IN USB2_HC_DEV
*HcDev
990 Whether frame list is programmable
1004 UINT32 HcCapParamsAddr
;
1005 UINT32 HcCapParamsReg
;
1007 HcCapParamsAddr
= HCCPARAMS
;
1009 ReadEhcCapabiltiyReg(
1015 if (HcCapParamsReg
& HCCP_PFLF
) {
1025 IsPeriodicScheduleEnabled (
1026 IN USB2_HC_DEV
*HcDev
1030 Routine Description:
1032 Whether periodic schedule is enabled
1046 UINT32 UsbStatusAddr
;
1047 UINT32 UsbStatusReg
;
1049 UsbStatusAddr
= USBSTS
;
1051 ReadEhcOperationalReg (
1057 if (UsbStatusReg
& USBSTS_PSS
) {
1067 IsAsyncScheduleEnabled (
1068 IN USB2_HC_DEV
*HcDev
1072 Routine Description:
1074 Whether asynchronous schedule is enabled
1088 UINT32 UsbStatusAddr
;
1089 UINT32 UsbStatusReg
;
1091 UsbStatusAddr
= USBSTS
;
1093 ReadEhcOperationalReg (
1099 if (UsbStatusReg
& USBSTS_ASS
) {
1110 IN USB2_HC_DEV
*HcDev
,
1115 Routine Description:
1117 Whether port is enabled
1130 UINT32 PortStatusControlAddr
;
1131 UINT32 PortStatusControlReg
;
1133 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNum
));
1135 ReadEhcOperationalReg (
1137 PortStatusControlAddr
,
1138 &PortStatusControlReg
1141 return ((BOOLEAN
) ((PortStatusControlReg
& PORTSC_PED
) ? TRUE
: FALSE
));
1146 IN USB2_HC_DEV
*HcDev
1150 Routine Description:
1152 Whether Ehc is reseted
1166 UINT32 UsbCommandAddr
;
1167 UINT32 UsbCommandReg
;
1169 UsbCommandAddr
= USBCMD
;
1171 ReadEhcOperationalReg (
1177 if (UsbCommandReg
& USBCMD_HCRESET
) {
1188 IN USB2_HC_DEV
*HcDev
1192 Routine Description:
1194 Whether Ehc is halted
1208 UINT32 UsbStatusAddr
;
1209 UINT32 UsbStatusReg
;
1211 UsbStatusAddr
= USBSTS
;
1213 ReadEhcOperationalReg (
1219 if (UsbStatusReg
& USBSTS_HCH
) {
1230 IN USB2_HC_DEV
*HcDev
1234 Routine Description:
1236 Whether Ehc is system error
1245 FALSE No system error
1250 UINT32 UsbStatusAddr
;
1251 UINT32 UsbStatusReg
;
1253 UsbStatusAddr
= USBSTS
;
1255 ReadEhcOperationalReg (
1261 if (UsbStatusReg
& USBSTS_HSE
) {
1272 IN EFI_USB2_HC_PROTOCOL
*This
,
1277 Routine Description:
1279 Whether high speed device attached
1293 UINT32 PortStatusControlAddr
;
1294 UINT32 PortStatusControlReg
;
1296 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1297 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNum
));
1300 // Set port reset bit
1302 ReadEhcOperationalReg (
1304 PortStatusControlAddr
,
1305 &PortStatusControlReg
1308 // Make sure Host Controller not halt before reset it
1310 if (IsEhcHalted (HcDev
)) {
1311 StartScheduleExecution (HcDev
);
1312 WaitForEhcNotHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1314 PortStatusControlReg
&= 0xffffffd5;
1315 PortStatusControlReg
|= PORTSC_PR
;
1317 // Set one to PortReset bit must also set zero to PortEnable bit
1319 PortStatusControlReg
&= ~PORTSC_PED
;
1320 WriteEhcOperationalReg (
1322 PortStatusControlAddr
,
1323 PortStatusControlReg
1327 // Set Port reset recovery time
1329 gBS
->Stall (EHCI_SET_PORT_RESET_RECOVERY_TIME
);
1332 // Clear port reset bit
1334 ReadEhcOperationalReg (
1336 PortStatusControlAddr
,
1337 &PortStatusControlReg
1339 PortStatusControlReg
&= 0xffffffd5;
1340 PortStatusControlReg
&= ~PORTSC_PR
;
1341 WriteEhcOperationalReg (
1343 PortStatusControlAddr
,
1344 PortStatusControlReg
1348 // Clear port reset recovery time
1350 gBS
->Stall (EHCI_CLEAR_PORT_RESET_RECOVERY_TIME
);
1352 return ((BOOLEAN
) (IsEhcPortEnabled (HcDev
, PortNum
) ? TRUE
: FALSE
));
1357 IN USB2_HC_DEV
*HcDev
,
1362 Routine Description:
1364 wait for Ehc reset or timeout
1369 Timeout - timeout threshold
1382 // Timeout is in US unit
1384 Delay
= (Timeout
/ 50) + 1;
1387 if (IsEhcReseted (HcDev
)) {
1388 Status
= EFI_SUCCESS
;
1391 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1395 Status
= EFI_TIMEOUT
;
1403 IN USB2_HC_DEV
*HcDev
,
1408 Routine Description:
1410 wait for Ehc halt or timeout
1415 Timeout - timeout threshold
1428 // Timeout is in US unit
1430 Delay
= (Timeout
/ 50) + 1;
1433 if (IsEhcHalted (HcDev
)) {
1434 Status
= EFI_SUCCESS
;
1437 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1441 Status
= EFI_TIMEOUT
;
1449 IN USB2_HC_DEV
*HcDev
,
1454 Routine Description:
1456 wait for Ehc not halt or timeout
1461 Timeout - timeout threshold
1474 // Timeout is in US unit
1476 Delay
= (Timeout
/ 50) + 1;
1479 if (!IsEhcHalted (HcDev
)) {
1480 Status
= EFI_SUCCESS
;
1483 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1487 Status
= EFI_TIMEOUT
;
1494 WaitForAsyncScheduleEnable (
1495 IN USB2_HC_DEV
*HcDev
,
1500 Routine Description:
1502 Wait for Ehc asynchronous schedule enable or timeout
1507 Timeout - timeout threshold
1520 // Timeout is in US unit
1522 Delay
= (Timeout
/ 50) + 1;
1525 if (IsAsyncScheduleEnabled (HcDev
)) {
1526 Status
= EFI_SUCCESS
;
1529 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1533 Status
= EFI_TIMEOUT
;
1540 WaitForAsyncScheduleDisable (
1541 IN USB2_HC_DEV
*HcDev
,
1546 Routine Description:
1548 Wait for Ehc asynchronous schedule disable or timeout
1553 Timeout - timeout threshold
1566 // Timeout is in US unit
1568 Delay
= (Timeout
/ 50) + 1;
1571 if (!IsAsyncScheduleEnabled (HcDev
)) {
1572 Status
= EFI_SUCCESS
;
1575 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1579 Status
= EFI_TIMEOUT
;
1586 WaitForPeriodicScheduleEnable (
1587 IN USB2_HC_DEV
*HcDev
,
1592 Routine Description:
1594 Wait for Ehc periodic schedule enable or timeout
1599 Timeout - timeout threshold
1612 // Timeout is in US unit
1614 Delay
= (Timeout
/ 50) + 1;
1617 if (IsPeriodicScheduleEnabled (HcDev
)) {
1618 Status
= EFI_SUCCESS
;
1621 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1625 Status
= EFI_TIMEOUT
;
1632 WaitForPeriodicScheduleDisable (
1633 IN USB2_HC_DEV
*HcDev
,
1638 Routine Description:
1640 Wait for periodic schedule disable or timeout
1645 Timeout - timeout threshold
1658 // Timeout is in US unit
1660 Delay
= (Timeout
/ 50) + 1;
1663 if (!IsPeriodicScheduleEnabled (HcDev
)) {
1664 Status
= EFI_SUCCESS
;
1667 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1671 Status
= EFI_TIMEOUT
;
1678 WaitForEhcDoorbell (
1679 IN USB2_HC_DEV
*HcDev
,
1684 Routine Description:
1686 Wait for periodic schedule disable or timeout
1691 Timeout - timeout threshold
1701 UINT32 UsbCommandAddr
;
1702 UINT32 UsbCommandReg
;
1705 UsbCommandAddr
= USBCMD
;
1706 Delay
= (Timeout
/ 50) + 1;
1709 Status
= ReadEhcOperationalReg (
1714 if (EFI_ERROR (Status
)) {
1715 Status
= EFI_DEVICE_ERROR
;
1718 if (!(UsbCommandReg
& USBCMD_IAAD
)) {
1725 Status
= EFI_TIMEOUT
;