X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=Omap35xxPkg%2FPciEmulation%2FPciEmulation.c;h=0cc0faa42c69bd7b3b8a8afcc91d03a9e0e57e7e;hp=6b5528cea429e45dc713f1245a31966a4fe0f6d8;hb=1e57a46299244793beb27e74be171d1540606999;hpb=5767f22fca7c337cdc113e14b411c1fd0ea7bd53 diff --git a/Omap35xxPkg/PciEmulation/PciEmulation.c b/Omap35xxPkg/PciEmulation/PciEmulation.c index 6b5528cea4..0cc0faa42c 100644 --- a/Omap35xxPkg/PciEmulation/PciEmulation.c +++ b/Omap35xxPkg/PciEmulation/PciEmulation.c @@ -1,524 +1,524 @@ -/** @file - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciEmulation.h" - -EMBEDDED_EXTERNAL_DEVICE *gTPS65950; - -#define HOST_CONTROLLER_OPERATION_REG_SIZE 0x44 - -typedef struct { - ACPI_HID_DEVICE_PATH AcpiDevicePath; - PCI_DEVICE_PATH PciDevicePath; - EFI_DEVICE_PATH_PROTOCOL EndDevicePath; -} EFI_PCI_IO_DEVICE_PATH; - -typedef struct { - UINT32 Signature; - EFI_PCI_IO_DEVICE_PATH DevicePath; - EFI_PCI_IO_PROTOCOL PciIoProtocol; - PCI_TYPE00 *ConfigSpace; - PCI_ROOT_BRIDGE RootBridge; - UINTN Segment; -} EFI_PCI_IO_PRIVATE_DATA; - -#define EFI_PCI_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'o') -#define EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(a) CR(a, EFI_PCI_IO_PRIVATE_DATA, PciIoProtocol, EFI_PCI_IO_PRIVATE_DATA_SIGNATURE) - -EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplate = -{ - { - { ACPI_DEVICE_PATH, ACPI_DP, sizeof (ACPI_HID_DEVICE_PATH), 0}, - EISA_PNP_ID(0x0A03), // HID - 0 // UID - }, - { - { HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof (PCI_DEVICE_PATH), 0}, - 0, - 0 - }, - { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} -}; - -STATIC -VOID -ConfigureUSBHost ( - VOID - ) -{ - EFI_STATUS Status; - UINT8 Data = 0; - - // Take USB host out of force-standby mode - MmioWrite32 (UHH_SYSCONFIG, UHH_SYSCONFIG_MIDLEMODE_NO_STANDBY - | UHH_SYSCONFIG_CLOCKACTIVITY_ON - | UHH_SYSCONFIG_SIDLEMODE_NO_STANDBY - | UHH_SYSCONFIG_ENAWAKEUP_ENABLE - | UHH_SYSCONFIG_AUTOIDLE_ALWAYS_RUN); - MmioWrite32 (UHH_HOSTCONFIG, UHH_HOSTCONFIG_P3_CONNECT_STATUS_DISCONNECT - | UHH_HOSTCONFIG_P2_CONNECT_STATUS_DISCONNECT - | UHH_HOSTCONFIG_P1_CONNECT_STATUS_DISCONNECT - | UHH_HOSTCONFIG_ENA_INCR_ALIGN_DISABLE - | UHH_HOSTCONFIG_ENA_INCR16_ENABLE - | UHH_HOSTCONFIG_ENA_INCR8_ENABLE - | UHH_HOSTCONFIG_ENA_INCR4_ENABLE - | UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN_ON - | UHH_HOSTCONFIG_P1_ULPI_BYPASS_ULPI_MODE); - - // USB reset (GPIO 147 - Port 5 pin 19) output high - MmioAnd32 (GPIO5_BASE + GPIO_OE, ~BIT19); - MmioWrite32 (GPIO5_BASE + GPIO_SETDATAOUT, BIT19); - - // Get the Power IC protocol - Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950); - ASSERT_EFI_ERROR (Status); - - // Power the USB PHY - Data = VAUX_DEV_GRP_P1; - Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEV_GRP), 1, &Data); - ASSERT_EFI_ERROR(Status); - - Data = VAUX_DEDICATED_18V; - Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEDICATED), 1, &Data); - ASSERT_EFI_ERROR (Status); - - // Enable power to the USB hub - Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data); - ASSERT_EFI_ERROR (Status); - - // LEDAON controls the power to the USB host, PWM is disabled - Data &= ~LEDAPWM; - Data |= LEDAON; - - Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data); - ASSERT_EFI_ERROR (Status); -} - - -EFI_STATUS -PciIoPollMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -{ - ASSERT (FALSE); - return EFI_UNSUPPORTED; -} - -EFI_STATUS -PciIoPollIo ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -{ - ASSERT (FALSE); - return EFI_UNSUPPORTED; -} - -EFI_STATUS -PciIoMemRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); - - return PciRootBridgeIoMemRead (&Private->RootBridge.Io, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Private->ConfigSpace->Device.Bar[BarIndex] + Offset, - Count, - Buffer - ); -} - -EFI_STATUS -PciIoMemWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); - - return PciRootBridgeIoMemWrite (&Private->RootBridge.Io, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Private->ConfigSpace->Device.Bar[BarIndex] + Offset, - Count, - Buffer - ); -} - -EFI_STATUS -PciIoIoRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - ASSERT (FALSE); - return EFI_UNSUPPORTED; -} - -EFI_STATUS -PciIoIoWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - ASSERT (FALSE); - return EFI_UNSUPPORTED; -} - -EFI_STATUS -PciIoPciRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); - - return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width, - Count, - TRUE, - (PTR)(UINTN)Buffer, - TRUE, - (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset) - ); -} - -EFI_STATUS -PciIoPciWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); - - return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Count, - TRUE, - (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset), - TRUE, - (PTR)(UINTN)Buffer - ); -} - -EFI_STATUS -PciIoCopyMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 DestBarIndex, - IN UINT64 DestOffset, - IN UINT8 SrcBarIndex, - IN UINT64 SrcOffset, - IN UINTN Count - ) -{ - ASSERT (FALSE); - return EFI_UNSUPPORTED; -} - -EFI_STATUS -PciIoMap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ) -{ - DMA_MAP_OPERATION DmaOperation; - - if (Operation == EfiPciIoOperationBusMasterRead) { - DmaOperation = MapOperationBusMasterRead; - } else if (Operation == EfiPciIoOperationBusMasterWrite) { - DmaOperation = MapOperationBusMasterWrite; - } else if (Operation == EfiPciIoOperationBusMasterCommonBuffer) { - DmaOperation = MapOperationBusMasterCommonBuffer; - } else { - return EFI_INVALID_PARAMETER; - } - return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping); -} - -EFI_STATUS -PciIoUnmap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN VOID *Mapping - ) -{ - return DmaUnmap (Mapping); -} - -EFI_STATUS -PciIoAllocateBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes - ) -{ - if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) { - // Check this - return EFI_UNSUPPORTED; - } - - return DmaAllocateBuffer (MemoryType, Pages, HostAddress); -} - - -EFI_STATUS -PciIoFreeBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINTN Pages, - IN VOID *HostAddress - ) -{ - return DmaFreeBuffer (Pages, HostAddress); -} - - -EFI_STATUS -PciIoFlush ( - IN EFI_PCI_IO_PROTOCOL *This - ) -{ - return EFI_SUCCESS; -} - -EFI_STATUS -PciIoGetLocation ( - IN EFI_PCI_IO_PROTOCOL *This, - OUT UINTN *SegmentNumber, - OUT UINTN *BusNumber, - OUT UINTN *DeviceNumber, - OUT UINTN *FunctionNumber - ) -{ - EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); - - if (SegmentNumber != NULL) { - *SegmentNumber = Private->Segment; - } - - if (BusNumber != NULL) { - *BusNumber = 0xff; - } - - if (DeviceNumber != NULL) { - *DeviceNumber = 0; - } - - if (FunctionNumber != NULL) { - *FunctionNumber = 0; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PciIoAttributes ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, - IN UINT64 Attributes, - OUT UINT64 *Result OPTIONAL - ) -{ - switch (Operation) { - case EfiPciIoAttributeOperationGet: - case EfiPciIoAttributeOperationSupported: - if (Result == NULL) { - return EFI_INVALID_PARAMETER; - } - // We are not a real PCI device so just say things we kind of do - *Result = EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | EFI_PCI_DEVICE_ENABLE; - break; - - case EfiPciIoAttributeOperationSet: - case EfiPciIoAttributeOperationEnable: - case EfiPciIoAttributeOperationDisable: - // Since we are not a real PCI device no enable/set or disable operations exist. - return EFI_SUCCESS; - - default: - ASSERT (FALSE); - return EFI_INVALID_PARAMETER; - }; - return EFI_SUCCESS; -} - -EFI_STATUS -PciIoGetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINT8 BarIndex, - OUT UINT64 *Supports, OPTIONAL - OUT VOID **Resources OPTIONAL - ) -{ - ASSERT (FALSE); - return EFI_UNSUPPORTED; -} - -EFI_STATUS -PciIoSetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINT64 Attributes, - IN UINT8 BarIndex, - IN OUT UINT64 *Offset, - IN OUT UINT64 *Length - ) -{ - ASSERT (FALSE); - return EFI_UNSUPPORTED; -} - -EFI_PCI_IO_PROTOCOL PciIoTemplate = -{ - PciIoPollMem, - PciIoPollIo, - PciIoMemRead, - PciIoMemWrite, - PciIoIoRead, - PciIoIoWrite, - PciIoPciRead, - PciIoPciWrite, - PciIoCopyMem, - PciIoMap, - PciIoUnmap, - PciIoAllocateBuffer, - PciIoFreeBuffer, - PciIoFlush, - PciIoGetLocation, - PciIoAttributes, - PciIoGetBarAttributes, - PciIoSetBarAttributes, - 0, - 0 -}; - -EFI_STATUS -EFIAPI -PciEmulationEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - EFI_PCI_IO_PRIVATE_DATA *Private; - UINT8 CapabilityLength; - UINT8 PhysicalPorts; - UINTN Count; - - - //Configure USB host for OMAP3530. - ConfigureUSBHost(); - - // Create a private structure - Private = AllocatePool(sizeof(EFI_PCI_IO_PRIVATE_DATA)); - if (Private == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Private->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature - Private->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too - Private->RootBridge.MemoryStart = USB_EHCI_HCCAPBASE; // Get the USB capability register base - Private->Segment = 0; // Default to segment zero - - // Find out the capability register length and number of physical ports. - CapabilityLength = MmioRead8(Private->RootBridge.MemoryStart); - PhysicalPorts = (MmioRead32 (Private->RootBridge.MemoryStart + 0x4)) & 0x0000000F; - - // Calculate the total size of the USB registers. - Private->RootBridge.MemorySize = CapabilityLength + (HOST_CONTROLLER_OPERATION_REG_SIZE + ((4 * PhysicalPorts) - 1)); - - // Enable Port Power bit in Port status and control registers in EHCI register space. - // Port Power Control (PPC) bit in the HCSPARAMS register is already set which indicates - // host controller implementation includes port power control. - for (Count = 0; Count < PhysicalPorts; Count++) { - MmioOr32 ((Private->RootBridge.MemoryStart + CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE + 4*Count), 0x00001000); - } - - // Create fake PCI config space. - Private->ConfigSpace = AllocateZeroPool(sizeof(PCI_TYPE00)); - if (Private->ConfigSpace == NULL) { - Status = EFI_OUT_OF_RESOURCES; - FreePool(Private); - return Status; - } - - // Configure PCI config space - Private->ConfigSpace->Hdr.VendorId = 0x3530; - Private->ConfigSpace->Hdr.DeviceId = 0x3530; - Private->ConfigSpace->Hdr.ClassCode[0] = 0x20; - Private->ConfigSpace->Hdr.ClassCode[1] = 0x03; - Private->ConfigSpace->Hdr.ClassCode[2] = 0x0C; - Private->ConfigSpace->Device.Bar[0] = Private->RootBridge.MemoryStart; - - Handle = NULL; - - // Unique device path. - CopyMem(&Private->DevicePath, &PciIoDevicePathTemplate, sizeof(PciIoDevicePathTemplate)); - Private->DevicePath.AcpiDevicePath.UID = 0; - - // Copy protocol structure - CopyMem(&Private->PciIoProtocol, &PciIoTemplate, sizeof(PciIoTemplate)); - - Status = gBS->InstallMultipleProtocolInterfaces(&Handle, - &gEfiPciIoProtocolGuid, &Private->PciIoProtocol, - &gEfiDevicePathProtocolGuid, &Private->DevicePath, - NULL); - if (EFI_ERROR(Status)) { - DEBUG((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces() failed.\n")); - } - - return Status; -} - +/** @file + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PciEmulation.h" + +EMBEDDED_EXTERNAL_DEVICE *gTPS65950; + +#define HOST_CONTROLLER_OPERATION_REG_SIZE 0x44 + +typedef struct { + ACPI_HID_DEVICE_PATH AcpiDevicePath; + PCI_DEVICE_PATH PciDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} EFI_PCI_IO_DEVICE_PATH; + +typedef struct { + UINT32 Signature; + EFI_PCI_IO_DEVICE_PATH DevicePath; + EFI_PCI_IO_PROTOCOL PciIoProtocol; + PCI_TYPE00 *ConfigSpace; + PCI_ROOT_BRIDGE RootBridge; + UINTN Segment; +} EFI_PCI_IO_PRIVATE_DATA; + +#define EFI_PCI_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'o') +#define EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(a) CR(a, EFI_PCI_IO_PRIVATE_DATA, PciIoProtocol, EFI_PCI_IO_PRIVATE_DATA_SIGNATURE) + +EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplate = +{ + { + { ACPI_DEVICE_PATH, ACPI_DP, sizeof (ACPI_HID_DEVICE_PATH), 0}, + EISA_PNP_ID(0x0A03), // HID + 0 // UID + }, + { + { HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof (PCI_DEVICE_PATH), 0}, + 0, + 0 + }, + { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} +}; + +STATIC +VOID +ConfigureUSBHost ( + VOID + ) +{ + EFI_STATUS Status; + UINT8 Data = 0; + + // Take USB host out of force-standby mode + MmioWrite32 (UHH_SYSCONFIG, UHH_SYSCONFIG_MIDLEMODE_NO_STANDBY + | UHH_SYSCONFIG_CLOCKACTIVITY_ON + | UHH_SYSCONFIG_SIDLEMODE_NO_STANDBY + | UHH_SYSCONFIG_ENAWAKEUP_ENABLE + | UHH_SYSCONFIG_AUTOIDLE_ALWAYS_RUN); + MmioWrite32 (UHH_HOSTCONFIG, UHH_HOSTCONFIG_P3_CONNECT_STATUS_DISCONNECT + | UHH_HOSTCONFIG_P2_CONNECT_STATUS_DISCONNECT + | UHH_HOSTCONFIG_P1_CONNECT_STATUS_DISCONNECT + | UHH_HOSTCONFIG_ENA_INCR_ALIGN_DISABLE + | UHH_HOSTCONFIG_ENA_INCR16_ENABLE + | UHH_HOSTCONFIG_ENA_INCR8_ENABLE + | UHH_HOSTCONFIG_ENA_INCR4_ENABLE + | UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN_ON + | UHH_HOSTCONFIG_P1_ULPI_BYPASS_ULPI_MODE); + + // USB reset (GPIO 147 - Port 5 pin 19) output high + MmioAnd32 (GPIO5_BASE + GPIO_OE, ~BIT19); + MmioWrite32 (GPIO5_BASE + GPIO_SETDATAOUT, BIT19); + + // Get the Power IC protocol + Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950); + ASSERT_EFI_ERROR (Status); + + // Power the USB PHY + Data = VAUX_DEV_GRP_P1; + Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEV_GRP), 1, &Data); + ASSERT_EFI_ERROR(Status); + + Data = VAUX_DEDICATED_18V; + Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEDICATED), 1, &Data); + ASSERT_EFI_ERROR (Status); + + // Enable power to the USB hub + Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data); + ASSERT_EFI_ERROR (Status); + + // LEDAON controls the power to the USB host, PWM is disabled + Data &= ~LEDAPWM; + Data |= LEDAON; + + Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data); + ASSERT_EFI_ERROR (Status); +} + + +EFI_STATUS +PciIoPollMem ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +EFI_STATUS +PciIoPollIo ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +EFI_STATUS +PciIoMemRead ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); + + return PciRootBridgeIoMemRead (&Private->RootBridge.Io, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Private->ConfigSpace->Device.Bar[BarIndex] + Offset, + Count, + Buffer + ); +} + +EFI_STATUS +PciIoMemWrite ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); + + return PciRootBridgeIoMemWrite (&Private->RootBridge.Io, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Private->ConfigSpace->Device.Bar[BarIndex] + Offset, + Count, + Buffer + ); +} + +EFI_STATUS +PciIoIoRead ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +EFI_STATUS +PciIoIoWrite ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +EFI_STATUS +PciIoPciRead ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); + + return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width, + Count, + TRUE, + (PTR)(UINTN)Buffer, + TRUE, + (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset) + ); +} + +EFI_STATUS +PciIoPciWrite ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); + + return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Count, + TRUE, + (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset), + TRUE, + (PTR)(UINTN)Buffer + ); +} + +EFI_STATUS +PciIoCopyMem ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 DestBarIndex, + IN UINT64 DestOffset, + IN UINT8 SrcBarIndex, + IN UINT64 SrcOffset, + IN UINTN Count + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +EFI_STATUS +PciIoMap ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +{ + DMA_MAP_OPERATION DmaOperation; + + if (Operation == EfiPciIoOperationBusMasterRead) { + DmaOperation = MapOperationBusMasterRead; + } else if (Operation == EfiPciIoOperationBusMasterWrite) { + DmaOperation = MapOperationBusMasterWrite; + } else if (Operation == EfiPciIoOperationBusMasterCommonBuffer) { + DmaOperation = MapOperationBusMasterCommonBuffer; + } else { + return EFI_INVALID_PARAMETER; + } + return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping); +} + +EFI_STATUS +PciIoUnmap ( + IN EFI_PCI_IO_PROTOCOL *This, + IN VOID *Mapping + ) +{ + return DmaUnmap (Mapping); +} + +EFI_STATUS +PciIoAllocateBuffer ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes + ) +{ + if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) { + // Check this + return EFI_UNSUPPORTED; + } + + return DmaAllocateBuffer (MemoryType, Pages, HostAddress); +} + + +EFI_STATUS +PciIoFreeBuffer ( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ) +{ + return DmaFreeBuffer (Pages, HostAddress); +} + + +EFI_STATUS +PciIoFlush ( + IN EFI_PCI_IO_PROTOCOL *This + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +PciIoGetLocation ( + IN EFI_PCI_IO_PROTOCOL *This, + OUT UINTN *SegmentNumber, + OUT UINTN *BusNumber, + OUT UINTN *DeviceNumber, + OUT UINTN *FunctionNumber + ) +{ + EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This); + + if (SegmentNumber != NULL) { + *SegmentNumber = Private->Segment; + } + + if (BusNumber != NULL) { + *BusNumber = 0xff; + } + + if (DeviceNumber != NULL) { + *DeviceNumber = 0; + } + + if (FunctionNumber != NULL) { + *FunctionNumber = 0; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PciIoAttributes ( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, + IN UINT64 Attributes, + OUT UINT64 *Result OPTIONAL + ) +{ + switch (Operation) { + case EfiPciIoAttributeOperationGet: + case EfiPciIoAttributeOperationSupported: + if (Result == NULL) { + return EFI_INVALID_PARAMETER; + } + // We are not a real PCI device so just say things we kind of do + *Result = EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | EFI_PCI_DEVICE_ENABLE; + break; + + case EfiPciIoAttributeOperationSet: + case EfiPciIoAttributeOperationEnable: + case EfiPciIoAttributeOperationDisable: + // Since we are not a real PCI device no enable/set or disable operations exist. + return EFI_SUCCESS; + + default: + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + }; + return EFI_SUCCESS; +} + +EFI_STATUS +PciIoGetBarAttributes ( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINT8 BarIndex, + OUT UINT64 *Supports, OPTIONAL + OUT VOID **Resources OPTIONAL + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +EFI_STATUS +PciIoSetBarAttributes ( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN UINT8 BarIndex, + IN OUT UINT64 *Offset, + IN OUT UINT64 *Length + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +EFI_PCI_IO_PROTOCOL PciIoTemplate = +{ + PciIoPollMem, + PciIoPollIo, + PciIoMemRead, + PciIoMemWrite, + PciIoIoRead, + PciIoIoWrite, + PciIoPciRead, + PciIoPciWrite, + PciIoCopyMem, + PciIoMap, + PciIoUnmap, + PciIoAllocateBuffer, + PciIoFreeBuffer, + PciIoFlush, + PciIoGetLocation, + PciIoAttributes, + PciIoGetBarAttributes, + PciIoSetBarAttributes, + 0, + 0 +}; + +EFI_STATUS +EFIAPI +PciEmulationEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_PCI_IO_PRIVATE_DATA *Private; + UINT8 CapabilityLength; + UINT8 PhysicalPorts; + UINTN Count; + + + //Configure USB host for OMAP3530. + ConfigureUSBHost(); + + // Create a private structure + Private = AllocatePool(sizeof(EFI_PCI_IO_PRIVATE_DATA)); + if (Private == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Private->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature + Private->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too + Private->RootBridge.MemoryStart = USB_EHCI_HCCAPBASE; // Get the USB capability register base + Private->Segment = 0; // Default to segment zero + + // Find out the capability register length and number of physical ports. + CapabilityLength = MmioRead8(Private->RootBridge.MemoryStart); + PhysicalPorts = (MmioRead32 (Private->RootBridge.MemoryStart + 0x4)) & 0x0000000F; + + // Calculate the total size of the USB registers. + Private->RootBridge.MemorySize = CapabilityLength + (HOST_CONTROLLER_OPERATION_REG_SIZE + ((4 * PhysicalPorts) - 1)); + + // Enable Port Power bit in Port status and control registers in EHCI register space. + // Port Power Control (PPC) bit in the HCSPARAMS register is already set which indicates + // host controller implementation includes port power control. + for (Count = 0; Count < PhysicalPorts; Count++) { + MmioOr32 ((Private->RootBridge.MemoryStart + CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE + 4*Count), 0x00001000); + } + + // Create fake PCI config space. + Private->ConfigSpace = AllocateZeroPool(sizeof(PCI_TYPE00)); + if (Private->ConfigSpace == NULL) { + Status = EFI_OUT_OF_RESOURCES; + FreePool(Private); + return Status; + } + + // Configure PCI config space + Private->ConfigSpace->Hdr.VendorId = 0x3530; + Private->ConfigSpace->Hdr.DeviceId = 0x3530; + Private->ConfigSpace->Hdr.ClassCode[0] = 0x20; + Private->ConfigSpace->Hdr.ClassCode[1] = 0x03; + Private->ConfigSpace->Hdr.ClassCode[2] = 0x0C; + Private->ConfigSpace->Device.Bar[0] = Private->RootBridge.MemoryStart; + + Handle = NULL; + + // Unique device path. + CopyMem(&Private->DevicePath, &PciIoDevicePathTemplate, sizeof(PciIoDevicePathTemplate)); + Private->DevicePath.AcpiDevicePath.UID = 0; + + // Copy protocol structure + CopyMem(&Private->PciIoProtocol, &PciIoTemplate, sizeof(PciIoTemplate)); + + Status = gBS->InstallMultipleProtocolInterfaces(&Handle, + &gEfiPciIoProtocolGuid, &Private->PciIoProtocol, + &gEfiDevicePathProtocolGuid, &Private->DevicePath, + NULL); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces() failed.\n")); + } + + return Status; +} +