EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c

Go to the documentation of this file.
00001 
00017 #include "Ehci.h"
00018 
00019 
00030 UINT32
00031 EhcReadCapRegister (
00032   IN  USB2_HC_DEV         *Ehc,
00033   IN  UINT32              Offset
00034   )
00035 {
00036   UINT32                  Data;
00037   EFI_STATUS              Status;
00038 
00039   Status = Ehc->PciIo->Mem.Read (
00040                              Ehc->PciIo,
00041                              EfiPciIoWidthUint32,
00042                              EHC_BAR_INDEX,
00043                              (UINT64) Offset,
00044                              1,
00045                              &Data
00046                              );
00047 
00048   if (EFI_ERROR (Status)) {
00049     DEBUG ((EFI_D_ERROR, "EhcReadCapRegister: Pci Io read error - %r at %d\n", Status, Offset));
00050     Data = 0xFFFF;
00051   }
00052 
00053   return Data;
00054 }
00055 
00056 
00067 UINT32
00068 EhcReadOpReg (
00069   IN  USB2_HC_DEV         *Ehc,
00070   IN  UINT32              Offset
00071   )
00072 {
00073   UINT32                  Data;
00074   EFI_STATUS              Status;
00075 
00076   ASSERT (Ehc->CapLen != 0);
00077 
00078   Status = Ehc->PciIo->Mem.Read (
00079                              Ehc->PciIo,
00080                              EfiPciIoWidthUint32,
00081                              EHC_BAR_INDEX,
00082                              (UINT64) (Ehc->CapLen + Offset),
00083                              1,
00084                              &Data
00085                              );
00086 
00087   if (EFI_ERROR (Status)) {
00088     DEBUG ((EFI_D_ERROR, "EhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));
00089     Data = 0xFFFF;
00090   }
00091 
00092   return Data;
00093 }
00094 
00095 
00104 VOID
00105 EhcWriteOpReg (
00106   IN USB2_HC_DEV          *Ehc,
00107   IN UINT32               Offset,
00108   IN UINT32               Data
00109   )
00110 {
00111   EFI_STATUS              Status;
00112 
00113   ASSERT (Ehc->CapLen != 0);
00114 
00115   Status = Ehc->PciIo->Mem.Write (
00116                              Ehc->PciIo,
00117                              EfiPciIoWidthUint32,
00118                              EHC_BAR_INDEX,
00119                              (UINT64) (Ehc->CapLen + Offset),
00120                              1,
00121                              &Data
00122                              );
00123 
00124   if (EFI_ERROR (Status)) {
00125     DEBUG ((EFI_D_ERROR, "EhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));
00126   }
00127 }
00128 
00129 
00138 VOID
00139 EhcSetOpRegBit (
00140   IN USB2_HC_DEV          *Ehc,
00141   IN UINT32               Offset,
00142   IN UINT32               Bit
00143   )
00144 {
00145   UINT32                  Data;
00146 
00147   Data  = EhcReadOpReg (Ehc, Offset);
00148   Data |= Bit;
00149   EhcWriteOpReg (Ehc, Offset, Data);
00150 }
00151 
00152 
00161 VOID
00162 EhcClearOpRegBit (
00163   IN USB2_HC_DEV          *Ehc,
00164   IN UINT32               Offset,
00165   IN UINT32               Bit
00166   )
00167 {
00168   UINT32                  Data;
00169 
00170   Data  = EhcReadOpReg (Ehc, Offset);
00171   Data &= ~Bit;
00172   EhcWriteOpReg (Ehc, Offset, Data);
00173 }
00174 
00175 
00190 EFI_STATUS
00191 EhcWaitOpRegBit (
00192   IN USB2_HC_DEV          *Ehc,
00193   IN UINT32               Offset,
00194   IN UINT32               Bit,
00195   IN BOOLEAN              WaitToSet,
00196   IN UINT32               Timeout
00197   )
00198 {
00199   UINT32                  Index;
00200 
00201   for (Index = 0; Index < Timeout / EHC_SYNC_POLL_INTERVAL + 1; Index++) {
00202     if (EHC_REG_BIT_IS_SET (Ehc, Offset, Bit) == WaitToSet) {
00203       return EFI_SUCCESS;
00204     }
00205 
00206     gBS->Stall (EHC_SYNC_POLL_INTERVAL);
00207   }
00208 
00209   return EFI_TIMEOUT;
00210 }
00211 
00212 
00220 VOID
00221 EhcClearLegacySupport (
00222   IN USB2_HC_DEV          *Ehc
00223   )
00224 {
00225   UINT32                    ExtendCap;
00226   EFI_PCI_IO_PROTOCOL       *PciIo;
00227   UINT32                    Value;
00228   UINT32                    TimeOut;
00229 
00230   DEBUG ((EFI_D_INFO, "EhcClearLegacySupport: called to clear legacy support\n"));
00231 
00232   PciIo     = Ehc->PciIo;
00233   ExtendCap = (Ehc->HcCapParams >> 8) & 0xFF;
00234 
00235   PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);
00236   PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value);
00237 
00238   PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);
00239   Value |= (0x1 << 24);
00240   PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);
00241 
00242   TimeOut = 40;
00243   while (TimeOut-- != 0) {
00244     gBS->Stall (500);
00245 
00246     PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);
00247 
00248     if ((Value & 0x01010000) == 0x01000000) {
00249       break;
00250     }
00251   }
00252 
00253   PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);
00254   PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value);
00255 }
00256 
00257 
00258 
00270 EFI_STATUS
00271 EhcSetAndWaitDoorBell (
00272   IN  USB2_HC_DEV         *Ehc,
00273   IN  UINT32              Timeout
00274   )
00275 {
00276   EFI_STATUS              Status;
00277   UINT32                  Data;
00278 
00279   EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_IAAD);
00280 
00281   Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_IAA, TRUE, Timeout);
00282 
00283   //
00284   // ACK the IAA bit in USBSTS register. Make sure other
00285   // interrupt bits are not ACKed. These bits are WC (Write Clean).
00286   //
00287   Data  = EhcReadOpReg (Ehc, EHC_USBSTS_OFFSET);
00288   Data &= ~USBSTS_INTACK_MASK;
00289   Data |= USBSTS_IAA;
00290 
00291   EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, Data);
00292 
00293   return Status;
00294 }
00295 
00296 
00304 VOID
00305 EhcAckAllInterrupt (
00306   IN  USB2_HC_DEV         *Ehc
00307   )
00308 {
00309   EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, USBSTS_INTACK_MASK);
00310 }
00311 
00312 
00324 EFI_STATUS
00325 EhcEnablePeriodSchd (
00326   IN USB2_HC_DEV          *Ehc,
00327   IN UINT32               Timeout
00328   )
00329 {
00330   EFI_STATUS              Status;
00331 
00332   EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_PERIOD);
00333 
00334   Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_PERIOD_ENABLED, TRUE, Timeout);
00335   return Status;
00336 }
00337 
00338 
00349 EFI_STATUS
00350 EhcDisablePeriodSchd (
00351   IN USB2_HC_DEV          *Ehc,
00352   IN UINT32               Timeout
00353   )
00354 {
00355   EFI_STATUS              Status;
00356 
00357   EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_PERIOD);
00358 
00359   Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_PERIOD_ENABLED, FALSE, Timeout);
00360   return Status;
00361 }
00362 
00363 
00364 
00375 EFI_STATUS
00376 EhcEnableAsyncSchd (
00377   IN USB2_HC_DEV          *Ehc,
00378   IN UINT32               Timeout
00379   )
00380 {
00381   EFI_STATUS              Status;
00382 
00383   EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_ASYNC);
00384 
00385   Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_ASYNC_ENABLED, TRUE, Timeout);
00386   return Status;
00387 }
00388 
00389 
00390 
00401 EFI_STATUS
00402 EhcDisableAsyncSchd (
00403   IN USB2_HC_DEV          *Ehc,
00404   IN UINT32               Timeout
00405   )
00406 {
00407   EFI_STATUS  Status;
00408 
00409   EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_ASYNC);
00410 
00411   Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_ASYNC_ENABLED, FALSE, Timeout);
00412   return Status;
00413 }
00414 
00415 
00416 
00426 BOOLEAN
00427 EhcIsHalt (
00428   IN USB2_HC_DEV          *Ehc
00429   )
00430 {
00431   return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT);
00432 }
00433 
00434 
00444 BOOLEAN
00445 EhcIsSysError (
00446   IN USB2_HC_DEV          *Ehc
00447   )
00448 {
00449   return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR);
00450 }
00451 
00452 
00463 EFI_STATUS
00464 EhcResetHC (
00465   IN USB2_HC_DEV          *Ehc,
00466   IN UINT32               Timeout
00467   )
00468 {
00469   EFI_STATUS              Status;
00470 
00471   //
00472   // Host can only be reset when it is halt. If not so, halt it
00473   //
00474   if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {
00475     Status = EhcHaltHC (Ehc, Timeout);
00476 
00477     if (EFI_ERROR (Status)) {
00478       return Status;
00479     }
00480   }
00481 
00482   EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET);
00483   Status = EhcWaitOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET, FALSE, Timeout);
00484   return Status;
00485 }
00486 
00487 
00498 EFI_STATUS
00499 EhcHaltHC (
00500   IN USB2_HC_DEV         *Ehc,
00501   IN UINT32              Timeout
00502   )
00503 {
00504   EFI_STATUS              Status;
00505 
00506   EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);
00507   Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, TRUE, Timeout);
00508   return Status;
00509 }
00510 
00511 
00522 EFI_STATUS
00523 EhcRunHC (
00524   IN USB2_HC_DEV          *Ehc,
00525   IN UINT32               Timeout
00526   )
00527 {
00528   EFI_STATUS              Status;
00529 
00530   EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);
00531   Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, FALSE, Timeout);
00532   return Status;
00533 }
00534 
00535 
00551 EFI_STATUS
00552 EhcInitHC (
00553   IN USB2_HC_DEV          *Ehc
00554   )
00555 {
00556   EFI_STATUS              Status;
00557 
00558   // This ASSERT crashes the BeagleBoard. There is some issue in the USB stack.
00559   // This ASSERT needs to be removed so the BeagleBoard will boot. When we fix
00560   // the USB stack we can put this ASSERT back in
00561   // ASSERT (EhcIsHalt (Ehc));
00562 
00563   //
00564   // Allocate the periodic frame and associated memeory
00565   // management facilities if not already done.
00566   //
00567   if (Ehc->PeriodFrame != NULL) {
00568     EhcFreeSched (Ehc);
00569   }
00570 
00571   Status = EhcInitSched (Ehc);
00572 
00573   if (EFI_ERROR (Status)) {
00574     return Status;
00575   }
00576 
00577   //
00578   // 1. Clear USBINTR to disable all the interrupt. UEFI works by polling
00579   //
00580   EhcWriteOpReg (Ehc, EHC_USBINTR_OFFSET, 0);
00581 
00582   //
00583   // 2. Program periodic frame list, already done in EhcInitSched
00584   // 3. Start the Host Controller
00585   //
00586   EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);
00587 
00588   //
00589   // 4. Set all ports routing to EHC
00590   //
00591   EhcSetOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);
00592 
00593   //
00594   // Wait roothub port power stable
00595   //
00596   gBS->Stall (EHC_ROOT_PORT_RECOVERY_STALL);
00597 
00598   Status = EhcEnablePeriodSchd (Ehc, EHC_GENERIC_TIMEOUT);
00599 
00600   if (EFI_ERROR (Status)) {
00601     DEBUG ((EFI_D_ERROR, "EhcInitHC: failed to enable period schedule\n"));
00602     return Status;
00603   }
00604 
00605   Status = EhcEnableAsyncSchd (Ehc, EHC_GENERIC_TIMEOUT);
00606 
00607   if (EFI_ERROR (Status)) {
00608     DEBUG ((EFI_D_ERROR, "EhcInitHC: failed to enable async schedule\n"));
00609     return Status;
00610   }
00611 
00612   return EFI_SUCCESS;
00613 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines