/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
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 <PiDxe.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/NonDiscoverableDeviceRegistrationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/EmbeddedExternalDevice.h>
#include <TPS65950.h>
#include <Omap3530/Omap3530.h>
EMBEDDED_EXTERNAL_DEVICE *gTPS65950;
#define HOST_CONTROLLER_OPERATION_REG_SIZE 0x44
STATIC
EFI_STATUS
ConfigureUSBHost (
NON_DISCOVERABLE_DEVICE *Device
)
{
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);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PciEmulationEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINT8 CapabilityLength;
UINT8 PhysicalPorts;
UINTN MemorySize;
CapabilityLength = MmioRead8 (USB_EHCI_HCCAPBASE);
PhysicalPorts = MmioRead32 (USB_EHCI_HCCAPBASE + 0x4) & 0x0000000F;
MemorySize = CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE +
4 * PhysicalPorts - 1;
return RegisterNonDiscoverableMmioDevice (
NonDiscoverableDeviceTypeEhci,
NonDiscoverableDeviceDmaTypeNonCoherent,
ConfigureUSBHost,
NULL,
1,
USB_EHCI_HCCAPBASE, MemorySize
);
}